Google Doc Embedder - Version 2.5.10

Version Description

  • Fixed: PHP warning on multisite during uninstall (thanks TigranTovmasyan)
  • Changed: (E) Viewer settings use native color picker
  • Changed: Now requires WordPress 3.5+ (removed legacy functions)
Download this release

Release Info

Developer k3davis
Plugin Icon wp plugin Google Doc Embedder
Version 2.5.10
Comparing to
See all releases

Code changes from version 2.5.8 to 2.5.10

css/admin-styles.css CHANGED
@@ -106,6 +106,14 @@ p.gde-submit {
106
  margin-left: 3px;
107
  }
108
 
 
 
 
 
 
 
 
 
109
  #toolbuttons td label, #fullscreen td label {
110
  margin-right: 10px;
111
  }
106
  margin-left: 3px;
107
  }
108
 
109
+ #gdev_t, #gdev_b {
110
+ margin-top: -6px;
111
+ }
112
+
113
+ #bgcolor label, #pbcolor label {
114
+ vertical-align: super;
115
+ }
116
+
117
  #toolbuttons td label, #fullscreen td label {
118
  margin-right: 10px;
119
  }
functions-admin.php CHANGED
@@ -519,6 +519,9 @@ function gde_admin_custom_css( $hook ) {
519
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'gde-settings' ) ) {
520
  $css = GDE_PLUGIN_URL . 'css/admin-styles.css';
521
  wp_enqueue_style( 'gde_css', $css );
 
 
 
522
  }
523
  }
524
 
