Version Description
Download this release
Release Info
Developer | averta |
Plugin | ![]() |
Version | 1.0.10 |
Comparing to | |
See all releases |
Code changes from version 1.0.5 to 1.0.10
- README.txt +28 -11
- admin/includes/classes/class-msp-parser.php +1 -1
- admin/includes/msp-hooks.php +10 -0
- admin/views/setting/class-msp-settings.php +14 -0
- admin/views/slider-panel/js/masterslider.wp.js +7 -3108
- admin/views/slider-panel/js/msp.required.js +28 -10913
- includes/init/define.php +1 -1
- master-slider.php +2 -2
- public/includes/class-msp-frontend-assets.php +4 -0
- uninstall.php +1 -1
README.txt
CHANGED
@@ -3,10 +3,10 @@ Contributors: averta
|
|
3 |
Donate link: http://averta.net/
|
4 |
License: GPLv3
|
5 |
License URI: http://www.gnu.org/licenses/gpl.html
|
6 |
-
Tags: banner rotator, carousel, content slider, gallery, image slider, responsive slider, showcase, slideshow, swipe, touch slider, video gallery, SEO, vertical slide, HTML5 slider, hardware accelerate, css3, animation, mobile slider, iOS, android, video slider, youtube slider, horizontal slider, vertical slider, fullwidth slider, fullscreen slider, post slider, photo slider, online album, mobile slider, WordPress slider,wpml, ,ultisite, wistia
|
7 |
Requires at least: 3.8
|
8 |
-
Tested up to: 3.9.
|
9 |
-
Stable tag: 1.0.
|
10 |
|
11 |
The Most advanced responsive HTML5 WordPress slider plugin with touch swipe navigation that works smoothly on devices too.
|
12 |
|
@@ -14,8 +14,9 @@ The Most advanced responsive HTML5 WordPress slider plugin with touch swipe navi
|
|
14 |
|
15 |
Master Slider is a free responsive image and content slider with super smooth hardware accelerated transitions. It supports touch navigation with pure swipe gesture that you have never experienced before. It's a truly responsive and device friendly slider which works perfectly in all major devices.
|
16 |
|
|
|
17 |
|
18 |
-
Master Slider is built using WordPress best practices both on the front and the back end. This results in an efficient, robust and intuitive plugin. It's works with any theme, including the default WordPress themes.
|
19 |
|
20 |
|
21 |
= Features =
|
@@ -123,7 +124,7 @@ You can use automatic update to update the plugin safely.
|
|
123 |
|
124 |
If you have any question about working with "Master Slider", you can take a look at [online documentations](http://masterslider.com/doc/wp/free/)
|
125 |
|
126 |
-
If you get stuck you can
|
127 |
|
128 |
= Will Master Slider work with my theme? =
|
129 |
Master Slider works with any theme, including the default WordPress themes.
|
@@ -157,11 +158,26 @@ Bugs can be reported in our [support forums](http://wordpress.org/tags/master-sl
|
|
157 |
|
158 |
== Changelog ==
|
159 |
|
160 |
-
= Version 1.0.
|
161 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
|
163 |
-
= Version 1.0.
|
164 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
|
166 |
= Version 1.0.1 / (12.07.2014) =
|
167 |
* initial release
|
@@ -170,5 +186,6 @@ Bugs can be reported in our [support forums](http://wordpress.org/tags/master-sl
|
|
170 |
|
171 |
== Upgrade Notice ==
|
172 |
|
173 |
-
= 1.0.
|
174 |
-
*
|
|
3 |
Donate link: http://averta.net/
|
4 |
License: GPLv3
|
5 |
License URI: http://www.gnu.org/licenses/gpl.html
|
6 |
+
Tags: banner rotator, carousel, content slider, gallery, image slider, responsive slider, showcase, slideshow, swipe, touch slider, video gallery, SEO, vertical slide, HTML5 slider, hardware accelerate, css3, animation, mobile slider, iOS, android, video slider, youtube slider, horizontal slider, vertical slider, fullwidth slider, fullscreen slider, post slider, photo slider, online album, mobile slider, WordPress slider,wpml, ,ultisite, wistia, woocommerce, product slider, woocommerce slider
|
7 |
Requires at least: 3.8
|
8 |
+
Tested up to: 3.9.2
|
9 |
+
Stable tag: 1.0.10
|
10 |
|
11 |
The Most advanced responsive HTML5 WordPress slider plugin with touch swipe navigation that works smoothly on devices too.
|
12 |
|
14 |
|
15 |
Master Slider is a free responsive image and content slider with super smooth hardware accelerated transitions. It supports touch navigation with pure swipe gesture that you have never experienced before. It's a truly responsive and device friendly slider which works perfectly in all major devices.
|
16 |
|
17 |
+
[youtube http://www.youtube.com/watch?v=t0N5BTH8kfE]
|
18 |
|
19 |
+
Master Slider is built using WordPress best practices both on the front and the back end. This results in an efficient, robust and intuitive plugin. It's works with any theme, including the default WordPress themes.
|
20 |
|
21 |
|
22 |
= Features =
|
124 |
|
125 |
If you have any question about working with "Master Slider", you can take a look at [online documentations](http://masterslider.com/doc/wp/free/)
|
126 |
|
127 |
+
If you get stuck you can follow these [steps to get support](http://masterslider.com/doc/wp/free/#support).
|
128 |
|
129 |
= Will Master Slider work with my theme? =
|
130 |
Master Slider works with any theme, including the default WordPress themes.
|
158 |
|
159 |
== Changelog ==
|
160 |
|
161 |
+
= Version 1.0.10 / (07.08.2014) =
|
162 |
+
* Slide info is now shortcode enabled
|
163 |
+
* compatibility with WordPress 3.9.2 added
|
164 |
+
|
165 |
+
= Version 1.0.9 / (22.07.2014) =
|
166 |
+
* A minor bug in plugins page fixed
|
167 |
+
|
168 |
+
= Version 1.0.8 / (21.07.2014) =
|
169 |
+
* A link added to plugins page for rating this plugin
|
170 |
|
171 |
+
= Version 1.0.7 / (19.07.2014) =
|
172 |
+
* [New Feature]: New option added to global setting that let you load plugins's scripts on all pages.
|
173 |
+
( Useful when loading slider via Ajax )
|
174 |
+
* An issue with text editor fixed
|
175 |
+
|
176 |
+
= Version 1.0.6 / (17.07.2014) =
|
177 |
+
* [New]: Introduction video added
|
178 |
+
|
179 |
+
= Version 1.0.5 / (15.07.2014) =
|
180 |
+
* [Fix]: An issue with uninstalling the plugin fixed
|
181 |
|
182 |
= Version 1.0.1 / (12.07.2014) =
|
183 |
* initial release
|
186 |
|
187 |
== Upgrade Notice ==
|
188 |
|
189 |
+
= 1.0.10 =
|
190 |
+
* Slide info is now shortcode enabled
|
191 |
+
* compatibility with WordPress 3.9.2 added
|
admin/includes/classes/class-msp-parser.php
CHANGED
@@ -316,7 +316,7 @@ class MSP_Parser {
|
|
316 |
'target' => isset( $slide['linkTarget'] ) ? (string) $slide['linkTarget'] : '',
|
317 |
'video' => isset( $slide['video'] ) ? esc_attr( $slide['video'] ) : '', // youtube or vimeo video link
|
318 |
|
319 |
-
'info' => wp_slash( $info ), // image alternative text
|
320 |
|
321 |
'mp4' => isset( $slide['bgv_mp4'] ) ? esc_attr( $slide['bgv_mp4'] ) : '', // self host video bg
|
322 |
'webm' => isset( $slide['bgv_webm'] ) ? esc_attr( $slide['bgv_webm'] ) : '', // self host video bg
|
316 |
'target' => isset( $slide['linkTarget'] ) ? (string) $slide['linkTarget'] : '',
|
317 |
'video' => isset( $slide['video'] ) ? esc_attr( $slide['video'] ) : '', // youtube or vimeo video link
|
318 |
|
319 |
+
'info' => wp_slash( do_shortcode( $info ) ), // image alternative text
|
320 |
|
321 |
'mp4' => isset( $slide['bgv_mp4'] ) ? esc_attr( $slide['bgv_mp4'] ) : '', // self host video bg
|
322 |
'webm' => isset( $slide['bgv_webm'] ) ? esc_attr( $slide['bgv_webm'] ) : '', // self host video bg
|
admin/includes/msp-hooks.php
CHANGED
@@ -1 +1,11 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
+
|
3 |
+
function after_master_slider_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ){
|
4 |
+
if( MSWP_AVERTA_BASE_NAME == $plugin_file ) {
|
5 |
+
$plugin_meta[] = '<a href="http://wordpress.org/support/view/plugin-reviews/' . MSWP_SLUG . '?rating=5#postform" target="_blank" title="' . esc_attr__( 'Rate this plugin', MSWP_TEXT_DOMAIN ) . '">' . __( 'Rate this plugin', MSWP_TEXT_DOMAIN ) . '</a>';
|
6 |
+
$plugin_meta[] = '<a href="http://masterslider.com/doc/wp/free/#donate" target="_blank" title="' . esc_attr__( 'Donate', MSWP_TEXT_DOMAIN ) . '">' . __( 'Donate', MSWP_TEXT_DOMAIN ) . '</a>';
|
7 |
+
}
|
8 |
+
return $plugin_meta;
|
9 |
+
}
|
10 |
+
|
11 |
+
add_filter( "plugin_row_meta", 'after_master_slider_row_meta', 10, 4 );
|
admin/views/setting/class-msp-settings.php
CHANGED
@@ -70,6 +70,11 @@ class MSP_Settings {
|
|
70 |
)
|
71 |
);
|
72 |
|
|
|
|
|
|
|
|
|
|
|
73 |
return $sections;
|
74 |
}
|
75 |
|
@@ -105,6 +110,15 @@ class MSP_Settings {
|
|
105 |
)
|
106 |
);
|
107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
return $settings_fields;
|
109 |
}
|
110 |
|
70 |
)
|
71 |
);
|
72 |
|
73 |
+
$sections[] = array(
|
74 |
+
'id' => 'msp_advanced',
|
75 |
+
'title' => __( 'Advanced Setting', MSWP_TEXT_DOMAIN )
|
76 |
+
);
|
77 |
+
|
78 |
return $sections;
|
79 |
}
|
80 |
|
110 |
)
|
111 |
);
|
112 |
|
113 |
+
$settings_fields['msp_advanced'] = array(
|
114 |
+
array(
|
115 |
+
'name' => 'allways_load_ms_assets',
|
116 |
+
'label' => __( 'Load assets on all pages?', MSWP_TEXT_DOMAIN ),
|
117 |
+
'desc' => __( 'By default, Master Slider will load corresponding JavaScript files on demand. but if you need to load assets on all pages, check this option. ( For example, if you plan to load Master Slider via Ajax, you need to check this option ) ', MSWP_TEXT_DOMAIN ),
|
118 |
+
'type' => 'checkbox'
|
119 |
+
)
|
120 |
+
);
|
121 |
+
|
122 |
return $settings_fields;
|
123 |
}
|
124 |
|
admin/views/slider-panel/js/masterslider.wp.js
CHANGED
@@ -1,3108 +1,7 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
* @
|
5 |
-
*
|
6 |
-
|
7 |
-
* http://www.averta.net
|
8 |
-
*/
|
9 |
-
|
10 |
-
window.MSPanel = Ember.Application.create({ rootElement : "#msp-root" });
|
11 |
-
MSPanel.version = '1.0';
|
12 |
-
MSPanel.SliderID = parseQueryString(window.location.search).slider_id || __MSP_SLIDER_ID || '100';
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Adds new function to String object 'jfmt' it's like Ember.fmt but first replaces '%s' or '%d' to '%@'
|
16 |
-
* @example 'Hi, %s'.jfmt('John');
|
17 |
-
*/
|
18 |
-
String.prototype.jfmt = function(){ return ''.fmt.apply(this.replace(/%s|%d/, '%@') ,arguments); };
|
19 |
-
|
20 |
-
$ = jQuery.noConflict();
|
21 |
-
jQuery.ui.dialog.prototype._focusTabbable = function(){};
|
22 |
-
|
23 |
-
// Setup Application Router
|
24 |
-
MSPanel.Router.map(function() {
|
25 |
-
this.resource('settings' );
|
26 |
-
this.resource('slides', {path: '/'});
|
27 |
-
this.resource('controls');
|
28 |
-
this.resource('callbacks');
|
29 |
-
this.resource('error');
|
30 |
-
});
|
31 |
-
MSPanel.Router.reopen({ location: 'none' });
|
32 |
-
|
33 |
-
// Application route
|
34 |
-
MSPanel.ApplicationRoute = Ember.Route.extend({
|
35 |
-
model: function() {
|
36 |
-
var setting = MSPanel.Settings.find();
|
37 |
-
if( setting.get('length') === 0){
|
38 |
-
MSPanel.Settings.create().save();
|
39 |
-
}
|
40 |
-
}
|
41 |
-
});
|
42 |
-
|
43 |
-
MSPanel.SettingsRoute = Ember.Route.extend({
|
44 |
-
model: function() {
|
45 |
-
return MSPanel.Settings.find(1);
|
46 |
-
},
|
47 |
-
setupController: function(controller, model) {
|
48 |
-
controller.set('model', model);
|
49 |
-
controller.setup();
|
50 |
-
}
|
51 |
-
});
|
52 |
-
|
53 |
-
MSPanel.SlidesRoute = Ember.Route.extend({
|
54 |
-
model: function(){
|
55 |
-
return MSPanel.Slide.find();
|
56 |
-
},
|
57 |
-
|
58 |
-
setupController: function(controller, model) {
|
59 |
-
controller.set('model', model);
|
60 |
-
controller.set('sliderSettings' , MSPanel.Settings.find(1)/*this.store.find('settings' , 1)*/);
|
61 |
-
controller.setup();
|
62 |
-
}
|
63 |
-
|
64 |
-
});
|
65 |
-
|
66 |
-
MSPanel.ControlsRoute = Ember.Route.extend({
|
67 |
-
model: function() {
|
68 |
-
return MSPanel.Control.find();
|
69 |
-
},
|
70 |
-
|
71 |
-
setupController: function(controller, model) {
|
72 |
-
controller.set('model', model);
|
73 |
-
controller.setup();
|
74 |
-
this.activate();
|
75 |
-
},
|
76 |
-
|
77 |
-
activate: function() {
|
78 |
-
var controller = this.get('controller');
|
79 |
-
if(controller){
|
80 |
-
controller.set('controlOptions', 'empty-template')
|
81 |
-
}
|
82 |
-
}
|
83 |
-
|
84 |
-
});
|
85 |
-
|
86 |
-
MSPanel.CallbacksRoute = Ember.Route.extend({
|
87 |
-
model: function() {
|
88 |
-
return MSPanel.Callback.find();
|
89 |
-
},
|
90 |
-
|
91 |
-
setupController: function(controller, model) {
|
92 |
-
controller.set('model', model);
|
93 |
-
controller.setup();
|
94 |
-
}
|
95 |
-
});//js\mspanel\models\SliderModel.js
|
96 |
-
|
97 |
-
/**
|
98 |
-
* Master Slider Panel Model
|
99 |
-
* @package MSPanel
|
100 |
-
* @author averta
|
101 |
-
*/
|
102 |
-
|
103 |
-
;(function(){
|
104 |
-
|
105 |
-
var attr = Ember.attr,
|
106 |
-
hasMany = Ember.hasMany,
|
107 |
-
belongsTo = Ember.belongsTo;
|
108 |
-
|
109 |
-
// custom data type, converts absolute paths to relative
|
110 |
-
var regp = /https\:|http\:/;
|
111 |
-
var WPPath = {
|
112 |
-
|
113 |
-
// convert to relative
|
114 |
-
serialize: function(path){
|
115 |
-
if ( path == undefined ){
|
116 |
-
return path;
|
117 |
-
}
|
118 |
-
|
119 |
-
if( regp.test(path) ) { // is it absolute?
|
120 |
-
return path.replace(__MS.upload_dir, '');
|
121 |
-
} else {
|
122 |
-
return path;
|
123 |
-
}
|
124 |
-
},
|
125 |
-
|
126 |
-
// covert to absolute
|
127 |
-
deserialize: function(path){
|
128 |
-
if ( path == undefined ) {
|
129 |
-
return path;
|
130 |
-
}
|
131 |
-
|
132 |
-
if( regp.test(path) ) { // is it absolute?
|
133 |
-
return path;
|
134 |
-
} else {
|
135 |
-
return __MS.upload_dir + path;
|
136 |
-
}
|
137 |
-
}
|
138 |
-
|
139 |
-
};
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Slider Settings Model
|
143 |
-
*/
|
144 |
-
MSPanel.Settings = Ember.Model.extend({
|
145 |
-
|
146 |
-
/* Internal Options */
|
147 |
-
// -------------------------------------------------------------------
|
148 |
-
id : attr('number'), // settings record id (not slider id)
|
149 |
-
snapping : attr('boolean', {defaultValue : true}),
|
150 |
-
bgImageThumb : attr(WPPath),
|
151 |
-
disableControls : attr('boolean', {defaultValue: false}),
|
152 |
-
// -------------------------------------------------------------------
|
153 |
-
|
154 |
-
// General
|
155 |
-
name : attr('string' , {defaultValue: __MSP_LAN.sm_001}),
|
156 |
-
width : attr('number' , {defaultValue: 1000}),
|
157 |
-
height : attr('number' , {defaultValue: 500}),
|
158 |
-
wrapperWidth : attr('number'),
|
159 |
-
wrapperWidthUnit : attr('string' , {defaultValue: 'px'}),
|
160 |
-
autoCrop : attr('boolean', {defaultValue: false}),
|
161 |
-
type : attr('string'),
|
162 |
-
sliderId : attr('string'),
|
163 |
-
|
164 |
-
/**
|
165 |
-
* Slider sizing methods
|
166 |
-
* Values:
|
167 |
-
* boxed,
|
168 |
-
* fullwidth,
|
169 |
-
* fullscreen,
|
170 |
-
* fillwidth,
|
171 |
-
* autofill,
|
172 |
-
* partialview
|
173 |
-
*/
|
174 |
-
layout : attr('string' , {defaultValue: 'boxed'}),
|
175 |
-
autoHeight : attr('boolean', {defaultValue: false}),
|
176 |
-
|
177 |
-
// navigation and appearance
|
178 |
-
trView : attr('string' , {defaultValue: 'basic'}),
|
179 |
-
speed : attr('number' , {defaultValue: 20}),
|
180 |
-
space : attr('number' , {defaultValue: 0}),
|
181 |
-
start : attr('number' , {defaultValue: 1}),
|
182 |
-
grabCursor : attr('boolean', {defaultValue: true}),
|
183 |
-
swipe : attr('boolean', {defaultValue: true}),
|
184 |
-
mouse : attr('boolean', {defaultValue: true}),
|
185 |
-
wheel : attr('boolean', {defaultValue: false}),
|
186 |
-
autoplay : attr('boolean', {defaultValue: false}),
|
187 |
-
loop : attr('boolean', {defaultValue: false}),
|
188 |
-
shuffle : attr('boolean', {defaultValue: false}),
|
189 |
-
preload : attr('string' , {defaultValue: '-1'}),
|
190 |
-
overPause : attr('boolean', {defaultValue: true}),
|
191 |
-
endPause : attr('boolean', {defaultValue: false}),
|
192 |
-
hideLayers : attr('boolean', {defaultValue: false}),
|
193 |
-
dir : attr('string' , {defaultValue: 'h'}),
|
194 |
-
parallaxMode: attr('srting' , {defaultValue: 'swipe'}),
|
195 |
-
centerControls : attr('boolean', {defaultValue: true}),
|
196 |
-
instantShowLayers : attr('boolean', {defaultValue: false}),
|
197 |
-
fullscreenMargin : attr('number'),
|
198 |
-
|
199 |
-
// misc
|
200 |
-
inlineStyle : attr('string'),
|
201 |
-
className : attr('string'),
|
202 |
-
bgColor : attr('string'),
|
203 |
-
bgImage : attr(WPPath),
|
204 |
-
|
205 |
-
skin : attr('string' , {defaultValue: 'ms-skin-default'}),
|
206 |
-
msTemplate : attr('string' , {defaultValue: 'custom'}),
|
207 |
-
msTemplateClass : attr('string' , {defaultValue: ''}),
|
208 |
-
usedFonts : attr('string'),
|
209 |
-
|
210 |
-
// Flickr/Facebook Settings
|
211 |
-
apiKey : attr('string'),
|
212 |
-
setId : attr('string'),
|
213 |
-
setType : attr('string'),
|
214 |
-
imgCount : attr('number'),
|
215 |
-
thumbSize : attr('srting'),
|
216 |
-
imgSize : attr('string'),
|
217 |
-
|
218 |
-
// Posts Settings
|
219 |
-
postType : attr('string'),
|
220 |
-
postCats : attr(Array),
|
221 |
-
postTags : attr(Array),
|
222 |
-
postCount : attr('number'),
|
223 |
-
postImageType : attr('string'),
|
224 |
-
postOrder : attr('string'),
|
225 |
-
postOrderDir : attr('string'),
|
226 |
-
postExcerptLen : attr('number'),
|
227 |
-
postExcludeIds : attr('string'),
|
228 |
-
postOffset : attr('number'),
|
229 |
-
postLinkSlide : attr('boolean'),
|
230 |
-
postLinkTarget : attr('string'),
|
231 |
-
postSlideBg : attr('string'),
|
232 |
-
postSlideBgthumb: attr('string'), // internal
|
233 |
-
|
234 |
-
// woocommmerce settings
|
235 |
-
wcOnlyInstock : attr('boolean'),
|
236 |
-
wcOnlyFeatured : attr('boolean'),
|
237 |
-
wcOnlyOnsale : attr('boolean')
|
238 |
-
})
|
239 |
-
|
240 |
-
/**
|
241 |
-
* Slider Slide Model
|
242 |
-
*/
|
243 |
-
MSPanel.Slide = Ember.Model.extend({
|
244 |
-
|
245 |
-
/* Internal Options */
|
246 |
-
// -------------------------------------------------------------------
|
247 |
-
id : attr('number'),
|
248 |
-
timeline_h : attr('number' , {defaultValue: 200}),
|
249 |
-
bgThumb : attr(WPPath),
|
250 |
-
thumbOrginal : attr(WPPath),
|
251 |
-
// -------------------------------------------------------------------
|
252 |
-
|
253 |
-
// General
|
254 |
-
order : attr('number'),
|
255 |
-
ishide : attr('boolean'),
|
256 |
-
bg : attr(WPPath),
|
257 |
-
duration : attr('number', {defaultValue : 3}),
|
258 |
-
|
259 |
-
fillMode : attr('string', {defaultValue : 'fill'}),
|
260 |
-
thumb : attr(WPPath),
|
261 |
-
info : attr('string'),
|
262 |
-
link : attr('string'),
|
263 |
-
linkTarget : attr('string'),
|
264 |
-
video : attr('string'),
|
265 |
-
bgColor : attr('string'),
|
266 |
-
|
267 |
-
bgv_mp4 : attr('string'),
|
268 |
-
bgv_ogg : attr('string'),
|
269 |
-
bgv_webm : attr('string'),
|
270 |
-
bgv_fillmode : attr('string' , {defaultValue: 'fill'}),
|
271 |
-
|
272 |
-
bgv_loop : attr('boolean', {defaultValue: true}),
|
273 |
-
bgv_mute : attr('boolean', {defaultValue: true}),
|
274 |
-
bgv_autopause : attr('boolean', {defaultValue: false}),
|
275 |
-
|
276 |
-
cssId : attr('string'),
|
277 |
-
cssClass : attr('string'),
|
278 |
-
bgAlt : attr('string'),
|
279 |
-
|
280 |
-
/**
|
281 |
-
* Slide Layers
|
282 |
-
* Object format: layer_ids:[1,2,3,...]
|
283 |
-
*/
|
284 |
-
layers : hasMany('MSPanel.Layer', {key: 'layer_ids'})
|
285 |
-
|
286 |
-
});
|
287 |
-
|
288 |
-
/**
|
289 |
-
* Slide Layer Model
|
290 |
-
*/
|
291 |
-
MSPanel.Layer = Ember.Model.extend({
|
292 |
-
|
293 |
-
/* Internal Options */
|
294 |
-
// -------------------------------------------------------------------
|
295 |
-
id : attr('number'),
|
296 |
-
name : attr('string'),
|
297 |
-
isLocked : attr('boolean' , {defaultValue: false}),
|
298 |
-
isHided : attr('boolean' , {defaultValue: false}),
|
299 |
-
isSoloed : attr('boolean' , {defaultValue: false}),
|
300 |
-
slide : belongsTo('MSPanel.Slide', {key: 'slide'}),
|
301 |
-
styleModel : belongsTo('MSPanel.Style', {key: 'styleModel', embedded:false}),
|
302 |
-
|
303 |
-
showEffect : belongsTo('MSPanel.Effect', {key: 'showEffect', embedded:false} ),
|
304 |
-
showTransform : attr('string' , {defaultValue: ''}), // tranform style
|
305 |
-
showOrigin : attr('string' , {defaultValue: ''}), // transform origin
|
306 |
-
showFade : attr('boolean', {defaultValue: true}),
|
307 |
-
|
308 |
-
hideEffect : belongsTo('MSPanel.Effect', {key: 'hideEffect', embedded:false}),
|
309 |
-
hideTransform : attr('string' , {defaultValue: ''}), // transform style
|
310 |
-
hideOrigin : attr('string' , {defaultValue: ''}),
|
311 |
-
hideFade : attr('boolean', {defaultValue: true}),
|
312 |
-
imgThumb : attr(WPPath),
|
313 |
-
|
314 |
-
stageOffsetX : attr('number', {defaultValue: 0}),
|
315 |
-
stageOffsetY : attr('number', {defaultValue: 0}),
|
316 |
-
|
317 |
-
|
318 |
-
// -------------------------------------------------------------------
|
319 |
-
|
320 |
-
// General
|
321 |
-
order : attr('number'),
|
322 |
-
type : attr('string'), // values: text, video, image, hotspot
|
323 |
-
|
324 |
-
// misc
|
325 |
-
cssClass : attr('string'), // custom css class name
|
326 |
-
cssId : attr('string'), // custom css id
|
327 |
-
title : attr('string'), // title attribute
|
328 |
-
rel : attr('string'), // rel attribute
|
329 |
-
|
330 |
-
// layer content
|
331 |
-
content : attr('string' , {defaultValue : 'Lorem Ipsum'}), // for text, hotspot
|
332 |
-
img : attr(WPPath), // for image and video
|
333 |
-
imgAlt : attr('string'),
|
334 |
-
video : attr('string', {defaultValue: 'http://player.vimeo.com/video/11721242'}), // video iframe path
|
335 |
-
|
336 |
-
align : attr('string', {defaultValue: 'top'}),
|
337 |
-
|
338 |
-
useAction : attr('boolean', {defaultValue: false}),
|
339 |
-
action : attr('string'),
|
340 |
-
toSlide : attr('number'), // gotoSlide action parameter
|
341 |
-
link : attr('string'),
|
342 |
-
linkTarget : attr('string'),
|
343 |
-
|
344 |
-
// Position
|
345 |
-
offsetX : attr('number' , {defaultValue : 0}),
|
346 |
-
offsetY : attr('number' , {defaultValue : 0}),
|
347 |
-
width : attr('number'),
|
348 |
-
height : attr('number'),
|
349 |
-
resize : attr('boolean', {defaultValue : true}),
|
350 |
-
fixed : attr('boolean', {defaultValue : false}),
|
351 |
-
widthlimit : attr('number' , {defaultValue : '0'}),
|
352 |
-
origin : attr('string' , {defaultValue : 'tl'}),
|
353 |
-
|
354 |
-
stayHover : attr('boolean', {defaultValue: true}), // hotspot only
|
355 |
-
|
356 |
-
// layer style class name
|
357 |
-
className : attr('string'),
|
358 |
-
|
359 |
-
// layer parallax effect
|
360 |
-
parallax : attr('string'),
|
361 |
-
|
362 |
-
// Show Effect
|
363 |
-
showDuration : attr('number' , {defaultValue : 1}),
|
364 |
-
showDelay : attr('number' , {defaultValue : 0}),
|
365 |
-
showEase : attr('string' , {defaultValue : 'easeOutQuint'}),
|
366 |
-
showEffFunc : attr('string'), // used by master slider
|
367 |
-
|
368 |
-
// Hide Effect
|
369 |
-
useHide : attr('boolean', {defaultValue : false}),
|
370 |
-
hideDuration : attr('number' , {defaultValue : 1}),
|
371 |
-
hideDelay : attr('number' , {defaultValue : 1}),
|
372 |
-
hideEase : attr('string' , {defaultValue : 'easeOutQuint'}),
|
373 |
-
hideEffFunc : attr('string'), // used by master slider
|
374 |
-
|
375 |
-
// btn layer only
|
376 |
-
btnClass : attr('string', {defaultValue : 'ms-default-btn'})
|
377 |
-
|
378 |
-
//style : attr('string' , {defaultValue: ''}),
|
379 |
-
});
|
380 |
-
|
381 |
-
/**
|
382 |
-
* Layer Styles Model
|
383 |
-
*/
|
384 |
-
MSPanel.Style = Ember.Model.extend({
|
385 |
-
|
386 |
-
/* Internal Options */
|
387 |
-
// -------------------------------------------------------------------
|
388 |
-
id : attr('number'),
|
389 |
-
name : attr('string'),
|
390 |
-
// -------------------------------------------------------------------
|
391 |
-
|
392 |
-
/**
|
393 |
-
* style type
|
394 |
-
* values:
|
395 |
-
* preset, preset style
|
396 |
-
* copy, on copy of preset style used in mspanel
|
397 |
-
* custom, layer custom style
|
398 |
-
*/
|
399 |
-
type : attr('string'),
|
400 |
-
|
401 |
-
/**
|
402 |
-
* style class name
|
403 |
-
* format:
|
404 |
-
* preset-> msp-preset-{{presetID}}
|
405 |
-
* custom-> msp-cn-{{sliderID}}-{{layer-ID}}
|
406 |
-
*/
|
407 |
-
className : attr('string'),
|
408 |
-
//css : attr('string'),
|
409 |
-
|
410 |
-
backgroundColor : attr('string'),
|
411 |
-
|
412 |
-
// padding
|
413 |
-
paddingTop : attr('number'),
|
414 |
-
paddingRight : attr('number'),
|
415 |
-
paddingBottom : attr('number'),
|
416 |
-
paddingLeft : attr('number'),
|
417 |
-
|
418 |
-
// border
|
419 |
-
borderTop : attr('number'),
|
420 |
-
borderRight : attr('number'),
|
421 |
-
borderBottom : attr('number'),
|
422 |
-
borderLeft : attr('number'),
|
423 |
-
|
424 |
-
borderColor : attr('string'),
|
425 |
-
borderRadius : attr('number'),
|
426 |
-
borderStyle : attr('string'),
|
427 |
-
|
428 |
-
//Typography
|
429 |
-
fontFamily : attr('string'),
|
430 |
-
fontWeight : attr('string' , {defaultValue: 'normal'}),
|
431 |
-
fontSize : attr('number'),
|
432 |
-
|
433 |
-
textAlign : attr('string'),
|
434 |
-
letterSpacing : attr('number'),
|
435 |
-
lineHeight : attr('string' , {defaultValue: 'normal'}),
|
436 |
-
whiteSpace : attr('string'),
|
437 |
-
color : attr('string'),
|
438 |
-
|
439 |
-
// custom style
|
440 |
-
custom : attr('string')
|
441 |
-
});
|
442 |
-
|
443 |
-
MSPanel.PresetStyle = MSPanel.Style.extend({});
|
444 |
-
|
445 |
-
/**
|
446 |
-
* Layer Effect Model
|
447 |
-
*/
|
448 |
-
MSPanel.Effect = Ember.Model.extend({
|
449 |
-
|
450 |
-
/* Internal Options */
|
451 |
-
// -------------------------------------------------------------------
|
452 |
-
id : attr('number'),
|
453 |
-
name : attr('string'),
|
454 |
-
// -------------------------------------------------------------------
|
455 |
-
|
456 |
-
type : attr('string'), // preset or null
|
457 |
-
|
458 |
-
fade : attr('boolean', {defaultValue: true}),
|
459 |
-
|
460 |
-
translateX : attr('number'),
|
461 |
-
translateY : attr('number'),
|
462 |
-
translateZ : attr('number'),
|
463 |
-
|
464 |
-
scaleX : attr('number'),
|
465 |
-
scaleY : attr('number'),
|
466 |
-
|
467 |
-
rotate : attr('number'),
|
468 |
-
rotateX : attr('number'),
|
469 |
-
rotateY : attr('number'),
|
470 |
-
rotateZ : attr('number'),
|
471 |
-
|
472 |
-
skewX : attr('number'),
|
473 |
-
skewY : attr('number'),
|
474 |
-
|
475 |
-
originX : attr('number'),
|
476 |
-
originY : attr('number'),
|
477 |
-
originZ : attr('number')
|
478 |
-
|
479 |
-
// effect function for master slider
|
480 |
-
//msEffect : attr('string'),
|
481 |
-
|
482 |
-
});
|
483 |
-
|
484 |
-
MSPanel.PresetEffect = MSPanel.Effect.extend({});
|
485 |
-
|
486 |
-
/**
|
487 |
-
* Slider control model
|
488 |
-
*/
|
489 |
-
MSPanel.Control = Ember.Model.extend({
|
490 |
-
|
491 |
-
/* Internal Options */
|
492 |
-
// -------------------------------------------------------------------
|
493 |
-
id : attr('number'),
|
494 |
-
label : attr('string'),
|
495 |
-
// -------------------------------------------------------------------
|
496 |
-
|
497 |
-
// general
|
498 |
-
name : attr('string'),
|
499 |
-
|
500 |
-
autoHide : attr('boolean', {defaultValue: true}), // in JS autohide
|
501 |
-
overVideo : attr('boolean', {defaultValue: true}),
|
502 |
-
|
503 |
-
// misc
|
504 |
-
cssClass : attr('string'),
|
505 |
-
cssId : attr('string'),
|
506 |
-
|
507 |
-
// align and margin
|
508 |
-
//align : attr('string'), // values : t, r, b, l \ tl,tr,bl,br (for circle timer)
|
509 |
-
//inset : attr('boolean'), // in slider or out of slider
|
510 |
-
margin : attr('number'), // element margin from top ,...
|
511 |
-
|
512 |
-
// used for bullets, scrollbar and thumbs/tabs
|
513 |
-
dir : attr('string'), // h or v
|
514 |
-
|
515 |
-
// circle timer options
|
516 |
-
color : attr('string'), // also scrollbar | timebar
|
517 |
-
radius : attr('number'),
|
518 |
-
stroke : attr('number'),
|
519 |
-
|
520 |
-
// thumbs/tabs
|
521 |
-
speed : attr('number'),
|
522 |
-
space : attr('number'),
|
523 |
-
type : attr('string'), // tab or thumb
|
524 |
-
|
525 |
-
width : attr('number'), /// thumblist | scrollbar | timebar
|
526 |
-
height : attr('number'), // thumbelist
|
527 |
-
|
528 |
-
align : attr('string'), // thumblist | scrollbar | bullets | timebar | slideinfo
|
529 |
-
inset : attr('boolean'), // thumblist | scrollbar | timebar | slideinfo
|
530 |
-
|
531 |
-
size : attr('number'), // slide info
|
532 |
-
|
533 |
-
hideUnder : attr('number'),
|
534 |
-
|
535 |
-
fillMode : attr('string')
|
536 |
-
|
537 |
-
});
|
538 |
-
|
539 |
-
/**
|
540 |
-
* Slider Callback functions
|
541 |
-
*/
|
542 |
-
MSPanel.Callback = Ember.Model.extend({
|
543 |
-
|
544 |
-
/* Internal Options */
|
545 |
-
// -------------------------------------------------------------------
|
546 |
-
id : attr('number'),
|
547 |
-
label : attr('string'),
|
548 |
-
// -------------------------------------------------------------------
|
549 |
-
|
550 |
-
name : attr('string'),
|
551 |
-
content : attr('string', {defaultValue: 'function(event){\n var api = event.target;\n}'})
|
552 |
-
|
553 |
-
});
|
554 |
-
|
555 |
-
/**
|
556 |
-
* Button Class Names
|
557 |
-
* @since 1.9.0
|
558 |
-
*/
|
559 |
-
|
560 |
-
MSPanel.ButtonStyle = Ember.Model.extend({
|
561 |
-
|
562 |
-
/* Internal Options */
|
563 |
-
// -------------------------------------------------------------
|
564 |
-
id : attr('number'),
|
565 |
-
// -------------------------------------------------------------
|
566 |
-
|
567 |
-
className : attr('string'),
|
568 |
-
normal : attr('string'),
|
569 |
-
hover : attr('string'),
|
570 |
-
active : attr('string')
|
571 |
-
|
572 |
-
});
|
573 |
-
|
574 |
-
|
575 |
-
var decodeFix = function(str){
|
576 |
-
var decoded = B64.decode(str);
|
577 |
-
return decoded.slice(0, decoded.lastIndexOf('}')+1);
|
578 |
-
}
|
579 |
-
|
580 |
-
window.__MSP_PRESET_BUTTON = null;
|
581 |
-
|
582 |
-
MSPanel.data = __MSP_DATA ? JSON.parse(decodeFix(__MSP_DATA)) : {meta:{}};
|
583 |
-
MSPanel.PSData = __MSP_PRESET_STYLE ? JSON.parse(decodeFix(__MSP_PRESET_STYLE)) : {meta:{}};
|
584 |
-
MSPanel.PEData = __MSP_PRESET_EFFECT ? JSON.parse(decodeFix(__MSP_PRESET_EFFECT)) : {meta:{}};
|
585 |
-
MSPanel.PBData = __MSP_PRESET_BUTTON ? JSON.parse(decodeFix(__MSP_PRESET_BUTTON)) : {meta:{}};
|
586 |
-
|
587 |
-
MSPanel.Settings.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.data});
|
588 |
-
MSPanel.Slide.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.data});
|
589 |
-
MSPanel.Layer.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.data});
|
590 |
-
MSPanel.Style.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.data});
|
591 |
-
MSPanel.Effect.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.data});
|
592 |
-
MSPanel.Control.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.data});
|
593 |
-
MSPanel.Callback.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.data});
|
594 |
-
MSPanel.PresetStyle.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.PSData});
|
595 |
-
MSPanel.PresetEffect.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.PEData});
|
596 |
-
MSPanel.ButtonStyle.adapter = Ember.OfflineAdapter.create({applicationData:MSPanel.PBData});
|
597 |
-
|
598 |
-
})();//js\mspanel\models\SliderTemplates.js
|
599 |
-
|
600 |
-
MSPanel.SliderTemplates = [
|
601 |
-
|
602 |
-
{
|
603 |
-
name:'Custom Template',
|
604 |
-
value:'custom',
|
605 |
-
className: '',
|
606 |
-
img: __MSP_PATH + 'images/templates/custom.gif',
|
607 |
-
controls: null
|
608 |
-
},
|
609 |
-
|
610 |
-
{
|
611 |
-
name:'3D Flow Carousel',
|
612 |
-
value:'3d-flow-carousel',
|
613 |
-
className:'ms-caro3d-template',
|
614 |
-
img: __MSP_PATH + 'images/templates/3d-flow-carousel.png',
|
615 |
-
settings: {
|
616 |
-
space:0,
|
617 |
-
loop:true,
|
618 |
-
trView:'flow',
|
619 |
-
layout:'partialview',
|
620 |
-
dir:'h',
|
621 |
-
wheel:false
|
622 |
-
},
|
623 |
-
controls: null
|
624 |
-
},
|
625 |
-
|
626 |
-
{
|
627 |
-
name:'3D Wave Carousel',
|
628 |
-
value:'3d-wave-carousel',
|
629 |
-
className:'ms-caro3d-template',
|
630 |
-
img: __MSP_PATH + 'images/templates/3d-wave-carousel.png',
|
631 |
-
settings: {
|
632 |
-
space:0,
|
633 |
-
loop:true,
|
634 |
-
trView:'flow',
|
635 |
-
layout:'partialview',
|
636 |
-
dir:'h',
|
637 |
-
wheel:false
|
638 |
-
},
|
639 |
-
controls: null
|
640 |
-
},
|
641 |
-
|
642 |
-
{
|
643 |
-
name:'Image Gallery with Thumbs',
|
644 |
-
value:'image-gallery',
|
645 |
-
className:'ms-gallery-template',
|
646 |
-
img: __MSP_PATH + 'images/templates/image-gallery.png',
|
647 |
-
settings: {
|
648 |
-
space:0,
|
649 |
-
trView:'basic',
|
650 |
-
skin:'ms-skin-black-2 round-skin'
|
651 |
-
},
|
652 |
-
controls: null,
|
653 |
-
disableControls: true
|
654 |
-
},
|
655 |
-
|
656 |
-
{
|
657 |
-
name:'Slider with Bottom Aligned Thumbs',
|
658 |
-
value:'slider-horizontal-thumbs',
|
659 |
-
className:'ms-thumbs-template',
|
660 |
-
img: __MSP_PATH + 'images/templates/slider-bottom-thumbs.png',
|
661 |
-
settings: {
|
662 |
-
trView:'scale',
|
663 |
-
space:0
|
664 |
-
},
|
665 |
-
controls: {
|
666 |
-
arrows: {},
|
667 |
-
scrollbar: {dir:'h'},
|
668 |
-
thumblist: {autohide:false ,dir:'h',arrows:false, align:'bottom', width:127, height:137, margin:5, space:5}
|
669 |
-
}
|
670 |
-
},
|
671 |
-
|
672 |
-
{
|
673 |
-
name:'Slider with Top Aligned Thumbs',
|
674 |
-
value:'slider-top-thumbs',
|
675 |
-
className:'ms-thumbs-template',
|
676 |
-
img: __MSP_PATH + 'images/templates/slider-top-thumbs.png',
|
677 |
-
settings: {
|
678 |
-
trView:'scale',
|
679 |
-
space:0
|
680 |
-
},
|
681 |
-
controls: {
|
682 |
-
arrows: {},
|
683 |
-
scrollbar: {dir:'h'},
|
684 |
-
thumblist: {autohide:false ,dir:'h',arrows:false, align:'top', width:127, height:137, margin:5, space:5}
|
685 |
-
}
|
686 |
-
},
|
687 |
-
|
688 |
-
{
|
689 |
-
name:'Slider with Right Aligned Thumbs',
|
690 |
-
value:'slider-vertical-thumbs',
|
691 |
-
className:'ms-thumbs-template',
|
692 |
-
img: __MSP_PATH + 'images/templates/slider-right-thumbs.png',
|
693 |
-
settings: null,
|
694 |
-
controls: {
|
695 |
-
arrows: {},
|
696 |
-
scrollbar: {dir:'v'},
|
697 |
-
thumblist: {autohide:false ,dir:'v',arrows:false, align:'right', width:127, height:137, margin:5, space:5}
|
698 |
-
}
|
699 |
-
},
|
700 |
-
|
701 |
-
{
|
702 |
-
name:'Slider with Left Aligned Thumbs',
|
703 |
-
value:'slider-left-thumbs',
|
704 |
-
className:'ms-thumbs-template',
|
705 |
-
img: __MSP_PATH + 'images/templates/slider-left-thumbs.png',
|
706 |
-
settings: null,
|
707 |
-
controls: {
|
708 |
-
arrows: {},
|
709 |
-
scrollbar: {dir:'v'},
|
710 |
-
thumblist: {autohide:false ,dir:'v',arrows:false, align:'left', width:127, height:137, margin:5, space:5}
|
711 |
-
}
|
712 |
-
},
|
713 |
-
|
714 |
-
{
|
715 |
-
name:'Slider with Horizontal Tabs',
|
716 |
-
value:'slider-horizontal-tabs',
|
717 |
-
className:'ms-tabs-template',
|
718 |
-
img: __MSP_PATH + 'images/templates/slider-horizontal-tabs.png',
|
719 |
-
settings: null,
|
720 |
-
controls: {
|
721 |
-
arrows: {},
|
722 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
723 |
-
thumblist: {autohide:false ,dir:'h', type:'tabs',width:240,height:120, align:'bottom', space:0 , margin:-12, hideUnder:400}
|
724 |
-
}
|
725 |
-
},
|
726 |
-
|
727 |
-
{
|
728 |
-
name:'Slider with Vertical Tabs',
|
729 |
-
value:'slider-vertical-tabs',
|
730 |
-
className:'ms-tabs-template',
|
731 |
-
img: __MSP_PATH + 'images/templates/slider-vertical-tabs.png',
|
732 |
-
settings: null,
|
733 |
-
controls: {
|
734 |
-
arrows: {},
|
735 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
736 |
-
thumblist: {autohide:false ,dir:'v', type:'tabs', align:'right', margin:-12, space:0, width:229, height:100, hideUnder:550}
|
737 |
-
}
|
738 |
-
},
|
739 |
-
|
740 |
-
{
|
741 |
-
name:'Partial View Slider V1',
|
742 |
-
value:'partial-1',
|
743 |
-
className:'ms-partialview-template',
|
744 |
-
img: __MSP_PATH + 'images/templates/partial-1.png',
|
745 |
-
settings: {
|
746 |
-
space:10,
|
747 |
-
loop:true,
|
748 |
-
trView:'partialWave',
|
749 |
-
layout:'partialview',
|
750 |
-
dir:'h'
|
751 |
-
},
|
752 |
-
controls: {
|
753 |
-
arrows: {},
|
754 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
755 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
756 |
-
}
|
757 |
-
},
|
758 |
-
|
759 |
-
{
|
760 |
-
name:'Partial View Slider V2',
|
761 |
-
value:'partial-2',
|
762 |
-
className:'ms-partialview-template',
|
763 |
-
img: __MSP_PATH + 'images/templates/partial-2.png',
|
764 |
-
settings: {
|
765 |
-
space:10,
|
766 |
-
loop:true,
|
767 |
-
trView:'fadeWave',
|
768 |
-
layout:'partialview',
|
769 |
-
dir:'h'
|
770 |
-
},
|
771 |
-
controls: {
|
772 |
-
arrows: {},
|
773 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
774 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
775 |
-
}
|
776 |
-
},
|
777 |
-
|
778 |
-
{
|
779 |
-
name:'Partial View Slider V3',
|
780 |
-
value:'partial-3',
|
781 |
-
className:'ms-partialview-template',
|
782 |
-
img: __MSP_PATH + 'images/templates/partial-3.png',
|
783 |
-
settings: {
|
784 |
-
space:10,
|
785 |
-
loop:true,
|
786 |
-
trView:'fadeFlow',
|
787 |
-
layout:'partialview',
|
788 |
-
dir:'h'
|
789 |
-
},
|
790 |
-
controls: {
|
791 |
-
arrows: {},
|
792 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
793 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
794 |
-
}
|
795 |
-
},
|
796 |
-
|
797 |
-
{
|
798 |
-
name:'Slider in Display',
|
799 |
-
value:'display',
|
800 |
-
className:'ms-display-template',
|
801 |
-
img: __MSP_PATH + 'images/templates/display.png',
|
802 |
-
settings: {
|
803 |
-
width:507,
|
804 |
-
height:286,
|
805 |
-
speed:20,
|
806 |
-
space:2,
|
807 |
-
trView:'flow',
|
808 |
-
dir:'h',
|
809 |
-
layout:'boxed'
|
810 |
-
},
|
811 |
-
controls: {
|
812 |
-
arrows: {},
|
813 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
814 |
-
bullets: {autohide:false}
|
815 |
-
},
|
816 |
-
disableControls: true
|
817 |
-
},
|
818 |
-
|
819 |
-
{
|
820 |
-
name:'Slider in Flat Display',
|
821 |
-
value:'flat-display',
|
822 |
-
className:'ms-display-template',
|
823 |
-
img: __MSP_PATH + 'images/templates/flat-display.png',
|
824 |
-
settings: {
|
825 |
-
width:507,
|
826 |
-
height:286,
|
827 |
-
speed:20,
|
828 |
-
space:2,
|
829 |
-
trView:'flow',
|
830 |
-
dir:'h',
|
831 |
-
layout:'boxed'
|
832 |
-
},
|
833 |
-
controls: {
|
834 |
-
arrows: {},
|
835 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
836 |
-
bullets: {autohide:false}
|
837 |
-
},
|
838 |
-
disableControls: true
|
839 |
-
},
|
840 |
-
|
841 |
-
{
|
842 |
-
name:'Slider in Laptop',
|
843 |
-
value:'laptop',
|
844 |
-
className:'ms-laptop-template',
|
845 |
-
img: __MSP_PATH + 'images/templates/laptop.png',
|
846 |
-
settings: {
|
847 |
-
width:492,
|
848 |
-
height:309,
|
849 |
-
speed:20,
|
850 |
-
space:2,
|
851 |
-
trView:'mask',
|
852 |
-
dir:'h',
|
853 |
-
layout:'boxed'
|
854 |
-
},
|
855 |
-
controls: {
|
856 |
-
arrows: {},
|
857 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
858 |
-
bullets: {autohide:false}
|
859 |
-
},
|
860 |
-
disableControls: true
|
861 |
-
},
|
862 |
-
|
863 |
-
{
|
864 |
-
name:'Slider in Flat Laptop',
|
865 |
-
value:'flat-laptop',
|
866 |
-
className:'ms-laptop-template',
|
867 |
-
img: __MSP_PATH + 'images/templates/flat-laptop.png',
|
868 |
-
settings: {
|
869 |
-
width:492,
|
870 |
-
height:309,
|
871 |
-
speed:20,
|
872 |
-
space:2,
|
873 |
-
trView:'mask',
|
874 |
-
dir:'h',
|
875 |
-
layout:'boxed'
|
876 |
-
},
|
877 |
-
controls: {
|
878 |
-
arrows: {},
|
879 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
880 |
-
bullets: {autohide:false}
|
881 |
-
},
|
882 |
-
disableControls: true
|
883 |
-
},
|
884 |
-
|
885 |
-
{
|
886 |
-
name:'Slider in Tablet',
|
887 |
-
value:'tablet',
|
888 |
-
className:'ms-tablet-template',
|
889 |
-
img: __MSP_PATH + 'images/templates/tablet.png',
|
890 |
-
settings: {
|
891 |
-
width:400,
|
892 |
-
height:534,
|
893 |
-
speed:20,
|
894 |
-
space:2,
|
895 |
-
trView:'wave',
|
896 |
-
dir:'h',
|
897 |
-
layout:'boxed'
|
898 |
-
},
|
899 |
-
controls: {
|
900 |
-
arrows: {},
|
901 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
902 |
-
bullets: {autohide:false}
|
903 |
-
},
|
904 |
-
disableControls: true
|
905 |
-
},
|
906 |
-
|
907 |
-
{
|
908 |
-
name:'Slider in Flat Tablet',
|
909 |
-
value:'flat-tablet',
|
910 |
-
className:'ms-tablet-template',
|
911 |
-
img: __MSP_PATH + 'images/templates/flat-tablet.png',
|
912 |
-
settings: {
|
913 |
-
width:400,
|
914 |
-
height:534,
|
915 |
-
speed:20,
|
916 |
-
space:2,
|
917 |
-
trView:'basic',
|
918 |
-
dir:'h',
|
919 |
-
layout:'boxed'
|
920 |
-
},
|
921 |
-
controls: {
|
922 |
-
arrows: {},
|
923 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
924 |
-
bullets: {autohide:false}
|
925 |
-
},
|
926 |
-
disableControls: true
|
927 |
-
},
|
928 |
-
|
929 |
-
{
|
930 |
-
name:'Slider in Landscape Tablet',
|
931 |
-
value:'tablet-land',
|
932 |
-
className:'ms-tablet-template ms-tablet-land',
|
933 |
-
img: __MSP_PATH + 'images/templates/tablet-land.png',
|
934 |
-
settings: {
|
935 |
-
width:632,
|
936 |
-
height:476,
|
937 |
-
speed:20,
|
938 |
-
space:2,
|
939 |
-
trView:'mask',
|
940 |
-
dir:'h',
|
941 |
-
layout:'boxed'
|
942 |
-
},
|
943 |
-
controls: {
|
944 |
-
arrows: {},
|
945 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
946 |
-
bullets: {autohide:false}
|
947 |
-
},
|
948 |
-
disableControls: true
|
949 |
-
},
|
950 |
-
|
951 |
-
{
|
952 |
-
name:'Slider in Flat Landscape Tablet',
|
953 |
-
value:'flat-tablet-land',
|
954 |
-
className:'ms-tablet-template ms-tablet-land',
|
955 |
-
img: __MSP_PATH + 'images/templates/flat-tablet-land.png',
|
956 |
-
settings: {
|
957 |
-
width:632,
|
958 |
-
height:476,
|
959 |
-
speed:20,
|
960 |
-
space:2,
|
961 |
-
trView:'mask',
|
962 |
-
dir:'h',
|
963 |
-
layout:'boxed'
|
964 |
-
},
|
965 |
-
controls: {
|
966 |
-
arrows: {},
|
967 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
968 |
-
bullets: {autohide:false}
|
969 |
-
},
|
970 |
-
disableControls: true
|
971 |
-
},
|
972 |
-
|
973 |
-
{
|
974 |
-
name:'Slider in Smart Phone',
|
975 |
-
value:'phone',
|
976 |
-
className:'ms-phone-template',
|
977 |
-
img: __MSP_PATH + 'images/templates/phone.png',
|
978 |
-
settings: {
|
979 |
-
width:258,
|
980 |
-
height:456,
|
981 |
-
speed:20,
|
982 |
-
space:2,
|
983 |
-
trView:'wave',
|
984 |
-
dir:'h',
|
985 |
-
layout:'boxed'
|
986 |
-
},
|
987 |
-
controls: {
|
988 |
-
arrows: {},
|
989 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
990 |
-
bullets: {autohide:false}
|
991 |
-
},
|
992 |
-
disableControls: true
|
993 |
-
},
|
994 |
-
|
995 |
-
{
|
996 |
-
name:'Slider in Flat Smart Phone',
|
997 |
-
value:'flat-phone',
|
998 |
-
className:'ms-phone-template',
|
999 |
-
img: __MSP_PATH + 'images/templates/flat-phone.png',
|
1000 |
-
settings: {
|
1001 |
-
width:258,
|
1002 |
-
height:456,
|
1003 |
-
speed:20,
|
1004 |
-
space:2,
|
1005 |
-
trView:'basic',
|
1006 |
-
dir:'h',
|
1007 |
-
layout:'boxed'
|
1008 |
-
},
|
1009 |
-
controls: {
|
1010 |
-
arrows: {},
|
1011 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
1012 |
-
bullets: {autohide:false}
|
1013 |
-
},
|
1014 |
-
disableControls: true
|
1015 |
-
},
|
1016 |
-
|
1017 |
-
{
|
1018 |
-
name:'Slider in Landscape Smart Phone',
|
1019 |
-
value:'phone-land',
|
1020 |
-
className:'ms-phone-template ms-phone-land',
|
1021 |
-
img: __MSP_PATH + 'images/templates/phone-land.png',
|
1022 |
-
settings: {
|
1023 |
-
width:456,
|
1024 |
-
height:258,
|
1025 |
-
speed:20,
|
1026 |
-
space:2,
|
1027 |
-
trView:'mask',
|
1028 |
-
dir:'h',
|
1029 |
-
layout:'boxed'
|
1030 |
-
},
|
1031 |
-
controls: {
|
1032 |
-
arrows: {},
|
1033 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
1034 |
-
bullets: {autohide:false}
|
1035 |
-
},
|
1036 |
-
disableControls: true
|
1037 |
-
},
|
1038 |
-
|
1039 |
-
{
|
1040 |
-
name:'Slider in Flat Landscape Smart Phone',
|
1041 |
-
value:'flat-phone-land',
|
1042 |
-
className:'ms-phone-template ms-phone-land',
|
1043 |
-
img: __MSP_PATH + 'images/templates/flat-phone-land.png',
|
1044 |
-
settings: {
|
1045 |
-
width:456,
|
1046 |
-
height:258,
|
1047 |
-
speed:20,
|
1048 |
-
space:2,
|
1049 |
-
trView:'mask',
|
1050 |
-
dir:'h',
|
1051 |
-
layout:'boxed'
|
1052 |
-
},
|
1053 |
-
controls: {
|
1054 |
-
arrows: {},
|
1055 |
-
bullets: {autohide:false}
|
1056 |
-
},
|
1057 |
-
disableControls: true
|
1058 |
-
},
|
1059 |
-
|
1060 |
-
{
|
1061 |
-
name:'Vertical Slider',
|
1062 |
-
value:'vertical-slider',
|
1063 |
-
className:'ms-vertical-template',
|
1064 |
-
img: __MSP_PATH + 'images/templates/vertical-slider.png',
|
1065 |
-
settings: {
|
1066 |
-
space:5,
|
1067 |
-
dir:'v'
|
1068 |
-
},
|
1069 |
-
controls: {
|
1070 |
-
arrows: {},
|
1071 |
-
scrollbar: {dir:'v'},
|
1072 |
-
circletimer: {color:"#FFFFFF" , stroke:9},
|
1073 |
-
thumblist : {autohide:false ,dir:'v',space:5,margin:5,align:'right'}
|
1074 |
-
}
|
1075 |
-
},
|
1076 |
-
|
1077 |
-
{
|
1078 |
-
name:'Staff Carousel V1',
|
1079 |
-
value:'staff-1',
|
1080 |
-
className:'ms-staff-carousel',
|
1081 |
-
img: __MSP_PATH + 'images/templates/staff-1.png',
|
1082 |
-
settings: {
|
1083 |
-
loop:true,
|
1084 |
-
width:240,
|
1085 |
-
height:240,
|
1086 |
-
speed:20,
|
1087 |
-
trView:'focus',
|
1088 |
-
layout:'partialview',
|
1089 |
-
space:0,
|
1090 |
-
wheel:true,
|
1091 |
-
dir:'h'
|
1092 |
-
},
|
1093 |
-
controls: {
|
1094 |
-
arrows: {},
|
1095 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
1096 |
-
}
|
1097 |
-
},
|
1098 |
-
|
1099 |
-
{
|
1100 |
-
name:'Staff Carousel V2',
|
1101 |
-
value:'staff-2',
|
1102 |
-
className:'ms-staff-carousel',
|
1103 |
-
img: __MSP_PATH + 'images/templates/staff-2.png',
|
1104 |
-
settings: {
|
1105 |
-
loop:true,
|
1106 |
-
width:240,
|
1107 |
-
height:240,
|
1108 |
-
speed:20,
|
1109 |
-
trView:'fadeBasic',
|
1110 |
-
layout:'partialview',
|
1111 |
-
space:0,
|
1112 |
-
dir:'h'
|
1113 |
-
},
|
1114 |
-
controls: {
|
1115 |
-
arrows: {},
|
1116 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
1117 |
-
}
|
1118 |
-
},
|
1119 |
-
|
1120 |
-
{
|
1121 |
-
name:'Staff Carousel V3',
|
1122 |
-
value:'staff-3',
|
1123 |
-
className:'ms-staff-carousel ms-round',
|
1124 |
-
img: __MSP_PATH + 'images/templates/staff-3.png',
|
1125 |
-
settings: {
|
1126 |
-
loop:true,
|
1127 |
-
width:240,
|
1128 |
-
height:240,
|
1129 |
-
speed:20,
|
1130 |
-
trView:'focus',
|
1131 |
-
layout:'partialview',
|
1132 |
-
space:0,
|
1133 |
-
space:35,
|
1134 |
-
dir:'h'
|
1135 |
-
},
|
1136 |
-
controls: {
|
1137 |
-
arrows: {},
|
1138 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
1139 |
-
}
|
1140 |
-
},
|
1141 |
-
|
1142 |
-
{
|
1143 |
-
name:'Staff Carousel V4',
|
1144 |
-
value:'staff-4',
|
1145 |
-
className:'ms-staff-carousel ms-round',
|
1146 |
-
img: __MSP_PATH + 'images/templates/staff-4.png',
|
1147 |
-
settings: {
|
1148 |
-
loop:true,
|
1149 |
-
width:240,
|
1150 |
-
height:240,
|
1151 |
-
speed:20,
|
1152 |
-
trView:'fadeBasic',
|
1153 |
-
layout:'partialview',
|
1154 |
-
space:0,
|
1155 |
-
space:45,
|
1156 |
-
dir:'h'
|
1157 |
-
},
|
1158 |
-
controls: {
|
1159 |
-
arrows: {},
|
1160 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
1161 |
-
}
|
1162 |
-
},
|
1163 |
-
|
1164 |
-
{
|
1165 |
-
name:'Staff Carousel V5',
|
1166 |
-
value:'staff-5',
|
1167 |
-
className:'ms-staff-carousel',
|
1168 |
-
img: __MSP_PATH + 'images/templates/staff-5.png',
|
1169 |
-
settings: {
|
1170 |
-
loop:true,
|
1171 |
-
width:240,
|
1172 |
-
height:240,
|
1173 |
-
speed:20,
|
1174 |
-
trView:'wave',
|
1175 |
-
layout:'partialview',
|
1176 |
-
space:0,
|
1177 |
-
wheel:true,
|
1178 |
-
dir:'h'
|
1179 |
-
},
|
1180 |
-
controls: {
|
1181 |
-
arrows: {},
|
1182 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
1183 |
-
}
|
1184 |
-
},
|
1185 |
-
|
1186 |
-
{
|
1187 |
-
name:'Staff Carousel V6',
|
1188 |
-
value:'staff-6',
|
1189 |
-
className:'ms-staff-carousel',
|
1190 |
-
img: __MSP_PATH + 'images/templates/staff-6.png',
|
1191 |
-
settings: {
|
1192 |
-
loop:true,
|
1193 |
-
width:240,
|
1194 |
-
height:240,
|
1195 |
-
speed:20,
|
1196 |
-
trView:'flow',
|
1197 |
-
layout:'partialview',
|
1198 |
-
space:0,
|
1199 |
-
wheel:true,
|
1200 |
-
dir:'h'
|
1201 |
-
},
|
1202 |
-
controls: {
|
1203 |
-
arrows: {},
|
1204 |
-
slideinfo: {autohide:false, align:'bottom', size:160}
|
1205 |
-
}
|
1206 |
-
},
|
1207 |
-
];
|
1208 |
-
//js\mspanel\views\UIViews.js
|
1209 |
-
|
1210 |
-
/* ---------------------------------------------------------
|
1211 |
-
Slideframe
|
1212 |
-
------------------------------------------------------------*/
|
1213 |
-
MSPanel.SlideFrame = Ember.View.extend({
|
1214 |
-
classNames : ['msp-slideframe'],
|
1215 |
-
classNameBindings: ['selected:active'],
|
1216 |
-
selected : false,
|
1217 |
-
thumb_src : '',
|
1218 |
-
showbtnclass : 'msp-ico msp-ico-whitehide',
|
1219 |
-
|
1220 |
-
template : Ember.Handlebars.compile('<div class="msp-img-cont">'+
|
1221 |
-
'{{#if view.hasImg}}'+
|
1222 |
-
'<div class="msp-imgselect-preview" {{bind-attr style=view.preview}})"></div>'+
|
1223 |
-
'{{/if}}'+
|
1224 |
-
'</div>'+
|
1225 |
-
'<span class="msp-frame-slideorder">#{{view.order}}</span>'+
|
1226 |
-
'<div class="msp-framehandle">'+
|
1227 |
-
'<ul>'+
|
1228 |
-
'<li><a title="'+__MSP_LAN.ui_001+'" href="#" {{action "hideswitch" target=view}}><span {{bind-attr class=view.showbtnclass}}></span></a></li>'+
|
1229 |
-
'<li><a title="'+__MSP_LAN.ui_002+'" href="#" {{action "duplicate" target=view}}><span class="msp-ico msp-ico-whiteduplicate"></span></a></li>'+
|
1230 |
-
'<li><a title="'+__MSP_LAN.ui_003+'" href="#" {{action "remove" target=view}}><span class="msp-ico msp-ico-whiteremove"></span></a></li>'+
|
1231 |
-
'</ul>'+
|
1232 |
-
'</div>'),
|
1233 |
-
|
1234 |
-
click : function(event){
|
1235 |
-
this.get('controller').send('select' , this.get('slide'));
|
1236 |
-
},
|
1237 |
-
|
1238 |
-
onValueChanged: function(){
|
1239 |
-
var hasImg = !Ember.isEmpty(this.get('slide.bg'));
|
1240 |
-
this.beginPropertyChanges();
|
1241 |
-
this.set('hasImg' ,hasImg);
|
1242 |
-
if(hasImg){
|
1243 |
-
this.set('preview', 'background-image:url(' + this.get('slide.bgThumb') + ');');
|
1244 |
-
}
|
1245 |
-
this.endPropertyChanges();
|
1246 |
-
}.observes('slide.bg').on('didInsertElement'),
|
1247 |
-
|
1248 |
-
onSelect : function(){
|
1249 |
-
var slide = this.get('slide');
|
1250 |
-
|
1251 |
-
this.set('selected' , slide === this.get('controller.currentSlide'));
|
1252 |
-
|
1253 |
-
}.observes('controller.currentSlide').on('init'),
|
1254 |
-
|
1255 |
-
hideChange : function(){
|
1256 |
-
if(this.get('slide.ishide'))
|
1257 |
-
this.set('showbtnclass' , 'msp-ico msp-ico-whitehide msp-ico-whiteshow');
|
1258 |
-
else
|
1259 |
-
this.set('showbtnclass' , 'msp-ico msp-ico-whitehide');
|
1260 |
-
|
1261 |
-
}.observes('slide.ishide').on('init'),
|
1262 |
-
|
1263 |
-
order: function(){
|
1264 |
-
return this.get('slide.order') + 1;
|
1265 |
-
}.property('slide.order'),
|
1266 |
-
|
1267 |
-
actions : {
|
1268 |
-
duplicate : function(){
|
1269 |
-
this.get('controller').duplicateSlide(this.get('slide'));
|
1270 |
-
},
|
1271 |
-
|
1272 |
-
hideswitch : function(){
|
1273 |
-
this.set('slide.ishide' , !this.get('slide.ishide'));
|
1274 |
-
},
|
1275 |
-
|
1276 |
-
remove : function(){
|
1277 |
-
if(confirm(__MSP_LAN.ui_004))
|
1278 |
-
this.get('controller').removeSlide(this.get('slide'));
|
1279 |
-
}
|
1280 |
-
}
|
1281 |
-
});
|
1282 |
-
|
1283 |
-
/* ---------------------------------------------------------
|
1284 |
-
SlideList
|
1285 |
-
------------------------------------------------------------*/
|
1286 |
-
MSPanel.SlideList = Ember.View.extend({
|
1287 |
-
tagName : 'ul',
|
1288 |
-
classNames : ['msp-slides'],
|
1289 |
-
|
1290 |
-
template : Ember.Handlebars.compile(
|
1291 |
-
'{{#each item in controller}}'+
|
1292 |
-
'<li class="msp-slideframe-item" {{bind-attr data-id=item.id}}>{{view MSPanel.SlideFrame slide=item}}</li>'+
|
1293 |
-
'{{/each}}'+
|
1294 |
-
'<li class="msp-addslide-cont">'+
|
1295 |
-
'<div class="msp-addslide" {{action "newSlide"}}>'+
|
1296 |
-
'<span class="msp-ico msp-ico-grayaddlarge"></span>'+
|
1297 |
-
'<span class="msp-addslide-label">Add Slide</span>'+
|
1298 |
-
'</div>'+
|
1299 |
-
'</li>'),
|
1300 |
-
|
1301 |
-
didInsertElement : function(){
|
1302 |
-
|
1303 |
-
var that = this;
|
1304 |
-
|
1305 |
-
this.$().sortable({
|
1306 |
-
placeholder: "msp-frames-srtplaceholder",
|
1307 |
-
items: ">li:not(.msp-addslide-cont)",
|
1308 |
-
delay: 100,
|
1309 |
-
update : function(event , ui){that.updateSort();},
|
1310 |
-
create: function(event, ui){that.updateSort();}
|
1311 |
-
});
|
1312 |
-
|
1313 |
-
},
|
1314 |
-
|
1315 |
-
updateSort: function(){
|
1316 |
-
var indexes = {};
|
1317 |
-
$('.msp-slideframe-item').each(function(index) {
|
1318 |
-
indexes[$(this).data('id')] = index;
|
1319 |
-
});
|
1320 |
-
this.$().sortable('cancel');
|
1321 |
-
this.get('controller').updateSlidesSort(indexes);
|
1322 |
-
}
|
1323 |
-
});
|
1324 |
-
|
1325 |
-
|
1326 |
-
/* ---------------------------------------------------------
|
1327 |
-
ImgSelect
|
1328 |
-
------------------------------------------------------------*/
|
1329 |
-
|
1330 |
-
|
1331 |
-
/*
|
1332 |
-
var frame; // to store already used upload frame
|
1333 |
-
|
1334 |
-
$upload_btn.on( 'click', function() {
|
1335 |
-
var $this = $(this);
|
1336 |
-
// get input field (the image src field)
|
1337 |
-
var $input = $this.siblings('input[type="text"]');
|
1338 |
-
|
1339 |
-
// If the frame already exists, re-open it.
|
1340 |
-
if ( frame ) {
|
1341 |
-
frame.open();
|
1342 |
-
return;
|
1343 |
-
}
|
1344 |
-
|
1345 |
-
var frame = wp.media.frames.frame = wp.media({
|
1346 |
-
title: "Select Image", // the select button label in media uploader
|
1347 |
-
multiple: false, // use single image upload or multiple?
|
1348 |
-
frame: 'select',
|
1349 |
-
library: { type: 'image' },
|
1350 |
-
button : { text : 'Add Image' }
|
1351 |
-
});
|
1352 |
-
|
1353 |
-
// on "Add Image" button clicked in media uploader
|
1354 |
-
frame.on( 'select', function() {
|
1355 |
-
var attachment = frame.state().get('selection').first().toJSON();
|
1356 |
-
$input.val(attachment.url).trigger('change'); // insert attachment url in our input field
|
1357 |
-
});
|
1358 |
-
|
1359 |
-
// open media uploader
|
1360 |
-
frame.open();
|
1361 |
-
});
|
1362 |
-
*/
|
1363 |
-
|
1364 |
-
|
1365 |
-
MSPanel.ImgSelect = Ember.View.extend({
|
1366 |
-
classNames : ['msp-imgselect'],
|
1367 |
-
value : '',
|
1368 |
-
hasImg : false,
|
1369 |
-
frame: null,
|
1370 |
-
template : Ember.Handlebars.compile('<div class="msp-img-cont">'+
|
1371 |
-
'{{#if view.hasImg}}'+
|
1372 |
-
'<div class="msp-imgselect-preview" {{bind-attr style=view.preview}})"></div>'+
|
1373 |
-
'{{/if}}'+
|
1374 |
-
'</div>'+
|
1375 |
-
'{{#if view.hasImg}}'+
|
1376 |
-
'<button {{action removeImg target="view"}} class="msp-img-btn"><span class="msp-ico msp-ico-grayremove"></span></button>'+
|
1377 |
-
'{{else}}'+
|
1378 |
-
'<button {{action addImg target="view"}} class="msp-img-btn"><span class="msp-ico msp-ico-grayadd"></span></button>'+
|
1379 |
-
'{{/if}}'),
|
1380 |
-
|
1381 |
-
willDestroyElement: function(){
|
1382 |
-
var frame = this.get('frame');
|
1383 |
-
|
1384 |
-
if(frame){
|
1385 |
-
frame.detach();
|
1386 |
-
frame.remove();
|
1387 |
-
frame = null;
|
1388 |
-
this.set('frame', null);
|
1389 |
-
}
|
1390 |
-
},
|
1391 |
-
|
1392 |
-
onValueChanged: function(){
|
1393 |
-
this.beginPropertyChanges();
|
1394 |
-
this.set('hasImg' , !Ember.isEmpty(this.get('value')));
|
1395 |
-
this.set('preview', 'background-image:url(' + this.get('thumb') + ');') ;
|
1396 |
-
this.endPropertyChanges();
|
1397 |
-
}.observes('value').on('didInsertElement'),
|
1398 |
-
|
1399 |
-
actions : {
|
1400 |
-
removeImg : function(){
|
1401 |
-
this.beginPropertyChanges();
|
1402 |
-
this.set('value' , undefined);
|
1403 |
-
this.set('thumb' , undefined);
|
1404 |
-
this.endPropertyChanges();
|
1405 |
-
},
|
1406 |
-
|
1407 |
-
addImg : function(){
|
1408 |
-
if( typeof wp === 'undefined'){
|
1409 |
-
return;
|
1410 |
-
}
|
1411 |
-
|
1412 |
-
var that = this,
|
1413 |
-
frame = this.get('frame');
|
1414 |
-
|
1415 |
-
if ( frame ) {
|
1416 |
-
frame.open();
|
1417 |
-
|
1418 |
-
return;
|
1419 |
-
}
|
1420 |
-
|
1421 |
-
var frame = wp.media.frames.frame = wp.media({
|
1422 |
-
title: "Select Image", // the select button label in media uploader
|
1423 |
-
multiple: false, // use single image upload or multiple?
|
1424 |
-
frame: 'select',
|
1425 |
-
library: { type: 'image' },
|
1426 |
-
button : { text : 'Add Image' }
|
1427 |
-
});
|
1428 |
-
|
1429 |
-
// on "Add Image" button clicked in media uploader
|
1430 |
-
frame.on( 'select', function() {
|
1431 |
-
var attachment = frame.state().get('selection').first().toJSON();
|
1432 |
-
//console.log(attachment)
|
1433 |
-
that.set('thumb', (attachment.sizes.thumbnail || attachment.sizes.full).url);
|
1434 |
-
that.set('value', attachment.url);
|
1435 |
-
});
|
1436 |
-
|
1437 |
-
// open media uploader
|
1438 |
-
frame.open();
|
1439 |
-
this.set('frame', frame);
|
1440 |
-
}
|
1441 |
-
}
|
1442 |
-
});
|
1443 |
-
|
1444 |
-
/* ---------------------------------------------------------
|
1445 |
-
Selectbox
|
1446 |
-
------------------------------------------------------------*/
|
1447 |
-
|
1448 |
-
MSPanel.Select = Ember.Select.extend({
|
1449 |
-
tagName: 'div',
|
1450 |
-
classNames: ['msp-ddlist'],
|
1451 |
-
layout: Ember.Handlebars.compile('<select>{{yield}}</select>'),
|
1452 |
-
value: null,
|
1453 |
-
width: 100,
|
1454 |
-
|
1455 |
-
didInsertElement: function(){
|
1456 |
-
var that = this;
|
1457 |
-
this.$('select').on('change', function(){
|
1458 |
-
var option = that.$('select option:selected');
|
1459 |
-
that.set('value', option.attr('value'));
|
1460 |
-
}).width(this.get('width'));
|
1461 |
-
|
1462 |
-
this.onValueChanged();
|
1463 |
-
},
|
1464 |
-
|
1465 |
-
onValueChanged: function(){
|
1466 |
-
if( !Ember.isEmpty(this.get('value')) ){
|
1467 |
-
this.$('select').val(this.get('value'));
|
1468 |
-
}
|
1469 |
-
}.observes('value')
|
1470 |
-
|
1471 |
-
/*classNames:['msp-selectbox'],
|
1472 |
-
tagName:'div',
|
1473 |
-
layout: Ember.Handlebars.compile('<select>{{yield}}</select>'),
|
1474 |
-
width:100,
|
1475 |
-
didInsertElement: function() {
|
1476 |
-
var that = this,
|
1477 |
-
isFirst = true;
|
1478 |
-
var ddslick = this.$('select').ddslick({width:this.get('width') , onSelected: function(selectedData){
|
1479 |
-
!isFirst && that.set('value' , selectedData.selectedData.value);
|
1480 |
-
isFirst = false;
|
1481 |
-
} });
|
1482 |
-
this.onValueChanged();
|
1483 |
-
},
|
1484 |
-
|
1485 |
-
onValueChanged: function(){
|
1486 |
-
var that = this,
|
1487 |
-
cindex = 0;
|
1488 |
-
this.$('.dd-option-value').each(function(){
|
1489 |
-
var $this = $(this);
|
1490 |
-
|
1491 |
-
if( $this.attr('value') === that.get('value') ){
|
1492 |
-
that.$('.dd-container').ddslick('select' , {index:cindex});
|
1493 |
-
return false;
|
1494 |
-
}
|
1495 |
-
cindex ++;
|
1496 |
-
});
|
1497 |
-
|
1498 |
-
}.observes('value')*/
|
1499 |
-
});
|
1500 |
-
|
1501 |
-
|
1502 |
-
/* ---------------------------------------------------------
|
1503 |
-
URLTarget
|
1504 |
-
------------------------------------------------------------*/
|
1505 |
-
MSPanel.URLTarget = MSPanel.Select.extend({
|
1506 |
-
|
1507 |
-
onInit : function(){
|
1508 |
-
var contents = [{lable:__MSP_LAN.ui_005 , value:"_self"},
|
1509 |
-
{lable:__MSP_LAN.ui_006 , value:"_blank"},
|
1510 |
-
{lable:__MSP_LAN.ui_007 , value:"_parent"},
|
1511 |
-
{lable:__MSP_LAN.ui_008 , value:"_top"}];
|
1512 |
-
|
1513 |
-
this.set('content' , contents);
|
1514 |
-
this.set('optionValuePath' , "content.value");
|
1515 |
-
this.set('optionLabelPath' , "content.lable");
|
1516 |
-
|
1517 |
-
this.set('width' , 200);
|
1518 |
-
|
1519 |
-
}.on('init')
|
1520 |
-
/*
|
1521 |
-
didInsertElement: function(){
|
1522 |
-
//this.$().css('vertical-align', 'top');
|
1523 |
-
this._super();
|
1524 |
-
}*/
|
1525 |
-
});
|
1526 |
-
|
1527 |
-
|
1528 |
-
/* ---------------------------------------------------------
|
1529 |
-
Fillmode
|
1530 |
-
------------------------------------------------------------*/
|
1531 |
-
MSPanel.Fillmode = Ember.View.extend({
|
1532 |
-
classNames : ['msp-fill-dd'],
|
1533 |
-
type : 'slide', // video
|
1534 |
-
value: 'fill',
|
1535 |
-
index: 1,
|
1536 |
-
template : Ember.Handlebars.compile('<select>{{#each item in view.contents}}'+
|
1537 |
-
'<option {{bind-attr value=item.value data-imagesrc=item.img}}>{{item.text}}</option>'+
|
1538 |
-
'{{/each}}</select>'),
|
1539 |
-
didInsertElement : function(){
|
1540 |
-
var that = this,
|
1541 |
-
isFirst = true;
|
1542 |
-
this.$('select').ddslick({width:154 , onSelected: function(selected){
|
1543 |
-
!isFirst && that.set('value' , selected.selectedData.value);
|
1544 |
-
isFirst = false;
|
1545 |
-
} });
|
1546 |
-
|
1547 |
-
this.onValueChanged();
|
1548 |
-
},
|
1549 |
-
|
1550 |
-
onValueChanged : function(){
|
1551 |
-
if( Ember.isEmpty(this.get('value')) ){
|
1552 |
-
return;
|
1553 |
-
}
|
1554 |
-
this.$('.dd-container').ddslick('select', {index:this.get('valuedic')[this.get('value')]});
|
1555 |
-
}.observes('value'),
|
1556 |
-
|
1557 |
-
onInit : function(){
|
1558 |
-
var contents , valuedic;
|
1559 |
-
if(this.get('type') === 'slide'){
|
1560 |
-
|
1561 |
-
contents = [{value:'fill' , text:__MSP_LAN.ui_009 , img: __MSP_PATH + 'images/fill.png' },
|
1562 |
-
{value:'fit' , text:__MSP_LAN.ui_010 , img: __MSP_PATH + 'images/fit.png' },
|
1563 |
-
{value:'center' , text:__MSP_LAN.ui_011 , img: __MSP_PATH + 'images/center.png' },
|
1564 |
-
{value:'stretch' , text:__MSP_LAN.ui_012 , img: __MSP_PATH + 'images/stretch.png' },
|
1565 |
-
{value:'tile' , text:__MSP_LAN.ui_013 , img: __MSP_PATH + 'images/tile.png' }];
|
1566 |
-
|
1567 |
-
valuedic = {fill:0 , fit:1 , center:2 , stretch:3 , tile:4};
|
1568 |
-
|
1569 |
-
}else if(this.get('type') === 'video'){
|
1570 |
-
|
1571 |
-
contents = [{value:'fill' , text:__MSP_LAN.ui_009 , img: __MSP_PATH + 'images/fill.png' },
|
1572 |
-
{value:'fit' , text:__MSP_LAN.ui_010 , img: __MSP_PATH + 'images/fit.png' }
|
1573 |
-
//{value:'none' , text:__MSP_LAN.ui_013 , img:'images/none.png' }
|
1574 |
-
];
|
1575 |
-
|
1576 |
-
valuedic = {fill:0 , fit:1 , none:2};
|
1577 |
-
}
|
1578 |
-
|
1579 |
-
this.set('contents' , contents);
|
1580 |
-
this.set('valuedic' , valuedic);
|
1581 |
-
}.on('init')
|
1582 |
-
|
1583 |
-
});
|
1584 |
-
|
1585 |
-
/* ------------------------------------------------------- *\
|
1586 |
-
SimpleCodeBlock
|
1587 |
-
\* --------------------------------------------------------*/
|
1588 |
-
MSPanel.SimpleCodeBlock = Ember.View.extend({
|
1589 |
-
classNames: ['msp-shortcode-box'],
|
1590 |
-
template: Ember.Handlebars.compile('<input type="text" readonly {{bind-attr value=view.value}}>' ),
|
1591 |
-
width:150,
|
1592 |
-
didInsertElement: function(){
|
1593 |
-
this.$('input').on('click',function(){
|
1594 |
-
$(this).select();
|
1595 |
-
}).width(this.get('width'));
|
1596 |
-
}
|
1597 |
-
});//js\mspanel\views\SettingsView.js
|
1598 |
-
|
1599 |
-
/**
|
1600 |
-
* Settings Page View
|
1601 |
-
* @package MSPanel
|
1602 |
-
* @extends {Ember.View}
|
1603 |
-
*/
|
1604 |
-
|
1605 |
-
MSPanel.SettingsView = Ember.View.extend({
|
1606 |
-
didInsertElement: function(){
|
1607 |
-
this.set('controller.mainView' , this);
|
1608 |
-
}
|
1609 |
-
});//js\mspanel\views\SlidesView.js
|
1610 |
-
|
1611 |
-
/**
|
1612 |
-
* Slides Page View
|
1613 |
-
* @package MSPanel
|
1614 |
-
* @extends {Ember.View}
|
1615 |
-
*/
|
1616 |
-
|
1617 |
-
MSPanel.SlidesView = Ember.View.extend({
|
1618 |
-
didInsertElement: function(){
|
1619 |
-
this.set('controller.mainView' , this);
|
1620 |
-
}
|
1621 |
-
});//js\mspanel\views\StageView.js
|
1622 |
-
|
1623 |
-
/* ---------------------------------------------------------
|
1624 |
-
Stage View
|
1625 |
-
------------------------------------------------------------*/
|
1626 |
-
MSPanel.StageArea = Ember.View.extend({
|
1627 |
-
classNames : ['msp-stage-area'],
|
1628 |
-
template : Ember.Handlebars.compile('{{view MSPanel.Stage}}'+
|
1629 |
-
'{{#if noticeMsg}}<div class="msp-stage-msg"><span class="msp-ico msp-ico-notice"></span>{{{noticeMsg}}}</div>{{/if}}'),
|
1630 |
-
});
|
1631 |
-
|
1632 |
-
|
1633 |
-
MSPanel.Stage = Ember.View.extend({
|
1634 |
-
|
1635 |
-
classNames : ['msp-slide-stage'],
|
1636 |
-
attributeBindings : ['style'],
|
1637 |
-
template : Ember.Handlebars.compile('<div id="stage-bg" class="msp-stage-bg"></div>'),
|
1638 |
-
|
1639 |
-
resize : function(){
|
1640 |
-
|
1641 |
-
var w = this.get('controller.sliderSettings.width'),
|
1642 |
-
h = this.get('controller.sliderSettings.height');
|
1643 |
-
|
1644 |
-
this.set('width' , w);
|
1645 |
-
this.set('height' , h);
|
1646 |
-
|
1647 |
-
this.$().css({
|
1648 |
-
width : w,
|
1649 |
-
height : h
|
1650 |
-
});
|
1651 |
-
|
1652 |
-
}.observes('controller.sliderSettings.width' , 'controller.sliderSettings.height').on('didInsertElement'),
|
1653 |
-
|
1654 |
-
didInsertElement : function(){
|
1655 |
-
var BG = this.$('#stage-bg'),
|
1656 |
-
BGImage = $('<img/>');
|
1657 |
-
|
1658 |
-
BGImage.css('visibelity' , 'hidden').each($.jqLoadFix);
|
1659 |
-
|
1660 |
-
var aligner = new MSAligner(this.get('controller.currentSlide.fillMode') , BG , BGImage);
|
1661 |
-
|
1662 |
-
this.set('bgAligner' , aligner);
|
1663 |
-
this.set('bgImg', BGImage);
|
1664 |
-
this.onBGChange();
|
1665 |
-
},
|
1666 |
-
|
1667 |
-
onBGColorChange: function(){
|
1668 |
-
|
1669 |
-
var color = this.get('controller.currentSlide.bgColor');
|
1670 |
-
|
1671 |
-
if( !Ember.isEmpty(color) ){
|
1672 |
-
this.$('#stage-bg').css('background-color', color);
|
1673 |
-
} else {
|
1674 |
-
this.$('#stage-bg').css('background-color', '');
|
1675 |
-
}
|
1676 |
-
|
1677 |
-
}.observes('controller.currentSlide.bgColor'),
|
1678 |
-
|
1679 |
-
onBGChange: function(){
|
1680 |
-
var alinger = this.get('bgAligner');
|
1681 |
-
if(alinger){
|
1682 |
-
alinger.reset();
|
1683 |
-
}
|
1684 |
-
|
1685 |
-
var bg = this.get('controller.currentSlide.bg'),
|
1686 |
-
bgImg = this.get('bgImg');
|
1687 |
-
|
1688 |
-
if( !Ember.isEmpty(bg) ){
|
1689 |
-
var that = this;
|
1690 |
-
bgImg.appendTo(this.$('#stage-bg'));
|
1691 |
-
bgImg.preloadImg(bg , function(event) {that._onBGLoad(event);});
|
1692 |
-
bgImg.attr('src', bg);
|
1693 |
-
//alinger.align();
|
1694 |
-
} else {
|
1695 |
-
bgImg.detach();
|
1696 |
-
}
|
1697 |
-
}.observes('controller.currentSlide.bg'),
|
1698 |
-
|
1699 |
-
_onBGLoad: function(event){
|
1700 |
-
var aligner = this.get('bgAligner');
|
1701 |
-
|
1702 |
-
if( !aligner ) {
|
1703 |
-
return;
|
1704 |
-
}
|
1705 |
-
|
1706 |
-
aligner.init(event.width , event.height);
|
1707 |
-
aligner.align();
|
1708 |
-
this.get('bgImg').css('visibelity' , '');
|
1709 |
-
},
|
1710 |
-
|
1711 |
-
onFillModeChanged : function(){
|
1712 |
-
var aligner = this.get('bgAligner');
|
1713 |
-
aligner.changeType(this.get('controller.currentSlide.fillMode'));
|
1714 |
-
}.observes('controller.currentSlide.fillMode'),
|
1715 |
-
|
1716 |
-
willDestroyElement: function(){
|
1717 |
-
this.set('bgAligner' , null);
|
1718 |
-
}
|
1719 |
-
});//js\mspanel\views\ControlsView.js
|
1720 |
-
|
1721 |
-
/*MSPanel.ControlsView = Ember.View.extend({
|
1722 |
-
didInsertElement: function(){
|
1723 |
-
this.get('controller').send('showControlOptions');
|
1724 |
-
}
|
1725 |
-
});
|
1726 |
-
*/
|
1727 |
-
MSPanel.ControlBtn = Ember.View.extend({
|
1728 |
-
control: null,
|
1729 |
-
tagName: 'div',
|
1730 |
-
active:false,
|
1731 |
-
classNames: ['msp-control-btn'],
|
1732 |
-
classNameBindings: ['active:msp-blue-btn'],
|
1733 |
-
|
1734 |
-
template : Ember.Handlebars.compile('<span class="msp-control-label">{{view.control.label}}</span>'+
|
1735 |
-
'<a href="#" {{action "removeControl" target=view bubbles=false}}><span class="msp-control-removes msp-ico msp-ico-whiteremove"></span></a>'),
|
1736 |
-
|
1737 |
-
|
1738 |
-
didInsertElement: function() {
|
1739 |
-
|
1740 |
-
},
|
1741 |
-
|
1742 |
-
onActiveChange: function(){
|
1743 |
-
this.set('active', this.get('controller.currentControl') === this.get('control'));
|
1744 |
-
|
1745 |
-
if( this.get('active') ){
|
1746 |
-
this.get('controller').send('showControlOptions');
|
1747 |
-
}
|
1748 |
-
|
1749 |
-
}.observes('controller.currentControl').on('init'),
|
1750 |
-
|
1751 |
-
click: function(){
|
1752 |
-
if( this.get('active') ) {
|
1753 |
-
return;
|
1754 |
-
}
|
1755 |
-
this.set('controller.currentControl', this.get('control'));
|
1756 |
-
//this.get('controller').send('showControlOptions');
|
1757 |
-
},
|
1758 |
-
|
1759 |
-
actions: {
|
1760 |
-
removeControl: function(){
|
1761 |
-
if( confirm('Are you sure want to remvoe "' + this.get('control.label') + '" control?')){
|
1762 |
-
this.get('controller').send('removeControl', this.get('control'));
|
1763 |
-
}
|
1764 |
-
}
|
1765 |
-
}
|
1766 |
-
|
1767 |
-
});
|
1768 |
-
//js\mspanel\components\UIComponents.js
|
1769 |
-
|
1770 |
-
/**
|
1771 |
-
MSPanel UI Components
|
1772 |
-
Version 1.0b
|
1773 |
-
*/
|
1774 |
-
|
1775 |
-
/* ---------------------------------------------------------
|
1776 |
-
Metabox
|
1777 |
-
------------------------------------------------------------*/
|
1778 |
-
|
1779 |
-
MSPanel.MetaBoxComponent = Ember.Component.extend({
|
1780 |
-
tagName: 'div',
|
1781 |
-
classNames: ['msp-metabox'],
|
1782 |
-
layout: Ember.Handlebars.compile('<div class="msp-metabox-handle">'+
|
1783 |
-
'<h3 class="msp-metabox-title">{{title}}</h3>'+
|
1784 |
-
'<div class="msp-metabox-toggle"></div>'+
|
1785 |
-
'</div>'+
|
1786 |
-
'{{yield}}'+
|
1787 |
-
'<div class="clear"> </div>')
|
1788 |
-
});
|
1789 |
-
|
1790 |
-
|
1791 |
-
/* ---------------------------------------------------------
|
1792 |
-
Tabs
|
1793 |
-
------------------------------------------------------------*/
|
1794 |
-
|
1795 |
-
Ember.TEMPLATES['components/tabs-panel'] = Ember.Handlebars.compile('{{yield}}');
|
1796 |
-
MSPanel.TabsPanelComponent = Ember.Component.extend({
|
1797 |
-
tagName: 'div',
|
1798 |
-
attributeBindings: ['id'],
|
1799 |
-
classNames: ['msp-metabox msp-metabox-tabs'],
|
1800 |
-
didInsertElement: function() {
|
1801 |
-
this.$().avertaLiveTabs();
|
1802 |
-
}
|
1803 |
-
});
|
1804 |
-
|
1805 |
-
|
1806 |
-
/* ---------------------------------------------------------
|
1807 |
-
Switchbox
|
1808 |
-
------------------------------------------------------------*/
|
1809 |
-
|
1810 |
-
MSPanel.SwitchBoxComponent = Ember.Component.extend({
|
1811 |
-
classNames : ['msp-switchbox'],
|
1812 |
-
offlable : 'OFF',
|
1813 |
-
onlable : 'ON',
|
1814 |
-
value : false,
|
1815 |
-
|
1816 |
-
layout : Ember.Handlebars.compile('<div class="msp-switch-cont">'+
|
1817 |
-
'<span class="msp-switch-off">{{view.offlable}}</span>'+
|
1818 |
-
'<div class="msp-switch-handle"></div>'+
|
1819 |
-
'<span class="msp-switch-on">{{view.onlable}}</span>'+
|
1820 |
-
'</div>'),
|
1821 |
-
|
1822 |
-
click:function(){
|
1823 |
-
var that = this;
|
1824 |
-
that.set('value' , !that.get('value'));
|
1825 |
-
},
|
1826 |
-
|
1827 |
-
update: function(){
|
1828 |
-
|
1829 |
-
if(this.get('value')) this.$().addClass('switched');
|
1830 |
-
else this.$().removeClass('switched');
|
1831 |
-
|
1832 |
-
}.observes('value').on('didInsertElement')
|
1833 |
-
|
1834 |
-
});
|
1835 |
-
|
1836 |
-
|
1837 |
-
/* ---------------------------------------------------------
|
1838 |
-
WP TinyMCE Editor
|
1839 |
-
------------------------------------------------------------*/
|
1840 |
-
var hiddenEditor = jQuery('#mspHiddenEditor')[0].outerHTML;
|
1841 |
-
function WPEditorTemplate(id){
|
1842 |
-
var newEditor = $(hiddenEditor);
|
1843 |
-
newEditor.find('link').remove(); // remove all css files init
|
1844 |
-
return newEditor.html().replace(/msp-hidden/g, id);
|
1845 |
-
}
|
1846 |
-
var __tmc_msp_id = 0;
|
1847 |
-
|
1848 |
-
MSPanel.WPEditor = Ember.View.extend({
|
1849 |
-
classNames : ['msp-wp-editor'],
|
1850 |
-
_id : null,
|
1851 |
-
template : null,
|
1852 |
-
tab: null,
|
1853 |
-
tabs: null,
|
1854 |
-
|
1855 |
-
onInit: function(){
|
1856 |
-
var id = 'msp-wpeditor-' + __tmc_msp_id;
|
1857 |
-
this.set('_id', id );
|
1858 |
-
this.set('template', Ember.Handlebars.compile( WPEditorTemplate(id)));
|
1859 |
-
|
1860 |
-
__tmc_msp_id++;
|
1861 |
-
|
1862 |
-
}.on('init'),
|
1863 |
-
|
1864 |
-
didInsertElement: function(){
|
1865 |
-
var tabs = this.get('tabs');
|
1866 |
-
if( Ember.isEmpty(tabs) ) {
|
1867 |
-
this.createEditor();
|
1868 |
-
return;
|
1869 |
-
}
|
1870 |
-
|
1871 |
-
// is in tabs
|
1872 |
-
$('#'+tabs).bind('avtTabChange', {that:this}, this.refreshEditor);
|
1873 |
-
},
|
1874 |
-
|
1875 |
-
refreshEditor: function(event , tab){
|
1876 |
-
var that = event.data.that;
|
1877 |
-
|
1878 |
-
if( that.get('tab') === tab ){
|
1879 |
-
that.createEditor();
|
1880 |
-
}
|
1881 |
-
},
|
1882 |
-
|
1883 |
-
createEditor: function(){
|
1884 |
-
if( this.get('inited') === true ){
|
1885 |
-
return;
|
1886 |
-
}
|
1887 |
-
|
1888 |
-
this.set('inited', true);
|
1889 |
-
var id = this.get('_id'),
|
1890 |
-
that = this;
|
1891 |
-
|
1892 |
-
// tinymce
|
1893 |
-
if( window.tinymce ){
|
1894 |
-
var settings = $.extend({}, window.tinyMCEPreInit.mceInit['msp-hidden'] || {});
|
1895 |
-
settings.forced_root_block = "";
|
1896 |
-
settings.force_br_newlines = true;
|
1897 |
-
settings.force_p_newlines = false;
|
1898 |
-
settings.wpautop = false;
|
1899 |
-
|
1900 |
-
if( tinyMCE.majorVersion == '3' ){
|
1901 |
-
settings.body_class = settings.elements = id;
|
1902 |
-
tinymce.init(settings);
|
1903 |
-
setTimeout(function(){
|
1904 |
-
that.initEditor(tinyMCE.getInstanceById(id));
|
1905 |
-
}, 50);
|
1906 |
-
} else if ( tinyMCE.majorVersion == '4' ){
|
1907 |
-
settings.body_class = "content post-type-post post-status-auto-draft post-format-standard";
|
1908 |
-
settings.selector = '#'+id;
|
1909 |
-
tinymce.init(settings);
|
1910 |
-
setTimeout(function(){
|
1911 |
-
that.initEditor(tinyMCE.get(id));
|
1912 |
-
}, 50);
|
1913 |
-
}
|
1914 |
-
settings.setup = function(ed) {
|
1915 |
-
//that.initEditor(ed);
|
1916 |
-
}
|
1917 |
-
|
1918 |
-
}
|
1919 |
-
|
1920 |
-
var qtagSettings = $.extend({}, window.tinyMCEPreInit.qtInit['msp-hidden'] || {}),
|
1921 |
-
qtags;
|
1922 |
-
|
1923 |
-
qtagSettings.id = id;
|
1924 |
-
|
1925 |
-
if ( typeof(QTags) === 'function' ) {
|
1926 |
-
qtags = quicktags(qtagSettings);
|
1927 |
-
QTags.buttonsInitDone = false;
|
1928 |
-
QTags._buttonsInit();
|
1929 |
-
that.set('qtags', qtags );
|
1930 |
-
switchEditors.go(id, 'html');
|
1931 |
-
|
1932 |
-
this.$('textarea#'+this.get('_id')).on('change keyup paste', function(e){
|
1933 |
-
that.set('internalChange', true);
|
1934 |
-
that.set('value', $(this).val());
|
1935 |
-
});
|
1936 |
-
}
|
1937 |
-
},
|
1938 |
-
|
1939 |
-
initEditor: function(mce){
|
1940 |
-
var id = this.get('_id'),
|
1941 |
-
value = this.get('value'),
|
1942 |
-
that = this;
|
1943 |
-
|
1944 |
-
this.$('.wp-editor-wrap').on('mousedown', function(){
|
1945 |
-
wpActiveEditor = id;
|
1946 |
-
});
|
1947 |
-
|
1948 |
-
function updateValue(ed,e){
|
1949 |
-
that.set('value', mce.getContent());
|
1950 |
-
}
|
1951 |
-
|
1952 |
-
function internalUpdate(ed,e){
|
1953 |
-
that.set('internalChange', true);
|
1954 |
-
that.set('value', mce.getContent());
|
1955 |
-
that.set('internalChange', false);
|
1956 |
-
}
|
1957 |
-
|
1958 |
-
// register events
|
1959 |
-
if( tinyMCE.majorVersion == '3' ){
|
1960 |
-
mce.onChange.add(internalUpdate);
|
1961 |
-
mce.onKeyUp.add(internalUpdate);
|
1962 |
-
} else if ( tinyMCE.majorVersion == '4' ){
|
1963 |
-
mce.on('change', internalUpdate);
|
1964 |
-
mce.on('keyup', internalUpdate);
|
1965 |
-
}
|
1966 |
-
|
1967 |
-
this.$().click(internalUpdate);
|
1968 |
-
|
1969 |
-
setTimeout(function(){
|
1970 |
-
switchEditors.go(id, 'html');
|
1971 |
-
switchEditors.go(id, 'tmce');
|
1972 |
-
}, 100);
|
1973 |
-
|
1974 |
-
this.set('mce', mce);
|
1975 |
-
|
1976 |
-
this.onValueChanged();
|
1977 |
-
},
|
1978 |
-
|
1979 |
-
onValueChanged: function(){
|
1980 |
-
|
1981 |
-
if( !this.get('inited') ){
|
1982 |
-
return;
|
1983 |
-
}
|
1984 |
-
|
1985 |
-
var value = this.get('value');
|
1986 |
-
|
1987 |
-
this.$('textarea#'+this.get('_id')).val(value);
|
1988 |
-
|
1989 |
-
if( this.get('internalChange') ){
|
1990 |
-
this.set('internalChange', false);
|
1991 |
-
return;
|
1992 |
-
}
|
1993 |
-
|
1994 |
-
var mce = this.get('mce');
|
1995 |
-
if( !Ember.isEmpty(mce) && value != null){
|
1996 |
-
mce.setContent(value);
|
1997 |
-
} else if( value == null ){
|
1998 |
-
mce.setContent(' ');
|
1999 |
-
}
|
2000 |
-
|
2001 |
-
}.observes('value'),
|
2002 |
-
|
2003 |
-
willDestroyElement: function(){
|
2004 |
-
if( !this.get('inited') ){
|
2005 |
-
return;
|
2006 |
-
}
|
2007 |
-
|
2008 |
-
if( window.tinymce ){
|
2009 |
-
tinymce.remove(this.get('_id'));
|
2010 |
-
}
|
2011 |
-
|
2012 |
-
var qtags = this.get('qtags');
|
2013 |
-
if( qtags ){
|
2014 |
-
$(qtags.toolbar).remove();
|
2015 |
-
qtags.toolbar = null;
|
2016 |
-
qtags = null;
|
2017 |
-
|
2018 |
-
if( QTags.instances[this.get('_id')] ) {
|
2019 |
-
delete QTags.instances[this.get('_id')];
|
2020 |
-
}
|
2021 |
-
|
2022 |
-
this.$('textarea#'+this.get('_id')).remove();
|
2023 |
-
}
|
2024 |
-
|
2025 |
-
var tabs = this.get('tabs');
|
2026 |
-
if( !Ember.isEmpty(tabs) ){
|
2027 |
-
$('#' + tabs).unbind('avtTabChange', this.refreshEditor);
|
2028 |
-
}
|
2029 |
-
}
|
2030 |
-
});
|
2031 |
-
|
2032 |
-
|
2033 |
-
/* ---------------------------------------------------------
|
2034 |
-
CKEditor
|
2035 |
-
------------------------------------------------------------*/
|
2036 |
-
/*MSPanel.HTMLTextArea = Ember.TextArea.extend({
|
2037 |
-
didInsertElement: function() {
|
2038 |
-
this._super();
|
2039 |
-
var that = this;
|
2040 |
-
|
2041 |
-
var cke = CKEDITOR.replace( that.get('elementId'), {
|
2042 |
-
uiColor: '#f1f1f1',
|
2043 |
-
removeButtons: 'Underline,Subscript,Superscript',
|
2044 |
-
entities : false,
|
2045 |
-
htmlEncodeOutput: true,
|
2046 |
-
forcePasteAsPlainText: true,
|
2047 |
-
enterMode : CKEDITOR.ENTER_BR,
|
2048 |
-
shiftEnterMode: CKEDITOR.ENTER_P ,
|
2049 |
-
toolbarGroups : [
|
2050 |
-
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
|
2051 |
-
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
|
2052 |
-
{ name: 'links' },
|
2053 |
-
{ name: 'insert' },
|
2054 |
-
{ name: 'tools' },
|
2055 |
-
|
2056 |
-
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
|
2057 |
-
'/',
|
2058 |
-
{ name: 'styles' },
|
2059 |
-
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
|
2060 |
-
{ name: 'paragraph', groups: [ 'blocks', 'align','list', 'indent' ] },
|
2061 |
-
{ name: 'others' }
|
2062 |
-
|
2063 |
-
]
|
2064 |
-
|
2065 |
-
});
|
2066 |
-
|
2067 |
-
var update = function(e){
|
2068 |
-
//if (e.editor.checkDirty()) {
|
2069 |
-
that.set('internalChange' , true);
|
2070 |
-
that.set('value', cke.getData());
|
2071 |
-
//console.log('changes', that.get('value'));
|
2072 |
-
|
2073 |
-
//}
|
2074 |
-
}
|
2075 |
-
|
2076 |
-
//cke.on( 'contentDom', function() {
|
2077 |
-
// var editable = cke.editable();
|
2078 |
-
|
2079 |
-
// editable.attachListener( editable, 'keyup', function() {
|
2080 |
-
// console.log( 'Editable has been clicked' );
|
2081 |
-
// update();
|
2082 |
-
// });
|
2083 |
-
//});
|
2084 |
-
|
2085 |
-
cke.on('key', update);
|
2086 |
-
cke.on('blur', update);
|
2087 |
-
cke.on('paste', update);
|
2088 |
-
|
2089 |
-
this.set('cke' , cke);
|
2090 |
-
},
|
2091 |
-
|
2092 |
-
willDestroyElement: function(){
|
2093 |
-
this.get('cke').destroy();
|
2094 |
-
//CKEDITOR.remove(this.get('cke'));
|
2095 |
-
this.set('cke', null);
|
2096 |
-
},
|
2097 |
-
|
2098 |
-
onValueChanged : function(){
|
2099 |
-
if(this.get('internalChange')){
|
2100 |
-
this.set('internalChange' , false);
|
2101 |
-
return;
|
2102 |
-
}
|
2103 |
-
|
2104 |
-
var cke = this.get('cke');
|
2105 |
-
cke.setData(this.get('value'));
|
2106 |
-
}.observes('value')
|
2107 |
-
});*/
|
2108 |
-
|
2109 |
-
/* ---------------------------------------------------------
|
2110 |
-
Number Input
|
2111 |
-
------------------------------------------------------------*/
|
2112 |
-
|
2113 |
-
/* Fixed jQuery UI Spinner changing value without focus bug. */
|
2114 |
-
if( jQuery.ui && jQuery.ui.spinner ){
|
2115 |
-
jQuery.ui.spinner.prototype._events.mousewheel = function ( event, delta ) {
|
2116 |
-
|
2117 |
-
if ( !delta || !this.element.is(':focus') ) {
|
2118 |
-
return;
|
2119 |
-
}
|
2120 |
-
if ( !this.spinning && !this._start( event ) ) {
|
2121 |
-
return false;
|
2122 |
-
}
|
2123 |
-
|
2124 |
-
this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
|
2125 |
-
clearTimeout( this.mousewheelTimer );
|
2126 |
-
this.mousewheelTimer = this._delay(function() {
|
2127 |
-
if ( this.spinning ) {
|
2128 |
-
this._stop( event );
|
2129 |
-
}
|
2130 |
-
}, 100 );
|
2131 |
-
event.preventDefault();
|
2132 |
-
}
|
2133 |
-
}
|
2134 |
-
|
2135 |
-
MSPanel.NumberInputView = Ember.View.extend({
|
2136 |
-
step : 1,
|
2137 |
-
min: 0,
|
2138 |
-
tagName: 'input',
|
2139 |
-
attributeBindings:['type'],
|
2140 |
-
lastValue: null,
|
2141 |
-
type: 'text',
|
2142 |
-
|
2143 |
-
didInsertElement : function(){
|
2144 |
-
|
2145 |
-
var that = this,
|
2146 |
-
input = this.$();
|
2147 |
-
var updateValue = function(event, ui){
|
2148 |
-
var value = input.spinner('value');
|
2149 |
-
that.set('internalChange', true);
|
2150 |
-
|
2151 |
-
if( isNaN(value) || value == null ){
|
2152 |
-
that.set('value', undefined);
|
2153 |
-
}else{
|
2154 |
-
that.set('value', parseFloat(value));
|
2155 |
-
}
|
2156 |
-
}
|
2157 |
-
|
2158 |
-
input.on('change',updateValue).spinner({
|
2159 |
-
step: this.get('step'),
|
2160 |
-
numberFormat: "n",
|
2161 |
-
min:this.get('min'),
|
2162 |
-
max:this.get('max'),
|
2163 |
-
spin: updateValue,
|
2164 |
-
stop: updateValue
|
2165 |
-
}).spinner('value', this.get('value'));
|
2166 |
-
|
2167 |
-
},
|
2168 |
-
|
2169 |
-
onValueChanged : function(){
|
2170 |
-
|
2171 |
-
if(this.get('internalChange')){
|
2172 |
-
this.set('internalChange', false);
|
2173 |
-
return;
|
2174 |
-
}
|
2175 |
-
|
2176 |
-
//this.$().val(this.get('value'));
|
2177 |
-
|
2178 |
-
this.$().spinner('value', this.get('value'));
|
2179 |
-
|
2180 |
-
|
2181 |
-
/*if(this.get('internalChange')){
|
2182 |
-
this.set('internalChange', false);
|
2183 |
-
return;
|
2184 |
-
}*/
|
2185 |
-
//var value = Number(this.get('value'));
|
2186 |
-
|
2187 |
-
//this.$().val(value);
|
2188 |
-
|
2189 |
-
/*
|
2190 |
-
if(value == this.get('lastValue')){
|
2191 |
-
return;
|
2192 |
-
}
|
2193 |
-
// convert to number always
|
2194 |
-
if(value === '' || isNaN(value)){
|
2195 |
-
this.set('value', undefined);
|
2196 |
-
return;
|
2197 |
-
}
|
2198 |
-
|
2199 |
-
if( typeof value !== 'number') {
|
2200 |
-
this.set('value', Number(this.get('value')));
|
2201 |
-
}
|
2202 |
-
|
2203 |
-
if(!Ember.isEmpty(value) && value < this.get('min')){
|
2204 |
-
value = this.get('min');
|
2205 |
-
this.set('value' , value);
|
2206 |
-
}
|
2207 |
-
|
2208 |
-
|
2209 |
-
|
2210 |
-
*/
|
2211 |
-
}.observes('value')
|
2212 |
-
|
2213 |
-
});
|
2214 |
-
|
2215 |
-
Ember.Handlebars.helper('number-input' , MSPanel.NumberInputView);
|
2216 |
-
|
2217 |
-
/**
|
2218 |
-
* Color Picker
|
2219 |
-
* @package MSPanel
|
2220 |
-
* @requires spectrum color picker
|
2221 |
-
*/
|
2222 |
-
MSPanel.ColorPickerComponent = Ember.Component.extend({
|
2223 |
-
tagName: 'input',
|
2224 |
-
classNames: 'msp-color-picker',
|
2225 |
-
value: null,
|
2226 |
-
|
2227 |
-
didInsertElement: function(){
|
2228 |
-
var that = this;
|
2229 |
-
this.$().spectrum({
|
2230 |
-
color: this.get('value'),
|
2231 |
-
allowEmpty:true,
|
2232 |
-
showInput: true,
|
2233 |
-
showAlpha: true,
|
2234 |
-
clickoutFiresChange:true,
|
2235 |
-
preferredFormat: "hex6",
|
2236 |
-
change: function(color) {
|
2237 |
-
if( color === null) {
|
2238 |
-
that.set('value' , null);
|
2239 |
-
} else {
|
2240 |
-
that.set('value', color.toString());
|
2241 |
-
}
|
2242 |
-
}
|
2243 |
-
})
|
2244 |
-
},
|
2245 |
-
|
2246 |
-
willDestroyElement: function(){
|
2247 |
-
this.$().spectrum("destroy");
|
2248 |
-
},
|
2249 |
-
onValueChanged: function(){
|
2250 |
-
this.$().spectrum("set", this.get('value'));
|
2251 |
-
}.observes('value')
|
2252 |
-
|
2253 |
-
});
|
2254 |
-
|
2255 |
-
/**
|
2256 |
-
* Dropdwon list
|
2257 |
-
* @package MSPanel
|
2258 |
-
*/
|
2259 |
-
MSPanel.DropdwonListComponent = Ember.Component.extend({
|
2260 |
-
tagName: 'div',
|
2261 |
-
classNames: ['msp-ddlist'],
|
2262 |
-
layout: Ember.Handlebars.compile('<select>{{yield}}</select>'),
|
2263 |
-
value: null,
|
2264 |
-
width: 100,
|
2265 |
-
|
2266 |
-
didInsertElement: function(){
|
2267 |
-
var that = this;
|
2268 |
-
this.$('select').on('change', function(){
|
2269 |
-
var option = that.$('select option:selected');
|
2270 |
-
that.set('value', option.attr('value'));
|
2271 |
-
}).width(this.get('width'));
|
2272 |
-
|
2273 |
-
this.onValueChanged();
|
2274 |
-
},
|
2275 |
-
|
2276 |
-
onValueChanged: function(){
|
2277 |
-
if( !Ember.isEmpty(this.get('value')) ){
|
2278 |
-
this.$('select').val(this.get('value'));
|
2279 |
-
}
|
2280 |
-
}.observes('value')
|
2281 |
-
});
|
2282 |
-
|
2283 |
-
|
2284 |
-
/**
|
2285 |
-
* CodeMirror Component
|
2286 |
-
* @package MSPanel
|
2287 |
-
* @requires Codemirror
|
2288 |
-
*/
|
2289 |
-
MSPanel.CodeMirrorComponent = Ember.Component.extend({
|
2290 |
-
classNames: ['msp-codemirror'],
|
2291 |
-
width: 250,
|
2292 |
-
height: 200,
|
2293 |
-
mode: 'css',
|
2294 |
-
tab: null,
|
2295 |
-
tabs: null,
|
2296 |
-
layout: Ember.Handlebars.compile('<textarea>{{yield}}</textarea>'),
|
2297 |
-
|
2298 |
-
didInsertElement: function(){
|
2299 |
-
|
2300 |
-
this.$().width(this.get('width'))
|
2301 |
-
.height(this.get('height'));
|
2302 |
-
|
2303 |
-
var that = this,
|
2304 |
-
editor = CodeMirror.fromTextArea(this.$('>textarea')[0], {
|
2305 |
-
lineNumbers:true,
|
2306 |
-
mode:this.get('mode')
|
2307 |
-
});
|
2308 |
-
|
2309 |
-
editor.on('change', function(){
|
2310 |
-
that.set('internalChange', true);
|
2311 |
-
that.set('value', editor.getValue());
|
2312 |
-
})
|
2313 |
-
|
2314 |
-
this.set('editor', editor);
|
2315 |
-
|
2316 |
-
var value = this.get('value');
|
2317 |
-
if( !Ember.isEmpty(value) ) {
|
2318 |
-
editor.setValue(value);
|
2319 |
-
}
|
2320 |
-
|
2321 |
-
// is in tabs
|
2322 |
-
var tabs = this.get('tabs');
|
2323 |
-
if( !Ember.isEmpty(tabs) ){
|
2324 |
-
$('#'+tabs).bind('avtTabChange', {that:this}, this.refreshEditor);
|
2325 |
-
}
|
2326 |
-
},
|
2327 |
-
|
2328 |
-
onValueChanged: function(){
|
2329 |
-
if( this.get('internalChange') === true) {
|
2330 |
-
this.set('internalChange', false);
|
2331 |
-
return;
|
2332 |
-
}
|
2333 |
-
|
2334 |
-
this.get('editor').setValue(this.get('value'));
|
2335 |
-
this.set('internalChange', false);
|
2336 |
-
|
2337 |
-
}.observes('value'),
|
2338 |
-
|
2339 |
-
refreshEditor: function(event , tab){
|
2340 |
-
var that = event.data.that;
|
2341 |
-
|
2342 |
-
if( that.get('tab') === tab ) {
|
2343 |
-
that.get('editor').refresh();
|
2344 |
-
}
|
2345 |
-
},
|
2346 |
-
|
2347 |
-
willDestroyElement: function(){
|
2348 |
-
var tabs = this.get('tabs');
|
2349 |
-
if( !Ember.isEmpty(tabs) ){
|
2350 |
-
$('#' + tabs).unbind('avtTabChange', this.refreshEditor);
|
2351 |
-
}
|
2352 |
-
|
2353 |
-
var editor = this.get('editor');
|
2354 |
-
editor.toTextArea();
|
2355 |
-
editor = null;
|
2356 |
-
this.set('editor', null);
|
2357 |
-
}
|
2358 |
-
|
2359 |
-
});//js\mspanel\controllers\ApplicationController.js
|
2360 |
-
|
2361 |
-
/*
|
2362 |
-
* Application controller
|
2363 |
-
* @package MSPanel
|
2364 |
-
*/
|
2365 |
-
|
2366 |
-
MSPanel.pushData = null;
|
2367 |
-
MSPanel.ApplicationController = Ember.Controller.extend({
|
2368 |
-
|
2369 |
-
sliderId : MSPanel.SliderID,
|
2370 |
-
|
2371 |
-
// if true save button will be disabled
|
2372 |
-
isSending: false,
|
2373 |
-
|
2374 |
-
// the status message that appears after save button
|
2375 |
-
statusMsg: '',
|
2376 |
-
|
2377 |
-
hasError: false,
|
2378 |
-
|
2379 |
-
|
2380 |
-
onInit: function(){
|
2381 |
-
// fetch all data
|
2382 |
-
|
2383 |
-
//setting
|
2384 |
-
MSPanel.Settings.find();
|
2385 |
-
// slides
|
2386 |
-
MSPanel.Slide.find();
|
2387 |
-
// layer
|
2388 |
-
//MSPanel.Layer.find();
|
2389 |
-
// style
|
2390 |
-
//MSPanel.Style.find();
|
2391 |
-
// effect
|
2392 |
-
//MSPanel.Effect.find();
|
2393 |
-
// style
|
2394 |
-
//MSPanel.PresetStyle.find();
|
2395 |
-
// effect
|
2396 |
-
//MSPanel.PresetEffect.find();
|
2397 |
-
//control
|
2398 |
-
MSPanel.Control.find();
|
2399 |
-
//callback
|
2400 |
-
MSPanel.Callback.find();
|
2401 |
-
//buttonClass
|
2402 |
-
//MSPanel.ButtonStyle.find();
|
2403 |
-
|
2404 |
-
//this.set('useCustomTemplate', MSPanel.Settings.find(0).get('msTemplate') === 'custom');
|
2405 |
-
this.set('disableControls', MSPanel.Settings.find(0).get('disableControls'));
|
2406 |
-
|
2407 |
-
var that = this;
|
2408 |
-
MSPanel.pushData = function(){
|
2409 |
-
that.prepareData();
|
2410 |
-
};
|
2411 |
-
|
2412 |
-
// redirect if woocommerce not installed
|
2413 |
-
if ( __MSP_TYPE === 'wc-product' && __MSP_POST == null && __WC_INSTALL_URL != null ){
|
2414 |
-
this.set('hasError', true);
|
2415 |
-
this.set('errorTemplate', 'wooc-error');
|
2416 |
-
this.set('wooLink', __WC_INSTALL_URL);
|
2417 |
-
}
|
2418 |
-
|
2419 |
-
// generate buttons style element
|
2420 |
-
this.generateButtonStyles();
|
2421 |
-
|
2422 |
-
this.set('shortCode', '[masterslider id='+this.get('sliderId')+']');
|
2423 |
-
this.set('phpFunction', '<?php masterslider('+this.get('sliderId')+'); ?>');
|
2424 |
-
|
2425 |
-
jQuery('#panelLoading').remove();
|
2426 |
-
|
2427 |
-
}.on('init'),
|
2428 |
-
|
2429 |
-
prepareData: function(){
|
2430 |
-
// Generate used fonts
|
2431 |
-
var fonts = {},
|
2432 |
-
font_str = '';
|
2433 |
-
MSPanel.Style.find().forEach(function(record){
|
2434 |
-
var font = record.get('fontFamily'),
|
2435 |
-
weight = record.get('fontWeight');
|
2436 |
-
|
2437 |
-
if( !Ember.isEmpty(font) ){
|
2438 |
-
|
2439 |
-
if( !fonts[font] ){
|
2440 |
-
fonts[font] = [];
|
2441 |
-
}
|
2442 |
-
|
2443 |
-
if( weight === 'normal' ){
|
2444 |
-
weight = 'regular';
|
2445 |
-
}
|
2446 |
-
|
2447 |
-
if( !Ember.isEmpty(weight) && fonts[font].indexOf(weight) === -1 ) {
|
2448 |
-
fonts[font].push(weight);
|
2449 |
-
}
|
2450 |
-
}
|
2451 |
-
});
|
2452 |
-
|
2453 |
-
for(var font in fonts){
|
2454 |
-
font_str += font.replace(/\s/, '+') + ':' + fonts[font].join(',') + '|';
|
2455 |
-
}
|
2456 |
-
|
2457 |
-
MSPanel.Settings.find(1).set('usedFonts', font_str.slice(0,-1));
|
2458 |
-
|
2459 |
-
// save all models
|
2460 |
-
|
2461 |
-
// settings
|
2462 |
-
this.saveRecords(MSPanel.Settings.find());
|
2463 |
-
// slides
|
2464 |
-
this.saveRecords(MSPanel.Slide.find());
|
2465 |
-
/*// layer
|
2466 |
-
this.saveRecords(MSPanel.Layer.find());
|
2467 |
-
// style
|
2468 |
-
this.saveRecords(MSPanel.Style.find());
|
2469 |
-
// effect
|
2470 |
-
this.saveRecords(MSPanel.Effect.find());
|
2471 |
-
// preset style
|
2472 |
-
this.saveRecords(MSPanel.PresetStyle.find());
|
2473 |
-
// preset effect
|
2474 |
-
this.saveRecords(MSPanel.PresetEffect.find());*/
|
2475 |
-
// control
|
2476 |
-
this.saveRecords(MSPanel.Control.find());
|
2477 |
-
// callback functions
|
2478 |
-
this.saveRecords(MSPanel.Callback.find());
|
2479 |
-
// button classes
|
2480 |
-
//this.saveRecords(MSPanel.ButtonStyle.find());
|
2481 |
-
|
2482 |
-
//console.log('saving data');
|
2483 |
-
},
|
2484 |
-
|
2485 |
-
generateButtonStyles: function(){
|
2486 |
-
var styles = MSPanel.ButtonStyle.find(),
|
2487 |
-
css = '',
|
2488 |
-
$styleElement = $('#msp-buttons');
|
2489 |
-
|
2490 |
-
styles.forEach(function(style){
|
2491 |
-
css += '.' + style.get('className') + ' {'+
|
2492 |
-
style.get('normal')+
|
2493 |
-
'}\n'+
|
2494 |
-
|
2495 |
-
'.' + style.get('className') + ':hover {'+
|
2496 |
-
style.get('hover')+
|
2497 |
-
'}\n'+
|
2498 |
-
'.' + style.get('className') + ':active {'+
|
2499 |
-
style.get('active')+
|
2500 |
-
'}\n';
|
2501 |
-
});
|
2502 |
-
|
2503 |
-
if( $styleElement.length === 0 ) {
|
2504 |
-
$styleElement = $('<style id="msp-buttons"></style>').text(css).appendTo($('head'));
|
2505 |
-
} else {
|
2506 |
-
$styleElement.text(css);
|
2507 |
-
}
|
2508 |
-
},
|
2509 |
-
|
2510 |
-
actions: {
|
2511 |
-
saveAll: function(){
|
2512 |
-
this.prepareData();
|
2513 |
-
this.sendData();
|
2514 |
-
},
|
2515 |
-
|
2516 |
-
showPreview: function(event){
|
2517 |
-
if(window.lunchMastersliderPreview){
|
2518 |
-
lunchMastersliderPreview(event);
|
2519 |
-
}
|
2520 |
-
}
|
2521 |
-
},
|
2522 |
-
|
2523 |
-
saveRecords: function(records){
|
2524 |
-
records.forEach(function(record){ record.save(); });
|
2525 |
-
},
|
2526 |
-
|
2527 |
-
/**
|
2528 |
-
* Send Data to WP Admin
|
2529 |
-
* @since 1.0.0
|
2530 |
-
* @return {null}
|
2531 |
-
*/
|
2532 |
-
sendData: function(){
|
2533 |
-
|
2534 |
-
this.set('statusMsg', __MSP_LAN.ap_001);
|
2535 |
-
this.set('isSending', true);
|
2536 |
-
var that = this;
|
2537 |
-
|
2538 |
-
|
2539 |
-
jQuery.post(
|
2540 |
-
__MS.ajax_url,
|
2541 |
-
{
|
2542 |
-
action : 'msp_panel_handler', // the handler
|
2543 |
-
nonce : jQuery('#msp-main-wrapper').data('nonce'), // the generated nonce value
|
2544 |
-
msp_data : B64.encode(JSON.stringify(MSPanel.data)),
|
2545 |
-
preset_style : B64.encode(JSON.stringify(MSPanel.PSData)),
|
2546 |
-
preset_effect : B64.encode(JSON.stringify(MSPanel.PEData)),
|
2547 |
-
buttons : B64.encode(JSON.stringify(MSPanel.PBData)),
|
2548 |
-
slider_id : MSPanel.SliderID,
|
2549 |
-
},
|
2550 |
-
function(res){
|
2551 |
-
that.set('statusMsg', res.message);
|
2552 |
-
that.set('isSending', false);
|
2553 |
-
/*if( res.success === true ){
|
2554 |
-
that.set('statusMsg', __MSP_LAN.ap_003);
|
2555 |
-
that.set('isSending', false);
|
2556 |
-
}else{
|
2557 |
-
that.set('isSending', false);
|
2558 |
-
that.set('statusMsg', __MSP_LAN.ap_002);
|
2559 |
-
}*/
|
2560 |
-
}
|
2561 |
-
);
|
2562 |
-
}
|
2563 |
-
|
2564 |
-
});
|
2565 |
-
|
2566 |
-
|
2567 |
-
//js\mspanel\controllers\SettingsController.js
|
2568 |
-
|
2569 |
-
|
2570 |
-
/**
|
2571 |
-
* Master Slider Settings Controller
|
2572 |
-
* @package MSPanel
|
2573 |
-
* @extends {Ember.Controller}
|
2574 |
-
*/
|
2575 |
-
MSPanel.SettingsController = Ember.ObjectController.extend({
|
2576 |
-
|
2577 |
-
customSlider : window.__MSP_TYPE && window.__MSP_TYPE === 'custom',
|
2578 |
-
templateSlider : window.__MSP_TYPE && ( window.__MSP_TYPE === 'flickr' || window.__MSP_TYPE === 'post' || window.__MSP_TYPE === 'wc-product' || window.__MSP_TYPE === 'facebook'),
|
2579 |
-
|
2580 |
-
sliderSkins : __MSP_SKINS,
|
2581 |
-
|
2582 |
-
|
2583 |
-
needs: ['application', 'controls'],
|
2584 |
-
msTemplateName: null,
|
2585 |
-
msTemplateImg: null,
|
2586 |
-
draftMSTemplate:null,
|
2587 |
-
templates: MSPanel.SliderTemplates,
|
2588 |
-
|
2589 |
-
showAutoHeight: false,
|
2590 |
-
showNearbyNum: false,
|
2591 |
-
showWrapperWidth: false,
|
2592 |
-
preloadMethod: null,
|
2593 |
-
|
2594 |
-
/**
|
2595 |
-
* Setup controller init values
|
2596 |
-
* It called from ember router in MSPanel.js
|
2597 |
-
*/
|
2598 |
-
setup: function(){
|
2599 |
-
// read preload valu from model and setup preload select list
|
2600 |
-
var preload = this.get('preload');
|
2601 |
-
if( preload === 'all' || preload === '-1' ){
|
2602 |
-
this.set('preloadMethod' , preload);
|
2603 |
-
} else {
|
2604 |
-
this.set('preloadMethod' , 'nearby');
|
2605 |
-
}
|
2606 |
-
|
2607 |
-
this.set('draftMSTemplate', this.get('msTemplate'));
|
2608 |
-
this.updateTemplate(true);
|
2609 |
-
},
|
2610 |
-
|
2611 |
-
/**
|
2612 |
-
* Remove autoheight option if layout style is fullscreen or autofill
|
2613 |
-
*/
|
2614 |
-
sliderLayoutChanged: function(){
|
2615 |
-
var layout = this.get('layout');
|
2616 |
-
if( layout === 'fullscreen' || layout === 'autofill' ) {
|
2617 |
-
this.set('showAutoHeight' , false);
|
2618 |
-
this.set('autoHeight' , false);
|
2619 |
-
} else {
|
2620 |
-
this.set('showAutoHeight' , true);
|
2621 |
-
}
|
2622 |
-
|
2623 |
-
this.set('showWrapperWidth', layout === 'boxed' || layout === 'partialview');
|
2624 |
-
|
2625 |
-
/* if( layout === 'boxed' && Ember.isEmpty(this.get('wrapperWidth')) ){
|
2626 |
-
this.set('wrapperWidth', this.get('width'));
|
2627 |
-
this.set('wrapperWidthUnit', 'px');
|
2628 |
-
}
|
2629 |
-
|
2630 |
-
if( layout === 'partialview' && Ember.isEmpty(this.get('wrapperWidth')) ){
|
2631 |
-
this.set('wrapperWidth', '100');
|
2632 |
-
this.set('wrapperWidthUnit', '%');
|
2633 |
-
}*/
|
2634 |
-
|
2635 |
-
this.set('showFSMargin', layout === 'fullscreen');
|
2636 |
-
|
2637 |
-
}.observes('layout').on('setup'),
|
2638 |
-
|
2639 |
-
/**
|
2640 |
-
* controll preloading method
|
2641 |
-
*/
|
2642 |
-
preloadSetup: function(){
|
2643 |
-
var preloadMethod = this.get('preloadMethod');
|
2644 |
-
|
2645 |
-
if( preloadMethod === 'nearby' ) {
|
2646 |
-
this.set('showNearbyNum' , true);
|
2647 |
-
var preload = this.get('preload');
|
2648 |
-
if(preload === 'all' || preload === '-1'){
|
2649 |
-
this.set('preload' , '0');
|
2650 |
-
}
|
2651 |
-
} else {
|
2652 |
-
this.set('showNearbyNum' , false);
|
2653 |
-
this.set('preload' , preloadMethod);
|
2654 |
-
}
|
2655 |
-
|
2656 |
-
}.observes('preloadMethod').on('setup'),
|
2657 |
-
|
2658 |
-
updateTemplate: function(init){
|
2659 |
-
var templateObject,
|
2660 |
-
msTemplate = this.get('msTemplate');
|
2661 |
-
|
2662 |
-
this.get('templates').forEach(function(template){
|
2663 |
-
if( template.value === msTemplate ) {
|
2664 |
-
templateObject = template;
|
2665 |
-
return;
|
2666 |
-
}
|
2667 |
-
});
|
2668 |
-
|
2669 |
-
if( templateObject ){
|
2670 |
-
this.set('msTemplateName', templateObject.name);
|
2671 |
-
this.set('msTemplateImg', templateObject.img);
|
2672 |
-
this.set('msTemplateClass', templateObject.className);
|
2673 |
-
this.set('controllers.application.disableControls', templateObject.disableControls );
|
2674 |
-
this.set('disableControls', templateObject.disableControls );
|
2675 |
-
|
2676 |
-
if(!init){
|
2677 |
-
var controllController = this.get('controllers.controls'),
|
2678 |
-
controlObj,
|
2679 |
-
control;
|
2680 |
-
// remove added controls
|
2681 |
-
var controls = MSPanel.Control.find();
|
2682 |
-
|
2683 |
-
while(controls.get('firstObject')){
|
2684 |
-
var control = controls.get('firstObject');
|
2685 |
-
|
2686 |
-
controllController.findControlObj(control.get('name')).used = false;
|
2687 |
-
control.deleteRecord();
|
2688 |
-
}
|
2689 |
-
|
2690 |
-
// create template controls
|
2691 |
-
for (var controlName in templateObject.controls){
|
2692 |
-
controlObj = controllController.findControlObj(controlName);
|
2693 |
-
control = MSPanel.Control.create($.extend(true, controllController.getDefaultValues(controlName), templateObject.controls[controlName]));
|
2694 |
-
control.set('label', controlObj.label);
|
2695 |
-
controlObj.used = true;
|
2696 |
-
control.save();
|
2697 |
-
}
|
2698 |
-
|
2699 |
-
// update slider settings
|
2700 |
-
for(var option in templateObject.settings){
|
2701 |
-
this.set(option, templateObject.settings[option]);
|
2702 |
-
}
|
2703 |
-
}
|
2704 |
-
|
2705 |
-
} else { // template not found! so lets select custom template
|
2706 |
-
this.set('draftMSTemplate', 'custom');
|
2707 |
-
this.updateTemplate();
|
2708 |
-
}
|
2709 |
-
|
2710 |
-
|
2711 |
-
},
|
2712 |
-
|
2713 |
-
actions: {
|
2714 |
-
|
2715 |
-
openTemplates: function(){
|
2716 |
-
var templatesView = MSPanel.TemplatesView.create({
|
2717 |
-
controller: this
|
2718 |
-
});
|
2719 |
-
|
2720 |
-
this.get('mainView').createChildView(templatesView);
|
2721 |
-
this.set('templatesView', templatesView);
|
2722 |
-
|
2723 |
-
templatesView.appendTo(MSPanel.rootElement);
|
2724 |
-
},
|
2725 |
-
|
2726 |
-
closeTemplates: function(){
|
2727 |
-
this.get('templatesView').destroy();
|
2728 |
-
|
2729 |
-
// rollback to current template
|
2730 |
-
this.set('draftMSTemplate', this.get('msTemplate'));
|
2731 |
-
},
|
2732 |
-
|
2733 |
-
saveTemplate: function(){
|
2734 |
-
if( this.get('draftMSTemplate') === this.get('msTemplate') ){
|
2735 |
-
this.send('closeTemplates');
|
2736 |
-
return;
|
2737 |
-
}
|
2738 |
-
|
2739 |
-
if( confirm(__MSP_LAN.tv_002) ){
|
2740 |
-
// update msTemplate
|
2741 |
-
this.set('msTemplate', this.get('draftMSTemplate'));
|
2742 |
-
this.send('closeTemplates');
|
2743 |
-
this.updateTemplate();
|
2744 |
-
}
|
2745 |
-
}
|
2746 |
-
}
|
2747 |
-
});
|
2748 |
-
//js\mspanel\controllers\SlidesController.js
|
2749 |
-
|
2750 |
-
MSPanel.SlidesController = Ember.ArrayController.extend({
|
2751 |
-
|
2752 |
-
customSlider : window.__MSP_TYPE && window.__MSP_TYPE === 'custom',
|
2753 |
-
|
2754 |
-
_order : -1,
|
2755 |
-
|
2756 |
-
sortProperties: ['order'],
|
2757 |
-
mainView: null, // main view object which will be setted by MSPanel.SlidesView
|
2758 |
-
|
2759 |
-
currentSlide: null,
|
2760 |
-
|
2761 |
-
setup: function(){
|
2762 |
-
if( this.get('length') === 0 ){
|
2763 |
-
this.send('newSlide');
|
2764 |
-
} else {
|
2765 |
-
var slide = this.get('firstObject');
|
2766 |
-
this.set('currentSlide' , slide);
|
2767 |
-
}
|
2768 |
-
|
2769 |
-
// slider type
|
2770 |
-
if( Ember.isEmpty(this.get('sliderSettings.type')) ){
|
2771 |
-
this.set('sliderSettings.type', __MSP_TYPE);
|
2772 |
-
}
|
2773 |
-
|
2774 |
-
this.set('sliderSettings.sliderId', MSPanel.SliderID);
|
2775 |
-
|
2776 |
-
this.updateOrder();
|
2777 |
-
//this.set('_order', this.get('lastObject.order'));
|
2778 |
-
},
|
2779 |
-
|
2780 |
-
duplicateSlide : function(slide){
|
2781 |
-
var slideProp = slide.toJSON();
|
2782 |
-
delete slideProp.id;
|
2783 |
-
delete slideProp.layers;
|
2784 |
-
|
2785 |
-
var newSlide = MSPanel.Slide.create(slideProp);
|
2786 |
-
|
2787 |
-
// insert after
|
2788 |
-
newSlide.set('order' , slide.get('order') + 1);
|
2789 |
-
|
2790 |
-
// update order
|
2791 |
-
this.forEach(function(_slide){
|
2792 |
-
var slide_order = _slide.get('order'),
|
2793 |
-
nslide_order = newSlide.get('order');
|
2794 |
-
|
2795 |
-
if(slide_order >= nslide_order && _slide !== newSlide)
|
2796 |
-
_slide.set('order' , slide_order + 1);
|
2797 |
-
});
|
2798 |
-
|
2799 |
-
newSlide.save();
|
2800 |
-
this.updateOrder();
|
2801 |
-
},
|
2802 |
-
|
2803 |
-
updateSlidesSort : function(indexes) {
|
2804 |
-
this.beginPropertyChanges();
|
2805 |
-
|
2806 |
-
this.forEach(function(slide) {
|
2807 |
-
slide.set('order', indexes[slide.get('id')]);
|
2808 |
-
}, this);
|
2809 |
-
this.endPropertyChanges();
|
2810 |
-
this.set('_order', this.get('lastObject.order'));
|
2811 |
-
},
|
2812 |
-
|
2813 |
-
updateOrder: function(){
|
2814 |
-
var i = 0;
|
2815 |
-
this.forEach(function(slide){
|
2816 |
-
slide.set('order', i++);
|
2817 |
-
});
|
2818 |
-
|
2819 |
-
this.set('_order', i - 1);
|
2820 |
-
},
|
2821 |
-
|
2822 |
-
removeSlide : function(slide){
|
2823 |
-
|
2824 |
-
slide.deleteRecord();
|
2825 |
-
|
2826 |
-
if(this.get('length') === 0){
|
2827 |
-
this.send('newSlide');
|
2828 |
-
}else{
|
2829 |
-
this.send('select' , this.get('firstObject'));
|
2830 |
-
}
|
2831 |
-
|
2832 |
-
this.updateOrder();
|
2833 |
-
},
|
2834 |
-
|
2835 |
-
actions: {
|
2836 |
-
|
2837 |
-
newSlide : function(){
|
2838 |
-
var slide = MSPanel.Slide.create({order: this.get('_order') + 1});
|
2839 |
-
this.set('currentSlide' , slide);
|
2840 |
-
this.set('_order' , this.get('_order') + 1);
|
2841 |
-
slide.save();
|
2842 |
-
},
|
2843 |
-
|
2844 |
-
select : function(slide){
|
2845 |
-
if(slide === this.get('currentSlide')) return;
|
2846 |
-
this.set('currentSlide' , slide);
|
2847 |
-
}
|
2848 |
-
}
|
2849 |
-
});
|
2850 |
-
//js\mspanel\controllers\ControlsController.js
|
2851 |
-
|
2852 |
-
/**
|
2853 |
-
* Master Slider Panel, Slider Controls controller
|
2854 |
-
* @package MSPanel
|
2855 |
-
* @author Averta
|
2856 |
-
* @version 1.0b
|
2857 |
-
*/
|
2858 |
-
MSPanel.ControlsController = Ember.ArrayController.extend({
|
2859 |
-
|
2860 |
-
needs: 'application',
|
2861 |
-
|
2862 |
-
controls: [
|
2863 |
-
{used:false, label:__MSP_LAN.cc_001, value:'arrows'},
|
2864 |
-
{used:false, label:__MSP_LAN.cc_002, value:'timebar'},
|
2865 |
-
{used:false, label:__MSP_LAN.cc_003, value:'bullets'},
|
2866 |
-
{used:false, label:__MSP_LAN.cc_004, value:'circletimer'},
|
2867 |
-
{used:false, label:__MSP_LAN.cc_005, value:'scrollbar'},
|
2868 |
-
{used:false, label:__MSP_LAN.cc_006, value:'slideinfo'},
|
2869 |
-
{used:false, label:__MSP_LAN.cc_007, value:'thumblist'}
|
2870 |
-
],
|
2871 |
-
|
2872 |
-
selectedControl: null, // selected control in combo box
|
2873 |
-
|
2874 |
-
availableControls: [], // already added to slider
|
2875 |
-
|
2876 |
-
noMore: false,
|
2877 |
-
|
2878 |
-
currentControl: null, // current active control
|
2879 |
-
|
2880 |
-
setup: function(){
|
2881 |
-
var that = this;
|
2882 |
-
this.forEach(function(control){
|
2883 |
-
that.findControlObj(control.get('name')).used = true;
|
2884 |
-
});
|
2885 |
-
this.set('availableControls', this.findAvailableControls());
|
2886 |
-
},
|
2887 |
-
|
2888 |
-
actions: {
|
2889 |
-
|
2890 |
-
addControl: function(){
|
2891 |
-
|
2892 |
-
var controlName = this.get('selectedControl'),
|
2893 |
-
controlObj = this.findControlObj(controlName),
|
2894 |
-
control;
|
2895 |
-
|
2896 |
-
// create control object
|
2897 |
-
control = MSPanel.Control.create(this.getDefaultValues(controlName));
|
2898 |
-
control.set('label', controlObj.label);
|
2899 |
-
|
2900 |
-
controlObj.used = true;
|
2901 |
-
this.set('availableControls', this.findAvailableControls());
|
2902 |
-
control.save();
|
2903 |
-
|
2904 |
-
this.set('currentControl', control);
|
2905 |
-
},
|
2906 |
-
|
2907 |
-
removeControl: function(control){
|
2908 |
-
this.findControlObj(control.get('name')).used = false;
|
2909 |
-
this.set('availableControls', this.findAvailableControls());
|
2910 |
-
control.deleteRecord();
|
2911 |
-
|
2912 |
-
this.set('currentControl', this.get('firstObject'));
|
2913 |
-
this.send('showControlOptions');
|
2914 |
-
},
|
2915 |
-
|
2916 |
-
showControlOptions: function(){
|
2917 |
-
var currentControl = this.get('currentControl');
|
2918 |
-
|
2919 |
-
if( Ember.isEmpty(currentControl) ){
|
2920 |
-
this.set('controlOptions', 'empty-template');
|
2921 |
-
} else {
|
2922 |
-
this.set('controlOptions', currentControl.get('name') + '-options');
|
2923 |
-
}
|
2924 |
-
}
|
2925 |
-
|
2926 |
-
},
|
2927 |
-
|
2928 |
-
/**
|
2929 |
-
* Find selected control from controls
|
2930 |
-
* @param {string} control
|
2931 |
-
* @return {object}
|
2932 |
-
*/
|
2933 |
-
findControlObj: function(control){
|
2934 |
-
var controls = this.get('controls');
|
2935 |
-
for(var i=0,l=controls.length; i!==l; i++){
|
2936 |
-
if( controls[i].value === control ){
|
2937 |
-
return controls[i];
|
2938 |
-
}
|
2939 |
-
}
|
2940 |
-
|
2941 |
-
return null;
|
2942 |
-
},
|
2943 |
-
|
2944 |
-
findAvailableControls: function(){
|
2945 |
-
var avc = [],
|
2946 |
-
controls = this.get('controls');
|
2947 |
-
for(var i=0,l=controls.length; i!==l; i++){
|
2948 |
-
if( !controls[i].used ){
|
2949 |
-
avc.push(controls[i]);
|
2950 |
-
}
|
2951 |
-
}
|
2952 |
-
|
2953 |
-
this.set('noMore', avc.length === 0);
|
2954 |
-
this.set('selectedControl', avc[0]?avc[0].value:null);
|
2955 |
-
|
2956 |
-
return avc;
|
2957 |
-
},
|
2958 |
-
|
2959 |
-
/**
|
2960 |
-
* creates an object of default values for new control
|
2961 |
-
* @param {Control} control
|
2962 |
-
* @return {Object}
|
2963 |
-
*/
|
2964 |
-
getDefaultValues: function(control){
|
2965 |
-
var values = {name:control};
|
2966 |
-
|
2967 |
-
values.inset = !(control === 'slideinfo' || control === 'thumblist');
|
2968 |
-
|
2969 |
-
switch(control){
|
2970 |
-
case 'timebar':
|
2971 |
-
values.align = 'bottom';
|
2972 |
-
values.color = '#FFFFFF';
|
2973 |
-
values.autoHide = false;
|
2974 |
-
values.width = 4;
|
2975 |
-
break;
|
2976 |
-
case 'bullets':
|
2977 |
-
values.align = 'bottom';
|
2978 |
-
values.dir = 'h';
|
2979 |
-
values.margin = 10;
|
2980 |
-
break;
|
2981 |
-
case 'circletimer':
|
2982 |
-
//values.align = 'tl';
|
2983 |
-
values.color = '#A2A2A2';
|
2984 |
-
values.stroke = 10;
|
2985 |
-
values.radius = 4;
|
2986 |
-
values.autoHide = false;
|
2987 |
-
break;
|
2988 |
-
case 'scrollbar':
|
2989 |
-
values.align = 'top';
|
2990 |
-
values.dir = 'h';
|
2991 |
-
values.color = '#3D3D3D';
|
2992 |
-
values.margin = 10;
|
2993 |
-
values.autoHide = false;
|
2994 |
-
values.width = 4;
|
2995 |
-
break;
|
2996 |
-
case 'slideinfo':
|
2997 |
-
values.align = 'bottom';
|
2998 |
-
values.margin = 10;
|
2999 |
-
values.autoHide = false;
|
3000 |
-
break;
|
3001 |
-
case 'thumblist':
|
3002 |
-
values.align = 'bottom';
|
3003 |
-
values.space = 5;
|
3004 |
-
values.width = 100;
|
3005 |
-
values.height = 80;
|
3006 |
-
values.margin = 10;
|
3007 |
-
values.fillMode = 'fill';
|
3008 |
-
values.autoHide = false;
|
3009 |
-
break;
|
3010 |
-
}
|
3011 |
-
|
3012 |
-
return values;
|
3013 |
-
}
|
3014 |
-
|
3015 |
-
});
|
3016 |
-
//js\mspanel\controllers\CallbacksController.js
|
3017 |
-
|
3018 |
-
/**
|
3019 |
-
* Master Slider Panel Callbacks controller
|
3020 |
-
* @package MSPanel
|
3021 |
-
* @version 1.0
|
3022 |
-
* @author Averta
|
3023 |
-
*/
|
3024 |
-
|
3025 |
-
MSPanel.CallbacksController = Ember.ArrayController.extend({
|
3026 |
-
|
3027 |
-
callbacks: [
|
3028 |
-
{used: false, label:__MSP_LAN.cb_011, value:'INIT'},
|
3029 |
-
{used: false, label:__MSP_LAN.cb_001, value:'CHANGE_START'},
|
3030 |
-
{used: false, label:__MSP_LAN.cb_002, value:'CHANGE_END'},
|
3031 |
-
{used: false, label:__MSP_LAN.cb_003, value:'WAITING'},
|
3032 |
-
{used: false, label:__MSP_LAN.cb_004, value:'RESIZE'},
|
3033 |
-
{used: false, label:__MSP_LAN.cb_005, value:'VIDEO_PLAY'},
|
3034 |
-
{used: false, label:__MSP_LAN.cb_006, value:'VIDEO_CLOSE'},
|
3035 |
-
{used: false, label:__MSP_LAN.cb_007, value:'SWIPE_START'},
|
3036 |
-
{used: false, label:__MSP_LAN.cb_008, value:'SWIPE_MOVE'},
|
3037 |
-
{used: false, label:__MSP_LAN.cb_009, value:'SWIPE_END'}
|
3038 |
-
],
|
3039 |
-
|
3040 |
-
availableCallbacks: [],
|
3041 |
-
noMore: false,
|
3042 |
-
selectedCallback: null, // selected callback in combo box
|
3043 |
-
|
3044 |
-
setup: function(){
|
3045 |
-
var that = this;
|
3046 |
-
this.forEach(function(callback){
|
3047 |
-
that.findCallbackObj(callback.get('name')).used = true;
|
3048 |
-
});
|
3049 |
-
this.set('availableCallbacks', this.findAvailableCallbacks());
|
3050 |
-
},
|
3051 |
-
|
3052 |
-
actions: {
|
3053 |
-
addCallback: function(){
|
3054 |
-
var callbackName = this.get('selectedCallback'),
|
3055 |
-
callbackObj = this.findCallbackObj(callbackName),
|
3056 |
-
callback;
|
3057 |
-
|
3058 |
-
// create callback object
|
3059 |
-
callback = MSPanel.Callback.create({
|
3060 |
-
name:callbackObj.value,
|
3061 |
-
label:callbackObj.label
|
3062 |
-
});
|
3063 |
-
|
3064 |
-
callbackObj.used = true;
|
3065 |
-
this.set('availableCallbacks', this.findAvailableCallbacks());
|
3066 |
-
callback.save();
|
3067 |
-
},
|
3068 |
-
|
3069 |
-
removeCallback: function(callback){
|
3070 |
-
if( confirm(__MSP_LAN.cb_010.jfmt(callback.get('label'))) ){
|
3071 |
-
this.findCallbackObj(callback.get('name')).used = false;
|
3072 |
-
this.set('availableCallbacks', this.findAvailableCallbacks());
|
3073 |
-
callback.deleteRecord();
|
3074 |
-
}
|
3075 |
-
}
|
3076 |
-
|
3077 |
-
},
|
3078 |
-
|
3079 |
-
/**
|
3080 |
-
* Find selected callback from callbacks
|
3081 |
-
* @param {string} callback
|
3082 |
-
* @return {object}
|
3083 |
-
*/
|
3084 |
-
findCallbackObj: function(callback){
|
3085 |
-
var callbacks = this.get('callbacks');
|
3086 |
-
for(var i=0,l=callbacks.length; i!==l; i++){
|
3087 |
-
if( callbacks[i].value === callback ){
|
3088 |
-
return callbacks[i];
|
3089 |
-
}
|
3090 |
-
}
|
3091 |
-
return null;
|
3092 |
-
},
|
3093 |
-
|
3094 |
-
findAvailableCallbacks: function(){
|
3095 |
-
var avc = [],
|
3096 |
-
callbacks = this.get('callbacks');
|
3097 |
-
for(var i=0,l=callbacks.length; i!==l; i++){
|
3098 |
-
if( !callbacks[i].used ){
|
3099 |
-
avc.push(callbacks[i]);
|
3100 |
-
}
|
3101 |
-
}
|
3102 |
-
|
3103 |
-
this.set('noMore', avc.length === 0);
|
3104 |
-
this.set('selectedCallback', avc[0]?avc[0].value:null);
|
3105 |
-
return avc;
|
3106 |
-
},
|
3107 |
-
|
3108 |
-
});
|
1 |
+
/*!
|
2 |
+
* @overview Master Slider Lite Wordpress Panel
|
3 |
+
* @copyright Copyright 2014 Averta Ltd.
|
4 |
+
* @version 1.0
|
5 |
+
* http://www.averta.net
|
6 |
+
*/
|
7 |
+
function WPEditorTemplate(n){var t=$(hiddenEditor);return t.find("link").remove(),t.html().replace(/msp-hidden/g,n)}var hiddenEditor,__tmc_msp_id;window.MSPanel=Ember.Application.create({rootElement:"#msp-root"}),MSPanel.version="1.0",MSPanel.SliderID=parseQueryString(window.location.search).slider_id||__MSP_SLIDER_ID||"100",String.prototype.jfmt=function(){return"".fmt.apply(this.replace(/%s|%d/,"%@"),arguments)},$=jQuery.noConflict(),jQuery.ui.dialog.prototype._focusTabbable=function(){},MSPanel.Router.map(function(){this.resource("settings"),this.resource("slides",{path:"/"}),this.resource("controls"),this.resource("callbacks"),this.resource("error")}),MSPanel.Router.reopen({location:"none"}),MSPanel.ApplicationRoute=Ember.Route.extend({model:function(){var n=MSPanel.Settings.find();n.get("length")===0&&MSPanel.Settings.create().save()}}),MSPanel.SettingsRoute=Ember.Route.extend({model:function(){return MSPanel.Settings.find(1)},setupController:function(n,t){n.set("model",t),n.setup()}}),MSPanel.SlidesRoute=Ember.Route.extend({model:function(){return MSPanel.Slide.find()},setupController:function(n,t){n.set("model",t),n.set("sliderSettings",MSPanel.Settings.find(1)),n.setup()}}),MSPanel.ControlsRoute=Ember.Route.extend({model:function(){return MSPanel.Control.find()},setupController:function(n,t){n.set("model",t),n.setup(),this.activate()},activate:function(){var n=this.get("controller");n&&n.set("controlOptions","empty-template")}}),MSPanel.CallbacksRoute=Ember.Route.extend({model:function(){return MSPanel.Callback.find()},setupController:function(n,t){n.set("model",t),n.setup()}}),function(){var n=Ember.attr,f=Ember.hasMany,r=Ember.belongsTo,u=/https\:|http\:/,t={serialize:function(n){return n==undefined?n:u.test(n)?n.replace(__MS.upload_dir,""):n},deserialize:function(n){return n==undefined?n:u.test(n)?n:__MS.upload_dir+n}},i;MSPanel.Settings=Ember.Model.extend({id:n("number"),snapping:n("boolean",{defaultValue:!0}),bgImageThumb:n(t),disableControls:n("boolean",{defaultValue:!1}),name:n("string",{defaultValue:__MSP_LAN.sm_001}),width:n("number",{defaultValue:1e3}),height:n("number",{defaultValue:500}),wrapperWidth:n("number"),wrapperWidthUnit:n("string",{defaultValue:"px"}),autoCrop:n("boolean",{defaultValue:!1}),type:n("string"),sliderId:n("string"),layout:n("string",{defaultValue:"boxed"}),autoHeight:n("boolean",{defaultValue:!1}),trView:n("string",{defaultValue:"basic"}),speed:n("number",{defaultValue:20}),space:n("number",{defaultValue:0}),start:n("number",{defaultValue:1}),grabCursor:n("boolean",{defaultValue:!0}),swipe:n("boolean",{defaultValue:!0}),mouse:n("boolean",{defaultValue:!0}),wheel:n("boolean",{defaultValue:!1}),autoplay:n("boolean",{defaultValue:!1}),loop:n("boolean",{defaultValue:!1}),shuffle:n("boolean",{defaultValue:!1}),preload:n("string",{defaultValue:"-1"}),overPause:n("boolean",{defaultValue:!0}),endPause:n("boolean",{defaultValue:!1}),hideLayers:n("boolean",{defaultValue:!1}),dir:n("string",{defaultValue:"h"}),parallaxMode:n("srting",{defaultValue:"swipe"}),centerControls:n("boolean",{defaultValue:!0}),instantShowLayers:n("boolean",{defaultValue:!1}),fullscreenMargin:n("number"),inlineStyle:n("string"),className:n("string"),bgColor:n("string"),bgImage:n(t),skin:n("string",{defaultValue:"ms-skin-default"}),msTemplate:n("string",{defaultValue:"custom"}),msTemplateClass:n("string",{defaultValue:""}),usedFonts:n("string"),apiKey:n("string"),setId:n("string"),setType:n("string"),imgCount:n("number"),thumbSize:n("srting"),imgSize:n("string"),postType:n("string"),postCats:n(Array),postTags:n(Array),postCount:n("number"),postImageType:n("string"),postOrder:n("string"),postOrderDir:n("string"),postExcerptLen:n("number"),postExcludeIds:n("string"),postOffset:n("number"),postLinkSlide:n("boolean"),postLinkTarget:n("string"),postSlideBg:n("string"),postSlideBgthumb:n("string"),wcOnlyInstock:n("boolean"),wcOnlyFeatured:n("boolean"),wcOnlyOnsale:n("boolean")}),MSPanel.Slide=Ember.Model.extend({id:n("number"),timeline_h:n("number",{defaultValue:200}),bgThumb:n(t),thumbOrginal:n(t),order:n("number"),ishide:n("boolean"),bg:n(t),duration:n("number",{defaultValue:3}),fillMode:n("string",{defaultValue:"fill"}),thumb:n(t),info:n("string"),link:n("string"),linkTarget:n("string"),video:n("string"),bgColor:n("string"),bgv_mp4:n("string"),bgv_ogg:n("string"),bgv_webm:n("string"),bgv_fillmode:n("string",{defaultValue:"fill"}),bgv_loop:n("boolean",{defaultValue:!0}),bgv_mute:n("boolean",{defaultValue:!0}),bgv_autopause:n("boolean",{defaultValue:!1}),cssId:n("string"),cssClass:n("string"),bgAlt:n("string"),layers:f("MSPanel.Layer",{key:"layer_ids"})}),MSPanel.Layer=Ember.Model.extend({id:n("number"),name:n("string"),isLocked:n("boolean",{defaultValue:!1}),isHided:n("boolean",{defaultValue:!1}),isSoloed:n("boolean",{defaultValue:!1}),slide:r("MSPanel.Slide",{key:"slide"}),styleModel:r("MSPanel.Style",{key:"styleModel",embedded:!1}),showEffect:r("MSPanel.Effect",{key:"showEffect",embedded:!1}),showTransform:n("string",{defaultValue:""}),showOrigin:n("string",{defaultValue:""}),showFade:n("boolean",{defaultValue:!0}),hideEffect:r("MSPanel.Effect",{key:"hideEffect",embedded:!1}),hideTransform:n("string",{defaultValue:""}),hideOrigin:n("string",{defaultValue:""}),hideFade:n("boolean",{defaultValue:!0}),imgThumb:n(t),stageOffsetX:n("number",{defaultValue:0}),stageOffsetY:n("number",{defaultValue:0}),order:n("number"),type:n("string"),cssClass:n("string"),cssId:n("string"),title:n("string"),rel:n("string"),content:n("string",{defaultValue:"Lorem Ipsum"}),img:n(t),imgAlt:n("string"),video:n("string",{defaultValue:"http://player.vimeo.com/video/11721242"}),align:n("string",{defaultValue:"top"}),useAction:n("boolean",{defaultValue:!1}),action:n("string"),toSlide:n("number"),link:n("string"),linkTarget:n("string"),offsetX:n("number",{defaultValue:0}),offsetY:n("number",{defaultValue:0}),width:n("number"),height:n("number"),resize:n("boolean",{defaultValue:!0}),fixed:n("boolean",{defaultValue:!1}),widthlimit:n("number",{defaultValue:"0"}),origin:n("string",{defaultValue:"tl"}),stayHover:n("boolean",{defaultValue:!0}),className:n("string"),parallax:n("string"),showDuration:n("number",{defaultValue:1}),showDelay:n("number",{defaultValue:0}),showEase:n("string",{defaultValue:"easeOutQuint"}),showEffFunc:n("string"),useHide:n("boolean",{defaultValue:!1}),hideDuration:n("number",{defaultValue:1}),hideDelay:n("number",{defaultValue:1}),hideEase:n("string",{defaultValue:"easeOutQuint"}),hideEffFunc:n("string"),btnClass:n("string",{defaultValue:"ms-default-btn"})}),MSPanel.Style=Ember.Model.extend({id:n("number"),name:n("string"),type:n("string"),className:n("string"),backgroundColor:n("string"),paddingTop:n("number"),paddingRight:n("number"),paddingBottom:n("number"),paddingLeft:n("number"),borderTop:n("number"),borderRight:n("number"),borderBottom:n("number"),borderLeft:n("number"),borderColor:n("string"),borderRadius:n("number"),borderStyle:n("string"),fontFamily:n("string"),fontWeight:n("string",{defaultValue:"normal"}),fontSize:n("number"),textAlign:n("string"),letterSpacing:n("number"),lineHeight:n("string",{defaultValue:"normal"}),whiteSpace:n("string"),color:n("string"),custom:n("string")}),MSPanel.PresetStyle=MSPanel.Style.extend({}),MSPanel.Effect=Ember.Model.extend({id:n("number"),name:n("string"),type:n("string"),fade:n("boolean",{defaultValue:!0}),translateX:n("number"),translateY:n("number"),translateZ:n("number"),scaleX:n("number"),scaleY:n("number"),rotate:n("number"),rotateX:n("number"),rotateY:n("number"),rotateZ:n("number"),skewX:n("number"),skewY:n("number"),originX:n("number"),originY:n("number"),originZ:n("number")}),MSPanel.PresetEffect=MSPanel.Effect.extend({}),MSPanel.Control=Ember.Model.extend({id:n("number"),label:n("string"),name:n("string"),autoHide:n("boolean",{defaultValue:!0}),overVideo:n("boolean",{defaultValue:!0}),cssClass:n("string"),cssId:n("string"),margin:n("number"),dir:n("string"),color:n("string"),radius:n("number"),stroke:n("number"),speed:n("number"),space:n("number"),type:n("string"),width:n("number"),height:n("number"),align:n("string"),inset:n("boolean"),size:n("number"),hideUnder:n("number"),fillMode:n("string")}),MSPanel.Callback=Ember.Model.extend({id:n("number"),label:n("string"),name:n("string"),content:n("string",{defaultValue:"function(event){\n var api = event.target;\n}"})}),MSPanel.ButtonStyle=Ember.Model.extend({id:n("number"),className:n("string"),normal:n("string"),hover:n("string"),active:n("string")}),i=function(n){var t=B64.decode(n);return t.slice(0,t.lastIndexOf("}")+1)},window.__MSP_PRESET_BUTTON=null,MSPanel.data=__MSP_DATA?JSON.parse(i(__MSP_DATA)):{meta:{}},MSPanel.PSData=__MSP_PRESET_STYLE?JSON.parse(i(__MSP_PRESET_STYLE)):{meta:{}},MSPanel.PEData=__MSP_PRESET_EFFECT?JSON.parse(i(__MSP_PRESET_EFFECT)):{meta:{}},MSPanel.PBData=__MSP_PRESET_BUTTON?JSON.parse(i(__MSP_PRESET_BUTTON)):{meta:{}},MSPanel.Settings.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.data}),MSPanel.Slide.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.data}),MSPanel.Layer.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.data}),MSPanel.Style.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.data}),MSPanel.Effect.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.data}),MSPanel.Control.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.data}),MSPanel.Callback.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.data}),MSPanel.PresetStyle.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.PSData}),MSPanel.PresetEffect.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.PEData}),MSPanel.ButtonStyle.adapter=Ember.OfflineAdapter.create({applicationData:MSPanel.PBData})}(),MSPanel.SliderTemplates=[{name:"Custom Template",value:"custom",className:"",img:__MSP_PATH+"images/templates/custom.gif",controls:null},{name:"3D Flow Carousel",value:"3d-flow-carousel",className:"ms-caro3d-template",img:__MSP_PATH+"images/templates/3d-flow-carousel.png",settings:{space:0,loop:!0,trView:"flow",layout:"partialview",dir:"h",wheel:!1},controls:null},{name:"3D Wave Carousel",value:"3d-wave-carousel",className:"ms-caro3d-template",img:__MSP_PATH+"images/templates/3d-wave-carousel.png",settings:{space:0,loop:!0,trView:"flow",layout:"partialview",dir:"h",wheel:!1},controls:null},{name:"Image Gallery with Thumbs",value:"image-gallery",className:"ms-gallery-template",img:__MSP_PATH+"images/templates/image-gallery.png",settings:{space:0,trView:"basic",skin:"ms-skin-black-2 round-skin"},controls:null,disableControls:!0},{name:"Slider with Bottom Aligned Thumbs",value:"slider-horizontal-thumbs",className:"ms-thumbs-template",img:__MSP_PATH+"images/templates/slider-bottom-thumbs.png",settings:{trView:"scale",space:0},controls:{arrows:{},scrollbar:{dir:"h"},thumblist:{autohide:!1,dir:"h",arrows:!1,align:"bottom",width:127,height:137,margin:5,space:5}}},{name:"Slider with Top Aligned Thumbs",value:"slider-top-thumbs",className:"ms-thumbs-template",img:__MSP_PATH+"images/templates/slider-top-thumbs.png",settings:{trView:"scale",space:0},controls:{arrows:{},scrollbar:{dir:"h"},thumblist:{autohide:!1,dir:"h",arrows:!1,align:"top",width:127,height:137,margin:5,space:5}}},{name:"Slider with Right Aligned Thumbs",value:"slider-vertical-thumbs",className:"ms-thumbs-template",img:__MSP_PATH+"images/templates/slider-right-thumbs.png",settings:null,controls:{arrows:{},scrollbar:{dir:"v"},thumblist:{autohide:!1,dir:"v",arrows:!1,align:"right",width:127,height:137,margin:5,space:5}}},{name:"Slider with Left Aligned Thumbs",value:"slider-left-thumbs",className:"ms-thumbs-template",img:__MSP_PATH+"images/templates/slider-left-thumbs.png",settings:null,controls:{arrows:{},scrollbar:{dir:"v"},thumblist:{autohide:!1,dir:"v",arrows:!1,align:"left",width:127,height:137,margin:5,space:5}}},{name:"Slider with Horizontal Tabs",value:"slider-horizontal-tabs",className:"ms-tabs-template",img:__MSP_PATH+"images/templates/slider-horizontal-tabs.png",settings:null,controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},thumblist:{autohide:!1,dir:"h",type:"tabs",width:240,height:120,align:"bottom",space:0,margin:-12,hideUnder:400}}},{name:"Slider with Vertical Tabs",value:"slider-vertical-tabs",className:"ms-tabs-template",img:__MSP_PATH+"images/templates/slider-vertical-tabs.png",settings:null,controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},thumblist:{autohide:!1,dir:"v",type:"tabs",align:"right",margin:-12,space:0,width:229,height:100,hideUnder:550}}},{name:"Partial View Slider V1",value:"partial-1",className:"ms-partialview-template",img:__MSP_PATH+"images/templates/partial-1.png",settings:{space:10,loop:!0,trView:"partialWave",layout:"partialview",dir:"h"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},slideinfo:{autohide:!1,align:"bottom",size:160}}},{name:"Partial View Slider V2",value:"partial-2",className:"ms-partialview-template",img:__MSP_PATH+"images/templates/partial-2.png",settings:{space:10,loop:!0,trView:"fadeWave",layout:"partialview",dir:"h"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},slideinfo:{autohide:!1,align:"bottom",size:160}}},{name:"Partial View Slider V3",value:"partial-3",className:"ms-partialview-template",img:__MSP_PATH+"images/templates/partial-3.png",settings:{space:10,loop:!0,trView:"fadeFlow",layout:"partialview",dir:"h"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},slideinfo:{autohide:!1,align:"bottom",size:160}}},{name:"Slider in Display",value:"display",className:"ms-display-template",img:__MSP_PATH+"images/templates/display.png",settings:{width:507,height:286,speed:20,space:2,trView:"flow",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Flat Display",value:"flat-display",className:"ms-display-template",img:__MSP_PATH+"images/templates/flat-display.png",settings:{width:507,height:286,speed:20,space:2,trView:"flow",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Laptop",value:"laptop",className:"ms-laptop-template",img:__MSP_PATH+"images/templates/laptop.png",settings:{width:492,height:309,speed:20,space:2,trView:"mask",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Flat Laptop",value:"flat-laptop",className:"ms-laptop-template",img:__MSP_PATH+"images/templates/flat-laptop.png",settings:{width:492,height:309,speed:20,space:2,trView:"mask",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Tablet",value:"tablet",className:"ms-tablet-template",img:__MSP_PATH+"images/templates/tablet.png",settings:{width:400,height:534,speed:20,space:2,trView:"wave",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Flat Tablet",value:"flat-tablet",className:"ms-tablet-template",img:__MSP_PATH+"images/templates/flat-tablet.png",settings:{width:400,height:534,speed:20,space:2,trView:"basic",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Landscape Tablet",value:"tablet-land",className:"ms-tablet-template ms-tablet-land",img:__MSP_PATH+"images/templates/tablet-land.png",settings:{width:632,height:476,speed:20,space:2,trView:"mask",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Flat Landscape Tablet",value:"flat-tablet-land",className:"ms-tablet-template ms-tablet-land",img:__MSP_PATH+"images/templates/flat-tablet-land.png",settings:{width:632,height:476,speed:20,space:2,trView:"mask",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Smart Phone",value:"phone",className:"ms-phone-template",img:__MSP_PATH+"images/templates/phone.png",settings:{width:258,height:456,speed:20,space:2,trView:"wave",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Flat Smart Phone",value:"flat-phone",className:"ms-phone-template",img:__MSP_PATH+"images/templates/flat-phone.png",settings:{width:258,height:456,speed:20,space:2,trView:"basic",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Landscape Smart Phone",value:"phone-land",className:"ms-phone-template ms-phone-land",img:__MSP_PATH+"images/templates/phone-land.png",settings:{width:456,height:258,speed:20,space:2,trView:"mask",dir:"h",layout:"boxed"},controls:{arrows:{},circletimer:{color:"#FFFFFF",stroke:9},bullets:{autohide:!1}},disableControls:!0},{name:"Slider in Flat Landscape Smart Phone",value:"flat-phone-land",className:"ms-phone-template ms-phone-land",img:__MSP_PATH+"images/templates/flat-phone-land.png",settings:{width:456,height:258,speed:20,space:2,trView:"mask",dir:"h",layout:"boxed"},controls:{arrows:{},bullets:{autohide:!1}},disableControls:!0},{name:"Vertical Slider",value:"vertical-slider",className:"ms-vertical-template",img:__MSP_PATH+"images/templates/vertical-slider.png",settings:{space:5,dir:"v"},controls:{arrows:{},scrollbar:{dir:"v"},circletimer:{color:"#FFFFFF",stroke:9},thumblist:{autohide:!1,dir:"v",space:5,margin:5,align:"right"}}},{name:"Staff Carousel V1",value:"staff-1",className:"ms-staff-carousel",img:__MSP_PATH+"images/templates/staff-1.png",settings:{loop:!0,width:240,height:240,speed:20,trView:"focus",layout:"partialview",space:0,wheel:!0,dir:"h"},controls:{arrows:{},slideinfo:{autohide:!1,align:"bottom",size:160}}},{name:"Staff Carousel V2",value:"staff-2",className:"ms-staff-carousel",img:__MSP_PATH+"images/templates/staff-2.png",settings:{loop:!0,width:240,height:240,speed:20,trView:"fadeBasic",layout:"partialview",space:0,dir:"h"},controls:{arrows:{},slideinfo:{autohide:!1,align:"bottom",size:160}}},{name:"Staff Carousel V3",value:"staff-3",className:"ms-staff-carousel ms-round",img:__MSP_PATH+"images/templates/staff-3.png",settings:{loop:!0,width:240,height:240,speed:20,trView:"focus",layout:"partialview",space:0,space:35,dir:"h"},controls:{arrows:{},slideinfo:{autohide:!1,align:"bottom",size:160}}},{name:"Staff Carousel V4",value:"staff-4",className:"ms-staff-carousel ms-round",img:__MSP_PATH+"images/templates/staff-4.png",settings:{loop:!0,width:240,height:240,speed:20,trView:"fadeBasic",layout:"partialview",space:0,space:45,dir:"h"},controls:{arrows:{},slideinfo:{autohide:!1,align:"bottom",size:160}}},{name:"Staff Carousel V5",value:"staff-5",className:"ms-staff-carousel",img:__MSP_PATH+"images/templates/staff-5.png",settings:{loop:!0,width:240,height:240,speed:20,trView:"wave",layout:"partialview",space:0,wheel:!0,dir:"h"},controls:{arrows:{},slideinfo:{autohide:!1,align:"bottom",size:160}}},{name:"Staff Carousel V6",value:"staff-6",className:"ms-staff-carousel",img:__MSP_PATH+"images/templates/staff-6.png",settings:{loop:!0,width:240,height:240,speed:20,trView:"flow",layout:"partialview",space:0,wheel:!0,dir:"h"},controls:{arrows:{},slideinfo:{autohide:!1,align:"bottom",size:160}}},],MSPanel.SlideFrame=Ember.View.extend({classNames:["msp-slideframe"],classNameBindings:["selected:active"],selected:!1,thumb_src:"",showbtnclass:"msp-ico msp-ico-whitehide",template:Ember.Handlebars.compile('<div class="msp-img-cont">{{#if view.hasImg}}<div class="msp-imgselect-preview" {{bind-attr style=view.preview}})"><\/div>{{/if}}<\/div><span class="msp-frame-slideorder">#{{view.order}}<\/span><div class="msp-framehandle"><ul><li><a title="'+__MSP_LAN.ui_001+'" href="#" {{action "hideswitch" target=view}}><span {{bind-attr class=view.showbtnclass}}><\/span><\/a><\/li><li><a title="'+__MSP_LAN.ui_002+'" href="#" {{action "duplicate" target=view}}><span class="msp-ico msp-ico-whiteduplicate"><\/span><\/a><\/li><li><a title="'+__MSP_LAN.ui_003+'" href="#" {{action "remove" target=view}}><span class="msp-ico msp-ico-whiteremove"><\/span><\/a><\/li><\/ul><\/div>'),click:function(){this.get("controller").send("select",this.get("slide"))},onValueChanged:function(){var n=!Ember.isEmpty(this.get("slide.bg"));this.beginPropertyChanges(),this.set("hasImg",n),n&&this.set("preview","background-image:url("+this.get("slide.bgThumb")+");"),this.endPropertyChanges()}.observes("slide.bg").on("didInsertElement"),onSelect:function(){var n=this.get("slide");this.set("selected",n===this.get("controller.currentSlide"))}.observes("controller.currentSlide").on("init"),hideChange:function(){this.get("slide.ishide")?this.set("showbtnclass","msp-ico msp-ico-whitehide msp-ico-whiteshow"):this.set("showbtnclass","msp-ico msp-ico-whitehide")}.observes("slide.ishide").on("init"),order:function(){return this.get("slide.order")+1}.property("slide.order"),actions:{duplicate:function(){this.get("controller").duplicateSlide(this.get("slide"))},hideswitch:function(){this.set("slide.ishide",!this.get("slide.ishide"))},remove:function(){confirm(__MSP_LAN.ui_004)&&this.get("controller").removeSlide(this.get("slide"))}}}),MSPanel.SlideList=Ember.View.extend({tagName:"ul",classNames:["msp-slides"],template:Ember.Handlebars.compile('{{#each item in controller}}<li class="msp-slideframe-item" {{bind-attr data-id=item.id}}>{{view MSPanel.SlideFrame slide=item}}<\/li>{{/each}}<li class="msp-addslide-cont"><div class="msp-addslide" {{action "newSlide"}}><span class="msp-ico msp-ico-grayaddlarge"><\/span><span class="msp-addslide-label">Add Slide<\/span><\/div><\/li>'),didInsertElement:function(){var n=this;this.$().sortable({placeholder:"msp-frames-srtplaceholder",items:">li:not(.msp-addslide-cont)",delay:100,update:function(){n.updateSort()},create:function(){n.updateSort()}})},updateSort:function(){var n={};$(".msp-slideframe-item").each(function(t){n[$(this).data("id")]=t}),this.$().sortable("cancel"),this.get("controller").updateSlidesSort(n)}}),MSPanel.ImgSelect=Ember.View.extend({classNames:["msp-imgselect"],value:"",hasImg:!1,frame:null,template:Ember.Handlebars.compile('<div class="msp-img-cont">{{#if view.hasImg}}<div class="msp-imgselect-preview" {{bind-attr style=view.preview}})"><\/div>{{/if}}<\/div>{{#if view.hasImg}}<button {{action removeImg target="view"}} class="msp-img-btn"><span class="msp-ico msp-ico-grayremove"><\/span><\/button>{{else}}<button {{action addImg target="view"}} class="msp-img-btn"><span class="msp-ico msp-ico-grayadd"><\/span><\/button>{{/if}}'),willDestroyElement:function(){var n=this.get("frame");n&&(n.detach(),n.remove(),n=null,this.set("frame",null))},onValueChanged:function(){this.beginPropertyChanges(),this.set("hasImg",!Ember.isEmpty(this.get("value"))),this.set("preview","background-image:url("+this.get("thumb")+");"),this.endPropertyChanges()}.observes("value").on("didInsertElement"),actions:{removeImg:function(){this.beginPropertyChanges(),this.set("value",undefined),this.set("thumb",undefined),this.endPropertyChanges()},addImg:function(){var t,n;if(typeof wp!="undefined"){if(t=this,n=this.get("frame"),n){n.open();return}n=wp.media.frames.frame=wp.media({title:"Select Image",multiple:!1,frame:"select",library:{type:"image"},button:{text:"Add Image"}});n.on("select",function(){var i=n.state().get("selection").first().toJSON();t.set("thumb",(i.sizes.thumbnail||i.sizes.full).url),t.set("value",i.url)});n.open(),this.set("frame",n)}}}}),MSPanel.Select=Ember.Select.extend({tagName:"div",classNames:["msp-ddlist"],layout:Ember.Handlebars.compile("<select>{{yield}}<\/select>"),value:null,width:100,didInsertElement:function(){var n=this;this.$("select").on("change",function(){var t=n.$("select option:selected");n.set("value",t.attr("value"))}).width(this.get("width")),this.onValueChanged()},onValueChanged:function(){Ember.isEmpty(this.get("value"))||this.$("select").val(this.get("value"))}.observes("value")}),MSPanel.URLTarget=MSPanel.Select.extend({onInit:function(){var n=[{lable:__MSP_LAN.ui_005,value:"_self"},{lable:__MSP_LAN.ui_006,value:"_blank"},{lable:__MSP_LAN.ui_007,value:"_parent"},{lable:__MSP_LAN.ui_008,value:"_top"}];this.set("content",n),this.set("optionValuePath","content.value"),this.set("optionLabelPath","content.lable"),this.set("width",200)}.on("init")}),MSPanel.Fillmode=Ember.View.extend({classNames:["msp-fill-dd"],type:"slide",value:"fill",index:1,template:Ember.Handlebars.compile("<select>{{#each item in view.contents}}<option {{bind-attr value=item.value data-imagesrc=item.img}}>{{item.text}}<\/option>{{/each}}<\/select>"),didInsertElement:function(){var t=this,n=!0;this.$("select").ddslick({width:154,onSelected:function(i){n||t.set("value",i.selectedData.value),n=!1}}),this.onValueChanged()},onValueChanged:function(){Ember.isEmpty(this.get("value"))||this.$(".dd-container").ddslick("select",{index:this.get("valuedic")[this.get("value")]})}.observes("value"),onInit:function(){var n,t;this.get("type")==="slide"?(n=[{value:"fill",text:__MSP_LAN.ui_009,img:__MSP_PATH+"images/fill.png"},{value:"fit",text:__MSP_LAN.ui_010,img:__MSP_PATH+"images/fit.png"},{value:"center",text:__MSP_LAN.ui_011,img:__MSP_PATH+"images/center.png"},{value:"stretch",text:__MSP_LAN.ui_012,img:__MSP_PATH+"images/stretch.png"},{value:"tile",text:__MSP_LAN.ui_013,img:__MSP_PATH+"images/tile.png"}],t={fill:0,fit:1,center:2,stretch:3,tile:4}):this.get("type")==="video"&&(n=[{value:"fill",text:__MSP_LAN.ui_009,img:__MSP_PATH+"images/fill.png"},{value:"fit",text:__MSP_LAN.ui_010,img:__MSP_PATH+"images/fit.png"}],t={fill:0,fit:1,none:2}),this.set("contents",n),this.set("valuedic",t)}.on("init")}),MSPanel.SimpleCodeBlock=Ember.View.extend({classNames:["msp-shortcode-box"],template:Ember.Handlebars.compile('<input type="text" readonly {{bind-attr value=view.value}}>'),width:150,didInsertElement:function(){this.$("input").on("click",function(){$(this).select()}).width(this.get("width"))}}),MSPanel.SettingsView=Ember.View.extend({didInsertElement:function(){this.set("controller.mainView",this)}}),MSPanel.SlidesView=Ember.View.extend({didInsertElement:function(){this.set("controller.mainView",this)}}),MSPanel.StageArea=Ember.View.extend({classNames:["msp-stage-area"],template:Ember.Handlebars.compile('{{view MSPanel.Stage}}{{#if noticeMsg}}<div class="msp-stage-msg"><span class="msp-ico msp-ico-notice"><\/span>{{{noticeMsg}}}<\/div>{{/if}}')}),MSPanel.Stage=Ember.View.extend({classNames:["msp-slide-stage"],attributeBindings:["style"],template:Ember.Handlebars.compile('<div id="stage-bg" class="msp-stage-bg"><\/div>'),resize:function(){var n=this.get("controller.sliderSettings.width"),t=this.get("controller.sliderSettings.height");this.set("width",n),this.set("height",t),this.$().css({width:n,height:t})}.observes("controller.sliderSettings.width","controller.sliderSettings.height").on("didInsertElement"),didInsertElement:function(){var i=this.$("#stage-bg"),n=$("<img/>"),t;n.css("visibelity","hidden").each($.jqLoadFix),t=new MSAligner(this.get("controller.currentSlide.fillMode"),i,n),this.set("bgAligner",t),this.set("bgImg",n),this.onBGChange()},onBGColorChange:function(){var n=this.get("controller.currentSlide.bgColor");Ember.isEmpty(n)?this.$("#stage-bg").css("background-color",""):this.$("#stage-bg").css("background-color",n)}.observes("controller.currentSlide.bgColor"),onBGChange:function(){var i=this.get("bgAligner"),t,n,r;i&&i.reset(),t=this.get("controller.currentSlide.bg"),n=this.get("bgImg"),Ember.isEmpty(t)?n.detach():(r=this,n.appendTo(this.$("#stage-bg")),n.preloadImg(t,function(n){r._onBGLoad(n)}),n.attr("src",t))}.observes("controller.currentSlide.bg"),_onBGLoad:function(n){var t=this.get("bgAligner");t&&(t.init(n.width,n.height),t.align(),this.get("bgImg").css("visibelity",""))},onFillModeChanged:function(){var n=this.get("bgAligner");n.changeType(this.get("controller.currentSlide.fillMode"))}.observes("controller.currentSlide.fillMode"),willDestroyElement:function(){this.set("bgAligner",null)}}),MSPanel.ControlBtn=Ember.View.extend({control:null,tagName:"div",active:!1,classNames:["msp-control-btn"],classNameBindings:["active:msp-blue-btn"],template:Ember.Handlebars.compile('<span class="msp-control-label">{{view.control.label}}<\/span><a href="#" {{action "removeControl" target=view bubbles=false}}><span class="msp-control-removes msp-ico msp-ico-whiteremove"><\/span><\/a>'),didInsertElement:function(){},onActiveChange:function(){this.set("active",this.get("controller.currentControl")===this.get("control")),this.get("active")&&this.get("controller").send("showControlOptions")}.observes("controller.currentControl").on("init"),click:function(){this.get("active")||this.set("controller.currentControl",this.get("control"))},actions:{removeControl:function(){confirm('Are you sure want to remvoe "'+this.get("control.label")+'" control?')&&this.get("controller").send("removeControl",this.get("control"))}}}),MSPanel.MetaBoxComponent=Ember.Component.extend({tagName:"div",classNames:["msp-metabox"],layout:Ember.Handlebars.compile('<div class="msp-metabox-handle"><h3 class="msp-metabox-title">{{title}}<\/h3><div class="msp-metabox-toggle"><\/div><\/div>{{yield}}<div class="clear"> <\/div>')}),Ember.TEMPLATES["components/tabs-panel"]=Ember.Handlebars.compile("{{yield}}"),MSPanel.TabsPanelComponent=Ember.Component.extend({tagName:"div",attributeBindings:["id"],classNames:["msp-metabox msp-metabox-tabs"],didInsertElement:function(){this.$().avertaLiveTabs()}}),MSPanel.SwitchBoxComponent=Ember.Component.extend({classNames:["msp-switchbox"],offlable:"OFF",onlable:"ON",value:!1,layout:Ember.Handlebars.compile('<div class="msp-switch-cont"><span class="msp-switch-off">{{view.offlable}}<\/span><div class="msp-switch-handle"><\/div><span class="msp-switch-on">{{view.onlable}}<\/span><\/div>'),click:function(){var n=this;n.set("value",!n.get("value"))},update:function(){this.get("value")?this.$().addClass("switched"):this.$().removeClass("switched")}.observes("value").on("didInsertElement")}),hiddenEditor=jQuery("#mspHiddenEditor")[0].outerHTML,__tmc_msp_id=0,MSPanel.WPEditor=Ember.View.extend({classNames:["msp-wp-editor"],_id:null,template:null,tab:null,tabs:null,onInit:function(){var n="msp-wpeditor-"+__tmc_msp_id;this.set("_id",n),this.set("template",Ember.Handlebars.compile(WPEditorTemplate(n))),__tmc_msp_id++}.on("init"),didInsertElement:function(){var n=this.get("tabs");if(Ember.isEmpty(n)){this.createEditor();return}$("#"+n).bind("avtTabChange",{that:this},this.refreshEditor)},refreshEditor:function(n,t){var i=n.data.that;i.get("tab")===t&&i.createEditor()},createEditor:function(){var t,i,n,r,u;if(this.get("inited")!==!0&&(this.set("inited",!0),t=this.get("_id"),i=this,window.tinymce&&(n=$.extend({},window.tinyMCEPreInit.mceInit["msp-hidden"]||{}),n.forced_root_block="",n.force_br_newlines=!0,n.force_p_newlines=!1,n.wpautop=!1,tinyMCE.majorVersion=="3"?(n.body_class=n.elements=t,tinymce.init(n),setTimeout(function(){i.initEditor(tinyMCE.getInstanceById(t))},50)):tinyMCE.majorVersion=="4"&&(n.body_class="content post-type-post post-status-auto-draft post-format-standard",n.selector="#"+t,tinymce.init(n),setTimeout(function(){i.initEditor(tinyMCE.get(t))},50)),n.setup=function(){}),r=$.extend({},window.tinyMCEPreInit.qtInit["msp-hidden"]||{}),r.id=t,typeof QTags=="function")){u=quicktags(r),QTags.buttonsInitDone=!1,QTags._buttonsInit(),i.set("qtags",u),switchEditors.go(t,"html");this.$("textarea#"+this.get("_id")).on("change keyup paste",function(){i.set("value",$(this).val())})}},initEditor:function(n){function t(){r.set("internalChange",!0),r.set("value",n.getContent()),r.set("internalChange",!1)}var i=this.get("_id"),u=this.get("value"),r=this;this.$(".wp-editor-wrap").on("mousedown",function(){wpActiveEditor=i});if(tinyMCE.majorVersion=="3")n.onChange.add(t),n.onKeyUp.add(t);else if(tinyMCE.majorVersion=="4"){n.on("change",t);n.on("keyup",t)}this.$().click(t),setTimeout(function(){switchEditors.go(i,"html"),switchEditors.go(i,"tmce")},100),this.set("mce",n),this.onValueChanged()},onValueChanged:function(){var n,t;if(this.get("inited")){if(n=this.get("value"),this.$("textarea#"+this.get("_id")).val(n),this.get("internalChange")){this.set("internalChange",!1);return}t=this.get("mce"),Ember.isEmpty(t)||n==null?n==null&&t.setContent(" "):t.setContent(n)}}.observes("value"),willDestroyElement:function(){var n,t;this.get("inited")&&(window.tinymce&&tinymce.remove(this.get("_id")),n=this.get("qtags"),n&&($(n.toolbar).remove(),n.toolbar=null,n=null,QTags.instances[this.get("_id")]&&delete QTags.instances[this.get("_id")],this.$("textarea#"+this.get("_id")).remove()),t=this.get("tabs"),Ember.isEmpty(t)||$("#"+t).unbind("avtTabChange",this.refreshEditor))}}),jQuery.ui&&jQuery.ui.spinner&&(jQuery.ui.spinner.prototype._events.mousewheel=function(n,t){if(t&&this.element.is(":focus")){if(!this.spinning&&!this._start(n))return!1;this._spin((t>0?1:-1)*this.options.step,n),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(n)},100),n.preventDefault()}}),MSPanel.NumberInputView=Ember.View.extend({step:1,min:0,tagName:"input",attributeBindings:["type"],lastValue:null,type:"text",didInsertElement:function(){var n=this,i=this.$(),t=function(){var t=i.spinner("value");n.set("internalChange",!0),isNaN(t)||t==null?n.set("value",undefined):n.set("value",parseFloat(t))};i.on("change",t).spinner({step:this.get("step"),numberFormat:"n",min:this.get("min"),max:this.get("max"),spin:t,stop:t}).spinner("value",this.get("value"))},onValueChanged:function(){if(this.get("internalChange")){this.set("internalChange",!1);return}this.$().spinner("value",this.get("value"))}.observes("value")}),Ember.Handlebars.helper("number-input",MSPanel.NumberInputView),MSPanel.ColorPickerComponent=Ember.Component.extend({tagName:"input",classNames:"msp-color-picker",value:null,didInsertElement:function(){var n=this;this.$().spectrum({color:this.get("value"),allowEmpty:!0,showInput:!0,showAlpha:!0,clickoutFiresChange:!0,preferredFormat:"hex6",change:function(t){t===null?n.set("value",null):n.set("value",t.toString())}})},willDestroyElement:function(){this.$().spectrum("destroy")},onValueChanged:function(){this.$().spectrum("set",this.get("value"))}.observes("value")}),MSPanel.DropdwonListComponent=Ember.Component.extend({tagName:"div",classNames:["msp-ddlist"],layout:Ember.Handlebars.compile("<select>{{yield}}<\/select>"),value:null,width:100,didInsertElement:function(){var n=this;this.$("select").on("change",function(){var t=n.$("select option:selected");n.set("value",t.attr("value"))}).width(this.get("width")),this.onValueChanged()},onValueChanged:function(){Ember.isEmpty(this.get("value"))||this.$("select").val(this.get("value"))}.observes("value")}),MSPanel.CodeMirrorComponent=Ember.Component.extend({classNames:["msp-codemirror"],width:250,height:200,mode:"css",tab:null,tabs:null,layout:Ember.Handlebars.compile("<textarea>{{yield}}<\/textarea>"),didInsertElement:function(){var t,n,i,r;this.$().width(this.get("width")).height(this.get("height")),t=this,n=CodeMirror.fromTextArea(this.$(">textarea")[0],{lineNumbers:!0,mode:this.get("mode")});n.on("change",function(){t.set("internalChange",!0),t.set("value",n.getValue())});this.set("editor",n),i=this.get("value"),Ember.isEmpty(i)||n.setValue(i),r=this.get("tabs"),Ember.isEmpty(r)||$("#"+r).bind("avtTabChange",{that:this},this.refreshEditor)},onValueChanged:function(){if(this.get("internalChange")===!0){this.set("internalChange",!1);return}this.get("editor").setValue(this.get("value")),this.set("internalChange",!1)}.observes("value"),refreshEditor:function(n,t){var i=n.data.that;i.get("tab")===t&&i.get("editor").refresh()},willDestroyElement:function(){var t=this.get("tabs"),n;Ember.isEmpty(t)||$("#"+t).unbind("avtTabChange",this.refreshEditor),n=this.get("editor"),n.toTextArea(),n=null,this.set("editor",null)}}),MSPanel.pushData=null,MSPanel.ApplicationController=Ember.Controller.extend({sliderId:MSPanel.SliderID,isSending:!1,statusMsg:"",hasError:!1,onInit:function(){MSPanel.Settings.find(),MSPanel.Slide.find(),MSPanel.Control.find(),MSPanel.Callback.find(),this.set("disableControls",MSPanel.Settings.find(0).get("disableControls"));var n=this;MSPanel.pushData=function(){n.prepareData()},__MSP_TYPE==="wc-product"&&__MSP_POST==null&&__WC_INSTALL_URL!=null&&(this.set("hasError",!0),this.set("errorTemplate","wooc-error"),this.set("wooLink",__WC_INSTALL_URL)),this.generateButtonStyles(),this.set("shortCode","[masterslider id="+this.get("sliderId")+"]"),this.set("phpFunction","<?php masterslider("+this.get("sliderId")+"); ?>"),jQuery("#panelLoading").remove()}.on("init"),prepareData:function(){var n={},i="",t;MSPanel.Style.find().forEach(function(t){var i=t.get("fontFamily"),r=t.get("fontWeight");Ember.isEmpty(i)||(n[i]||(n[i]=[]),r==="normal"&&(r="regular"),Ember.isEmpty(r)||n[i].indexOf(r)!==-1||n[i].push(r))});for(t in n)i+=t.replace(/\s/,"+")+":"+n[t].join(",")+"|";MSPanel.Settings.find(1).set("usedFonts",i.slice(0,-1)),this.saveRecords(MSPanel.Settings.find()),this.saveRecords(MSPanel.Slide.find()),this.saveRecords(MSPanel.Control.find()),this.saveRecords(MSPanel.Callback.find())},generateButtonStyles:function(){var i=MSPanel.ButtonStyle.find(),n="",t=$("#msp-buttons");i.forEach(function(t){n+="."+t.get("className")+" {"+t.get("normal")+"}\n."+t.get("className")+":hover {"+t.get("hover")+"}\n."+t.get("className")+":active {"+t.get("active")+"}\n"}),t.length===0?t=$('<style id="msp-buttons"><\/style>').text(n).appendTo($("head")):t.text(n)},actions:{saveAll:function(){this.prepareData(),this.sendData()},showPreview:function(n){window.lunchMastersliderPreview&&lunchMastersliderPreview(n)}},saveRecords:function(n){n.forEach(function(n){n.save()})},sendData:function(){this.set("statusMsg",__MSP_LAN.ap_001),this.set("isSending",!0);var n=this;jQuery.post(__MS.ajax_url,{action:"msp_panel_handler",nonce:jQuery("#msp-main-wrapper").data("nonce"),msp_data:B64.encode(JSON.stringify(MSPanel.data)),preset_style:B64.encode(JSON.stringify(MSPanel.PSData)),preset_effect:B64.encode(JSON.stringify(MSPanel.PEData)),buttons:B64.encode(JSON.stringify(MSPanel.PBData)),slider_id:MSPanel.SliderID},function(t){n.set("statusMsg",t.message),n.set("isSending",!1)})}}),MSPanel.SettingsController=Ember.ObjectController.extend({customSlider:window.__MSP_TYPE&&window.__MSP_TYPE==="custom",templateSlider:window.__MSP_TYPE&&(window.__MSP_TYPE==="flickr"||window.__MSP_TYPE==="post"||window.__MSP_TYPE==="wc-product"||window.__MSP_TYPE==="facebook"),sliderSkins:__MSP_SKINS,needs:["application","controls"],msTemplateName:null,msTemplateImg:null,draftMSTemplate:null,templates:MSPanel.SliderTemplates,showAutoHeight:!1,showNearbyNum:!1,showWrapperWidth:!1,preloadMethod:null,setup:function(){var n=this.get("preload");n==="all"||n==="-1"?this.set("preloadMethod",n):this.set("preloadMethod","nearby"),this.set("draftMSTemplate",this.get("msTemplate")),this.updateTemplate(!0)},sliderLayoutChanged:function(){var n=this.get("layout");n==="fullscreen"||n==="autofill"?(this.set("showAutoHeight",!1),this.set("autoHeight",!1)):this.set("showAutoHeight",!0),this.set("showWrapperWidth",n==="boxed"||n==="partialview"),this.set("showFSMargin",n==="fullscreen")}.observes("layout").on("setup"),preloadSetup:function(){var t=this.get("preloadMethod"),n;t==="nearby"?(this.set("showNearbyNum",!0),n=this.get("preload"),(n==="all"||n==="-1")&&this.set("preload","0")):(this.set("showNearbyNum",!1),this.set("preload",t))}.observes("preloadMethod").on("setup"),updateTemplate:function(n){var t,s=this.get("msTemplate"),r,f,e,i,u,o;if(this.get("templates").forEach(function(n){if(n.value===s){t=n;return}}),t){if(this.set("msTemplateName",t.name),this.set("msTemplateImg",t.img),this.set("msTemplateClass",t.className),this.set("controllers.application.disableControls",t.disableControls),this.set("disableControls",t.disableControls),!n){for(r=this.get("controllers.controls"),e=MSPanel.Control.find();e.get("firstObject");)i=e.get("firstObject"),r.findControlObj(i.get("name")).used=!1,i.deleteRecord();for(u in t.controls)f=r.findControlObj(u),i=MSPanel.Control.create($.extend(!0,r.getDefaultValues(u),t.controls[u])),i.set("label",f.label),f.used=!0,i.save();for(o in t.settings)this.set(o,t.settings[o])}}else this.set("draftMSTemplate","custom"),this.updateTemplate()},actions:{openTemplates:function(){var n=MSPanel.TemplatesView.create({controller:this});this.get("mainView").createChildView(n),this.set("templatesView",n),n.appendTo(MSPanel.rootElement)},closeTemplates:function(){this.get("templatesView").destroy(),this.set("draftMSTemplate",this.get("msTemplate"))},saveTemplate:function(){if(this.get("draftMSTemplate")===this.get("msTemplate")){this.send("closeTemplates");return}confirm(__MSP_LAN.tv_002)&&(this.set("msTemplate",this.get("draftMSTemplate")),this.send("closeTemplates"),this.updateTemplate())}}}),MSPanel.SlidesController=Ember.ArrayController.extend({customSlider:window.__MSP_TYPE&&window.__MSP_TYPE==="custom",_order:-1,sortProperties:["order"],mainView:null,currentSlide:null,setup:function(){if(this.get("length")===0)this.send("newSlide");else{var n=this.get("firstObject");this.set("currentSlide",n)}Ember.isEmpty(this.get("sliderSettings.type"))&&this.set("sliderSettings.type",__MSP_TYPE),this.set("sliderSettings.sliderId",MSPanel.SliderID),this.updateOrder()},duplicateSlide:function(n){var i=n.toJSON(),t;delete i.id,delete i.layers,t=MSPanel.Slide.create(i),t.set("order",n.get("order")+1),this.forEach(function(n){var i=n.get("order"),r=t.get("order");i>=r&&n!==t&&n.set("order",i+1)}),t.save(),this.updateOrder()},updateSlidesSort:function(n){this.beginPropertyChanges(),this.forEach(function(t){t.set("order",n[t.get("id")])},this),this.endPropertyChanges(),this.set("_order",this.get("lastObject.order"))},updateOrder:function(){var n=0;this.forEach(function(t){t.set("order",n++)}),this.set("_order",n-1)},removeSlide:function(n){n.deleteRecord(),this.get("length")===0?this.send("newSlide"):this.send("select",this.get("firstObject")),this.updateOrder()},actions:{newSlide:function(){var n=MSPanel.Slide.create({order:this.get("_order")+1});this.set("currentSlide",n),this.set("_order",this.get("_order")+1),n.save()},select:function(n){n!==this.get("currentSlide")&&this.set("currentSlide",n)}}}),MSPanel.ControlsController=Ember.ArrayController.extend({needs:"application",controls:[{used:!1,label:__MSP_LAN.cc_001,value:"arrows"},{used:!1,label:__MSP_LAN.cc_002,value:"timebar"},{used:!1,label:__MSP_LAN.cc_003,value:"bullets"},{used:!1,label:__MSP_LAN.cc_004,value:"circletimer"},{used:!1,label:__MSP_LAN.cc_005,value:"scrollbar"},{used:!1,label:__MSP_LAN.cc_006,value:"slideinfo"},{used:!1,label:__MSP_LAN.cc_007,value:"thumblist"}],selectedControl:null,availableControls:[],noMore:!1,currentControl:null,setup:function(){var n=this;this.forEach(function(t){n.findControlObj(t.get("name")).used=!0}),this.set("availableControls",this.findAvailableControls())},actions:{addControl:function(){var t=this.get("selectedControl"),i=this.findControlObj(t),n;n=MSPanel.Control.create(this.getDefaultValues(t)),n.set("label",i.label),i.used=!0,this.set("availableControls",this.findAvailableControls()),n.save(),this.set("currentControl",n)},removeControl:function(n){this.findControlObj(n.get("name")).used=!1,this.set("availableControls",this.findAvailableControls()),n.deleteRecord(),this.set("currentControl",this.get("firstObject")),this.send("showControlOptions")},showControlOptions:function(){var n=this.get("currentControl");Ember.isEmpty(n)?this.set("controlOptions","empty-template"):this.set("controlOptions",n.get("name")+"-options")}},findControlObj:function(n){for(var i=this.get("controls"),t=0,r=i.length;t!==r;t++)if(i[t].value===n)return i[t];return null},findAvailableControls:function(){for(var n=[],i=this.get("controls"),t=0,r=i.length;t!==r;t++)i[t].used||n.push(i[t]);return this.set("noMore",n.length===0),this.set("selectedControl",n[0]?n[0].value:null),n},getDefaultValues:function(n){var t={name:n};t.inset=!(n==="slideinfo"||n==="thumblist");switch(n){case"timebar":t.align="bottom",t.color="#FFFFFF",t.autoHide=!1,t.width=4;break;case"bullets":t.align="bottom",t.dir="h",t.margin=10;break;case"circletimer":t.color="#A2A2A2",t.stroke=10,t.radius=4,t.autoHide=!1;break;case"scrollbar":t.align="top",t.dir="h",t.color="#3D3D3D",t.margin=10,t.autoHide=!1,t.width=4;break;case"slideinfo":t.align="bottom",t.margin=10,t.autoHide=!1;break;case"thumblist":t.align="bottom",t.space=5,t.width=100,t.height=80,t.margin=10,t.fillMode="fill",t.autoHide=!1}return t}}),MSPanel.CallbacksController=Ember.ArrayController.extend({callbacks:[{used:!1,label:__MSP_LAN.cb_011,value:"INIT"},{used:!1,label:__MSP_LAN.cb_001,value:"CHANGE_START"},{used:!1,label:__MSP_LAN.cb_002,value:"CHANGE_END"},{used:!1,label:__MSP_LAN.cb_003,value:"WAITING"},{used:!1,label:__MSP_LAN.cb_004,value:"RESIZE"},{used:!1,label:__MSP_LAN.cb_005,value:"VIDEO_PLAY"},{used:!1,label:__MSP_LAN.cb_006,value:"VIDEO_CLOSE"},{used:!1,label:__MSP_LAN.cb_007,value:"SWIPE_START"},{used:!1,label:__MSP_LAN.cb_008,value:"SWIPE_MOVE"},{used:!1,label:__MSP_LAN.cb_009,value:"SWIPE_END"}],availableCallbacks:[],noMore:!1,selectedCallback:null,setup:function(){var n=this;this.forEach(function(t){n.findCallbackObj(t.get("name")).used=!0}),this.set("availableCallbacks",this.findAvailableCallbacks())},actions:{addCallback:function(){var i=this.get("selectedCallback"),n=this.findCallbackObj(i),t;t=MSPanel.Callback.create({name:n.value,label:n.label}),n.used=!0,this.set("availableCallbacks",this.findAvailableCallbacks()),t.save()},removeCallback:function(n){confirm(__MSP_LAN.cb_010.jfmt(n.get("label")))&&(this.findCallbackObj(n.get("name")).used=!1,this.set("availableCallbacks",this.findAvailableCallbacks()),n.deleteRecord())}},findCallbackObj:function(n){for(var i=this.get("callbacks"),t=0,r=i.length;t!==r;t++)if(i[t].value===n)return i[t];return null},findAvailableCallbacks:function(){for(var n=[],i=this.get("callbacks"),t=0,r=i.length;t!==r;t++)i[t].used||n.push(i[t]);return this.set("noMore",n.length===0),this.set("selectedCallback",n[0]?n[0].value:null),n}})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/views/slider-panel/js/msp.required.js
CHANGED
@@ -1,945 +1,15 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
*
|
5 |
-
|
6 |
-
*
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
window.package = function(name){
|
15 |
-
if(!window[name]) window[name] = {};
|
16 |
-
};
|
17 |
-
|
18 |
-
// conflict with Emberjs
|
19 |
-
/*var extend = function(target , object){
|
20 |
-
for(var key in object) target[key] = object[key];
|
21 |
-
};
|
22 |
-
|
23 |
-
Function.prototype.extend = function(superclass){
|
24 |
-
if(typeof superclass.prototype.constructor === "function"){
|
25 |
-
extend(this.prototype , superclass.prototype);
|
26 |
-
this.prototype.constructor = this;
|
27 |
-
}else{
|
28 |
-
this.prototype.extend(superclass);
|
29 |
-
this.prototype.constructor = this;
|
30 |
-
}
|
31 |
-
};*/
|
32 |
-
|
33 |
-
// Converts JS prefix to CSS prefix
|
34 |
-
var trans = {
|
35 |
-
'Moz' : '-moz-',
|
36 |
-
'Webkit' : '-webkit-',
|
37 |
-
'Khtml' : '-khtml-' ,
|
38 |
-
'O' : '-o-',
|
39 |
-
'ms' : '-ms-',
|
40 |
-
'Icab' : '-icab-'
|
41 |
-
};
|
42 |
-
|
43 |
-
$(document).ready(function(){
|
44 |
-
window._jcsspfx = getVendorPrefix(); // JS CSS VendorPrefix
|
45 |
-
window._csspfx = trans[window._jcsspfx]; // CSS VendorPrefix
|
46 |
-
window._cssanim = supportsTransitions();
|
47 |
-
window._css3d = supports3DTransforms();
|
48 |
-
window._css2d = supportsTransforms();
|
49 |
-
window._mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
50 |
-
window._touch = 'ontouchstart' in document;
|
51 |
-
});
|
52 |
-
|
53 |
-
|
54 |
-
// Thanks to LEA VEROU
|
55 |
-
// http://lea.verou.me/2009/02/find-the-vendor-prefix-of-the-current-browser/
|
56 |
-
function getVendorPrefix() {
|
57 |
-
|
58 |
-
if('result' in arguments.callee) return arguments.callee.result;
|
59 |
-
|
60 |
-
var regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
|
61 |
-
|
62 |
-
var someScript = document.getElementsByTagName('script')[0];
|
63 |
-
|
64 |
-
for(var prop in someScript.style)
|
65 |
-
if(regex.test(prop))
|
66 |
-
return arguments.callee.result = prop.match(regex)[0];
|
67 |
-
|
68 |
-
if('WebkitOpacity' in someScript.style) return arguments.callee.result = 'Webkit';
|
69 |
-
if('KhtmlOpacity' in someScript.style) return arguments.callee.result = 'Khtml';
|
70 |
-
|
71 |
-
return arguments.callee.result = '';
|
72 |
-
}
|
73 |
-
|
74 |
-
|
75 |
-
// Thanks to Steven Benner.
|
76 |
-
// http://stevenbenner.com/2010/03/javascript-regex-trick-parse-a-query-string-into-an-object/
|
77 |
-
window.parseQueryString = function(url){
|
78 |
-
var queryString = {};
|
79 |
-
url.replace(
|
80 |
-
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
|
81 |
-
function($0, $1, $2, $3) { queryString[$1] = $3; }
|
82 |
-
);
|
83 |
-
|
84 |
-
return queryString;
|
85 |
-
};
|
86 |
-
|
87 |
-
function checkStyleValue(prop){
|
88 |
-
var b = document.body || document.documentElement;
|
89 |
-
var s = b.style;
|
90 |
-
var p = prop;
|
91 |
-
if(typeof s[p] == 'string') {return true; }
|
92 |
-
|
93 |
-
// Tests for vendor specific prop
|
94 |
-
v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms'],
|
95 |
-
p = p.charAt(0).toUpperCase() + p.substr(1);
|
96 |
-
for(var i=0; i<v.length; i++) {
|
97 |
-
if(typeof s[v[i] + p] == 'string') { return true; }
|
98 |
-
}
|
99 |
-
return false;
|
100 |
-
}
|
101 |
-
|
102 |
-
function supportsTransitions() {
|
103 |
-
return checkStyleValue('transition');
|
104 |
-
}
|
105 |
-
|
106 |
-
function supportsTransforms(){
|
107 |
-
return checkStyleValue('transform');
|
108 |
-
}
|
109 |
-
|
110 |
-
function supports3DTransforms(){
|
111 |
-
if(!supportsTransforms()) return false;
|
112 |
-
var el = document.createElement('p'),
|
113 |
-
has3d,
|
114 |
-
transforms = {
|
115 |
-
'WebkitTransform':'-webkit-transform',
|
116 |
-
'OTransform':'-o-transform',
|
117 |
-
'MSTransform':'-ms-transform',
|
118 |
-
'MozTransform':'-moz-transform',
|
119 |
-
'Transform':'transform'
|
120 |
-
};
|
121 |
-
|
122 |
-
// Add it to the body to get the computed style
|
123 |
-
document.body.insertBefore(el, null);
|
124 |
-
|
125 |
-
for(var t in transforms){
|
126 |
-
if( el.style[t] !== undefined ){
|
127 |
-
el.style[t] = 'translate3d(1px,1px,1px)';
|
128 |
-
has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
|
129 |
-
}
|
130 |
-
}
|
131 |
-
|
132 |
-
document.body.removeChild(el);
|
133 |
-
|
134 |
-
return (has3d != null && has3d.length > 0 && has3d !== "none");
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* Provides requestAnimationFrame in a cross browser way.
|
139 |
-
* @author paulirish / http://paulirish.com/
|
140 |
-
*/
|
141 |
-
var fps60 = 50/3;
|
142 |
-
|
143 |
-
if ( !window.requestAnimationFrame ) {
|
144 |
-
|
145 |
-
window.requestAnimationFrame = ( function() {
|
146 |
-
|
147 |
-
return window.webkitRequestAnimationFrame ||
|
148 |
-
window.mozRequestAnimationFrame ||
|
149 |
-
window.oRequestAnimationFrame ||
|
150 |
-
window.msRequestAnimationFrame ||
|
151 |
-
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
|
152 |
-
|
153 |
-
window.setTimeout( callback, fps60 );
|
154 |
-
|
155 |
-
};
|
156 |
-
|
157 |
-
} )();
|
158 |
-
|
159 |
-
}
|
160 |
-
|
161 |
-
if (!window.getComputedStyle) {
|
162 |
-
window.getComputedStyle = function(el, pseudo) {
|
163 |
-
this.el = el;
|
164 |
-
this.getPropertyValue = function(prop) {
|
165 |
-
var re = /(\-([a-z]){1})/g;
|
166 |
-
if (prop == 'float') prop = 'styleFloat';
|
167 |
-
if (re.test(prop)) {
|
168 |
-
prop = prop.replace(re, function () {
|
169 |
-
return arguments[2].toUpperCase();
|
170 |
-
});
|
171 |
-
}
|
172 |
-
return el.currentStyle[prop] ? el.currentStyle[prop] : null;
|
173 |
-
};
|
174 |
-
return el.currentStyle;
|
175 |
-
};
|
176 |
-
}
|
177 |
-
|
178 |
-
if(jQuery){
|
179 |
-
$.jqLoadFix = function(){
|
180 |
-
if(this.complete){
|
181 |
-
var that = this;
|
182 |
-
setTimeout(function(){$(that).load();} , 1);
|
183 |
-
}
|
184 |
-
};
|
185 |
-
|
186 |
-
jQuery.uaMatch = jQuery.uaMatch || function( ua ) {
|
187 |
-
ua = ua.toLowerCase();
|
188 |
-
|
189 |
-
var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
|
190 |
-
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
|
191 |
-
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
|
192 |
-
/(msie) ([\w.]+)/.exec( ua ) ||
|
193 |
-
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
|
194 |
-
[];
|
195 |
-
|
196 |
-
return {
|
197 |
-
browser: match[ 1 ] || "",
|
198 |
-
version: match[ 2 ] || "0"
|
199 |
-
};
|
200 |
-
};
|
201 |
-
|
202 |
-
// Don't clobber any existing jQuery.browser in case it's different
|
203 |
-
if ( !jQuery.browser ) {
|
204 |
-
matched = jQuery.uaMatch( navigator.userAgent );
|
205 |
-
browser = {};
|
206 |
-
|
207 |
-
if ( matched.browser ) {
|
208 |
-
browser[ matched.browser ] = true;
|
209 |
-
browser.version = matched.version;
|
210 |
-
}
|
211 |
-
|
212 |
-
// Chrome is Webkit, but Webkit is also Safari.
|
213 |
-
if ( browser.chrome ) {
|
214 |
-
browser.webkit = true;
|
215 |
-
} else if ( browser.webkit ) {
|
216 |
-
browser.safari = true;
|
217 |
-
}
|
218 |
-
|
219 |
-
jQuery.browser = browser;
|
220 |
-
|
221 |
-
}
|
222 |
-
|
223 |
-
$.fn.preloadImg = function(src , _event){
|
224 |
-
this.each(function(){
|
225 |
-
var $this = $(this);
|
226 |
-
var self = this;
|
227 |
-
var img = new Image();
|
228 |
-
img.onload = function(event){
|
229 |
-
$this.attr('src' , src);
|
230 |
-
event.width = img.width;
|
231 |
-
event.height = img.height;
|
232 |
-
setTimeout(function(){_event.call(self , event);},50);
|
233 |
-
img = null;
|
234 |
-
};
|
235 |
-
img.src = src;
|
236 |
-
});
|
237 |
-
return this;
|
238 |
-
};
|
239 |
-
}
|
240 |
-
|
241 |
-
|
242 |
-
window.parseTransform = function(transformCSS_str) {
|
243 |
-
if(transformCSS_str === null) return {};
|
244 |
-
|
245 |
-
transformCSS_str = transformCSS_str.replace(/\s+/g, '');
|
246 |
-
|
247 |
-
var fullFun_array = transformCSS_str.split(")");
|
248 |
-
fullFun_array.pop();
|
249 |
-
|
250 |
-
var parsed_obj = {};
|
251 |
-
|
252 |
-
for( var i = 0 , l = fullFun_array.length ; i < l ; ++i){
|
253 |
-
var fun = fullFun_array[i];
|
254 |
-
parsed_obj[fun.slice(0, fun.indexOf("("))] = fun.slice(fun.indexOf("(")+1).split(",");
|
255 |
-
}
|
256 |
-
|
257 |
-
return parsed_obj;
|
258 |
-
};
|
259 |
-
|
260 |
-
|
261 |
-
/**
|
262 |
-
* Converts CSS3 ease names to JTween ease functions
|
263 |
-
* @param {string} easeName
|
264 |
-
* @return {function}
|
265 |
-
*/
|
266 |
-
window.convertEaseName = function(easeName){
|
267 |
-
if(easeName === 'linear') return Linear.easeNone;
|
268 |
-
var isInOut = easeName.indexOf('InOut') !== -1,
|
269 |
-
isIn = easeName.indexOf('In') !== -1;
|
270 |
-
|
271 |
-
if(isInOut) return window[easeName.slice(9)].easeInOut;
|
272 |
-
if(isIn) return window[easeName.slice(6)].easeIn;
|
273 |
-
|
274 |
-
return window[easeName.slice(7)].easeOut;
|
275 |
-
};
|
276 |
-
|
277 |
-
jQuery.fn.extend({
|
278 |
-
insertAtCaret: function(myValue){
|
279 |
-
return this.each(function(i) {
|
280 |
-
if (document.selection) {
|
281 |
-
//For browsers like Internet Explorer
|
282 |
-
this.focus();
|
283 |
-
var sel = document.selection.createRange();
|
284 |
-
sel.text = myValue;
|
285 |
-
this.focus();
|
286 |
-
}
|
287 |
-
else if (this.selectionStart || this.selectionStart == '0') {
|
288 |
-
//For browsers like Firefox and Webkit based
|
289 |
-
var startPos = this.selectionStart;
|
290 |
-
var endPos = this.selectionEnd;
|
291 |
-
var scrollTop = this.scrollTop;
|
292 |
-
this.value = this.value.substring(0, startPos)+myValue+this.value.substring(endPos,this.value.length);
|
293 |
-
this.focus();
|
294 |
-
this.selectionStart = startPos + myValue.length;
|
295 |
-
this.selectionEnd = startPos + myValue.length;
|
296 |
-
this.scrollTop = scrollTop;
|
297 |
-
} else {
|
298 |
-
this.value += myValue;
|
299 |
-
this.focus();
|
300 |
-
}
|
301 |
-
});
|
302 |
-
}
|
303 |
-
});
|
304 |
-
})(jQuery);
|
305 |
-
//js\libs\averta.livetabs.js
|
306 |
-
|
307 |
-
/**
|
308 |
-
* AvertaLiveTabs v1.4
|
309 |
-
* Plugin for enabling tabs
|
310 |
-
* Copyright (c) averta | http://averta.net | 2011-2014
|
311 |
-
* licensed under the MIT license
|
312 |
-
**/
|
313 |
-
|
314 |
-
/**
|
315 |
-
* USAGE :
|
316 |
-
* -----------------------------------------------------------------------------------------------------
|
317 |
-
* HTML:
|
318 |
-
<div id="container">
|
319 |
-
<ul class="tabs">
|
320 |
-
<li class="active"><a href="#s1">Tab1</a></li>
|
321 |
-
<li><a href="#s2">Tab2</a></li>
|
322 |
-
<li><a href="#s3">Tab3</a></li>
|
323 |
-
</ul>
|
324 |
-
|
325 |
-
<ul class="tabs-content">
|
326 |
-
<li id="s1">Contnt1</li>
|
327 |
-
<li id="s2">Contnt2</li>
|
328 |
-
<li id="s3">Contnt3</li>
|
329 |
-
</ul>
|
330 |
-
</div>
|
331 |
-
*
|
332 |
-
* JS:
|
333 |
-
$('#container').avertaLiveTabs({
|
334 |
-
tabs: 'ul.tabs > li', // Tabs selector
|
335 |
-
tabsActiveClass: 'active', // A Class that indicates active tab
|
336 |
-
contents: 'ul.tabs-content > li', // Tabs content selector
|
337 |
-
contentsActiveClass: 'active', // A Class that indicates active tab-content
|
338 |
-
transition: 'fade', // Animation type white swiching tabs
|
339 |
-
duration : '500', // Animation duration in mili seconds
|
340 |
-
connectType: 'index', // connect tabs and contents by 'index' or 'id'
|
341 |
-
enableHash: false , // check to select initial tab based on hash address
|
342 |
-
updateHash: false , // update hash in browser while switching between tabs
|
343 |
-
hashSuffix: '-tab' // suffix to add at the end of hash url to prevent page scroll
|
344 |
-
});
|
345 |
-
|
346 |
-
* ---------------------------------------------------------------------------------------------------------
|
347 |
-
**/
|
348 |
-
|
349 |
-
if(typeof Object.create !== 'function' ){ Object.create = function (obj){ function F(){} F.prototype = obj;return new F();};}
|
350 |
-
|
351 |
-
;(function($){
|
352 |
-
|
353 |
-
var Container = {
|
354 |
-
|
355 |
-
init : function(el, options){
|
356 |
-
//cache this
|
357 |
-
var self = this;
|
358 |
-
self.options = $.extend({} ,$.fn.avertaLiveTabs.defaultOptions, options || {} );
|
359 |
-
|
360 |
-
// Access to jQuery and DOM versions of element
|
361 |
-
self.$el = $(el);
|
362 |
-
self.el = el;
|
363 |
-
|
364 |
-
self.$tabs = self.$el.find(self.options.tabs);
|
365 |
-
self.$contents = self.$el.find(self.options.contents);
|
366 |
-
|
367 |
-
self.setup();
|
368 |
-
},
|
369 |
-
|
370 |
-
setup: function(){
|
371 |
-
var self = this,
|
372 |
-
$active_tab,
|
373 |
-
$active_content;
|
374 |
-
// click event when new tab selected
|
375 |
-
self.$tabs.on('click', {self:self}, self.onTabClicked);
|
376 |
-
|
377 |
-
// if hash is enabled in options get current hash and select related tab
|
378 |
-
if(self.options.enableHash && window.location.hash !== '') {
|
379 |
-
var id = window.location.hash.substring(1);
|
380 |
-
$active_tab = self.getTabById(id);
|
381 |
-
} else {
|
382 |
-
// find the tab with tabsActiveClass
|
383 |
-
$active_tab = self.$tabs.filter('.'+self.options.tabsActiveClass);
|
384 |
-
}
|
385 |
-
// validate to select the active tab for start
|
386 |
-
$active_tab = ($active_tab.length)?$active_tab:self.$tabs.first();
|
387 |
-
$active_tab.trigger('click', true);
|
388 |
-
|
389 |
-
},
|
390 |
-
|
391 |
-
onTabClicked:function(event, fromSetup){
|
392 |
-
event.preventDefault();
|
393 |
-
var self = event.data.self,
|
394 |
-
$this = $(this),
|
395 |
-
$tab_content,
|
396 |
-
active_id;
|
397 |
-
|
398 |
-
if( !fromSetup && $this.hasClass('active') ){
|
399 |
-
return;
|
400 |
-
}
|
401 |
-
|
402 |
-
self.$tabs.removeClass(self.options.tabsActiveClass);
|
403 |
-
$this.addClass(self.options.tabsActiveClass);
|
404 |
-
|
405 |
-
self.$contents.hide();
|
406 |
-
if(self.options.connectType == 'id'){
|
407 |
-
active_id = self.getIdByTab($this);
|
408 |
-
$tab_content = self.getContentById(active_id);
|
409 |
-
} else{
|
410 |
-
$tab_content = self.$contents.eq($this.index());
|
411 |
-
}
|
412 |
-
$tab_content.fadeIn(self.options.duration);
|
413 |
-
|
414 |
-
// update hash in page address if updateHash is enabled
|
415 |
-
if(self.options.updateHash){
|
416 |
-
active_id = self.getIdByTab($this);
|
417 |
-
active_id = active_id?active_id+self.options.hashSuffix:'';
|
418 |
-
|
419 |
-
if(window.history && window.history.pushState )
|
420 |
-
window.history.pushState(null, null, window.location.href.split('#')[0]+'#'+active_id);
|
421 |
-
else
|
422 |
-
window.location.hash = active_id;
|
423 |
-
}
|
424 |
-
|
425 |
-
// trigger custom event
|
426 |
-
self.$el.trigger('avtTabChange', $tab_content.attr('id'));
|
427 |
-
|
428 |
-
},
|
429 |
-
|
430 |
-
getTabById:function(id){
|
431 |
-
// remove hashSuffix (if exist) from id hash to get real element id
|
432 |
-
id = id.split(this.options.hashSuffix)[0];
|
433 |
-
// search for hash in tabs markup - generaly should be direct children of tab
|
434 |
-
// check for href="#id" format
|
435 |
-
var $active_tab = this.$tabs.find('[href="#'+ id +'"]').eq(0);
|
436 |
-
// if no match found, check for href="id" format too
|
437 |
-
if(!$active_tab.length)
|
438 |
-
$active_tab = this.$tabs.find('[href="'+ id +'"]').eq(0);
|
439 |
-
// get the tab if hash found in it
|
440 |
-
return $active_tab.length?$active_tab.parent():$active_tab;
|
441 |
-
},
|
442 |
-
|
443 |
-
getContentById:function(id){
|
444 |
-
return this.$contents.filter('#'+id);
|
445 |
-
},
|
446 |
-
|
447 |
-
getIdByTab:function($tab){
|
448 |
-
var $anchor = $tab.find('[href]').eq(0);
|
449 |
-
return $anchor.length?$anchor.attr('href'):false;
|
450 |
-
}
|
451 |
-
};
|
452 |
-
|
453 |
-
|
454 |
-
$.fn.avertaLiveTabs = function(options){
|
455 |
-
return this.each(function(){
|
456 |
-
var container = Object.create(Container);
|
457 |
-
container.init(this, options);
|
458 |
-
});
|
459 |
-
};
|
460 |
-
|
461 |
-
$.fn.avertaLiveTabs.defaultOptions = {
|
462 |
-
tabs: 'ul.tabs > li', // Tabs selector
|
463 |
-
tabsActiveClass: 'active', // A Class that indicates active tab
|
464 |
-
contents: 'ul.tabs-content > li', // Tabs content selector
|
465 |
-
contentsActiveClass: 'active', // A Class that indicates active tab-content
|
466 |
-
transition: 'fade', // Animation type white swiching tabs
|
467 |
-
duration : '500', // Animation duration in mili seconds
|
468 |
-
connectType: 'index', // connect tabs and contents by 'index' or 'id'
|
469 |
-
enableHash: false , // check to select initial tab based on hash address
|
470 |
-
updateHash: false , // update hash in browser while switching between tabs
|
471 |
-
hashSuffix: '-tab' // suffix to add at the end of hash url to prevent page scroll
|
472 |
-
};
|
473 |
-
|
474 |
-
})(jQuery);
|
475 |
-
//js\libs\averta.aligner.js
|
476 |
-
|
477 |
-
;(function(){
|
478 |
-
|
479 |
-
"use strict";
|
480 |
-
|
481 |
-
window.MSAligner = function(type , $container , $img ){
|
482 |
-
|
483 |
-
this.$container = $container;
|
484 |
-
this.$img = $img;
|
485 |
-
|
486 |
-
this.type = type || 'stretch'; // fill , fit , stretch , tile , center
|
487 |
-
|
488 |
-
this.widthOnly = false;
|
489 |
-
this.heightOnly = false;
|
490 |
-
};
|
491 |
-
|
492 |
-
var p = MSAligner.prototype;
|
493 |
-
|
494 |
-
/*-------------- METHODS --------------*/
|
495 |
-
|
496 |
-
p.init = function(w , h){
|
497 |
-
|
498 |
-
this.baseWidth = w;
|
499 |
-
this.baseHeight = h;
|
500 |
-
this.imgRatio = w / h;
|
501 |
-
this.imgRatio2 = h / w;
|
502 |
-
|
503 |
-
switch(this.type){
|
504 |
-
case 'tile':
|
505 |
-
this.$container.css('background-image' , 'url('+ this.$img.attr('src') +')');
|
506 |
-
this.$img.detach();
|
507 |
-
break;
|
508 |
-
case 'center':
|
509 |
-
this.$container.css('background-image' , 'url('+ this.$img.attr('src') +')');
|
510 |
-
this.$container.css({
|
511 |
-
backgroundPosition : 'center center',
|
512 |
-
backgroundRepeat : 'no-repeat'
|
513 |
-
});
|
514 |
-
this.$img.detach();
|
515 |
-
break;
|
516 |
-
case 'stretch':
|
517 |
-
this.$img.css({
|
518 |
-
width : '100%',
|
519 |
-
height : '100%'
|
520 |
-
});
|
521 |
-
break;
|
522 |
-
case 'fill':
|
523 |
-
case 'fit' :
|
524 |
-
this.needAlign = true;
|
525 |
-
this.align();
|
526 |
-
break;
|
527 |
-
}
|
528 |
-
|
529 |
-
};
|
530 |
-
|
531 |
-
p.align = function(){
|
532 |
-
if(!this.needAlign) return;
|
533 |
-
|
534 |
-
var cont_w = this.$container.width();
|
535 |
-
var cont_h = this.$container.height();
|
536 |
-
|
537 |
-
var contRatio = cont_w / cont_h;
|
538 |
-
|
539 |
-
if(this.type == 'fill'){
|
540 |
-
if(this.imgRatio < contRatio ){
|
541 |
-
this.$img.width(cont_w);
|
542 |
-
this.$img.height(cont_w * this.imgRatio2);
|
543 |
-
}else{
|
544 |
-
this.$img.height(cont_h);
|
545 |
-
this.$img.width(cont_h * this.imgRatio);
|
546 |
-
}
|
547 |
-
|
548 |
-
}else if(this.type == 'fit'){
|
549 |
-
|
550 |
-
if(this.imgRatio < contRatio){
|
551 |
-
this.$img.height(cont_h);
|
552 |
-
this.$img.width(cont_h * this.imgRatio);
|
553 |
-
}else{
|
554 |
-
this.$img.width(cont_w);
|
555 |
-
this.$img.height(cont_w * this.imgRatio2);
|
556 |
-
}
|
557 |
-
}
|
558 |
-
|
559 |
-
this.setMargin();
|
560 |
-
|
561 |
-
};
|
562 |
-
|
563 |
-
p.changeType = function(type){
|
564 |
-
this.reset();
|
565 |
-
this.type = type;
|
566 |
-
this.reinit();
|
567 |
-
}
|
568 |
-
|
569 |
-
p.reinit = function(){
|
570 |
-
this.init(this.baseWidth , this.baseHeight);
|
571 |
-
};
|
572 |
-
|
573 |
-
p.reset = function(){
|
574 |
-
if(this.type === 'center' || this.type === 'tile'){
|
575 |
-
this.$container.css({
|
576 |
-
'background-image' : '',
|
577 |
-
backgroundPosition : '',
|
578 |
-
backgroundRepeat : ''
|
579 |
-
});
|
580 |
-
this.$img.appendTo(this.$container);
|
581 |
-
}else{
|
582 |
-
this.$img.css({
|
583 |
-
width : '',
|
584 |
-
height : '',
|
585 |
-
'margin-top' : '',
|
586 |
-
'margin-left': ''
|
587 |
-
});
|
588 |
-
}
|
589 |
-
};
|
590 |
-
|
591 |
-
p.setMargin = function(){
|
592 |
-
|
593 |
-
var cont_w = this.$container.width();
|
594 |
-
var cont_h = this.$container.height();
|
595 |
-
|
596 |
-
this.$img.css('margin-top' , (cont_h - this.$img[0].offsetHeight) / 2 + 'px');
|
597 |
-
this.$img.css('margin-left', (cont_w - this.$img[0].offsetWidth ) / 2 + 'px');
|
598 |
-
};
|
599 |
-
|
600 |
-
})();
|
601 |
-
//js\libs\jquery.ddslick.js
|
602 |
-
|
603 |
-
/*!
|
604 |
-
* Custom DropDown plugin by PC
|
605 |
-
* http://designwithpc.com/Plugins/ddslick
|
606 |
-
* Author: PC
|
607 |
-
*/
|
608 |
-
|
609 |
-
//Title: Custom DropDown plugin by PC
|
610 |
-
//Documentation: http://designwithpc.com/Plugins/ddslick
|
611 |
-
//Author: PC
|
612 |
-
//Website: http://designwithpc.com
|
613 |
-
//Twitter: http://twitter.com/chaudharyp
|
614 |
-
|
615 |
-
(function ($) {
|
616 |
-
|
617 |
-
$.fn.ddslick = function (method) {
|
618 |
-
if (methods[method]) {
|
619 |
-
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
620 |
-
} else if (typeof method === 'object' || !method) {
|
621 |
-
return methods.init.apply(this, arguments);
|
622 |
-
} else {
|
623 |
-
$.error('Method ' + method + ' does not exists.');
|
624 |
-
}
|
625 |
-
};
|
626 |
-
|
627 |
-
var methods = {},
|
628 |
-
|
629 |
-
//Set defauls for the control
|
630 |
-
defaults = {
|
631 |
-
data: [],
|
632 |
-
keepJSONItemsOnTop: false,
|
633 |
-
width: 260,
|
634 |
-
height: null,
|
635 |
-
background: "#eee",
|
636 |
-
selectText: "",
|
637 |
-
defaultSelectedIndex: null,
|
638 |
-
truncateDescription: true,
|
639 |
-
imagePosition: "left",
|
640 |
-
showSelectedHTML: true,
|
641 |
-
clickOffToClose: true,
|
642 |
-
onSelected: function () { }
|
643 |
-
},
|
644 |
-
|
645 |
-
ddSelectHtml = '<div class="dd-select"><input class="dd-selected-value" type="hidden" /><a class="dd-selected"></a><span class="dd-pointer dd-pointer-down"></span></div>',
|
646 |
-
ddOptionsHtml = '<ul class="dd-options"></ul>';
|
647 |
-
|
648 |
-
//CSS for ddSlick
|
649 |
-
/* ddslickCSS = '<style id="css-ddslick" type="text/css">' +
|
650 |
-
'.dd-select{ border-radius:2px; border:solid 1px #ccc; position:relative; cursor:pointer;}' +
|
651 |
-
'.dd-desc { color:#aaa; display:block; overflow: hidden; font-weight:normal; line-height: 1.4em; }' +
|
652 |
-
'.dd-selected{ overflow:hidden; display:block; padding:10px; font-weight:bold;}' +
|
653 |
-
'.dd-pointer{ width:0; height:0; position:absolute; right:10px; top:50%; margin-top:-3px;}' +
|
654 |
-
'.dd-pointer-down{ border:solid 5px transparent; border-top:solid 5px #000; }' +
|
655 |
-
'.dd-pointer-up{border:solid 5px transparent !important; border-bottom:solid 5px #000 !important; margin-top:-8px;}' +
|
656 |
-
'.dd-options{ border:solid 1px #ccc; border-top:none; list-style:none; box-shadow:0px 1px 5px #ddd; display:none; position:absolute; z-index:2000; margin:0; padding:0;background:#fff; overflow:auto;}' +
|
657 |
-
'.dd-option{ padding:10px; display:block; border-bottom:solid 1px #ddd; overflow:hidden; text-decoration:none; color:#333; cursor:pointer;-webkit-transition: all 0.25s ease-in-out; -moz-transition: all 0.25s ease-in-out;-o-transition: all 0.25s ease-in-out;-ms-transition: all 0.25s ease-in-out; }' +
|
658 |
-
'.dd-options > li:last-child > .dd-option{ border-bottom:none;}' +
|
659 |
-
'.dd-option:hover{ background:#f3f3f3; color:#000;}' +
|
660 |
-
'.dd-selected-description-truncated { text-overflow: ellipsis; white-space:nowrap; }' +
|
661 |
-
'.dd-option-selected { background:#f6f6f6; }' +
|
662 |
-
'.dd-option-image, .dd-selected-image { vertical-align:middle; float:left; margin-right:5px; max-width:64px;}' +
|
663 |
-
'.dd-image-right { float:right; margin-right:15px; margin-left:5px;}' +
|
664 |
-
'.dd-container{ position:relative;} .dd-selected-text { font-weight:bold}</style>';
|
665 |
-
|
666 |
-
//CSS styles are only added once.
|
667 |
-
if ($('#css-ddslick').length <= 0) {
|
668 |
-
$(ddslickCSS).appendTo('head');
|
669 |
-
}*/
|
670 |
-
|
671 |
-
//Public methods
|
672 |
-
methods.init = function (options) {
|
673 |
-
//Preserve the original defaults by passing an empty object as the target
|
674 |
-
var options = $.extend({}, defaults, options);
|
675 |
-
|
676 |
-
//Apply on all selected elements
|
677 |
-
return this.each(function () {
|
678 |
-
var obj = $(this),
|
679 |
-
data = obj.data('ddslick');
|
680 |
-
//If the plugin has not been initialized yet
|
681 |
-
if (!data) {
|
682 |
-
|
683 |
-
var ddSelect = [], ddJson = options.data;
|
684 |
-
|
685 |
-
//Get data from HTML select options
|
686 |
-
obj.find('option').each(function () {
|
687 |
-
var $this = $(this), thisData = $this.data();
|
688 |
-
ddSelect.push({
|
689 |
-
text: $.trim($this.text()),
|
690 |
-
value: $this.val(),
|
691 |
-
selected: $this.is(':selected'),
|
692 |
-
description: thisData.description,
|
693 |
-
imageSrc: thisData.imagesrc //keep it lowercase for HTML5 data-attributes
|
694 |
-
});
|
695 |
-
});
|
696 |
-
|
697 |
-
//Update Plugin data merging both HTML select data and JSON data for the dropdown
|
698 |
-
if (options.keepJSONItemsOnTop)
|
699 |
-
$.merge(options.data, ddSelect);
|
700 |
-
else options.data = $.merge(ddSelect, options.data);
|
701 |
-
|
702 |
-
//Replace HTML select with empty placeholder, keep the original
|
703 |
-
var original = obj, placeholder = $('<div id="' + obj.attr('id') + '"></div>');
|
704 |
-
obj.replaceWith(placeholder);
|
705 |
-
obj = placeholder;
|
706 |
-
|
707 |
-
//Add classes and append ddSelectHtml & ddOptionsHtml to the container
|
708 |
-
obj.addClass('dd-container').append(ddSelectHtml).append(ddOptionsHtml);
|
709 |
-
|
710 |
-
//Get newly created ddOptions and ddSelect to manipulate
|
711 |
-
var ddSelect = obj.find('.dd-select'),
|
712 |
-
ddOptions = obj.find('.dd-options');
|
713 |
-
|
714 |
-
//Set widths
|
715 |
-
ddOptions.css({ width: options.width });
|
716 |
-
ddSelect.css({ width: options.width, background: options.background });
|
717 |
-
obj.css({ width: options.width });
|
718 |
-
|
719 |
-
//Set height
|
720 |
-
if (options.height != null)
|
721 |
-
ddOptions.css({ height: options.height, overflow: 'auto' });
|
722 |
-
|
723 |
-
//Add ddOptions to the container. Replace with template engine later.
|
724 |
-
$.each(options.data, function (index, item) {
|
725 |
-
if (item.selected) options.defaultSelectedIndex = index;
|
726 |
-
ddOptions.append('<li>' +
|
727 |
-
'<a class="dd-option">' +
|
728 |
-
(item.value ? ' <input class="dd-option-value" type="hidden" value="' + item.value + '" />' : '') +
|
729 |
-
(item.imageSrc ? ' <img class="dd-option-image' + (options.imagePosition == "right" ? ' dd-image-right' : '') + '" src="' + item.imageSrc + '" />' : '') +
|
730 |
-
(item.text ? ' <label class="dd-option-text">' + item.text + '</label>' : '') +
|
731 |
-
(item.description ? ' <small class="dd-option-description dd-desc">' + item.description + '</small>' : '') +
|
732 |
-
'</a>' +
|
733 |
-
'</li>');
|
734 |
-
});
|
735 |
-
|
736 |
-
//Save plugin data.
|
737 |
-
var pluginData = {
|
738 |
-
settings: options,
|
739 |
-
original: original,
|
740 |
-
selectedIndex: -1,
|
741 |
-
selectedItem: null,
|
742 |
-
selectedData: null
|
743 |
-
}
|
744 |
-
obj.data('ddslick', pluginData);
|
745 |
-
|
746 |
-
//Check if needs to show the select text, otherwise show selected or default selection
|
747 |
-
if (options.selectText.length > 0 && options.defaultSelectedIndex == null) {
|
748 |
-
obj.find('.dd-selected').html(options.selectText);
|
749 |
-
}
|
750 |
-
else {
|
751 |
-
var index = (options.defaultSelectedIndex != null && options.defaultSelectedIndex >= 0 && options.defaultSelectedIndex < options.data.length)
|
752 |
-
? options.defaultSelectedIndex
|
753 |
-
: 0;
|
754 |
-
selectIndex(obj, index);
|
755 |
-
}
|
756 |
-
|
757 |
-
//EVENTS
|
758 |
-
//Displaying options
|
759 |
-
obj.find('.dd-select').on('click.ddslick', function () {
|
760 |
-
open(obj);
|
761 |
-
});
|
762 |
-
|
763 |
-
//Selecting an option
|
764 |
-
obj.find('.dd-option').on('click.ddslick', function () {
|
765 |
-
selectIndex(obj, $(this).closest('li').index());
|
766 |
-
});
|
767 |
-
|
768 |
-
//Click anywhere to close
|
769 |
-
if (options.clickOffToClose) {
|
770 |
-
ddOptions.addClass('dd-click-off-close');
|
771 |
-
obj.on('click.ddslick', function (e) { e.stopPropagation(); });
|
772 |
-
$('body').on('click', function () {
|
773 |
-
$('.dd-click-off-close').slideUp(50).siblings('.dd-select').find('.dd-pointer').removeClass('dd-pointer-up');
|
774 |
-
});
|
775 |
-
}
|
776 |
-
}
|
777 |
-
});
|
778 |
-
};
|
779 |
-
|
780 |
-
//Public method to select an option by its index
|
781 |
-
methods.select = function (options) {
|
782 |
-
return this.each(function () {
|
783 |
-
if (options.index !== null)
|
784 |
-
selectIndex($(this), options.index);
|
785 |
-
});
|
786 |
-
}
|
787 |
-
|
788 |
-
//Public method to open drop down
|
789 |
-
methods.open = function () {
|
790 |
-
return this.each(function () {
|
791 |
-
var $this = $(this),
|
792 |
-
pluginData = $this.data('ddslick');
|
793 |
-
|
794 |
-
//Check if plugin is initialized
|
795 |
-
if (pluginData)
|
796 |
-
open($this);
|
797 |
-
});
|
798 |
-
};
|
799 |
-
|
800 |
-
//Public method to close drop down
|
801 |
-
methods.close = function () {
|
802 |
-
return this.each(function () {
|
803 |
-
var $this = $(this),
|
804 |
-
pluginData = $this.data('ddslick');
|
805 |
-
|
806 |
-
//Check if plugin is initialized
|
807 |
-
if (pluginData)
|
808 |
-
close($this);
|
809 |
-
});
|
810 |
-
};
|
811 |
-
|
812 |
-
//Public method to destroy. Unbind all events and restore the original Html select/options
|
813 |
-
methods.destroy = function () {
|
814 |
-
return this.each(function () {
|
815 |
-
var $this = $(this),
|
816 |
-
pluginData = $this.data('ddslick');
|
817 |
-
|
818 |
-
//Check if already destroyed
|
819 |
-
if (pluginData) {
|
820 |
-
var originalElement = pluginData.original;
|
821 |
-
$this.removeData('ddslick').unbind('.ddslick').replaceWith(originalElement);
|
822 |
-
}
|
823 |
-
});
|
824 |
-
}
|
825 |
-
|
826 |
-
//Private: Select index
|
827 |
-
function selectIndex(obj, index) {
|
828 |
-
|
829 |
-
//Get plugin data
|
830 |
-
var pluginData = obj.data('ddslick');
|
831 |
-
|
832 |
-
//Get required elements
|
833 |
-
var ddSelected = obj.find('.dd-selected'),
|
834 |
-
ddSelectedValue = ddSelected.siblings('.dd-selected-value'),
|
835 |
-
ddOptions = obj.find('.dd-options'),
|
836 |
-
ddPointer = ddSelected.siblings('.dd-pointer'),
|
837 |
-
selectedOption = obj.find('.dd-option').eq(index),
|
838 |
-
selectedLiItem = selectedOption.closest('li'),
|
839 |
-
settings = pluginData.settings,
|
840 |
-
selectedData = pluginData.settings.data[index];
|
841 |
-
|
842 |
-
//Highlight selected option
|
843 |
-
obj.find('.dd-option').removeClass('dd-option-selected');
|
844 |
-
selectedOption.addClass('dd-option-selected');
|
845 |
-
|
846 |
-
//Update or Set plugin data with new selection
|
847 |
-
pluginData.selectedIndex = index;
|
848 |
-
pluginData.selectedItem = selectedLiItem;
|
849 |
-
pluginData.selectedData = selectedData;
|
850 |
-
|
851 |
-
//If set to display to full html, add html
|
852 |
-
if (settings.showSelectedHTML) {
|
853 |
-
ddSelected.html(
|
854 |
-
(selectedData.imageSrc ? '<img class="dd-selected-image' + (settings.imagePosition == "right" ? ' dd-image-right' : '') + '" src="' + selectedData.imageSrc + '" />' : '') +
|
855 |
-
(selectedData.text ? '<label class="dd-selected-text">' + selectedData.text + '</label>' : '') +
|
856 |
-
(selectedData.description ? '<small class="dd-selected-description dd-desc' + (settings.truncateDescription ? ' dd-selected-description-truncated' : '') + '" >' + selectedData.description + '</small>' : '')
|
857 |
-
);
|
858 |
-
|
859 |
-
}
|
860 |
-
//Else only display text as selection
|
861 |
-
else ddSelected.html(selectedData.text);
|
862 |
-
|
863 |
-
//Updating selected option value
|
864 |
-
ddSelectedValue.val(selectedData.value);
|
865 |
-
|
866 |
-
//BONUS! Update the original element attribute with the new selection
|
867 |
-
pluginData.original.val(selectedData.value);
|
868 |
-
obj.data('ddslick', pluginData);
|
869 |
-
|
870 |
-
//Close options on selection
|
871 |
-
close(obj);
|
872 |
-
|
873 |
-
//Adjust appearence for selected option
|
874 |
-
adjustSelectedHeight(obj);
|
875 |
-
|
876 |
-
//Callback function on selection
|
877 |
-
if (typeof settings.onSelected == 'function') {
|
878 |
-
settings.onSelected.call(this, pluginData);
|
879 |
-
}
|
880 |
-
}
|
881 |
-
|
882 |
-
//Private: Close the drop down options
|
883 |
-
function open(obj) {
|
884 |
-
|
885 |
-
var $this = obj.find('.dd-select'),
|
886 |
-
ddOptions = $this.siblings('.dd-options'),
|
887 |
-
ddPointer = $this.find('.dd-pointer'),
|
888 |
-
wasOpen = ddOptions.is(':visible');
|
889 |
-
|
890 |
-
//Close all open options (multiple plugins) on the page
|
891 |
-
$('.dd-click-off-close').not(ddOptions).slideUp(50);
|
892 |
-
$('.dd-pointer').removeClass('dd-pointer-up');
|
893 |
-
|
894 |
-
if (wasOpen) {
|
895 |
-
ddOptions.slideUp('fast');
|
896 |
-
ddPointer.removeClass('dd-pointer-up');
|
897 |
-
}
|
898 |
-
else {
|
899 |
-
ddOptions.slideDown('fast');
|
900 |
-
ddPointer.addClass('dd-pointer-up');
|
901 |
-
}
|
902 |
-
|
903 |
-
//Fix text height (i.e. display title in center), if there is no description
|
904 |
-
adjustOptionsHeight(obj);
|
905 |
-
}
|
906 |
-
|
907 |
-
//Private: Close the drop down options
|
908 |
-
function close(obj) {
|
909 |
-
//Close drop down and adjust pointer direction
|
910 |
-
obj.find('.dd-options').slideUp(50);
|
911 |
-
obj.find('.dd-pointer').removeClass('dd-pointer-up').removeClass('dd-pointer-up');
|
912 |
-
}
|
913 |
-
|
914 |
-
//Private: Adjust appearence for selected option (move title to middle), when no desripction
|
915 |
-
function adjustSelectedHeight(obj) {
|
916 |
-
|
917 |
-
//Get height of dd-selected
|
918 |
-
var lSHeight = obj.find('.dd-select').css('height');
|
919 |
-
|
920 |
-
//Check if there is selected description
|
921 |
-
var descriptionSelected = obj.find('.dd-selected-description');
|
922 |
-
var imgSelected = obj.find('.dd-selected-image');
|
923 |
-
if (descriptionSelected.length <= 0 && imgSelected.length > 0) {
|
924 |
-
obj.find('.dd-selected-text').css('lineHeight', lSHeight);
|
925 |
-
}
|
926 |
-
}
|
927 |
-
|
928 |
-
//Private: Adjust appearence for drop down options (move title to middle), when no desripction
|
929 |
-
function adjustOptionsHeight(obj) {
|
930 |
-
obj.find('.dd-option').each(function () {
|
931 |
-
var $this = $(this);
|
932 |
-
var lOHeight = $this.css('height');
|
933 |
-
var descriptionOption = $this.find('.dd-option-description');
|
934 |
-
var imgOption = obj.find('.dd-option-image');
|
935 |
-
if (descriptionOption.length <= 0 && imgOption.length > 0) {
|
936 |
-
$this.find('.dd-option-text').css('lineHeight', lOHeight);
|
937 |
-
}
|
938 |
-
});
|
939 |
-
}
|
940 |
-
|
941 |
-
})(jQuery);//js\libs\jquery.mousewheel.js
|
942 |
-
|
943 |
/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
|
944 |
* Licensed under the MIT License (LICENSE.txt).
|
945 |
*
|
@@ -947,9984 +17,29 @@ if(typeof Object.create !== 'function' ){ Object.create = function (obj){ functi
|
|
947 |
*
|
948 |
* Requires: jQuery 1.2.2+
|
949 |
*/
|
950 |
-
|
951 |
-
(function (factory) {
|
952 |
-
if ( typeof define === 'function' && define.amd ) {
|
953 |
-
// AMD. Register as an anonymous module.
|
954 |
-
define(['jquery'], factory);
|
955 |
-
} else if (typeof exports === 'object') {
|
956 |
-
// Node/CommonJS style for Browserify
|
957 |
-
module.exports = factory;
|
958 |
-
} else {
|
959 |
-
// Browser globals
|
960 |
-
factory(jQuery);
|
961 |
-
}
|
962 |
-
}(function ($) {
|
963 |
-
|
964 |
-
var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
|
965 |
-
toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
|
966 |
-
['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
|
967 |
-
slice = Array.prototype.slice,
|
968 |
-
nullLowestDeltaTimeout, lowestDelta;
|
969 |
-
|
970 |
-
if ( $.event.fixHooks ) {
|
971 |
-
for ( var i = toFix.length; i; ) {
|
972 |
-
$.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
|
973 |
-
}
|
974 |
-
}
|
975 |
-
|
976 |
-
var special = $.event.special.mousewheel = {
|
977 |
-
version: '3.1.9',
|
978 |
-
|
979 |
-
setup: function() {
|
980 |
-
if ( this.addEventListener ) {
|
981 |
-
for ( var i = toBind.length; i; ) {
|
982 |
-
this.addEventListener( toBind[--i], handler, false );
|
983 |
-
}
|
984 |
-
} else {
|
985 |
-
this.onmousewheel = handler;
|
986 |
-
}
|
987 |
-
// Store the line height and page height for this particular element
|
988 |
-
$.data(this, 'mousewheel-line-height', special.getLineHeight(this));
|
989 |
-
$.data(this, 'mousewheel-page-height', special.getPageHeight(this));
|
990 |
-
},
|
991 |
-
|
992 |
-
teardown: function() {
|
993 |
-
if ( this.removeEventListener ) {
|
994 |
-
for ( var i = toBind.length; i; ) {
|
995 |
-
this.removeEventListener( toBind[--i], handler, false );
|
996 |
-
}
|
997 |
-
} else {
|
998 |
-
this.onmousewheel = null;
|
999 |
-
}
|
1000 |
-
},
|
1001 |
-
|
1002 |
-
getLineHeight: function(elem) {
|
1003 |
-
return parseInt($(elem)['offsetParent' in $.fn ? 'offsetParent' : 'parent']().css('fontSize'), 10);
|
1004 |
-
},
|
1005 |
-
|
1006 |
-
getPageHeight: function(elem) {
|
1007 |
-
return $(elem).height();
|
1008 |
-
},
|
1009 |
-
|
1010 |
-
settings: {
|
1011 |
-
adjustOldDeltas: true
|
1012 |
-
}
|
1013 |
-
};
|
1014 |
-
|
1015 |
-
$.fn.extend({
|
1016 |
-
mousewheel: function(fn) {
|
1017 |
-
return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
|
1018 |
-
},
|
1019 |
-
|
1020 |
-
unmousewheel: function(fn) {
|
1021 |
-
return this.unbind('mousewheel', fn);
|
1022 |
-
}
|
1023 |
-
});
|
1024 |
-
|
1025 |
-
|
1026 |
-
function handler(event) {
|
1027 |
-
var orgEvent = event || window.event,
|
1028 |
-
args = slice.call(arguments, 1),
|
1029 |
-
delta = 0,
|
1030 |
-
deltaX = 0,
|
1031 |
-
deltaY = 0,
|
1032 |
-
absDelta = 0;
|
1033 |
-
event = $.event.fix(orgEvent);
|
1034 |
-
event.type = 'mousewheel';
|
1035 |
-
|
1036 |
-
// Old school scrollwheel delta
|
1037 |
-
if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
|
1038 |
-
if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
|
1039 |
-
if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
|
1040 |
-
if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
|
1041 |
-
|
1042 |
-
// Firefox < 17 horizontal scrolling related to DOMMouseScroll event
|
1043 |
-
if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
1044 |
-
deltaX = deltaY * -1;
|
1045 |
-
deltaY = 0;
|
1046 |
-
}
|
1047 |
-
|
1048 |
-
// Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
|
1049 |
-
delta = deltaY === 0 ? deltaX : deltaY;
|
1050 |
-
|
1051 |
-
// New school wheel delta (wheel event)
|
1052 |
-
if ( 'deltaY' in orgEvent ) {
|
1053 |
-
deltaY = orgEvent.deltaY * -1;
|
1054 |
-
delta = deltaY;
|
1055 |
-
}
|
1056 |
-
if ( 'deltaX' in orgEvent ) {
|
1057 |
-
deltaX = orgEvent.deltaX;
|
1058 |
-
if ( deltaY === 0 ) { delta = deltaX * -1; }
|
1059 |
-
}
|
1060 |
-
|
1061 |
-
// No change actually happened, no reason to go any further
|
1062 |
-
if ( deltaY === 0 && deltaX === 0 ) { return; }
|
1063 |
-
|
1064 |
-
// Need to convert lines and pages to pixels if we aren't already in pixels
|
1065 |
-
// There are three delta modes:
|
1066 |
-
// * deltaMode 0 is by pixels, nothing to do
|
1067 |
-
// * deltaMode 1 is by lines
|
1068 |
-
// * deltaMode 2 is by pages
|
1069 |
-
if ( orgEvent.deltaMode === 1 ) {
|
1070 |
-
var lineHeight = $.data(this, 'mousewheel-line-height');
|
1071 |
-
delta *= lineHeight;
|
1072 |
-
deltaY *= lineHeight;
|
1073 |
-
deltaX *= lineHeight;
|
1074 |
-
} else if ( orgEvent.deltaMode === 2 ) {
|
1075 |
-
var pageHeight = $.data(this, 'mousewheel-page-height');
|
1076 |
-
delta *= pageHeight;
|
1077 |
-
deltaY *= pageHeight;
|
1078 |
-
deltaX *= pageHeight;
|
1079 |
-
}
|
1080 |
-
|
1081 |
-
// Store lowest absolute delta to normalize the delta values
|
1082 |
-
absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
|
1083 |
-
|
1084 |
-
if ( !lowestDelta || absDelta < lowestDelta ) {
|
1085 |
-
lowestDelta = absDelta;
|
1086 |
-
|
1087 |
-
// Adjust older deltas if necessary
|
1088 |
-
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
|
1089 |
-
lowestDelta /= 40;
|
1090 |
-
}
|
1091 |
-
}
|
1092 |
-
|
1093 |
-
// Adjust older deltas if necessary
|
1094 |
-
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
|
1095 |
-
// Divide all the things by 40!
|
1096 |
-
delta /= 40;
|
1097 |
-
deltaX /= 40;
|
1098 |
-
deltaY /= 40;
|
1099 |
-
}
|
1100 |
-
|
1101 |
-
// Get a whole, normalized value for the deltas
|
1102 |
-
delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
|
1103 |
-
deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
|
1104 |
-
deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
|
1105 |
-
|
1106 |
-
// Add information to the event object
|
1107 |
-
event.deltaX = deltaX;
|
1108 |
-
event.deltaY = deltaY;
|
1109 |
-
event.deltaFactor = lowestDelta;
|
1110 |
-
// Go ahead and set deltaMode to 0 since we converted to pixels
|
1111 |
-
// Although this is a little odd since we overwrite the deltaX/Y
|
1112 |
-
// properties with normalized deltas.
|
1113 |
-
event.deltaMode = 0;
|
1114 |
-
|
1115 |
-
// Add event and delta to the front of the arguments
|
1116 |
-
args.unshift(event, delta, deltaX, deltaY);
|
1117 |
-
|
1118 |
-
// Clearout lowestDelta after sometime to better
|
1119 |
-
// handle multiple device types that give different
|
1120 |
-
// a different lowestDelta
|
1121 |
-
// Ex: trackpad = 3 and mouse wheel = 120
|
1122 |
-
if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
|
1123 |
-
nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
|
1124 |
-
|
1125 |
-
return ($.event.dispatch || $.event.handle).apply(this, args);
|
1126 |
-
}
|
1127 |
-
|
1128 |
-
function nullLowestDelta() {
|
1129 |
-
lowestDelta = null;
|
1130 |
-
}
|
1131 |
-
|
1132 |
-
function shouldAdjustOldDeltas(orgEvent, absDelta) {
|
1133 |
-
// If this is an older event and the delta is divisable by 120,
|
1134 |
-
// then we are assuming that the browser is treating this as an
|
1135 |
-
// older mouse wheel event and that we should divide the deltas
|
1136 |
-
// by 40 to try and get a more usable deltaFactor.
|
1137 |
-
// Side note, this actually impacts the reported scroll distance
|
1138 |
-
// in older browsers and can cause scrolling to be slower than native.
|
1139 |
-
// Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
|
1140 |
-
return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
|
1141 |
-
}
|
1142 |
-
|
1143 |
-
}));
|
1144 |
-
|
1145 |
-
//js\libs\spectrum.js
|
1146 |
-
|
1147 |
/*! Spectrum Colorpicker v1.3.2
|
1148 |
* License: MIT
|
1149 |
* Author: Brian Grinstead
|
1150 |
* https://github.com/bgrins/spectrum
|
1151 |
* Requires: jQuery
|
1152 |
*/
|
1153 |
-
|
1154 |
-
// Spectrum Colorpicker v1.3.2
|
1155 |
-
// https://github.com/bgrins/spectrum
|
1156 |
-
// Author: Brian Grinstead
|
1157 |
-
// License: MIT
|
1158 |
-
|
1159 |
-
(function (window, $, undefined) {
|
1160 |
-
var defaultOpts = {
|
1161 |
-
|
1162 |
-
// Callbacks
|
1163 |
-
beforeShow: noop,
|
1164 |
-
move: noop,
|
1165 |
-
change: noop,
|
1166 |
-
show: noop,
|
1167 |
-
hide: noop,
|
1168 |
-
|
1169 |
-
// Options
|
1170 |
-
color: false,
|
1171 |
-
flat: false,
|
1172 |
-
showInput: false,
|
1173 |
-
allowEmpty: false,
|
1174 |
-
showButtons: true,
|
1175 |
-
clickoutFiresChange: false,
|
1176 |
-
showInitial: false,
|
1177 |
-
showPalette: false,
|
1178 |
-
showPaletteOnly: false,
|
1179 |
-
showSelectionPalette: true,
|
1180 |
-
localStorageKey: false,
|
1181 |
-
appendTo: "body",
|
1182 |
-
maxSelectionSize: 7,
|
1183 |
-
cancelText: "cancel",
|
1184 |
-
chooseText: "choose",
|
1185 |
-
clearText: "Clear Color Selection",
|
1186 |
-
preferredFormat: false,
|
1187 |
-
className: "",
|
1188 |
-
showAlpha: false,
|
1189 |
-
theme: "sp-light",
|
1190 |
-
palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
|
1191 |
-
selectionPalette: [],
|
1192 |
-
disabled: false
|
1193 |
-
},
|
1194 |
-
spectrums = [],
|
1195 |
-
IE = !!/msie/i.exec( window.navigator.userAgent ),
|
1196 |
-
rgbaSupport = (function() {
|
1197 |
-
function contains( str, substr ) {
|
1198 |
-
return !!~('' + str).indexOf(substr);
|
1199 |
-
}
|
1200 |
-
|
1201 |
-
var elem = document.createElement('div');
|
1202 |
-
var style = elem.style;
|
1203 |
-
style.cssText = 'background-color:rgba(0,0,0,.5)';
|
1204 |
-
return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
|
1205 |
-
})(),
|
1206 |
-
inputTypeColorSupport = (function() {
|
1207 |
-
var colorInput = $("<input type='color' value='!' />")[0];
|
1208 |
-
return colorInput.type === "color" && colorInput.value !== "!";
|
1209 |
-
})(),
|
1210 |
-
replaceInput = [
|
1211 |
-
"<div class='sp-replacer'>",
|
1212 |
-
"<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
|
1213 |
-
"<div class='sp-dd'>▼</div>",
|
1214 |
-
"</div>"
|
1215 |
-
].join(''),
|
1216 |
-
markup = (function () {
|
1217 |
-
|
1218 |
-
// IE does not support gradients with multiple stops, so we need to simulate
|
1219 |
-
// that for the rainbow slider with 8 divs that each have a single gradient
|
1220 |
-
var gradientFix = "";
|
1221 |
-
if (IE) {
|
1222 |
-
for (var i = 1; i <= 6; i++) {
|
1223 |
-
gradientFix += "<div class='sp-" + i + "'></div>";
|
1224 |
-
}
|
1225 |
-
}
|
1226 |
-
|
1227 |
-
return [
|
1228 |
-
"<div class='sp-container sp-hidden'>",
|
1229 |
-
"<div class='sp-palette-container'>",
|
1230 |
-
"<div class='sp-palette sp-thumb sp-cf'></div>",
|
1231 |
-
"</div>",
|
1232 |
-
"<div class='sp-picker-container'>",
|
1233 |
-
"<div class='sp-top sp-cf'>",
|
1234 |
-
"<div class='sp-fill'></div>",
|
1235 |
-
"<div class='sp-top-inner'>",
|
1236 |
-
"<div class='sp-color'>",
|
1237 |
-
"<div class='sp-sat'>",
|
1238 |
-
"<div class='sp-val'>",
|
1239 |
-
"<div class='sp-dragger'></div>",
|
1240 |
-
"</div>",
|
1241 |
-
"</div>",
|
1242 |
-
"</div>",
|
1243 |
-
"<div class='sp-clear sp-clear-display'>",
|
1244 |
-
"</div>",
|
1245 |
-
"<div class='sp-hue'>",
|
1246 |
-
"<div class='sp-slider'></div>",
|
1247 |
-
gradientFix,
|
1248 |
-
"</div>",
|
1249 |
-
"</div>",
|
1250 |
-
"<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
|
1251 |
-
"</div>",
|
1252 |
-
"<div class='sp-input-container sp-cf'>",
|
1253 |
-
"<input class='sp-input' type='text' spellcheck='false' />",
|
1254 |
-
"</div>",
|
1255 |
-
"<div class='sp-initial sp-thumb sp-cf'></div>",
|
1256 |
-
"<div class='sp-button-container sp-cf'>",
|
1257 |
-
"<a class='sp-cancel' href='#'></a>",
|
1258 |
-
"<button class='sp-choose'></button>",
|
1259 |
-
"</div>",
|
1260 |
-
"</div>",
|
1261 |
-
"</div>"
|
1262 |
-
].join("");
|
1263 |
-
})();
|
1264 |
-
|
1265 |
-
function paletteTemplate (p, color, className) {
|
1266 |
-
var html = [];
|
1267 |
-
for (var i = 0; i < p.length; i++) {
|
1268 |
-
var current = p[i];
|
1269 |
-
if(current) {
|
1270 |
-
var tiny = tinycolor(current);
|
1271 |
-
var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
|
1272 |
-
c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
|
1273 |
-
|
1274 |
-
var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
|
1275 |
-
html.push('<span title="' + tiny.toRgbString() + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
|
1276 |
-
} else {
|
1277 |
-
var cls = 'sp-clear-display';
|
1278 |
-
html.push('<span title="No Color Selected" data-color="" style="background-color:transparent;" class="' + cls + '"></span>');
|
1279 |
-
}
|
1280 |
-
}
|
1281 |
-
return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
|
1282 |
-
}
|
1283 |
-
|
1284 |
-
function hideAll() {
|
1285 |
-
for (var i = 0; i < spectrums.length; i++) {
|
1286 |
-
if (spectrums[i]) {
|
1287 |
-
spectrums[i].hide();
|
1288 |
-
}
|
1289 |
-
}
|
1290 |
-
}
|
1291 |
-
|
1292 |
-
function instanceOptions(o, callbackContext) {
|
1293 |
-
var opts = $.extend({}, defaultOpts, o);
|
1294 |
-
opts.callbacks = {
|
1295 |
-
'move': bind(opts.move, callbackContext),
|
1296 |
-
'change': bind(opts.change, callbackContext),
|
1297 |
-
'show': bind(opts.show, callbackContext),
|
1298 |
-
'hide': bind(opts.hide, callbackContext),
|
1299 |
-
'beforeShow': bind(opts.beforeShow, callbackContext)
|
1300 |
-
};
|
1301 |
-
|
1302 |
-
return opts;
|
1303 |
-
}
|
1304 |
-
|
1305 |
-
function spectrum(element, o) {
|
1306 |
-
|
1307 |
-
var opts = instanceOptions(o, element),
|
1308 |
-
flat = opts.flat,
|
1309 |
-
showSelectionPalette = opts.showSelectionPalette,
|
1310 |
-
localStorageKey = opts.localStorageKey,
|
1311 |
-
theme = opts.theme,
|
1312 |
-
callbacks = opts.callbacks,
|
1313 |
-
resize = throttle(reflow, 10),
|
1314 |
-
visible = false,
|
1315 |
-
dragWidth = 0,
|
1316 |
-
dragHeight = 0,
|
1317 |
-
dragHelperHeight = 0,
|
1318 |
-
slideHeight = 0,
|
1319 |
-
slideWidth = 0,
|
1320 |
-
alphaWidth = 0,
|
1321 |
-
alphaSlideHelperWidth = 0,
|
1322 |
-
slideHelperHeight = 0,
|
1323 |
-
currentHue = 0,
|
1324 |
-
currentSaturation = 0,
|
1325 |
-
currentValue = 0,
|
1326 |
-
currentAlpha = 1,
|
1327 |
-
palette = [],
|
1328 |
-
paletteArray = [],
|
1329 |
-
paletteLookup = {},
|
1330 |
-
selectionPalette = opts.selectionPalette.slice(0),
|
1331 |
-
maxSelectionSize = opts.maxSelectionSize,
|
1332 |
-
draggingClass = "sp-dragging",
|
1333 |
-
shiftMovementDirection = null;
|
1334 |
-
|
1335 |
-
var doc = element.ownerDocument,
|
1336 |
-
body = doc.body,
|
1337 |
-
boundElement = $(element),
|
1338 |
-
disabled = false,
|
1339 |
-
container = $(markup, doc).addClass(theme),
|
1340 |
-
dragger = container.find(".sp-color"),
|
1341 |
-
dragHelper = container.find(".sp-dragger"),
|
1342 |
-
slider = container.find(".sp-hue"),
|
1343 |
-
slideHelper = container.find(".sp-slider"),
|
1344 |
-
alphaSliderInner = container.find(".sp-alpha-inner"),
|
1345 |
-
alphaSlider = container.find(".sp-alpha"),
|
1346 |
-
alphaSlideHelper = container.find(".sp-alpha-handle"),
|
1347 |
-
textInput = container.find(".sp-input"),
|
1348 |
-
paletteContainer = container.find(".sp-palette"),
|
1349 |
-
initialColorContainer = container.find(".sp-initial"),
|
1350 |
-
cancelButton = container.find(".sp-cancel"),
|
1351 |
-
clearButton = container.find(".sp-clear"),
|
1352 |
-
chooseButton = container.find(".sp-choose"),
|
1353 |
-
isInput = boundElement.is("input"),
|
1354 |
-
isInputTypeColor = isInput && inputTypeColorSupport && boundElement.attr("type") === "color",
|
1355 |
-
shouldReplace = isInput && !flat,
|
1356 |
-
replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className) : $([]),
|
1357 |
-
offsetElement = (shouldReplace) ? replacer : boundElement,
|
1358 |
-
previewElement = replacer.find(".sp-preview-inner"),
|
1359 |
-
initialColor = opts.color || (isInput && boundElement.val()),
|
1360 |
-
colorOnShow = false,
|
1361 |
-
preferredFormat = opts.preferredFormat,
|
1362 |
-
currentPreferredFormat = preferredFormat,
|
1363 |
-
clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,
|
1364 |
-
isEmpty = !initialColor,
|
1365 |
-
allowEmpty = opts.allowEmpty && !isInputTypeColor;
|
1366 |
-
|
1367 |
-
function applyOptions() {
|
1368 |
-
|
1369 |
-
if (opts.showPaletteOnly) {
|
1370 |
-
opts.showPalette = true;
|
1371 |
-
}
|
1372 |
-
|
1373 |
-
if (opts.palette) {
|
1374 |
-
palette = opts.palette.slice(0);
|
1375 |
-
paletteArray = $.isArray(palette[0]) ? palette : [palette];
|
1376 |
-
paletteLookup = {};
|
1377 |
-
for (var i = 0; i < paletteArray.length; i++) {
|
1378 |
-
for (var j = 0; j < paletteArray[i].length; j++) {
|
1379 |
-
var rgb = tinycolor(paletteArray[i][j]).toRgbString();
|
1380 |
-
paletteLookup[rgb] = true;
|
1381 |
-
}
|
1382 |
-
}
|
1383 |
-
}
|
1384 |
-
|
1385 |
-
container.toggleClass("sp-flat", flat);
|
1386 |
-
container.toggleClass("sp-input-disabled", !opts.showInput);
|
1387 |
-
container.toggleClass("sp-alpha-enabled", opts.showAlpha);
|
1388 |
-
container.toggleClass("sp-clear-enabled", allowEmpty);
|
1389 |
-
container.toggleClass("sp-buttons-disabled", !opts.showButtons);
|
1390 |
-
container.toggleClass("sp-palette-disabled", !opts.showPalette);
|
1391 |
-
container.toggleClass("sp-palette-only", opts.showPaletteOnly);
|
1392 |
-
container.toggleClass("sp-initial-disabled", !opts.showInitial);
|
1393 |
-
container.addClass(opts.className);
|
1394 |
-
|
1395 |
-
reflow();
|
1396 |
-
}
|
1397 |
-
|
1398 |
-
function initialize() {
|
1399 |
-
|
1400 |
-
if (IE) {
|
1401 |
-
container.find("*:not(input)").attr("unselectable", "on");
|
1402 |
-
}
|
1403 |
-
|
1404 |
-
applyOptions();
|
1405 |
-
|
1406 |
-
if (shouldReplace) {
|
1407 |
-
boundElement.after(replacer).hide();
|
1408 |
-
}
|
1409 |
-
|
1410 |
-
if (!allowEmpty) {
|
1411 |
-
clearButton.hide();
|
1412 |
-
}
|
1413 |
-
|
1414 |
-
if (flat) {
|
1415 |
-
boundElement.after(container).hide();
|
1416 |
-
}
|
1417 |
-
else {
|
1418 |
-
|
1419 |
-
var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
|
1420 |
-
if (appendTo.length !== 1) {
|
1421 |
-
appendTo = $("body");
|
1422 |
-
}
|
1423 |
-
|
1424 |
-
appendTo.append(container);
|
1425 |
-
}
|
1426 |
-
|
1427 |
-
updateSelectionPaletteFromStorage();
|
1428 |
-
|
1429 |
-
offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
|
1430 |
-
if (!disabled) {
|
1431 |
-
toggle();
|
1432 |
-
}
|
1433 |
-
|
1434 |
-
e.stopPropagation();
|
1435 |
-
|
1436 |
-
if (!$(e.target).is("input")) {
|
1437 |
-
e.preventDefault();
|
1438 |
-
}
|
1439 |
-
});
|
1440 |
-
|
1441 |
-
if(boundElement.is(":disabled") || (opts.disabled === true)) {
|
1442 |
-
disable();
|
1443 |
-
}
|
1444 |
-
|
1445 |
-
// Prevent clicks from bubbling up to document. This would cause it to be hidden.
|
1446 |
-
container.click(stopPropagation);
|
1447 |
-
|
1448 |
-
// Handle user typed input
|
1449 |
-
textInput.change(setFromTextInput);
|
1450 |
-
textInput.bind("paste", function () {
|
1451 |
-
setTimeout(setFromTextInput, 1);
|
1452 |
-
});
|
1453 |
-
textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });
|
1454 |
-
|
1455 |
-
cancelButton.text(opts.cancelText);
|
1456 |
-
cancelButton.bind("click.spectrum", function (e) {
|
1457 |
-
e.stopPropagation();
|
1458 |
-
e.preventDefault();
|
1459 |
-
hide("cancel");
|
1460 |
-
});
|
1461 |
-
|
1462 |
-
clearButton.attr("title", opts.clearText);
|
1463 |
-
clearButton.bind("click.spectrum", function (e) {
|
1464 |
-
e.stopPropagation();
|
1465 |
-
e.preventDefault();
|
1466 |
-
isEmpty = true;
|
1467 |
-
move();
|
1468 |
-
|
1469 |
-
if(flat) {
|
1470 |
-
//for the flat style, this is a change event
|
1471 |
-
updateOriginalInput(true);
|
1472 |
-
}
|
1473 |
-
});
|
1474 |
-
|
1475 |
-
chooseButton.text(opts.chooseText);
|
1476 |
-
chooseButton.bind("click.spectrum", function (e) {
|
1477 |
-
e.stopPropagation();
|
1478 |
-
e.preventDefault();
|
1479 |
-
|
1480 |
-
if (isValid()) {
|
1481 |
-
updateOriginalInput(true);
|
1482 |
-
hide();
|
1483 |
-
}
|
1484 |
-
});
|
1485 |
-
|
1486 |
-
draggable(alphaSlider, function (dragX, dragY, e) {
|
1487 |
-
currentAlpha = (dragX / alphaWidth);
|
1488 |
-
isEmpty = false;
|
1489 |
-
if (e.shiftKey) {
|
1490 |
-
currentAlpha = Math.round(currentAlpha * 10) / 10;
|
1491 |
-
}
|
1492 |
-
|
1493 |
-
move();
|
1494 |
-
}, dragStart, dragStop);
|
1495 |
-
|
1496 |
-
draggable(slider, function (dragX, dragY) {
|
1497 |
-
currentHue = parseFloat(dragY / slideHeight);
|
1498 |
-
isEmpty = false;
|
1499 |
-
if (!opts.showAlpha) {
|
1500 |
-
currentAlpha = 1;
|
1501 |
-
}
|
1502 |
-
move();
|
1503 |
-
}, dragStart, dragStop);
|
1504 |
-
|
1505 |
-
draggable(dragger, function (dragX, dragY, e) {
|
1506 |
-
|
1507 |
-
// shift+drag should snap the movement to either the x or y axis.
|
1508 |
-
if (!e.shiftKey) {
|
1509 |
-
shiftMovementDirection = null;
|
1510 |
-
}
|
1511 |
-
else if (!shiftMovementDirection) {
|
1512 |
-
var oldDragX = currentSaturation * dragWidth;
|
1513 |
-
var oldDragY = dragHeight - (currentValue * dragHeight);
|
1514 |
-
var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
|
1515 |
-
|
1516 |
-
shiftMovementDirection = furtherFromX ? "x" : "y";
|
1517 |
-
}
|
1518 |
-
|
1519 |
-
var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
|
1520 |
-
var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
|
1521 |
-
|
1522 |
-
if (setSaturation) {
|
1523 |
-
currentSaturation = parseFloat(dragX / dragWidth);
|
1524 |
-
}
|
1525 |
-
if (setValue) {
|
1526 |
-
currentValue = parseFloat((dragHeight - dragY) / dragHeight);
|
1527 |
-
}
|
1528 |
-
|
1529 |
-
isEmpty = false;
|
1530 |
-
if (!opts.showAlpha) {
|
1531 |
-
currentAlpha = 1;
|
1532 |
-
}
|
1533 |
-
|
1534 |
-
move();
|
1535 |
-
|
1536 |
-
}, dragStart, dragStop);
|
1537 |
-
|
1538 |
-
if (!!initialColor) {
|
1539 |
-
set(initialColor);
|
1540 |
-
|
1541 |
-
// In case color was black - update the preview UI and set the format
|
1542 |
-
// since the set function will not run (default color is black).
|
1543 |
-
updateUI();
|
1544 |
-
currentPreferredFormat = preferredFormat || tinycolor(initialColor).format;
|
1545 |
-
|
1546 |
-
addColorToSelectionPalette(initialColor);
|
1547 |
-
}
|
1548 |
-
else {
|
1549 |
-
updateUI();
|
1550 |
-
}
|
1551 |
-
|
1552 |
-
if (flat) {
|
1553 |
-
show();
|
1554 |
-
}
|
1555 |
-
|
1556 |
-
function palletElementClick(e) {
|
1557 |
-
if (e.data && e.data.ignore) {
|
1558 |
-
set($(this).data("color"));
|
1559 |
-
move();
|
1560 |
-
}
|
1561 |
-
else {
|
1562 |
-
set($(this).data("color"));
|
1563 |
-
move();
|
1564 |
-
updateOriginalInput(true);
|
1565 |
-
hide();
|
1566 |
-
}
|
1567 |
-
|
1568 |
-
return false;
|
1569 |
-
}
|
1570 |
-
|
1571 |
-
var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
|
1572 |
-
paletteContainer.delegate(".sp-thumb-el", paletteEvent, palletElementClick);
|
1573 |
-
initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, palletElementClick);
|
1574 |
-
}
|
1575 |
-
|
1576 |
-
function updateSelectionPaletteFromStorage() {
|
1577 |
-
|
1578 |
-
if (localStorageKey && window.localStorage) {
|
1579 |
-
|
1580 |
-
// Migrate old palettes over to new format. May want to remove this eventually.
|
1581 |
-
try {
|
1582 |
-
var oldPalette = window.localStorage[localStorageKey].split(",#");
|
1583 |
-
if (oldPalette.length > 1) {
|
1584 |
-
delete window.localStorage[localStorageKey];
|
1585 |
-
$.each(oldPalette, function(i, c) {
|
1586 |
-
addColorToSelectionPalette(c);
|
1587 |
-
});
|
1588 |
-
}
|
1589 |
-
}
|
1590 |
-
catch(e) { }
|
1591 |
-
|
1592 |
-
try {
|
1593 |
-
selectionPalette = window.localStorage[localStorageKey].split(";");
|
1594 |
-
}
|
1595 |
-
catch (e) { }
|
1596 |
-
}
|
1597 |
-
}
|
1598 |
-
|
1599 |
-
function addColorToSelectionPalette(color) {
|
1600 |
-
if (showSelectionPalette) {
|
1601 |
-
var rgb = tinycolor(color).toRgbString();
|
1602 |
-
if (!paletteLookup[rgb] && selectionPalette.indexOf(rgb) === -1) {
|
1603 |
-
selectionPalette.push(rgb);
|
1604 |
-
while(selectionPalette.length > maxSelectionSize) {
|
1605 |
-
selectionPalette.shift();
|
1606 |
-
}
|
1607 |
-
}
|
1608 |
-
|
1609 |
-
if (localStorageKey && window.localStorage) {
|
1610 |
-
try {
|
1611 |
-
window.localStorage[localStorageKey] = selectionPalette.join(";");
|
1612 |
-
}
|
1613 |
-
catch(e) { }
|
1614 |
-
}
|
1615 |
-
}
|
1616 |
-
}
|
1617 |
-
|
1618 |
-
function getUniqueSelectionPalette() {
|
1619 |
-
var unique = [];
|
1620 |
-
if (opts.showPalette) {
|
1621 |
-
for (i = 0; i < selectionPalette.length; i++) {
|
1622 |
-
var rgb = tinycolor(selectionPalette[i]).toRgbString();
|
1623 |
-
|
1624 |
-
if (!paletteLookup[rgb]) {
|
1625 |
-
unique.push(selectionPalette[i]);
|
1626 |
-
}
|
1627 |
-
}
|
1628 |
-
}
|
1629 |
-
|
1630 |
-
return unique.reverse().slice(0, opts.maxSelectionSize);
|
1631 |
-
}
|
1632 |
-
|
1633 |
-
function drawPalette() {
|
1634 |
-
|
1635 |
-
var currentColor = get();
|
1636 |
-
|
1637 |
-
var html = $.map(paletteArray, function (palette, i) {
|
1638 |
-
return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i);
|
1639 |
-
});
|
1640 |
-
|
1641 |
-
updateSelectionPaletteFromStorage();
|
1642 |
-
|
1643 |
-
if (selectionPalette) {
|
1644 |
-
html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection"));
|
1645 |
-
}
|
1646 |
-
|
1647 |
-
paletteContainer.html(html.join(""));
|
1648 |
-
}
|
1649 |
-
|
1650 |
-
function drawInitial() {
|
1651 |
-
if (opts.showInitial) {
|
1652 |
-
var initial = colorOnShow;
|
1653 |
-
var current = get();
|
1654 |
-
initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial"));
|
1655 |
-
}
|
1656 |
-
}
|
1657 |
-
|
1658 |
-
function dragStart() {
|
1659 |
-
if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
|
1660 |
-
reflow();
|
1661 |
-
}
|
1662 |
-
container.addClass(draggingClass);
|
1663 |
-
shiftMovementDirection = null;
|
1664 |
-
boundElement.trigger('dragstart.spectrum', [ get() ]);
|
1665 |
-
}
|
1666 |
-
|
1667 |
-
function dragStop() {
|
1668 |
-
container.removeClass(draggingClass);
|
1669 |
-
boundElement.trigger('dragstop.spectrum', [ get() ]);
|
1670 |
-
}
|
1671 |
-
|
1672 |
-
function setFromTextInput() {
|
1673 |
-
|
1674 |
-
var value = textInput.val();
|
1675 |
-
|
1676 |
-
if ((value === null || value === "") && allowEmpty) {
|
1677 |
-
set(null);
|
1678 |
-
updateOriginalInput(true);
|
1679 |
-
}
|
1680 |
-
else {
|
1681 |
-
var tiny = tinycolor(value);
|
1682 |
-
if (tiny.ok) {
|
1683 |
-
set(tiny);
|
1684 |
-
updateOriginalInput(true);
|
1685 |
-
}
|
1686 |
-
else {
|
1687 |
-
textInput.addClass("sp-validation-error");
|
1688 |
-
}
|
1689 |
-
}
|
1690 |
-
}
|
1691 |
-
|
1692 |
-
function toggle() {
|
1693 |
-
if (visible) {
|
1694 |
-
hide();
|
1695 |
-
}
|
1696 |
-
else {
|
1697 |
-
show();
|
1698 |
-
}
|
1699 |
-
}
|
1700 |
-
|
1701 |
-
function show() {
|
1702 |
-
var event = $.Event('beforeShow.spectrum');
|
1703 |
-
|
1704 |
-
if (visible) {
|
1705 |
-
reflow();
|
1706 |
-
return;
|
1707 |
-
}
|
1708 |
-
|
1709 |
-
boundElement.trigger(event, [ get() ]);
|
1710 |
-
|
1711 |
-
if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
|
1712 |
-
return;
|
1713 |
-
}
|
1714 |
-
|
1715 |
-
hideAll();
|
1716 |
-
visible = true;
|
1717 |
-
|
1718 |
-
$(doc).bind("click.spectrum", hide);
|
1719 |
-
$(window).bind("resize.spectrum", resize);
|
1720 |
-
replacer.addClass("sp-active");
|
1721 |
-
container.removeClass("sp-hidden");
|
1722 |
-
|
1723 |
-
reflow();
|
1724 |
-
updateUI();
|
1725 |
-
|
1726 |
-
colorOnShow = get();
|
1727 |
-
|
1728 |
-
drawInitial();
|
1729 |
-
callbacks.show(colorOnShow);
|
1730 |
-
boundElement.trigger('show.spectrum', [ colorOnShow ]);
|
1731 |
-
}
|
1732 |
-
|
1733 |
-
function hide(e) {
|
1734 |
-
|
1735 |
-
// Return on right click
|
1736 |
-
if (e && e.type == "click" && e.button == 2) { return; }
|
1737 |
-
|
1738 |
-
// Return if hiding is unnecessary
|
1739 |
-
if (!visible || flat) { return; }
|
1740 |
-
visible = false;
|
1741 |
-
|
1742 |
-
$(doc).unbind("click.spectrum", hide);
|
1743 |
-
$(window).unbind("resize.spectrum", resize);
|
1744 |
-
|
1745 |
-
replacer.removeClass("sp-active");
|
1746 |
-
container.addClass("sp-hidden");
|
1747 |
-
|
1748 |
-
var colorHasChanged = !tinycolor.equals(get(), colorOnShow);
|
1749 |
-
|
1750 |
-
if (colorHasChanged) {
|
1751 |
-
if (clickoutFiresChange && e !== "cancel") {
|
1752 |
-
updateOriginalInput(true);
|
1753 |
-
}
|
1754 |
-
else {
|
1755 |
-
revert();
|
1756 |
-
}
|
1757 |
-
}
|
1758 |
-
|
1759 |
-
callbacks.hide(get());
|
1760 |
-
boundElement.trigger('hide.spectrum', [ get() ]);
|
1761 |
-
}
|
1762 |
-
|
1763 |
-
function revert() {
|
1764 |
-
set(colorOnShow, true);
|
1765 |
-
}
|
1766 |
-
|
1767 |
-
function set(color, ignoreFormatChange) {
|
1768 |
-
if (tinycolor.equals(color, get())) {
|
1769 |
-
// Update UI just in case a validation error needs
|
1770 |
-
// to be cleared.
|
1771 |
-
updateUI();
|
1772 |
-
return;
|
1773 |
-
}
|
1774 |
-
|
1775 |
-
var newColor, newHsv;
|
1776 |
-
if (!color && allowEmpty) {
|
1777 |
-
isEmpty = true;
|
1778 |
-
} else {
|
1779 |
-
isEmpty = false;
|
1780 |
-
newColor = tinycolor(color);
|
1781 |
-
newHsv = newColor.toHsv();
|
1782 |
-
|
1783 |
-
currentHue = (newHsv.h % 360) / 360;
|
1784 |
-
currentSaturation = newHsv.s;
|
1785 |
-
currentValue = newHsv.v;
|
1786 |
-
currentAlpha = newHsv.a;
|
1787 |
-
}
|
1788 |
-
updateUI();
|
1789 |
-
|
1790 |
-
if (newColor && newColor.ok && !ignoreFormatChange) {
|
1791 |
-
currentPreferredFormat = preferredFormat || newColor.format;
|
1792 |
-
}
|
1793 |
-
}
|
1794 |
-
|
1795 |
-
function get(opts) {
|
1796 |
-
opts = opts || { };
|
1797 |
-
|
1798 |
-
if (allowEmpty && isEmpty) {
|
1799 |
-
return null;
|
1800 |
-
}
|
1801 |
-
|
1802 |
-
return tinycolor.fromRatio({
|
1803 |
-
h: currentHue,
|
1804 |
-
s: currentSaturation,
|
1805 |
-
v: currentValue,
|
1806 |
-
a: Math.round(currentAlpha * 100) / 100
|
1807 |
-
}, { format: opts.format || currentPreferredFormat });
|
1808 |
-
}
|
1809 |
-
|
1810 |
-
function isValid() {
|
1811 |
-
return !textInput.hasClass("sp-validation-error");
|
1812 |
-
}
|
1813 |
-
|
1814 |
-
function move() {
|
1815 |
-
updateUI();
|
1816 |
-
|
1817 |
-
callbacks.move(get());
|
1818 |
-
boundElement.trigger('move.spectrum', [ get() ]);
|
1819 |
-
}
|
1820 |
-
|
1821 |
-
function updateUI() {
|
1822 |
-
|
1823 |
-
textInput.removeClass("sp-validation-error");
|
1824 |
-
|
1825 |
-
updateHelperLocations();
|
1826 |
-
|
1827 |
-
// Update dragger background color (gradients take care of saturation and value).
|
1828 |
-
var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });
|
1829 |
-
dragger.css("background-color", flatColor.toHexString());
|
1830 |
-
|
1831 |
-
// Get a format that alpha will be included in (hex and names ignore alpha)
|
1832 |
-
var format = currentPreferredFormat;
|
1833 |
-
if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
|
1834 |
-
if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
|
1835 |
-
format = "rgb";
|
1836 |
-
}
|
1837 |
-
}
|
1838 |
-
|
1839 |
-
var realColor = get({ format: format }),
|
1840 |
-
displayColor = '';
|
1841 |
-
|
1842 |
-
//reset background info for preview element
|
1843 |
-
previewElement.removeClass("sp-clear-display");
|
1844 |
-
previewElement.css('background-color', 'transparent');
|
1845 |
-
|
1846 |
-
if (!realColor && allowEmpty) {
|
1847 |
-
// Update the replaced elements background with icon indicating no color selection
|
1848 |
-
previewElement.addClass("sp-clear-display");
|
1849 |
-
}
|
1850 |
-
else {
|
1851 |
-
var realHex = realColor.toHexString(),
|
1852 |
-
realRgb = realColor.toRgbString();
|
1853 |
-
|
1854 |
-
// Update the replaced elements background color (with actual selected color)
|
1855 |
-
if (rgbaSupport || realColor.alpha === 1) {
|
1856 |
-
previewElement.css("background-color", realRgb);
|
1857 |
-
}
|
1858 |
-
else {
|
1859 |
-
previewElement.css("background-color", "transparent");
|
1860 |
-
previewElement.css("filter", realColor.toFilter());
|
1861 |
-
}
|
1862 |
-
|
1863 |
-
if (opts.showAlpha) {
|
1864 |
-
var rgb = realColor.toRgb();
|
1865 |
-
rgb.a = 0;
|
1866 |
-
var realAlpha = tinycolor(rgb).toRgbString();
|
1867 |
-
var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
|
1868 |
-
|
1869 |
-
if (IE) {
|
1870 |
-
alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));
|
1871 |
-
}
|
1872 |
-
else {
|
1873 |
-
alphaSliderInner.css("background", "-webkit-" + gradient);
|
1874 |
-
alphaSliderInner.css("background", "-moz-" + gradient);
|
1875 |
-
alphaSliderInner.css("background", "-ms-" + gradient);
|
1876 |
-
// Use current syntax gradient on unprefixed property.
|
1877 |
-
alphaSliderInner.css("background",
|
1878 |
-
"linear-gradient(to right, " + realAlpha + ", " + realHex + ")");
|
1879 |
-
}
|
1880 |
-
}
|
1881 |
-
|
1882 |
-
displayColor = realColor.toString(format);
|
1883 |
-
}
|
1884 |
-
|
1885 |
-
// Update the text entry input as it changes happen
|
1886 |
-
if (opts.showInput) {
|
1887 |
-
textInput.val(displayColor);
|
1888 |
-
}
|
1889 |
-
|
1890 |
-
if (opts.showPalette) {
|
1891 |
-
drawPalette();
|
1892 |
-
}
|
1893 |
-
|
1894 |
-
drawInitial();
|
1895 |
-
}
|
1896 |
-
|
1897 |
-
function updateHelperLocations() {
|
1898 |
-
var s = currentSaturation;
|
1899 |
-
var v = currentValue;
|
1900 |
-
|
1901 |
-
if(allowEmpty && isEmpty) {
|
1902 |
-
//if selected color is empty, hide the helpers
|
1903 |
-
alphaSlideHelper.hide();
|
1904 |
-
slideHelper.hide();
|
1905 |
-
dragHelper.hide();
|
1906 |
-
}
|
1907 |
-
else {
|
1908 |
-
//make sure helpers are visible
|
1909 |
-
alphaSlideHelper.show();
|
1910 |
-
slideHelper.show();
|
1911 |
-
dragHelper.show();
|
1912 |
-
|
1913 |
-
// Where to show the little circle in that displays your current selected color
|
1914 |
-
var dragX = s * dragWidth;
|
1915 |
-
var dragY = dragHeight - (v * dragHeight);
|
1916 |
-
dragX = Math.max(
|
1917 |
-
-dragHelperHeight,
|
1918 |
-
Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)
|
1919 |
-
);
|
1920 |
-
dragY = Math.max(
|
1921 |
-
-dragHelperHeight,
|
1922 |
-
Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)
|
1923 |
-
);
|
1924 |
-
dragHelper.css({
|
1925 |
-
"top": dragY + "px",
|
1926 |
-
"left": dragX + "px"
|
1927 |
-
});
|
1928 |
-
|
1929 |
-
var alphaX = currentAlpha * alphaWidth;
|
1930 |
-
alphaSlideHelper.css({
|
1931 |
-
"left": (alphaX - (alphaSlideHelperWidth / 2)) + "px"
|
1932 |
-
});
|
1933 |
-
|
1934 |
-
// Where to show the bar that displays your current selected hue
|
1935 |
-
var slideY = (currentHue) * slideHeight;
|
1936 |
-
slideHelper.css({
|
1937 |
-
"top": (slideY - slideHelperHeight) + "px"
|
1938 |
-
});
|
1939 |
-
}
|
1940 |
-
}
|
1941 |
-
|
1942 |
-
function updateOriginalInput(fireCallback) {
|
1943 |
-
var color = get(),
|
1944 |
-
displayColor = '',
|
1945 |
-
hasChanged = !tinycolor.equals(color, colorOnShow);
|
1946 |
-
|
1947 |
-
if (color) {
|
1948 |
-
displayColor = color.toString(currentPreferredFormat);
|
1949 |
-
// Update the selection palette with the current color
|
1950 |
-
addColorToSelectionPalette(color);
|
1951 |
-
}
|
1952 |
-
|
1953 |
-
if (isInput) {
|
1954 |
-
boundElement.val(displayColor);
|
1955 |
-
}
|
1956 |
-
|
1957 |
-
colorOnShow = color;
|
1958 |
-
|
1959 |
-
if (fireCallback && hasChanged) {
|
1960 |
-
callbacks.change(color);
|
1961 |
-
boundElement.trigger('change', [ color ]);
|
1962 |
-
}
|
1963 |
-
}
|
1964 |
-
|
1965 |
-
function reflow() {
|
1966 |
-
dragWidth = dragger.width();
|
1967 |
-
dragHeight = dragger.height();
|
1968 |
-
dragHelperHeight = dragHelper.height();
|
1969 |
-
slideWidth = slider.width();
|
1970 |
-
slideHeight = slider.height();
|
1971 |
-
slideHelperHeight = slideHelper.height();
|
1972 |
-
alphaWidth = alphaSlider.width();
|
1973 |
-
alphaSlideHelperWidth = alphaSlideHelper.width();
|
1974 |
-
|
1975 |
-
if (!flat) {
|
1976 |
-
container.css("position", "absolute");
|
1977 |
-
container.offset(getOffset(container, offsetElement));
|
1978 |
-
}
|
1979 |
-
|
1980 |
-
updateHelperLocations();
|
1981 |
-
|
1982 |
-
if (opts.showPalette) {
|
1983 |
-
drawPalette();
|
1984 |
-
}
|
1985 |
-
|
1986 |
-
boundElement.trigger('reflow.spectrum');
|
1987 |
-
}
|
1988 |
-
|
1989 |
-
function destroy() {
|
1990 |
-
boundElement.show();
|
1991 |
-
offsetElement.unbind("click.spectrum touchstart.spectrum");
|
1992 |
-
container.remove();
|
1993 |
-
replacer.remove();
|
1994 |
-
spectrums[spect.id] = null;
|
1995 |
-
}
|
1996 |
-
|
1997 |
-
function option(optionName, optionValue) {
|
1998 |
-
if (optionName === undefined) {
|
1999 |
-
return $.extend({}, opts);
|
2000 |
-
}
|
2001 |
-
if (optionValue === undefined) {
|
2002 |
-
return opts[optionName];
|
2003 |
-
}
|
2004 |
-
|
2005 |
-
opts[optionName] = optionValue;
|
2006 |
-
applyOptions();
|
2007 |
-
}
|
2008 |
-
|
2009 |
-
function enable() {
|
2010 |
-
disabled = false;
|
2011 |
-
boundElement.attr("disabled", false);
|
2012 |
-
offsetElement.removeClass("sp-disabled");
|
2013 |
-
}
|
2014 |
-
|
2015 |
-
function disable() {
|
2016 |
-
hide();
|
2017 |
-
disabled = true;
|
2018 |
-
boundElement.attr("disabled", true);
|
2019 |
-
offsetElement.addClass("sp-disabled");
|
2020 |
-
}
|
2021 |
-
|
2022 |
-
initialize();
|
2023 |
-
|
2024 |
-
var spect = {
|
2025 |
-
show: show,
|
2026 |
-
hide: hide,
|
2027 |
-
toggle: toggle,
|
2028 |
-
reflow: reflow,
|
2029 |
-
option: option,
|
2030 |
-
enable: enable,
|
2031 |
-
disable: disable,
|
2032 |
-
set: function (c) {
|
2033 |
-
set(c);
|
2034 |
-
updateOriginalInput();
|
2035 |
-
},
|
2036 |
-
get: get,
|
2037 |
-
destroy: destroy,
|
2038 |
-
container: container
|
2039 |
-
};
|
2040 |
-
|
2041 |
-
spect.id = spectrums.push(spect) - 1;
|
2042 |
-
|
2043 |
-
return spect;
|
2044 |
-
}
|
2045 |
-
|
2046 |
-
/**
|
2047 |
-
* checkOffset - get the offset below/above and left/right element depending on screen position
|
2048 |
-
* Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
|
2049 |
-
*/
|
2050 |
-
function getOffset(picker, input) {
|
2051 |
-
var extraY = 0;
|
2052 |
-
var dpWidth = picker.outerWidth();
|
2053 |
-
var dpHeight = picker.outerHeight();
|
2054 |
-
var inputHeight = input.outerHeight();
|
2055 |
-
var doc = picker[0].ownerDocument;
|
2056 |
-
var docElem = doc.documentElement;
|
2057 |
-
var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
|
2058 |
-
var viewHeight = docElem.clientHeight + $(doc).scrollTop();
|
2059 |
-
var offset = input.offset();
|
2060 |
-
offset.top += inputHeight;
|
2061 |
-
|
2062 |
-
offset.left -=
|
2063 |
-
Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
|
2064 |
-
Math.abs(offset.left + dpWidth - viewWidth) : 0);
|
2065 |
-
|
2066 |
-
offset.top -=
|
2067 |
-
Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
|
2068 |
-
Math.abs(dpHeight + inputHeight - extraY) : extraY));
|
2069 |
-
|
2070 |
-
return offset;
|
2071 |
-
}
|
2072 |
-
|
2073 |
-
/**
|
2074 |
-
* noop - do nothing
|
2075 |
-
*/
|
2076 |
-
function noop() {
|
2077 |
-
|
2078 |
-
}
|
2079 |
-
|
2080 |
-
/**
|
2081 |
-
* stopPropagation - makes the code only doing this a little easier to read in line
|
2082 |
-
*/
|
2083 |
-
function stopPropagation(e) {
|
2084 |
-
e.stopPropagation();
|
2085 |
-
}
|
2086 |
-
|
2087 |
-
/**
|
2088 |
-
* Create a function bound to a given object
|
2089 |
-
* Thanks to underscore.js
|
2090 |
-
*/
|
2091 |
-
function bind(func, obj) {
|
2092 |
-
var slice = Array.prototype.slice;
|
2093 |
-
var args = slice.call(arguments, 2);
|
2094 |
-
return function () {
|
2095 |
-
return func.apply(obj, args.concat(slice.call(arguments)));
|
2096 |
-
};
|
2097 |
-
}
|
2098 |
-
|
2099 |
-
/**
|
2100 |
-
* Lightweight drag helper. Handles containment within the element, so that
|
2101 |
-
* when dragging, the x is within [0,element.width] and y is within [0,element.height]
|
2102 |
-
*/
|
2103 |
-
function draggable(element, onmove, onstart, onstop) {
|
2104 |
-
onmove = onmove || function () { };
|
2105 |
-
onstart = onstart || function () { };
|
2106 |
-
onstop = onstop || function () { };
|
2107 |
-
var doc = element.ownerDocument || document;
|
2108 |
-
var dragging = false;
|
2109 |
-
var offset = {};
|
2110 |
-
var maxHeight = 0;
|
2111 |
-
var maxWidth = 0;
|
2112 |
-
var hasTouch = ('ontouchstart' in window);
|
2113 |
-
|
2114 |
-
var duringDragEvents = {};
|
2115 |
-
duringDragEvents["selectstart"] = prevent;
|
2116 |
-
duringDragEvents["dragstart"] = prevent;
|
2117 |
-
duringDragEvents["touchmove mousemove"] = move;
|
2118 |
-
duringDragEvents["touchend mouseup"] = stop;
|
2119 |
-
|
2120 |
-
function prevent(e) {
|
2121 |
-
if (e.stopPropagation) {
|
2122 |
-
e.stopPropagation();
|
2123 |
-
}
|
2124 |
-
if (e.preventDefault) {
|
2125 |
-
e.preventDefault();
|
2126 |
-
}
|
2127 |
-
e.returnValue = false;
|
2128 |
-
}
|
2129 |
-
|
2130 |
-
function move(e) {
|
2131 |
-
if (dragging) {
|
2132 |
-
// Mouseup happened outside of window
|
2133 |
-
if (IE && document.documentMode < 9 && !e.button) {
|
2134 |
-
return stop();
|
2135 |
-
}
|
2136 |
-
|
2137 |
-
var touches = e.originalEvent.touches;
|
2138 |
-
var pageX = touches ? touches[0].pageX : e.pageX;
|
2139 |
-
var pageY = touches ? touches[0].pageY : e.pageY;
|
2140 |
-
|
2141 |
-
var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
|
2142 |
-
var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
|
2143 |
-
|
2144 |
-
if (hasTouch) {
|
2145 |
-
// Stop scrolling in iOS
|
2146 |
-
prevent(e);
|
2147 |
-
}
|
2148 |
-
|
2149 |
-
onmove.apply(element, [dragX, dragY, e]);
|
2150 |
-
}
|
2151 |
-
}
|
2152 |
-
|
2153 |
-
function start(e) {
|
2154 |
-
var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
|
2155 |
-
var touches = e.originalEvent.touches;
|
2156 |
-
|
2157 |
-
if (!rightclick && !dragging) {
|
2158 |
-
if (onstart.apply(element, arguments) !== false) {
|
2159 |
-
dragging = true;
|
2160 |
-
maxHeight = $(element).height();
|
2161 |
-
maxWidth = $(element).width();
|
2162 |
-
offset = $(element).offset();
|
2163 |
-
|
2164 |
-
$(doc).bind(duringDragEvents);
|
2165 |
-
$(doc.body).addClass("sp-dragging");
|
2166 |
-
|
2167 |
-
if (!hasTouch) {
|
2168 |
-
move(e);
|
2169 |
-
}
|
2170 |
-
|
2171 |
-
prevent(e);
|
2172 |
-
}
|
2173 |
-
}
|
2174 |
-
}
|
2175 |
-
|
2176 |
-
function stop() {
|
2177 |
-
if (dragging) {
|
2178 |
-
$(doc).unbind(duringDragEvents);
|
2179 |
-
$(doc.body).removeClass("sp-dragging");
|
2180 |
-
onstop.apply(element, arguments);
|
2181 |
-
}
|
2182 |
-
dragging = false;
|
2183 |
-
}
|
2184 |
-
|
2185 |
-
$(element).bind("touchstart mousedown", start);
|
2186 |
-
}
|
2187 |
-
|
2188 |
-
function throttle(func, wait, debounce) {
|
2189 |
-
var timeout;
|
2190 |
-
return function () {
|
2191 |
-
var context = this, args = arguments;
|
2192 |
-
var throttler = function () {
|
2193 |
-
timeout = null;
|
2194 |
-
func.apply(context, args);
|
2195 |
-
};
|
2196 |
-
if (debounce) clearTimeout(timeout);
|
2197 |
-
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
|
2198 |
-
};
|
2199 |
-
}
|
2200 |
-
|
2201 |
-
function log(){/* jshint -W021 */if(window.console){if(Function.prototype.bind)log=Function.prototype.bind.call(console.log,console);else log=function(){Function.prototype.apply.call(console.log,console,arguments);};log.apply(this,arguments);}}
|
2202 |
-
|
2203 |
-
/**
|
2204 |
-
* Define a jQuery plugin
|
2205 |
-
*/
|
2206 |
-
var dataID = "spectrum.id";
|
2207 |
-
$.fn.spectrum = function (opts, extra) {
|
2208 |
-
|
2209 |
-
if (typeof opts == "string") {
|
2210 |
-
|
2211 |
-
var returnValue = this;
|
2212 |
-
var args = Array.prototype.slice.call( arguments, 1 );
|
2213 |
-
|
2214 |
-
this.each(function () {
|
2215 |
-
var spect = spectrums[$(this).data(dataID)];
|
2216 |
-
if (spect) {
|
2217 |
-
var method = spect[opts];
|
2218 |
-
if (!method) {
|
2219 |
-
throw new Error( "Spectrum: no such method: '" + opts + "'" );
|
2220 |
-
}
|
2221 |
-
|
2222 |
-
if (opts == "get") {
|
2223 |
-
returnValue = spect.get();
|
2224 |
-
}
|
2225 |
-
else if (opts == "container") {
|
2226 |
-
returnValue = spect.container;
|
2227 |
-
}
|
2228 |
-
else if (opts == "option") {
|
2229 |
-
returnValue = spect.option.apply(spect, args);
|
2230 |
-
}
|
2231 |
-
else if (opts == "destroy") {
|
2232 |
-
spect.destroy();
|
2233 |
-
$(this).removeData(dataID);
|
2234 |
-
}
|
2235 |
-
else {
|
2236 |
-
method.apply(spect, args);
|
2237 |
-
}
|
2238 |
-
}
|
2239 |
-
});
|
2240 |
-
|
2241 |
-
return returnValue;
|
2242 |
-
}
|
2243 |
-
|
2244 |
-
// Initializing a new instance of spectrum
|
2245 |
-
return this.spectrum("destroy").each(function () {
|
2246 |
-
var options = $.extend({}, opts, $(this).data());
|
2247 |
-
var spect = spectrum(this, options);
|
2248 |
-
$(this).data(dataID, spect.id);
|
2249 |
-
});
|
2250 |
-
};
|
2251 |
-
|
2252 |
-
$.fn.spectrum.load = true;
|
2253 |
-
$.fn.spectrum.loadOpts = {};
|
2254 |
-
$.fn.spectrum.draggable = draggable;
|
2255 |
-
$.fn.spectrum.defaults = defaultOpts;
|
2256 |
-
|
2257 |
-
$.spectrum = { };
|
2258 |
-
$.spectrum.localization = { };
|
2259 |
-
$.spectrum.palettes = { };
|
2260 |
-
|
2261 |
-
$.fn.spectrum.processNativeColorInputs = function () {
|
2262 |
-
if (!inputTypeColorSupport) {
|
2263 |
-
$("input[type=color]").spectrum({
|
2264 |
-
preferredFormat: "hex6"
|
2265 |
-
});
|
2266 |
-
}
|
2267 |
-
};
|
2268 |
-
|
2269 |
-
// TinyColor v0.9.17
|
2270 |
-
// https://github.com/bgrins/TinyColor
|
2271 |
-
// 2013-08-10, Brian Grinstead, MIT License
|
2272 |
-
|
2273 |
-
(function() {
|
2274 |
-
|
2275 |
-
var trimLeft = /^[\s,#]+/,
|
2276 |
-
trimRight = /\s+$/,
|
2277 |
-
tinyCounter = 0,
|
2278 |
-
math = Math,
|
2279 |
-
mathRound = math.round,
|
2280 |
-
mathMin = math.min,
|
2281 |
-
mathMax = math.max,
|
2282 |
-
mathRandom = math.random;
|
2283 |
-
|
2284 |
-
function tinycolor (color, opts) {
|
2285 |
-
|
2286 |
-
color = (color) ? color : '';
|
2287 |
-
opts = opts || { };
|
2288 |
-
|
2289 |
-
// If input is already a tinycolor, return itself
|
2290 |
-
if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
|
2291 |
-
return color;
|
2292 |
-
}
|
2293 |
-
|
2294 |
-
var rgb = inputToRGB(color);
|
2295 |
-
var r = rgb.r,
|
2296 |
-
g = rgb.g,
|
2297 |
-
b = rgb.b,
|
2298 |
-
a = rgb.a,
|
2299 |
-
roundA = mathRound(100*a) / 100,
|
2300 |
-
format = opts.format || rgb.format;
|
2301 |
-
|
2302 |
-
// Don't let the range of [0,255] come back in [0,1].
|
2303 |
-
// Potentially lose a little bit of precision here, but will fix issues where
|
2304 |
-
// .5 gets interpreted as half of the total, instead of half of 1
|
2305 |
-
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
2306 |
-
if (r < 1) { r = mathRound(r); }
|
2307 |
-
if (g < 1) { g = mathRound(g); }
|
2308 |
-
if (b < 1) { b = mathRound(b); }
|
2309 |
-
|
2310 |
-
return {
|
2311 |
-
ok: rgb.ok,
|
2312 |
-
format: format,
|
2313 |
-
_tc_id: tinyCounter++,
|
2314 |
-
alpha: a,
|
2315 |
-
getAlpha: function() {
|
2316 |
-
return a;
|
2317 |
-
},
|
2318 |
-
setAlpha: function(value) {
|
2319 |
-
a = boundAlpha(value);
|
2320 |
-
roundA = mathRound(100*a) / 100;
|
2321 |
-
},
|
2322 |
-
toHsv: function() {
|
2323 |
-
var hsv = rgbToHsv(r, g, b);
|
2324 |
-
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: a };
|
2325 |
-
},
|
2326 |
-
toHsvString: function() {
|
2327 |
-
var hsv = rgbToHsv(r, g, b);
|
2328 |
-
var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
|
2329 |
-
return (a == 1) ?
|
2330 |
-
"hsv(" + h + ", " + s + "%, " + v + "%)" :
|
2331 |
-
"hsva(" + h + ", " + s + "%, " + v + "%, "+ roundA + ")";
|
2332 |
-
},
|
2333 |
-
toHsl: function() {
|
2334 |
-
var hsl = rgbToHsl(r, g, b);
|
2335 |
-
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: a };
|
2336 |
-
},
|
2337 |
-
toHslString: function() {
|
2338 |
-
var hsl = rgbToHsl(r, g, b);
|
2339 |
-
var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
|
2340 |
-
return (a == 1) ?
|
2341 |
-
"hsl(" + h + ", " + s + "%, " + l + "%)" :
|
2342 |
-
"hsla(" + h + ", " + s + "%, " + l + "%, "+ roundA + ")";
|
2343 |
-
},
|
2344 |
-
toHex: function(allow3Char) {
|
2345 |
-
return rgbToHex(r, g, b, allow3Char);
|
2346 |
-
},
|
2347 |
-
toHexString: function(allow3Char) {
|
2348 |
-
return '#' + this.toHex(allow3Char);
|
2349 |
-
},
|
2350 |
-
toHex8: function() {
|
2351 |
-
return rgbaToHex(r, g, b, a);
|
2352 |
-
},
|
2353 |
-
toHex8String: function() {
|
2354 |
-
return '#' + this.toHex8();
|
2355 |
-
},
|
2356 |
-
toRgb: function() {
|
2357 |
-
return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a };
|
2358 |
-
},
|
2359 |
-
toRgbString: function() {
|
2360 |
-
return (a == 1) ?
|
2361 |
-
"rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" :
|
2362 |
-
"rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")";
|
2363 |
-
},
|
2364 |
-
toPercentageRgb: function() {
|
2365 |
-
return { r: mathRound(bound01(r, 255) * 100) + "%", g: mathRound(bound01(g, 255) * 100) + "%", b: mathRound(bound01(b, 255) * 100) + "%", a: a };
|
2366 |
-
},
|
2367 |
-
toPercentageRgbString: function() {
|
2368 |
-
return (a == 1) ?
|
2369 |
-
"rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" :
|
2370 |
-
"rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")";
|
2371 |
-
},
|
2372 |
-
toName: function() {
|
2373 |
-
if (a === 0) {
|
2374 |
-
return "transparent";
|
2375 |
-
}
|
2376 |
-
|
2377 |
-
return hexNames[rgbToHex(r, g, b, true)] || false;
|
2378 |
-
},
|
2379 |
-
toFilter: function(secondColor) {
|
2380 |
-
var hex8String = '#' + rgbaToHex(r, g, b, a);
|
2381 |
-
var secondHex8String = hex8String;
|
2382 |
-
var gradientType = opts && opts.gradientType ? "GradientType = 1, " : "";
|
2383 |
-
|
2384 |
-
if (secondColor) {
|
2385 |
-
var s = tinycolor(secondColor);
|
2386 |
-
secondHex8String = s.toHex8String();
|
2387 |
-
}
|
2388 |
-
|
2389 |
-
return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
|
2390 |
-
},
|
2391 |
-
toString: function(format) {
|
2392 |
-
var formatSet = !!format;
|
2393 |
-
format = format || this.format;
|
2394 |
-
|
2395 |
-
var formattedString = false;
|
2396 |
-
var hasAlphaAndFormatNotSet = !formatSet && a < 1 && a > 0;
|
2397 |
-
var formatWithAlpha = hasAlphaAndFormatNotSet && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
|
2398 |
-
|
2399 |
-
if (format === "rgb") {
|
2400 |
-
formattedString = this.toRgbString();
|
2401 |
-
}
|
2402 |
-
if (format === "prgb") {
|
2403 |
-
formattedString = this.toPercentageRgbString();
|
2404 |
-
}
|
2405 |
-
if (format === "hex" || format === "hex6") {
|
2406 |
-
formattedString = this.toHexString();
|
2407 |
-
}
|
2408 |
-
if (format === "hex3") {
|
2409 |
-
formattedString = this.toHexString(true);
|
2410 |
-
}
|
2411 |
-
if (format === "hex8") {
|
2412 |
-
formattedString = this.toHex8String();
|
2413 |
-
}
|
2414 |
-
if (format === "name") {
|
2415 |
-
formattedString = this.toName();
|
2416 |
-
}
|
2417 |
-
if (format === "hsl") {
|
2418 |
-
formattedString = this.toHslString();
|
2419 |
-
}
|
2420 |
-
if (format === "hsv") {
|
2421 |
-
formattedString = this.toHsvString();
|
2422 |
-
}
|
2423 |
-
|
2424 |
-
if (formatWithAlpha) {
|
2425 |
-
return this.toRgbString();
|
2426 |
-
}
|
2427 |
-
|
2428 |
-
return formattedString || this.toHexString();
|
2429 |
-
}
|
2430 |
-
};
|
2431 |
-
}
|
2432 |
-
|
2433 |
-
// If input is an object, force 1 into "1.0" to handle ratios properly
|
2434 |
-
// String input requires "1.0" as input, so 1 will be treated as 1
|
2435 |
-
tinycolor.fromRatio = function(color, opts) {
|
2436 |
-
if (typeof color == "object") {
|
2437 |
-
var newColor = {};
|
2438 |
-
for (var i in color) {
|
2439 |
-
if (color.hasOwnProperty(i)) {
|
2440 |
-
if (i === "a") {
|
2441 |
-
newColor[i] = color[i];
|
2442 |
-
}
|
2443 |
-
else {
|
2444 |
-
newColor[i] = convertToPercentage(color[i]);
|
2445 |
-
}
|
2446 |
-
}
|
2447 |
-
}
|
2448 |
-
color = newColor;
|
2449 |
-
}
|
2450 |
-
|
2451 |
-
return tinycolor(color, opts);
|
2452 |
-
};
|
2453 |
-
|
2454 |
-
// Given a string or object, convert that input to RGB
|
2455 |
-
// Possible string inputs:
|
2456 |
-
//
|
2457 |
-
// "red"
|
2458 |
-
// "#f00" or "f00"
|
2459 |
-
// "#ff0000" or "ff0000"
|
2460 |
-
// "#ff000000" or "ff000000"
|
2461 |
-
// "rgb 255 0 0" or "rgb (255, 0, 0)"
|
2462 |
-
// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
|
2463 |
-
// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
|
2464 |
-
// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
|
2465 |
-
// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
|
2466 |
-
// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
|
2467 |
-
// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
|
2468 |
-
//
|
2469 |
-
function inputToRGB(color) {
|
2470 |
-
|
2471 |
-
var rgb = { r: 0, g: 0, b: 0 };
|
2472 |
-
var a = 1;
|
2473 |
-
var ok = false;
|
2474 |
-
var format = false;
|
2475 |
-
|
2476 |
-
if (typeof color == "string") {
|
2477 |
-
color = stringInputToObject(color);
|
2478 |
-
}
|
2479 |
-
|
2480 |
-
if (typeof color == "object") {
|
2481 |
-
if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
|
2482 |
-
rgb = rgbToRgb(color.r, color.g, color.b);
|
2483 |
-
ok = true;
|
2484 |
-
format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
|
2485 |
-
}
|
2486 |
-
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
|
2487 |
-
color.s = convertToPercentage(color.s);
|
2488 |
-
color.v = convertToPercentage(color.v);
|
2489 |
-
rgb = hsvToRgb(color.h, color.s, color.v);
|
2490 |
-
ok = true;
|
2491 |
-
format = "hsv";
|
2492 |
-
}
|
2493 |
-
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
|
2494 |
-
color.s = convertToPercentage(color.s);
|
2495 |
-
color.l = convertToPercentage(color.l);
|
2496 |
-
rgb = hslToRgb(color.h, color.s, color.l);
|
2497 |
-
ok = true;
|
2498 |
-
format = "hsl";
|
2499 |
-
}
|
2500 |
-
|
2501 |
-
if (color.hasOwnProperty("a")) {
|
2502 |
-
a = color.a;
|
2503 |
-
}
|
2504 |
-
}
|
2505 |
-
|
2506 |
-
a = boundAlpha(a);
|
2507 |
-
|
2508 |
-
return {
|
2509 |
-
ok: ok,
|
2510 |
-
format: color.format || format,
|
2511 |
-
r: mathMin(255, mathMax(rgb.r, 0)),
|
2512 |
-
g: mathMin(255, mathMax(rgb.g, 0)),
|
2513 |
-
b: mathMin(255, mathMax(rgb.b, 0)),
|
2514 |
-
a: a
|
2515 |
-
};
|
2516 |
-
}
|
2517 |
-
|
2518 |
-
|
2519 |
-
// Conversion Functions
|
2520 |
-
// --------------------
|
2521 |
-
|
2522 |
-
// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
|
2523 |
-
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
|
2524 |
-
|
2525 |
-
// `rgbToRgb`
|
2526 |
-
// Handle bounds / percentage checking to conform to CSS color spec
|
2527 |
-
// <http://www.w3.org/TR/css3-color/>
|
2528 |
-
// *Assumes:* r, g, b in [0, 255] or [0, 1]
|
2529 |
-
// *Returns:* { r, g, b } in [0, 255]
|
2530 |
-
function rgbToRgb(r, g, b){
|
2531 |
-
return {
|
2532 |
-
r: bound01(r, 255) * 255,
|
2533 |
-
g: bound01(g, 255) * 255,
|
2534 |
-
b: bound01(b, 255) * 255
|
2535 |
-
};
|
2536 |
-
}
|
2537 |
-
|
2538 |
-
// `rgbToHsl`
|
2539 |
-
// Converts an RGB color value to HSL.
|
2540 |
-
// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
|
2541 |
-
// *Returns:* { h, s, l } in [0,1]
|
2542 |
-
function rgbToHsl(r, g, b) {
|
2543 |
-
|
2544 |
-
r = bound01(r, 255);
|
2545 |
-
g = bound01(g, 255);
|
2546 |
-
b = bound01(b, 255);
|
2547 |
-
|
2548 |
-
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
2549 |
-
var h, s, l = (max + min) / 2;
|
2550 |
-
|
2551 |
-
if(max == min) {
|
2552 |
-
h = s = 0; // achromatic
|
2553 |
-
}
|
2554 |
-
else {
|
2555 |
-
var d = max - min;
|
2556 |
-
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
2557 |
-
switch(max) {
|
2558 |
-
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
2559 |
-
case g: h = (b - r) / d + 2; break;
|
2560 |
-
case b: h = (r - g) / d + 4; break;
|
2561 |
-
}
|
2562 |
-
|
2563 |
-
h /= 6;
|
2564 |
-
}
|
2565 |
-
|
2566 |
-
return { h: h, s: s, l: l };
|
2567 |
-
}
|
2568 |
-
|
2569 |
-
// `hslToRgb`
|
2570 |
-
// Converts an HSL color value to RGB.
|
2571 |
-
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
|
2572 |
-
// *Returns:* { r, g, b } in the set [0, 255]
|
2573 |
-
function hslToRgb(h, s, l) {
|
2574 |
-
var r, g, b;
|
2575 |
-
|
2576 |
-
h = bound01(h, 360);
|
2577 |
-
s = bound01(s, 100);
|
2578 |
-
l = bound01(l, 100);
|
2579 |
-
|
2580 |
-
function hue2rgb(p, q, t) {
|
2581 |
-
if(t < 0) t += 1;
|
2582 |
-
if(t > 1) t -= 1;
|
2583 |
-
if(t < 1/6) return p + (q - p) * 6 * t;
|
2584 |
-
if(t < 1/2) return q;
|
2585 |
-
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
2586 |
-
return p;
|
2587 |
-
}
|
2588 |
-
|
2589 |
-
if(s === 0) {
|
2590 |
-
r = g = b = l; // achromatic
|
2591 |
-
}
|
2592 |
-
else {
|
2593 |
-
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
2594 |
-
var p = 2 * l - q;
|
2595 |
-
r = hue2rgb(p, q, h + 1/3);
|
2596 |
-
g = hue2rgb(p, q, h);
|
2597 |
-
b = hue2rgb(p, q, h - 1/3);
|
2598 |
-
}
|
2599 |
-
|
2600 |
-
return { r: r * 255, g: g * 255, b: b * 255 };
|
2601 |
-
}
|
2602 |
-
|
2603 |
-
// `rgbToHsv`
|
2604 |
-
// Converts an RGB color value to HSV
|
2605 |
-
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
|
2606 |
-
// *Returns:* { h, s, v } in [0,1]
|
2607 |
-
function rgbToHsv(r, g, b) {
|
2608 |
-
|
2609 |
-
r = bound01(r, 255);
|
2610 |
-
g = bound01(g, 255);
|
2611 |
-
b = bound01(b, 255);
|
2612 |
-
|
2613 |
-
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
2614 |
-
var h, s, v = max;
|
2615 |
-
|
2616 |
-
var d = max - min;
|
2617 |
-
s = max === 0 ? 0 : d / max;
|
2618 |
-
|
2619 |
-
if(max == min) {
|
2620 |
-
h = 0; // achromatic
|
2621 |
-
}
|
2622 |
-
else {
|
2623 |
-
switch(max) {
|
2624 |
-
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
2625 |
-
case g: h = (b - r) / d + 2; break;
|
2626 |
-
case b: h = (r - g) / d + 4; break;
|
2627 |
-
}
|
2628 |
-
h /= 6;
|
2629 |
-
}
|
2630 |
-
return { h: h, s: s, v: v };
|
2631 |
-
}
|
2632 |
-
|
2633 |
-
// `hsvToRgb`
|
2634 |
-
// Converts an HSV color value to RGB.
|
2635 |
-
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
|
2636 |
-
// *Returns:* { r, g, b } in the set [0, 255]
|
2637 |
-
function hsvToRgb(h, s, v) {
|
2638 |
-
|
2639 |
-
h = bound01(h, 360) * 6;
|
2640 |
-
s = bound01(s, 100);
|
2641 |
-
v = bound01(v, 100);
|
2642 |
-
|
2643 |
-
var i = math.floor(h),
|
2644 |
-
f = h - i,
|
2645 |
-
p = v * (1 - s),
|
2646 |
-
q = v * (1 - f * s),
|
2647 |
-
t = v * (1 - (1 - f) * s),
|
2648 |
-
mod = i % 6,
|
2649 |
-
r = [v, q, p, p, t, v][mod],
|
2650 |
-
g = [t, v, v, q, p, p][mod],
|
2651 |
-
b = [p, p, t, v, v, q][mod];
|
2652 |
-
|
2653 |
-
return { r: r * 255, g: g * 255, b: b * 255 };
|
2654 |
-
}
|
2655 |
-
|
2656 |
-
// `rgbToHex`
|
2657 |
-
// Converts an RGB color to hex
|
2658 |
-
// Assumes r, g, and b are contained in the set [0, 255]
|
2659 |
-
// Returns a 3 or 6 character hex
|
2660 |
-
function rgbToHex(r, g, b, allow3Char) {
|
2661 |
-
|
2662 |
-
var hex = [
|
2663 |
-
pad2(mathRound(r).toString(16)),
|
2664 |
-
pad2(mathRound(g).toString(16)),
|
2665 |
-
pad2(mathRound(b).toString(16))
|
2666 |
-
];
|
2667 |
-
|
2668 |
-
// Return a 3 character hex if possible
|
2669 |
-
if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
|
2670 |
-
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
2671 |
-
}
|
2672 |
-
|
2673 |
-
return hex.join("");
|
2674 |
-
}
|
2675 |
-
// `rgbaToHex`
|
2676 |
-
// Converts an RGBA color plus alpha transparency to hex
|
2677 |
-
// Assumes r, g, b and a are contained in the set [0, 255]
|
2678 |
-
// Returns an 8 character hex
|
2679 |
-
function rgbaToHex(r, g, b, a) {
|
2680 |
-
|
2681 |
-
var hex = [
|
2682 |
-
pad2(convertDecimalToHex(a)),
|
2683 |
-
pad2(mathRound(r).toString(16)),
|
2684 |
-
pad2(mathRound(g).toString(16)),
|
2685 |
-
pad2(mathRound(b).toString(16))
|
2686 |
-
];
|
2687 |
-
|
2688 |
-
return hex.join("");
|
2689 |
-
}
|
2690 |
-
|
2691 |
-
// `equals`
|
2692 |
-
// Can be called with any tinycolor input
|
2693 |
-
tinycolor.equals = function (color1, color2) {
|
2694 |
-
if (!color1 || !color2) { return false; }
|
2695 |
-
return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
|
2696 |
-
};
|
2697 |
-
tinycolor.random = function() {
|
2698 |
-
return tinycolor.fromRatio({
|
2699 |
-
r: mathRandom(),
|
2700 |
-
g: mathRandom(),
|
2701 |
-
b: mathRandom()
|
2702 |
-
});
|
2703 |
-
};
|
2704 |
-
|
2705 |
-
|
2706 |
-
// Modification Functions
|
2707 |
-
// ----------------------
|
2708 |
-
// Thanks to less.js for some of the basics here
|
2709 |
-
// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
|
2710 |
-
|
2711 |
-
tinycolor.desaturate = function (color, amount) {
|
2712 |
-
amount = (amount === 0) ? 0 : (amount || 10);
|
2713 |
-
var hsl = tinycolor(color).toHsl();
|
2714 |
-
hsl.s -= amount / 100;
|
2715 |
-
hsl.s = clamp01(hsl.s);
|
2716 |
-
return tinycolor(hsl);
|
2717 |
-
};
|
2718 |
-
tinycolor.saturate = function (color, amount) {
|
2719 |
-
amount = (amount === 0) ? 0 : (amount || 10);
|
2720 |
-
var hsl = tinycolor(color).toHsl();
|
2721 |
-
hsl.s += amount / 100;
|
2722 |
-
hsl.s = clamp01(hsl.s);
|
2723 |
-
return tinycolor(hsl);
|
2724 |
-
};
|
2725 |
-
tinycolor.greyscale = function(color) {
|
2726 |
-
return tinycolor.desaturate(color, 100);
|
2727 |
-
};
|
2728 |
-
tinycolor.lighten = function(color, amount) {
|
2729 |
-
amount = (amount === 0) ? 0 : (amount || 10);
|
2730 |
-
var hsl = tinycolor(color).toHsl();
|
2731 |
-
hsl.l += amount / 100;
|
2732 |
-
hsl.l = clamp01(hsl.l);
|
2733 |
-
return tinycolor(hsl);
|
2734 |
-
};
|
2735 |
-
tinycolor.darken = function (color, amount) {
|
2736 |
-
amount = (amount === 0) ? 0 : (amount || 10);
|
2737 |
-
var hsl = tinycolor(color).toHsl();
|
2738 |
-
hsl.l -= amount / 100;
|
2739 |
-
hsl.l = clamp01(hsl.l);
|
2740 |
-
return tinycolor(hsl);
|
2741 |
-
};
|
2742 |
-
tinycolor.complement = function(color) {
|
2743 |
-
var hsl = tinycolor(color).toHsl();
|
2744 |
-
hsl.h = (hsl.h + 180) % 360;
|
2745 |
-
return tinycolor(hsl);
|
2746 |
-
};
|
2747 |
-
|
2748 |
-
|
2749 |
-
// Combination Functions
|
2750 |
-
// ---------------------
|
2751 |
-
// Thanks to jQuery xColor for some of the ideas behind these
|
2752 |
-
// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
|
2753 |
-
|
2754 |
-
tinycolor.triad = function(color) {
|
2755 |
-
var hsl = tinycolor(color).toHsl();
|
2756 |
-
var h = hsl.h;
|
2757 |
-
return [
|
2758 |
-
tinycolor(color),
|
2759 |
-
tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
|
2760 |
-
tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
|
2761 |
-
];
|
2762 |
-
};
|
2763 |
-
tinycolor.tetrad = function(color) {
|
2764 |
-
var hsl = tinycolor(color).toHsl();
|
2765 |
-
var h = hsl.h;
|
2766 |
-
return [
|
2767 |
-
tinycolor(color),
|
2768 |
-
tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
|
2769 |
-
tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
|
2770 |
-
tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
|
2771 |
-
];
|
2772 |
-
};
|
2773 |
-
tinycolor.splitcomplement = function(color) {
|
2774 |
-
var hsl = tinycolor(color).toHsl();
|
2775 |
-
var h = hsl.h;
|
2776 |
-
return [
|
2777 |
-
tinycolor(color),
|
2778 |
-
tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
|
2779 |
-
tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
|
2780 |
-
];
|
2781 |
-
};
|
2782 |
-
tinycolor.analogous = function(color, results, slices) {
|
2783 |
-
results = results || 6;
|
2784 |
-
slices = slices || 30;
|
2785 |
-
|
2786 |
-
var hsl = tinycolor(color).toHsl();
|
2787 |
-
var part = 360 / slices;
|
2788 |
-
var ret = [tinycolor(color)];
|
2789 |
-
|
2790 |
-
for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
|
2791 |
-
hsl.h = (hsl.h + part) % 360;
|
2792 |
-
ret.push(tinycolor(hsl));
|
2793 |
-
}
|
2794 |
-
return ret;
|
2795 |
-
};
|
2796 |
-
tinycolor.monochromatic = function(color, results) {
|
2797 |
-
results = results || 6;
|
2798 |
-
var hsv = tinycolor(color).toHsv();
|
2799 |
-
var h = hsv.h, s = hsv.s, v = hsv.v;
|
2800 |
-
var ret = [];
|
2801 |
-
var modification = 1 / results;
|
2802 |
-
|
2803 |
-
while (results--) {
|
2804 |
-
ret.push(tinycolor({ h: h, s: s, v: v}));
|
2805 |
-
v = (v + modification) % 1;
|
2806 |
-
}
|
2807 |
-
|
2808 |
-
return ret;
|
2809 |
-
};
|
2810 |
-
|
2811 |
-
|
2812 |
-
// Readability Functions
|
2813 |
-
// ---------------------
|
2814 |
-
// <http://www.w3.org/TR/AERT#color-contrast>
|
2815 |
-
|
2816 |
-
// `readability`
|
2817 |
-
// Analyze the 2 colors and returns an object with the following properties:
|
2818 |
-
// `brightness`: difference in brightness between the two colors
|
2819 |
-
// `color`: difference in color/hue between the two colors
|
2820 |
-
tinycolor.readability = function(color1, color2) {
|
2821 |
-
var a = tinycolor(color1).toRgb();
|
2822 |
-
var b = tinycolor(color2).toRgb();
|
2823 |
-
var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
|
2824 |
-
var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
|
2825 |
-
var colorDiff = (
|
2826 |
-
Math.max(a.r, b.r) - Math.min(a.r, b.r) +
|
2827 |
-
Math.max(a.g, b.g) - Math.min(a.g, b.g) +
|
2828 |
-
Math.max(a.b, b.b) - Math.min(a.b, b.b)
|
2829 |
-
);
|
2830 |
-
|
2831 |
-
return {
|
2832 |
-
brightness: Math.abs(brightnessA - brightnessB),
|
2833 |
-
color: colorDiff
|
2834 |
-
};
|
2835 |
-
};
|
2836 |
-
|
2837 |
-
// `readable`
|
2838 |
-
// http://www.w3.org/TR/AERT#color-contrast
|
2839 |
-
// Ensure that foreground and background color combinations provide sufficient contrast.
|
2840 |
-
// *Example*
|
2841 |
-
// tinycolor.readable("#000", "#111") => false
|
2842 |
-
tinycolor.readable = function(color1, color2) {
|
2843 |
-
var readability = tinycolor.readability(color1, color2);
|
2844 |
-
return readability.brightness > 125 && readability.color > 500;
|
2845 |
-
};
|
2846 |
-
|
2847 |
-
// `mostReadable`
|
2848 |
-
// Given a base color and a list of possible foreground or background
|
2849 |
-
// colors for that base, returns the most readable color.
|
2850 |
-
// *Example*
|
2851 |
-
// tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
|
2852 |
-
tinycolor.mostReadable = function(baseColor, colorList) {
|
2853 |
-
var bestColor = null;
|
2854 |
-
var bestScore = 0;
|
2855 |
-
var bestIsReadable = false;
|
2856 |
-
for (var i=0; i < colorList.length; i++) {
|
2857 |
-
|
2858 |
-
// We normalize both around the "acceptable" breaking point,
|
2859 |
-
// but rank brightness constrast higher than hue.
|
2860 |
-
|
2861 |
-
var readability = tinycolor.readability(baseColor, colorList[i]);
|
2862 |
-
var readable = readability.brightness > 125 && readability.color > 500;
|
2863 |
-
var score = 3 * (readability.brightness / 125) + (readability.color / 500);
|
2864 |
-
|
2865 |
-
if ((readable && ! bestIsReadable) ||
|
2866 |
-
(readable && bestIsReadable && score > bestScore) ||
|
2867 |
-
((! readable) && (! bestIsReadable) && score > bestScore)) {
|
2868 |
-
bestIsReadable = readable;
|
2869 |
-
bestScore = score;
|
2870 |
-
bestColor = tinycolor(colorList[i]);
|
2871 |
-
}
|
2872 |
-
}
|
2873 |
-
return bestColor;
|
2874 |
-
};
|
2875 |
-
|
2876 |
-
|
2877 |
-
// Big List of Colors
|
2878 |
-
// ------------------
|
2879 |
-
// <http://www.w3.org/TR/css3-color/#svg-color>
|
2880 |
-
var names = tinycolor.names = {
|
2881 |
-
aliceblue: "f0f8ff",
|
2882 |
-
antiquewhite: "faebd7",
|
2883 |
-
aqua: "0ff",
|
2884 |
-
aquamarine: "7fffd4",
|
2885 |
-
azure: "f0ffff",
|
2886 |
-
beige: "f5f5dc",
|
2887 |
-
bisque: "ffe4c4",
|
2888 |
-
black: "000",
|
2889 |
-
blanchedalmond: "ffebcd",
|
2890 |
-
blue: "00f",
|
2891 |
-
blueviolet: "8a2be2",
|
2892 |
-
brown: "a52a2a",
|
2893 |
-
burlywood: "deb887",
|
2894 |
-
burntsienna: "ea7e5d",
|
2895 |
-
cadetblue: "5f9ea0",
|
2896 |
-
chartreuse: "7fff00",
|
2897 |
-
chocolate: "d2691e",
|
2898 |
-
coral: "ff7f50",
|
2899 |
-
cornflowerblue: "6495ed",
|
2900 |
-
cornsilk: "fff8dc",
|
2901 |
-
crimson: "dc143c",
|
2902 |
-
cyan: "0ff",
|
2903 |
-
darkblue: "00008b",
|
2904 |
-
darkcyan: "008b8b",
|
2905 |
-
darkgoldenrod: "b8860b",
|
2906 |
-
darkgray: "a9a9a9",
|
2907 |
-
darkgreen: "006400",
|
2908 |
-
darkgrey: "a9a9a9",
|
2909 |
-
darkkhaki: "bdb76b",
|
2910 |
-
darkmagenta: "8b008b",
|
2911 |
-
darkolivegreen: "556b2f",
|
2912 |
-
darkorange: "ff8c00",
|
2913 |
-
darkorchid: "9932cc",
|
2914 |
-
darkred: "8b0000",
|
2915 |
-
darksalmon: "e9967a",
|
2916 |
-
darkseagreen: "8fbc8f",
|
2917 |
-
darkslateblue: "483d8b",
|
2918 |
-
darkslategray: "2f4f4f",
|
2919 |
-
darkslategrey: "2f4f4f",
|
2920 |
-
darkturquoise: "00ced1",
|
2921 |
-
darkviolet: "9400d3",
|
2922 |
-
deeppink: "ff1493",
|
2923 |
-
deepskyblue: "00bfff",
|
2924 |
-
dimgray: "696969",
|
2925 |
-
dimgrey: "696969",
|
2926 |
-
dodgerblue: "1e90ff",
|
2927 |
-
firebrick: "b22222",
|
2928 |
-
floralwhite: "fffaf0",
|
2929 |
-
forestgreen: "228b22",
|
2930 |
-
fuchsia: "f0f",
|
2931 |
-
gainsboro: "dcdcdc",
|
2932 |
-
ghostwhite: "f8f8ff",
|
2933 |
-
gold: "ffd700",
|
2934 |
-
goldenrod: "daa520",
|
2935 |
-
gray: "808080",
|
2936 |
-
green: "008000",
|
2937 |
-
greenyellow: "adff2f",
|
2938 |
-
grey: "808080",
|
2939 |
-
honeydew: "f0fff0",
|
2940 |
-
hotpink: "ff69b4",
|
2941 |
-
indianred: "cd5c5c",
|
2942 |
-
indigo: "4b0082",
|
2943 |
-
ivory: "fffff0",
|
2944 |
-
khaki: "f0e68c",
|
2945 |
-
lavender: "e6e6fa",
|
2946 |
-
lavenderblush: "fff0f5",
|
2947 |
-
lawngreen: "7cfc00",
|
2948 |
-
lemonchiffon: "fffacd",
|
2949 |
-
lightblue: "add8e6",
|
2950 |
-
lightcoral: "f08080",
|
2951 |
-
lightcyan: "e0ffff",
|
2952 |
-
lightgoldenrodyellow: "fafad2",
|
2953 |
-
lightgray: "d3d3d3",
|
2954 |
-
lightgreen: "90ee90",
|
2955 |
-
lightgrey: "d3d3d3",
|
2956 |
-
lightpink: "ffb6c1",
|
2957 |
-
lightsalmon: "ffa07a",
|
2958 |
-
lightseagreen: "20b2aa",
|
2959 |
-
lightskyblue: "87cefa",
|
2960 |
-
lightslategray: "789",
|
2961 |
-
lightslategrey: "789",
|
2962 |
-
lightsteelblue: "b0c4de",
|
2963 |
-
lightyellow: "ffffe0",
|
2964 |
-
lime: "0f0",
|
2965 |
-
limegreen: "32cd32",
|
2966 |
-
linen: "faf0e6",
|
2967 |
-
magenta: "f0f",
|
2968 |
-
maroon: "800000",
|
2969 |
-
mediumaquamarine: "66cdaa",
|
2970 |
-
mediumblue: "0000cd",
|
2971 |
-
mediumorchid: "ba55d3",
|
2972 |
-
mediumpurple: "9370db",
|
2973 |
-
mediumseagreen: "3cb371",
|
2974 |
-
mediumslateblue: "7b68ee",
|
2975 |
-
mediumspringgreen: "00fa9a",
|
2976 |
-
mediumturquoise: "48d1cc",
|
2977 |
-
mediumvioletred: "c71585",
|
2978 |
-
midnightblue: "191970",
|
2979 |
-
mintcream: "f5fffa",
|
2980 |
-
mistyrose: "ffe4e1",
|
2981 |
-
moccasin: "ffe4b5",
|
2982 |
-
navajowhite: "ffdead",
|
2983 |
-
navy: "000080",
|
2984 |
-
oldlace: "fdf5e6",
|
2985 |
-
olive: "808000",
|
2986 |
-
olivedrab: "6b8e23",
|
2987 |
-
orange: "ffa500",
|
2988 |
-
orangered: "ff4500",
|
2989 |
-
orchid: "da70d6",
|
2990 |
-
palegoldenrod: "eee8aa",
|
2991 |
-
palegreen: "98fb98",
|
2992 |
-
paleturquoise: "afeeee",
|
2993 |
-
palevioletred: "db7093",
|
2994 |
-
papayawhip: "ffefd5",
|
2995 |
-
peachpuff: "ffdab9",
|
2996 |
-
peru: "cd853f",
|
2997 |
-
pink: "ffc0cb",
|
2998 |
-
plum: "dda0dd",
|
2999 |
-
powderblue: "b0e0e6",
|
3000 |
-
purple: "800080",
|
3001 |
-
red: "f00",
|
3002 |
-
rosybrown: "bc8f8f",
|
3003 |
-
royalblue: "4169e1",
|
3004 |
-
saddlebrown: "8b4513",
|
3005 |
-
salmon: "fa8072",
|
3006 |
-
sandybrown: "f4a460",
|
3007 |
-
seagreen: "2e8b57",
|
3008 |
-
seashell: "fff5ee",
|
3009 |
-
sienna: "a0522d",
|
3010 |
-
silver: "c0c0c0",
|
3011 |
-
skyblue: "87ceeb",
|
3012 |
-
slateblue: "6a5acd",
|
3013 |
-
slategray: "708090",
|
3014 |
-
slategrey: "708090",
|
3015 |
-
snow: "fffafa",
|
3016 |
-
springgreen: "00ff7f",
|
3017 |
-
steelblue: "4682b4",
|
3018 |
-
tan: "d2b48c",
|
3019 |
-
teal: "008080",
|
3020 |
-
thistle: "d8bfd8",
|
3021 |
-
tomato: "ff6347",
|
3022 |
-
turquoise: "40e0d0",
|
3023 |
-
violet: "ee82ee",
|
3024 |
-
wheat: "f5deb3",
|
3025 |
-
white: "fff",
|
3026 |
-
whitesmoke: "f5f5f5",
|
3027 |
-
yellow: "ff0",
|
3028 |
-
yellowgreen: "9acd32"
|
3029 |
-
};
|
3030 |
-
|
3031 |
-
// Make it easy to access colors via `hexNames[hex]`
|
3032 |
-
var hexNames = tinycolor.hexNames = flip(names);
|
3033 |
-
|
3034 |
-
|
3035 |
-
// Utilities
|
3036 |
-
// ---------
|
3037 |
-
|
3038 |
-
// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
|
3039 |
-
function flip(o) {
|
3040 |
-
var flipped = { };
|
3041 |
-
for (var i in o) {
|
3042 |
-
if (o.hasOwnProperty(i)) {
|
3043 |
-
flipped[o[i]] = i;
|
3044 |
-
}
|
3045 |
-
}
|
3046 |
-
return flipped;
|
3047 |
-
}
|
3048 |
-
|
3049 |
-
// Return a valid alpha value [0,1] with all invalid values being set to 1
|
3050 |
-
function boundAlpha(a) {
|
3051 |
-
a = parseFloat(a);
|
3052 |
-
|
3053 |
-
if (isNaN(a) || a < 0 || a > 1) {
|
3054 |
-
a = 1;
|
3055 |
-
}
|
3056 |
-
|
3057 |
-
return a;
|
3058 |
-
}
|
3059 |
-
|
3060 |
-
// Take input from [0, n] and return it as [0, 1]
|
3061 |
-
function bound01(n, max) {
|
3062 |
-
if (isOnePointZero(n)) { n = "100%"; }
|
3063 |
-
|
3064 |
-
var processPercent = isPercentage(n);
|
3065 |
-
n = mathMin(max, mathMax(0, parseFloat(n)));
|
3066 |
-
|
3067 |
-
// Automatically convert percentage into number
|
3068 |
-
if (processPercent) {
|
3069 |
-
n = parseInt(n * max, 10) / 100;
|
3070 |
-
}
|
3071 |
-
|
3072 |
-
// Handle floating point rounding errors
|
3073 |
-
if ((math.abs(n - max) < 0.000001)) {
|
3074 |
-
return 1;
|
3075 |
-
}
|
3076 |
-
|
3077 |
-
// Convert into [0, 1] range if it isn't already
|
3078 |
-
return (n % max) / parseFloat(max);
|
3079 |
-
}
|
3080 |
-
|
3081 |
-
// Force a number between 0 and 1
|
3082 |
-
function clamp01(val) {
|
3083 |
-
return mathMin(1, mathMax(0, val));
|
3084 |
-
}
|
3085 |
-
|
3086 |
-
// Parse a base-16 hex value into a base-10 integer
|
3087 |
-
function parseIntFromHex(val) {
|
3088 |
-
return parseInt(val, 16);
|
3089 |
-
}
|
3090 |
-
|
3091 |
-
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
|
3092 |
-
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
|
3093 |
-
function isOnePointZero(n) {
|
3094 |
-
return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
|
3095 |
-
}
|
3096 |
-
|
3097 |
-
// Check to see if string passed in is a percentage
|
3098 |
-
function isPercentage(n) {
|
3099 |
-
return typeof n === "string" && n.indexOf('%') != -1;
|
3100 |
-
}
|
3101 |
-
|
3102 |
-
// Force a hex value to have 2 characters
|
3103 |
-
function pad2(c) {
|
3104 |
-
return c.length == 1 ? '0' + c : '' + c;
|
3105 |
-
}
|
3106 |
-
|
3107 |
-
// Replace a decimal with it's percentage value
|
3108 |
-
function convertToPercentage(n) {
|
3109 |
-
if (n <= 1) {
|
3110 |
-
n = (n * 100) + "%";
|
3111 |
-
}
|
3112 |
-
|
3113 |
-
return n;
|
3114 |
-
}
|
3115 |
-
|
3116 |
-
// Converts a decimal to a hex value
|
3117 |
-
function convertDecimalToHex(d) {
|
3118 |
-
return Math.round(parseFloat(d) * 255).toString(16);
|
3119 |
-
}
|
3120 |
-
// Converts a hex value to a decimal
|
3121 |
-
function convertHexToDecimal(h) {
|
3122 |
-
return (parseIntFromHex(h) / 255);
|
3123 |
-
}
|
3124 |
-
|
3125 |
-
var matchers = (function() {
|
3126 |
-
|
3127 |
-
// <http://www.w3.org/TR/css3-values/#integers>
|
3128 |
-
var CSS_INTEGER = "[-\\+]?\\d+%?";
|
3129 |
-
|
3130 |
-
// <http://www.w3.org/TR/css3-values/#number-value>
|
3131 |
-
var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
|
3132 |
-
|
3133 |
-
// Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
|
3134 |
-
var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
|
3135 |
-
|
3136 |
-
// Actual matching.
|
3137 |
-
// Parentheses and commas are optional, but not required.
|
3138 |
-
// Whitespace can take the place of commas or opening paren
|
3139 |
-
var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
3140 |
-
var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
3141 |
-
|
3142 |
-
return {
|
3143 |
-
rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
|
3144 |
-
rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
|
3145 |
-
hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
|
3146 |
-
hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
|
3147 |
-
hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
|
3148 |
-
hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
3149 |
-
hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
3150 |
-
hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
|
3151 |
-
};
|
3152 |
-
})();
|
3153 |
-
|
3154 |
-
// `stringInputToObject`
|
3155 |
-
// Permissive string parsing. Take in a number of formats, and output an object
|
3156 |
-
// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
|
3157 |
-
function stringInputToObject(color) {
|
3158 |
-
|
3159 |
-
color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
|
3160 |
-
var named = false;
|
3161 |
-
if (names[color]) {
|
3162 |
-
color = names[color];
|
3163 |
-
named = true;
|
3164 |
-
}
|
3165 |
-
else if (color == 'transparent') {
|
3166 |
-
return { r: 0, g: 0, b: 0, a: 0, format: "name" };
|
3167 |
-
}
|
3168 |
-
|
3169 |
-
// Try to match string input using regular expressions.
|
3170 |
-
// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
|
3171 |
-
// Just return an object and let the conversion functions handle that.
|
3172 |
-
// This way the result will be the same whether the tinycolor is initialized with string or object.
|
3173 |
-
var match;
|
3174 |
-
if ((match = matchers.rgb.exec(color))) {
|
3175 |
-
return { r: match[1], g: match[2], b: match[3] };
|
3176 |
-
}
|
3177 |
-
if ((match = matchers.rgba.exec(color))) {
|
3178 |
-
return { r: match[1], g: match[2], b: match[3], a: match[4] };
|
3179 |
-
}
|
3180 |
-
if ((match = matchers.hsl.exec(color))) {
|
3181 |
-
return { h: match[1], s: match[2], l: match[3] };
|
3182 |
-
}
|
3183 |
-
if ((match = matchers.hsla.exec(color))) {
|
3184 |
-
return { h: match[1], s: match[2], l: match[3], a: match[4] };
|
3185 |
-
}
|
3186 |
-
if ((match = matchers.hsv.exec(color))) {
|
3187 |
-
return { h: match[1], s: match[2], v: match[3] };
|
3188 |
-
}
|
3189 |
-
if ((match = matchers.hex8.exec(color))) {
|
3190 |
-
return {
|
3191 |
-
a: convertHexToDecimal(match[1]),
|
3192 |
-
r: parseIntFromHex(match[2]),
|
3193 |
-
g: parseIntFromHex(match[3]),
|
3194 |
-
b: parseIntFromHex(match[4]),
|
3195 |
-
format: named ? "name" : "hex8"
|
3196 |
-
};
|
3197 |
-
}
|
3198 |
-
if ((match = matchers.hex6.exec(color))) {
|
3199 |
-
return {
|
3200 |
-
r: parseIntFromHex(match[1]),
|
3201 |
-
g: parseIntFromHex(match[2]),
|
3202 |
-
b: parseIntFromHex(match[3]),
|
3203 |
-
format: named ? "name" : "hex"
|
3204 |
-
};
|
3205 |
-
}
|
3206 |
-
if ((match = matchers.hex3.exec(color))) {
|
3207 |
-
return {
|
3208 |
-
r: parseIntFromHex(match[1] + '' + match[1]),
|
3209 |
-
g: parseIntFromHex(match[2] + '' + match[2]),
|
3210 |
-
b: parseIntFromHex(match[3] + '' + match[3]),
|
3211 |
-
format: named ? "name" : "hex"
|
3212 |
-
};
|
3213 |
-
}
|
3214 |
-
|
3215 |
-
return false;
|
3216 |
-
}
|
3217 |
-
|
3218 |
-
// Expose tinycolor to window, does not need to run in non-browser context.
|
3219 |
-
window.tinycolor = tinycolor;
|
3220 |
-
|
3221 |
-
})();
|
3222 |
-
|
3223 |
-
|
3224 |
-
$(function () {
|
3225 |
-
if ($.fn.spectrum.load) {
|
3226 |
-
$.fn.spectrum.processNativeColorInputs();
|
3227 |
-
}
|
3228 |
-
});
|
3229 |
-
|
3230 |
-
})(window, jQuery);
|
3231 |
-
//js\libs\codemirror\codemirror.js
|
3232 |
-
|
3233 |
/*!
|
3234 |
* @overview CodeMirror version 3.22
|
3235 |
* http://codemirror.net/
|
3236 |
*/
|
3237 |
-
|
3238 |
-
|
3239 |
-
|
3240 |
-
|
3241 |
-
|
3242 |
-
|
3243 |
-
|
3244 |
-
|
3245 |
-
|
3246 |
-
|
3247 |
-
|
3248 |
-
|
3249 |
-
|
3250 |
-
|
3251 |
-
// incompatibilities in that version.
|
3252 |
-
var old_ie = /MSIE \d/.test(navigator.userAgent);
|
3253 |
-
var ie_lt8 = old_ie && (document.documentMode == null || document.documentMode < 8);
|
3254 |
-
var ie_lt9 = old_ie && (document.documentMode == null || document.documentMode < 9);
|
3255 |
-
var ie_lt10 = old_ie && (document.documentMode == null || document.documentMode < 10);
|
3256 |
-
var ie_gt10 = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent);
|
3257 |
-
var ie = old_ie || ie_gt10;
|
3258 |
-
var webkit = /WebKit\//.test(navigator.userAgent);
|
3259 |
-
var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
|
3260 |
-
var chrome = /Chrome\//.test(navigator.userAgent);
|
3261 |
-
var opera = /Opera\//.test(navigator.userAgent);
|
3262 |
-
var safari = /Apple Computer/.test(navigator.vendor);
|
3263 |
-
var khtml = /KHTML\//.test(navigator.userAgent);
|
3264 |
-
var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
|
3265 |
-
var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
|
3266 |
-
var phantom = /PhantomJS/.test(navigator.userAgent);
|
3267 |
-
|
3268 |
-
var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
|
3269 |
-
// This is woefully incomplete. Suggestions for alternative methods welcome.
|
3270 |
-
var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
|
3271 |
-
var mac = ios || /Mac/.test(navigator.platform);
|
3272 |
-
var windows = /win/i.test(navigator.platform);
|
3273 |
-
|
3274 |
-
var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
|
3275 |
-
if (opera_version) opera_version = Number(opera_version[1]);
|
3276 |
-
if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
|
3277 |
-
// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
|
3278 |
-
var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
|
3279 |
-
var captureMiddleClick = gecko || (ie && !ie_lt9);
|
3280 |
-
|
3281 |
-
// Optimize some code when these features are not used
|
3282 |
-
var sawReadOnlySpans = false, sawCollapsedSpans = false;
|
3283 |
-
|
3284 |
-
// CONSTRUCTOR
|
3285 |
-
|
3286 |
-
function CodeMirror(place, options) {
|
3287 |
-
if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
|
3288 |
-
|
3289 |
-
this.options = options = options || {};
|
3290 |
-
// Determine effective options based on given values and defaults.
|
3291 |
-
for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
|
3292 |
-
options[opt] = defaults[opt];
|
3293 |
-
setGuttersForLineNumbers(options);
|
3294 |
-
|
3295 |
-
var docStart = typeof options.value == "string" ? 0 : options.value.first;
|
3296 |
-
var display = this.display = makeDisplay(place, docStart);
|
3297 |
-
display.wrapper.CodeMirror = this;
|
3298 |
-
updateGutters(this);
|
3299 |
-
if (options.autofocus && !mobile) focusInput(this);
|
3300 |
-
|
3301 |
-
this.state = {keyMaps: [],
|
3302 |
-
overlays: [],
|
3303 |
-
modeGen: 0,
|
3304 |
-
overwrite: false, focused: false,
|
3305 |
-
suppressEdits: false,
|
3306 |
-
pasteIncoming: false, cutIncoming: false,
|
3307 |
-
draggingText: false,
|
3308 |
-
highlight: new Delayed()};
|
3309 |
-
|
3310 |
-
themeChanged(this);
|
3311 |
-
if (options.lineWrapping)
|
3312 |
-
this.display.wrapper.className += " CodeMirror-wrap";
|
3313 |
-
|
3314 |
-
var doc = options.value;
|
3315 |
-
if (typeof doc == "string") doc = new Doc(options.value, options.mode);
|
3316 |
-
operation(this, attachDoc)(this, doc);
|
3317 |
-
|
3318 |
-
// Override magic textarea content restore that IE sometimes does
|
3319 |
-
// on our hidden textarea on reload
|
3320 |
-
if (old_ie) setTimeout(bind(resetInput, this, true), 20);
|
3321 |
-
|
3322 |
-
registerEventHandlers(this);
|
3323 |
-
// IE throws unspecified error in certain cases, when
|
3324 |
-
// trying to access activeElement before onload
|
3325 |
-
var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
|
3326 |
-
if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
|
3327 |
-
else onBlur(this);
|
3328 |
-
|
3329 |
-
operation(this, function() {
|
3330 |
-
for (var opt in optionHandlers)
|
3331 |
-
if (optionHandlers.propertyIsEnumerable(opt))
|
3332 |
-
optionHandlers[opt](this, options[opt], Init);
|
3333 |
-
for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
|
3334 |
-
})();
|
3335 |
-
}
|
3336 |
-
|
3337 |
-
// DISPLAY CONSTRUCTOR
|
3338 |
-
|
3339 |
-
function makeDisplay(place, docStart) {
|
3340 |
-
var d = {};
|
3341 |
-
|
3342 |
-
var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
|
3343 |
-
if (webkit) input.style.width = "1000px";
|
3344 |
-
else input.setAttribute("wrap", "off");
|
3345 |
-
// if border: 0; -- iOS fails to open keyboard (issue #1287)
|
3346 |
-
if (ios) input.style.border = "1px solid black";
|
3347 |
-
input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
|
3348 |
-
|
3349 |
-
// Wraps and hides input textarea
|
3350 |
-
d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
|
3351 |
-
// The actual fake scrollbars.
|
3352 |
-
d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
|
3353 |
-
d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
|
3354 |
-
d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
|
3355 |
-
d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
|
3356 |
-
// DIVs containing the selection and the actual code
|
3357 |
-
d.lineDiv = elt("div", null, "CodeMirror-code");
|
3358 |
-
d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
|
3359 |
-
// Blinky cursor, and element used to ensure cursor fits at the end of a line
|
3360 |
-
d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
|
3361 |
-
// Secondary cursor, shown when on a 'jump' in bi-directional text
|
3362 |
-
d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
|
3363 |
-
// Used to measure text size
|
3364 |
-
d.measure = elt("div", null, "CodeMirror-measure");
|
3365 |
-
// Wraps everything that needs to exist inside the vertically-padded coordinate system
|
3366 |
-
d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
|
3367 |
-
null, "position: relative; outline: none");
|
3368 |
-
// Moved around its parent to cover visible view
|
3369 |
-
d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
|
3370 |
-
// Set to the height of the text, causes scrolling
|
3371 |
-
d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
|
3372 |
-
// D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
|
3373 |
-
d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
|
3374 |
-
// Will contain the gutters, if any
|
3375 |
-
d.gutters = elt("div", null, "CodeMirror-gutters");
|
3376 |
-
d.lineGutter = null;
|
3377 |
-
// Provides scrolling
|
3378 |
-
d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
|
3379 |
-
d.scroller.setAttribute("tabIndex", "-1");
|
3380 |
-
// The element in which the editor lives.
|
3381 |
-
d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
|
3382 |
-
d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
|
3383 |
-
// Work around IE7 z-index bug
|
3384 |
-
if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
|
3385 |
-
if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);
|
3386 |
-
|
3387 |
-
// Needed to hide big blue blinking cursor on Mobile Safari
|
3388 |
-
if (ios) input.style.width = "0px";
|
3389 |
-
if (!webkit) d.scroller.draggable = true;
|
3390 |
-
// Needed to handle Tab key in KHTML
|
3391 |
-
if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
|
3392 |
-
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
|
3393 |
-
else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
|
3394 |
-
|
3395 |
-
// Current visible range (may be bigger than the view window).
|
3396 |
-
d.viewOffset = d.lastSizeC = 0;
|
3397 |
-
d.showingFrom = d.showingTo = docStart;
|
3398 |
-
|
3399 |
-
// Used to only resize the line number gutter when necessary (when
|
3400 |
-
// the amount of lines crosses a boundary that makes its width change)
|
3401 |
-
d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
|
3402 |
-
// See readInput and resetInput
|
3403 |
-
d.prevInput = "";
|
3404 |
-
// Set to true when a non-horizontal-scrolling widget is added. As
|
3405 |
-
// an optimization, widget aligning is skipped when d is false.
|
3406 |
-
d.alignWidgets = false;
|
3407 |
-
// Flag that indicates whether we currently expect input to appear
|
3408 |
-
// (after some event like 'keypress' or 'input') and are polling
|
3409 |
-
// intensively.
|
3410 |
-
d.pollingFast = false;
|
3411 |
-
// Self-resetting timeout for the poller
|
3412 |
-
d.poll = new Delayed();
|
3413 |
-
|
3414 |
-
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
|
3415 |
-
d.measureLineCache = [];
|
3416 |
-
d.measureLineCachePos = 0;
|
3417 |
-
|
3418 |
-
// Tracks when resetInput has punted to just putting a short
|
3419 |
-
// string instead of the (large) selection.
|
3420 |
-
d.inaccurateSelection = false;
|
3421 |
-
|
3422 |
-
// Tracks the maximum line length so that the horizontal scrollbar
|
3423 |
-
// can be kept static when scrolling.
|
3424 |
-
d.maxLine = null;
|
3425 |
-
d.maxLineLength = 0;
|
3426 |
-
d.maxLineChanged = false;
|
3427 |
-
|
3428 |
-
// Used for measuring wheel scrolling granularity
|
3429 |
-
d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
|
3430 |
-
|
3431 |
-
return d;
|
3432 |
-
}
|
3433 |
-
|
3434 |
-
// STATE UPDATES
|
3435 |
-
|
3436 |
-
// Used to get the editor into a consistent state again when options change.
|
3437 |
-
|
3438 |
-
function loadMode(cm) {
|
3439 |
-
cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
|
3440 |
-
resetModeState(cm);
|
3441 |
-
}
|
3442 |
-
|
3443 |
-
function resetModeState(cm) {
|
3444 |
-
cm.doc.iter(function(line) {
|
3445 |
-
if (line.stateAfter) line.stateAfter = null;
|
3446 |
-
if (line.styles) line.styles = null;
|
3447 |
-
});
|
3448 |
-
cm.doc.frontier = cm.doc.first;
|
3449 |
-
startWorker(cm, 100);
|
3450 |
-
cm.state.modeGen++;
|
3451 |
-
if (cm.curOp) regChange(cm);
|
3452 |
-
}
|
3453 |
-
|
3454 |
-
function wrappingChanged(cm) {
|
3455 |
-
if (cm.options.lineWrapping) {
|
3456 |
-
cm.display.wrapper.className += " CodeMirror-wrap";
|
3457 |
-
cm.display.sizer.style.minWidth = "";
|
3458 |
-
} else {
|
3459 |
-
cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
|
3460 |
-
computeMaxLength(cm);
|
3461 |
-
}
|
3462 |
-
estimateLineHeights(cm);
|
3463 |
-
regChange(cm);
|
3464 |
-
clearCaches(cm);
|
3465 |
-
setTimeout(function(){updateScrollbars(cm);}, 100);
|
3466 |
-
}
|
3467 |
-
|
3468 |
-
function estimateHeight(cm) {
|
3469 |
-
var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
|
3470 |
-
var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
|
3471 |
-
return function(line) {
|
3472 |
-
if (lineIsHidden(cm.doc, line))
|
3473 |
-
return 0;
|
3474 |
-
else if (wrapping)
|
3475 |
-
return (Math.ceil(line.text.length / perLine) || 1) * th;
|
3476 |
-
else
|
3477 |
-
return th;
|
3478 |
-
};
|
3479 |
-
}
|
3480 |
-
|
3481 |
-
function estimateLineHeights(cm) {
|
3482 |
-
var doc = cm.doc, est = estimateHeight(cm);
|
3483 |
-
doc.iter(function(line) {
|
3484 |
-
var estHeight = est(line);
|
3485 |
-
if (estHeight != line.height) updateLineHeight(line, estHeight);
|
3486 |
-
});
|
3487 |
-
}
|
3488 |
-
|
3489 |
-
function keyMapChanged(cm) {
|
3490 |
-
var map = keyMap[cm.options.keyMap], style = map.style;
|
3491 |
-
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
|
3492 |
-
(style ? " cm-keymap-" + style : "");
|
3493 |
-
}
|
3494 |
-
|
3495 |
-
function themeChanged(cm) {
|
3496 |
-
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
|
3497 |
-
cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
|
3498 |
-
clearCaches(cm);
|
3499 |
-
}
|
3500 |
-
|
3501 |
-
function guttersChanged(cm) {
|
3502 |
-
updateGutters(cm);
|
3503 |
-
regChange(cm);
|
3504 |
-
setTimeout(function(){alignHorizontally(cm);}, 20);
|
3505 |
-
}
|
3506 |
-
|
3507 |
-
function updateGutters(cm) {
|
3508 |
-
var gutters = cm.display.gutters, specs = cm.options.gutters;
|
3509 |
-
removeChildren(gutters);
|
3510 |
-
for (var i = 0; i < specs.length; ++i) {
|
3511 |
-
var gutterClass = specs[i];
|
3512 |
-
var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
|
3513 |
-
if (gutterClass == "CodeMirror-linenumbers") {
|
3514 |
-
cm.display.lineGutter = gElt;
|
3515 |
-
gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
|
3516 |
-
}
|
3517 |
-
}
|
3518 |
-
gutters.style.display = i ? "" : "none";
|
3519 |
-
}
|
3520 |
-
|
3521 |
-
function lineLength(doc, line) {
|
3522 |
-
if (line.height == 0) return 0;
|
3523 |
-
var len = line.text.length, merged, cur = line;
|
3524 |
-
while (merged = collapsedSpanAtStart(cur)) {
|
3525 |
-
var found = merged.find();
|
3526 |
-
cur = getLine(doc, found.from.line);
|
3527 |
-
len += found.from.ch - found.to.ch;
|
3528 |
-
}
|
3529 |
-
cur = line;
|
3530 |
-
while (merged = collapsedSpanAtEnd(cur)) {
|
3531 |
-
var found = merged.find();
|
3532 |
-
len -= cur.text.length - found.from.ch;
|
3533 |
-
cur = getLine(doc, found.to.line);
|
3534 |
-
len += cur.text.length - found.to.ch;
|
3535 |
-
}
|
3536 |
-
return len;
|
3537 |
-
}
|
3538 |
-
|
3539 |
-
function computeMaxLength(cm) {
|
3540 |
-
var d = cm.display, doc = cm.doc;
|
3541 |
-
d.maxLine = getLine(doc, doc.first);
|
3542 |
-
d.maxLineLength = lineLength(doc, d.maxLine);
|
3543 |
-
d.maxLineChanged = true;
|
3544 |
-
doc.iter(function(line) {
|
3545 |
-
var len = lineLength(doc, line);
|
3546 |
-
if (len > d.maxLineLength) {
|
3547 |
-
d.maxLineLength = len;
|
3548 |
-
d.maxLine = line;
|
3549 |
-
}
|
3550 |
-
});
|
3551 |
-
}
|
3552 |
-
|
3553 |
-
// Make sure the gutters options contains the element
|
3554 |
-
// "CodeMirror-linenumbers" when the lineNumbers option is true.
|
3555 |
-
function setGuttersForLineNumbers(options) {
|
3556 |
-
var found = indexOf(options.gutters, "CodeMirror-linenumbers");
|
3557 |
-
if (found == -1 && options.lineNumbers) {
|
3558 |
-
options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
|
3559 |
-
} else if (found > -1 && !options.lineNumbers) {
|
3560 |
-
options.gutters = options.gutters.slice(0);
|
3561 |
-
options.gutters.splice(found, 1);
|
3562 |
-
}
|
3563 |
-
}
|
3564 |
-
|
3565 |
-
// SCROLLBARS
|
3566 |
-
|
3567 |
-
// Re-synchronize the fake scrollbars with the actual size of the
|
3568 |
-
// content. Optionally force a scrollTop.
|
3569 |
-
function updateScrollbars(cm) {
|
3570 |
-
var d = cm.display, docHeight = cm.doc.height;
|
3571 |
-
var totalHeight = docHeight + paddingVert(d);
|
3572 |
-
d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
|
3573 |
-
d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
|
3574 |
-
var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
|
3575 |
-
var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
|
3576 |
-
var needsV = scrollHeight > (d.scroller.clientHeight + 1);
|
3577 |
-
if (needsV) {
|
3578 |
-
d.scrollbarV.style.display = "block";
|
3579 |
-
d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
|
3580 |
-
// A bug in IE8 can cause this value to be negative, so guard it.
|
3581 |
-
d.scrollbarV.firstChild.style.height =
|
3582 |
-
Math.max(0, scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
|
3583 |
-
} else {
|
3584 |
-
d.scrollbarV.style.display = "";
|
3585 |
-
d.scrollbarV.firstChild.style.height = "0";
|
3586 |
-
}
|
3587 |
-
if (needsH) {
|
3588 |
-
d.scrollbarH.style.display = "block";
|
3589 |
-
d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
|
3590 |
-
d.scrollbarH.firstChild.style.width =
|
3591 |
-
(d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
|
3592 |
-
} else {
|
3593 |
-
d.scrollbarH.style.display = "";
|
3594 |
-
d.scrollbarH.firstChild.style.width = "0";
|
3595 |
-
}
|
3596 |
-
if (needsH && needsV) {
|
3597 |
-
d.scrollbarFiller.style.display = "block";
|
3598 |
-
d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
|
3599 |
-
} else d.scrollbarFiller.style.display = "";
|
3600 |
-
if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
|
3601 |
-
d.gutterFiller.style.display = "block";
|
3602 |
-
d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
|
3603 |
-
d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
|
3604 |
-
} else d.gutterFiller.style.display = "";
|
3605 |
-
|
3606 |
-
if (mac_geLion && scrollbarWidth(d.measure) === 0) {
|
3607 |
-
d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
|
3608 |
-
d.scrollbarV.style.pointerEvents = d.scrollbarH.style.pointerEvents = "none";
|
3609 |
-
}
|
3610 |
-
}
|
3611 |
-
|
3612 |
-
function visibleLines(display, doc, viewPort) {
|
3613 |
-
var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
|
3614 |
-
if (typeof viewPort == "number") top = viewPort;
|
3615 |
-
else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
|
3616 |
-
top = Math.floor(top - paddingTop(display));
|
3617 |
-
var bottom = Math.ceil(top + height);
|
3618 |
-
return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
|
3619 |
-
}
|
3620 |
-
|
3621 |
-
// LINE NUMBERS
|
3622 |
-
|
3623 |
-
function alignHorizontally(cm) {
|
3624 |
-
var display = cm.display;
|
3625 |
-
if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
|
3626 |
-
var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
|
3627 |
-
var gutterW = display.gutters.offsetWidth, l = comp + "px";
|
3628 |
-
for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
|
3629 |
-
for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
|
3630 |
-
}
|
3631 |
-
if (cm.options.fixedGutter)
|
3632 |
-
display.gutters.style.left = (comp + gutterW) + "px";
|
3633 |
-
}
|
3634 |
-
|
3635 |
-
function maybeUpdateLineNumberWidth(cm) {
|
3636 |
-
if (!cm.options.lineNumbers) return false;
|
3637 |
-
var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
|
3638 |
-
if (last.length != display.lineNumChars) {
|
3639 |
-
var test = display.measure.appendChild(elt("div", [elt("div", last)],
|
3640 |
-
"CodeMirror-linenumber CodeMirror-gutter-elt"));
|
3641 |
-
var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
|
3642 |
-
display.lineGutter.style.width = "";
|
3643 |
-
display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
|
3644 |
-
display.lineNumWidth = display.lineNumInnerWidth + padding;
|
3645 |
-
display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
|
3646 |
-
display.lineGutter.style.width = display.lineNumWidth + "px";
|
3647 |
-
return true;
|
3648 |
-
}
|
3649 |
-
return false;
|
3650 |
-
}
|
3651 |
-
|
3652 |
-
function lineNumberFor(options, i) {
|
3653 |
-
return String(options.lineNumberFormatter(i + options.firstLineNumber));
|
3654 |
-
}
|
3655 |
-
function compensateForHScroll(display) {
|
3656 |
-
return getRect(display.scroller).left - getRect(display.sizer).left;
|
3657 |
-
}
|
3658 |
-
|
3659 |
-
// DISPLAY DRAWING
|
3660 |
-
|
3661 |
-
function updateDisplay(cm, changes, viewPort, forced) {
|
3662 |
-
var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
|
3663 |
-
var visible = visibleLines(cm.display, cm.doc, viewPort);
|
3664 |
-
for (var first = true;; first = false) {
|
3665 |
-
var oldWidth = cm.display.scroller.clientWidth;
|
3666 |
-
if (!updateDisplayInner(cm, changes, visible, forced)) break;
|
3667 |
-
updated = true;
|
3668 |
-
changes = [];
|
3669 |
-
updateSelection(cm);
|
3670 |
-
updateScrollbars(cm);
|
3671 |
-
if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {
|
3672 |
-
forced = true;
|
3673 |
-
continue;
|
3674 |
-
}
|
3675 |
-
forced = false;
|
3676 |
-
|
3677 |
-
// Clip forced viewport to actual scrollable area
|
3678 |
-
if (viewPort)
|
3679 |
-
viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
|
3680 |
-
typeof viewPort == "number" ? viewPort : viewPort.top);
|
3681 |
-
visible = visibleLines(cm.display, cm.doc, viewPort);
|
3682 |
-
if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
|
3683 |
-
break;
|
3684 |
-
}
|
3685 |
-
|
3686 |
-
if (updated) {
|
3687 |
-
signalLater(cm, "update", cm);
|
3688 |
-
if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
|
3689 |
-
signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
|
3690 |
-
}
|
3691 |
-
return updated;
|
3692 |
-
}
|
3693 |
-
|
3694 |
-
// Uses a set of changes plus the current scroll position to
|
3695 |
-
// determine which DOM updates have to be made, and makes the
|
3696 |
-
// updates.
|
3697 |
-
function updateDisplayInner(cm, changes, visible, forced) {
|
3698 |
-
var display = cm.display, doc = cm.doc;
|
3699 |
-
if (!display.wrapper.offsetWidth) {
|
3700 |
-
display.showingFrom = display.showingTo = doc.first;
|
3701 |
-
display.viewOffset = 0;
|
3702 |
-
return;
|
3703 |
-
}
|
3704 |
-
|
3705 |
-
// Bail out if the visible area is already rendered and nothing changed.
|
3706 |
-
if (!forced && changes.length == 0 &&
|
3707 |
-
visible.from > display.showingFrom && visible.to < display.showingTo)
|
3708 |
-
return;
|
3709 |
-
|
3710 |
-
if (maybeUpdateLineNumberWidth(cm))
|
3711 |
-
changes = [{from: doc.first, to: doc.first + doc.size}];
|
3712 |
-
var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
|
3713 |
-
display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
|
3714 |
-
|
3715 |
-
// Used to determine which lines need their line numbers updated
|
3716 |
-
var positionsChangedFrom = Infinity;
|
3717 |
-
if (cm.options.lineNumbers)
|
3718 |
-
for (var i = 0; i < changes.length; ++i)
|
3719 |
-
if (changes[i].diff && changes[i].from < positionsChangedFrom) { positionsChangedFrom = changes[i].from; }
|
3720 |
-
|
3721 |
-
var end = doc.first + doc.size;
|
3722 |
-
var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
|
3723 |
-
var to = Math.min(end, visible.to + cm.options.viewportMargin);
|
3724 |
-
if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom);
|
3725 |
-
if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo);
|
3726 |
-
if (sawCollapsedSpans) {
|
3727 |
-
from = lineNo(visualLine(doc, getLine(doc, from)));
|
3728 |
-
while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to;
|
3729 |
-
}
|
3730 |
-
|
3731 |
-
// Create a range of theoretically intact lines, and punch holes
|
3732 |
-
// in that using the change info.
|
3733 |
-
var intact = [{from: Math.max(display.showingFrom, doc.first),
|
3734 |
-
to: Math.min(display.showingTo, end)}];
|
3735 |
-
if (intact[0].from >= intact[0].to) intact = [];
|
3736 |
-
else intact = computeIntact(intact, changes);
|
3737 |
-
// When merged lines are present, we might have to reduce the
|
3738 |
-
// intact ranges because changes in continued fragments of the
|
3739 |
-
// intact lines do require the lines to be redrawn.
|
3740 |
-
if (sawCollapsedSpans)
|
3741 |
-
for (var i = 0; i < intact.length; ++i) {
|
3742 |
-
var range = intact[i], merged;
|
3743 |
-
while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) {
|
3744 |
-
var newTo = merged.find().from.line;
|
3745 |
-
if (newTo > range.from) range.to = newTo;
|
3746 |
-
else { intact.splice(i--, 1); break; }
|
3747 |
-
}
|
3748 |
-
}
|
3749 |
-
|
3750 |
-
// Clip off the parts that won't be visible
|
3751 |
-
var intactLines = 0;
|
3752 |
-
for (var i = 0; i < intact.length; ++i) {
|
3753 |
-
var range = intact[i];
|
3754 |
-
if (range.from < from) range.from = from;
|
3755 |
-
if (range.to > to) range.to = to;
|
3756 |
-
if (range.from >= range.to) intact.splice(i--, 1);
|
3757 |
-
else intactLines += range.to - range.from;
|
3758 |
-
}
|
3759 |
-
if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
|
3760 |
-
updateViewOffset(cm);
|
3761 |
-
return;
|
3762 |
-
}
|
3763 |
-
intact.sort(function(a, b) {return a.from - b.from;});
|
3764 |
-
|
3765 |
-
// Avoid crashing on IE's "unspecified error" when in iframes
|
3766 |
-
try {
|
3767 |
-
var focused = document.activeElement;
|
3768 |
-
} catch(e) {}
|
3769 |
-
if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
|
3770 |
-
patchDisplay(cm, from, to, intact, positionsChangedFrom);
|
3771 |
-
display.lineDiv.style.display = "";
|
3772 |
-
if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus();
|
3773 |
-
|
3774 |
-
var different = from != display.showingFrom || to != display.showingTo ||
|
3775 |
-
display.lastSizeC != display.wrapper.clientHeight;
|
3776 |
-
// This is just a bogus formula that detects when the editor is
|
3777 |
-
// resized or the font size changes.
|
3778 |
-
if (different) {
|
3779 |
-
display.lastSizeC = display.wrapper.clientHeight;
|
3780 |
-
startWorker(cm, 400);
|
3781 |
-
}
|
3782 |
-
display.showingFrom = from; display.showingTo = to;
|
3783 |
-
|
3784 |
-
display.gutters.style.height = "";
|
3785 |
-
updateHeightsInViewport(cm);
|
3786 |
-
updateViewOffset(cm);
|
3787 |
-
|
3788 |
-
return true;
|
3789 |
-
}
|
3790 |
-
|
3791 |
-
function updateHeightsInViewport(cm) {
|
3792 |
-
var display = cm.display;
|
3793 |
-
var prevBottom = display.lineDiv.offsetTop;
|
3794 |
-
for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
|
3795 |
-
if (ie_lt8) {
|
3796 |
-
var bot = node.offsetTop + node.offsetHeight;
|
3797 |
-
height = bot - prevBottom;
|
3798 |
-
prevBottom = bot;
|
3799 |
-
} else {
|
3800 |
-
var box = getRect(node);
|
3801 |
-
height = box.bottom - box.top;
|
3802 |
-
}
|
3803 |
-
var diff = node.lineObj.height - height;
|
3804 |
-
if (height < 2) height = textHeight(display);
|
3805 |
-
if (diff > .001 || diff < -.001) {
|
3806 |
-
updateLineHeight(node.lineObj, height);
|
3807 |
-
var widgets = node.lineObj.widgets;
|
3808 |
-
if (widgets) for (var i = 0; i < widgets.length; ++i)
|
3809 |
-
widgets[i].height = widgets[i].node.offsetHeight;
|
3810 |
-
}
|
3811 |
-
}
|
3812 |
-
}
|
3813 |
-
|
3814 |
-
function updateViewOffset(cm) {
|
3815 |
-
var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom));
|
3816 |
-
// Position the mover div to align with the current virtual scroll position
|
3817 |
-
cm.display.mover.style.top = off + "px";
|
3818 |
-
}
|
3819 |
-
|
3820 |
-
function computeIntact(intact, changes) {
|
3821 |
-
for (var i = 0, l = changes.length || 0; i < l; ++i) {
|
3822 |
-
var change = changes[i], intact2 = [], diff = change.diff || 0;
|
3823 |
-
for (var j = 0, l2 = intact.length; j < l2; ++j) {
|
3824 |
-
var range = intact[j];
|
3825 |
-
if (change.to <= range.from && change.diff) {
|
3826 |
-
intact2.push({from: range.from + diff, to: range.to + diff});
|
3827 |
-
} else if (change.to <= range.from || change.from >= range.to) {
|
3828 |
-
intact2.push(range);
|
3829 |
-
} else {
|
3830 |
-
if (change.from > range.from)
|
3831 |
-
intact2.push({from: range.from, to: change.from});
|
3832 |
-
if (change.to < range.to)
|
3833 |
-
intact2.push({from: change.to + diff, to: range.to + diff});
|
3834 |
-
}
|
3835 |
-
}
|
3836 |
-
intact = intact2;
|
3837 |
-
}
|
3838 |
-
return intact;
|
3839 |
-
}
|
3840 |
-
|
3841 |
-
function getDimensions(cm) {
|
3842 |
-
var d = cm.display, left = {}, width = {};
|
3843 |
-
for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
|
3844 |
-
left[cm.options.gutters[i]] = n.offsetLeft;
|
3845 |
-
width[cm.options.gutters[i]] = n.offsetWidth;
|
3846 |
-
}
|
3847 |
-
return {fixedPos: compensateForHScroll(d),
|
3848 |
-
gutterTotalWidth: d.gutters.offsetWidth,
|
3849 |
-
gutterLeft: left,
|
3850 |
-
gutterWidth: width,
|
3851 |
-
wrapperWidth: d.wrapper.clientWidth};
|
3852 |
-
}
|
3853 |
-
|
3854 |
-
function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
|
3855 |
-
var dims = getDimensions(cm);
|
3856 |
-
var display = cm.display, lineNumbers = cm.options.lineNumbers;
|
3857 |
-
if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
|
3858 |
-
removeChildren(display.lineDiv);
|
3859 |
-
var container = display.lineDiv, cur = container.firstChild;
|
3860 |
-
|
3861 |
-
function rm(node) {
|
3862 |
-
var next = node.nextSibling;
|
3863 |
-
if (webkit && mac && cm.display.currentWheelTarget == node) {
|
3864 |
-
node.style.display = "none";
|
3865 |
-
node.lineObj = null;
|
3866 |
-
} else {
|
3867 |
-
node.parentNode.removeChild(node);
|
3868 |
-
}
|
3869 |
-
return next;
|
3870 |
-
}
|
3871 |
-
|
3872 |
-
var nextIntact = intact.shift(), lineN = from;
|
3873 |
-
cm.doc.iter(from, to, function(line) {
|
3874 |
-
if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
|
3875 |
-
if (lineIsHidden(cm.doc, line)) {
|
3876 |
-
if (line.height != 0) updateLineHeight(line, 0);
|
3877 |
-
if (line.widgets && cur && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
|
3878 |
-
var w = line.widgets[i];
|
3879 |
-
if (w.showIfHidden) {
|
3880 |
-
var prev = cur.previousSibling;
|
3881 |
-
if (/pre/i.test(prev.nodeName)) {
|
3882 |
-
var wrap = elt("div", null, null, "position: relative");
|
3883 |
-
prev.parentNode.replaceChild(wrap, prev);
|
3884 |
-
wrap.appendChild(prev);
|
3885 |
-
prev = wrap;
|
3886 |
-
}
|
3887 |
-
var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget"));
|
3888 |
-
if (!w.handleMouseEvents) wnode.ignoreEvents = true;
|
3889 |
-
positionLineWidget(w, wnode, prev, dims);
|
3890 |
-
}
|
3891 |
-
}
|
3892 |
-
} else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) {
|
3893 |
-
// This line is intact. Skip to the actual node. Update its
|
3894 |
-
// line number if needed.
|
3895 |
-
while (cur.lineObj != line) cur = rm(cur);
|
3896 |
-
if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber)
|
3897 |
-
setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN));
|
3898 |
-
cur = cur.nextSibling;
|
3899 |
-
} else {
|
3900 |
-
// For lines with widgets, make an attempt to find and reuse
|
3901 |
-
// the existing element, so that widgets aren't needlessly
|
3902 |
-
// removed and re-inserted into the dom
|
3903 |
-
if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling)
|
3904 |
-
if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; }
|
3905 |
-
// This line needs to be generated.
|
3906 |
-
var lineNode = buildLineElement(cm, line, lineN, dims, reuse);
|
3907 |
-
if (lineNode != reuse) {
|
3908 |
-
container.insertBefore(lineNode, cur);
|
3909 |
-
} else {
|
3910 |
-
while (cur != reuse) cur = rm(cur);
|
3911 |
-
cur = cur.nextSibling;
|
3912 |
-
}
|
3913 |
-
|
3914 |
-
lineNode.lineObj = line;
|
3915 |
-
}
|
3916 |
-
++lineN;
|
3917 |
-
});
|
3918 |
-
while (cur) cur = rm(cur);
|
3919 |
-
}
|
3920 |
-
|
3921 |
-
function buildLineElement(cm, line, lineNo, dims, reuse) {
|
3922 |
-
var built = buildLineContent(cm, line), lineElement = built.pre;
|
3923 |
-
var markers = line.gutterMarkers, display = cm.display, wrap;
|
3924 |
-
|
3925 |
-
var bgClass = built.bgClass ? built.bgClass + " " + (line.bgClass || "") : line.bgClass;
|
3926 |
-
if (!cm.options.lineNumbers && !markers && !bgClass && !line.wrapClass && !line.widgets)
|
3927 |
-
return lineElement;
|
3928 |
-
|
3929 |
-
// Lines with gutter elements, widgets or a background class need
|
3930 |
-
// to be wrapped again, and have the extra elements added to the
|
3931 |
-
// wrapper div
|
3932 |
-
|
3933 |
-
if (reuse) {
|
3934 |
-
reuse.alignable = null;
|
3935 |
-
var isOk = true, widgetsSeen = 0, insertBefore = null;
|
3936 |
-
for (var n = reuse.firstChild, next; n; n = next) {
|
3937 |
-
next = n.nextSibling;
|
3938 |
-
if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
|
3939 |
-
reuse.removeChild(n);
|
3940 |
-
} else {
|
3941 |
-
for (var i = 0; i < line.widgets.length; ++i) {
|
3942 |
-
var widget = line.widgets[i];
|
3943 |
-
if (widget.node == n.firstChild) {
|
3944 |
-
if (!widget.above && !insertBefore) insertBefore = n;
|
3945 |
-
positionLineWidget(widget, n, reuse, dims);
|
3946 |
-
++widgetsSeen;
|
3947 |
-
break;
|
3948 |
-
}
|
3949 |
-
}
|
3950 |
-
if (i == line.widgets.length) { isOk = false; break; }
|
3951 |
-
}
|
3952 |
-
}
|
3953 |
-
reuse.insertBefore(lineElement, insertBefore);
|
3954 |
-
if (isOk && widgetsSeen == line.widgets.length) {
|
3955 |
-
wrap = reuse;
|
3956 |
-
reuse.className = line.wrapClass || "";
|
3957 |
-
}
|
3958 |
-
}
|
3959 |
-
if (!wrap) {
|
3960 |
-
wrap = elt("div", null, line.wrapClass, "position: relative");
|
3961 |
-
wrap.appendChild(lineElement);
|
3962 |
-
}
|
3963 |
-
// Kludge to make sure the styled element lies behind the selection (by z-index)
|
3964 |
-
if (bgClass)
|
3965 |
-
wrap.insertBefore(elt("div", null, bgClass + " CodeMirror-linebackground"), wrap.firstChild);
|
3966 |
-
if (cm.options.lineNumbers || markers) {
|
3967 |
-
var gutterWrap = wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " +
|
3968 |
-
(cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
|
3969 |
-
lineElement);
|
3970 |
-
if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
|
3971 |
-
if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
|
3972 |
-
wrap.lineNumber = gutterWrap.appendChild(
|
3973 |
-
elt("div", lineNumberFor(cm.options, lineNo),
|
3974 |
-
"CodeMirror-linenumber CodeMirror-gutter-elt",
|
3975 |
-
"left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
|
3976 |
-
+ display.lineNumInnerWidth + "px"));
|
3977 |
-
if (markers)
|
3978 |
-
for (var k = 0; k < cm.options.gutters.length; ++k) {
|
3979 |
-
var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
|
3980 |
-
if (found)
|
3981 |
-
gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
|
3982 |
-
dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
|
3983 |
-
}
|
3984 |
-
}
|
3985 |
-
if (ie_lt8) wrap.style.zIndex = 2;
|
3986 |
-
if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
|
3987 |
-
var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
|
3988 |
-
if (!widget.handleMouseEvents) node.ignoreEvents = true;
|
3989 |
-
positionLineWidget(widget, node, wrap, dims);
|
3990 |
-
if (widget.above)
|
3991 |
-
wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
|
3992 |
-
else
|
3993 |
-
wrap.appendChild(node);
|
3994 |
-
signalLater(widget, "redraw");
|
3995 |
-
}
|
3996 |
-
return wrap;
|
3997 |
-
}
|
3998 |
-
|
3999 |
-
function positionLineWidget(widget, node, wrap, dims) {
|
4000 |
-
if (widget.noHScroll) {
|
4001 |
-
(wrap.alignable || (wrap.alignable = [])).push(node);
|
4002 |
-
var width = dims.wrapperWidth;
|
4003 |
-
node.style.left = dims.fixedPos + "px";
|
4004 |
-
if (!widget.coverGutter) {
|
4005 |
-
width -= dims.gutterTotalWidth;
|
4006 |
-
node.style.paddingLeft = dims.gutterTotalWidth + "px";
|
4007 |
-
}
|
4008 |
-
node.style.width = width + "px";
|
4009 |
-
}
|
4010 |
-
if (widget.coverGutter) {
|
4011 |
-
node.style.zIndex = 5;
|
4012 |
-
node.style.position = "relative";
|
4013 |
-
if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
|
4014 |
-
}
|
4015 |
-
}
|
4016 |
-
|
4017 |
-
// SELECTION / CURSOR
|
4018 |
-
|
4019 |
-
function updateSelection(cm) {
|
4020 |
-
var display = cm.display;
|
4021 |
-
var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to);
|
4022 |
-
if (collapsed || cm.options.showCursorWhenSelecting)
|
4023 |
-
updateSelectionCursor(cm);
|
4024 |
-
else
|
4025 |
-
display.cursor.style.display = display.otherCursor.style.display = "none";
|
4026 |
-
if (!collapsed)
|
4027 |
-
updateSelectionRange(cm);
|
4028 |
-
else
|
4029 |
-
display.selectionDiv.style.display = "none";
|
4030 |
-
|
4031 |
-
// Move the hidden textarea near the cursor to prevent scrolling artifacts
|
4032 |
-
if (cm.options.moveInputWithCursor) {
|
4033 |
-
var headPos = cursorCoords(cm, cm.doc.sel.head, "div");
|
4034 |
-
var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv);
|
4035 |
-
display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
|
4036 |
-
headPos.top + lineOff.top - wrapOff.top)) + "px";
|
4037 |
-
display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
|
4038 |
-
headPos.left + lineOff.left - wrapOff.left)) + "px";
|
4039 |
-
}
|
4040 |
-
}
|
4041 |
-
|
4042 |
-
// No selection, plain cursor
|
4043 |
-
function updateSelectionCursor(cm) {
|
4044 |
-
var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div");
|
4045 |
-
display.cursor.style.left = pos.left + "px";
|
4046 |
-
display.cursor.style.top = pos.top + "px";
|
4047 |
-
display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
|
4048 |
-
display.cursor.style.display = "";
|
4049 |
-
|
4050 |
-
if (pos.other) {
|
4051 |
-
display.otherCursor.style.display = "";
|
4052 |
-
display.otherCursor.style.left = pos.other.left + "px";
|
4053 |
-
display.otherCursor.style.top = pos.other.top + "px";
|
4054 |
-
display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
|
4055 |
-
} else { display.otherCursor.style.display = "none"; }
|
4056 |
-
}
|
4057 |
-
|
4058 |
-
// Highlight selection
|
4059 |
-
function updateSelectionRange(cm) {
|
4060 |
-
var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
|
4061 |
-
var fragment = document.createDocumentFragment();
|
4062 |
-
var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right;
|
4063 |
-
|
4064 |
-
function add(left, top, width, bottom) {
|
4065 |
-
if (top < 0) top = 0;
|
4066 |
-
fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
|
4067 |
-
"px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
|
4068 |
-
"px; height: " + (bottom - top) + "px"));
|
4069 |
-
}
|
4070 |
-
|
4071 |
-
function drawForLine(line, fromArg, toArg) {
|
4072 |
-
var lineObj = getLine(doc, line);
|
4073 |
-
var lineLen = lineObj.text.length;
|
4074 |
-
var start, end;
|
4075 |
-
function coords(ch, bias) {
|
4076 |
-
return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
|
4077 |
-
}
|
4078 |
-
|
4079 |
-
iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
|
4080 |
-
var leftPos = coords(from, "left"), rightPos, left, right;
|
4081 |
-
if (from == to) {
|
4082 |
-
rightPos = leftPos;
|
4083 |
-
left = right = leftPos.left;
|
4084 |
-
} else {
|
4085 |
-
rightPos = coords(to - 1, "right");
|
4086 |
-
if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
|
4087 |
-
left = leftPos.left;
|
4088 |
-
right = rightPos.right;
|
4089 |
-
}
|
4090 |
-
if (fromArg == null && from == 0) left = leftSide;
|
4091 |
-
if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
|
4092 |
-
add(left, leftPos.top, null, leftPos.bottom);
|
4093 |
-
left = leftSide;
|
4094 |
-
if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
|
4095 |
-
}
|
4096 |
-
if (toArg == null && to == lineLen) right = rightSide;
|
4097 |
-
if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
|
4098 |
-
start = leftPos;
|
4099 |
-
if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
|
4100 |
-
end = rightPos;
|
4101 |
-
if (left < leftSide + 1) left = leftSide;
|
4102 |
-
add(left, rightPos.top, right - left, rightPos.bottom);
|
4103 |
-
});
|
4104 |
-
return {start: start, end: end};
|
4105 |
-
}
|
4106 |
-
|
4107 |
-
if (sel.from.line == sel.to.line) {
|
4108 |
-
drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
|
4109 |
-
} else {
|
4110 |
-
var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line);
|
4111 |
-
var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine);
|
4112 |
-
var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
|
4113 |
-
var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
|
4114 |
-
if (singleVLine) {
|
4115 |
-
if (leftEnd.top < rightStart.top - 2) {
|
4116 |
-
add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
|
4117 |
-
add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
|
4118 |
-
} else {
|
4119 |
-
add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
|
4120 |
-
}
|
4121 |
-
}
|
4122 |
-
if (leftEnd.bottom < rightStart.top)
|
4123 |
-
add(leftSide, leftEnd.bottom, null, rightStart.top);
|
4124 |
-
}
|
4125 |
-
|
4126 |
-
removeChildrenAndAdd(display.selectionDiv, fragment);
|
4127 |
-
display.selectionDiv.style.display = "";
|
4128 |
-
}
|
4129 |
-
|
4130 |
-
// Cursor-blinking
|
4131 |
-
function restartBlink(cm) {
|
4132 |
-
if (!cm.state.focused) return;
|
4133 |
-
var display = cm.display;
|
4134 |
-
clearInterval(display.blinker);
|
4135 |
-
var on = true;
|
4136 |
-
display.cursor.style.visibility = display.otherCursor.style.visibility = "";
|
4137 |
-
if (cm.options.cursorBlinkRate > 0)
|
4138 |
-
display.blinker = setInterval(function() {
|
4139 |
-
display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
|
4140 |
-
}, cm.options.cursorBlinkRate);
|
4141 |
-
}
|
4142 |
-
|
4143 |
-
// HIGHLIGHT WORKER
|
4144 |
-
|
4145 |
-
function startWorker(cm, time) {
|
4146 |
-
if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo)
|
4147 |
-
cm.state.highlight.set(time, bind(highlightWorker, cm));
|
4148 |
-
}
|
4149 |
-
|
4150 |
-
function highlightWorker(cm) {
|
4151 |
-
var doc = cm.doc;
|
4152 |
-
if (doc.frontier < doc.first) doc.frontier = doc.first;
|
4153 |
-
if (doc.frontier >= cm.display.showingTo) return;
|
4154 |
-
var end = +new Date + cm.options.workTime;
|
4155 |
-
var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
|
4156 |
-
var changed = [], prevChange;
|
4157 |
-
doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
|
4158 |
-
if (doc.frontier >= cm.display.showingFrom) { // Visible
|
4159 |
-
var oldStyles = line.styles;
|
4160 |
-
line.styles = highlightLine(cm, line, state, true);
|
4161 |
-
var ischange = !oldStyles || oldStyles.length != line.styles.length;
|
4162 |
-
for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
|
4163 |
-
if (ischange) {
|
4164 |
-
if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
|
4165 |
-
else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
|
4166 |
-
}
|
4167 |
-
line.stateAfter = copyState(doc.mode, state);
|
4168 |
-
} else {
|
4169 |
-
processLine(cm, line.text, state);
|
4170 |
-
line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
|
4171 |
-
}
|
4172 |
-
++doc.frontier;
|
4173 |
-
if (+new Date > end) {
|
4174 |
-
startWorker(cm, cm.options.workDelay);
|
4175 |
-
return true;
|
4176 |
-
}
|
4177 |
-
});
|
4178 |
-
if (changed.length)
|
4179 |
-
operation(cm, function() {
|
4180 |
-
for (var i = 0; i < changed.length; ++i)
|
4181 |
-
regChange(this, changed[i].start, changed[i].end);
|
4182 |
-
})();
|
4183 |
-
}
|
4184 |
-
|
4185 |
-
// Finds the line to start with when starting a parse. Tries to
|
4186 |
-
// find a line with a stateAfter, so that it can start with a
|
4187 |
-
// valid state. If that fails, it returns the line with the
|
4188 |
-
// smallest indentation, which tends to need the least context to
|
4189 |
-
// parse correctly.
|
4190 |
-
function findStartLine(cm, n, precise) {
|
4191 |
-
var minindent, minline, doc = cm.doc;
|
4192 |
-
var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
|
4193 |
-
for (var search = n; search > lim; --search) {
|
4194 |
-
if (search <= doc.first) return doc.first;
|
4195 |
-
var line = getLine(doc, search - 1);
|
4196 |
-
if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
|
4197 |
-
var indented = countColumn(line.text, null, cm.options.tabSize);
|
4198 |
-
if (minline == null || minindent > indented) {
|
4199 |
-
minline = search - 1;
|
4200 |
-
minindent = indented;
|
4201 |
-
}
|
4202 |
-
}
|
4203 |
-
return minline;
|
4204 |
-
}
|
4205 |
-
|
4206 |
-
function getStateBefore(cm, n, precise) {
|
4207 |
-
var doc = cm.doc, display = cm.display;
|
4208 |
-
if (!doc.mode.startState) return true;
|
4209 |
-
var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
|
4210 |
-
if (!state) state = startState(doc.mode);
|
4211 |
-
else state = copyState(doc.mode, state);
|
4212 |
-
doc.iter(pos, n, function(line) {
|
4213 |
-
processLine(cm, line.text, state);
|
4214 |
-
var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
|
4215 |
-
line.stateAfter = save ? copyState(doc.mode, state) : null;
|
4216 |
-
++pos;
|
4217 |
-
});
|
4218 |
-
if (precise) doc.frontier = pos;
|
4219 |
-
return state;
|
4220 |
-
}
|
4221 |
-
|
4222 |
-
// POSITION MEASUREMENT
|
4223 |
-
|
4224 |
-
function paddingTop(display) {return display.lineSpace.offsetTop;}
|
4225 |
-
function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
|
4226 |
-
function paddingH(display) {
|
4227 |
-
if (display.cachedPaddingH) return display.cachedPaddingH;
|
4228 |
-
var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
|
4229 |
-
var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
|
4230 |
-
return display.cachedPaddingH = {left: parseInt(style.paddingLeft),
|
4231 |
-
right: parseInt(style.paddingRight)};
|
4232 |
-
}
|
4233 |
-
|
4234 |
-
function measureChar(cm, line, ch, data, bias) {
|
4235 |
-
var dir = -1;
|
4236 |
-
data = data || measureLine(cm, line);
|
4237 |
-
if (data.crude) {
|
4238 |
-
var left = data.left + ch * data.width;
|
4239 |
-
return {left: left, right: left + data.width, top: data.top, bottom: data.bottom};
|
4240 |
-
}
|
4241 |
-
|
4242 |
-
for (var pos = ch;; pos += dir) {
|
4243 |
-
var r = data[pos];
|
4244 |
-
if (r) break;
|
4245 |
-
if (dir < 0 && pos == 0) dir = 1;
|
4246 |
-
}
|
4247 |
-
bias = pos > ch ? "left" : pos < ch ? "right" : bias;
|
4248 |
-
if (bias == "left" && r.leftSide) r = r.leftSide;
|
4249 |
-
else if (bias == "right" && r.rightSide) r = r.rightSide;
|
4250 |
-
return {left: pos < ch ? r.right : r.left,
|
4251 |
-
right: pos > ch ? r.left : r.right,
|
4252 |
-
top: r.top,
|
4253 |
-
bottom: r.bottom};
|
4254 |
-
}
|
4255 |
-
|
4256 |
-
function findCachedMeasurement(cm, line) {
|
4257 |
-
var cache = cm.display.measureLineCache;
|
4258 |
-
for (var i = 0; i < cache.length; ++i) {
|
4259 |
-
var memo = cache[i];
|
4260 |
-
if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
|
4261 |
-
cm.display.scroller.clientWidth == memo.width &&
|
4262 |
-
memo.classes == line.textClass + "|" + line.wrapClass)
|
4263 |
-
return memo;
|
4264 |
-
}
|
4265 |
-
}
|
4266 |
-
|
4267 |
-
function clearCachedMeasurement(cm, line) {
|
4268 |
-
var exists = findCachedMeasurement(cm, line);
|
4269 |
-
if (exists) exists.text = exists.measure = exists.markedSpans = null;
|
4270 |
-
}
|
4271 |
-
|
4272 |
-
function measureLine(cm, line) {
|
4273 |
-
// First look in the cache
|
4274 |
-
var cached = findCachedMeasurement(cm, line);
|
4275 |
-
if (cached) return cached.measure;
|
4276 |
-
|
4277 |
-
// Failing that, recompute and store result in cache
|
4278 |
-
var measure = measureLineInner(cm, line);
|
4279 |
-
var cache = cm.display.measureLineCache;
|
4280 |
-
var memo = {text: line.text, width: cm.display.scroller.clientWidth,
|
4281 |
-
markedSpans: line.markedSpans, measure: measure,
|
4282 |
-
classes: line.textClass + "|" + line.wrapClass};
|
4283 |
-
if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
|
4284 |
-
else cache.push(memo);
|
4285 |
-
return measure;
|
4286 |
-
}
|
4287 |
-
|
4288 |
-
function measureLineInner(cm, line) {
|
4289 |
-
if (!cm.options.lineWrapping && line.text.length >= cm.options.crudeMeasuringFrom)
|
4290 |
-
return crudelyMeasureLine(cm, line);
|
4291 |
-
|
4292 |
-
var display = cm.display, measure = emptyArray(line.text.length);
|
4293 |
-
var pre = buildLineContent(cm, line, measure, true).pre;
|
4294 |
-
|
4295 |
-
// IE does not cache element positions of inline elements between
|
4296 |
-
// calls to getBoundingClientRect. This makes the loop below,
|
4297 |
-
// which gathers the positions of all the characters on the line,
|
4298 |
-
// do an amount of layout work quadratic to the number of
|
4299 |
-
// characters. When line wrapping is off, we try to improve things
|
4300 |
-
// by first subdividing the line into a bunch of inline blocks, so
|
4301 |
-
// that IE can reuse most of the layout information from caches
|
4302 |
-
// for those blocks. This does interfere with line wrapping, so it
|
4303 |
-
// doesn't work when wrapping is on, but in that case the
|
4304 |
-
// situation is slightly better, since IE does cache line-wrapping
|
4305 |
-
// information and only recomputes per-line.
|
4306 |
-
if (old_ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
|
4307 |
-
var fragment = document.createDocumentFragment();
|
4308 |
-
var chunk = 10, n = pre.childNodes.length;
|
4309 |
-
for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
|
4310 |
-
var wrap = elt("div", null, null, "display: inline-block");
|
4311 |
-
for (var j = 0; j < chunk && n; ++j) {
|
4312 |
-
wrap.appendChild(pre.firstChild);
|
4313 |
-
--n;
|
4314 |
-
}
|
4315 |
-
fragment.appendChild(wrap);
|
4316 |
-
}
|
4317 |
-
pre.appendChild(fragment);
|
4318 |
-
}
|
4319 |
-
|
4320 |
-
removeChildrenAndAdd(display.measure, pre);
|
4321 |
-
|
4322 |
-
var outer = getRect(display.lineDiv);
|
4323 |
-
var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight;
|
4324 |
-
// Work around an IE7/8 bug where it will sometimes have randomly
|
4325 |
-
// replaced our pre with a clone at this point.
|
4326 |
-
if (ie_lt9 && display.measure.first != pre)
|
4327 |
-
removeChildrenAndAdd(display.measure, pre);
|
4328 |
-
|
4329 |
-
function measureRect(rect) {
|
4330 |
-
var top = rect.top - outer.top, bot = rect.bottom - outer.top;
|
4331 |
-
if (bot > maxBot) bot = maxBot;
|
4332 |
-
if (top < 0) top = 0;
|
4333 |
-
for (var i = vranges.length - 2; i >= 0; i -= 2) {
|
4334 |
-
var rtop = vranges[i], rbot = vranges[i+1];
|
4335 |
-
if (rtop > bot || rbot < top) continue;
|
4336 |
-
if (rtop <= top && rbot >= bot ||
|
4337 |
-
top <= rtop && bot >= rbot ||
|
4338 |
-
Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
|
4339 |
-
vranges[i] = Math.min(top, rtop);
|
4340 |
-
vranges[i+1] = Math.max(bot, rbot);
|
4341 |
-
break;
|
4342 |
-
}
|
4343 |
-
}
|
4344 |
-
if (i < 0) { i = vranges.length; vranges.push(top, bot); }
|
4345 |
-
return {left: rect.left - outer.left,
|
4346 |
-
right: rect.right - outer.left,
|
4347 |
-
top: i, bottom: null};
|
4348 |
-
}
|
4349 |
-
function finishRect(rect) {
|
4350 |
-
rect.bottom = vranges[rect.top+1];
|
4351 |
-
rect.top = vranges[rect.top];
|
4352 |
-
}
|
4353 |
-
|
4354 |
-
for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
|
4355 |
-
var node = cur, rect = null;
|
4356 |
-
// A widget might wrap, needs special care
|
4357 |
-
if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
|
4358 |
-
if (cur.firstChild.nodeType == 1) node = cur.firstChild;
|
4359 |
-
var rects = node.getClientRects();
|
4360 |
-
if (rects.length > 1) {
|
4361 |
-
rect = data[i] = measureRect(rects[0]);
|
4362 |
-
rect.rightSide = measureRect(rects[rects.length - 1]);
|
4363 |
-
}
|
4364 |
-
}
|
4365 |
-
if (!rect) rect = data[i] = measureRect(getRect(node));
|
4366 |
-
if (cur.measureRight) rect.right = getRect(cur.measureRight).left - outer.left;
|
4367 |
-
if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
|
4368 |
-
}
|
4369 |
-
removeChildren(cm.display.measure);
|
4370 |
-
for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
|
4371 |
-
finishRect(cur);
|
4372 |
-
if (cur.leftSide) finishRect(cur.leftSide);
|
4373 |
-
if (cur.rightSide) finishRect(cur.rightSide);
|
4374 |
-
}
|
4375 |
-
return data;
|
4376 |
-
}
|
4377 |
-
|
4378 |
-
function crudelyMeasureLine(cm, line) {
|
4379 |
-
var copy = new Line(line.text.slice(0, 100), null);
|
4380 |
-
if (line.textClass) copy.textClass = line.textClass;
|
4381 |
-
var measure = measureLineInner(cm, copy);
|
4382 |
-
var left = measureChar(cm, copy, 0, measure, "left");
|
4383 |
-
var right = measureChar(cm, copy, 99, measure, "right");
|
4384 |
-
return {crude: true, top: left.top, left: left.left, bottom: left.bottom, width: (right.right - left.left) / 100};
|
4385 |
-
}
|
4386 |
-
|
4387 |
-
function measureLineWidth(cm, line) {
|
4388 |
-
var hasBadSpan = false;
|
4389 |
-
if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
|
4390 |
-
var sp = line.markedSpans[i];
|
4391 |
-
if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
|
4392 |
-
}
|
4393 |
-
var cached = !hasBadSpan && findCachedMeasurement(cm, line);
|
4394 |
-
if (cached || line.text.length >= cm.options.crudeMeasuringFrom)
|
4395 |
-
return measureChar(cm, line, line.text.length, cached && cached.measure, "right").right;
|
4396 |
-
|
4397 |
-
var pre = buildLineContent(cm, line, null, true).pre;
|
4398 |
-
var end = pre.appendChild(zeroWidthElement(cm.display.measure));
|
4399 |
-
removeChildrenAndAdd(cm.display.measure, pre);
|
4400 |
-
return getRect(end).right - getRect(cm.display.lineDiv).left;
|
4401 |
-
}
|
4402 |
-
|
4403 |
-
function clearCaches(cm) {
|
4404 |
-
cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
|
4405 |
-
cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
|
4406 |
-
if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
|
4407 |
-
cm.display.lineNumChars = null;
|
4408 |
-
}
|
4409 |
-
|
4410 |
-
function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
|
4411 |
-
function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
|
4412 |
-
|
4413 |
-
// Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
|
4414 |
-
function intoCoordSystem(cm, lineObj, rect, context) {
|
4415 |
-
if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
|
4416 |
-
var size = widgetHeight(lineObj.widgets[i]);
|
4417 |
-
rect.top += size; rect.bottom += size;
|
4418 |
-
}
|
4419 |
-
if (context == "line") return rect;
|
4420 |
-
if (!context) context = "local";
|
4421 |
-
var yOff = heightAtLine(cm, lineObj);
|
4422 |
-
if (context == "local") yOff += paddingTop(cm.display);
|
4423 |
-
else yOff -= cm.display.viewOffset;
|
4424 |
-
if (context == "page" || context == "window") {
|
4425 |
-
var lOff = getRect(cm.display.lineSpace);
|
4426 |
-
yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
|
4427 |
-
var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
|
4428 |
-
rect.left += xOff; rect.right += xOff;
|
4429 |
-
}
|
4430 |
-
rect.top += yOff; rect.bottom += yOff;
|
4431 |
-
return rect;
|
4432 |
-
}
|
4433 |
-
|
4434 |
-
// Context may be "window", "page", "div", or "local"/null
|
4435 |
-
// Result is in "div" coords
|
4436 |
-
function fromCoordSystem(cm, coords, context) {
|
4437 |
-
if (context == "div") return coords;
|
4438 |
-
var left = coords.left, top = coords.top;
|
4439 |
-
// First move into "page" coordinate system
|
4440 |
-
if (context == "page") {
|
4441 |
-
left -= pageScrollX();
|
4442 |
-
top -= pageScrollY();
|
4443 |
-
} else if (context == "local" || !context) {
|
4444 |
-
var localBox = getRect(cm.display.sizer);
|
4445 |
-
left += localBox.left;
|
4446 |
-
top += localBox.top;
|
4447 |
-
}
|
4448 |
-
|
4449 |
-
var lineSpaceBox = getRect(cm.display.lineSpace);
|
4450 |
-
return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
|
4451 |
-
}
|
4452 |
-
|
4453 |
-
function charCoords(cm, pos, context, lineObj, bias) {
|
4454 |
-
if (!lineObj) lineObj = getLine(cm.doc, pos.line);
|
4455 |
-
return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context);
|
4456 |
-
}
|
4457 |
-
|
4458 |
-
function cursorCoords(cm, pos, context, lineObj, measurement) {
|
4459 |
-
lineObj = lineObj || getLine(cm.doc, pos.line);
|
4460 |
-
if (!measurement) measurement = measureLine(cm, lineObj);
|
4461 |
-
function get(ch, right) {
|
4462 |
-
var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left");
|
4463 |
-
if (right) m.left = m.right; else m.right = m.left;
|
4464 |
-
return intoCoordSystem(cm, lineObj, m, context);
|
4465 |
-
}
|
4466 |
-
function getBidi(ch, partPos) {
|
4467 |
-
var part = order[partPos], right = part.level % 2;
|
4468 |
-
if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
|
4469 |
-
part = order[--partPos];
|
4470 |
-
ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
|
4471 |
-
right = true;
|
4472 |
-
} else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
|
4473 |
-
part = order[++partPos];
|
4474 |
-
ch = bidiLeft(part) - part.level % 2;
|
4475 |
-
right = false;
|
4476 |
-
}
|
4477 |
-
if (right && ch == part.to && ch > part.from) return get(ch - 1);
|
4478 |
-
return get(ch, right);
|
4479 |
-
}
|
4480 |
-
var order = getOrder(lineObj), ch = pos.ch;
|
4481 |
-
if (!order) return get(ch);
|
4482 |
-
var partPos = getBidiPartAt(order, ch);
|
4483 |
-
var val = getBidi(ch, partPos);
|
4484 |
-
if (bidiOther != null) val.other = getBidi(ch, bidiOther);
|
4485 |
-
return val;
|
4486 |
-
}
|
4487 |
-
|
4488 |
-
function PosWithInfo(line, ch, outside, xRel) {
|
4489 |
-
var pos = new Pos(line, ch);
|
4490 |
-
pos.xRel = xRel;
|
4491 |
-
if (outside) pos.outside = true;
|
4492 |
-
return pos;
|
4493 |
-
}
|
4494 |
-
|
4495 |
-
// Coords must be lineSpace-local
|
4496 |
-
function coordsChar(cm, x, y) {
|
4497 |
-
var doc = cm.doc;
|
4498 |
-
y += cm.display.viewOffset;
|
4499 |
-
if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
|
4500 |
-
var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
|
4501 |
-
if (lineNo > last)
|
4502 |
-
return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
|
4503 |
-
if (x < 0) x = 0;
|
4504 |
-
|
4505 |
-
for (;;) {
|
4506 |
-
var lineObj = getLine(doc, lineNo);
|
4507 |
-
var found = coordsCharInner(cm, lineObj, lineNo, x, y);
|
4508 |
-
var merged = collapsedSpanAtEnd(lineObj);
|
4509 |
-
var mergedPos = merged && merged.find();
|
4510 |
-
if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
|
4511 |
-
lineNo = mergedPos.to.line;
|
4512 |
-
else
|
4513 |
-
return found;
|
4514 |
-
}
|
4515 |
-
}
|
4516 |
-
|
4517 |
-
function coordsCharInner(cm, lineObj, lineNo, x, y) {
|
4518 |
-
var innerOff = y - heightAtLine(cm, lineObj);
|
4519 |
-
var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
|
4520 |
-
var measurement = measureLine(cm, lineObj);
|
4521 |
-
|
4522 |
-
function getX(ch) {
|
4523 |
-
var sp = cursorCoords(cm, Pos(lineNo, ch), "line",
|
4524 |
-
lineObj, measurement);
|
4525 |
-
wrongLine = true;
|
4526 |
-
if (innerOff > sp.bottom) return sp.left - adjust;
|
4527 |
-
else if (innerOff < sp.top) return sp.left + adjust;
|
4528 |
-
else wrongLine = false;
|
4529 |
-
return sp.left;
|
4530 |
-
}
|
4531 |
-
|
4532 |
-
var bidi = getOrder(lineObj), dist = lineObj.text.length;
|
4533 |
-
var from = lineLeft(lineObj), to = lineRight(lineObj);
|
4534 |
-
var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
|
4535 |
-
|
4536 |
-
if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
|
4537 |
-
// Do a binary search between these bounds.
|
4538 |
-
for (;;) {
|
4539 |
-
if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
|
4540 |
-
var ch = x < fromX || x - fromX <= toX - x ? from : to;
|
4541 |
-
var xDiff = x - (ch == from ? fromX : toX);
|
4542 |
-
while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
|
4543 |
-
var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
|
4544 |
-
xDiff < 0 ? -1 : xDiff ? 1 : 0);
|
4545 |
-
return pos;
|
4546 |
-
}
|
4547 |
-
var step = Math.ceil(dist / 2), middle = from + step;
|
4548 |
-
if (bidi) {
|
4549 |
-
middle = from;
|
4550 |
-
for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
|
4551 |
-
}
|
4552 |
-
var middleX = getX(middle);
|
4553 |
-
if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
|
4554 |
-
else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
|
4555 |
-
}
|
4556 |
-
}
|
4557 |
-
|
4558 |
-
var measureText;
|
4559 |
-
function textHeight(display) {
|
4560 |
-
if (display.cachedTextHeight != null) return display.cachedTextHeight;
|
4561 |
-
if (measureText == null) {
|
4562 |
-
measureText = elt("pre");
|
4563 |
-
// Measure a bunch of lines, for browsers that compute
|
4564 |
-
// fractional heights.
|
4565 |
-
for (var i = 0; i < 49; ++i) {
|
4566 |
-
measureText.appendChild(document.createTextNode("x"));
|
4567 |
-
measureText.appendChild(elt("br"));
|
4568 |
-
}
|
4569 |
-
measureText.appendChild(document.createTextNode("x"));
|
4570 |
-
}
|
4571 |
-
removeChildrenAndAdd(display.measure, measureText);
|
4572 |
-
var height = measureText.offsetHeight / 50;
|
4573 |
-
if (height > 3) display.cachedTextHeight = height;
|
4574 |
-
removeChildren(display.measure);
|
4575 |
-
return height || 1;
|
4576 |
-
}
|
4577 |
-
|
4578 |
-
function charWidth(display) {
|
4579 |
-
if (display.cachedCharWidth != null) return display.cachedCharWidth;
|
4580 |
-
var anchor = elt("span", "x");
|
4581 |
-
var pre = elt("pre", [anchor]);
|
4582 |
-
removeChildrenAndAdd(display.measure, pre);
|
4583 |
-
var width = anchor.offsetWidth;
|
4584 |
-
if (width > 2) display.cachedCharWidth = width;
|
4585 |
-
return width || 10;
|
4586 |
-
}
|
4587 |
-
|
4588 |
-
// OPERATIONS
|
4589 |
-
|
4590 |
-
// Operations are used to wrap changes in such a way that each
|
4591 |
-
// change won't have to update the cursor and display (which would
|
4592 |
-
// be awkward, slow, and error-prone), but instead updates are
|
4593 |
-
// batched and then all combined and executed at once.
|
4594 |
-
|
4595 |
-
var nextOpId = 0;
|
4596 |
-
function startOperation(cm) {
|
4597 |
-
cm.curOp = {
|
4598 |
-
// An array of ranges of lines that have to be updated. See
|
4599 |
-
// updateDisplay.
|
4600 |
-
changes: [],
|
4601 |
-
forceUpdate: false,
|
4602 |
-
updateInput: null,
|
4603 |
-
userSelChange: null,
|
4604 |
-
textChanged: null,
|
4605 |
-
selectionChanged: false,
|
4606 |
-
cursorActivity: false,
|
4607 |
-
updateMaxLine: false,
|
4608 |
-
updateScrollPos: false,
|
4609 |
-
id: ++nextOpId
|
4610 |
-
};
|
4611 |
-
if (!delayedCallbackDepth++) delayedCallbacks = [];
|
4612 |
-
}
|
4613 |
-
|
4614 |
-
function endOperation(cm) {
|
4615 |
-
var op = cm.curOp, doc = cm.doc, display = cm.display;
|
4616 |
-
cm.curOp = null;
|
4617 |
-
|
4618 |
-
if (op.updateMaxLine) computeMaxLength(cm);
|
4619 |
-
if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
|
4620 |
-
var width = measureLineWidth(cm, display.maxLine);
|
4621 |
-
display.sizer.style.minWidth = Math.max(0, width + 3) + "px";
|
4622 |
-
display.maxLineChanged = false;
|
4623 |
-
var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
|
4624 |
-
if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
|
4625 |
-
setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
|
4626 |
-
}
|
4627 |
-
var newScrollPos, updated;
|
4628 |
-
if (op.updateScrollPos) {
|
4629 |
-
newScrollPos = op.updateScrollPos;
|
4630 |
-
} else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible
|
4631 |
-
var coords = cursorCoords(cm, doc.sel.head);
|
4632 |
-
newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
|
4633 |
-
}
|
4634 |
-
if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
|
4635 |
-
updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
|
4636 |
-
if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
|
4637 |
-
}
|
4638 |
-
if (!updated && op.selectionChanged) updateSelection(cm);
|
4639 |
-
if (op.updateScrollPos) {
|
4640 |
-
var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, newScrollPos.scrollTop));
|
4641 |
-
var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, newScrollPos.scrollLeft));
|
4642 |
-
display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top;
|
4643 |
-
display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left;
|
4644 |
-
alignHorizontally(cm);
|
4645 |
-
if (op.scrollToPos)
|
4646 |
-
scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from),
|
4647 |
-
clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin);
|
4648 |
-
} else if (newScrollPos) {
|
4649 |
-
scrollCursorIntoView(cm);
|
4650 |
-
}
|
4651 |
-
if (op.selectionChanged) restartBlink(cm);
|
4652 |
-
|
4653 |
-
if (cm.state.focused && op.updateInput)
|
4654 |
-
resetInput(cm, op.userSelChange);
|
4655 |
-
|
4656 |
-
var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
|
4657 |
-
if (hidden) for (var i = 0; i < hidden.length; ++i)
|
4658 |
-
if (!hidden[i].lines.length) signal(hidden[i], "hide");
|
4659 |
-
if (unhidden) for (var i = 0; i < unhidden.length; ++i)
|
4660 |
-
if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
|
4661 |
-
|
4662 |
-
var delayed;
|
4663 |
-
if (!--delayedCallbackDepth) {
|
4664 |
-
delayed = delayedCallbacks;
|
4665 |
-
delayedCallbacks = null;
|
4666 |
-
}
|
4667 |
-
if (op.textChanged)
|
4668 |
-
signal(cm, "change", cm, op.textChanged);
|
4669 |
-
if (op.cursorActivity) signal(cm, "cursorActivity", cm);
|
4670 |
-
if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
|
4671 |
-
}
|
4672 |
-
|
4673 |
-
// Wraps a function in an operation. Returns the wrapped function.
|
4674 |
-
function operation(cm1, f) {
|
4675 |
-
return function() {
|
4676 |
-
var cm = cm1 || this, withOp = !cm.curOp;
|
4677 |
-
if (withOp) startOperation(cm);
|
4678 |
-
try { var result = f.apply(cm, arguments); }
|
4679 |
-
finally { if (withOp) endOperation(cm); }
|
4680 |
-
return result;
|
4681 |
-
};
|
4682 |
-
}
|
4683 |
-
function docOperation(f) {
|
4684 |
-
return function() {
|
4685 |
-
var withOp = this.cm && !this.cm.curOp, result;
|
4686 |
-
if (withOp) startOperation(this.cm);
|
4687 |
-
try { result = f.apply(this, arguments); }
|
4688 |
-
finally { if (withOp) endOperation(this.cm); }
|
4689 |
-
return result;
|
4690 |
-
};
|
4691 |
-
}
|
4692 |
-
function runInOp(cm, f) {
|
4693 |
-
var withOp = !cm.curOp, result;
|
4694 |
-
if (withOp) startOperation(cm);
|
4695 |
-
try { result = f(); }
|
4696 |
-
finally { if (withOp) endOperation(cm); }
|
4697 |
-
return result;
|
4698 |
-
}
|
4699 |
-
|
4700 |
-
function regChange(cm, from, to, lendiff) {
|
4701 |
-
if (from == null) from = cm.doc.first;
|
4702 |
-
if (to == null) to = cm.doc.first + cm.doc.size;
|
4703 |
-
cm.curOp.changes.push({from: from, to: to, diff: lendiff});
|
4704 |
-
}
|
4705 |
-
|
4706 |
-
// INPUT HANDLING
|
4707 |
-
|
4708 |
-
function slowPoll(cm) {
|
4709 |
-
if (cm.display.pollingFast) return;
|
4710 |
-
cm.display.poll.set(cm.options.pollInterval, function() {
|
4711 |
-
readInput(cm);
|
4712 |
-
if (cm.state.focused) slowPoll(cm);
|
4713 |
-
});
|
4714 |
-
}
|
4715 |
-
|
4716 |
-
function fastPoll(cm) {
|
4717 |
-
var missed = false;
|
4718 |
-
cm.display.pollingFast = true;
|
4719 |
-
function p() {
|
4720 |
-
var changed = readInput(cm);
|
4721 |
-
if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
|
4722 |
-
else {cm.display.pollingFast = false; slowPoll(cm);}
|
4723 |
-
}
|
4724 |
-
cm.display.poll.set(20, p);
|
4725 |
-
}
|
4726 |
-
|
4727 |
-
// prevInput is a hack to work with IME. If we reset the textarea
|
4728 |
-
// on every change, that breaks IME. So we look for changes
|
4729 |
-
// compared to the previous content instead. (Modern browsers have
|
4730 |
-
// events that indicate IME taking place, but these are not widely
|
4731 |
-
// supported or compatible enough yet to rely on.)
|
4732 |
-
function readInput(cm) {
|
4733 |
-
var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
|
4734 |
-
if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.options.disableInput) return false;
|
4735 |
-
if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
|
4736 |
-
input.value = input.value.substring(0, input.value.length - 1);
|
4737 |
-
cm.state.fakedLastChar = false;
|
4738 |
-
}
|
4739 |
-
var text = input.value;
|
4740 |
-
if (text == prevInput && posEq(sel.from, sel.to)) return false;
|
4741 |
-
if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
|
4742 |
-
resetInput(cm, true);
|
4743 |
-
return false;
|
4744 |
-
}
|
4745 |
-
|
4746 |
-
var withOp = !cm.curOp;
|
4747 |
-
if (withOp) startOperation(cm);
|
4748 |
-
sel.shift = false;
|
4749 |
-
var same = 0, l = Math.min(prevInput.length, text.length);
|
4750 |
-
while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
|
4751 |
-
var from = sel.from, to = sel.to;
|
4752 |
-
var inserted = text.slice(same);
|
4753 |
-
if (same < prevInput.length)
|
4754 |
-
from = Pos(from.line, from.ch - (prevInput.length - same));
|
4755 |
-
else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
|
4756 |
-
to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + inserted.length));
|
4757 |
-
|
4758 |
-
var updateInput = cm.curOp.updateInput;
|
4759 |
-
var changeEvent = {from: from, to: to, text: splitLines(inserted),
|
4760 |
-
origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
|
4761 |
-
makeChange(cm.doc, changeEvent, "end");
|
4762 |
-
cm.curOp.updateInput = updateInput;
|
4763 |
-
signalLater(cm, "inputRead", cm, changeEvent);
|
4764 |
-
if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
|
4765 |
-
cm.options.smartIndent && sel.head.ch < 100) {
|
4766 |
-
var electric = cm.getModeAt(sel.head).electricChars;
|
4767 |
-
if (electric) for (var i = 0; i < electric.length; i++)
|
4768 |
-
if (inserted.indexOf(electric.charAt(i)) > -1) {
|
4769 |
-
indentLine(cm, sel.head.line, "smart");
|
4770 |
-
break;
|
4771 |
-
}
|
4772 |
-
}
|
4773 |
-
|
4774 |
-
if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
|
4775 |
-
else cm.display.prevInput = text;
|
4776 |
-
if (withOp) endOperation(cm);
|
4777 |
-
cm.state.pasteIncoming = cm.state.cutIncoming = false;
|
4778 |
-
return true;
|
4779 |
-
}
|
4780 |
-
|
4781 |
-
function resetInput(cm, user) {
|
4782 |
-
var minimal, selected, doc = cm.doc;
|
4783 |
-
if (!posEq(doc.sel.from, doc.sel.to)) {
|
4784 |
-
cm.display.prevInput = "";
|
4785 |
-
minimal = hasCopyEvent &&
|
4786 |
-
(doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
|
4787 |
-
var content = minimal ? "-" : selected || cm.getSelection();
|
4788 |
-
cm.display.input.value = content;
|
4789 |
-
if (cm.state.focused) selectInput(cm.display.input);
|
4790 |
-
if (ie && !ie_lt9) cm.display.inputHasSelection = content;
|
4791 |
-
} else if (user) {
|
4792 |
-
cm.display.prevInput = cm.display.input.value = "";
|
4793 |
-
if (ie && !ie_lt9) cm.display.inputHasSelection = null;
|
4794 |
-
}
|
4795 |
-
cm.display.inaccurateSelection = minimal;
|
4796 |
-
}
|
4797 |
-
|
4798 |
-
function focusInput(cm) {
|
4799 |
-
if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
|
4800 |
-
cm.display.input.focus();
|
4801 |
-
}
|
4802 |
-
|
4803 |
-
function ensureFocus(cm) {
|
4804 |
-
if (!cm.state.focused) { focusInput(cm); onFocus(cm); }
|
4805 |
-
}
|
4806 |
-
|
4807 |
-
function isReadOnly(cm) {
|
4808 |
-
return cm.options.readOnly || cm.doc.cantEdit;
|
4809 |
-
}
|
4810 |
-
|
4811 |
-
// EVENT HANDLERS
|
4812 |
-
|
4813 |
-
function registerEventHandlers(cm) {
|
4814 |
-
var d = cm.display;
|
4815 |
-
on(d.scroller, "mousedown", operation(cm, onMouseDown));
|
4816 |
-
if (old_ie)
|
4817 |
-
on(d.scroller, "dblclick", operation(cm, function(e) {
|
4818 |
-
if (signalDOMEvent(cm, e)) return;
|
4819 |
-
var pos = posFromMouse(cm, e);
|
4820 |
-
if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
|
4821 |
-
e_preventDefault(e);
|
4822 |
-
var word = findWordAt(getLine(cm.doc, pos.line).text, pos);
|
4823 |
-
extendSelection(cm.doc, word.from, word.to);
|
4824 |
-
}));
|
4825 |
-
else
|
4826 |
-
on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
|
4827 |
-
on(d.lineSpace, "selectstart", function(e) {
|
4828 |
-
if (!eventInWidget(d, e)) e_preventDefault(e);
|
4829 |
-
});
|
4830 |
-
// Gecko browsers fire contextmenu *after* opening the menu, at
|
4831 |
-
// which point we can't mess with it anymore. Context menu is
|
4832 |
-
// handled in onMouseDown for Gecko.
|
4833 |
-
if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
|
4834 |
-
|
4835 |
-
on(d.scroller, "scroll", function() {
|
4836 |
-
if (d.scroller.clientHeight) {
|
4837 |
-
setScrollTop(cm, d.scroller.scrollTop);
|
4838 |
-
setScrollLeft(cm, d.scroller.scrollLeft, true);
|
4839 |
-
signal(cm, "scroll", cm);
|
4840 |
-
}
|
4841 |
-
});
|
4842 |
-
on(d.scrollbarV, "scroll", function() {
|
4843 |
-
if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
|
4844 |
-
});
|
4845 |
-
on(d.scrollbarH, "scroll", function() {
|
4846 |
-
if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
|
4847 |
-
});
|
4848 |
-
|
4849 |
-
on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
|
4850 |
-
on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
|
4851 |
-
|
4852 |
-
function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
|
4853 |
-
on(d.scrollbarH, "mousedown", reFocus);
|
4854 |
-
on(d.scrollbarV, "mousedown", reFocus);
|
4855 |
-
// Prevent wrapper from ever scrolling
|
4856 |
-
on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
|
4857 |
-
|
4858 |
-
var resizeTimer;
|
4859 |
-
function onResize() {
|
4860 |
-
if (resizeTimer == null) resizeTimer = setTimeout(function() {
|
4861 |
-
resizeTimer = null;
|
4862 |
-
// Might be a text scaling operation, clear size caches.
|
4863 |
-
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = knownScrollbarWidth = null;
|
4864 |
-
clearCaches(cm);
|
4865 |
-
runInOp(cm, bind(regChange, cm));
|
4866 |
-
}, 100);
|
4867 |
-
}
|
4868 |
-
on(window, "resize", onResize);
|
4869 |
-
// Above handler holds on to the editor and its data structures.
|
4870 |
-
// Here we poll to unregister it when the editor is no longer in
|
4871 |
-
// the document, so that it can be garbage-collected.
|
4872 |
-
function unregister() {
|
4873 |
-
for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
|
4874 |
-
if (p) setTimeout(unregister, 5000);
|
4875 |
-
else off(window, "resize", onResize);
|
4876 |
-
}
|
4877 |
-
setTimeout(unregister, 5000);
|
4878 |
-
|
4879 |
-
on(d.input, "keyup", operation(cm, onKeyUp));
|
4880 |
-
on(d.input, "input", function() {
|
4881 |
-
if (ie && !ie_lt9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
|
4882 |
-
fastPoll(cm);
|
4883 |
-
});
|
4884 |
-
on(d.input, "keydown", operation(cm, onKeyDown));
|
4885 |
-
on(d.input, "keypress", operation(cm, onKeyPress));
|
4886 |
-
on(d.input, "focus", bind(onFocus, cm));
|
4887 |
-
on(d.input, "blur", bind(onBlur, cm));
|
4888 |
-
|
4889 |
-
function drag_(e) {
|
4890 |
-
if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
|
4891 |
-
e_stop(e);
|
4892 |
-
}
|
4893 |
-
if (cm.options.dragDrop) {
|
4894 |
-
on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
|
4895 |
-
on(d.scroller, "dragenter", drag_);
|
4896 |
-
on(d.scroller, "dragover", drag_);
|
4897 |
-
on(d.scroller, "drop", operation(cm, onDrop));
|
4898 |
-
}
|
4899 |
-
on(d.scroller, "paste", function(e) {
|
4900 |
-
if (eventInWidget(d, e)) return;
|
4901 |
-
focusInput(cm);
|
4902 |
-
fastPoll(cm);
|
4903 |
-
});
|
4904 |
-
on(d.input, "paste", function() {
|
4905 |
-
// Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
|
4906 |
-
// Add a char to the end of textarea before paste occur so that
|
4907 |
-
// selection doesn't span to the end of textarea.
|
4908 |
-
if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
|
4909 |
-
var start = d.input.selectionStart, end = d.input.selectionEnd;
|
4910 |
-
d.input.value += "$";
|
4911 |
-
d.input.selectionStart = start;
|
4912 |
-
d.input.selectionEnd = end;
|
4913 |
-
cm.state.fakedLastChar = true;
|
4914 |
-
}
|
4915 |
-
cm.state.pasteIncoming = true;
|
4916 |
-
fastPoll(cm);
|
4917 |
-
});
|
4918 |
-
|
4919 |
-
function prepareCopy(e) {
|
4920 |
-
if (d.inaccurateSelection) {
|
4921 |
-
d.prevInput = "";
|
4922 |
-
d.inaccurateSelection = false;
|
4923 |
-
d.input.value = cm.getSelection();
|
4924 |
-
selectInput(d.input);
|
4925 |
-
}
|
4926 |
-
if (e.type == "cut") cm.state.cutIncoming = true;
|
4927 |
-
}
|
4928 |
-
on(d.input, "cut", prepareCopy);
|
4929 |
-
on(d.input, "copy", prepareCopy);
|
4930 |
-
|
4931 |
-
// Needed to handle Tab key in KHTML
|
4932 |
-
if (khtml) on(d.sizer, "mouseup", function() {
|
4933 |
-
if (document.activeElement == d.input) d.input.blur();
|
4934 |
-
focusInput(cm);
|
4935 |
-
});
|
4936 |
-
}
|
4937 |
-
|
4938 |
-
function eventInWidget(display, e) {
|
4939 |
-
for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
|
4940 |
-
if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
|
4941 |
-
}
|
4942 |
-
}
|
4943 |
-
|
4944 |
-
function posFromMouse(cm, e, liberal) {
|
4945 |
-
var display = cm.display;
|
4946 |
-
if (!liberal) {
|
4947 |
-
var target = e_target(e);
|
4948 |
-
if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
|
4949 |
-
target == display.scrollbarV || target == display.scrollbarV.firstChild ||
|
4950 |
-
target == display.scrollbarFiller || target == display.gutterFiller) return null;
|
4951 |
-
}
|
4952 |
-
var x, y, space = getRect(display.lineSpace);
|
4953 |
-
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
|
4954 |
-
try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
|
4955 |
-
return coordsChar(cm, x - space.left, y - space.top);
|
4956 |
-
}
|
4957 |
-
|
4958 |
-
var lastClick, lastDoubleClick;
|
4959 |
-
function onMouseDown(e) {
|
4960 |
-
if (signalDOMEvent(this, e)) return;
|
4961 |
-
var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel;
|
4962 |
-
sel.shift = e.shiftKey;
|
4963 |
-
|
4964 |
-
if (eventInWidget(display, e)) {
|
4965 |
-
if (!webkit) {
|
4966 |
-
display.scroller.draggable = false;
|
4967 |
-
setTimeout(function(){display.scroller.draggable = true;}, 100);
|
4968 |
-
}
|
4969 |
-
return;
|
4970 |
-
}
|
4971 |
-
if (clickInGutter(cm, e)) return;
|
4972 |
-
var start = posFromMouse(cm, e);
|
4973 |
-
window.focus();
|
4974 |
-
|
4975 |
-
switch (e_button(e)) {
|
4976 |
-
case 3:
|
4977 |
-
if (captureMiddleClick) onContextMenu.call(cm, cm, e);
|
4978 |
-
return;
|
4979 |
-
case 2:
|
4980 |
-
if (webkit) cm.state.lastMiddleDown = +new Date;
|
4981 |
-
if (start) extendSelection(cm.doc, start);
|
4982 |
-
setTimeout(bind(focusInput, cm), 20);
|
4983 |
-
e_preventDefault(e);
|
4984 |
-
return;
|
4985 |
-
}
|
4986 |
-
// For button 1, if it was clicked inside the editor
|
4987 |
-
// (posFromMouse returning non-null), we have to adjust the
|
4988 |
-
// selection.
|
4989 |
-
if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
|
4990 |
-
|
4991 |
-
setTimeout(bind(ensureFocus, cm), 0);
|
4992 |
-
|
4993 |
-
var now = +new Date, type = "single";
|
4994 |
-
if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
|
4995 |
-
type = "triple";
|
4996 |
-
e_preventDefault(e);
|
4997 |
-
setTimeout(bind(focusInput, cm), 20);
|
4998 |
-
selectLine(cm, start.line);
|
4999 |
-
} else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
|
5000 |
-
type = "double";
|
5001 |
-
lastDoubleClick = {time: now, pos: start};
|
5002 |
-
e_preventDefault(e);
|
5003 |
-
var word = findWordAt(getLine(doc, start.line).text, start);
|
5004 |
-
extendSelection(cm.doc, word.from, word.to);
|
5005 |
-
} else { lastClick = {time: now, pos: start}; }
|
5006 |
-
|
5007 |
-
var last = start;
|
5008 |
-
if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
|
5009 |
-
!posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
|
5010 |
-
var dragEnd = operation(cm, function(e2) {
|
5011 |
-
if (webkit) display.scroller.draggable = false;
|
5012 |
-
cm.state.draggingText = false;
|
5013 |
-
off(document, "mouseup", dragEnd);
|
5014 |
-
off(display.scroller, "drop", dragEnd);
|
5015 |
-
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
|
5016 |
-
e_preventDefault(e2);
|
5017 |
-
extendSelection(cm.doc, start);
|
5018 |
-
focusInput(cm);
|
5019 |
-
// Work around unexplainable focus problem in IE9 (#2127)
|
5020 |
-
if (old_ie && !ie_lt9)
|
5021 |
-
setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);
|
5022 |
-
}
|
5023 |
-
});
|
5024 |
-
// Let the drag handler handle this.
|
5025 |
-
if (webkit) display.scroller.draggable = true;
|
5026 |
-
cm.state.draggingText = dragEnd;
|
5027 |
-
// IE's approach to draggable
|
5028 |
-
if (display.scroller.dragDrop) display.scroller.dragDrop();
|
5029 |
-
on(document, "mouseup", dragEnd);
|
5030 |
-
on(display.scroller, "drop", dragEnd);
|
5031 |
-
return;
|
5032 |
-
}
|
5033 |
-
e_preventDefault(e);
|
5034 |
-
if (type == "single") extendSelection(cm.doc, clipPos(doc, start));
|
5035 |
-
|
5036 |
-
var startstart = sel.from, startend = sel.to, lastPos = start;
|
5037 |
-
|
5038 |
-
function doSelect(cur) {
|
5039 |
-
if (posEq(lastPos, cur)) return;
|
5040 |
-
lastPos = cur;
|
5041 |
-
|
5042 |
-
if (type == "single") {
|
5043 |
-
extendSelection(cm.doc, clipPos(doc, start), cur);
|
5044 |
-
return;
|
5045 |
-
}
|
5046 |
-
|
5047 |
-
startstart = clipPos(doc, startstart);
|
5048 |
-
startend = clipPos(doc, startend);
|
5049 |
-
if (type == "double") {
|
5050 |
-
var word = findWordAt(getLine(doc, cur.line).text, cur);
|
5051 |
-
if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend);
|
5052 |
-
else extendSelection(cm.doc, startstart, word.to);
|
5053 |
-
} else if (type == "triple") {
|
5054 |
-
if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0)));
|
5055 |
-
else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0)));
|
5056 |
-
}
|
5057 |
-
}
|
5058 |
-
|
5059 |
-
var editorSize = getRect(display.wrapper);
|
5060 |
-
// Used to ensure timeout re-tries don't fire when another extend
|
5061 |
-
// happened in the meantime (clearTimeout isn't reliable -- at
|
5062 |
-
// least on Chrome, the timeouts still happen even when cleared,
|
5063 |
-
// if the clear happens after their scheduled firing time).
|
5064 |
-
var counter = 0;
|
5065 |
-
|
5066 |
-
function extend(e) {
|
5067 |
-
var curCount = ++counter;
|
5068 |
-
var cur = posFromMouse(cm, e, true);
|
5069 |
-
if (!cur) return;
|
5070 |
-
if (!posEq(cur, last)) {
|
5071 |
-
ensureFocus(cm);
|
5072 |
-
last = cur;
|
5073 |
-
doSelect(cur);
|
5074 |
-
var visible = visibleLines(display, doc);
|
5075 |
-
if (cur.line >= visible.to || cur.line < visible.from)
|
5076 |
-
setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
|
5077 |
-
} else {
|
5078 |
-
var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
|
5079 |
-
if (outside) setTimeout(operation(cm, function() {
|
5080 |
-
if (counter != curCount) return;
|
5081 |
-
display.scroller.scrollTop += outside;
|
5082 |
-
extend(e);
|
5083 |
-
}), 50);
|
5084 |
-
}
|
5085 |
-
}
|
5086 |
-
|
5087 |
-
function done(e) {
|
5088 |
-
counter = Infinity;
|
5089 |
-
e_preventDefault(e);
|
5090 |
-
focusInput(cm);
|
5091 |
-
off(document, "mousemove", move);
|
5092 |
-
off(document, "mouseup", up);
|
5093 |
-
}
|
5094 |
-
|
5095 |
-
var move = operation(cm, function(e) {
|
5096 |
-
if ((ie && !ie_lt10) ? !e.buttons : !e_button(e)) done(e);
|
5097 |
-
else extend(e);
|
5098 |
-
});
|
5099 |
-
var up = operation(cm, done);
|
5100 |
-
on(document, "mousemove", move);
|
5101 |
-
on(document, "mouseup", up);
|
5102 |
-
}
|
5103 |
-
|
5104 |
-
function gutterEvent(cm, e, type, prevent, signalfn) {
|
5105 |
-
try { var mX = e.clientX, mY = e.clientY; }
|
5106 |
-
catch(e) { return false; }
|
5107 |
-
if (mX >= Math.floor(getRect(cm.display.gutters).right)) return false;
|
5108 |
-
if (prevent) e_preventDefault(e);
|
5109 |
-
|
5110 |
-
var display = cm.display;
|
5111 |
-
var lineBox = getRect(display.lineDiv);
|
5112 |
-
|
5113 |
-
if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
|
5114 |
-
mY -= lineBox.top - display.viewOffset;
|
5115 |
-
|
5116 |
-
for (var i = 0; i < cm.options.gutters.length; ++i) {
|
5117 |
-
var g = display.gutters.childNodes[i];
|
5118 |
-
if (g && getRect(g).right >= mX) {
|
5119 |
-
var line = lineAtHeight(cm.doc, mY);
|
5120 |
-
var gutter = cm.options.gutters[i];
|
5121 |
-
signalfn(cm, type, cm, line, gutter, e);
|
5122 |
-
return e_defaultPrevented(e);
|
5123 |
-
}
|
5124 |
-
}
|
5125 |
-
}
|
5126 |
-
|
5127 |
-
function contextMenuInGutter(cm, e) {
|
5128 |
-
if (!hasHandler(cm, "gutterContextMenu")) return false;
|
5129 |
-
return gutterEvent(cm, e, "gutterContextMenu", false, signal);
|
5130 |
-
}
|
5131 |
-
|
5132 |
-
function clickInGutter(cm, e) {
|
5133 |
-
return gutterEvent(cm, e, "gutterClick", true, signalLater);
|
5134 |
-
}
|
5135 |
-
|
5136 |
-
// Kludge to work around strange IE behavior where it'll sometimes
|
5137 |
-
// re-fire a series of drag-related events right after the drop (#1551)
|
5138 |
-
var lastDrop = 0;
|
5139 |
-
|
5140 |
-
function onDrop(e) {
|
5141 |
-
var cm = this;
|
5142 |
-
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
|
5143 |
-
return;
|
5144 |
-
e_preventDefault(e);
|
5145 |
-
if (ie) lastDrop = +new Date;
|
5146 |
-
var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
|
5147 |
-
if (!pos || isReadOnly(cm)) return;
|
5148 |
-
if (files && files.length && window.FileReader && window.File) {
|
5149 |
-
var n = files.length, text = Array(n), read = 0;
|
5150 |
-
var loadFile = function(file, i) {
|
5151 |
-
var reader = new FileReader;
|
5152 |
-
reader.onload = function() {
|
5153 |
-
text[i] = reader.result;
|
5154 |
-
if (++read == n) {
|
5155 |
-
pos = clipPos(cm.doc, pos);
|
5156 |
-
makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around");
|
5157 |
-
}
|
5158 |
-
};
|
5159 |
-
reader.readAsText(file);
|
5160 |
-
};
|
5161 |
-
for (var i = 0; i < n; ++i) loadFile(files[i], i);
|
5162 |
-
} else {
|
5163 |
-
// Don't do a replace if the drop happened inside of the selected text.
|
5164 |
-
if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) {
|
5165 |
-
cm.state.draggingText(e);
|
5166 |
-
// Ensure the editor is re-focused
|
5167 |
-
setTimeout(bind(focusInput, cm), 20);
|
5168 |
-
return;
|
5169 |
-
}
|
5170 |
-
try {
|
5171 |
-
var text = e.dataTransfer.getData("Text");
|
5172 |
-
if (text) {
|
5173 |
-
var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
|
5174 |
-
setSelection(cm.doc, pos, pos);
|
5175 |
-
if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
|
5176 |
-
cm.replaceSelection(text, null, "paste");
|
5177 |
-
focusInput(cm);
|
5178 |
-
}
|
5179 |
-
}
|
5180 |
-
catch(e){}
|
5181 |
-
}
|
5182 |
-
}
|
5183 |
-
|
5184 |
-
function onDragStart(cm, e) {
|
5185 |
-
if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
|
5186 |
-
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
|
5187 |
-
|
5188 |
-
var txt = cm.getSelection();
|
5189 |
-
e.dataTransfer.setData("Text", txt);
|
5190 |
-
|
5191 |
-
// Use dummy image instead of default browsers image.
|
5192 |
-
// Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
|
5193 |
-
if (e.dataTransfer.setDragImage && !safari) {
|
5194 |
-
var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
|
5195 |
-
img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
5196 |
-
if (opera) {
|
5197 |
-
img.width = img.height = 1;
|
5198 |
-
cm.display.wrapper.appendChild(img);
|
5199 |
-
// Force a relayout, or Opera won't use our image for some obscure reason
|
5200 |
-
img._top = img.offsetTop;
|
5201 |
-
}
|
5202 |
-
e.dataTransfer.setDragImage(img, 0, 0);
|
5203 |
-
if (opera) img.parentNode.removeChild(img);
|
5204 |
-
}
|
5205 |
-
}
|
5206 |
-
|
5207 |
-
function setScrollTop(cm, val) {
|
5208 |
-
if (Math.abs(cm.doc.scrollTop - val) < 2) return;
|
5209 |
-
cm.doc.scrollTop = val;
|
5210 |
-
if (!gecko) updateDisplay(cm, [], val);
|
5211 |
-
if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
|
5212 |
-
if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
|
5213 |
-
if (gecko) updateDisplay(cm, []);
|
5214 |
-
startWorker(cm, 100);
|
5215 |
-
}
|
5216 |
-
function setScrollLeft(cm, val, isScroller) {
|
5217 |
-
if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
|
5218 |
-
val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
|
5219 |
-
cm.doc.scrollLeft = val;
|
5220 |
-
alignHorizontally(cm);
|
5221 |
-
if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
|
5222 |
-
if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
|
5223 |
-
}
|
5224 |
-
|
5225 |
-
// Since the delta values reported on mouse wheel events are
|
5226 |
-
// unstandardized between browsers and even browser versions, and
|
5227 |
-
// generally horribly unpredictable, this code starts by measuring
|
5228 |
-
// the scroll effect that the first few mouse wheel events have,
|
5229 |
-
// and, from that, detects the way it can convert deltas to pixel
|
5230 |
-
// offsets afterwards.
|
5231 |
-
//
|
5232 |
-
// The reason we want to know the amount a wheel event will scroll
|
5233 |
-
// is that it gives us a chance to update the display before the
|
5234 |
-
// actual scrolling happens, reducing flickering.
|
5235 |
-
|
5236 |
-
var wheelSamples = 0, wheelPixelsPerUnit = null;
|
5237 |
-
// Fill in a browser-detected starting value on browsers where we
|
5238 |
-
// know one. These don't have to be accurate -- the result of them
|
5239 |
-
// being wrong would just be a slight flicker on the first wheel
|
5240 |
-
// scroll (if it is large enough).
|
5241 |
-
if (ie) wheelPixelsPerUnit = -.53;
|
5242 |
-
else if (gecko) wheelPixelsPerUnit = 15;
|
5243 |
-
else if (chrome) wheelPixelsPerUnit = -.7;
|
5244 |
-
else if (safari) wheelPixelsPerUnit = -1/3;
|
5245 |
-
|
5246 |
-
function onScrollWheel(cm, e) {
|
5247 |
-
var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
|
5248 |
-
if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
|
5249 |
-
if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
|
5250 |
-
else if (dy == null) dy = e.wheelDelta;
|
5251 |
-
|
5252 |
-
var display = cm.display, scroll = display.scroller;
|
5253 |
-
// Quit if there's nothing to scroll here
|
5254 |
-
if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
|
5255 |
-
dy && scroll.scrollHeight > scroll.clientHeight)) return;
|
5256 |
-
|
5257 |
-
// Webkit browsers on OS X abort momentum scrolls when the target
|
5258 |
-
// of the scroll event is removed from the scrollable element.
|
5259 |
-
// This hack (see related code in patchDisplay) makes sure the
|
5260 |
-
// element is kept around.
|
5261 |
-
if (dy && mac && webkit) {
|
5262 |
-
for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
|
5263 |
-
if (cur.lineObj) {
|
5264 |
-
cm.display.currentWheelTarget = cur;
|
5265 |
-
break;
|
5266 |
-
}
|
5267 |
-
}
|
5268 |
-
}
|
5269 |
-
|
5270 |
-
// On some browsers, horizontal scrolling will cause redraws to
|
5271 |
-
// happen before the gutter has been realigned, causing it to
|
5272 |
-
// wriggle around in a most unseemly way. When we have an
|
5273 |
-
// estimated pixels/delta value, we just handle horizontal
|
5274 |
-
// scrolling entirely here. It'll be slightly off from native, but
|
5275 |
-
// better than glitching out.
|
5276 |
-
if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
|
5277 |
-
if (dy)
|
5278 |
-
setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
|
5279 |
-
setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
|
5280 |
-
e_preventDefault(e);
|
5281 |
-
display.wheelStartX = null; // Abort measurement, if in progress
|
5282 |
-
return;
|
5283 |
-
}
|
5284 |
-
|
5285 |
-
if (dy && wheelPixelsPerUnit != null) {
|
5286 |
-
var pixels = dy * wheelPixelsPerUnit;
|
5287 |
-
var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
|
5288 |
-
if (pixels < 0) top = Math.max(0, top + pixels - 50);
|
5289 |
-
else bot = Math.min(cm.doc.height, bot + pixels + 50);
|
5290 |
-
updateDisplay(cm, [], {top: top, bottom: bot});
|
5291 |
-
}
|
5292 |
-
|
5293 |
-
if (wheelSamples < 20) {
|
5294 |
-
if (display.wheelStartX == null) {
|
5295 |
-
display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
|
5296 |
-
display.wheelDX = dx; display.wheelDY = dy;
|
5297 |
-
setTimeout(function() {
|
5298 |
-
if (display.wheelStartX == null) return;
|
5299 |
-
var movedX = scroll.scrollLeft - display.wheelStartX;
|
5300 |
-
var movedY = scroll.scrollTop - display.wheelStartY;
|
5301 |
-
var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
|
5302 |
-
(movedX && display.wheelDX && movedX / display.wheelDX);
|
5303 |
-
display.wheelStartX = display.wheelStartY = null;
|
5304 |
-
if (!sample) return;
|
5305 |
-
wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
|
5306 |
-
++wheelSamples;
|
5307 |
-
}, 200);
|
5308 |
-
} else {
|
5309 |
-
display.wheelDX += dx; display.wheelDY += dy;
|
5310 |
-
}
|
5311 |
-
}
|
5312 |
-
}
|
5313 |
-
|
5314 |
-
function doHandleBinding(cm, bound, dropShift) {
|
5315 |
-
if (typeof bound == "string") {
|
5316 |
-
bound = commands[bound];
|
5317 |
-
if (!bound) return false;
|
5318 |
-
}
|
5319 |
-
// Ensure previous input has been read, so that the handler sees a
|
5320 |
-
// consistent view of the document
|
5321 |
-
if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
|
5322 |
-
var doc = cm.doc, prevShift = doc.sel.shift, done = false;
|
5323 |
-
try {
|
5324 |
-
if (isReadOnly(cm)) cm.state.suppressEdits = true;
|
5325 |
-
if (dropShift) doc.sel.shift = false;
|
5326 |
-
done = bound(cm) != Pass;
|
5327 |
-
} finally {
|
5328 |
-
doc.sel.shift = prevShift;
|
5329 |
-
cm.state.suppressEdits = false;
|
5330 |
-
}
|
5331 |
-
return done;
|
5332 |
-
}
|
5333 |
-
|
5334 |
-
function allKeyMaps(cm) {
|
5335 |
-
var maps = cm.state.keyMaps.slice(0);
|
5336 |
-
if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
|
5337 |
-
maps.push(cm.options.keyMap);
|
5338 |
-
return maps;
|
5339 |
-
}
|
5340 |
-
|
5341 |
-
var maybeTransition;
|
5342 |
-
function handleKeyBinding(cm, e) {
|
5343 |
-
// Handle auto keymap transitions
|
5344 |
-
var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
|
5345 |
-
clearTimeout(maybeTransition);
|
5346 |
-
if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
|
5347 |
-
if (getKeyMap(cm.options.keyMap) == startMap) {
|
5348 |
-
cm.options.keyMap = (next.call ? next.call(null, cm) : next);
|
5349 |
-
keyMapChanged(cm);
|
5350 |
-
}
|
5351 |
-
}, 50);
|
5352 |
-
|
5353 |
-
var name = keyName(e, true), handled = false;
|
5354 |
-
if (!name) return false;
|
5355 |
-
var keymaps = allKeyMaps(cm);
|
5356 |
-
|
5357 |
-
if (e.shiftKey) {
|
5358 |
-
// First try to resolve full name (including 'Shift-'). Failing
|
5359 |
-
// that, see if there is a cursor-motion command (starting with
|
5360 |
-
// 'go') bound to the keyname without 'Shift-'.
|
5361 |
-
handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
|
5362 |
-
|| lookupKey(name, keymaps, function(b) {
|
5363 |
-
if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
|
5364 |
-
return doHandleBinding(cm, b);
|
5365 |
-
});
|
5366 |
-
} else {
|
5367 |
-
handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
|
5368 |
-
}
|
5369 |
-
|
5370 |
-
if (handled) {
|
5371 |
-
e_preventDefault(e);
|
5372 |
-
restartBlink(cm);
|
5373 |
-
if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
|
5374 |
-
signalLater(cm, "keyHandled", cm, name, e);
|
5375 |
-
}
|
5376 |
-
return handled;
|
5377 |
-
}
|
5378 |
-
|
5379 |
-
function handleCharBinding(cm, e, ch) {
|
5380 |
-
var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
|
5381 |
-
function(b) { return doHandleBinding(cm, b, true); });
|
5382 |
-
if (handled) {
|
5383 |
-
e_preventDefault(e);
|
5384 |
-
restartBlink(cm);
|
5385 |
-
signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
|
5386 |
-
}
|
5387 |
-
return handled;
|
5388 |
-
}
|
5389 |
-
|
5390 |
-
function onKeyUp(e) {
|
5391 |
-
var cm = this;
|
5392 |
-
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
|
5393 |
-
if (e.keyCode == 16) cm.doc.sel.shift = false;
|
5394 |
-
}
|
5395 |
-
|
5396 |
-
var lastStoppedKey = null;
|
5397 |
-
function onKeyDown(e) {
|
5398 |
-
var cm = this;
|
5399 |
-
ensureFocus(cm);
|
5400 |
-
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
|
5401 |
-
if (old_ie && e.keyCode == 27) e.returnValue = false;
|
5402 |
-
var code = e.keyCode;
|
5403 |
-
// IE does strange things with escape.
|
5404 |
-
cm.doc.sel.shift = code == 16 || e.shiftKey;
|
5405 |
-
// First give onKeyEvent option a chance to handle this.
|
5406 |
-
var handled = handleKeyBinding(cm, e);
|
5407 |
-
if (opera) {
|
5408 |
-
lastStoppedKey = handled ? code : null;
|
5409 |
-
// Opera has no cut event... we try to at least catch the key combo
|
5410 |
-
if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
|
5411 |
-
cm.replaceSelection("");
|
5412 |
-
}
|
5413 |
-
}
|
5414 |
-
|
5415 |
-
function onKeyPress(e) {
|
5416 |
-
var cm = this;
|
5417 |
-
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
|
5418 |
-
var keyCode = e.keyCode, charCode = e.charCode;
|
5419 |
-
if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
|
5420 |
-
if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
|
5421 |
-
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
|
5422 |
-
if (handleCharBinding(cm, e, ch)) return;
|
5423 |
-
if (ie && !ie_lt9) cm.display.inputHasSelection = null;
|
5424 |
-
fastPoll(cm);
|
5425 |
-
}
|
5426 |
-
|
5427 |
-
function onFocus(cm) {
|
5428 |
-
if (cm.options.readOnly == "nocursor") return;
|
5429 |
-
if (!cm.state.focused) {
|
5430 |
-
signal(cm, "focus", cm);
|
5431 |
-
cm.state.focused = true;
|
5432 |
-
if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
|
5433 |
-
cm.display.wrapper.className += " CodeMirror-focused";
|
5434 |
-
if (!cm.curOp) {
|
5435 |
-
resetInput(cm, true);
|
5436 |
-
if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
|
5437 |
-
}
|
5438 |
-
}
|
5439 |
-
slowPoll(cm);
|
5440 |
-
restartBlink(cm);
|
5441 |
-
}
|
5442 |
-
function onBlur(cm) {
|
5443 |
-
if (cm.state.focused) {
|
5444 |
-
signal(cm, "blur", cm);
|
5445 |
-
cm.state.focused = false;
|
5446 |
-
cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
|
5447 |
-
}
|
5448 |
-
clearInterval(cm.display.blinker);
|
5449 |
-
setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150);
|
5450 |
-
}
|
5451 |
-
|
5452 |
-
var detectingSelectAll;
|
5453 |
-
function onContextMenu(cm, e) {
|
5454 |
-
if (signalDOMEvent(cm, e, "contextmenu")) return;
|
5455 |
-
var display = cm.display, sel = cm.doc.sel;
|
5456 |
-
if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;
|
5457 |
-
|
5458 |
-
var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
|
5459 |
-
if (!pos || opera) return; // Opera is difficult.
|
5460 |
-
|
5461 |
-
// Reset the current text selection only if the click is done outside of the selection
|
5462 |
-
// and 'resetSelectionOnContextMenu' option is true.
|
5463 |
-
var reset = cm.options.resetSelectionOnContextMenu;
|
5464 |
-
if (reset && (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to)))
|
5465 |
-
operation(cm, setSelection)(cm.doc, pos, pos);
|
5466 |
-
|
5467 |
-
var oldCSS = display.input.style.cssText;
|
5468 |
-
display.inputDiv.style.position = "absolute";
|
5469 |
-
display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
|
5470 |
-
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: transparent; outline: none;" +
|
5471 |
-
"border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
|
5472 |
-
focusInput(cm);
|
5473 |
-
resetInput(cm, true);
|
5474 |
-
// Adds "Select all" to context menu in FF
|
5475 |
-
if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
|
5476 |
-
|
5477 |
-
function prepareSelectAllHack() {
|
5478 |
-
if (display.input.selectionStart != null) {
|
5479 |
-
var extval = display.input.value = "\u200b" + (posEq(sel.from, sel.to) ? "" : display.input.value);
|
5480 |
-
display.prevInput = "\u200b";
|
5481 |
-
display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
|
5482 |
-
}
|
5483 |
-
}
|
5484 |
-
function rehide() {
|
5485 |
-
display.inputDiv.style.position = "relative";
|
5486 |
-
display.input.style.cssText = oldCSS;
|
5487 |
-
if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
|
5488 |
-
slowPoll(cm);
|
5489 |
-
|
5490 |
-
// Try to detect the user choosing select-all
|
5491 |
-
if (display.input.selectionStart != null) {
|
5492 |
-
if (!ie || ie_lt9) prepareSelectAllHack();
|
5493 |
-
clearTimeout(detectingSelectAll);
|
5494 |
-
var i = 0, poll = function(){
|
5495 |
-
if (display.prevInput == "\u200b" && display.input.selectionStart == 0)
|
5496 |
-
operation(cm, commands.selectAll)(cm);
|
5497 |
-
else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
|
5498 |
-
else resetInput(cm);
|
5499 |
-
};
|
5500 |
-
detectingSelectAll = setTimeout(poll, 200);
|
5501 |
-
}
|
5502 |
-
}
|
5503 |
-
|
5504 |
-
if (ie && !ie_lt9) prepareSelectAllHack();
|
5505 |
-
if (captureMiddleClick) {
|
5506 |
-
e_stop(e);
|
5507 |
-
var mouseup = function() {
|
5508 |
-
off(window, "mouseup", mouseup);
|
5509 |
-
setTimeout(rehide, 20);
|
5510 |
-
};
|
5511 |
-
on(window, "mouseup", mouseup);
|
5512 |
-
} else {
|
5513 |
-
setTimeout(rehide, 50);
|
5514 |
-
}
|
5515 |
-
}
|
5516 |
-
|
5517 |
-
// UPDATING
|
5518 |
-
|
5519 |
-
var changeEnd = CodeMirror.changeEnd = function(change) {
|
5520 |
-
if (!change.text) return change.to;
|
5521 |
-
return Pos(change.from.line + change.text.length - 1,
|
5522 |
-
lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
|
5523 |
-
};
|
5524 |
-
|
5525 |
-
// Make sure a position will be valid after the given change.
|
5526 |
-
function clipPostChange(doc, change, pos) {
|
5527 |
-
if (!posLess(change.from, pos)) return clipPos(doc, pos);
|
5528 |
-
var diff = (change.text.length - 1) - (change.to.line - change.from.line);
|
5529 |
-
if (pos.line > change.to.line + diff) {
|
5530 |
-
var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1;
|
5531 |
-
if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length);
|
5532 |
-
return clipToLen(pos, getLine(doc, preLine).text.length);
|
5533 |
-
}
|
5534 |
-
if (pos.line == change.to.line + diff)
|
5535 |
-
return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) +
|
5536 |
-
getLine(doc, change.to.line).text.length - change.to.ch);
|
5537 |
-
var inside = pos.line - change.from.line;
|
5538 |
-
return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch));
|
5539 |
-
}
|
5540 |
-
|
5541 |
-
// Hint can be null|"end"|"start"|"around"|{anchor,head}
|
5542 |
-
function computeSelAfterChange(doc, change, hint) {
|
5543 |
-
if (hint && typeof hint == "object") // Assumed to be {anchor, head} object
|
5544 |
-
return {anchor: clipPostChange(doc, change, hint.anchor),
|
5545 |
-
head: clipPostChange(doc, change, hint.head)};
|
5546 |
-
|
5547 |
-
if (hint == "start") return {anchor: change.from, head: change.from};
|
5548 |
-
|
5549 |
-
var end = changeEnd(change);
|
5550 |
-
if (hint == "around") return {anchor: change.from, head: end};
|
5551 |
-
if (hint == "end") return {anchor: end, head: end};
|
5552 |
-
|
5553 |
-
// hint is null, leave the selection alone as much as possible
|
5554 |
-
var adjustPos = function(pos) {
|
5555 |
-
if (posLess(pos, change.from)) return pos;
|
5556 |
-
if (!posLess(change.to, pos)) return end;
|
5557 |
-
|
5558 |
-
var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
|
5559 |
-
if (pos.line == change.to.line) ch += end.ch - change.to.ch;
|
5560 |
-
return Pos(line, ch);
|
5561 |
-
};
|
5562 |
-
return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)};
|
5563 |
-
}
|
5564 |
-
|
5565 |
-
function filterChange(doc, change, update) {
|
5566 |
-
var obj = {
|
5567 |
-
canceled: false,
|
5568 |
-
from: change.from,
|
5569 |
-
to: change.to,
|
5570 |
-
text: change.text,
|
5571 |
-
origin: change.origin,
|
5572 |
-
cancel: function() { this.canceled = true; }
|
5573 |
-
};
|
5574 |
-
if (update) obj.update = function(from, to, text, origin) {
|
5575 |
-
if (from) this.from = clipPos(doc, from);
|
5576 |
-
if (to) this.to = clipPos(doc, to);
|
5577 |
-
if (text) this.text = text;
|
5578 |
-
if (origin !== undefined) this.origin = origin;
|
5579 |
-
};
|
5580 |
-
signal(doc, "beforeChange", doc, obj);
|
5581 |
-
if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
|
5582 |
-
|
5583 |
-
if (obj.canceled) return null;
|
5584 |
-
return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
|
5585 |
-
}
|
5586 |
-
|
5587 |
-
// Replace the range from from to to by the strings in replacement.
|
5588 |
-
// change is a {from, to, text [, origin]} object
|
5589 |
-
function makeChange(doc, change, selUpdate, ignoreReadOnly) {
|
5590 |
-
if (doc.cm) {
|
5591 |
-
if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly);
|
5592 |
-
if (doc.cm.state.suppressEdits) return;
|
5593 |
-
}
|
5594 |
-
|
5595 |
-
if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
|
5596 |
-
change = filterChange(doc, change, true);
|
5597 |
-
if (!change) return;
|
5598 |
-
}
|
5599 |
-
|
5600 |
-
// Possibly split or suppress the update based on the presence
|
5601 |
-
// of read-only spans in its range.
|
5602 |
-
var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
|
5603 |
-
if (split) {
|
5604 |
-
for (var i = split.length - 1; i >= 1; --i)
|
5605 |
-
makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]});
|
5606 |
-
if (split.length)
|
5607 |
-
makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate);
|
5608 |
-
} else {
|
5609 |
-
makeChangeNoReadonly(doc, change, selUpdate);
|
5610 |
-
}
|
5611 |
-
}
|
5612 |
-
|
5613 |
-
function makeChangeNoReadonly(doc, change, selUpdate) {
|
5614 |
-
if (change.text.length == 1 && change.text[0] == "" && posEq(change.from, change.to)) return;
|
5615 |
-
var selAfter = computeSelAfterChange(doc, change, selUpdate);
|
5616 |
-
addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
|
5617 |
-
|
5618 |
-
makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
|
5619 |
-
var rebased = [];
|
5620 |
-
|
5621 |
-
linkedDocs(doc, function(doc, sharedHist) {
|
5622 |
-
if (!sharedHist && indexOf(rebased, doc.history) == -1) {
|
5623 |
-
rebaseHist(doc.history, change);
|
5624 |
-
rebased.push(doc.history);
|
5625 |
-
}
|
5626 |
-
makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
|
5627 |
-
});
|
5628 |
-
}
|
5629 |
-
|
5630 |
-
function makeChangeFromHistory(doc, type) {
|
5631 |
-
if (doc.cm && doc.cm.state.suppressEdits) return;
|
5632 |
-
|
5633 |
-
var hist = doc.history;
|
5634 |
-
var event = (type == "undo" ? hist.done : hist.undone).pop();
|
5635 |
-
if (!event) return;
|
5636 |
-
|
5637 |
-
var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
|
5638 |
-
anchorAfter: event.anchorBefore, headAfter: event.headBefore,
|
5639 |
-
generation: hist.generation};
|
5640 |
-
(type == "undo" ? hist.undone : hist.done).push(anti);
|
5641 |
-
hist.generation = event.generation || ++hist.maxGeneration;
|
5642 |
-
|
5643 |
-
var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
|
5644 |
-
|
5645 |
-
for (var i = event.changes.length - 1; i >= 0; --i) {
|
5646 |
-
var change = event.changes[i];
|
5647 |
-
change.origin = type;
|
5648 |
-
if (filter && !filterChange(doc, change, false)) {
|
5649 |
-
(type == "undo" ? hist.done : hist.undone).length = 0;
|
5650 |
-
return;
|
5651 |
-
}
|
5652 |
-
|
5653 |
-
anti.changes.push(historyChangeFromChange(doc, change));
|
5654 |
-
|
5655 |
-
var after = i ? computeSelAfterChange(doc, change, null)
|
5656 |
-
: {anchor: event.anchorBefore, head: event.headBefore};
|
5657 |
-
makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
|
5658 |
-
var rebased = [];
|
5659 |
-
|
5660 |
-
linkedDocs(doc, function(doc, sharedHist) {
|
5661 |
-
if (!sharedHist && indexOf(rebased, doc.history) == -1) {
|
5662 |
-
rebaseHist(doc.history, change);
|
5663 |
-
rebased.push(doc.history);
|
5664 |
-
}
|
5665 |
-
makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
|
5666 |
-
});
|
5667 |
-
}
|
5668 |
-
}
|
5669 |
-
|
5670 |
-
function shiftDoc(doc, distance) {
|
5671 |
-
function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);}
|
5672 |
-
doc.first += distance;
|
5673 |
-
if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance);
|
5674 |
-
doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor);
|
5675 |
-
doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to);
|
5676 |
-
}
|
5677 |
-
|
5678 |
-
function makeChangeSingleDoc(doc, change, selAfter, spans) {
|
5679 |
-
if (doc.cm && !doc.cm.curOp)
|
5680 |
-
return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
|
5681 |
-
|
5682 |
-
if (change.to.line < doc.first) {
|
5683 |
-
shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
|
5684 |
-
return;
|
5685 |
-
}
|
5686 |
-
if (change.from.line > doc.lastLine()) return;
|
5687 |
-
|
5688 |
-
// Clip the change to the size of this doc
|
5689 |
-
if (change.from.line < doc.first) {
|
5690 |
-
var shift = change.text.length - 1 - (doc.first - change.from.line);
|
5691 |
-
shiftDoc(doc, shift);
|
5692 |
-
change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
|
5693 |
-
text: [lst(change.text)], origin: change.origin};
|
5694 |
-
}
|
5695 |
-
var last = doc.lastLine();
|
5696 |
-
if (change.to.line > last) {
|
5697 |
-
change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
|
5698 |
-
text: [change.text[0]], origin: change.origin};
|
5699 |
-
}
|
5700 |
-
|
5701 |
-
change.removed = getBetween(doc, change.from, change.to);
|
5702 |
-
|
5703 |
-
if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
|
5704 |
-
if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter);
|
5705 |
-
else updateDoc(doc, change, spans, selAfter);
|
5706 |
-
}
|
5707 |
-
|
5708 |
-
function makeChangeSingleDocInEditor(cm, change, spans, selAfter) {
|
5709 |
-
var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
|
5710 |
-
|
5711 |
-
var recomputeMaxLength = false, checkWidthStart = from.line;
|
5712 |
-
if (!cm.options.lineWrapping) {
|
5713 |
-
checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line)));
|
5714 |
-
doc.iter(checkWidthStart, to.line + 1, function(line) {
|
5715 |
-
if (line == display.maxLine) {
|
5716 |
-
recomputeMaxLength = true;
|
5717 |
-
return true;
|
5718 |
-
}
|
5719 |
-
});
|
5720 |
-
}
|
5721 |
-
|
5722 |
-
if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head))
|
5723 |
-
cm.curOp.cursorActivity = true;
|
5724 |
-
|
5725 |
-
updateDoc(doc, change, spans, selAfter, estimateHeight(cm));
|
5726 |
-
|
5727 |
-
if (!cm.options.lineWrapping) {
|
5728 |
-
doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
|
5729 |
-
var len = lineLength(doc, line);
|
5730 |
-
if (len > display.maxLineLength) {
|
5731 |
-
display.maxLine = line;
|
5732 |
-
display.maxLineLength = len;
|
5733 |
-
display.maxLineChanged = true;
|
5734 |
-
recomputeMaxLength = false;
|
5735 |
-
}
|
5736 |
-
});
|
5737 |
-
if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
|
5738 |
-
}
|
5739 |
-
|
5740 |
-
// Adjust frontier, schedule worker
|
5741 |
-
doc.frontier = Math.min(doc.frontier, from.line);
|
5742 |
-
startWorker(cm, 400);
|
5743 |
-
|
5744 |
-
var lendiff = change.text.length - (to.line - from.line) - 1;
|
5745 |
-
// Remember that these lines changed, for updating the display
|
5746 |
-
regChange(cm, from.line, to.line + 1, lendiff);
|
5747 |
-
|
5748 |
-
if (hasHandler(cm, "change")) {
|
5749 |
-
var changeObj = {from: from, to: to,
|
5750 |
-
text: change.text,
|
5751 |
-
removed: change.removed,
|
5752 |
-
origin: change.origin};
|
5753 |
-
if (cm.curOp.textChanged) {
|
5754 |
-
for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
|
5755 |
-
cur.next = changeObj;
|
5756 |
-
} else cm.curOp.textChanged = changeObj;
|
5757 |
-
}
|
5758 |
-
}
|
5759 |
-
|
5760 |
-
function replaceRange(doc, code, from, to, origin) {
|
5761 |
-
if (!to) to = from;
|
5762 |
-
if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
|
5763 |
-
if (typeof code == "string") code = splitLines(code);
|
5764 |
-
makeChange(doc, {from: from, to: to, text: code, origin: origin}, null);
|
5765 |
-
}
|
5766 |
-
|
5767 |
-
// POSITION OBJECT
|
5768 |
-
|
5769 |
-
function Pos(line, ch) {
|
5770 |
-
if (!(this instanceof Pos)) return new Pos(line, ch);
|
5771 |
-
this.line = line; this.ch = ch;
|
5772 |
-
}
|
5773 |
-
CodeMirror.Pos = Pos;
|
5774 |
-
|
5775 |
-
function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
|
5776 |
-
function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
|
5777 |
-
function cmp(a, b) {return a.line - b.line || a.ch - b.ch;}
|
5778 |
-
function copyPos(x) {return Pos(x.line, x.ch);}
|
5779 |
-
|
5780 |
-
// SELECTION
|
5781 |
-
|
5782 |
-
function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
|
5783 |
-
function clipPos(doc, pos) {
|
5784 |
-
if (pos.line < doc.first) return Pos(doc.first, 0);
|
5785 |
-
var last = doc.first + doc.size - 1;
|
5786 |
-
if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
|
5787 |
-
return clipToLen(pos, getLine(doc, pos.line).text.length);
|
5788 |
-
}
|
5789 |
-
function clipToLen(pos, linelen) {
|
5790 |
-
var ch = pos.ch;
|
5791 |
-
if (ch == null || ch > linelen) return Pos(pos.line, linelen);
|
5792 |
-
else if (ch < 0) return Pos(pos.line, 0);
|
5793 |
-
else return pos;
|
5794 |
-
}
|
5795 |
-
function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
|
5796 |
-
|
5797 |
-
// If shift is held, this will move the selection anchor. Otherwise,
|
5798 |
-
// it'll set the whole selection.
|
5799 |
-
function extendSelection(doc, pos, other, bias) {
|
5800 |
-
if (doc.sel.shift || doc.sel.extend) {
|
5801 |
-
var anchor = doc.sel.anchor;
|
5802 |
-
if (other) {
|
5803 |
-
var posBefore = posLess(pos, anchor);
|
5804 |
-
if (posBefore != posLess(other, anchor)) {
|
5805 |
-
anchor = pos;
|
5806 |
-
pos = other;
|
5807 |
-
} else if (posBefore != posLess(pos, other)) {
|
5808 |
-
pos = other;
|
5809 |
-
}
|
5810 |
-
}
|
5811 |
-
setSelection(doc, anchor, pos, bias);
|
5812 |
-
} else {
|
5813 |
-
setSelection(doc, pos, other || pos, bias);
|
5814 |
-
}
|
5815 |
-
if (doc.cm) doc.cm.curOp.userSelChange = true;
|
5816 |
-
}
|
5817 |
-
|
5818 |
-
function filterSelectionChange(doc, anchor, head) {
|
5819 |
-
var obj = {anchor: anchor, head: head};
|
5820 |
-
signal(doc, "beforeSelectionChange", doc, obj);
|
5821 |
-
if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
|
5822 |
-
obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head);
|
5823 |
-
return obj;
|
5824 |
-
}
|
5825 |
-
|
5826 |
-
// Update the selection. Last two args are only used by
|
5827 |
-
// updateDoc, since they have to be expressed in the line
|
5828 |
-
// numbers before the update.
|
5829 |
-
function setSelection(doc, anchor, head, bias, checkAtomic) {
|
5830 |
-
if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) {
|
5831 |
-
var filtered = filterSelectionChange(doc, anchor, head);
|
5832 |
-
head = filtered.head;
|
5833 |
-
anchor = filtered.anchor;
|
5834 |
-
}
|
5835 |
-
|
5836 |
-
var sel = doc.sel;
|
5837 |
-
sel.goalColumn = null;
|
5838 |
-
if (bias == null) bias = posLess(head, sel.head) ? -1 : 1;
|
5839 |
-
// Skip over atomic spans.
|
5840 |
-
if (checkAtomic || !posEq(anchor, sel.anchor))
|
5841 |
-
anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
|
5842 |
-
if (checkAtomic || !posEq(head, sel.head))
|
5843 |
-
head = skipAtomic(doc, head, bias, checkAtomic != "push");
|
5844 |
-
|
5845 |
-
if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;
|
5846 |
-
|
5847 |
-
sel.anchor = anchor; sel.head = head;
|
5848 |
-
var inv = posLess(head, anchor);
|
5849 |
-
sel.from = inv ? head : anchor;
|
5850 |
-
sel.to = inv ? anchor : head;
|
5851 |
-
|
5852 |
-
if (doc.cm)
|
5853 |
-
doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
|
5854 |
-
doc.cm.curOp.cursorActivity = true;
|
5855 |
-
|
5856 |
-
signalLater(doc, "cursorActivity", doc);
|
5857 |
-
}
|
5858 |
-
|
5859 |
-
function reCheckSelection(cm) {
|
5860 |
-
setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push");
|
5861 |
-
}
|
5862 |
-
|
5863 |
-
function skipAtomic(doc, pos, bias, mayClear) {
|
5864 |
-
var flipped = false, curPos = pos;
|
5865 |
-
var dir = bias || 1;
|
5866 |
-
doc.cantEdit = false;
|
5867 |
-
search: for (;;) {
|
5868 |
-
var line = getLine(doc, curPos.line);
|
5869 |
-
if (line.markedSpans) {
|
5870 |
-
for (var i = 0; i < line.markedSpans.length; ++i) {
|
5871 |
-
var sp = line.markedSpans[i], m = sp.marker;
|
5872 |
-
if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
|
5873 |
-
(sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
|
5874 |
-
if (mayClear) {
|
5875 |
-
signal(m, "beforeCursorEnter");
|
5876 |
-
if (m.explicitlyCleared) {
|
5877 |
-
if (!line.markedSpans) break;
|
5878 |
-
else {--i; continue;}
|
5879 |
-
}
|
5880 |
-
}
|
5881 |
-
if (!m.atomic) continue;
|
5882 |
-
var newPos = m.find()[dir < 0 ? "from" : "to"];
|
5883 |
-
if (posEq(newPos, curPos)) {
|
5884 |
-
newPos.ch += dir;
|
5885 |
-
if (newPos.ch < 0) {
|
5886 |
-
if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
|
5887 |
-
else newPos = null;
|
5888 |
-
} else if (newPos.ch > line.text.length) {
|
5889 |
-
if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
|
5890 |
-
else newPos = null;
|
5891 |
-
}
|
5892 |
-
if (!newPos) {
|
5893 |
-
if (flipped) {
|
5894 |
-
// Driven in a corner -- no valid cursor position found at all
|
5895 |
-
// -- try again *with* clearing, if we didn't already
|
5896 |
-
if (!mayClear) return skipAtomic(doc, pos, bias, true);
|
5897 |
-
// Otherwise, turn off editing until further notice, and return the start of the doc
|
5898 |
-
doc.cantEdit = true;
|
5899 |
-
return Pos(doc.first, 0);
|
5900 |
-
}
|
5901 |
-
flipped = true; newPos = pos; dir = -dir;
|
5902 |
-
}
|
5903 |
-
}
|
5904 |
-
curPos = newPos;
|
5905 |
-
continue search;
|
5906 |
-
}
|
5907 |
-
}
|
5908 |
-
}
|
5909 |
-
return curPos;
|
5910 |
-
}
|
5911 |
-
}
|
5912 |
-
|
5913 |
-
// SCROLLING
|
5914 |
-
|
5915 |
-
function scrollCursorIntoView(cm) {
|
5916 |
-
var coords = scrollPosIntoView(cm, cm.doc.sel.head, null, cm.options.cursorScrollMargin);
|
5917 |
-
if (!cm.state.focused) return;
|
5918 |
-
var display = cm.display, box = getRect(display.sizer), doScroll = null;
|
5919 |
-
if (coords.top + box.top < 0) doScroll = true;
|
5920 |
-
else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
|
5921 |
-
if (doScroll != null && !phantom) {
|
5922 |
-
var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
|
5923 |
-
(coords.top - display.viewOffset) + "px; height: " +
|
5924 |
-
(coords.bottom - coords.top + scrollerCutOff) + "px; left: " +
|
5925 |
-
coords.left + "px; width: 2px;");
|
5926 |
-
cm.display.lineSpace.appendChild(scrollNode);
|
5927 |
-
scrollNode.scrollIntoView(doScroll);
|
5928 |
-
cm.display.lineSpace.removeChild(scrollNode);
|
5929 |
-
}
|
5930 |
-
}
|
5931 |
-
|
5932 |
-
function scrollPosIntoView(cm, pos, end, margin) {
|
5933 |
-
if (margin == null) margin = 0;
|
5934 |
-
for (;;) {
|
5935 |
-
var changed = false, coords = cursorCoords(cm, pos);
|
5936 |
-
var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
|
5937 |
-
var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
|
5938 |
-
Math.min(coords.top, endCoords.top) - margin,
|
5939 |
-
Math.max(coords.left, endCoords.left),
|
5940 |
-
Math.max(coords.bottom, endCoords.bottom) + margin);
|
5941 |
-
var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
|
5942 |
-
if (scrollPos.scrollTop != null) {
|
5943 |
-
setScrollTop(cm, scrollPos.scrollTop);
|
5944 |
-
if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
|
5945 |
-
}
|
5946 |
-
if (scrollPos.scrollLeft != null) {
|
5947 |
-
setScrollLeft(cm, scrollPos.scrollLeft);
|
5948 |
-
if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
|
5949 |
-
}
|
5950 |
-
if (!changed) return coords;
|
5951 |
-
}
|
5952 |
-
}
|
5953 |
-
|
5954 |
-
function scrollIntoView(cm, x1, y1, x2, y2) {
|
5955 |
-
var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
|
5956 |
-
if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
|
5957 |
-
if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
|
5958 |
-
}
|
5959 |
-
|
5960 |
-
function calculateScrollPos(cm, x1, y1, x2, y2) {
|
5961 |
-
var display = cm.display, snapMargin = textHeight(cm.display);
|
5962 |
-
if (y1 < 0) y1 = 0;
|
5963 |
-
var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
|
5964 |
-
var docBottom = cm.doc.height + paddingVert(display);
|
5965 |
-
var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
|
5966 |
-
if (y1 < screentop) {
|
5967 |
-
result.scrollTop = atTop ? 0 : y1;
|
5968 |
-
} else if (y2 > screentop + screen) {
|
5969 |
-
var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
|
5970 |
-
if (newTop != screentop) result.scrollTop = newTop;
|
5971 |
-
}
|
5972 |
-
|
5973 |
-
var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
|
5974 |
-
x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
|
5975 |
-
var gutterw = display.gutters.offsetWidth;
|
5976 |
-
var atLeft = x1 < gutterw + 10;
|
5977 |
-
if (x1 < screenleft + gutterw || atLeft) {
|
5978 |
-
if (atLeft) x1 = 0;
|
5979 |
-
result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
|
5980 |
-
} else if (x2 > screenw + screenleft - 3) {
|
5981 |
-
result.scrollLeft = x2 + 10 - screenw;
|
5982 |
-
}
|
5983 |
-
return result;
|
5984 |
-
}
|
5985 |
-
|
5986 |
-
function updateScrollPos(cm, left, top) {
|
5987 |
-
cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left,
|
5988 |
-
scrollTop: top == null ? cm.doc.scrollTop : top};
|
5989 |
-
}
|
5990 |
-
|
5991 |
-
function addToScrollPos(cm, left, top) {
|
5992 |
-
var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop});
|
5993 |
-
var scroll = cm.display.scroller;
|
5994 |
-
pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top));
|
5995 |
-
pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left));
|
5996 |
-
}
|
5997 |
-
|
5998 |
-
// API UTILITIES
|
5999 |
-
|
6000 |
-
function indentLine(cm, n, how, aggressive) {
|
6001 |
-
var doc = cm.doc, state;
|
6002 |
-
if (how == null) how = "add";
|
6003 |
-
if (how == "smart") {
|
6004 |
-
if (!cm.doc.mode.indent) how = "prev";
|
6005 |
-
else state = getStateBefore(cm, n);
|
6006 |
-
}
|
6007 |
-
|
6008 |
-
var tabSize = cm.options.tabSize;
|
6009 |
-
var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
|
6010 |
-
if (line.stateAfter) line.stateAfter = null;
|
6011 |
-
var curSpaceString = line.text.match(/^\s*/)[0], indentation;
|
6012 |
-
if (!aggressive && !/\S/.test(line.text)) {
|
6013 |
-
indentation = 0;
|
6014 |
-
how = "not";
|
6015 |
-
} else if (how == "smart") {
|
6016 |
-
indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
|
6017 |
-
if (indentation == Pass) {
|
6018 |
-
if (!aggressive) return;
|
6019 |
-
how = "prev";
|
6020 |
-
}
|
6021 |
-
}
|
6022 |
-
if (how == "prev") {
|
6023 |
-
if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
|
6024 |
-
else indentation = 0;
|
6025 |
-
} else if (how == "add") {
|
6026 |
-
indentation = curSpace + cm.options.indentUnit;
|
6027 |
-
} else if (how == "subtract") {
|
6028 |
-
indentation = curSpace - cm.options.indentUnit;
|
6029 |
-
} else if (typeof how == "number") {
|
6030 |
-
indentation = curSpace + how;
|
6031 |
-
}
|
6032 |
-
indentation = Math.max(0, indentation);
|
6033 |
-
|
6034 |
-
var indentString = "", pos = 0;
|
6035 |
-
if (cm.options.indentWithTabs)
|
6036 |
-
for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
|
6037 |
-
if (pos < indentation) indentString += spaceStr(indentation - pos);
|
6038 |
-
|
6039 |
-
if (indentString != curSpaceString)
|
6040 |
-
replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
|
6041 |
-
else if (doc.sel.head.line == n && doc.sel.head.ch < curSpaceString.length)
|
6042 |
-
setSelection(doc, Pos(n, curSpaceString.length), Pos(n, curSpaceString.length), 1);
|
6043 |
-
line.stateAfter = null;
|
6044 |
-
}
|
6045 |
-
|
6046 |
-
function changeLine(cm, handle, op) {
|
6047 |
-
var no = handle, line = handle, doc = cm.doc;
|
6048 |
-
if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
|
6049 |
-
else no = lineNo(handle);
|
6050 |
-
if (no == null) return null;
|
6051 |
-
if (op(line, no)) regChange(cm, no, no + 1);
|
6052 |
-
else return null;
|
6053 |
-
return line;
|
6054 |
-
}
|
6055 |
-
|
6056 |
-
function findPosH(doc, pos, dir, unit, visually) {
|
6057 |
-
var line = pos.line, ch = pos.ch, origDir = dir;
|
6058 |
-
var lineObj = getLine(doc, line);
|
6059 |
-
var possible = true;
|
6060 |
-
function findNextLine() {
|
6061 |
-
var l = line + dir;
|
6062 |
-
if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
|
6063 |
-
line = l;
|
6064 |
-
return lineObj = getLine(doc, l);
|
6065 |
-
}
|
6066 |
-
function moveOnce(boundToLine) {
|
6067 |
-
var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
|
6068 |
-
if (next == null) {
|
6069 |
-
if (!boundToLine && findNextLine()) {
|
6070 |
-
if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
|
6071 |
-
else ch = dir < 0 ? lineObj.text.length : 0;
|
6072 |
-
} else return (possible = false);
|
6073 |
-
} else ch = next;
|
6074 |
-
return true;
|
6075 |
-
}
|
6076 |
-
|
6077 |
-
if (unit == "char") moveOnce();
|
6078 |
-
else if (unit == "column") moveOnce(true);
|
6079 |
-
else if (unit == "word" || unit == "group") {
|
6080 |
-
var sawType = null, group = unit == "group";
|
6081 |
-
for (var first = true;; first = false) {
|
6082 |
-
if (dir < 0 && !moveOnce(!first)) break;
|
6083 |
-
var cur = lineObj.text.charAt(ch) || "\n";
|
6084 |
-
var type = isWordChar(cur) ? "w"
|
6085 |
-
: group && cur == "\n" ? "n"
|
6086 |
-
: !group || /\s/.test(cur) ? null
|
6087 |
-
: "p";
|
6088 |
-
if (group && !first && !type) type = "s";
|
6089 |
-
if (sawType && sawType != type) {
|
6090 |
-
if (dir < 0) {dir = 1; moveOnce();}
|
6091 |
-
break;
|
6092 |
-
}
|
6093 |
-
|
6094 |
-
if (type) sawType = type;
|
6095 |
-
if (dir > 0 && !moveOnce(!first)) break;
|
6096 |
-
}
|
6097 |
-
}
|
6098 |
-
var result = skipAtomic(doc, Pos(line, ch), origDir, true);
|
6099 |
-
if (!possible) result.hitSide = true;
|
6100 |
-
return result;
|
6101 |
-
}
|
6102 |
-
|
6103 |
-
function findPosV(cm, pos, dir, unit) {
|
6104 |
-
var doc = cm.doc, x = pos.left, y;
|
6105 |
-
if (unit == "page") {
|
6106 |
-
var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
|
6107 |
-
y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
|
6108 |
-
} else if (unit == "line") {
|
6109 |
-
y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
|
6110 |
-
}
|
6111 |
-
for (;;) {
|
6112 |
-
var target = coordsChar(cm, x, y);
|
6113 |
-
if (!target.outside) break;
|
6114 |
-
if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
|
6115 |
-
y += dir * 5;
|
6116 |
-
}
|
6117 |
-
return target;
|
6118 |
-
}
|
6119 |
-
|
6120 |
-
function findWordAt(line, pos) {
|
6121 |
-
var start = pos.ch, end = pos.ch;
|
6122 |
-
if (line) {
|
6123 |
-
if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
|
6124 |
-
var startChar = line.charAt(start);
|
6125 |
-
var check = isWordChar(startChar) ? isWordChar
|
6126 |
-
: /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
|
6127 |
-
: function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
|
6128 |
-
while (start > 0 && check(line.charAt(start - 1))) --start;
|
6129 |
-
while (end < line.length && check(line.charAt(end))) ++end;
|
6130 |
-
}
|
6131 |
-
return {from: Pos(pos.line, start), to: Pos(pos.line, end)};
|
6132 |
-
}
|
6133 |
-
|
6134 |
-
function selectLine(cm, line) {
|
6135 |
-
extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0)));
|
6136 |
-
}
|
6137 |
-
|
6138 |
-
// PROTOTYPE
|
6139 |
-
|
6140 |
-
// The publicly visible API. Note that operation(null, f) means
|
6141 |
-
// 'wrap f in an operation, performed on its `this` parameter'
|
6142 |
-
|
6143 |
-
CodeMirror.prototype = {
|
6144 |
-
constructor: CodeMirror,
|
6145 |
-
focus: function(){window.focus(); focusInput(this); fastPoll(this);},
|
6146 |
-
|
6147 |
-
setOption: function(option, value) {
|
6148 |
-
var options = this.options, old = options[option];
|
6149 |
-
if (options[option] == value && option != "mode") return;
|
6150 |
-
options[option] = value;
|
6151 |
-
if (optionHandlers.hasOwnProperty(option))
|
6152 |
-
operation(this, optionHandlers[option])(this, value, old);
|
6153 |
-
},
|
6154 |
-
|
6155 |
-
getOption: function(option) {return this.options[option];},
|
6156 |
-
getDoc: function() {return this.doc;},
|
6157 |
-
|
6158 |
-
addKeyMap: function(map, bottom) {
|
6159 |
-
this.state.keyMaps[bottom ? "push" : "unshift"](map);
|
6160 |
-
},
|
6161 |
-
removeKeyMap: function(map) {
|
6162 |
-
var maps = this.state.keyMaps;
|
6163 |
-
for (var i = 0; i < maps.length; ++i)
|
6164 |
-
if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
|
6165 |
-
maps.splice(i, 1);
|
6166 |
-
return true;
|
6167 |
-
}
|
6168 |
-
},
|
6169 |
-
|
6170 |
-
addOverlay: operation(null, function(spec, options) {
|
6171 |
-
var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
|
6172 |
-
if (mode.startState) throw new Error("Overlays may not be stateful.");
|
6173 |
-
this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
|
6174 |
-
this.state.modeGen++;
|
6175 |
-
regChange(this);
|
6176 |
-
}),
|
6177 |
-
removeOverlay: operation(null, function(spec) {
|
6178 |
-
var overlays = this.state.overlays;
|
6179 |
-
for (var i = 0; i < overlays.length; ++i) {
|
6180 |
-
var cur = overlays[i].modeSpec;
|
6181 |
-
if (cur == spec || typeof spec == "string" && cur.name == spec) {
|
6182 |
-
overlays.splice(i, 1);
|
6183 |
-
this.state.modeGen++;
|
6184 |
-
regChange(this);
|
6185 |
-
return;
|
6186 |
-
}
|
6187 |
-
}
|
6188 |
-
}),
|
6189 |
-
|
6190 |
-
indentLine: operation(null, function(n, dir, aggressive) {
|
6191 |
-
if (typeof dir != "string" && typeof dir != "number") {
|
6192 |
-
if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
|
6193 |
-
else dir = dir ? "add" : "subtract";
|
6194 |
-
}
|
6195 |
-
if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
|
6196 |
-
}),
|
6197 |
-
indentSelection: operation(null, function(how) {
|
6198 |
-
var sel = this.doc.sel;
|
6199 |
-
if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how, true);
|
6200 |
-
var e = sel.to.line - (sel.to.ch ? 0 : 1);
|
6201 |
-
for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
|
6202 |
-
}),
|
6203 |
-
|
6204 |
-
// Fetch the parser token for a given character. Useful for hacks
|
6205 |
-
// that want to inspect the mode state (say, for completion).
|
6206 |
-
getTokenAt: function(pos, precise) {
|
6207 |
-
var doc = this.doc;
|
6208 |
-
pos = clipPos(doc, pos);
|
6209 |
-
var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
|
6210 |
-
var line = getLine(doc, pos.line);
|
6211 |
-
var stream = new StringStream(line.text, this.options.tabSize);
|
6212 |
-
while (stream.pos < pos.ch && !stream.eol()) {
|
6213 |
-
stream.start = stream.pos;
|
6214 |
-
var style = mode.token(stream, state);
|
6215 |
-
}
|
6216 |
-
return {start: stream.start,
|
6217 |
-
end: stream.pos,
|
6218 |
-
string: stream.current(),
|
6219 |
-
className: style || null, // Deprecated, use 'type' instead
|
6220 |
-
type: style || null,
|
6221 |
-
state: state};
|
6222 |
-
},
|
6223 |
-
|
6224 |
-
getTokenTypeAt: function(pos) {
|
6225 |
-
pos = clipPos(this.doc, pos);
|
6226 |
-
var styles = getLineStyles(this, getLine(this.doc, pos.line));
|
6227 |
-
var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
|
6228 |
-
if (ch == 0) return styles[2];
|
6229 |
-
for (;;) {
|
6230 |
-
var mid = (before + after) >> 1;
|
6231 |
-
if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
|
6232 |
-
else if (styles[mid * 2 + 1] < ch) before = mid + 1;
|
6233 |
-
else return styles[mid * 2 + 2];
|
6234 |
-
}
|
6235 |
-
},
|
6236 |
-
|
6237 |
-
getModeAt: function(pos) {
|
6238 |
-
var mode = this.doc.mode;
|
6239 |
-
if (!mode.innerMode) return mode;
|
6240 |
-
return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
|
6241 |
-
},
|
6242 |
-
|
6243 |
-
getHelper: function(pos, type) {
|
6244 |
-
return this.getHelpers(pos, type)[0];
|
6245 |
-
},
|
6246 |
-
|
6247 |
-
getHelpers: function(pos, type) {
|
6248 |
-
var found = [];
|
6249 |
-
if (!helpers.hasOwnProperty(type)) return helpers;
|
6250 |
-
var help = helpers[type], mode = this.getModeAt(pos);
|
6251 |
-
if (typeof mode[type] == "string") {
|
6252 |
-
if (help[mode[type]]) found.push(help[mode[type]]);
|
6253 |
-
} else if (mode[type]) {
|
6254 |
-
for (var i = 0; i < mode[type].length; i++) {
|
6255 |
-
var val = help[mode[type][i]];
|
6256 |
-
if (val) found.push(val);
|
6257 |
-
}
|
6258 |
-
} else if (mode.helperType && help[mode.helperType]) {
|
6259 |
-
found.push(help[mode.helperType]);
|
6260 |
-
} else if (help[mode.name]) {
|
6261 |
-
found.push(help[mode.name]);
|
6262 |
-
}
|
6263 |
-
for (var i = 0; i < help._global.length; i++) {
|
6264 |
-
var cur = help._global[i];
|
6265 |
-
if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
|
6266 |
-
found.push(cur.val);
|
6267 |
-
}
|
6268 |
-
return found;
|
6269 |
-
},
|
6270 |
-
|
6271 |
-
getStateAfter: function(line, precise) {
|
6272 |
-
var doc = this.doc;
|
6273 |
-
line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
|
6274 |
-
return getStateBefore(this, line + 1, precise);
|
6275 |
-
},
|
6276 |
-
|
6277 |
-
cursorCoords: function(start, mode) {
|
6278 |
-
var pos, sel = this.doc.sel;
|
6279 |
-
if (start == null) pos = sel.head;
|
6280 |
-
else if (typeof start == "object") pos = clipPos(this.doc, start);
|
6281 |
-
else pos = start ? sel.from : sel.to;
|
6282 |
-
return cursorCoords(this, pos, mode || "page");
|
6283 |
-
},
|
6284 |
-
|
6285 |
-
charCoords: function(pos, mode) {
|
6286 |
-
return charCoords(this, clipPos(this.doc, pos), mode || "page");
|
6287 |
-
},
|
6288 |
-
|
6289 |
-
coordsChar: function(coords, mode) {
|
6290 |
-
coords = fromCoordSystem(this, coords, mode || "page");
|
6291 |
-
return coordsChar(this, coords.left, coords.top);
|
6292 |
-
},
|
6293 |
-
|
6294 |
-
lineAtHeight: function(height, mode) {
|
6295 |
-
height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
|
6296 |
-
return lineAtHeight(this.doc, height + this.display.viewOffset);
|
6297 |
-
},
|
6298 |
-
heightAtLine: function(line, mode) {
|
6299 |
-
var end = false, last = this.doc.first + this.doc.size - 1;
|
6300 |
-
if (line < this.doc.first) line = this.doc.first;
|
6301 |
-
else if (line > last) { line = last; end = true; }
|
6302 |
-
var lineObj = getLine(this.doc, line);
|
6303 |
-
return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
|
6304 |
-
(end ? lineObj.height : 0);
|
6305 |
-
},
|
6306 |
-
|
6307 |
-
defaultTextHeight: function() { return textHeight(this.display); },
|
6308 |
-
defaultCharWidth: function() { return charWidth(this.display); },
|
6309 |
-
|
6310 |
-
setGutterMarker: operation(null, function(line, gutterID, value) {
|
6311 |
-
return changeLine(this, line, function(line) {
|
6312 |
-
var markers = line.gutterMarkers || (line.gutterMarkers = {});
|
6313 |
-
markers[gutterID] = value;
|
6314 |
-
if (!value && isEmpty(markers)) line.gutterMarkers = null;
|
6315 |
-
return true;
|
6316 |
-
});
|
6317 |
-
}),
|
6318 |
-
|
6319 |
-
clearGutter: operation(null, function(gutterID) {
|
6320 |
-
var cm = this, doc = cm.doc, i = doc.first;
|
6321 |
-
doc.iter(function(line) {
|
6322 |
-
if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
|
6323 |
-
line.gutterMarkers[gutterID] = null;
|
6324 |
-
regChange(cm, i, i + 1);
|
6325 |
-
if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
|
6326 |
-
}
|
6327 |
-
++i;
|
6328 |
-
});
|
6329 |
-
}),
|
6330 |
-
|
6331 |
-
addLineClass: operation(null, function(handle, where, cls) {
|
6332 |
-
return changeLine(this, handle, function(line) {
|
6333 |
-
var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
|
6334 |
-
if (!line[prop]) line[prop] = cls;
|
6335 |
-
else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
|
6336 |
-
else line[prop] += " " + cls;
|
6337 |
-
return true;
|
6338 |
-
});
|
6339 |
-
}),
|
6340 |
-
|
6341 |
-
removeLineClass: operation(null, function(handle, where, cls) {
|
6342 |
-
return changeLine(this, handle, function(line) {
|
6343 |
-
var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
|
6344 |
-
var cur = line[prop];
|
6345 |
-
if (!cur) return false;
|
6346 |
-
else if (cls == null) line[prop] = null;
|
6347 |
-
else {
|
6348 |
-
var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
|
6349 |
-
if (!found) return false;
|
6350 |
-
var end = found.index + found[0].length;
|
6351 |
-
line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
|
6352 |
-
}
|
6353 |
-
return true;
|
6354 |
-
});
|
6355 |
-
}),
|
6356 |
-
|
6357 |
-
addLineWidget: operation(null, function(handle, node, options) {
|
6358 |
-
return addLineWidget(this, handle, node, options);
|
6359 |
-
}),
|
6360 |
-
|
6361 |
-
removeLineWidget: function(widget) { widget.clear(); },
|
6362 |
-
|
6363 |
-
lineInfo: function(line) {
|
6364 |
-
if (typeof line == "number") {
|
6365 |
-
if (!isLine(this.doc, line)) return null;
|
6366 |
-
var n = line;
|
6367 |
-
line = getLine(this.doc, line);
|
6368 |
-
if (!line) return null;
|
6369 |
-
} else {
|
6370 |
-
var n = lineNo(line);
|
6371 |
-
if (n == null) return null;
|
6372 |
-
}
|
6373 |
-
return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
|
6374 |
-
textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
|
6375 |
-
widgets: line.widgets};
|
6376 |
-
},
|
6377 |
-
|
6378 |
-
getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},
|
6379 |
-
|
6380 |
-
addWidget: function(pos, node, scroll, vert, horiz) {
|
6381 |
-
var display = this.display;
|
6382 |
-
pos = cursorCoords(this, clipPos(this.doc, pos));
|
6383 |
-
var top = pos.bottom, left = pos.left;
|
6384 |
-
node.style.position = "absolute";
|
6385 |
-
display.sizer.appendChild(node);
|
6386 |
-
if (vert == "over") {
|
6387 |
-
top = pos.top;
|
6388 |
-
} else if (vert == "above" || vert == "near") {
|
6389 |
-
var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
|
6390 |
-
hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
|
6391 |
-
// Default to positioning above (if specified and possible); otherwise default to positioning below
|
6392 |
-
if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
|
6393 |
-
top = pos.top - node.offsetHeight;
|
6394 |
-
else if (pos.bottom + node.offsetHeight <= vspace)
|
6395 |
-
top = pos.bottom;
|
6396 |
-
if (left + node.offsetWidth > hspace)
|
6397 |
-
left = hspace - node.offsetWidth;
|
6398 |
-
}
|
6399 |
-
node.style.top = top + "px";
|
6400 |
-
node.style.left = node.style.right = "";
|
6401 |
-
if (horiz == "right") {
|
6402 |
-
left = display.sizer.clientWidth - node.offsetWidth;
|
6403 |
-
node.style.right = "0px";
|
6404 |
-
} else {
|
6405 |
-
if (horiz == "left") left = 0;
|
6406 |
-
else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
|
6407 |
-
node.style.left = left + "px";
|
6408 |
-
}
|
6409 |
-
if (scroll)
|
6410 |
-
scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
|
6411 |
-
},
|
6412 |
-
|
6413 |
-
triggerOnKeyDown: operation(null, onKeyDown),
|
6414 |
-
triggerOnKeyPress: operation(null, onKeyPress),
|
6415 |
-
triggerOnKeyUp: operation(null, onKeyUp),
|
6416 |
-
|
6417 |
-
execCommand: function(cmd) {
|
6418 |
-
if (commands.hasOwnProperty(cmd))
|
6419 |
-
return commands[cmd](this);
|
6420 |
-
},
|
6421 |
-
|
6422 |
-
findPosH: function(from, amount, unit, visually) {
|
6423 |
-
var dir = 1;
|
6424 |
-
if (amount < 0) { dir = -1; amount = -amount; }
|
6425 |
-
for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
|
6426 |
-
cur = findPosH(this.doc, cur, dir, unit, visually);
|
6427 |
-
if (cur.hitSide) break;
|
6428 |
-
}
|
6429 |
-
return cur;
|
6430 |
-
},
|
6431 |
-
|
6432 |
-
moveH: operation(null, function(dir, unit) {
|
6433 |
-
var sel = this.doc.sel, pos;
|
6434 |
-
if (sel.shift || sel.extend || posEq(sel.from, sel.to))
|
6435 |
-
pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually);
|
6436 |
-
else
|
6437 |
-
pos = dir < 0 ? sel.from : sel.to;
|
6438 |
-
extendSelection(this.doc, pos, pos, dir);
|
6439 |
-
}),
|
6440 |
-
|
6441 |
-
deleteH: operation(null, function(dir, unit) {
|
6442 |
-
var sel = this.doc.sel;
|
6443 |
-
if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete");
|
6444 |
-
else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete");
|
6445 |
-
this.curOp.userSelChange = true;
|
6446 |
-
}),
|
6447 |
-
|
6448 |
-
findPosV: function(from, amount, unit, goalColumn) {
|
6449 |
-
var dir = 1, x = goalColumn;
|
6450 |
-
if (amount < 0) { dir = -1; amount = -amount; }
|
6451 |
-
for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
|
6452 |
-
var coords = cursorCoords(this, cur, "div");
|
6453 |
-
if (x == null) x = coords.left;
|
6454 |
-
else coords.left = x;
|
6455 |
-
cur = findPosV(this, coords, dir, unit);
|
6456 |
-
if (cur.hitSide) break;
|
6457 |
-
}
|
6458 |
-
return cur;
|
6459 |
-
},
|
6460 |
-
|
6461 |
-
moveV: operation(null, function(dir, unit) {
|
6462 |
-
var sel = this.doc.sel, target, goal;
|
6463 |
-
if (sel.shift || sel.extend || posEq(sel.from, sel.to)) {
|
6464 |
-
var pos = cursorCoords(this, sel.head, "div");
|
6465 |
-
if (sel.goalColumn != null) pos.left = sel.goalColumn;
|
6466 |
-
target = findPosV(this, pos, dir, unit);
|
6467 |
-
if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
|
6468 |
-
goal = pos.left;
|
6469 |
-
} else {
|
6470 |
-
target = dir < 0 ? sel.from : sel.to;
|
6471 |
-
}
|
6472 |
-
extendSelection(this.doc, target, target, dir);
|
6473 |
-
if (goal != null) sel.goalColumn = goal;
|
6474 |
-
}),
|
6475 |
-
|
6476 |
-
toggleOverwrite: function(value) {
|
6477 |
-
if (value != null && value == this.state.overwrite) return;
|
6478 |
-
if (this.state.overwrite = !this.state.overwrite)
|
6479 |
-
this.display.cursor.className += " CodeMirror-overwrite";
|
6480 |
-
else
|
6481 |
-
this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
|
6482 |
-
|
6483 |
-
signal(this, "overwriteToggle", this, this.state.overwrite);
|
6484 |
-
},
|
6485 |
-
hasFocus: function() { return document.activeElement == this.display.input; },
|
6486 |
-
|
6487 |
-
scrollTo: operation(null, function(x, y) {
|
6488 |
-
updateScrollPos(this, x, y);
|
6489 |
-
}),
|
6490 |
-
getScrollInfo: function() {
|
6491 |
-
var scroller = this.display.scroller, co = scrollerCutOff;
|
6492 |
-
return {left: scroller.scrollLeft, top: scroller.scrollTop,
|
6493 |
-
height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
|
6494 |
-
clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
|
6495 |
-
},
|
6496 |
-
|
6497 |
-
scrollIntoView: operation(null, function(range, margin) {
|
6498 |
-
if (range == null) range = {from: this.doc.sel.head, to: null};
|
6499 |
-
else if (typeof range == "number") range = {from: Pos(range, 0), to: null};
|
6500 |
-
else if (range.from == null) range = {from: range, to: null};
|
6501 |
-
if (!range.to) range.to = range.from;
|
6502 |
-
if (!margin) margin = 0;
|
6503 |
-
|
6504 |
-
var coords = range;
|
6505 |
-
if (range.from.line != null) {
|
6506 |
-
this.curOp.scrollToPos = {from: range.from, to: range.to, margin: margin};
|
6507 |
-
coords = {from: cursorCoords(this, range.from),
|
6508 |
-
to: cursorCoords(this, range.to)};
|
6509 |
-
}
|
6510 |
-
var sPos = calculateScrollPos(this, Math.min(coords.from.left, coords.to.left),
|
6511 |
-
Math.min(coords.from.top, coords.to.top) - margin,
|
6512 |
-
Math.max(coords.from.right, coords.to.right),
|
6513 |
-
Math.max(coords.from.bottom, coords.to.bottom) + margin);
|
6514 |
-
updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
|
6515 |
-
}),
|
6516 |
-
|
6517 |
-
setSize: operation(null, function(width, height) {
|
6518 |
-
function interpret(val) {
|
6519 |
-
return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
|
6520 |
-
}
|
6521 |
-
if (width != null) this.display.wrapper.style.width = interpret(width);
|
6522 |
-
if (height != null) this.display.wrapper.style.height = interpret(height);
|
6523 |
-
if (this.options.lineWrapping)
|
6524 |
-
this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
|
6525 |
-
this.curOp.forceUpdate = true;
|
6526 |
-
signal(this, "refresh", this);
|
6527 |
-
}),
|
6528 |
-
|
6529 |
-
operation: function(f){return runInOp(this, f);},
|
6530 |
-
|
6531 |
-
refresh: operation(null, function() {
|
6532 |
-
var oldHeight = this.display.cachedTextHeight;
|
6533 |
-
clearCaches(this);
|
6534 |
-
updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
|
6535 |
-
regChange(this);
|
6536 |
-
if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
|
6537 |
-
estimateLineHeights(this);
|
6538 |
-
signal(this, "refresh", this);
|
6539 |
-
}),
|
6540 |
-
|
6541 |
-
swapDoc: operation(null, function(doc) {
|
6542 |
-
var old = this.doc;
|
6543 |
-
old.cm = null;
|
6544 |
-
attachDoc(this, doc);
|
6545 |
-
clearCaches(this);
|
6546 |
-
resetInput(this, true);
|
6547 |
-
updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
|
6548 |
-
signalLater(this, "swapDoc", this, old);
|
6549 |
-
return old;
|
6550 |
-
}),
|
6551 |
-
|
6552 |
-
getInputField: function(){return this.display.input;},
|
6553 |
-
getWrapperElement: function(){return this.display.wrapper;},
|
6554 |
-
getScrollerElement: function(){return this.display.scroller;},
|
6555 |
-
getGutterElement: function(){return this.display.gutters;}
|
6556 |
-
};
|
6557 |
-
eventMixin(CodeMirror);
|
6558 |
-
|
6559 |
-
// OPTION DEFAULTS
|
6560 |
-
|
6561 |
-
var optionHandlers = CodeMirror.optionHandlers = {};
|
6562 |
-
|
6563 |
-
// The default configuration options.
|
6564 |
-
var defaults = CodeMirror.defaults = {};
|
6565 |
-
|
6566 |
-
function option(name, deflt, handle, notOnInit) {
|
6567 |
-
CodeMirror.defaults[name] = deflt;
|
6568 |
-
if (handle) optionHandlers[name] =
|
6569 |
-
notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
|
6570 |
-
}
|
6571 |
-
|
6572 |
-
var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
|
6573 |
-
|
6574 |
-
// These two are, on init, called from the constructor because they
|
6575 |
-
// have to be initialized before the editor can start at all.
|
6576 |
-
option("value", "", function(cm, val) {
|
6577 |
-
cm.setValue(val);
|
6578 |
-
}, true);
|
6579 |
-
option("mode", null, function(cm, val) {
|
6580 |
-
cm.doc.modeOption = val;
|
6581 |
-
loadMode(cm);
|
6582 |
-
}, true);
|
6583 |
-
|
6584 |
-
option("indentUnit", 2, loadMode, true);
|
6585 |
-
option("indentWithTabs", false);
|
6586 |
-
option("smartIndent", true);
|
6587 |
-
option("tabSize", 4, function(cm) {
|
6588 |
-
resetModeState(cm);
|
6589 |
-
clearCaches(cm);
|
6590 |
-
regChange(cm);
|
6591 |
-
}, true);
|
6592 |
-
option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) {
|
6593 |
-
cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
|
6594 |
-
cm.refresh();
|
6595 |
-
}, true);
|
6596 |
-
option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
|
6597 |
-
option("electricChars", true);
|
6598 |
-
option("rtlMoveVisually", !windows);
|
6599 |
-
option("wholeLineUpdateBefore", true);
|
6600 |
-
|
6601 |
-
option("theme", "default", function(cm) {
|
6602 |
-
themeChanged(cm);
|
6603 |
-
guttersChanged(cm);
|
6604 |
-
}, true);
|
6605 |
-
option("keyMap", "default", keyMapChanged);
|
6606 |
-
option("extraKeys", null);
|
6607 |
-
|
6608 |
-
option("onKeyEvent", null);
|
6609 |
-
option("onDragEvent", null);
|
6610 |
-
|
6611 |
-
option("lineWrapping", false, wrappingChanged, true);
|
6612 |
-
option("gutters", [], function(cm) {
|
6613 |
-
setGuttersForLineNumbers(cm.options);
|
6614 |
-
guttersChanged(cm);
|
6615 |
-
}, true);
|
6616 |
-
option("fixedGutter", true, function(cm, val) {
|
6617 |
-
cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
|
6618 |
-
cm.refresh();
|
6619 |
-
}, true);
|
6620 |
-
option("coverGutterNextToScrollbar", false, updateScrollbars, true);
|
6621 |
-
option("lineNumbers", false, function(cm) {
|
6622 |
-
setGuttersForLineNumbers(cm.options);
|
6623 |
-
guttersChanged(cm);
|
6624 |
-
}, true);
|
6625 |
-
option("firstLineNumber", 1, guttersChanged, true);
|
6626 |
-
option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
|
6627 |
-
option("showCursorWhenSelecting", false, updateSelection, true);
|
6628 |
-
|
6629 |
-
option("resetSelectionOnContextMenu", true);
|
6630 |
-
|
6631 |
-
option("readOnly", false, function(cm, val) {
|
6632 |
-
if (val == "nocursor") {
|
6633 |
-
onBlur(cm);
|
6634 |
-
cm.display.input.blur();
|
6635 |
-
cm.display.disabled = true;
|
6636 |
-
} else {
|
6637 |
-
cm.display.disabled = false;
|
6638 |
-
if (!val) resetInput(cm, true);
|
6639 |
-
}
|
6640 |
-
});
|
6641 |
-
option("disableInput", false, function(cm, val) {if (!val) resetInput(cm, true);}, true);
|
6642 |
-
option("dragDrop", true);
|
6643 |
-
|
6644 |
-
option("cursorBlinkRate", 530);
|
6645 |
-
option("cursorScrollMargin", 0);
|
6646 |
-
option("cursorHeight", 1);
|
6647 |
-
option("workTime", 100);
|
6648 |
-
option("workDelay", 100);
|
6649 |
-
option("flattenSpans", true, resetModeState, true);
|
6650 |
-
option("addModeClass", false, resetModeState, true);
|
6651 |
-
option("pollInterval", 100);
|
6652 |
-
option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
|
6653 |
-
option("historyEventDelay", 500);
|
6654 |
-
option("viewportMargin", 10, function(cm){cm.refresh();}, true);
|
6655 |
-
option("maxHighlightLength", 10000, resetModeState, true);
|
6656 |
-
option("crudeMeasuringFrom", 10000);
|
6657 |
-
option("moveInputWithCursor", true, function(cm, val) {
|
6658 |
-
if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
|
6659 |
-
});
|
6660 |
-
|
6661 |
-
option("tabindex", null, function(cm, val) {
|
6662 |
-
cm.display.input.tabIndex = val || "";
|
6663 |
-
});
|
6664 |
-
option("autofocus", null);
|
6665 |
-
|
6666 |
-
// MODE DEFINITION AND QUERYING
|
6667 |
-
|
6668 |
-
// Known modes, by name and by MIME
|
6669 |
-
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
|
6670 |
-
|
6671 |
-
CodeMirror.defineMode = function(name, mode) {
|
6672 |
-
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
|
6673 |
-
if (arguments.length > 2) {
|
6674 |
-
mode.dependencies = [];
|
6675 |
-
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
|
6676 |
-
}
|
6677 |
-
modes[name] = mode;
|
6678 |
-
};
|
6679 |
-
|
6680 |
-
CodeMirror.defineMIME = function(mime, spec) {
|
6681 |
-
mimeModes[mime] = spec;
|
6682 |
-
};
|
6683 |
-
|
6684 |
-
CodeMirror.resolveMode = function(spec) {
|
6685 |
-
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
|
6686 |
-
spec = mimeModes[spec];
|
6687 |
-
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
|
6688 |
-
var found = mimeModes[spec.name];
|
6689 |
-
if (typeof found == "string") found = {name: found};
|
6690 |
-
spec = createObj(found, spec);
|
6691 |
-
spec.name = found.name;
|
6692 |
-
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
|
6693 |
-
return CodeMirror.resolveMode("application/xml");
|
6694 |
-
}
|
6695 |
-
if (typeof spec == "string") return {name: spec};
|
6696 |
-
else return spec || {name: "null"};
|
6697 |
-
};
|
6698 |
-
|
6699 |
-
CodeMirror.getMode = function(options, spec) {
|
6700 |
-
var spec = CodeMirror.resolveMode(spec);
|
6701 |
-
var mfactory = modes[spec.name];
|
6702 |
-
if (!mfactory) return CodeMirror.getMode(options, "text/plain");
|
6703 |
-
var modeObj = mfactory(options, spec);
|
6704 |
-
if (modeExtensions.hasOwnProperty(spec.name)) {
|
6705 |
-
var exts = modeExtensions[spec.name];
|
6706 |
-
for (var prop in exts) {
|
6707 |
-
if (!exts.hasOwnProperty(prop)) continue;
|
6708 |
-
if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
|
6709 |
-
modeObj[prop] = exts[prop];
|
6710 |
-
}
|
6711 |
-
}
|
6712 |
-
modeObj.name = spec.name;
|
6713 |
-
if (spec.helperType) modeObj.helperType = spec.helperType;
|
6714 |
-
if (spec.modeProps) for (var prop in spec.modeProps)
|
6715 |
-
modeObj[prop] = spec.modeProps[prop];
|
6716 |
-
|
6717 |
-
return modeObj;
|
6718 |
-
};
|
6719 |
-
|
6720 |
-
CodeMirror.defineMode("null", function() {
|
6721 |
-
return {token: function(stream) {stream.skipToEnd();}};
|
6722 |
-
});
|
6723 |
-
CodeMirror.defineMIME("text/plain", "null");
|
6724 |
-
|
6725 |
-
var modeExtensions = CodeMirror.modeExtensions = {};
|
6726 |
-
CodeMirror.extendMode = function(mode, properties) {
|
6727 |
-
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
|
6728 |
-
copyObj(properties, exts);
|
6729 |
-
};
|
6730 |
-
|
6731 |
-
// EXTENSIONS
|
6732 |
-
|
6733 |
-
CodeMirror.defineExtension = function(name, func) {
|
6734 |
-
CodeMirror.prototype[name] = func;
|
6735 |
-
};
|
6736 |
-
CodeMirror.defineDocExtension = function(name, func) {
|
6737 |
-
Doc.prototype[name] = func;
|
6738 |
-
};
|
6739 |
-
CodeMirror.defineOption = option;
|
6740 |
-
|
6741 |
-
var initHooks = [];
|
6742 |
-
CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
|
6743 |
-
|
6744 |
-
var helpers = CodeMirror.helpers = {};
|
6745 |
-
CodeMirror.registerHelper = function(type, name, value) {
|
6746 |
-
if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
|
6747 |
-
helpers[type][name] = value;
|
6748 |
-
};
|
6749 |
-
CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
|
6750 |
-
CodeMirror.registerHelper(type, name, value);
|
6751 |
-
helpers[type]._global.push({pred: predicate, val: value});
|
6752 |
-
};
|
6753 |
-
|
6754 |
-
// UTILITIES
|
6755 |
-
|
6756 |
-
CodeMirror.isWordChar = isWordChar;
|
6757 |
-
|
6758 |
-
// MODE STATE HANDLING
|
6759 |
-
|
6760 |
-
// Utility functions for working with state. Exported because modes
|
6761 |
-
// sometimes need to do this.
|
6762 |
-
function copyState(mode, state) {
|
6763 |
-
if (state === true) return state;
|
6764 |
-
if (mode.copyState) return mode.copyState(state);
|
6765 |
-
var nstate = {};
|
6766 |
-
for (var n in state) {
|
6767 |
-
var val = state[n];
|
6768 |
-
if (val instanceof Array) val = val.concat([]);
|
6769 |
-
nstate[n] = val;
|
6770 |
-
}
|
6771 |
-
return nstate;
|
6772 |
-
}
|
6773 |
-
CodeMirror.copyState = copyState;
|
6774 |
-
|
6775 |
-
function startState(mode, a1, a2) {
|
6776 |
-
return mode.startState ? mode.startState(a1, a2) : true;
|
6777 |
-
}
|
6778 |
-
CodeMirror.startState = startState;
|
6779 |
-
|
6780 |
-
CodeMirror.innerMode = function(mode, state) {
|
6781 |
-
while (mode.innerMode) {
|
6782 |
-
var info = mode.innerMode(state);
|
6783 |
-
if (!info || info.mode == mode) break;
|
6784 |
-
state = info.state;
|
6785 |
-
mode = info.mode;
|
6786 |
-
}
|
6787 |
-
return info || {mode: mode, state: state};
|
6788 |
-
};
|
6789 |
-
|
6790 |
-
// STANDARD COMMANDS
|
6791 |
-
|
6792 |
-
var commands = CodeMirror.commands = {
|
6793 |
-
selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
|
6794 |
-
killLine: function(cm) {
|
6795 |
-
var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
|
6796 |
-
if (!sel && cm.getLine(from.line).length == from.ch)
|
6797 |
-
cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
|
6798 |
-
else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
|
6799 |
-
},
|
6800 |
-
deleteLine: function(cm) {
|
6801 |
-
var l = cm.getCursor().line;
|
6802 |
-
cm.replaceRange("", Pos(l, 0), Pos(l + 1, 0), "+delete");
|
6803 |
-
},
|
6804 |
-
delLineLeft: function(cm) {
|
6805 |
-
var cur = cm.getCursor();
|
6806 |
-
cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
|
6807 |
-
},
|
6808 |
-
undo: function(cm) {cm.undo();},
|
6809 |
-
redo: function(cm) {cm.redo();},
|
6810 |
-
goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
|
6811 |
-
goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
|
6812 |
-
goLineStart: function(cm) {
|
6813 |
-
cm.extendSelection(lineStart(cm, cm.getCursor().line));
|
6814 |
-
},
|
6815 |
-
goLineStartSmart: function(cm) {
|
6816 |
-
var cur = cm.getCursor(), start = lineStart(cm, cur.line);
|
6817 |
-
var line = cm.getLineHandle(start.line);
|
6818 |
-
var order = getOrder(line);
|
6819 |
-
if (!order || order[0].level == 0) {
|
6820 |
-
var firstNonWS = Math.max(0, line.text.search(/\S/));
|
6821 |
-
var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
|
6822 |
-
cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS));
|
6823 |
-
} else cm.extendSelection(start);
|
6824 |
-
},
|
6825 |
-
goLineEnd: function(cm) {
|
6826 |
-
cm.extendSelection(lineEnd(cm, cm.getCursor().line));
|
6827 |
-
},
|
6828 |
-
goLineRight: function(cm) {
|
6829 |
-
var top = cm.charCoords(cm.getCursor(), "div").top + 5;
|
6830 |
-
cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"));
|
6831 |
-
},
|
6832 |
-
goLineLeft: function(cm) {
|
6833 |
-
var top = cm.charCoords(cm.getCursor(), "div").top + 5;
|
6834 |
-
cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div"));
|
6835 |
-
},
|
6836 |
-
goLineUp: function(cm) {cm.moveV(-1, "line");},
|
6837 |
-
goLineDown: function(cm) {cm.moveV(1, "line");},
|
6838 |
-
goPageUp: function(cm) {cm.moveV(-1, "page");},
|
6839 |
-
goPageDown: function(cm) {cm.moveV(1, "page");},
|
6840 |
-
goCharLeft: function(cm) {cm.moveH(-1, "char");},
|
6841 |
-
goCharRight: function(cm) {cm.moveH(1, "char");},
|
6842 |
-
goColumnLeft: function(cm) {cm.moveH(-1, "column");},
|
6843 |
-
goColumnRight: function(cm) {cm.moveH(1, "column");},
|
6844 |
-
goWordLeft: function(cm) {cm.moveH(-1, "word");},
|
6845 |
-
goGroupRight: function(cm) {cm.moveH(1, "group");},
|
6846 |
-
goGroupLeft: function(cm) {cm.moveH(-1, "group");},
|
6847 |
-
goWordRight: function(cm) {cm.moveH(1, "word");},
|
6848 |
-
delCharBefore: function(cm) {cm.deleteH(-1, "char");},
|
6849 |
-
delCharAfter: function(cm) {cm.deleteH(1, "char");},
|
6850 |
-
delWordBefore: function(cm) {cm.deleteH(-1, "word");},
|
6851 |
-
delWordAfter: function(cm) {cm.deleteH(1, "word");},
|
6852 |
-
delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
|
6853 |
-
delGroupAfter: function(cm) {cm.deleteH(1, "group");},
|
6854 |
-
indentAuto: function(cm) {cm.indentSelection("smart");},
|
6855 |
-
indentMore: function(cm) {cm.indentSelection("add");},
|
6856 |
-
indentLess: function(cm) {cm.indentSelection("subtract");},
|
6857 |
-
insertTab: function(cm) {
|
6858 |
-
cm.replaceSelection("\t", "end", "+input");
|
6859 |
-
},
|
6860 |
-
defaultTab: function(cm) {
|
6861 |
-
if (cm.somethingSelected()) cm.indentSelection("add");
|
6862 |
-
else cm.replaceSelection("\t", "end", "+input");
|
6863 |
-
},
|
6864 |
-
transposeChars: function(cm) {
|
6865 |
-
var cur = cm.getCursor(), line = cm.getLine(cur.line);
|
6866 |
-
if (cur.ch > 0 && cur.ch < line.length - 1)
|
6867 |
-
cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
|
6868 |
-
Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
|
6869 |
-
},
|
6870 |
-
newlineAndIndent: function(cm) {
|
6871 |
-
operation(cm, function() {
|
6872 |
-
cm.replaceSelection("\n", "end", "+input");
|
6873 |
-
cm.indentLine(cm.getCursor().line, null, true);
|
6874 |
-
})();
|
6875 |
-
},
|
6876 |
-
toggleOverwrite: function(cm) {cm.toggleOverwrite();}
|
6877 |
-
};
|
6878 |
-
|
6879 |
-
// STANDARD KEYMAPS
|
6880 |
-
|
6881 |
-
var keyMap = CodeMirror.keyMap = {};
|
6882 |
-
keyMap.basic = {
|
6883 |
-
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
|
6884 |
-
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
|
6885 |
-
"Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
|
6886 |
-
"Tab": "defaultTab", "Shift-Tab": "indentAuto",
|
6887 |
-
"Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
|
6888 |
-
};
|
6889 |
-
// Note that the save and find-related commands aren't defined by
|
6890 |
-
// default. Unknown commands are simply ignored.
|
6891 |
-
keyMap.pcDefault = {
|
6892 |
-
"Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
|
6893 |
-
"Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
|
6894 |
-
"Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
|
6895 |
-
"Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
|
6896 |
-
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
|
6897 |
-
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
|
6898 |
-
fallthrough: "basic"
|
6899 |
-
};
|
6900 |
-
keyMap.macDefault = {
|
6901 |
-
"Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
|
6902 |
-
"Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
|
6903 |
-
"Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore",
|
6904 |
-
"Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
|
6905 |
-
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
|
6906 |
-
"Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
|
6907 |
-
fallthrough: ["basic", "emacsy"]
|
6908 |
-
};
|
6909 |
-
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
|
6910 |
-
keyMap.emacsy = {
|
6911 |
-
"Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
|
6912 |
-
"Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
|
6913 |
-
"Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
|
6914 |
-
"Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
|
6915 |
-
};
|
6916 |
-
|
6917 |
-
// KEYMAP DISPATCH
|
6918 |
-
|
6919 |
-
function getKeyMap(val) {
|
6920 |
-
if (typeof val == "string") return keyMap[val];
|
6921 |
-
else return val;
|
6922 |
-
}
|
6923 |
-
|
6924 |
-
function lookupKey(name, maps, handle) {
|
6925 |
-
function lookup(map) {
|
6926 |
-
map = getKeyMap(map);
|
6927 |
-
var found = map[name];
|
6928 |
-
if (found === false) return "stop";
|
6929 |
-
if (found != null && handle(found)) return true;
|
6930 |
-
if (map.nofallthrough) return "stop";
|
6931 |
-
|
6932 |
-
var fallthrough = map.fallthrough;
|
6933 |
-
if (fallthrough == null) return false;
|
6934 |
-
if (Object.prototype.toString.call(fallthrough) != "[object Array]")
|
6935 |
-
return lookup(fallthrough);
|
6936 |
-
for (var i = 0, e = fallthrough.length; i < e; ++i) {
|
6937 |
-
var done = lookup(fallthrough[i]);
|
6938 |
-
if (done) return done;
|
6939 |
-
}
|
6940 |
-
return false;
|
6941 |
-
}
|
6942 |
-
|
6943 |
-
for (var i = 0; i < maps.length; ++i) {
|
6944 |
-
var done = lookup(maps[i]);
|
6945 |
-
if (done) return done != "stop";
|
6946 |
-
}
|
6947 |
-
}
|
6948 |
-
function isModifierKey(event) {
|
6949 |
-
var name = keyNames[event.keyCode];
|
6950 |
-
return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
|
6951 |
-
}
|
6952 |
-
function keyName(event, noShift) {
|
6953 |
-
if (opera && event.keyCode == 34 && event["char"]) return false;
|
6954 |
-
var name = keyNames[event.keyCode];
|
6955 |
-
if (name == null || event.altGraphKey) return false;
|
6956 |
-
if (event.altKey) name = "Alt-" + name;
|
6957 |
-
if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
|
6958 |
-
if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
|
6959 |
-
if (!noShift && event.shiftKey) name = "Shift-" + name;
|
6960 |
-
return name;
|
6961 |
-
}
|
6962 |
-
CodeMirror.lookupKey = lookupKey;
|
6963 |
-
CodeMirror.isModifierKey = isModifierKey;
|
6964 |
-
CodeMirror.keyName = keyName;
|
6965 |
-
|
6966 |
-
// FROMTEXTAREA
|
6967 |
-
|
6968 |
-
CodeMirror.fromTextArea = function(textarea, options) {
|
6969 |
-
if (!options) options = {};
|
6970 |
-
options.value = textarea.value;
|
6971 |
-
if (!options.tabindex && textarea.tabindex)
|
6972 |
-
options.tabindex = textarea.tabindex;
|
6973 |
-
if (!options.placeholder && textarea.placeholder)
|
6974 |
-
options.placeholder = textarea.placeholder;
|
6975 |
-
// Set autofocus to true if this textarea is focused, or if it has
|
6976 |
-
// autofocus and no other element is focused.
|
6977 |
-
if (options.autofocus == null) {
|
6978 |
-
var hasFocus = document.body;
|
6979 |
-
// doc.activeElement occasionally throws on IE
|
6980 |
-
try { hasFocus = document.activeElement; } catch(e) {}
|
6981 |
-
options.autofocus = hasFocus == textarea ||
|
6982 |
-
textarea.getAttribute("autofocus") != null && hasFocus == document.body;
|
6983 |
-
}
|
6984 |
-
|
6985 |
-
function save() {textarea.value = cm.getValue();}
|
6986 |
-
if (textarea.form) {
|
6987 |
-
on(textarea.form, "submit", save);
|
6988 |
-
// Deplorable hack to make the submit method do the right thing.
|
6989 |
-
if (!options.leaveSubmitMethodAlone) {
|
6990 |
-
var form = textarea.form, realSubmit = form.submit;
|
6991 |
-
try {
|
6992 |
-
var wrappedSubmit = form.submit = function() {
|
6993 |
-
save();
|
6994 |
-
form.submit = realSubmit;
|
6995 |
-
form.submit();
|
6996 |
-
form.submit = wrappedSubmit;
|
6997 |
-
};
|
6998 |
-
} catch(e) {}
|
6999 |
-
}
|
7000 |
-
}
|
7001 |
-
|
7002 |
-
textarea.style.display = "none";
|
7003 |
-
var cm = CodeMirror(function(node) {
|
7004 |
-
textarea.parentNode.insertBefore(node, textarea.nextSibling);
|
7005 |
-
}, options);
|
7006 |
-
cm.save = save;
|
7007 |
-
cm.getTextArea = function() { return textarea; };
|
7008 |
-
cm.toTextArea = function() {
|
7009 |
-
save();
|
7010 |
-
textarea.parentNode.removeChild(cm.getWrapperElement());
|
7011 |
-
textarea.style.display = "";
|
7012 |
-
if (textarea.form) {
|
7013 |
-
off(textarea.form, "submit", save);
|
7014 |
-
if (typeof textarea.form.submit == "function")
|
7015 |
-
textarea.form.submit = realSubmit;
|
7016 |
-
}
|
7017 |
-
};
|
7018 |
-
return cm;
|
7019 |
-
};
|
7020 |
-
|
7021 |
-
// STRING STREAM
|
7022 |
-
|
7023 |
-
// Fed to the mode parsers, provides helper functions to make
|
7024 |
-
// parsers more succinct.
|
7025 |
-
|
7026 |
-
// The character stream used by a mode's parser.
|
7027 |
-
function StringStream(string, tabSize) {
|
7028 |
-
this.pos = this.start = 0;
|
7029 |
-
this.string = string;
|
7030 |
-
this.tabSize = tabSize || 8;
|
7031 |
-
this.lastColumnPos = this.lastColumnValue = 0;
|
7032 |
-
this.lineStart = 0;
|
7033 |
-
}
|
7034 |
-
|
7035 |
-
StringStream.prototype = {
|
7036 |
-
eol: function() {return this.pos >= this.string.length;},
|
7037 |
-
sol: function() {return this.pos == this.lineStart;},
|
7038 |
-
peek: function() {return this.string.charAt(this.pos) || undefined;},
|
7039 |
-
next: function() {
|
7040 |
-
if (this.pos < this.string.length)
|
7041 |
-
return this.string.charAt(this.pos++);
|
7042 |
-
},
|
7043 |
-
eat: function(match) {
|
7044 |
-
var ch = this.string.charAt(this.pos);
|
7045 |
-
if (typeof match == "string") var ok = ch == match;
|
7046 |
-
else var ok = ch && (match.test ? match.test(ch) : match(ch));
|
7047 |
-
if (ok) {++this.pos; return ch;}
|
7048 |
-
},
|
7049 |
-
eatWhile: function(match) {
|
7050 |
-
var start = this.pos;
|
7051 |
-
while (this.eat(match)){}
|
7052 |
-
return this.pos > start;
|
7053 |
-
},
|
7054 |
-
eatSpace: function() {
|
7055 |
-
var start = this.pos;
|
7056 |
-
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
|
7057 |
-
return this.pos > start;
|
7058 |
-
},
|
7059 |
-
skipToEnd: function() {this.pos = this.string.length;},
|
7060 |
-
skipTo: function(ch) {
|
7061 |
-
var found = this.string.indexOf(ch, this.pos);
|
7062 |
-
if (found > -1) {this.pos = found; return true;}
|
7063 |
-
},
|
7064 |
-
backUp: function(n) {this.pos -= n;},
|
7065 |
-
column: function() {
|
7066 |
-
if (this.lastColumnPos < this.start) {
|
7067 |
-
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
|
7068 |
-
this.lastColumnPos = this.start;
|
7069 |
-
}
|
7070 |
-
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
|
7071 |
-
},
|
7072 |
-
indentation: function() {
|
7073 |
-
return countColumn(this.string, null, this.tabSize) -
|
7074 |
-
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
|
7075 |
-
},
|
7076 |
-
match: function(pattern, consume, caseInsensitive) {
|
7077 |
-
if (typeof pattern == "string") {
|
7078 |
-
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
|
7079 |
-
var substr = this.string.substr(this.pos, pattern.length);
|
7080 |
-
if (cased(substr) == cased(pattern)) {
|
7081 |
-
if (consume !== false) this.pos += pattern.length;
|
7082 |
-
return true;
|
7083 |
-
}
|
7084 |
-
} else {
|
7085 |
-
var match = this.string.slice(this.pos).match(pattern);
|
7086 |
-
if (match && match.index > 0) return null;
|
7087 |
-
if (match && consume !== false) this.pos += match[0].length;
|
7088 |
-
return match;
|
7089 |
-
}
|
7090 |
-
},
|
7091 |
-
current: function(){return this.string.slice(this.start, this.pos);},
|
7092 |
-
hideFirstChars: function(n, inner) {
|
7093 |
-
this.lineStart += n;
|
7094 |
-
try { return inner(); }
|
7095 |
-
finally { this.lineStart -= n; }
|
7096 |
-
}
|
7097 |
-
};
|
7098 |
-
CodeMirror.StringStream = StringStream;
|
7099 |
-
|
7100 |
-
// TEXTMARKERS
|
7101 |
-
|
7102 |
-
function TextMarker(doc, type) {
|
7103 |
-
this.lines = [];
|
7104 |
-
this.type = type;
|
7105 |
-
this.doc = doc;
|
7106 |
-
}
|
7107 |
-
CodeMirror.TextMarker = TextMarker;
|
7108 |
-
eventMixin(TextMarker);
|
7109 |
-
|
7110 |
-
TextMarker.prototype.clear = function() {
|
7111 |
-
if (this.explicitlyCleared) return;
|
7112 |
-
var cm = this.doc.cm, withOp = cm && !cm.curOp;
|
7113 |
-
if (withOp) startOperation(cm);
|
7114 |
-
if (hasHandler(this, "clear")) {
|
7115 |
-
var found = this.find();
|
7116 |
-
if (found) signalLater(this, "clear", found.from, found.to);
|
7117 |
-
}
|
7118 |
-
var min = null, max = null;
|
7119 |
-
for (var i = 0; i < this.lines.length; ++i) {
|
7120 |
-
var line = this.lines[i];
|
7121 |
-
var span = getMarkedSpanFor(line.markedSpans, this);
|
7122 |
-
if (span.to != null) max = lineNo(line);
|
7123 |
-
line.markedSpans = removeMarkedSpan(line.markedSpans, span);
|
7124 |
-
if (span.from != null)
|
7125 |
-
min = lineNo(line);
|
7126 |
-
else if (this.collapsed && !lineIsHidden(this.doc, line) && cm)
|
7127 |
-
updateLineHeight(line, textHeight(cm.display));
|
7128 |
-
}
|
7129 |
-
if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
|
7130 |
-
var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual);
|
7131 |
-
if (len > cm.display.maxLineLength) {
|
7132 |
-
cm.display.maxLine = visual;
|
7133 |
-
cm.display.maxLineLength = len;
|
7134 |
-
cm.display.maxLineChanged = true;
|
7135 |
-
}
|
7136 |
-
}
|
7137 |
-
|
7138 |
-
if (min != null && cm) regChange(cm, min, max + 1);
|
7139 |
-
this.lines.length = 0;
|
7140 |
-
this.explicitlyCleared = true;
|
7141 |
-
if (this.atomic && this.doc.cantEdit) {
|
7142 |
-
this.doc.cantEdit = false;
|
7143 |
-
if (cm) reCheckSelection(cm);
|
7144 |
-
}
|
7145 |
-
if (withOp) endOperation(cm);
|
7146 |
-
};
|
7147 |
-
|
7148 |
-
TextMarker.prototype.find = function(bothSides) {
|
7149 |
-
var from, to;
|
7150 |
-
for (var i = 0; i < this.lines.length; ++i) {
|
7151 |
-
var line = this.lines[i];
|
7152 |
-
var span = getMarkedSpanFor(line.markedSpans, this);
|
7153 |
-
if (span.from != null || span.to != null) {
|
7154 |
-
var found = lineNo(line);
|
7155 |
-
if (span.from != null) from = Pos(found, span.from);
|
7156 |
-
if (span.to != null) to = Pos(found, span.to);
|
7157 |
-
}
|
7158 |
-
}
|
7159 |
-
if (this.type == "bookmark" && !bothSides) return from;
|
7160 |
-
return from && {from: from, to: to};
|
7161 |
-
};
|
7162 |
-
|
7163 |
-
TextMarker.prototype.changed = function() {
|
7164 |
-
var pos = this.find(), cm = this.doc.cm;
|
7165 |
-
if (!pos || !cm) return;
|
7166 |
-
if (this.type != "bookmark") pos = pos.from;
|
7167 |
-
var line = getLine(this.doc, pos.line);
|
7168 |
-
clearCachedMeasurement(cm, line);
|
7169 |
-
if (pos.line >= cm.display.showingFrom && pos.line < cm.display.showingTo) {
|
7170 |
-
for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
|
7171 |
-
if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
|
7172 |
-
break;
|
7173 |
-
}
|
7174 |
-
runInOp(cm, function() {
|
7175 |
-
cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
|
7176 |
-
});
|
7177 |
-
}
|
7178 |
-
};
|
7179 |
-
|
7180 |
-
TextMarker.prototype.attachLine = function(line) {
|
7181 |
-
if (!this.lines.length && this.doc.cm) {
|
7182 |
-
var op = this.doc.cm.curOp;
|
7183 |
-
if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
|
7184 |
-
(op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
|
7185 |
-
}
|
7186 |
-
this.lines.push(line);
|
7187 |
-
};
|
7188 |
-
TextMarker.prototype.detachLine = function(line) {
|
7189 |
-
this.lines.splice(indexOf(this.lines, line), 1);
|
7190 |
-
if (!this.lines.length && this.doc.cm) {
|
7191 |
-
var op = this.doc.cm.curOp;
|
7192 |
-
(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
|
7193 |
-
}
|
7194 |
-
};
|
7195 |
-
|
7196 |
-
var nextMarkerId = 0;
|
7197 |
-
|
7198 |
-
function markText(doc, from, to, options, type) {
|
7199 |
-
if (options && options.shared) return markTextShared(doc, from, to, options, type);
|
7200 |
-
if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
|
7201 |
-
|
7202 |
-
var marker = new TextMarker(doc, type);
|
7203 |
-
if (options) copyObj(options, marker);
|
7204 |
-
if (posLess(to, from) || posEq(from, to) && marker.clearWhenEmpty !== false)
|
7205 |
-
return marker;
|
7206 |
-
if (marker.replacedWith) {
|
7207 |
-
marker.collapsed = true;
|
7208 |
-
marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
|
7209 |
-
if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
|
7210 |
-
}
|
7211 |
-
if (marker.collapsed) {
|
7212 |
-
if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
|
7213 |
-
from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
|
7214 |
-
throw new Error("Inserting collapsed marker partially overlapping an existing one");
|
7215 |
-
sawCollapsedSpans = true;
|
7216 |
-
}
|
7217 |
-
|
7218 |
-
if (marker.addToHistory)
|
7219 |
-
addToHistory(doc, {from: from, to: to, origin: "markText"},
|
7220 |
-
{head: doc.sel.head, anchor: doc.sel.anchor}, NaN);
|
7221 |
-
|
7222 |
-
var curLine = from.line, cm = doc.cm, updateMaxLine;
|
7223 |
-
doc.iter(curLine, to.line + 1, function(line) {
|
7224 |
-
if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
|
7225 |
-
updateMaxLine = true;
|
7226 |
-
var span = {from: null, to: null, marker: marker};
|
7227 |
-
if (curLine == from.line) span.from = from.ch;
|
7228 |
-
if (curLine == to.line) span.to = to.ch;
|
7229 |
-
if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
|
7230 |
-
addMarkedSpan(line, span);
|
7231 |
-
++curLine;
|
7232 |
-
});
|
7233 |
-
if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
|
7234 |
-
if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
|
7235 |
-
});
|
7236 |
-
|
7237 |
-
if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
|
7238 |
-
|
7239 |
-
if (marker.readOnly) {
|
7240 |
-
sawReadOnlySpans = true;
|
7241 |
-
if (doc.history.done.length || doc.history.undone.length)
|
7242 |
-
doc.clearHistory();
|
7243 |
-
}
|
7244 |
-
if (marker.collapsed) {
|
7245 |
-
marker.id = ++nextMarkerId;
|
7246 |
-
marker.atomic = true;
|
7247 |
-
}
|
7248 |
-
if (cm) {
|
7249 |
-
if (updateMaxLine) cm.curOp.updateMaxLine = true;
|
7250 |
-
if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
|
7251 |
-
regChange(cm, from.line, to.line + 1);
|
7252 |
-
if (marker.atomic) reCheckSelection(cm);
|
7253 |
-
}
|
7254 |
-
return marker;
|
7255 |
-
}
|
7256 |
-
|
7257 |
-
// SHARED TEXTMARKERS
|
7258 |
-
|
7259 |
-
function SharedTextMarker(markers, primary) {
|
7260 |
-
this.markers = markers;
|
7261 |
-
this.primary = primary;
|
7262 |
-
for (var i = 0, me = this; i < markers.length; ++i) {
|
7263 |
-
markers[i].parent = this;
|
7264 |
-
on(markers[i], "clear", function(){me.clear();});
|
7265 |
-
}
|
7266 |
-
}
|
7267 |
-
CodeMirror.SharedTextMarker = SharedTextMarker;
|
7268 |
-
eventMixin(SharedTextMarker);
|
7269 |
-
|
7270 |
-
SharedTextMarker.prototype.clear = function() {
|
7271 |
-
if (this.explicitlyCleared) return;
|
7272 |
-
this.explicitlyCleared = true;
|
7273 |
-
for (var i = 0; i < this.markers.length; ++i)
|
7274 |
-
this.markers[i].clear();
|
7275 |
-
signalLater(this, "clear");
|
7276 |
-
};
|
7277 |
-
SharedTextMarker.prototype.find = function() {
|
7278 |
-
return this.primary.find();
|
7279 |
-
};
|
7280 |
-
|
7281 |
-
function markTextShared(doc, from, to, options, type) {
|
7282 |
-
options = copyObj(options);
|
7283 |
-
options.shared = false;
|
7284 |
-
var markers = [markText(doc, from, to, options, type)], primary = markers[0];
|
7285 |
-
var widget = options.replacedWith;
|
7286 |
-
linkedDocs(doc, function(doc) {
|
7287 |
-
if (widget) options.replacedWith = widget.cloneNode(true);
|
7288 |
-
markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
|
7289 |
-
for (var i = 0; i < doc.linked.length; ++i)
|
7290 |
-
if (doc.linked[i].isParent) return;
|
7291 |
-
primary = lst(markers);
|
7292 |
-
});
|
7293 |
-
return new SharedTextMarker(markers, primary);
|
7294 |
-
}
|
7295 |
-
|
7296 |
-
// TEXTMARKER SPANS
|
7297 |
-
|
7298 |
-
function getMarkedSpanFor(spans, marker) {
|
7299 |
-
if (spans) for (var i = 0; i < spans.length; ++i) {
|
7300 |
-
var span = spans[i];
|
7301 |
-
if (span.marker == marker) return span;
|
7302 |
-
}
|
7303 |
-
}
|
7304 |
-
function removeMarkedSpan(spans, span) {
|
7305 |
-
for (var r, i = 0; i < spans.length; ++i)
|
7306 |
-
if (spans[i] != span) (r || (r = [])).push(spans[i]);
|
7307 |
-
return r;
|
7308 |
-
}
|
7309 |
-
function addMarkedSpan(line, span) {
|
7310 |
-
line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
|
7311 |
-
span.marker.attachLine(line);
|
7312 |
-
}
|
7313 |
-
|
7314 |
-
function markedSpansBefore(old, startCh, isInsert) {
|
7315 |
-
if (old) for (var i = 0, nw; i < old.length; ++i) {
|
7316 |
-
var span = old[i], marker = span.marker;
|
7317 |
-
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
|
7318 |
-
if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
|
7319 |
-
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
|
7320 |
-
(nw || (nw = [])).push({from: span.from,
|
7321 |
-
to: endsAfter ? null : span.to,
|
7322 |
-
marker: marker});
|
7323 |
-
}
|
7324 |
-
}
|
7325 |
-
return nw;
|
7326 |
-
}
|
7327 |
-
|
7328 |
-
function markedSpansAfter(old, endCh, isInsert) {
|
7329 |
-
if (old) for (var i = 0, nw; i < old.length; ++i) {
|
7330 |
-
var span = old[i], marker = span.marker;
|
7331 |
-
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
|
7332 |
-
if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
|
7333 |
-
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
|
7334 |
-
(nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
|
7335 |
-
to: span.to == null ? null : span.to - endCh,
|
7336 |
-
marker: marker});
|
7337 |
-
}
|
7338 |
-
}
|
7339 |
-
return nw;
|
7340 |
-
}
|
7341 |
-
|
7342 |
-
function stretchSpansOverChange(doc, change) {
|
7343 |
-
var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
|
7344 |
-
var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
|
7345 |
-
if (!oldFirst && !oldLast) return null;
|
7346 |
-
|
7347 |
-
var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
|
7348 |
-
// Get the spans that 'stick out' on both sides
|
7349 |
-
var first = markedSpansBefore(oldFirst, startCh, isInsert);
|
7350 |
-
var last = markedSpansAfter(oldLast, endCh, isInsert);
|
7351 |
-
|
7352 |
-
// Next, merge those two ends
|
7353 |
-
var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
|
7354 |
-
if (first) {
|
7355 |
-
// Fix up .to properties of first
|
7356 |
-
for (var i = 0; i < first.length; ++i) {
|
7357 |
-
var span = first[i];
|
7358 |
-
if (span.to == null) {
|
7359 |
-
var found = getMarkedSpanFor(last, span.marker);
|
7360 |
-
if (!found) span.to = startCh;
|
7361 |
-
else if (sameLine) span.to = found.to == null ? null : found.to + offset;
|
7362 |
-
}
|
7363 |
-
}
|
7364 |
-
}
|
7365 |
-
if (last) {
|
7366 |
-
// Fix up .from in last (or move them into first in case of sameLine)
|
7367 |
-
for (var i = 0; i < last.length; ++i) {
|
7368 |
-
var span = last[i];
|
7369 |
-
if (span.to != null) span.to += offset;
|
7370 |
-
if (span.from == null) {
|
7371 |
-
var found = getMarkedSpanFor(first, span.marker);
|
7372 |
-
if (!found) {
|
7373 |
-
span.from = offset;
|
7374 |
-
if (sameLine) (first || (first = [])).push(span);
|
7375 |
-
}
|
7376 |
-
} else {
|
7377 |
-
span.from += offset;
|
7378 |
-
if (sameLine) (first || (first = [])).push(span);
|
7379 |
-
}
|
7380 |
-
}
|
7381 |
-
}
|
7382 |
-
// Make sure we didn't create any zero-length spans
|
7383 |
-
if (first) first = clearEmptySpans(first);
|
7384 |
-
if (last && last != first) last = clearEmptySpans(last);
|
7385 |
-
|
7386 |
-
var newMarkers = [first];
|
7387 |
-
if (!sameLine) {
|
7388 |
-
// Fill gap with whole-line-spans
|
7389 |
-
var gap = change.text.length - 2, gapMarkers;
|
7390 |
-
if (gap > 0 && first)
|
7391 |
-
for (var i = 0; i < first.length; ++i)
|
7392 |
-
if (first[i].to == null)
|
7393 |
-
(gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
|
7394 |
-
for (var i = 0; i < gap; ++i)
|
7395 |
-
newMarkers.push(gapMarkers);
|
7396 |
-
newMarkers.push(last);
|
7397 |
-
}
|
7398 |
-
return newMarkers;
|
7399 |
-
}
|
7400 |
-
|
7401 |
-
function clearEmptySpans(spans) {
|
7402 |
-
for (var i = 0; i < spans.length; ++i) {
|
7403 |
-
var span = spans[i];
|
7404 |
-
if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
|
7405 |
-
spans.splice(i--, 1);
|
7406 |
-
}
|
7407 |
-
if (!spans.length) return null;
|
7408 |
-
return spans;
|
7409 |
-
}
|
7410 |
-
|
7411 |
-
function mergeOldSpans(doc, change) {
|
7412 |
-
var old = getOldSpans(doc, change);
|
7413 |
-
var stretched = stretchSpansOverChange(doc, change);
|
7414 |
-
if (!old) return stretched;
|
7415 |
-
if (!stretched) return old;
|
7416 |
-
|
7417 |
-
for (var i = 0; i < old.length; ++i) {
|
7418 |
-
var oldCur = old[i], stretchCur = stretched[i];
|
7419 |
-
if (oldCur && stretchCur) {
|
7420 |
-
spans: for (var j = 0; j < stretchCur.length; ++j) {
|
7421 |
-
var span = stretchCur[j];
|
7422 |
-
for (var k = 0; k < oldCur.length; ++k)
|
7423 |
-
if (oldCur[k].marker == span.marker) continue spans;
|
7424 |
-
oldCur.push(span);
|
7425 |
-
}
|
7426 |
-
} else if (stretchCur) {
|
7427 |
-
old[i] = stretchCur;
|
7428 |
-
}
|
7429 |
-
}
|
7430 |
-
return old;
|
7431 |
-
}
|
7432 |
-
|
7433 |
-
function removeReadOnlyRanges(doc, from, to) {
|
7434 |
-
var markers = null;
|
7435 |
-
doc.iter(from.line, to.line + 1, function(line) {
|
7436 |
-
if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
|
7437 |
-
var mark = line.markedSpans[i].marker;
|
7438 |
-
if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
|
7439 |
-
(markers || (markers = [])).push(mark);
|
7440 |
-
}
|
7441 |
-
});
|
7442 |
-
if (!markers) return null;
|
7443 |
-
var parts = [{from: from, to: to}];
|
7444 |
-
for (var i = 0; i < markers.length; ++i) {
|
7445 |
-
var mk = markers[i], m = mk.find();
|
7446 |
-
for (var j = 0; j < parts.length; ++j) {
|
7447 |
-
var p = parts[j];
|
7448 |
-
if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue;
|
7449 |
-
var newParts = [j, 1];
|
7450 |
-
if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from))
|
7451 |
-
newParts.push({from: p.from, to: m.from});
|
7452 |
-
if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to))
|
7453 |
-
newParts.push({from: m.to, to: p.to});
|
7454 |
-
parts.splice.apply(parts, newParts);
|
7455 |
-
j += newParts.length - 1;
|
7456 |
-
}
|
7457 |
-
}
|
7458 |
-
return parts;
|
7459 |
-
}
|
7460 |
-
|
7461 |
-
function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
|
7462 |
-
function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
|
7463 |
-
|
7464 |
-
function compareCollapsedMarkers(a, b) {
|
7465 |
-
var lenDiff = a.lines.length - b.lines.length;
|
7466 |
-
if (lenDiff != 0) return lenDiff;
|
7467 |
-
var aPos = a.find(), bPos = b.find();
|
7468 |
-
var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
|
7469 |
-
if (fromCmp) return -fromCmp;
|
7470 |
-
var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
|
7471 |
-
if (toCmp) return toCmp;
|
7472 |
-
return b.id - a.id;
|
7473 |
-
}
|
7474 |
-
|
7475 |
-
function collapsedSpanAtSide(line, start) {
|
7476 |
-
var sps = sawCollapsedSpans && line.markedSpans, found;
|
7477 |
-
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
|
7478 |
-
sp = sps[i];
|
7479 |
-
if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
|
7480 |
-
(!found || compareCollapsedMarkers(found, sp.marker) < 0))
|
7481 |
-
found = sp.marker;
|
7482 |
-
}
|
7483 |
-
return found;
|
7484 |
-
}
|
7485 |
-
function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
|
7486 |
-
function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
|
7487 |
-
|
7488 |
-
function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
|
7489 |
-
var line = getLine(doc, lineNo);
|
7490 |
-
var sps = sawCollapsedSpans && line.markedSpans;
|
7491 |
-
if (sps) for (var i = 0; i < sps.length; ++i) {
|
7492 |
-
var sp = sps[i];
|
7493 |
-
if (!sp.marker.collapsed) continue;
|
7494 |
-
var found = sp.marker.find(true);
|
7495 |
-
var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
|
7496 |
-
var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
|
7497 |
-
if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;
|
7498 |
-
if (fromCmp <= 0 && (cmp(found.to, from) || extraRight(sp.marker) - extraLeft(marker)) > 0 ||
|
7499 |
-
fromCmp >= 0 && (cmp(found.from, to) || extraLeft(sp.marker) - extraRight(marker)) < 0)
|
7500 |
-
return true;
|
7501 |
-
}
|
7502 |
-
}
|
7503 |
-
|
7504 |
-
function visualLine(doc, line) {
|
7505 |
-
var merged;
|
7506 |
-
while (merged = collapsedSpanAtStart(line))
|
7507 |
-
line = getLine(doc, merged.find().from.line);
|
7508 |
-
return line;
|
7509 |
-
}
|
7510 |
-
|
7511 |
-
function lineIsHidden(doc, line) {
|
7512 |
-
var sps = sawCollapsedSpans && line.markedSpans;
|
7513 |
-
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
|
7514 |
-
sp = sps[i];
|
7515 |
-
if (!sp.marker.collapsed) continue;
|
7516 |
-
if (sp.from == null) return true;
|
7517 |
-
if (sp.marker.replacedWith) continue;
|
7518 |
-
if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
|
7519 |
-
return true;
|
7520 |
-
}
|
7521 |
-
}
|
7522 |
-
function lineIsHiddenInner(doc, line, span) {
|
7523 |
-
if (span.to == null) {
|
7524 |
-
var end = span.marker.find().to, endLine = getLine(doc, end.line);
|
7525 |
-
return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
|
7526 |
-
}
|
7527 |
-
if (span.marker.inclusiveRight && span.to == line.text.length)
|
7528 |
-
return true;
|
7529 |
-
for (var sp, i = 0; i < line.markedSpans.length; ++i) {
|
7530 |
-
sp = line.markedSpans[i];
|
7531 |
-
if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
|
7532 |
-
(sp.to == null || sp.to != span.from) &&
|
7533 |
-
(sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
|
7534 |
-
lineIsHiddenInner(doc, line, sp)) return true;
|
7535 |
-
}
|
7536 |
-
}
|
7537 |
-
|
7538 |
-
function detachMarkedSpans(line) {
|
7539 |
-
var spans = line.markedSpans;
|
7540 |
-
if (!spans) return;
|
7541 |
-
for (var i = 0; i < spans.length; ++i)
|
7542 |
-
spans[i].marker.detachLine(line);
|
7543 |
-
line.markedSpans = null;
|
7544 |
-
}
|
7545 |
-
|
7546 |
-
function attachMarkedSpans(line, spans) {
|
7547 |
-
if (!spans) return;
|
7548 |
-
for (var i = 0; i < spans.length; ++i)
|
7549 |
-
spans[i].marker.attachLine(line);
|
7550 |
-
line.markedSpans = spans;
|
7551 |
-
}
|
7552 |
-
|
7553 |
-
// LINE WIDGETS
|
7554 |
-
|
7555 |
-
var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
|
7556 |
-
if (options) for (var opt in options) if (options.hasOwnProperty(opt))
|
7557 |
-
this[opt] = options[opt];
|
7558 |
-
this.cm = cm;
|
7559 |
-
this.node = node;
|
7560 |
-
};
|
7561 |
-
eventMixin(LineWidget);
|
7562 |
-
function widgetOperation(f) {
|
7563 |
-
return function() {
|
7564 |
-
var withOp = !this.cm.curOp;
|
7565 |
-
if (withOp) startOperation(this.cm);
|
7566 |
-
try {var result = f.apply(this, arguments);}
|
7567 |
-
finally {if (withOp) endOperation(this.cm);}
|
7568 |
-
return result;
|
7569 |
-
};
|
7570 |
-
}
|
7571 |
-
LineWidget.prototype.clear = widgetOperation(function() {
|
7572 |
-
var ws = this.line.widgets, no = lineNo(this.line);
|
7573 |
-
if (no == null || !ws) return;
|
7574 |
-
for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
|
7575 |
-
if (!ws.length) this.line.widgets = null;
|
7576 |
-
var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
|
7577 |
-
updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
|
7578 |
-
if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
|
7579 |
-
regChange(this.cm, no, no + 1);
|
7580 |
-
});
|
7581 |
-
LineWidget.prototype.changed = widgetOperation(function() {
|
7582 |
-
var oldH = this.height;
|
7583 |
-
this.height = null;
|
7584 |
-
var diff = widgetHeight(this) - oldH;
|
7585 |
-
if (!diff) return;
|
7586 |
-
updateLineHeight(this.line, this.line.height + diff);
|
7587 |
-
var no = lineNo(this.line);
|
7588 |
-
regChange(this.cm, no, no + 1);
|
7589 |
-
});
|
7590 |
-
|
7591 |
-
function widgetHeight(widget) {
|
7592 |
-
if (widget.height != null) return widget.height;
|
7593 |
-
if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
|
7594 |
-
removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
|
7595 |
-
return widget.height = widget.node.offsetHeight;
|
7596 |
-
}
|
7597 |
-
|
7598 |
-
function addLineWidget(cm, handle, node, options) {
|
7599 |
-
var widget = new LineWidget(cm, node, options);
|
7600 |
-
if (widget.noHScroll) cm.display.alignWidgets = true;
|
7601 |
-
changeLine(cm, handle, function(line) {
|
7602 |
-
var widgets = line.widgets || (line.widgets = []);
|
7603 |
-
if (widget.insertAt == null) widgets.push(widget);
|
7604 |
-
else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
|
7605 |
-
widget.line = line;
|
7606 |
-
if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
|
7607 |
-
var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
|
7608 |
-
updateLineHeight(line, line.height + widgetHeight(widget));
|
7609 |
-
if (aboveVisible) addToScrollPos(cm, 0, widget.height);
|
7610 |
-
cm.curOp.forceUpdate = true;
|
7611 |
-
}
|
7612 |
-
return true;
|
7613 |
-
});
|
7614 |
-
return widget;
|
7615 |
-
}
|
7616 |
-
|
7617 |
-
// LINE DATA STRUCTURE
|
7618 |
-
|
7619 |
-
// Line objects. These hold state related to a line, including
|
7620 |
-
// highlighting info (the styles array).
|
7621 |
-
var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
|
7622 |
-
this.text = text;
|
7623 |
-
attachMarkedSpans(this, markedSpans);
|
7624 |
-
this.height = estimateHeight ? estimateHeight(this) : 1;
|
7625 |
-
};
|
7626 |
-
eventMixin(Line);
|
7627 |
-
Line.prototype.lineNo = function() { return lineNo(this); };
|
7628 |
-
|
7629 |
-
function updateLine(line, text, markedSpans, estimateHeight) {
|
7630 |
-
line.text = text;
|
7631 |
-
if (line.stateAfter) line.stateAfter = null;
|
7632 |
-
if (line.styles) line.styles = null;
|
7633 |
-
if (line.order != null) line.order = null;
|
7634 |
-
detachMarkedSpans(line);
|
7635 |
-
attachMarkedSpans(line, markedSpans);
|
7636 |
-
var estHeight = estimateHeight ? estimateHeight(line) : 1;
|
7637 |
-
if (estHeight != line.height) updateLineHeight(line, estHeight);
|
7638 |
-
}
|
7639 |
-
|
7640 |
-
function cleanUpLine(line) {
|
7641 |
-
line.parent = null;
|
7642 |
-
detachMarkedSpans(line);
|
7643 |
-
}
|
7644 |
-
|
7645 |
-
// Run the given mode's parser over a line, update the styles
|
7646 |
-
// array, which contains alternating fragments of text and CSS
|
7647 |
-
// classes.
|
7648 |
-
function runMode(cm, text, mode, state, f, forceToEnd) {
|
7649 |
-
var flattenSpans = mode.flattenSpans;
|
7650 |
-
if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
|
7651 |
-
var curStart = 0, curStyle = null;
|
7652 |
-
var stream = new StringStream(text, cm.options.tabSize), style;
|
7653 |
-
if (text == "" && mode.blankLine) mode.blankLine(state);
|
7654 |
-
while (!stream.eol()) {
|
7655 |
-
if (stream.pos > cm.options.maxHighlightLength) {
|
7656 |
-
flattenSpans = false;
|
7657 |
-
if (forceToEnd) processLine(cm, text, state, stream.pos);
|
7658 |
-
stream.pos = text.length;
|
7659 |
-
style = null;
|
7660 |
-
} else {
|
7661 |
-
style = mode.token(stream, state);
|
7662 |
-
}
|
7663 |
-
if (cm.options.addModeClass) {
|
7664 |
-
var mName = CodeMirror.innerMode(mode, state).mode.name;
|
7665 |
-
if (mName) style = "m-" + (style ? mName + " " + style : mName);
|
7666 |
-
}
|
7667 |
-
if (!flattenSpans || curStyle != style) {
|
7668 |
-
if (curStart < stream.start) f(stream.start, curStyle);
|
7669 |
-
curStart = stream.start; curStyle = style;
|
7670 |
-
}
|
7671 |
-
stream.start = stream.pos;
|
7672 |
-
}
|
7673 |
-
while (curStart < stream.pos) {
|
7674 |
-
// Webkit seems to refuse to render text nodes longer than 57444 characters
|
7675 |
-
var pos = Math.min(stream.pos, curStart + 50000);
|
7676 |
-
f(pos, curStyle);
|
7677 |
-
curStart = pos;
|
7678 |
-
}
|
7679 |
-
}
|
7680 |
-
|
7681 |
-
function highlightLine(cm, line, state, forceToEnd) {
|
7682 |
-
// A styles array always starts with a number identifying the
|
7683 |
-
// mode/overlays that it is based on (for easy invalidation).
|
7684 |
-
var st = [cm.state.modeGen];
|
7685 |
-
// Compute the base array of styles
|
7686 |
-
runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
|
7687 |
-
st.push(end, style);
|
7688 |
-
}, forceToEnd);
|
7689 |
-
|
7690 |
-
// Run overlays, adjust style array.
|
7691 |
-
for (var o = 0; o < cm.state.overlays.length; ++o) {
|
7692 |
-
var overlay = cm.state.overlays[o], i = 1, at = 0;
|
7693 |
-
runMode(cm, line.text, overlay.mode, true, function(end, style) {
|
7694 |
-
var start = i;
|
7695 |
-
// Ensure there's a token end at the current position, and that i points at it
|
7696 |
-
while (at < end) {
|
7697 |
-
var i_end = st[i];
|
7698 |
-
if (i_end > end)
|
7699 |
-
st.splice(i, 1, end, st[i+1], i_end);
|
7700 |
-
i += 2;
|
7701 |
-
at = Math.min(end, i_end);
|
7702 |
-
}
|
7703 |
-
if (!style) return;
|
7704 |
-
if (overlay.opaque) {
|
7705 |
-
st.splice(start, i - start, end, style);
|
7706 |
-
i = start + 2;
|
7707 |
-
} else {
|
7708 |
-
for (; start < i; start += 2) {
|
7709 |
-
var cur = st[start+1];
|
7710 |
-
st[start+1] = cur ? cur + " " + style : style;
|
7711 |
-
}
|
7712 |
-
}
|
7713 |
-
});
|
7714 |
-
}
|
7715 |
-
|
7716 |
-
return st;
|
7717 |
-
}
|
7718 |
-
|
7719 |
-
function getLineStyles(cm, line) {
|
7720 |
-
if (!line.styles || line.styles[0] != cm.state.modeGen)
|
7721 |
-
line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
|
7722 |
-
return line.styles;
|
7723 |
-
}
|
7724 |
-
|
7725 |
-
// Lightweight form of highlight -- proceed over this line and
|
7726 |
-
// update state, but don't save a style array.
|
7727 |
-
function processLine(cm, text, state, startAt) {
|
7728 |
-
var mode = cm.doc.mode;
|
7729 |
-
var stream = new StringStream(text, cm.options.tabSize);
|
7730 |
-
stream.start = stream.pos = startAt || 0;
|
7731 |
-
if (text == "" && mode.blankLine) mode.blankLine(state);
|
7732 |
-
while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
|
7733 |
-
mode.token(stream, state);
|
7734 |
-
stream.start = stream.pos;
|
7735 |
-
}
|
7736 |
-
}
|
7737 |
-
|
7738 |
-
var styleToClassCache = {}, styleToClassCacheWithMode = {};
|
7739 |
-
function interpretTokenStyle(style, builder) {
|
7740 |
-
if (!style) return null;
|
7741 |
-
for (;;) {
|
7742 |
-
var lineClass = style.match(/(?:^|\s+)line-(background-)?(\S+)/);
|
7743 |
-
if (!lineClass) break;
|
7744 |
-
style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length);
|
7745 |
-
var prop = lineClass[1] ? "bgClass" : "textClass";
|
7746 |
-
if (builder[prop] == null)
|
7747 |
-
builder[prop] = lineClass[2];
|
7748 |
-
else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop]))
|
7749 |
-
builder[prop] += " " + lineClass[2];
|
7750 |
-
}
|
7751 |
-
if (/^\s*$/.test(style)) return null;
|
7752 |
-
var cache = builder.cm.options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
|
7753 |
-
return cache[style] ||
|
7754 |
-
(cache[style] = style.replace(/\S+/g, "cm-$&"));
|
7755 |
-
}
|
7756 |
-
|
7757 |
-
function buildLineContent(cm, realLine, measure, copyWidgets) {
|
7758 |
-
var merged, line = realLine, empty = true;
|
7759 |
-
while (merged = collapsedSpanAtStart(line))
|
7760 |
-
line = getLine(cm.doc, merged.find().from.line);
|
7761 |
-
|
7762 |
-
var builder = {pre: elt("pre"), col: 0, pos: 0,
|
7763 |
-
measure: null, measuredSomething: false, cm: cm,
|
7764 |
-
copyWidgets: copyWidgets};
|
7765 |
-
|
7766 |
-
do {
|
7767 |
-
if (line.text) empty = false;
|
7768 |
-
builder.measure = line == realLine && measure;
|
7769 |
-
builder.pos = 0;
|
7770 |
-
builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
|
7771 |
-
if ((ie || webkit) && cm.getOption("lineWrapping"))
|
7772 |
-
builder.addToken = buildTokenSplitSpaces(builder.addToken);
|
7773 |
-
var next = insertLineContent(line, builder, getLineStyles(cm, line));
|
7774 |
-
if (measure && line == realLine && !builder.measuredSomething) {
|
7775 |
-
measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
|
7776 |
-
builder.measuredSomething = true;
|
7777 |
-
}
|
7778 |
-
if (next) line = getLine(cm.doc, next.to.line);
|
7779 |
-
} while (next);
|
7780 |
-
|
7781 |
-
if (measure && !builder.measuredSomething && !measure[0])
|
7782 |
-
measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
|
7783 |
-
if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine))
|
7784 |
-
builder.pre.appendChild(document.createTextNode("\u00a0"));
|
7785 |
-
|
7786 |
-
var order;
|
7787 |
-
// Work around problem with the reported dimensions of single-char
|
7788 |
-
// direction spans on IE (issue #1129). See also the comment in
|
7789 |
-
// cursorCoords.
|
7790 |
-
if (measure && ie && (order = getOrder(line))) {
|
7791 |
-
var l = order.length - 1;
|
7792 |
-
if (order[l].from == order[l].to) --l;
|
7793 |
-
var last = order[l], prev = order[l - 1];
|
7794 |
-
if (last.from + 1 == last.to && prev && last.level < prev.level) {
|
7795 |
-
var span = measure[builder.pos - 1];
|
7796 |
-
if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
|
7797 |
-
span.nextSibling);
|
7798 |
-
}
|
7799 |
-
}
|
7800 |
-
|
7801 |
-
var textClass = builder.textClass ? builder.textClass + " " + (realLine.textClass || "") : realLine.textClass;
|
7802 |
-
if (textClass) builder.pre.className = textClass;
|
7803 |
-
|
7804 |
-
signal(cm, "renderLine", cm, realLine, builder.pre);
|
7805 |
-
return builder;
|
7806 |
-
}
|
7807 |
-
|
7808 |
-
function defaultSpecialCharPlaceholder(ch) {
|
7809 |
-
var token = elt("span", "\u2022", "cm-invalidchar");
|
7810 |
-
token.title = "\\u" + ch.charCodeAt(0).toString(16);
|
7811 |
-
return token;
|
7812 |
-
}
|
7813 |
-
|
7814 |
-
function buildToken(builder, text, style, startStyle, endStyle, title) {
|
7815 |
-
if (!text) return;
|
7816 |
-
var special = builder.cm.options.specialChars;
|
7817 |
-
if (!special.test(text)) {
|
7818 |
-
builder.col += text.length;
|
7819 |
-
var content = document.createTextNode(text);
|
7820 |
-
} else {
|
7821 |
-
var content = document.createDocumentFragment(), pos = 0;
|
7822 |
-
while (true) {
|
7823 |
-
special.lastIndex = pos;
|
7824 |
-
var m = special.exec(text);
|
7825 |
-
var skipped = m ? m.index - pos : text.length - pos;
|
7826 |
-
if (skipped) {
|
7827 |
-
content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
|
7828 |
-
builder.col += skipped;
|
7829 |
-
}
|
7830 |
-
if (!m) break;
|
7831 |
-
pos += skipped + 1;
|
7832 |
-
if (m[0] == "\t") {
|
7833 |
-
var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
|
7834 |
-
content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
|
7835 |
-
builder.col += tabWidth;
|
7836 |
-
} else {
|
7837 |
-
var token = builder.cm.options.specialCharPlaceholder(m[0]);
|
7838 |
-
content.appendChild(token);
|
7839 |
-
builder.col += 1;
|
7840 |
-
}
|
7841 |
-
}
|
7842 |
-
}
|
7843 |
-
if (style || startStyle || endStyle || builder.measure) {
|
7844 |
-
var fullStyle = style || "";
|
7845 |
-
if (startStyle) fullStyle += startStyle;
|
7846 |
-
if (endStyle) fullStyle += endStyle;
|
7847 |
-
var token = elt("span", [content], fullStyle);
|
7848 |
-
if (title) token.title = title;
|
7849 |
-
return builder.pre.appendChild(token);
|
7850 |
-
}
|
7851 |
-
builder.pre.appendChild(content);
|
7852 |
-
}
|
7853 |
-
|
7854 |
-
function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
|
7855 |
-
var wrapping = builder.cm.options.lineWrapping;
|
7856 |
-
for (var i = 0; i < text.length; ++i) {
|
7857 |
-
var start = i == 0, to = i + 1;
|
7858 |
-
while (to < text.length && isExtendingChar(text.charAt(to))) ++to;
|
7859 |
-
var ch = text.slice(i, to);
|
7860 |
-
i = to - 1;
|
7861 |
-
if (i && wrapping && spanAffectsWrapping(text, i))
|
7862 |
-
builder.pre.appendChild(elt("wbr"));
|
7863 |
-
var old = builder.measure[builder.pos];
|
7864 |
-
var span = builder.measure[builder.pos] =
|
7865 |
-
buildToken(builder, ch, style,
|
7866 |
-
start && startStyle, i == text.length - 1 && endStyle);
|
7867 |
-
if (old) span.leftSide = old.leftSide || old;
|
7868 |
-
// In IE single-space nodes wrap differently than spaces
|
7869 |
-
// embedded in larger text nodes, except when set to
|
7870 |
-
// white-space: normal (issue #1268).
|
7871 |
-
if (old_ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
|
7872 |
-
i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
|
7873 |
-
span.style.whiteSpace = "normal";
|
7874 |
-
builder.pos += ch.length;
|
7875 |
-
}
|
7876 |
-
if (text.length) builder.measuredSomething = true;
|
7877 |
-
}
|
7878 |
-
|
7879 |
-
function buildTokenSplitSpaces(inner) {
|
7880 |
-
function split(old) {
|
7881 |
-
var out = " ";
|
7882 |
-
for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
|
7883 |
-
out += " ";
|
7884 |
-
return out;
|
7885 |
-
}
|
7886 |
-
return function(builder, text, style, startStyle, endStyle, title) {
|
7887 |
-
return inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);
|
7888 |
-
};
|
7889 |
-
}
|
7890 |
-
|
7891 |
-
function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
|
7892 |
-
var widget = !ignoreWidget && marker.replacedWith;
|
7893 |
-
if (widget) {
|
7894 |
-
if (builder.copyWidgets) widget = widget.cloneNode(true);
|
7895 |
-
builder.pre.appendChild(widget);
|
7896 |
-
if (builder.measure) {
|
7897 |
-
if (size) {
|
7898 |
-
builder.measure[builder.pos] = widget;
|
7899 |
-
} else {
|
7900 |
-
var elt = zeroWidthElement(builder.cm.display.measure);
|
7901 |
-
if (marker.type == "bookmark" && !marker.insertLeft)
|
7902 |
-
builder.measure[builder.pos] = builder.pre.appendChild(elt);
|
7903 |
-
else if (builder.measure[builder.pos])
|
7904 |
-
return;
|
7905 |
-
else
|
7906 |
-
builder.measure[builder.pos] = builder.pre.insertBefore(elt, widget);
|
7907 |
-
}
|
7908 |
-
builder.measuredSomething = true;
|
7909 |
-
}
|
7910 |
-
}
|
7911 |
-
builder.pos += size;
|
7912 |
-
}
|
7913 |
-
|
7914 |
-
// Outputs a number of spans to make up a line, taking highlighting
|
7915 |
-
// and marked text into account.
|
7916 |
-
function insertLineContent(line, builder, styles) {
|
7917 |
-
var spans = line.markedSpans, allText = line.text, at = 0;
|
7918 |
-
if (!spans) {
|
7919 |
-
for (var i = 1; i < styles.length; i+=2)
|
7920 |
-
builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder));
|
7921 |
-
return;
|
7922 |
-
}
|
7923 |
-
|
7924 |
-
var len = allText.length, pos = 0, i = 1, text = "", style;
|
7925 |
-
var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
|
7926 |
-
for (;;) {
|
7927 |
-
if (nextChange == pos) { // Update current marker set
|
7928 |
-
spanStyle = spanEndStyle = spanStartStyle = title = "";
|
7929 |
-
collapsed = null; nextChange = Infinity;
|
7930 |
-
var foundBookmarks = [];
|
7931 |
-
for (var j = 0; j < spans.length; ++j) {
|
7932 |
-
var sp = spans[j], m = sp.marker;
|
7933 |
-
if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
|
7934 |
-
if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
|
7935 |
-
if (m.className) spanStyle += " " + m.className;
|
7936 |
-
if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
|
7937 |
-
if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
|
7938 |
-
if (m.title && !title) title = m.title;
|
7939 |
-
if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
|
7940 |
-
collapsed = sp;
|
7941 |
-
} else if (sp.from > pos && nextChange > sp.from) {
|
7942 |
-
nextChange = sp.from;
|
7943 |
-
}
|
7944 |
-
if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmarks.push(m);
|
7945 |
-
}
|
7946 |
-
if (collapsed && (collapsed.from || 0) == pos) {
|
7947 |
-
buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
|
7948 |
-
collapsed.marker, collapsed.from == null);
|
7949 |
-
if (collapsed.to == null) return collapsed.marker.find();
|
7950 |
-
}
|
7951 |
-
if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
|
7952 |
-
buildCollapsedSpan(builder, 0, foundBookmarks[j]);
|
7953 |
-
}
|
7954 |
-
if (pos >= len) break;
|
7955 |
-
|
7956 |
-
var upto = Math.min(len, nextChange);
|
7957 |
-
while (true) {
|
7958 |
-
if (text) {
|
7959 |
-
var end = pos + text.length;
|
7960 |
-
if (!collapsed) {
|
7961 |
-
var tokenText = end > upto ? text.slice(0, upto - pos) : text;
|
7962 |
-
builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
|
7963 |
-
spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
|
7964 |
-
}
|
7965 |
-
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
|
7966 |
-
pos = end;
|
7967 |
-
spanStartStyle = "";
|
7968 |
-
}
|
7969 |
-
text = allText.slice(at, at = styles[i++]);
|
7970 |
-
style = interpretTokenStyle(styles[i++], builder);
|
7971 |
-
}
|
7972 |
-
}
|
7973 |
-
}
|
7974 |
-
|
7975 |
-
// DOCUMENT DATA STRUCTURE
|
7976 |
-
|
7977 |
-
function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) {
|
7978 |
-
function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
|
7979 |
-
function update(line, text, spans) {
|
7980 |
-
updateLine(line, text, spans, estimateHeight);
|
7981 |
-
signalLater(line, "change", line, change);
|
7982 |
-
}
|
7983 |
-
|
7984 |
-
var from = change.from, to = change.to, text = change.text;
|
7985 |
-
var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
|
7986 |
-
var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
|
7987 |
-
|
7988 |
-
// First adjust the line structure
|
7989 |
-
if (from.ch == 0 && to.ch == 0 && lastText == "" &&
|
7990 |
-
(!doc.cm || doc.cm.options.wholeLineUpdateBefore)) {
|
7991 |
-
// This is a whole-line replace. Treated specially to make
|
7992 |
-
// sure line objects move the way they are supposed to.
|
7993 |
-
for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
|
7994 |
-
added.push(new Line(text[i], spansFor(i), estimateHeight));
|
7995 |
-
update(lastLine, lastLine.text, lastSpans);
|
7996 |
-
if (nlines) doc.remove(from.line, nlines);
|
7997 |
-
if (added.length) doc.insert(from.line, added);
|
7998 |
-
} else if (firstLine == lastLine) {
|
7999 |
-
if (text.length == 1) {
|
8000 |
-
update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
|
8001 |
-
} else {
|
8002 |
-
for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
|
8003 |
-
added.push(new Line(text[i], spansFor(i), estimateHeight));
|
8004 |
-
added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
|
8005 |
-
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
|
8006 |
-
doc.insert(from.line + 1, added);
|
8007 |
-
}
|
8008 |
-
} else if (text.length == 1) {
|
8009 |
-
update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
|
8010 |
-
doc.remove(from.line + 1, nlines);
|
8011 |
-
} else {
|
8012 |
-
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
|
8013 |
-
update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
|
8014 |
-
for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
|
8015 |
-
added.push(new Line(text[i], spansFor(i), estimateHeight));
|
8016 |
-
if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
|
8017 |
-
doc.insert(from.line + 1, added);
|
8018 |
-
}
|
8019 |
-
|
8020 |
-
signalLater(doc, "change", doc, change);
|
8021 |
-
setSelection(doc, selAfter.anchor, selAfter.head, null, true);
|
8022 |
-
}
|
8023 |
-
|
8024 |
-
function LeafChunk(lines) {
|
8025 |
-
this.lines = lines;
|
8026 |
-
this.parent = null;
|
8027 |
-
for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
|
8028 |
-
lines[i].parent = this;
|
8029 |
-
height += lines[i].height;
|
8030 |
-
}
|
8031 |
-
this.height = height;
|
8032 |
-
}
|
8033 |
-
|
8034 |
-
LeafChunk.prototype = {
|
8035 |
-
chunkSize: function() { return this.lines.length; },
|
8036 |
-
removeInner: function(at, n) {
|
8037 |
-
for (var i = at, e = at + n; i < e; ++i) {
|
8038 |
-
var line = this.lines[i];
|
8039 |
-
this.height -= line.height;
|
8040 |
-
cleanUpLine(line);
|
8041 |
-
signalLater(line, "delete");
|
8042 |
-
}
|
8043 |
-
this.lines.splice(at, n);
|
8044 |
-
},
|
8045 |
-
collapse: function(lines) {
|
8046 |
-
lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
|
8047 |
-
},
|
8048 |
-
insertInner: function(at, lines, height) {
|
8049 |
-
this.height += height;
|
8050 |
-
this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
|
8051 |
-
for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
|
8052 |
-
},
|
8053 |
-
iterN: function(at, n, op) {
|
8054 |
-
for (var e = at + n; at < e; ++at)
|
8055 |
-
if (op(this.lines[at])) return true;
|
8056 |
-
}
|
8057 |
-
};
|
8058 |
-
|
8059 |
-
function BranchChunk(children) {
|
8060 |
-
this.children = children;
|
8061 |
-
var size = 0, height = 0;
|
8062 |
-
for (var i = 0, e = children.length; i < e; ++i) {
|
8063 |
-
var ch = children[i];
|
8064 |
-
size += ch.chunkSize(); height += ch.height;
|
8065 |
-
ch.parent = this;
|
8066 |
-
}
|
8067 |
-
this.size = size;
|
8068 |
-
this.height = height;
|
8069 |
-
this.parent = null;
|
8070 |
-
}
|
8071 |
-
|
8072 |
-
BranchChunk.prototype = {
|
8073 |
-
chunkSize: function() { return this.size; },
|
8074 |
-
removeInner: function(at, n) {
|
8075 |
-
this.size -= n;
|
8076 |
-
for (var i = 0; i < this.children.length; ++i) {
|
8077 |
-
var child = this.children[i], sz = child.chunkSize();
|
8078 |
-
if (at < sz) {
|
8079 |
-
var rm = Math.min(n, sz - at), oldHeight = child.height;
|
8080 |
-
child.removeInner(at, rm);
|
8081 |
-
this.height -= oldHeight - child.height;
|
8082 |
-
if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
|
8083 |
-
if ((n -= rm) == 0) break;
|
8084 |
-
at = 0;
|
8085 |
-
} else at -= sz;
|
8086 |
-
}
|
8087 |
-
if (this.size - n < 25) {
|
8088 |
-
var lines = [];
|
8089 |
-
this.collapse(lines);
|
8090 |
-
this.children = [new LeafChunk(lines)];
|
8091 |
-
this.children[0].parent = this;
|
8092 |
-
}
|
8093 |
-
},
|
8094 |
-
collapse: function(lines) {
|
8095 |
-
for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
|
8096 |
-
},
|
8097 |
-
insertInner: function(at, lines, height) {
|
8098 |
-
this.size += lines.length;
|
8099 |
-
this.height += height;
|
8100 |
-
for (var i = 0, e = this.children.length; i < e; ++i) {
|
8101 |
-
var child = this.children[i], sz = child.chunkSize();
|
8102 |
-
if (at <= sz) {
|
8103 |
-
child.insertInner(at, lines, height);
|
8104 |
-
if (child.lines && child.lines.length > 50) {
|
8105 |
-
while (child.lines.length > 50) {
|
8106 |
-
var spilled = child.lines.splice(child.lines.length - 25, 25);
|
8107 |
-
var newleaf = new LeafChunk(spilled);
|
8108 |
-
child.height -= newleaf.height;
|
8109 |
-
this.children.splice(i + 1, 0, newleaf);
|
8110 |
-
newleaf.parent = this;
|
8111 |
-
}
|
8112 |
-
this.maybeSpill();
|
8113 |
-
}
|
8114 |
-
break;
|
8115 |
-
}
|
8116 |
-
at -= sz;
|
8117 |
-
}
|
8118 |
-
},
|
8119 |
-
maybeSpill: function() {
|
8120 |
-
if (this.children.length <= 10) return;
|
8121 |
-
var me = this;
|
8122 |
-
do {
|
8123 |
-
var spilled = me.children.splice(me.children.length - 5, 5);
|
8124 |
-
var sibling = new BranchChunk(spilled);
|
8125 |
-
if (!me.parent) { // Become the parent node
|
8126 |
-
var copy = new BranchChunk(me.children);
|
8127 |
-
copy.parent = me;
|
8128 |
-
me.children = [copy, sibling];
|
8129 |
-
me = copy;
|
8130 |
-
} else {
|
8131 |
-
me.size -= sibling.size;
|
8132 |
-
me.height -= sibling.height;
|
8133 |
-
var myIndex = indexOf(me.parent.children, me);
|
8134 |
-
me.parent.children.splice(myIndex + 1, 0, sibling);
|
8135 |
-
}
|
8136 |
-
sibling.parent = me.parent;
|
8137 |
-
} while (me.children.length > 10);
|
8138 |
-
me.parent.maybeSpill();
|
8139 |
-
},
|
8140 |
-
iterN: function(at, n, op) {
|
8141 |
-
for (var i = 0, e = this.children.length; i < e; ++i) {
|
8142 |
-
var child = this.children[i], sz = child.chunkSize();
|
8143 |
-
if (at < sz) {
|
8144 |
-
var used = Math.min(n, sz - at);
|
8145 |
-
if (child.iterN(at, used, op)) return true;
|
8146 |
-
if ((n -= used) == 0) break;
|
8147 |
-
at = 0;
|
8148 |
-
} else at -= sz;
|
8149 |
-
}
|
8150 |
-
}
|
8151 |
-
};
|
8152 |
-
|
8153 |
-
var nextDocId = 0;
|
8154 |
-
var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
|
8155 |
-
if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
|
8156 |
-
if (firstLine == null) firstLine = 0;
|
8157 |
-
|
8158 |
-
BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
|
8159 |
-
this.first = firstLine;
|
8160 |
-
this.scrollTop = this.scrollLeft = 0;
|
8161 |
-
this.cantEdit = false;
|
8162 |
-
this.history = makeHistory();
|
8163 |
-
this.cleanGeneration = 1;
|
8164 |
-
this.frontier = firstLine;
|
8165 |
-
var start = Pos(firstLine, 0);
|
8166 |
-
this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null};
|
8167 |
-
this.id = ++nextDocId;
|
8168 |
-
this.modeOption = mode;
|
8169 |
-
|
8170 |
-
if (typeof text == "string") text = splitLines(text);
|
8171 |
-
updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start});
|
8172 |
-
};
|
8173 |
-
|
8174 |
-
Doc.prototype = createObj(BranchChunk.prototype, {
|
8175 |
-
constructor: Doc,
|
8176 |
-
iter: function(from, to, op) {
|
8177 |
-
if (op) this.iterN(from - this.first, to - from, op);
|
8178 |
-
else this.iterN(this.first, this.first + this.size, from);
|
8179 |
-
},
|
8180 |
-
|
8181 |
-
insert: function(at, lines) {
|
8182 |
-
var height = 0;
|
8183 |
-
for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
|
8184 |
-
this.insertInner(at - this.first, lines, height);
|
8185 |
-
},
|
8186 |
-
remove: function(at, n) { this.removeInner(at - this.first, n); },
|
8187 |
-
|
8188 |
-
getValue: function(lineSep) {
|
8189 |
-
var lines = getLines(this, this.first, this.first + this.size);
|
8190 |
-
if (lineSep === false) return lines;
|
8191 |
-
return lines.join(lineSep || "\n");
|
8192 |
-
},
|
8193 |
-
setValue: function(code) {
|
8194 |
-
var top = Pos(this.first, 0), last = this.first + this.size - 1;
|
8195 |
-
makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
|
8196 |
-
text: splitLines(code), origin: "setValue"},
|
8197 |
-
{head: top, anchor: top}, true);
|
8198 |
-
},
|
8199 |
-
replaceRange: function(code, from, to, origin) {
|
8200 |
-
from = clipPos(this, from);
|
8201 |
-
to = to ? clipPos(this, to) : from;
|
8202 |
-
replaceRange(this, code, from, to, origin);
|
8203 |
-
},
|
8204 |
-
getRange: function(from, to, lineSep) {
|
8205 |
-
var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
|
8206 |
-
if (lineSep === false) return lines;
|
8207 |
-
return lines.join(lineSep || "\n");
|
8208 |
-
},
|
8209 |
-
|
8210 |
-
getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
|
8211 |
-
setLine: function(line, text) {
|
8212 |
-
if (isLine(this, line))
|
8213 |
-
replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line)));
|
8214 |
-
},
|
8215 |
-
removeLine: function(line) {
|
8216 |
-
if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line)));
|
8217 |
-
else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0)));
|
8218 |
-
},
|
8219 |
-
|
8220 |
-
getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
|
8221 |
-
getLineNumber: function(line) {return lineNo(line);},
|
8222 |
-
|
8223 |
-
getLineHandleVisualStart: function(line) {
|
8224 |
-
if (typeof line == "number") line = getLine(this, line);
|
8225 |
-
return visualLine(this, line);
|
8226 |
-
},
|
8227 |
-
|
8228 |
-
lineCount: function() {return this.size;},
|
8229 |
-
firstLine: function() {return this.first;},
|
8230 |
-
lastLine: function() {return this.first + this.size - 1;},
|
8231 |
-
|
8232 |
-
clipPos: function(pos) {return clipPos(this, pos);},
|
8233 |
-
|
8234 |
-
getCursor: function(start) {
|
8235 |
-
var sel = this.sel, pos;
|
8236 |
-
if (start == null || start == "head") pos = sel.head;
|
8237 |
-
else if (start == "anchor") pos = sel.anchor;
|
8238 |
-
else if (start == "end" || start === false) pos = sel.to;
|
8239 |
-
else pos = sel.from;
|
8240 |
-
return copyPos(pos);
|
8241 |
-
},
|
8242 |
-
somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);},
|
8243 |
-
|
8244 |
-
setCursor: docOperation(function(line, ch, extend) {
|
8245 |
-
var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line);
|
8246 |
-
if (extend) extendSelection(this, pos);
|
8247 |
-
else setSelection(this, pos, pos);
|
8248 |
-
}),
|
8249 |
-
setSelection: docOperation(function(anchor, head, bias) {
|
8250 |
-
setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), bias);
|
8251 |
-
}),
|
8252 |
-
extendSelection: docOperation(function(from, to, bias) {
|
8253 |
-
extendSelection(this, clipPos(this, from), to && clipPos(this, to), bias);
|
8254 |
-
}),
|
8255 |
-
|
8256 |
-
getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
|
8257 |
-
replaceSelection: function(code, collapse, origin) {
|
8258 |
-
makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around");
|
8259 |
-
},
|
8260 |
-
undo: docOperation(function() {makeChangeFromHistory(this, "undo");}),
|
8261 |
-
redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),
|
8262 |
-
|
8263 |
-
setExtending: function(val) {this.sel.extend = val;},
|
8264 |
-
|
8265 |
-
historySize: function() {
|
8266 |
-
var hist = this.history;
|
8267 |
-
return {undo: hist.done.length, redo: hist.undone.length};
|
8268 |
-
},
|
8269 |
-
clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},
|
8270 |
-
|
8271 |
-
markClean: function() {
|
8272 |
-
this.cleanGeneration = this.changeGeneration(true);
|
8273 |
-
},
|
8274 |
-
changeGeneration: function(forceSplit) {
|
8275 |
-
if (forceSplit)
|
8276 |
-
this.history.lastOp = this.history.lastOrigin = null;
|
8277 |
-
return this.history.generation;
|
8278 |
-
},
|
8279 |
-
isClean: function (gen) {
|
8280 |
-
return this.history.generation == (gen || this.cleanGeneration);
|
8281 |
-
},
|
8282 |
-
|
8283 |
-
getHistory: function() {
|
8284 |
-
return {done: copyHistoryArray(this.history.done),
|
8285 |
-
undone: copyHistoryArray(this.history.undone)};
|
8286 |
-
},
|
8287 |
-
setHistory: function(histData) {
|
8288 |
-
var hist = this.history = makeHistory(this.history.maxGeneration);
|
8289 |
-
hist.done = histData.done.slice(0);
|
8290 |
-
hist.undone = histData.undone.slice(0);
|
8291 |
-
},
|
8292 |
-
|
8293 |
-
markText: function(from, to, options) {
|
8294 |
-
return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
|
8295 |
-
},
|
8296 |
-
setBookmark: function(pos, options) {
|
8297 |
-
var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
|
8298 |
-
insertLeft: options && options.insertLeft,
|
8299 |
-
clearWhenEmpty: false};
|
8300 |
-
pos = clipPos(this, pos);
|
8301 |
-
return markText(this, pos, pos, realOpts, "bookmark");
|
8302 |
-
},
|
8303 |
-
findMarksAt: function(pos) {
|
8304 |
-
pos = clipPos(this, pos);
|
8305 |
-
var markers = [], spans = getLine(this, pos.line).markedSpans;
|
8306 |
-
if (spans) for (var i = 0; i < spans.length; ++i) {
|
8307 |
-
var span = spans[i];
|
8308 |
-
if ((span.from == null || span.from <= pos.ch) &&
|
8309 |
-
(span.to == null || span.to >= pos.ch))
|
8310 |
-
markers.push(span.marker.parent || span.marker);
|
8311 |
-
}
|
8312 |
-
return markers;
|
8313 |
-
},
|
8314 |
-
findMarks: function(from, to) {
|
8315 |
-
from = clipPos(this, from); to = clipPos(this, to);
|
8316 |
-
var found = [], lineNo = from.line;
|
8317 |
-
this.iter(from.line, to.line + 1, function(line) {
|
8318 |
-
var spans = line.markedSpans;
|
8319 |
-
if (spans) for (var i = 0; i < spans.length; i++) {
|
8320 |
-
var span = spans[i];
|
8321 |
-
if (!(lineNo == from.line && from.ch > span.to ||
|
8322 |
-
span.from == null && lineNo != from.line||
|
8323 |
-
lineNo == to.line && span.from > to.ch))
|
8324 |
-
found.push(span.marker.parent || span.marker);
|
8325 |
-
}
|
8326 |
-
++lineNo;
|
8327 |
-
});
|
8328 |
-
return found;
|
8329 |
-
},
|
8330 |
-
getAllMarks: function() {
|
8331 |
-
var markers = [];
|
8332 |
-
this.iter(function(line) {
|
8333 |
-
var sps = line.markedSpans;
|
8334 |
-
if (sps) for (var i = 0; i < sps.length; ++i)
|
8335 |
-
if (sps[i].from != null) markers.push(sps[i].marker);
|
8336 |
-
});
|
8337 |
-
return markers;
|
8338 |
-
},
|
8339 |
-
|
8340 |
-
posFromIndex: function(off) {
|
8341 |
-
var ch, lineNo = this.first;
|
8342 |
-
this.iter(function(line) {
|
8343 |
-
var sz = line.text.length + 1;
|
8344 |
-
if (sz > off) { ch = off; return true; }
|
8345 |
-
off -= sz;
|
8346 |
-
++lineNo;
|
8347 |
-
});
|
8348 |
-
return clipPos(this, Pos(lineNo, ch));
|
8349 |
-
},
|
8350 |
-
indexFromPos: function (coords) {
|
8351 |
-
coords = clipPos(this, coords);
|
8352 |
-
var index = coords.ch;
|
8353 |
-
if (coords.line < this.first || coords.ch < 0) return 0;
|
8354 |
-
this.iter(this.first, coords.line, function (line) {
|
8355 |
-
index += line.text.length + 1;
|
8356 |
-
});
|
8357 |
-
return index;
|
8358 |
-
},
|
8359 |
-
|
8360 |
-
copy: function(copyHistory) {
|
8361 |
-
var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
|
8362 |
-
doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
|
8363 |
-
doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor,
|
8364 |
-
shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn};
|
8365 |
-
if (copyHistory) {
|
8366 |
-
doc.history.undoDepth = this.history.undoDepth;
|
8367 |
-
doc.setHistory(this.getHistory());
|
8368 |
-
}
|
8369 |
-
return doc;
|
8370 |
-
},
|
8371 |
-
|
8372 |
-
linkedDoc: function(options) {
|
8373 |
-
if (!options) options = {};
|
8374 |
-
var from = this.first, to = this.first + this.size;
|
8375 |
-
if (options.from != null && options.from > from) from = options.from;
|
8376 |
-
if (options.to != null && options.to < to) to = options.to;
|
8377 |
-
var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
|
8378 |
-
if (options.sharedHist) copy.history = this.history;
|
8379 |
-
(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
|
8380 |
-
copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
|
8381 |
-
return copy;
|
8382 |
-
},
|
8383 |
-
unlinkDoc: function(other) {
|
8384 |
-
if (other instanceof CodeMirror) other = other.doc;
|
8385 |
-
if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
|
8386 |
-
var link = this.linked[i];
|
8387 |
-
if (link.doc != other) continue;
|
8388 |
-
this.linked.splice(i, 1);
|
8389 |
-
other.unlinkDoc(this);
|
8390 |
-
break;
|
8391 |
-
}
|
8392 |
-
// If the histories were shared, split them again
|
8393 |
-
if (other.history == this.history) {
|
8394 |
-
var splitIds = [other.id];
|
8395 |
-
linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
|
8396 |
-
other.history = makeHistory();
|
8397 |
-
other.history.done = copyHistoryArray(this.history.done, splitIds);
|
8398 |
-
other.history.undone = copyHistoryArray(this.history.undone, splitIds);
|
8399 |
-
}
|
8400 |
-
},
|
8401 |
-
iterLinkedDocs: function(f) {linkedDocs(this, f);},
|
8402 |
-
|
8403 |
-
getMode: function() {return this.mode;},
|
8404 |
-
getEditor: function() {return this.cm;}
|
8405 |
-
});
|
8406 |
-
|
8407 |
-
Doc.prototype.eachLine = Doc.prototype.iter;
|
8408 |
-
|
8409 |
-
// The Doc methods that should be available on CodeMirror instances
|
8410 |
-
var dontDelegate = "iter insert remove copy getEditor".split(" ");
|
8411 |
-
for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
|
8412 |
-
CodeMirror.prototype[prop] = (function(method) {
|
8413 |
-
return function() {return method.apply(this.doc, arguments);};
|
8414 |
-
})(Doc.prototype[prop]);
|
8415 |
-
|
8416 |
-
eventMixin(Doc);
|
8417 |
-
|
8418 |
-
function linkedDocs(doc, f, sharedHistOnly) {
|
8419 |
-
function propagate(doc, skip, sharedHist) {
|
8420 |
-
if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
|
8421 |
-
var rel = doc.linked[i];
|
8422 |
-
if (rel.doc == skip) continue;
|
8423 |
-
var shared = sharedHist && rel.sharedHist;
|
8424 |
-
if (sharedHistOnly && !shared) continue;
|
8425 |
-
f(rel.doc, shared);
|
8426 |
-
propagate(rel.doc, doc, shared);
|
8427 |
-
}
|
8428 |
-
}
|
8429 |
-
propagate(doc, null, true);
|
8430 |
-
}
|
8431 |
-
|
8432 |
-
function attachDoc(cm, doc) {
|
8433 |
-
if (doc.cm) throw new Error("This document is already in use.");
|
8434 |
-
cm.doc = doc;
|
8435 |
-
doc.cm = cm;
|
8436 |
-
estimateLineHeights(cm);
|
8437 |
-
loadMode(cm);
|
8438 |
-
if (!cm.options.lineWrapping) computeMaxLength(cm);
|
8439 |
-
cm.options.mode = doc.modeOption;
|
8440 |
-
regChange(cm);
|
8441 |
-
}
|
8442 |
-
|
8443 |
-
// LINE UTILITIES
|
8444 |
-
|
8445 |
-
function getLine(chunk, n) {
|
8446 |
-
n -= chunk.first;
|
8447 |
-
while (!chunk.lines) {
|
8448 |
-
for (var i = 0;; ++i) {
|
8449 |
-
var child = chunk.children[i], sz = child.chunkSize();
|
8450 |
-
if (n < sz) { chunk = child; break; }
|
8451 |
-
n -= sz;
|
8452 |
-
}
|
8453 |
-
}
|
8454 |
-
return chunk.lines[n];
|
8455 |
-
}
|
8456 |
-
|
8457 |
-
function getBetween(doc, start, end) {
|
8458 |
-
var out = [], n = start.line;
|
8459 |
-
doc.iter(start.line, end.line + 1, function(line) {
|
8460 |
-
var text = line.text;
|
8461 |
-
if (n == end.line) text = text.slice(0, end.ch);
|
8462 |
-
if (n == start.line) text = text.slice(start.ch);
|
8463 |
-
out.push(text);
|
8464 |
-
++n;
|
8465 |
-
});
|
8466 |
-
return out;
|
8467 |
-
}
|
8468 |
-
function getLines(doc, from, to) {
|
8469 |
-
var out = [];
|
8470 |
-
doc.iter(from, to, function(line) { out.push(line.text); });
|
8471 |
-
return out;
|
8472 |
-
}
|
8473 |
-
|
8474 |
-
function updateLineHeight(line, height) {
|
8475 |
-
var diff = height - line.height;
|
8476 |
-
for (var n = line; n; n = n.parent) n.height += diff;
|
8477 |
-
}
|
8478 |
-
|
8479 |
-
function lineNo(line) {
|
8480 |
-
if (line.parent == null) return null;
|
8481 |
-
var cur = line.parent, no = indexOf(cur.lines, line);
|
8482 |
-
for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
|
8483 |
-
for (var i = 0;; ++i) {
|
8484 |
-
if (chunk.children[i] == cur) break;
|
8485 |
-
no += chunk.children[i].chunkSize();
|
8486 |
-
}
|
8487 |
-
}
|
8488 |
-
return no + cur.first;
|
8489 |
-
}
|
8490 |
-
|
8491 |
-
function lineAtHeight(chunk, h) {
|
8492 |
-
var n = chunk.first;
|
8493 |
-
outer: do {
|
8494 |
-
for (var i = 0, e = chunk.children.length; i < e; ++i) {
|
8495 |
-
var child = chunk.children[i], ch = child.height;
|
8496 |
-
if (h < ch) { chunk = child; continue outer; }
|
8497 |
-
h -= ch;
|
8498 |
-
n += child.chunkSize();
|
8499 |
-
}
|
8500 |
-
return n;
|
8501 |
-
} while (!chunk.lines);
|
8502 |
-
for (var i = 0, e = chunk.lines.length; i < e; ++i) {
|
8503 |
-
var line = chunk.lines[i], lh = line.height;
|
8504 |
-
if (h < lh) break;
|
8505 |
-
h -= lh;
|
8506 |
-
}
|
8507 |
-
return n + i;
|
8508 |
-
}
|
8509 |
-
|
8510 |
-
function heightAtLine(cm, lineObj) {
|
8511 |
-
lineObj = visualLine(cm.doc, lineObj);
|
8512 |
-
|
8513 |
-
var h = 0, chunk = lineObj.parent;
|
8514 |
-
for (var i = 0; i < chunk.lines.length; ++i) {
|
8515 |
-
var line = chunk.lines[i];
|
8516 |
-
if (line == lineObj) break;
|
8517 |
-
else h += line.height;
|
8518 |
-
}
|
8519 |
-
for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
|
8520 |
-
for (var i = 0; i < p.children.length; ++i) {
|
8521 |
-
var cur = p.children[i];
|
8522 |
-
if (cur == chunk) break;
|
8523 |
-
else h += cur.height;
|
8524 |
-
}
|
8525 |
-
}
|
8526 |
-
return h;
|
8527 |
-
}
|
8528 |
-
|
8529 |
-
function getOrder(line) {
|
8530 |
-
var order = line.order;
|
8531 |
-
if (order == null) order = line.order = bidiOrdering(line.text);
|
8532 |
-
return order;
|
8533 |
-
}
|
8534 |
-
|
8535 |
-
// HISTORY
|
8536 |
-
|
8537 |
-
function makeHistory(startGen) {
|
8538 |
-
return {
|
8539 |
-
// Arrays of history events. Doing something adds an event to
|
8540 |
-
// done and clears undo. Undoing moves events from done to
|
8541 |
-
// undone, redoing moves them in the other direction.
|
8542 |
-
done: [], undone: [], undoDepth: Infinity,
|
8543 |
-
// Used to track when changes can be merged into a single undo
|
8544 |
-
// event
|
8545 |
-
lastTime: 0, lastOp: null, lastOrigin: null,
|
8546 |
-
// Used by the isClean() method
|
8547 |
-
generation: startGen || 1, maxGeneration: startGen || 1
|
8548 |
-
};
|
8549 |
-
}
|
8550 |
-
|
8551 |
-
function attachLocalSpans(doc, change, from, to) {
|
8552 |
-
var existing = change["spans_" + doc.id], n = 0;
|
8553 |
-
doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
|
8554 |
-
if (line.markedSpans)
|
8555 |
-
(existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
|
8556 |
-
++n;
|
8557 |
-
});
|
8558 |
-
}
|
8559 |
-
|
8560 |
-
function historyChangeFromChange(doc, change) {
|
8561 |
-
var from = { line: change.from.line, ch: change.from.ch };
|
8562 |
-
var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
|
8563 |
-
attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
|
8564 |
-
linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
|
8565 |
-
return histChange;
|
8566 |
-
}
|
8567 |
-
|
8568 |
-
function addToHistory(doc, change, selAfter, opId) {
|
8569 |
-
var hist = doc.history;
|
8570 |
-
hist.undone.length = 0;
|
8571 |
-
var time = +new Date, cur = lst(hist.done);
|
8572 |
-
|
8573 |
-
if (cur &&
|
8574 |
-
(hist.lastOp == opId ||
|
8575 |
-
hist.lastOrigin == change.origin && change.origin &&
|
8576 |
-
((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) ||
|
8577 |
-
change.origin.charAt(0) == "*"))) {
|
8578 |
-
// Merge this change into the last event
|
8579 |
-
var last = lst(cur.changes);
|
8580 |
-
if (posEq(change.from, change.to) && posEq(change.from, last.to)) {
|
8581 |
-
// Optimized case for simple insertion -- don't want to add
|
8582 |
-
// new changesets for every character typed
|
8583 |
-
last.to = changeEnd(change);
|
8584 |
-
} else {
|
8585 |
-
// Add new sub-event
|
8586 |
-
cur.changes.push(historyChangeFromChange(doc, change));
|
8587 |
-
}
|
8588 |
-
cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head;
|
8589 |
-
} else {
|
8590 |
-
// Can not be merged, start a new event.
|
8591 |
-
cur = {changes: [historyChangeFromChange(doc, change)],
|
8592 |
-
generation: hist.generation,
|
8593 |
-
anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
|
8594 |
-
anchorAfter: selAfter.anchor, headAfter: selAfter.head};
|
8595 |
-
hist.done.push(cur);
|
8596 |
-
while (hist.done.length > hist.undoDepth)
|
8597 |
-
hist.done.shift();
|
8598 |
-
}
|
8599 |
-
hist.generation = ++hist.maxGeneration;
|
8600 |
-
hist.lastTime = time;
|
8601 |
-
hist.lastOp = opId;
|
8602 |
-
hist.lastOrigin = change.origin;
|
8603 |
-
|
8604 |
-
if (!last) signal(doc, "historyAdded");
|
8605 |
-
}
|
8606 |
-
|
8607 |
-
function removeClearedSpans(spans) {
|
8608 |
-
if (!spans) return null;
|
8609 |
-
for (var i = 0, out; i < spans.length; ++i) {
|
8610 |
-
if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
|
8611 |
-
else if (out) out.push(spans[i]);
|
8612 |
-
}
|
8613 |
-
return !out ? spans : out.length ? out : null;
|
8614 |
-
}
|
8615 |
-
|
8616 |
-
function getOldSpans(doc, change) {
|
8617 |
-
var found = change["spans_" + doc.id];
|
8618 |
-
if (!found) return null;
|
8619 |
-
for (var i = 0, nw = []; i < change.text.length; ++i)
|
8620 |
-
nw.push(removeClearedSpans(found[i]));
|
8621 |
-
return nw;
|
8622 |
-
}
|
8623 |
-
|
8624 |
-
// Used both to provide a JSON-safe object in .getHistory, and, when
|
8625 |
-
// detaching a document, to split the history in two
|
8626 |
-
function copyHistoryArray(events, newGroup) {
|
8627 |
-
for (var i = 0, copy = []; i < events.length; ++i) {
|
8628 |
-
var event = events[i], changes = event.changes, newChanges = [];
|
8629 |
-
copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore,
|
8630 |
-
anchorAfter: event.anchorAfter, headAfter: event.headAfter});
|
8631 |
-
for (var j = 0; j < changes.length; ++j) {
|
8632 |
-
var change = changes[j], m;
|
8633 |
-
newChanges.push({from: change.from, to: change.to, text: change.text});
|
8634 |
-
if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
|
8635 |
-
if (indexOf(newGroup, Number(m[1])) > -1) {
|
8636 |
-
lst(newChanges)[prop] = change[prop];
|
8637 |
-
delete change[prop];
|
8638 |
-
}
|
8639 |
-
}
|
8640 |
-
}
|
8641 |
-
}
|
8642 |
-
return copy;
|
8643 |
-
}
|
8644 |
-
|
8645 |
-
// Rebasing/resetting history to deal with externally-sourced changes
|
8646 |
-
|
8647 |
-
function rebaseHistSel(pos, from, to, diff) {
|
8648 |
-
if (to < pos.line) {
|
8649 |
-
pos.line += diff;
|
8650 |
-
} else if (from < pos.line) {
|
8651 |
-
pos.line = from;
|
8652 |
-
pos.ch = 0;
|
8653 |
-
}
|
8654 |
-
}
|
8655 |
-
|
8656 |
-
// Tries to rebase an array of history events given a change in the
|
8657 |
-
// document. If the change touches the same lines as the event, the
|
8658 |
-
// event, and everything 'behind' it, is discarded. If the change is
|
8659 |
-
// before the event, the event's positions are updated. Uses a
|
8660 |
-
// copy-on-write scheme for the positions, to avoid having to
|
8661 |
-
// reallocate them all on every rebase, but also avoid problems with
|
8662 |
-
// shared position objects being unsafely updated.
|
8663 |
-
function rebaseHistArray(array, from, to, diff) {
|
8664 |
-
for (var i = 0; i < array.length; ++i) {
|
8665 |
-
var sub = array[i], ok = true;
|
8666 |
-
for (var j = 0; j < sub.changes.length; ++j) {
|
8667 |
-
var cur = sub.changes[j];
|
8668 |
-
if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); }
|
8669 |
-
if (to < cur.from.line) {
|
8670 |
-
cur.from.line += diff;
|
8671 |
-
cur.to.line += diff;
|
8672 |
-
} else if (from <= cur.to.line) {
|
8673 |
-
ok = false;
|
8674 |
-
break;
|
8675 |
-
}
|
8676 |
-
}
|
8677 |
-
if (!sub.copied) {
|
8678 |
-
sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore);
|
8679 |
-
sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter);
|
8680 |
-
sub.copied = true;
|
8681 |
-
}
|
8682 |
-
if (!ok) {
|
8683 |
-
array.splice(0, i + 1);
|
8684 |
-
i = 0;
|
8685 |
-
} else {
|
8686 |
-
rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore);
|
8687 |
-
rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter);
|
8688 |
-
}
|
8689 |
-
}
|
8690 |
-
}
|
8691 |
-
|
8692 |
-
function rebaseHist(hist, change) {
|
8693 |
-
var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
|
8694 |
-
rebaseHistArray(hist.done, from, to, diff);
|
8695 |
-
rebaseHistArray(hist.undone, from, to, diff);
|
8696 |
-
}
|
8697 |
-
|
8698 |
-
// EVENT OPERATORS
|
8699 |
-
|
8700 |
-
function stopMethod() {e_stop(this);}
|
8701 |
-
// Ensure an event has a stop method.
|
8702 |
-
function addStop(event) {
|
8703 |
-
if (!event.stop) event.stop = stopMethod;
|
8704 |
-
return event;
|
8705 |
-
}
|
8706 |
-
|
8707 |
-
function e_preventDefault(e) {
|
8708 |
-
if (e.preventDefault) e.preventDefault();
|
8709 |
-
else e.returnValue = false;
|
8710 |
-
}
|
8711 |
-
function e_stopPropagation(e) {
|
8712 |
-
if (e.stopPropagation) e.stopPropagation();
|
8713 |
-
else e.cancelBubble = true;
|
8714 |
-
}
|
8715 |
-
function e_defaultPrevented(e) {
|
8716 |
-
return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
|
8717 |
-
}
|
8718 |
-
function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
|
8719 |
-
CodeMirror.e_stop = e_stop;
|
8720 |
-
CodeMirror.e_preventDefault = e_preventDefault;
|
8721 |
-
CodeMirror.e_stopPropagation = e_stopPropagation;
|
8722 |
-
|
8723 |
-
function e_target(e) {return e.target || e.srcElement;}
|
8724 |
-
function e_button(e) {
|
8725 |
-
var b = e.which;
|
8726 |
-
if (b == null) {
|
8727 |
-
if (e.button & 1) b = 1;
|
8728 |
-
else if (e.button & 2) b = 3;
|
8729 |
-
else if (e.button & 4) b = 2;
|
8730 |
-
}
|
8731 |
-
if (mac && e.ctrlKey && b == 1) b = 3;
|
8732 |
-
return b;
|
8733 |
-
}
|
8734 |
-
|
8735 |
-
// EVENT HANDLING
|
8736 |
-
|
8737 |
-
function on(emitter, type, f) {
|
8738 |
-
if (emitter.addEventListener)
|
8739 |
-
emitter.addEventListener(type, f, false);
|
8740 |
-
else if (emitter.attachEvent)
|
8741 |
-
emitter.attachEvent("on" + type, f);
|
8742 |
-
else {
|
8743 |
-
var map = emitter._handlers || (emitter._handlers = {});
|
8744 |
-
var arr = map[type] || (map[type] = []);
|
8745 |
-
arr.push(f);
|
8746 |
-
}
|
8747 |
-
}
|
8748 |
-
|
8749 |
-
function off(emitter, type, f) {
|
8750 |
-
if (emitter.removeEventListener)
|
8751 |
-
emitter.removeEventListener(type, f, false);
|
8752 |
-
else if (emitter.detachEvent)
|
8753 |
-
emitter.detachEvent("on" + type, f);
|
8754 |
-
else {
|
8755 |
-
var arr = emitter._handlers && emitter._handlers[type];
|
8756 |
-
if (!arr) return;
|
8757 |
-
for (var i = 0; i < arr.length; ++i)
|
8758 |
-
if (arr[i] == f) { arr.splice(i, 1); break; }
|
8759 |
-
}
|
8760 |
-
}
|
8761 |
-
|
8762 |
-
function signal(emitter, type /*, values...*/) {
|
8763 |
-
var arr = emitter._handlers && emitter._handlers[type];
|
8764 |
-
if (!arr) return;
|
8765 |
-
var args = Array.prototype.slice.call(arguments, 2);
|
8766 |
-
for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
|
8767 |
-
}
|
8768 |
-
|
8769 |
-
var delayedCallbacks, delayedCallbackDepth = 0;
|
8770 |
-
function signalLater(emitter, type /*, values...*/) {
|
8771 |
-
var arr = emitter._handlers && emitter._handlers[type];
|
8772 |
-
if (!arr) return;
|
8773 |
-
var args = Array.prototype.slice.call(arguments, 2);
|
8774 |
-
if (!delayedCallbacks) {
|
8775 |
-
++delayedCallbackDepth;
|
8776 |
-
delayedCallbacks = [];
|
8777 |
-
setTimeout(fireDelayed, 0);
|
8778 |
-
}
|
8779 |
-
function bnd(f) {return function(){f.apply(null, args);};};
|
8780 |
-
for (var i = 0; i < arr.length; ++i)
|
8781 |
-
delayedCallbacks.push(bnd(arr[i]));
|
8782 |
-
}
|
8783 |
-
|
8784 |
-
function signalDOMEvent(cm, e, override) {
|
8785 |
-
signal(cm, override || e.type, cm, e);
|
8786 |
-
return e_defaultPrevented(e) || e.codemirrorIgnore;
|
8787 |
-
}
|
8788 |
-
|
8789 |
-
function fireDelayed() {
|
8790 |
-
--delayedCallbackDepth;
|
8791 |
-
var delayed = delayedCallbacks;
|
8792 |
-
delayedCallbacks = null;
|
8793 |
-
for (var i = 0; i < delayed.length; ++i) delayed[i]();
|
8794 |
-
}
|
8795 |
-
|
8796 |
-
function hasHandler(emitter, type) {
|
8797 |
-
var arr = emitter._handlers && emitter._handlers[type];
|
8798 |
-
return arr && arr.length > 0;
|
8799 |
-
}
|
8800 |
-
|
8801 |
-
CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
|
8802 |
-
|
8803 |
-
function eventMixin(ctor) {
|
8804 |
-
ctor.prototype.on = function(type, f) {on(this, type, f);};
|
8805 |
-
ctor.prototype.off = function(type, f) {off(this, type, f);};
|
8806 |
-
}
|
8807 |
-
|
8808 |
-
// MISC UTILITIES
|
8809 |
-
|
8810 |
-
// Number of pixels added to scroller and sizer to hide scrollbar
|
8811 |
-
var scrollerCutOff = 30;
|
8812 |
-
|
8813 |
|