@@ -554,11 +557,8 @@ function gde_admin_custom_js( $hook ) {
554
  global $gde_settings_page, $gde_global_page, $pagenow;
555
 
556
  if ( $gde_settings_page == $hook || $gde_global_page == $hook ) {
557
- $js['gde_clr'] = GDE_PLUGIN_URL . 'js/jscolor/jscolor.js';
558
- $js['gde_jqs'] = GDE_PLUGIN_URL . 'js/gde-jquery.js';
559
- foreach ( $js as $key => $script ) {
560
- wp_enqueue_script( $key, $script );
561
- }
562
  // localize
563
  wp_localize_script( 'gde_jqs', 'jqs_vars', array (
564
  // internal use
@@ -579,82 +579,14 @@ function gde_admin_custom_js( $hook ) {
579
 
580
  /* MEDIA LIBRARY & EDITOR INTEGRATION ****/
581
 
582
- /**
583
- * Select embed behavior and profile from Media Library
584
- *
585
- * @since 2.5.0.1
586
- * @note Doesn't work in WP 3.5+ (not called in those versions)
587
- * @return array Form fields for attachment form
588
- */
589
- function gde_attachment_fields_to_edit( $form_fields, $post ) {
590
- global $gdeoptions, $pagenow;
591
-
592
- if ( $pagenow == "media.php" ) {
593
- // attachment info page, added fields not relevant
594
- return $form_fields;
595
- }
596
-
597
- $supported_exts = gde_supported_types();
598
-
599
- if ( in_array( $post->post_mime_type, $supported_exts ) ) {
600
- // file is supported, show fields
601
-
602
- if ( $gdeoptions['ed_embed_sc'] == "yes" ) {
603
- $use_sc = true;
604
- } else {
605
- $use_sc = false;
606
- }
607
-
608
- $checked = ( $use_sc ) ? 'checked' : '';
609
- $form_fields['gde_use_sc'] = array(
610
- 'label' => 'Google Doc Embedder',
611
- 'input' => 'html',
612
- 'html' => "<input type='checkbox' {$checked} name='attachments[{$post->ID}][gde_use_sc]' id='attachments[{$post->ID}][gde_use_sc]' /> " . __('Embed file using Google Doc Embedder', 'gde'),
613
- 'value' => $use_sc
614
- );
615
-
616
- // get profiles
617
- $profiles = gde_get_profiles();
618
-
619
- $html = "<select name='attachments[{$post->ID}][gde_profile]' id='attachments[{$post->ID}][gde_profile]' style='height:2em;'>";
620
- foreach ( $profiles as $p ) {
621
- $html .= "\t<option value='".$p['profile_id']."'>".$p['profile_name']."</option>\n";
622
- }
623
- $html .= "</select>";
624
-
625
- $form_fields['gde_profile'] = array(
626
- 'label' => '',
627
- 'input' => 'html',
628
- 'html' => $html,
629
- 'helps' => __('Select the GDE viewer profile to use', 'gde')
630
- );
631
- }
632
-
633
- return $form_fields;
634
- }
635
-
636
  /**
637
  * Modify the file insertion from Media Library if requested
638
  *
639
  * @since 2.4.0.1
640
- * @note Doesn't work in WP 3.5+ (not called in those versions)
641
  * @return string HTML to insert into editor
642
  */
643
  function gde_media_insert( $html, $id, $attachment ) {
644
- if ( isset( $attachment['gde_use_sc'] ) && $attachment['gde_use_sc'] == "on" ) {
645
- $output = '[gview file="' . $attachment['url'] . '"';
646
- if ( isset( $attachment['gde_profile'] ) && $attachment['gde_profile'] !== "1" ) {
647
- $output .= ' profile="' . $attachment['gde_profile'] . '"]';
648
- } else {
649
- $output .= ']';
650
- }
651
- return $output;
652
- } else {
653
- return $html;
654
- }
655
- }
656
-
657
- function gde_media_insert_35( $html, $id, $attachment ) {
658
  global $gdeoptions;
659
 
660
  if ( gde_valid_type( $attachment['url'] ) && $gdeoptions['ed_embed_sc'] == "yes" ) {
@@ -808,6 +740,7 @@ function gde_warn_on_plugin_page( $plugin_file ) {
808
  * @return bool True or false, there is a (newer) beta available
809
  */
810
  function gde_check_for_beta( $plugin_file ) {
 
811
  global $gdeoptions, $pdata;
812
 
813
  // beta checking is enabled
@@ -851,6 +784,7 @@ function gde_check_for_beta( $plugin_file ) {
851
  * @return bool Whether or not a new beta is available
852
  */
853
  function gde_beta_available() {
 
854
  global $gdeoptions, $pdata;
855
 
856
  $key = 'gde_beta_version';
519
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'gde-settings' ) ) {
520
  $css = GDE_PLUGIN_URL . 'css/admin-styles.css';
521
  wp_enqueue_style( 'gde_css', $css );
522
+
523
+ // native color picker
524
+ wp_enqueue_style( 'wp-color-picker' );
525
  }
526
  }
527
 
557
  global $gde_settings_page, $gde_global_page, $pagenow;
558
 
559
  if ( $gde_settings_page == $hook || $gde_global_page == $hook ) {
560
+ wp_enqueue_script( 'gde_jqs', GDE_PLUGIN_URL . 'js/gde-jquery.js', array( 'wp-color-picker' ), false, true );
561
+
 
 
 
562
  // localize
563
  wp_localize_script( 'gde_jqs', 'jqs_vars', array (
564
  // internal use
579
 
580
  /* MEDIA LIBRARY & EDITOR INTEGRATION ****/
581
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
582
  /**
583
  * Modify the file insertion from Media Library if requested
584
  *
585
  * @since 2.4.0.1
586
+ * @note Requires WP 3.5+
587
  * @return string HTML to insert into editor
588
  */
589
  function gde_media_insert( $html, $id, $attachment ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  global $gdeoptions;
591
 
592
  if ( gde_valid_type( $attachment['url'] ) && $gdeoptions['ed_embed_sc'] == "yes" ) {
740
  * @return bool True or false, there is a (newer) beta available
741
  */
742
  function gde_check_for_beta( $plugin_file ) {
743
+ return false; // disable beta api (bandwidth issues)
744
  global $gdeoptions, $pdata;
745
 
746
  // beta checking is enabled
784
  * @return bool Whether or not a new beta is available
785
  */
786
  function gde_beta_available() {
787
+ return false; // disable beta api (bandwidth issues)
788
  global $gdeoptions, $pdata;
789
 
790
  $key = 'gde_beta_version';
functions.php CHANGED
@@ -24,7 +24,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
24
  @define( 'GDE_ADVOPT_URL', 'http://www.davistribe.org/gde/settings/advanced-options/' );
25
  @define( 'GDE_FORUM_URL', 'http://wordpress.org/support/plugin/google-document-embedder' );
26
  @define( 'GDE_WP_URL', 'http://wordpress.org/extend/plugins/google-document-embedder/' );
27
- @define( 'GDE_BETA_API', 'http://dev.davismetro.com/api/1.0/' );
28
 
29
  /**
30
  * List supported extensions & MIME types
24
  @define( 'GDE_ADVOPT_URL', 'http://www.davistribe.org/gde/settings/advanced-options/' );
25
  @define( 'GDE_FORUM_URL', 'http://wordpress.org/support/plugin/google-document-embedder' );
26
  @define( 'GDE_WP_URL', 'http://wordpress.org/extend/plugins/google-document-embedder/' );
27
+ //@define( 'GDE_BETA_API', 'http://dev.davismetro.com/api/1.0/' );
28
 
29
  /**
30
  * List supported extensions & MIME types
gviewer.php CHANGED
@@ -3,12 +3,12 @@
3
  /*
4
  Plugin Name: Google Doc Embedder
5
  Plugin URI: http://www.davistribe.org/gde/
6
- Description: Lets you embed MS Office, PDF, TIFF, and many other file types in a web page using the Google Docs Viewer (no Flash or PDF browser plug-ins required).
7
  Author: Kevin Davis
8
  Author URI: http://www.davistribe.org/
9
  Text Domain: gde
10
  Domain Path: /languages/
11
- Version: 2.5.8
12
  License: GPLv2
13
  */
14
 
@@ -38,7 +38,7 @@ License: GPLv2
38
  */
39
 
40
  // boring init junk
41
- $gde_ver = "2.5.8.98";
42
  $gde_db_ver = "1.2"; // update also in gde_activate()
43
 
44
  require_once( plugin_dir_path( __FILE__ ) . 'functions.php' );
@@ -96,7 +96,7 @@ function gde_do_shortcode( $atts ) {
96
  'height' => '',
97
  'cache' => '',
98
  'title' => '', // not yet implemented
99
- 'page' => '',
100
 
101
  // backwards compatibility < gde 2.5 (still work but now "deprecated" and discouraged in the documentation)
102
  'authonly' => '',
@@ -241,8 +241,10 @@ function gde_do_shortcode( $atts ) {
241
  // which viewer?
242
  if ( $profile['viewer'] == "enhanced" ) {
243
  $lnk = GDE_PLUGIN_URL . "view.php?url=" . urlencode( $links[0] ) . "&hl=" . $lang . "&gpid=" . $pid;
 
 
244
  } else {
245
- $lnk = "http://docs.google.com/viewer?url=" . urlencode( $links[0] ) . "&hl=" . $lang;
246
  }
247
 
248
  // what mode?
@@ -264,10 +266,10 @@ function gde_do_shortcode( $atts ) {
264
 
265
  // frame attributes
266
  $vattr[] = ' scrolling="no"'; // iphone scrolling bug
267
- if ( ! empty( $page ) && is_numeric( $page ) ) { // selected starting page
268
- $page = (int) $page - 1;
269
- $vattr[] = ' onload="javascript:this.contentWindow.location.hash=\':0.page.' . $page . '\';"';
270
- }
271
  $vwr = str_replace( "%ATTRS%", implode( '', $vattr ), $vwr );
272
  }
273
 
@@ -351,14 +353,8 @@ if ( is_admin() ) {
351
  add_filter( 'upload_mimes', 'gde_upload_mimes' );
352
  }
353
 
354
- if ( version_compare( $wp_version, "3.5", "<" ) ) {
355
- // embed shortcode instead of link from media library for supported types
356
- add_filter( 'attachment_fields_to_edit', 'gde_attachment_fields_to_edit', null, 2 );
357
- add_filter( 'media_send_to_editor', 'gde_media_insert', 20, 3 );
358
- } else {
359
- //add_filter( 'attachment_fields_to_edit', 'gde_attachment_fields_to_edit_35', null, 2 );
360
- add_filter( 'media_send_to_editor', 'gde_media_insert_35', 20, 3 );
361
- }
362
  }
363
 
364
  // add local settings page
3
  /*
4
  Plugin Name: Google Doc Embedder
5
  Plugin URI: http://www.davistribe.org/gde/
6
+ Description: Lets you embed PDF, MS Office, TIFF, and many other file types in a web page using the Google Docs Viewer (no Flash or PDF browser plug-ins required).
7
  Author: Kevin Davis
8
  Author URI: http://www.davistribe.org/
9
  Text Domain: gde
10
  Domain Path: /languages/
11
+ Version: 2.5.10
12
  License: GPLv2
13
  */
14
 
38
  */
39
 
40
  // boring init junk
41
+ $gde_ver = "2.5.10.98";
42
  $gde_db_ver = "1.2"; // update also in gde_activate()
43
 
44
  require_once( plugin_dir_path( __FILE__ ) . 'functions.php' );
96
  'height' => '',
97
  'cache' => '',
98
  'title' => '', // not yet implemented
99
+ //'page' => '', // support broken in Google Viewer
100
 
101
  // backwards compatibility < gde 2.5 (still work but now "deprecated" and discouraged in the documentation)
102
  'authonly' => '',
241
  // which viewer?
242
  if ( $profile['viewer'] == "enhanced" ) {
243
  $lnk = GDE_PLUGIN_URL . "view.php?url=" . urlencode( $links[0] ) . "&hl=" . $lang . "&gpid=" . $pid;
244
+ // make protocol-agnostic
245
+ $lnk = preg_replace( '/^https?:/i', '', $lnk );
246
  } else {
247
+ $lnk = "//docs.google.com/viewer?url=" . urlencode( $links[0] ) . "&hl=" . $lang;
248
  }
249
 
250
  // what mode?
266
 
267
  // frame attributes
268
  $vattr[] = ' scrolling="no"'; // iphone scrolling bug
269
+ //if ( ! empty( $page ) && is_numeric( $page ) ) { // selected starting page
270
+ // $page = (int) $page - 1;
271
+ // $vattr[] = ' onload="javascript:this.contentWindow.location.hash=\':0.page.' . $page . '\';"';
272
+ //}
273
  $vwr = str_replace( "%ATTRS%", implode( '', $vattr ), $vwr );
274
  }
275
 
353
  add_filter( 'upload_mimes', 'gde_upload_mimes' );
354
  }
355
 
356
+ // embed shortcode instead of link from media library for supported types
357
+ add_filter( 'media_send_to_editor', 'gde_media_insert', 20, 3 );
 
 
 
 
 
 
358
  }
359
 
360
  // add local settings page
js/dialog.js CHANGED
@@ -27,9 +27,9 @@ var GDEInsertDialog = {
27
  update_sc();
28
  });
29
 
30
- jQuery('#page').blur(function(){
31
- update_sc();
32
- });
33
 
34
  jQuery('.save').click(function(){
35
  update_sc();
@@ -126,9 +126,9 @@ var GDEInsertDialog = {
126
  shortcode = shortcode + ' width="'+width+'"';
127
  }
128
 
129
- if (( jQuery('#page').val() != "1" ) & ( jQuery('#page').val() ) !='') {
130
- shortcode = shortcode + ' page="'+jQuery('#page').val()+'"';
131
- }
132
 
133
  if ( jQuery("input[name='save']:checked").val() == '1') {
134
  shortcode = shortcode + ' save="1"';
27
  update_sc();
28
  });
29
 
30
+ //jQuery('#page').blur(function(){
31
+ // update_sc();
32
+ //});
33
 
34
  jQuery('.save').click(function(){
35
  update_sc();
126
  shortcode = shortcode + ' width="'+width+'"';
127
  }
128
 
129
+ //if (( jQuery('#page').val() != "1" ) & ( jQuery('#page').val() ) !='') {
130
+ // shortcode = shortcode + ' page="'+jQuery('#page').val()+'"';
131
+ //}
132
 
133
  if ( jQuery("input[name='save']:checked").val() == '1') {
134
  shortcode = shortcode + ' save="1"';
js/editor_plugin.js CHANGED
@@ -9,7 +9,7 @@
9
  ed.windowManager.open( {
10
  file : url + '/libs/lib-eddialog.php',
11
  width : 475 + parseInt(ed.getLang('gde.delta_width',0)),
12
- height : 500 + parseInt(ed.getLang('gde.delta_height',0)),
13
  inline : 1}, {
14
  plugin_url : url
15
  }
@@ -34,7 +34,7 @@
34
  author : 'Kevin Davis',
35
  authorurl : 'http://www.davistribe.org/gde',
36
  infourl : 'http://www.davistribe.org/gde',
37
- version : "1.4"}
38
  }
39
  });
40
  tinymce.PluginManager.add('gde',tinymce.plugins.gde);
9
  ed.windowManager.open( {
10
  file : url + '/libs/lib-eddialog.php',
11
  width : 475 + parseInt(ed.getLang('gde.delta_width',0)),
12
+ height : 475 + parseInt(ed.getLang('gde.delta_height',0)), // 500 with page option
13
  inline : 1}, {
14
  plugin_url : url
15
  }
34
  author : 'Kevin Davis',
35
  authorurl : 'http://www.davistribe.org/gde',
36
  infourl : 'http://www.davistribe.org/gde',
37
+ version : "1.5"}
38
  }
39
  });
40
  tinymce.PluginManager.add('gde',tinymce.plugins.gde);
js/gde-jquery.js CHANGED
@@ -61,8 +61,6 @@ jQuery(function ($) {
61
  updateHelp('linkshow-h', title);
62
  var title = $('#tb_mobile').children(":selected").attr("title");
63
  updateHelp('mobile-h', title);
64
- colorSelected('gdev_t', 'vw_bgcolor');
65
- colorSelected('gdev_b', 'vw_pbcolor');
66
 
67
  // adv tab
68
  var title = $('#beta_check').children(":selected").attr("title");
@@ -102,18 +100,11 @@ jQuery(function ($) {
102
  toggleLink(lset);
103
  allowSecure();
104
  });
105
- $('#gdev_t').change(function() {
106
- colorSelected('gdev_t', 'vw_bgcolor');
107
- });
108
- $('#gdev_b').change(function() {
109
- colorSelected('gdev_b', 'vw_pbcolor');
110
- });
111
- $('#vw_bgcolor').change(function() {
112
- $('#vw_bgcolor_holder').val($('#vw_bgcolor').val());
113
- });
114
- $('#vw_pbcolor').change(function() {
115
- $('#vw_pbcolor_holder').val($('#vw_pbcolor').val());
116
- });
117
 
118
  // adv tab
119
  $('#ed_disable').change(function() {
@@ -174,17 +165,6 @@ jQuery(function ($) {
174
  }
175
  }
176
 
177
- function colorSelected(source, target) {
178
- if ($('#' + source).is(':checked')) {
179
- $('#' + target).attr('disabled', 'disabled').hide();
180
- $('#' + target + "_holder").show();
181
- } else {
182
- $('#' + target).removeAttr('disabled');
183
- $('#' + target + "_holder").hide();
184
- $('#' + target).show();
185
- }
186
- }
187
-
188
  function updateHelp(id, text) {
189
  $('#' + id).html(text);
190
  }
61
  updateHelp('linkshow-h', title);
62
  var title = $('#tb_mobile').children(":selected").attr("title");
63
  updateHelp('mobile-h', title);
 
 
64
 
65
  // adv tab
66
  var title = $('#beta_check').children(":selected").attr("title");
100
  toggleLink(lset);
101
  allowSecure();
102
  });
103
+
104
+ $('#vw_bgcolor').attr('data-default-color', '#EBEBEB');
105
+ $('#vw_pbcolor').attr('data-default-color', '#DADADA');
106
+ var colorPickerOptions = { palettes: false };
107
+ $('.gde-color-field').wpColorPicker(colorPickerOptions).removeAttr('disabled');
 
 
 
 
 
 
 
108
 
109
  // adv tab
110
  $('#ed_disable').change(function() {
165
  }
166
  }
167
 
 
 
 
 
 
 
 
 
 
 
 
168
  function updateHelp(id, text) {
169
  $('#' + id).html(text);
170
  }
js/jscolor/arrow.gif DELETED
Binary file
js/jscolor/cross.gif DELETED
Binary file
js/jscolor/hs.png DELETED
Binary file
js/jscolor/hv.png DELETED
Binary file
js/jscolor/jscolor.js DELETED
@@ -1,953 +0,0 @@
1
- /**
2
- * jscolor, JavaScript Color Picker
3
- *
4
- * @version 1.4.0
5
- * @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html
6
- * @author Jan Odvarko, http://odvarko.cz
7
- * @created 2008-06-15
8
- * @updated 2012-07-06
9
- * @link http://jscolor.com
10
- */
11
-
12
-
13
- var jscolor = {
14
-
15
-
16
- dir : '', // location of jscolor directory (leave empty to autodetect)
17
- bindClass : 'color', // class name
18
- binding : true, // automatic binding via <input class="...">
19
- preloading : true, // use image preloading?
20
-
21
-
22
- install : function() {
23
- jscolor.addEvent(window, 'load', jscolor.init);
24
- },
25
-
26
-
27
- init : function() {
28
- if(jscolor.binding) {
29
- jscolor.bind();
30
- }
31
- if(jscolor.preloading) {
32
- jscolor.preload();
33
- }
34
- },
35
-
36
-
37
- getDir : function() {
38
- if(!jscolor.dir) {
39
- var detected = jscolor.detectDir();
40
- jscolor.dir = detected!==false ? detected : 'jscolor/';
41
- }
42
- return jscolor.dir;
43
- },
44
-
45
-
46
- detectDir : function() {
47
- var base = location.href;
48
-
49
- var e = document.getElementsByTagName('base');
50
- for(var i=0; i<e.length; i+=1) {
51
- if(e[i].href) { base = e[i].href; }
52
- }
53
-
54
- var e = document.getElementsByTagName('script');
55
- for(var i=0; i<e.length; i+=1) {
56
- if(e[i].src && /(^|\/)jscolor\.js([?#].*)?$/i.test(e[i].src)) {
57
- var src = new jscolor.URI(e[i].src);
58
- var srcAbs = src.toAbsolute(base);
59
- srcAbs.path = srcAbs.path.replace(/[^\/]+$/, ''); // remove filename
60
- srcAbs.query = null;
61
- srcAbs.fragment = null;
62
- return srcAbs.toString();
63
- }
64
- }
65
- return false;
66
- },
67
-
68
-
69
- bind : function() {
70
- var matchClass = new RegExp('(^|\\s)('+jscolor.bindClass+')\\s*(\\{[^}]*\\})?', 'i');
71
- var e = document.getElementsByTagName('input');
72
- for(var i=0; i<e.length; i+=1) {
73
- var m;
74
- if(!e[i].color && e[i].className && (m = e[i].className.match(matchClass))) {
75
- var prop = {};
76
- if(m[3]) {
77
- try {
78
- prop = (new Function ('return (' + m[3] + ')'))();
79
- } catch(eInvalidProp) {}
80
- }
81
- e[i].color = new jscolor.color(e[i], prop);
82
- }
83
- }
84
- },
85
-
86
-
87
- preload : function() {
88
- for(var fn in jscolor.imgRequire) {
89
- if(jscolor.imgRequire.hasOwnProperty(fn)) {
90
- jscolor.loadImage(fn);
91
- }
92
- }
93
- },
94
-
95
-
96
- images : {
97
- pad : [ 181, 101 ],
98
- sld : [ 16, 101 ],
99
- cross : [ 15, 15 ],
100
- arrow : [ 7, 11 ]
101
- },
102
-
103
-
104
- imgRequire : {},
105
- imgLoaded : {},
106
-
107
-
108
- requireImage : function(filename) {
109
- jscolor.imgRequire[filename] = true;
110
- },
111
-
112
-
113
- loadImage : function(filename) {
114
- if(!jscolor.imgLoaded[filename]) {
115
- jscolor.imgLoaded[filename] = new Image();
116
- jscolor.imgLoaded[filename].src = jscolor.getDir()+filename;
117
- }
118
- },
119
-
120
-
121
- fetchElement : function(mixed) {
122
- return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;
123
- },
124
-
125
-
126
- addEvent : function(el, evnt, func) {
127
- if(el.addEventListener) {
128
- el.addEventListener(evnt, func, false);
129
- } else if(el.attachEvent) {
130
- el.attachEvent('on'+evnt, func);
131
- }
132
- },
133
-
134
-
135
- fireEvent : function(el, evnt) {
136
- if(!el) {
137
- return;
138
- }
139
- if(document.createEvent) {
140
- var ev = document.createEvent('HTMLEvents');
141
- ev.initEvent(evnt, true, true);
142
- el.dispatchEvent(ev);
143
- } else if(document.createEventObject) {
144
- var ev = document.createEventObject();
145
- el.fireEvent('on'+evnt, ev);
146
- } else if(el['on'+evnt]) { // alternatively use the traditional event model (IE5)
147
- el['on'+evnt]();
148
- }
149
- },
150
-
151
-
152
- getElementPos : function(e) {
153
- var e1=e, e2=e;
154
- var x=0, y=0;
155
- if(e1.offsetParent) {
156
- do {
157
- x += e1.offsetLeft;
158
- y += e1.offsetTop;
159
- } while(e1 = e1.offsetParent);
160
- }
161
- while((e2 = e2.parentNode) && e2.nodeName.toUpperCase() !== 'BODY') {
162
- x -= e2.scrollLeft;
163
- y -= e2.scrollTop;
164
- }
165
- return [x, y];
166
- },
167
-
168
-
169
- getElementSize : function(e) {
170
- return [e.offsetWidth, e.offsetHeight];
171
- },
172
-
173
-
174
- getRelMousePos : function(e) {
175
- var x = 0, y = 0;
176
- if (!e) { e = window.event; }
177
- if (typeof e.offsetX === 'number') {
178
- x = e.offsetX;
179
- y = e.offsetY;
180
- } else if (typeof e.layerX === 'number') {
181
- x = e.layerX;
182
- y = e.layerY;
183
- }
184
- return { x: x, y: y };
185
- },
186
-
187
-
188
- getViewPos : function() {
189
- if(typeof window.pageYOffset === 'number') {
190
- return [window.pageXOffset, window.pageYOffset];
191
- } else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
192
- return [document.body.scrollLeft, document.body.scrollTop];
193
- } else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
194
- return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
195
- } else {
196
- return [0, 0];
197
- }
198
- },
199
-
200
-
201
- getViewSize : function() {
202
- if(typeof window.innerWidth === 'number') {
203
- return [window.innerWidth, window.innerHeight];
204
- } else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
205
- return [document.body.clientWidth, document.body.clientHeight];
206
- } else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
207
- return [document.documentElement.clientWidth, document.documentElement.clientHeight];
208
- } else {
209
- return [0, 0];
210
- }
211
- },
212
-
213
-
214
- URI : function(uri) { // See RFC3986
215
-
216
- this.scheme = null;
217
- this.authority = null;
218
- this.path = '';
219
- this.query = null;
220
- this.fragment = null;
221
-
222
- this.parse = function(uri) {
223
- var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
224
- this.scheme = m[3] ? m[2] : null;
225
- this.authority = m[5] ? m[6] : null;
226
- this.path = m[7];
227
- this.query = m[9] ? m[10] : null;
228
- this.fragment = m[12] ? m[13] : null;
229
- return this;
230
- };
231
-
232
- this.toString = function() {
233
- var result = '';
234
- if(this.scheme !== null) { result = result + this.scheme + ':'; }
235
- if(this.authority !== null) { result = result + '//' + this.authority; }
236
- if(this.path !== null) { result = result + this.path; }
237
- if(this.query !== null) { result = result + '?' + this.query; }
238
- if(this.fragment !== null) { result = result + '#' + this.fragment; }
239
- return result;
240
- };
241
-
242
- this.toAbsolute = function(base) {
243
- var base = new jscolor.URI(base);
244
- var r = this;
245
- var t = new jscolor.URI;
246
-
247
- if(base.scheme === null) { return false; }
248
-
249
- if(r.scheme !== null && r.scheme.toLowerCase() === base.scheme.toLowerCase()) {
250
- r.scheme = null;
251
- }
252
-
253
- if(r.scheme !== null) {
254
- t.scheme = r.scheme;
255
- t.authority = r.authority;
256
- t.path = removeDotSegments(r.path);
257
- t.query = r.query;
258
- } else {
259
- if(r.authority !== null) {
260
- t.authority = r.authority;
261
- t.path = removeDotSegments(r.path);
262
- t.query = r.query;
263
- } else {
264
- if(r.path === '') {
265
- t.path = base.path;
266
- if(r.query !== null) {
267
- t.query = r.query;
268
- } else {
269
- t.query = base.query;
270
- }
271
- } else {
272
- if(r.path.substr(0,1) === '/') {
273
- t.path = removeDotSegments(r.path);
274
- } else {
275
- if(base.authority !== null && base.path === '') {
276
- t.path = '/'+r.path;
277
- } else {
278
- t.path = base.path.replace(/[^\/]+$/,'')+r.path;
279
- }
280
- t.path = removeDotSegments(t.path);
281
- }
282
- t.query = r.query;
283
- }
284
- t.authority = base.authority;
285
- }
286
- t.scheme = base.scheme;
287
- }
288
- t.fragment = r.fragment;
289
-
290
- return t;
291
- };
292
-
293
- function removeDotSegments(path) {
294
- var out = '';
295
- while(path) {
296
- if(path.substr(0,3)==='../' || path.substr(0,2)==='./') {
297
- path = path.replace(/^\.+/,'').substr(1);
298
- } else if(path.substr(0,3)==='/./' || path==='/.') {
299
- path = '/'+path.substr(3);
300
- } else if(path.substr(0,4)==='/../' || path==='/..') {
301
- path = '/'+path.substr(4);
302
- out = out.replace(/\/?[^\/]*$/, '');
303
- } else if(path==='.' || path==='..') {
304
- path = '';
305
- } else {
306
- var rm = path.match(/^\/?[^\/]*/)[0];
307
- path = path.substr(rm.length);
308
- out = out + rm;
309
- }
310
- }
311
- return out;
312
- }
313
-
314
- if(uri) {
315
- this.parse(uri);
316
- }
317
-
318
- },
319
-
320
-
321
- /*
322
- * Usage example:
323
- * var myColor = new jscolor.color(myInputElement)
324
- */
325
-
326
- color : function(target, prop) {
327
-
328
-
329
- this.required = true; // refuse empty values?
330
- this.adjust = true; // adjust value to uniform notation?
331
- this.hash = false; // prefix color with # symbol?
332
- this.caps = true; // uppercase?
333
- this.slider = true; // show the value/saturation slider?
334
- this.valueElement = target; // value holder
335
- this.styleElement = target; // where to reflect current color
336
- this.onImmediateChange = null; // onchange callback (can be either string or function)
337
- this.hsv = [0, 0, 1]; // read-only 0-6, 0-1, 0-1
338
- this.rgb = [1, 1, 1]; // read-only 0-1, 0-1, 0-1
339
- this.minH = 0; // read-only 0-6
340
- this.maxH = 6; // read-only 0-6
341
- this.minS = 0; // read-only 0-1
342
- this.maxS = 1; // read-only 0-1
343
- this.minV = 0; // read-only 0-1
344
- this.maxV = 1; // read-only 0-1
345
-
346
- this.pickerOnfocus = true; // display picker on focus?
347
- this.pickerMode = 'HSV'; // HSV | HVS
348
- this.pickerPosition = 'bottom'; // left | right | top | bottom
349
- this.pickerSmartPosition = true; // automatically adjust picker position when necessary
350
- this.pickerButtonHeight = 20; // px
351
- this.pickerClosable = false;
352
- this.pickerCloseText = 'Close';
353
- this.pickerButtonColor = 'ButtonText'; // px
354
- this.pickerFace = 10; // px
355
- this.pickerFaceColor = 'ThreeDFace'; // CSS color
356
- this.pickerBorder = 1; // px
357
- this.pickerBorderColor = 'ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight'; // CSS color
358
- this.pickerInset = 1; // px
359
- this.pickerInsetColor = 'ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow'; // CSS color
360
- this.pickerZIndex = 10000;
361
-
362
-
363
- for(var p in prop) {
364
- if(prop.hasOwnProperty(p)) {
365
- this[p] = prop[p];
366
- }
367
- }
368
-
369
-
370
- this.hidePicker = function() {
371
- if(isPickerOwner()) {
372
- removePicker();
373
- }
374
- };
375
-
376
-
377
- this.showPicker = function() {
378
- if(!isPickerOwner()) {
379
- var tp = jscolor.getElementPos(target); // target pos
380
- var ts = jscolor.getElementSize(target); // target size
381
- var vp = jscolor.getViewPos(); // view pos
382
- var vs = jscolor.getViewSize(); // view size
383
- var ps = getPickerDims(this); // picker size
384
- var a, b, c;
385
- switch(this.pickerPosition.toLowerCase()) {
386
- case 'left': a=1; b=0; c=-1; break;
387
- case 'right':a=1; b=0; c=1; break;
388
- case 'top': a=0; b=1; c=-1; break;
389
- default: a=0; b=1; c=1; break;
390
- }
391
- var l = (ts[b]+ps[b])/2;
392
-
393
- // picker pos
394
- if (!this.pickerSmartPosition) {
395
- var pp = [
396
- tp[a],
397
- tp[b]+ts[b]-l+l*c
398
- ];
399
- } else {
400
- var pp = [
401
- -vp[a]+tp[a]+ps[a] > vs[a] ?
402
- (-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :
403
- tp[a],
404
- -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?
405
- (-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :
406
- (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)
407
- ];
408
- }
409
- drawPicker(pp[a], pp[b]);
410
- }
411
- };
412
-
413
-
414
- this.importColor = function() {
415
- if(!valueElement) {
416
- this.exportColor();
417
- } else {
418
- if(!this.adjust) {
419
- if(!this.fromString(valueElement.value, leaveValue)) {
420
- styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
421
- styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
422
- styleElement.style.color = styleElement.jscStyle.color;
423
- this.exportColor(leaveValue | leaveStyle);
424
- }
425
- } else if(!this.required && /^\s*$/.test(valueElement.value)) {
426
- valueElement.value = '';
427
- styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
428
- styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
429
- styleElement.style.color = styleElement.jscStyle.color;
430
- this.exportColor(leaveValue | leaveStyle);
431
-
432
- } else if(this.fromString(valueElement.value)) {
433
- // OK
434
- } else {
435
- this.exportColor();
436
- }
437
- }
438
- };
439
-
440
-
441
- this.exportColor = function(flags) {
442
- if(!(flags & leaveValue) && valueElement) {
443
- var value = this.toString();
444
- if(this.caps) { value = value.toUpperCase(); }
445
- if(this.hash) { value = '#'+value; }
446
- valueElement.value = value;
447
- }
448
- if(!(flags & leaveStyle) && styleElement) {
449
- styleElement.style.backgroundImage = "none";
450
- styleElement.style.backgroundColor =
451
- '#'+this.toString();
452
- styleElement.style.color =
453
- 0.213 * this.rgb[0] +
454
- 0.715 * this.rgb[1] +
455
- 0.072 * this.rgb[2]
456
- < 0.5 ? '#FFF' : '#000';
457
- }
458
- if(!(flags & leavePad) && isPickerOwner()) {
459
- redrawPad();
460
- }
461
- if(!(flags & leaveSld) && isPickerOwner()) {
462
- redrawSld();
463
- }
464
- };
465
-
466
-
467
- this.fromHSV = function(h, s, v, flags) { // null = don't change
468
- if(h !== null) { h = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, h)); }
469
- if(s !== null) { s = Math.max(0.0, this.minS, Math.min(1.0, this.maxS, s)); }
470
- if(v !== null) { v = Math.max(0.0, this.minV, Math.min(1.0, this.maxV, v)); }
471
-
472
- this.rgb = HSV_RGB(
473
- h===null ? this.hsv[0] : (this.hsv[0]=h),
474
- s===null ? this.hsv[1] : (this.hsv[1]=s),
475
- v===null ? this.hsv[2] : (this.hsv[2]=v)
476
- );
477
-
478
- this.exportColor(flags);
479
- };
480
-
481
-
482
- this.fromRGB = function(r, g, b, flags) { // null = don't change
483
- if(r !== null) { r = Math.max(0.0, Math.min(1.0, r)); }
484
- if(g !== null) { g = Math.max(0.0, Math.min(1.0, g)); }
485
- if(b !== null) { b = Math.max(0.0, Math.min(1.0, b)); }
486
-
487
- var hsv = RGB_HSV(
488
- r===null ? this.rgb[0] : r,
489
- g===null ? this.rgb[1] : g,
490
- b===null ? this.rgb[2] : b
491
- );
492
- if(hsv[0] !== null) {
493
- this.hsv[0] = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, hsv[0]));
494
- }
495
- if(hsv[2] !== 0) {
496
- this.hsv[1] = hsv[1]===null ? null : Math.max(0.0, this.minS, Math.min(1.0, this.maxS, hsv[1]));
497
- }
498
- this.hsv[2] = hsv[2]===null ? null : Math.max(0.0, this.minV, Math.min(1.0, this.maxV, hsv[2]));
499
-
500
- // update RGB according to final HSV, as some values might be trimmed
501
- var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);
502
- this.rgb[0] = rgb[0];
503
- this.rgb[1] = rgb[1];
504
- this.rgb[2] = rgb[2];
505
-
506
- this.exportColor(flags);
507
- };
508
-
509
-
510
- this.fromString = function(hex, flags) {
511
- var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
512
- if(!m) {
513
- return false;
514
- } else {
515
- if(m[1].length === 6) { // 6-char notation
516
- this.fromRGB(
517
- parseInt(m[1].substr(0,2),16) / 255,
518
- parseInt(m[1].substr(2,2),16) / 255,
519
- parseInt(m[1].substr(4,2),16) / 255,
520
- flags
521
- );
522
- } else { // 3-char notation
523
- this.fromRGB(
524
- parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255,
525
- parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255,
526
- parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255,
527
- flags
528
- );
529
- }
530
- return true;
531
- }
532
- };
533
-
534
-
535
- this.toString = function() {
536
- return (
537
- (0x100 | Math.round(255*this.rgb[0])).toString(16).substr(1) +
538
- (0x100 | Math.round(255*this.rgb[1])).toString(16).substr(1) +
539
- (0x100 | Math.round(255*this.rgb[2])).toString(16).substr(1)
540
- );
541
- };
542
-
543
-
544
- function RGB_HSV(r, g, b) {
545
- var n = Math.min(Math.min(r,g),b);
546
- var v = Math.max(Math.max(r,g),b);
547
- var m = v - n;
548
- if(m === 0) { return [ null, 0, v ]; }
549
- var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);
550
- return [ h===6?0:h, m/v, v ];
551
- }
552
-
553
-
554
- function HSV_RGB(h, s, v) {
555
- if(h === null) { return [ v, v, v ]; }
556
- var i = Math.floor(h);
557
- var f = i%2 ? h-i : 1-(h-i);
558
- var m = v * (1 - s);
559
- var n = v * (1 - s*f);
560
- switch(i) {
561
- case 6:
562
- case 0: return [v,n,m];
563
- case 1: return [n,v,m];
564
- case 2: return [m,v,n];
565
- case 3: return [m,n,v];
566
- case 4: return [n,m,v];
567
- case 5: return [v,m,n];
568
- }
569
- }
570
-
571
-
572
- function removePicker() {
573
- delete jscolor.picker.owner;
574
- document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB);
575
- }
576
-
577
-
578
- function drawPicker(x, y) {
579
- if(!jscolor.picker) {
580
- jscolor.picker = {
581
- box : document.createElement('div'),
582
- boxB : document.createElement('div'),
583
- pad : document.createElement('div'),
584
- padB : document.createElement('div'),
585
- padM : document.createElement('div'),
586
- sld : document.createElement('div'),
587
- sldB : document.createElement('div'),
588
- sldM : document.createElement('div'),
589
- btn : document.createElement('div'),
590
- btnS : document.createElement('span'),
591
- btnT : document.createTextNode(THIS.pickerCloseText)
592
- };
593
- for(var i=0,segSize=4; i<jscolor.images.sld[1]; i+=segSize) {
594
- var seg = document.createElement('div');
595
- seg.style.height = segSize+'px';
596
- seg.style.fontSize = '1px';
597
- seg.style.lineHeight = '0';
598
- jscolor.picker.sld.appendChild(seg);
599
- }
600
- jscolor.picker.sldB.appendChild(jscolor.picker.sld);
601
- jscolor.picker.box.appendChild(jscolor.picker.sldB);
602
- jscolor.picker.box.appendChild(jscolor.picker.sldM);
603
- jscolor.picker.padB.appendChild(jscolor.picker.pad);
604
- jscolor.picker.box.appendChild(jscolor.picker.padB);
605
- jscolor.picker.box.appendChild(jscolor.picker.padM);
606
- jscolor.picker.btnS.appendChild(jscolor.picker.btnT);
607
- jscolor.picker.btn.appendChild(jscolor.picker.btnS);
608
- jscolor.picker.box.appendChild(jscolor.picker.btn);
609
- jscolor.picker.boxB.appendChild(jscolor.picker.box);
610
- }
611
-
612
- var p = jscolor.picker;
613
-
614
- // controls interaction
615
- p.box.onmouseup =
616
- p.box.onmouseout = function() { target.focus(); };
617
- p.box.onmousedown = function() { abortBlur=true; };
618
- p.box.onmousemove = function(e) {
619
- if (holdPad || holdSld) {
620
- holdPad && setPad(e);
621
- holdSld && setSld(e);
622
- if (document.selection) {
623
- document.selection.empty();
624
- } else if (window.getSelection) {
625
- window.getSelection().removeAllRanges();
626
- }
627
- dispatchImmediateChange();
628
- }
629
- };
630
- p.padM.onmouseup =
631
- p.padM.onmouseout = function() { if(holdPad) { holdPad=false; jscolor.fireEvent(valueElement,'change'); } };
632
- p.padM.onmousedown = function(e) {
633
- // if the slider is at the bottom, move it up
634
- switch(modeID) {
635
- case 0: if (THIS.hsv[2] === 0) { THIS.fromHSV(null, null, 1.0); }; break;
636
- case 1: if (THIS.hsv[1] === 0) { THIS.fromHSV(null, 1.0, null); }; break;
637
- }
638
- holdPad=true;
639
- setPad(e);
640
- dispatchImmediateChange();
641
- };
642
- p.sldM.onmouseup =
643
- p.sldM.onmouseout = function() { if(holdSld) { holdSld=false; jscolor.fireEvent(valueElement,'change'); } };
644
- p.sldM.onmousedown = function(e) {
645
- holdSld=true;
646
- setSld(e);
647
- dispatchImmediateChange();
648
- };
649
-
650
- // picker
651
- var dims = getPickerDims(THIS);
652
- p.box.style.width = dims[0] + 'px';
653
- p.box.style.height = dims[1] + 'px';
654
-
655
- // picker border
656
- p.boxB.style.position = 'absolute';
657
- p.boxB.style.clear = 'both';
658
- p.boxB.style.left = x+'px';
659
- p.boxB.style.top = y+'px';
660
- p.boxB.style.zIndex = THIS.pickerZIndex;
661
- p.boxB.style.border = THIS.pickerBorder+'px solid';
662
- p.boxB.style.borderColor = THIS.pickerBorderColor;
663
- p.boxB.style.background = THIS.pickerFaceColor;
664
-
665
- // pad image
666
- p.pad.style.width = jscolor.images.pad[0]+'px';
667
- p.pad.style.height = jscolor.images.pad[1]+'px';
668
-
669
- // pad border
670
- p.padB.style.position = 'absolute';
671
- p.padB.style.left = THIS.pickerFace+'px';
672
- p.padB.style.top = THIS.pickerFace+'px';
673
- p.padB.style.border = THIS.pickerInset+'px solid';
674
- p.padB.style.borderColor = THIS.pickerInsetColor;
675
-
676
- // pad mouse area
677
- p.padM.style.position = 'absolute';
678
- p.padM.style.left = '0';
679
- p.padM.style.top = '0';
680
- p.padM.style.width = THIS.pickerFace + 2*THIS.pickerInset + jscolor.images.pad[0] + jscolor.images.arrow[0] + 'px';
681
- p.padM.style.height = p.box.style.height;
682
- p.padM.style.cursor = 'crosshair';
683
-
684
- // slider image
685
- p.sld.style.overflow = 'hidden';
686
- p.sld.style.width = jscolor.images.sld[0]+'px';
687
- p.sld.style.height = jscolor.images.sld[1]+'px';
688
-
689
- // slider border
690
- p.sldB.style.display = THIS.slider ? 'block' : 'none';
691
- p.sldB.style.position = 'absolute';
692
- p.sldB.style.right = THIS.pickerFace+'px';
693
- p.sldB.style.top = THIS.pickerFace+'px';
694
- p.sldB.style.border = THIS.pickerInset+'px solid';
695
- p.sldB.style.borderColor = THIS.pickerInsetColor;
696
-
697
- // slider mouse area
698
- p.sldM.style.display = THIS.slider ? 'block' : 'none';
699
- p.sldM.style.position = 'absolute';
700
- p.sldM.style.right = '0';
701
- p.sldM.style.top = '0';
702
- p.sldM.style.width = jscolor.images.sld[0] + jscolor.images.arrow[0] + THIS.pickerFace + 2*THIS.pickerInset + 'px';
703
- p.sldM.style.height = p.box.style.height;
704
- try {
705
- p.sldM.style.cursor = 'pointer';
706
- } catch(eOldIE) {
707
- p.sldM.style.cursor = 'hand';
708
- }
709
-
710
- // "close" button
711
- function setBtnBorder() {
712
- var insetColors = THIS.pickerInsetColor.split(/\s+/);
713
- var pickerOutsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];
714
- p.btn.style.borderColor = pickerOutsetColor;
715
- }
716
- p.btn.style.display = THIS.pickerClosable ? 'block' : 'none';
717
- p.btn.style.position = 'absolute';
718
- p.btn.style.left = THIS.pickerFace + 'px';
719
- p.btn.style.bottom = THIS.pickerFace + 'px';
720
- p.btn.style.padding = '0 15px';
721
- p.btn.style.height = '18px';
722
- p.btn.style.border = THIS.pickerInset + 'px solid';
723
- setBtnBorder();
724
- p.btn.style.color = THIS.pickerButtonColor;
725
- p.btn.style.font = '12px sans-serif';
726
- p.btn.style.textAlign = 'center';
727
- try {
728
- p.btn.style.cursor = 'pointer';
729
- } catch(eOldIE) {
730
- p.btn.style.cursor = 'hand';
731
- }
732
- p.btn.onmousedown = function () {
733
- THIS.hidePicker();
734
- };
735
- p.btnS.style.lineHeight = p.btn.style.height;
736
-
737
- // load images in optimal order
738
- switch(modeID) {
739
- case 0: var padImg = 'hs.png'; break;
740
- case 1: var padImg = 'hv.png'; break;
741
- }
742
- p.padM.style.backgroundImage = "url('"+jscolor.getDir()+"cross.gif')";
743
- p.padM.style.backgroundRepeat = "no-repeat";
744
- p.sldM.style.backgroundImage = "url('"+jscolor.getDir()+"arrow.gif')";
745
- p.sldM.style.backgroundRepeat = "no-repeat";
746
- p.pad.style.backgroundImage = "url('"+jscolor.getDir()+padImg+"')";
747
- p.pad.style.backgroundRepeat = "no-repeat";
748
- p.pad.style.backgroundPosition = "0 0";
749
-
750
- // place pointers
751
- redrawPad();
752
- redrawSld();
753
-
754
- jscolor.picker.owner = THIS;
755
- document.getElementsByTagName('body')[0].appendChild(p.boxB);
756
- }
757
-
758
-
759
- function getPickerDims(o) {
760
- var dims = [
761
- 2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[0] +
762
- (o.slider ? 2*o.pickerInset + 2*jscolor.images.arrow[0] + jscolor.images.sld[0] : 0),
763
- o.pickerClosable ?
764
- 4*o.pickerInset + 3*o.pickerFace + jscolor.images.pad[1] + o.pickerButtonHeight :
765
- 2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[1]
766
- ];
767
- return dims;
768
- }
769
-
770
-
771
- function redrawPad() {
772
- // redraw the pad pointer
773
- switch(modeID) {
774
- case 0: var yComponent = 1; break;
775
- case 1: var yComponent = 2; break;
776
- }
777
- var x = Math.round((THIS.hsv[0]/6) * (jscolor.images.pad[0]-1));
778
- var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.pad[1]-1));
779
- jscolor.picker.padM.style.backgroundPosition =
780
- (THIS.pickerFace+THIS.pickerInset+x - Math.floor(jscolor.images.cross[0]/2)) + 'px ' +
781
- (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.cross[1]/2)) + 'px';
782
-
783
- // redraw the slider image
784
- var seg = jscolor.picker.sld.childNodes;
785
-
786
- switch(modeID) {
787
- case 0:
788
- var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 1);
789
- for(var i=0; i<seg.length; i+=1) {
790
- seg[i].style.backgroundColor = 'rgb('+
791
- (rgb[0]*(1-i/seg.length)*100)+'%,'+
792
- (rgb[1]*(1-i/seg.length)*100)+'%,'+
793
- (rgb[2]*(1-i/seg.length)*100)+'%)';
794
- }
795
- break;
796
- case 1:
797
- var rgb, s, c = [ THIS.hsv[2], 0, 0 ];
798
- var i = Math.floor(THIS.hsv[0]);
799
- var f = i%2 ? THIS.hsv[0]-i : 1-(THIS.hsv[0]-i);
800
- switch(i) {
801
- case 6:
802
- case 0: rgb=[0,1,2]; break;
803
- case 1: rgb=[1,0,2]; break;
804
- case 2: rgb=[2,0,1]; break;
805
- case 3: rgb=[2,1,0]; break;
806
- case 4: rgb=[1,2,0]; break;
807
- case 5: rgb=[0,2,1]; break;
808
- }
809
- for(var i=0; i<seg.length; i+=1) {
810
- s = 1 - 1/(seg.length-1)*i;
811
- c[1] = c[0] * (1 - s*f);
812
- c[2] = c[0] * (1 - s);
813
- seg[i].style.backgroundColor = 'rgb('+
814
- (c[rgb[0]]*100)+'%,'+
815
- (c[rgb[1]]*100)+'%,'+
816
- (c[rgb[2]]*100)+'%)';
817
- }
818
- break;
819
- }
820
- }
821
-
822
-
823
- function redrawSld() {
824
- // redraw the slider pointer
825
- switch(modeID) {
826
- case 0: var yComponent = 2; break;
827
- case 1: var yComponent = 1; break;
828
- }
829
- var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.sld[1]-1));
830
- jscolor.picker.sldM.style.backgroundPosition =
831
- '0 ' + (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.arrow[1]/2)) + 'px';
832
- }
833
-
834
-
835
- function isPickerOwner() {
836
- return jscolor.picker && jscolor.picker.owner === THIS;
837
- }
838
-
839
-
840
- function blurTarget() {
841
- if(valueElement === target) {
842
- THIS.importColor();
843
- }
844
- if(THIS.pickerOnfocus) {
845
- THIS.hidePicker();
846
- }
847
- }
848
-
849
-
850
- function blurValue() {
851
- if(valueElement !== target) {
852
- THIS.importColor();
853
- }
854
- }
855
-
856
-
857
- function setPad(e) {
858
- var mpos = jscolor.getRelMousePos(e);
859
- var x = mpos.x - THIS.pickerFace - THIS.pickerInset;
860
- var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
861
- switch(modeID) {
862
- case 0: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), 1 - y/(jscolor.images.pad[1]-1), null, leaveSld); break;
863
- case 1: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), null, 1 - y/(jscolor.images.pad[1]-1), leaveSld); break;
864
- }
865
- }
866
-
867
-
868
- function setSld(e) {
869
- var mpos = jscolor.getRelMousePos(e);
870
- var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
871
- switch(modeID) {
872
- case 0: THIS.fromHSV(null, null, 1 - y/(jscolor.images.sld[1]-1), leavePad); break;
873
- case 1: THIS.fromHSV(null, 1 - y/(jscolor.images.sld[1]-1), null, leavePad); break;
874
- }
875
- }
876
-
877
-
878
- function dispatchImmediateChange() {
879
- if (THIS.onImmediateChange) {
880
- var callback;
881
- if (typeof THIS.onImmediateChange === 'string') {
882
- callback = new Function (THIS.onImmediateChange);
883
- } else {
884
- callback = THIS.onImmediateChange;
885
- }
886
- callback.call(THIS);
887
- }
888
- }
889
-
890
-
891
- var THIS = this;
892
- var modeID = this.pickerMode.toLowerCase()==='hvs' ? 1 : 0;
893
- var abortBlur = false;
894
- var
895
- valueElement = jscolor.fetchElement(this.valueElement),
896
- styleElement = jscolor.fetchElement(this.styleElement);
897
- var
898
- holdPad = false,
899
- holdSld = false;
900
- var
901
- leaveValue = 1<<0,
902
- leaveStyle = 1<<1,
903
- leavePad = 1<<2,
904
- leaveSld = 1<<3;
905
-
906
- // target
907
- jscolor.addEvent(target, 'focus', function() {
908
- if(THIS.pickerOnfocus) { THIS.showPicker(); }
909
- });
910
- jscolor.addEvent(target, 'blur', function() {
911
- if(!abortBlur) {
912
- window.setTimeout(function(){ abortBlur || blurTarget(); abortBlur=false; }, 0);
913
- } else {
914
- abortBlur = false;
915
- }
916
- });
917
-
918
- // valueElement
919
- if(valueElement) {
920
- var updateField = function() {
921
- THIS.fromString(valueElement.value, leaveValue);
922
- dispatchImmediateChange();
923
- };
924
- jscolor.addEvent(valueElement, 'keyup', updateField);
925
- jscolor.addEvent(valueElement, 'input', updateField);
926
- jscolor.addEvent(valueElement, 'blur', blurValue);
927
- valueElement.setAttribute('autocomplete', 'off');
928
- }
929
-
930
- // styleElement
931
- if(styleElement) {
932
- styleElement.jscStyle = {
933
- backgroundImage : styleElement.style.backgroundImage,
934
- backgroundColor : styleElement.style.backgroundColor,
935
- color : styleElement.style.color
936
- };
937
- }
938
-
939
- // require images
940
- switch(modeID) {
941
- case 0: jscolor.requireImage('hs.png'); break;
942
- case 1: jscolor.requireImage('hv.png'); break;
943
- }
944
- jscolor.requireImage('cross.gif');
945
- jscolor.requireImage('arrow.gif');
946
-
947
- this.importColor();
948
- }
949
-
950
- };
951
-
952
-
953
- jscolor.install();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/lib-eddialog.php CHANGED
@@ -109,14 +109,14 @@ $profiles = gde_get_profiles();
109
  <span class="note"><?php _e('Format: 40% or 300px', 'gde'); ?></span>
110
  </td>
111
  </tr>
112
- <tr class="ovrride">
113
  <td align="right" class="gray dwl_gray">
114
  <strong><?php _e('Start Page #', 'gde'); ?></strong>
115
  </td>
116
  <td valign="top">
117
  <input name="page" type="text" class="opt dwl" id="page" size="6" value="1" />
118
  </td>
119
- </tr>
120
  <tr class="ovrride">
121
  <td align="right" class="gray dwl_gray">
122
  <strong><?php _e('Show Download Link', 'gde'); ?></strong>
109
  <span class="note"><?php _e('Format: 40% or 300px', 'gde'); ?></span>
110
  </td>
111
  </tr>
112
+ <!--tr class="ovrride">
113
  <td align="right" class="gray dwl_gray">
114
  <strong><?php _e('Start Page #', 'gde'); ?></strong>
115
  </td>
116
  <td valign="top">
117
  <input name="page" type="text" class="opt dwl" id="page" size="6" value="1" />
118
  </td>
119
+ </tr-->
120
  <tr class="ovrride">
121
  <td align="right" class="gray dwl_gray">
122
  <strong><?php _e('Show Download Link', 'gde'); ?></strong>
libs/lib-profile.php CHANGED
@@ -134,8 +134,7 @@ print_r($p);
134
  <th scope="row"><?php _e('Page Area Background Color', 'gde'); ?></th>
135
  <td>
136
  <?php
137
- gde_profile_text( $p['vw_bgcolor'], 'vw_bgcolor', 'color {hash:true,required:false}', 10 );
138
- gde_profile_text( $p['vw_bgcolor'], 'vw_bgcolor_holder', 'holder', 10, false );
139
  gde_profile_checkbox( $p['vw_flags'], 'gdev_t', __('None (Transparent)', 'gde') );
140
  ?>
141
  </td>
@@ -144,8 +143,7 @@ print_r($p);
144
  <th scope="row"><?php _e('Page Border Color', 'gde'); ?></th>
145
  <td>
146
  <?php
147
- gde_profile_text( $p['vw_pbcolor'], 'vw_pbcolor', 'color {hash:true,required:false}', 10 );
148
- gde_profile_text( $p['vw_pbcolor'], 'vw_pbcolor_holder', 'holder', 10, false );
149
  gde_profile_checkbox( $p['vw_flags'], 'gdev_b', __('No Border', 'gde') );
150
  ?>
151
  </td>
134
  <th scope="row"><?php _e('Page Area Background Color', 'gde'); ?></th>
135
  <td>
136
  <?php
137
+ gde_profile_text( $p['vw_bgcolor'], 'vw_bgcolor', 'gde-color-field', 10 );
 
138
  gde_profile_checkbox( $p['vw_flags'], 'gdev_t', __('None (Transparent)', 'gde') );
139
  ?>
140
  </td>
143
  <th scope="row"><?php _e('Page Border Color', 'gde'); ?></th>
144
  <td>
145
  <?php
146
+ gde_profile_text( $p['vw_pbcolor'], 'vw_pbcolor', 'gde-color-field', 10 );
 
147
  gde_profile_checkbox( $p['vw_flags'], 'gdev_b', __('No Border', 'gde') );
148
  ?>
149
  </td>
libs/lib-setup.php CHANGED
@@ -29,7 +29,7 @@ function gde_defaults( $type ) {
29
  'beta_check' => 'yes',
30
  'api_key' => $env['apikey']
31
  );
32
-
33
  // define default options
34
  $defopts = array(
35
  'ed_disable' => 'no',
@@ -295,6 +295,7 @@ function gde_get_options() {
295
  * @note This should only run once on activation so no transient is necessary
296
  */
297
  function gde_get_api_key( $ver ) {
 
298
  global $current_user;
299
 
300
  if ( is_multisite() ) {
29
  'beta_check' => 'yes',
30
  'api_key' => $env['apikey']
31
  );
32
+
33
  // define default options
34
  $defopts = array(
35
  'ed_disable' => 'no',
295
  * @note This should only run once on activation so no transient is necessary
296
  */
297
  function gde_get_api_key( $ver ) {
298
+ return ''; // disable api keyfetch (bandwidth issues)
299
  global $current_user;
300
 
301
  if ( is_multisite() ) {
readme.txt CHANGED
@@ -3,12 +3,12 @@ Contributors: k3davis
3
  Tags: doc, docx, pdf, ppt, pptx, xls, psd, zip, rar, tiff, ttf, office, powerpoint, google
4
  Author URI: http://www.davistribe.org/code/
5
  Donate link: http://www.davistribe.org/gde/donate/
6
- Requires at least: 3.2
7
- Tested up to: 3.6
8
  Stable tag: trunk
9
  License: GPLv2 or later
10
 
11
- Lets you embed MS Office, PDF, and many other file types in a web page using the Google Docs Viewer (no Flash or PDF browser plug-ins required).
12
 
13
  == Description ==
14
 
@@ -68,7 +68,7 @@ Go to "GDE Settings" (under "Settings" in the admin panel) to change defaults, o
68
 
69
  = Where can the files live? =
70
  The file to embed must first be publicly available somewhere on the internet, in order for Google to retrieve the document for conversion.
71
- You can upload it to your WordPress site using the standard techniques, or link to a file on another site.
72
 
73
  = How do I embed a file in my page or post? =
74
  There are several ways you can insert a supported document, depending on your preference:
@@ -93,7 +93,6 @@ Common optional attributes:
93
  * `profile=` : Enter the number or name of the desired profile for the viewer to use (default profile is used if not specified)
94
  * `width=` : To override the profile's default width of the viewer, enter a new width value - e.g., "400px" or "80%"
95
  * `height=` : To override the profile's default height of the viewer, enter a new height value - e.g., "400px" or "80%"
96
- * `page=` : Set to the number of the page you want the document to open up to (if not page 1)
97
 
98
  For a list of all available attributes, see [Usage](http://www.davistribe.org/gde/usage/ "Usage").
99
 
@@ -118,9 +117,8 @@ documents stored there and shared publicly do not embed reliably with their stan
118
  supported by the plug-in. Please store your original documents somewhere on your web site in their native supported formats.
119
 
120
  = Does it work in Multisite environments? =
121
- Yes, though the plugin does not support network activation at this time. For now, please activate individually on muultisite installs.
122
- I will work to improve this in a coming version. Otherwise, more granular multisite options are planned for future versions based on demand.
123
- If you use GDE in a multisite environment, I welcome your feedback on what functionality you would like to see.
124
 
125
  = Other Common Questions =
126
  More common questions are answered on the GDE web site [here](http://www.davistribe.org/gde/notes/ "Notes").
@@ -137,6 +135,15 @@ More common questions are answered on the GDE web site [here](http://www.davistr
137
 
138
  (E) Enhanced Viewer
139
 
 
 
 
 
 
 
 
 
 
140
  = 2.5.8 =
141
  * Added: (E) Right-click menu disabled on secure documents
142
  * Fixed: Support tab service errors
@@ -212,49 +219,9 @@ More common questions are answered on the GDE web site [here](http://www.davistr
212
  * Changed: Errors now show inline instead of as HTML comments by default
213
  * Removed: force= shortcode attribute (redundant and confusing)
214
 
215
- = 2.4.6 =
216
- * Fixed: Error in Mask URL download link for non-PDF file types
217
-
218
- = 2.4.5 =
219
- * Fixed: Regression breaks some files containing spaces (thanks mlautens)
220
- * Fixed: Mask URL 400 error on filenames with spaces (thanks mrhaanraadts)
221
- * Fixed: PDF Force Download option doesn't support SSL
222
-
223
- = 2.4.4 =
224
- * Added: PPS and OTF support
225
- * Fixed: Broken support of international filenames in IE (thanks beredim)
226
- * Fixed: More robust file size checking with nonstandard filenames
227
- * Fixed: Global disable cache option not always honored
228
- * Fixed: (E) Mobile theme not loaded if not globally requested
229
- * Changed: Now requires WordPress 3.0+ (mainly for support reasons)
230
-
231
- = 2.4.3 =
232
- * Added: (E) Dark theme shortcode option (EXPERIMENTAL)
233
- * Added: Turkish translation (thanks LettoBlog)
234
- * Fixed: Visual editor integration for IIS webhosts (thanks Kristof)
235
- * Changed: Debug information is now a support page from plugin list
236
-
237
- = 2.4.2 =
238
- * Fixed: PHP Warning related to MIME type expansion (thanks Adebayo)
239
-
240
- = 2.4.1 =
241
- * Added: Spanish translation (thanks elarequi)
242
- * Added: Method to obtain debug information
243
- * Fixed: Insertion of non-GDE file types from Media Library
244
-
245
- = 2.4 =
246
- * Added: Allow native upload/insert of all supported file types
247
- * Added: Shortcode inserted from Media Library for supported files
248
- * Added: Localization support (translations welcome)
249
- * Added: (E) Ability to use mobile theme
250
- * Fixed: (E) Toolbar customization on mobile
251
- * Fixed: Editor integration no longer loads its own TinyMCE/jquery libs
252
- * Fixed: URL changes for plugin, help links, beta checking
253
- * Fixed: (E) "Moved Temporarily" error (thanks webmonkeywatts)
254
-
255
  [Full history...](http://www.davistribe.org/gde/changelog/ "Full history")
256
 
257
  == Upgrade Notice ==
258
 
259
- = 2.5.8 =
260
  Maintenance release
3
  Tags: doc, docx, pdf, ppt, pptx, xls, psd, zip, rar, tiff, ttf, office, powerpoint, google
4
  Author URI: http://www.davistribe.org/code/
5
  Donate link: http://www.davistribe.org/gde/donate/
6
+ Requires at least: 3.5
7
+ Tested up to: 3.8
8
  Stable tag: trunk
9
  License: GPLv2 or later
10
 
11
+ Lets you embed PDF, MS Office, and many other file types in a web page using the Google Docs Viewer (no Flash or PDF browser plug-ins required).
12
 
13
  == Description ==
14
 
68
 
69
  = Where can the files live? =
70
  The file to embed must first be publicly available somewhere on the internet, in order for Google to retrieve the document for conversion.
71
+ You can upload it to your WordPress site using the standard techniques, or link to a file on another site. For testing purposes, your site can run locally or on private networks, but the documents you wish to embed must be publicly accessible.
72
 
73
  = How do I embed a file in my page or post? =
74
  There are several ways you can insert a supported document, depending on your preference:
93
  * `profile=` : Enter the number or name of the desired profile for the viewer to use (default profile is used if not specified)
94
  * `width=` : To override the profile's default width of the viewer, enter a new width value - e.g., "400px" or "80%"
95
  * `height=` : To override the profile's default height of the viewer, enter a new height value - e.g., "400px" or "80%"
 
96
 
97
  For a list of all available attributes, see [Usage](http://www.davistribe.org/gde/usage/ "Usage").
98
 
117
  supported by the plug-in. Please store your original documents somewhere on your web site in their native supported formats.
118
 
119
  = Does it work in Multisite environments? =
120
+ The plugin works on network installs, though it must be activated on a per-site basis (not network activated). There are no multisite
121
+ specific features at this time, but it will function normally in this environment. If you use GDE in a multisite environment, I welcome your feedback on what functionality you would like to see.
 
122
 
123
  = Other Common Questions =
124
  More common questions are answered on the GDE web site [here](http://www.davistribe.org/gde/notes/ "Notes").
135
 
136
  (E) Enhanced Viewer
137
 
138
+ = 2.5.10 =
139
+ * Fixed: PHP warning on multisite during uninstall (thanks TigranTovmasyan)
140
+ * Changed: (E) Viewer settings use native color picker
141
+ * Changed: Now requires WordPress 3.5+ (removed legacy functions)
142
+
143
+ = 2.5.9 =
144
+ * Fixed: Mixed content restrictions while parent page is SSL
145
+ * Removed: page= shortcode attribute (broken in Google Viewer)
146
+
147
  = 2.5.8 =
148
  * Added: (E) Right-click menu disabled on secure documents
149
  * Fixed: Support tab service errors
219
  * Changed: Errors now show inline instead of as HTML comments by default
220
  * Removed: force= shortcode attribute (redundant and confusing)
221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  [Full history...](http://www.davistribe.org/gde/changelog/ "Full history")
223
 
224
  == Upgrade Notice ==
225
 
226
+ = 2.5.10 =
227
  Maintenance release
screenshot-4.png CHANGED
Binary file
uninstall.php CHANGED
@@ -8,7 +8,7 @@ if ( is_multisite() ) {
8
  delete_site_option( 'gde_globals' );
9
  delete_site_transient( 'gde_beta_version' );
10
 
11
- $blogids = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs" ) );
12
  foreach ( $blogids as $blogid ) {
13
  switch_to_blog( $blogid );
14
 
8
  delete_site_option( 'gde_globals' );
9
  delete_site_transient( 'gde_beta_version' );
10
 
11
+ $blogids = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM '%s'", $wpdb->blogs ) );
12
  foreach ( $blogids as $blogid ) {
13
  switch_to_blog( $blogid );
14