Project

General

Profile

Paste
Download (19.1 KB) Statistics
| Branch: | Revision:

root / drupal7 / sites / all / modules / jquery_update / jquery_update.module @ 2c8c2b87

1
<?php
2

    
3
/**
4
 * @file
5
 * Updates Drupal to use the latest version of jQuery.
6
 */
7

    
8
/**
9
 * Implements hook_help().
10
 */
11
function jquery_update_help($path, $arg) {
12
  switch ($path) {
13
    // Help for another path in the block module.
14
    case 'admin/config/development/jquery_update':
15
      return '<p>' . t('Configure how <a href="@jquery">jQuery</a> behaves on the site. Select which jQuery version, the compression level and whether or not to use a CDN.', array(
16
        '@jquery' => 'http://jquery.com',
17
      )) . '</p>';
18
  }
19
}
20

    
21
/**
22
 * Implements hook_library().
23
 */
24
function jquery_update_library() {
25
  // Register libraries available in the external directory.
26
  $path = drupal_get_path('module', 'jquery_update') . '/ui/external';
27
  $libraries['qunit'] = array(
28
    'title' => 'QUnit',
29
    'js' => array(
30
      $path . '/qunit.js' => array(
31
        'group' => JS_LIBRARY,
32
        'weight' => 2,
33
      ),
34
    ),
35
    'css' => array(
36
      $path . '/qunit.css' => array(),
37
    ),
38
    'version' => '1.11.0',
39
  );
40
  $libraries['jquery_update.ajax.fix'] = array(
41
    'title' => 'jQuery Update Version Fix',
42
    'js' => array(
43
      drupal_get_path('module', 'jquery_update') . '/js/jquery_update.js' => array(
44
        'group' => JS_LIBRARY,
45
        'weight' => 3,
46
      ),
47
    ),
48
    'version' => '0.0.1',
49
  );
50
  $libraries['jquery.metadata'] = array(
51
    'title' => 'QUnit',
52
    'js' => array(
53
      $path . '/jquery.metadata.js' => array(
54
        'group' => JS_LIBRARY,
55
        'weight' => 2,
56
      ),
57
    ),
58
    'version' => '4187',
59
  );
60
  $libraries['jquery.bgiframe'] = array(
61
    'title' => 'bgiframe',
62
    'website' => 'http://docs.jquery.com/Plugins/bgiframe',
63
    'js' => array(
64
      $path . '/jquery.bgiframe.js' => array(
65
        'group' => JS_LIBRARY,
66
        'weight' => 2,
67
      ),
68
    ),
69
    'version' => '2.1.2',
70
  );
71
  return $libraries;
72
}
73

    
74
/**
75
 * Implements hook_library_alter().
76
 */
77
function jquery_update_library_alter(&$javascript, $module) {
78
  $path = drupal_get_path('module', 'jquery_update');
79
  $version = variable_get('jquery_update_jquery_version', '1.10');
80

    
81

    
82
  // Modified System Library.
83
  if ($module === 'system') {
84

    
85
    // Make sure we inject either the minified or uncompressed version as desired.
86
    $min = variable_get('jquery_update_compression_type', 'min') == 'none' ? '' : '.min';
87
    $cdn = variable_get('jquery_update_jquery_cdn', 'none');
88

    
89
    // Replace jQuery with the alternative version.
90
    $admin_version = variable_get('jquery_update_jquery_admin_version', '');
91

    
92
    if (!empty($admin_version) && path_is_admin(current_path())) {
93
      if (version_compare($version, $admin_version, '!=')) {
94
        $version = $admin_version;
95
      }
96
    }
97
    // If the ajax version is set then that one always win.
98
    if (!empty($_POST['ajax_page_state']['jquery_version'])) {
99
      $ajax_version = $_POST['ajax_page_state']['jquery_version'];
100
      if (in_array($ajax_version, array('default', '1.5', '1.6', '1.7', '1.8', '1.9', '1.10'))) {
101
        $version = $ajax_version;
102
      }
103
    }
104

    
105
    // Always add a new jquery_version array to ajaxPageState.
106
    // This is what we used to determine which version to use
107
    // for any ajax callback.
108
    $javascript['drupal.ajax']['js'][] = array(
109
      'data' => array('ajaxPageState' => array('jquery_version' => $version)),
110
      'type' => 'setting',
111
    );
112
    $javascript['drupal.ajax']['dependencies'][] = array('jquery_update', 'jquery_update.ajax.fix');
113

    
114
    // Don't replace anything if Drupal provided jQuery should be used
115
    if ('default' == $version) {
116
      return;
117
    }
118

    
119
    jquery_update_jquery_replace($javascript, $cdn, $path, $min, $version);
120

    
121
    // Replace jQuery UI with CDN or local files. If from a CDN include all of
122
    // jQuery UI.
123
    if (version_compare($version, '1.6', '>=')) {
124
      jquery_update_jqueryui_replace($javascript, $cdn, $path, $min);
125
    }
126

    
127
    // Replace the jQuery Cookie plugin.
128
    $javascript['cookie']['js']['misc/jquery.cookie.js']['data'] = $path . '/replace/ui/external/jquery.cookie.js';
129
    // Noting the version based on git commit as no version number is available.
130
    $javascript['cookie']['version'] = '67fb34f6a866c40d0570';
131

    
132
    // Replace jQuery Form plugin.
133
    $javascript['jquery.form']['js']['misc/jquery.form.js']['data'] = $path . '/replace/misc/jquery.form' . $min . '.js';
134
    $javascript['jquery.form']['version'] = '2.69';
135

    
136
    // Replace files for Jquery 1.9 and up
137
    if (version_compare($version, '1.9', '>=')) {
138
      $javascript['jquery.bbq']['js']['misc/jquery.ba-bbq.js']['data'] = $path . '/replace/misc/1.9/jquery.ba-bbq' . $min . '.js';
139
    }
140
  }
141

    
142
  if ($module == 'overlay') {
143
    if (version_compare($version, '1.9', '>=')) {
144
      $javascript['parent']['js']['modules/overlay/overlay-parent.js']['data'] = $path . '/replace/misc/1.9/overlay-parent.js';
145
    }
146
  }
147
}
148

    
149
/**
150
 * Implements hook_menu().
151
 */
152
function jquery_update_menu() {
153
  $items['admin/config/development/jquery_update'] = array(
154
    'title' => 'jQuery update',
155
    'description' => 'Configure settings related to the jQuery upgrade, the library path and compression.',
156
    'page callback' => 'drupal_get_form',
157
    'page arguments' => array('jquery_update_settings_form'),
158
    'access arguments' => array('administer site configuration'),
159
  );
160

    
161
  return $items;
162
}
163

    
164
/**
165
 * Admin settings menu callback.
166
 *
167
 * @see jquery_update_menu()
168
 */
169
function jquery_update_settings_form() {
170
  $form['version_options'] = array(
171
    '#type' => 'fieldset',
172
    '#title' => t('Version options'),
173
  );
174

    
175
  $form['version_options']['jquery_update_jquery_version'] = array(
176
    '#type' => 'select',
177
    '#title' => t('Default jQuery Version'),
178
    '#options' => array(
179
      'default' => t('Default (provided by Drupal)'),
180
      '1.5' => '1.5',
181
      '1.7' => '1.7',
182
      '1.8' => '1.8',
183
      '1.9' => '1.9',
184
      '1.10' => '1.10',
185
    ),
186
    '#default_value' => variable_get('jquery_update_jquery_version', '1.10'),
187
    '#description' => t('Select which jQuery version to use by default.'),
188
  );
189

    
190
  $form['version_options']['jquery_update_jquery_admin_version'] = array(
191
    '#type' => 'select',
192
    '#title' => t('Alternate jQuery version for administrative pages'),
193
    '#options' => array(
194
      '' => t('Default jQuery Version'),
195
      'default' => t('Default (provided by Drupal)'),
196
      '1.5' => '1.5',
197
      '1.7' => '1.7',
198
      '1.8' => '1.8',
199
      '1.10' => '1.10',
200
    ),
201
    '#default_value' => variable_get('jquery_update_jquery_admin_version', ''),
202
    '#description' => t('Optionally select a different version of jQuery to use on administrative pages.'),
203
  );
204

    
205
  $form['jquery_update_compression_type'] = array(
206
    '#type' => 'radios',
207
    '#title' => t('jQuery compression level'),
208
    '#options' => array(
209
      'min' => t('Production (minified)'),
210
      'none' => t('Development (uncompressed)'),
211
    ),
212
    // Do not show this field if jQuery version is default
213
    '#states' => array(
214
      'invisible' => array(
215
        ':input[name=jquery_update_jquery_version]' => array('value' => "default"),
216
      ),
217
    ),
218
    '#default_value' => variable_get('jquery_update_compression_type', 'min'),
219
  );
220
  $form['jquery_update_jquery_cdn'] = array(
221
    '#type' => 'select',
222
    '#title' => t('jQuery and jQuery UI CDN'),
223
    '#options' => array(
224
      'none' => t('None'),
225
      'google' => t('Google'),
226
      'microsoft' => t('Microsoft'),
227
      'jquery' => t('jQuery'),
228
    ),
229
    // Do not show this field if jQuery version is default
230
    '#states' => array(
231
      'invisible' => array(
232
        ':input[name=jquery_update_jquery_version]' => array('value' => "default"),
233
      ),
234
    ),
235
    '#default_value' => variable_get('jquery_update_jquery_cdn', 'none'),
236
    '#description' => t('Use jQuery and jQuery UI from a CDN. If the CDN is not available the local version of jQuery and jQuery UI will be used.'),
237
  );
238

    
239
  return system_settings_form($form);
240
}
241

    
242
/**
243
 * Update jQuery to the CDN or local path.
244
 *
245
 * @param array $javascript
246
 *   The library definition array as seen in hook_library_alter().
247
 * @param string $cdn
248
 *   The name of the CDN option to use. Possible options are:
249
 *   - none
250
 *   - google
251
 *   - microsoft
252
 * @param string $path
253
 *   The path to the module where replacements can be found.
254
 * @param string $min
255
 *   The '.min' to include in the file name if we are requesting a minified
256
 *   version.
257
 * @param string $version
258
 *   The version of jQuery to use.
259
 */
260
function jquery_update_jquery_replace(&$javascript, $cdn, $path, $min, $version) {
261

    
262
  // Make sure to use the latest version in given branch.
263
  $trueversion = NULL;
264
  switch ($version) {
265
    case '1.5':
266
      $trueversion = '1.5.2';
267
      break;
268

    
269
    case '1.7':
270
      $trueversion = '1.7.2';
271
      break;
272

    
273
    case '1.8':
274
      $trueversion = '1.8.3';
275
      break;
276

    
277
    case '1.9':
278
      $trueversion = '1.9.1';
279
      break;
280

    
281
    case '1.10':
282
      $trueversion = '1.10.2';
283
      break;
284
  }
285
  $javascript['jquery']['version'] = $trueversion;
286

    
287
  // Check for CDN support.
288
  switch ($cdn) {
289
    case 'google':
290
      $javascript['jquery']['js']['misc/jquery.js']['data'] = '//ajax.googleapis.com/ajax/libs/jquery/' . $trueversion . '/jquery' . $min . '.js';
291
      $javascript['jquery']['js']['misc/jquery.js']['type'] = 'external';
292
      jquery_update_jquery_backup($javascript, $path, $min, $version);
293
      break;
294

    
295
    case 'microsoft':
296
      $javascript['jquery']['js']['misc/jquery.js']['data'] = '//ajax.aspnetcdn.com/ajax/jQuery/jquery-' . $trueversion . $min . '.js';
297
      $javascript['jquery']['js']['misc/jquery.js']['type'] = 'external';
298
      jquery_update_jquery_backup($javascript, $path, $min, $version);
299
      break;
300

    
301
    case 'jquery':
302
      $javascript['jquery']['js']['misc/jquery.js']['data'] = '//code.jquery.com/jquery-' . $trueversion . $min . '.js';
303
      $javascript['jquery']['js']['misc/jquery.js']['type'] = 'external';
304
      jquery_update_jquery_backup($javascript, $path, $min, $version);
305
      break;
306

    
307
    case 'none':
308
    default:
309
      $javascript['jquery']['js']['misc/jquery.js']['data'] = $path . '/replace/jquery/' . $version . '/jquery' . $min . '.js';
310
      break;
311
  }
312
}
313

    
314
/**
315
 * Add the local fallback in case jQuery from the CDN is unavailable.
316
 *
317
 * @param array $javascript
318
 *   The $libraries array as seen in hook_library_alter()
319
 * @param string $path
320
 *   The path to the module where replacements can be found.
321
 * @param string $min
322
 *   The '.min' to include in the file name if we are requesting a minified
323
 *   version.
324
 * @param string $version
325
 *   The verison of jQuery to use.
326
 */
327
function jquery_update_jquery_backup(&$javascript, $path, $min, $version) {
328
  $javascript['jquery']['js'][] = array(
329
    'data' => 'window.jQuery || document.write("<script src=\'' . base_path() . $path . '/replace/jquery/' . $version . '/jquery' . $min . '.js\'>\x3C/script>")',
330
    'type' => 'inline',
331
    'group' => JS_LIBRARY,
332
    'weight' => -19.999999999,
333
  );
334
}
335

    
336
/**
337
 * Update jQuery UI to the CDN or local path.
338
 *
339
 * @param array $javascript
340
 *   The library definition array as seen in hook_library_alter().
341
 * @param string $cdn
342
 *   The name of the CDN option to use. Possible options are:
343
 *   - none
344
 *   - google
345
 *   - microsoft
346
 * @param string $path
347
 *   The path to the module where replacements can be found.
348
 * @param string $min
349
 *   The '.min' to include in the file name if we are requesting a minified
350
 *   version.
351
 */
352
function jquery_update_jqueryui_replace(&$javascript, $cdn, $path, $min) {
353
  // Add new components
354
  $javascript['ui.menu'] = array(
355
    'title' => 'jQuery UI: Menu',
356
    'website' => 'http://jqueryui.com/demos/menu/',
357
    'version' => '1.10.2',
358
    'js' => array('misc/ui/jquery.ui.menu.min.js' => array()),
359
    'css' => array('misc/ui/jquery.ui.menu.css' => array()),
360
    'dependencies' => array(array('system', 'ui.widget'), array('system', 'ui.position')),
361
  );
362
  $javascript['ui.spinner'] = array(
363
    'title' => 'jQuery UI: Spinner',
364
    'website' => 'http://jqueryui.com/demos/spinner/',
365
    'version' => '1.10.2',
366
    'js' => array('misc/ui/jquery.ui.spinner.min.js' => array()),
367
    'css' => array('misc/ui/jquery.ui.spinner.css' => array()),
368
    'dependencies' => array(array('system', 'ui.widget'), array('system', 'ui.button')),
369
  );
370
  $javascript['ui.tooltip'] = array(
371
    'title' => 'jQuery UI: Spinner',
372
    'website' => 'http://jqueryui.com/demos/tooltip/',
373
    'version' => '1.10.2',
374
    'js' => array('misc/ui/jquery.ui.tooltip.min.js' => array()),
375
    'css' => array('misc/ui/jquery.ui.tooltip.css' => array()),
376
    'dependencies' => array(array('system', 'ui.widget'), array('system', 'ui.position')),
377
  );
378

    
379
  // fix dependencies
380
  $javascript['ui.autocomplete']['dependencies'][] = array('system', 'ui.menu');
381
  // Replace all CSS files.
382
  $names = drupal_map_assoc(array(
383
    'ui.accordion', 'ui.autocomplete', 'ui.button', 'ui.datepicker', 'ui.dialog',
384
    'ui.progressbar', 'ui.resizable', 'ui.selectable', 'ui.slider', 'ui.tabs',
385
    'ui.menu', 'ui.spinner', 'ui.tooltip',
386
  ));
387
  $names['ui'] = 'ui.core';
388
  $csspath = $path . '/replace/ui/themes/base/' . (($min == '.min') ? 'minified/' : '');
389
  foreach ($names as $name => $file) {
390
    $javascript[$name]['css']["misc/ui/jquery.$file.css"]['data'] = $csspath . 'jquery.' . $file . $min . '.css';
391
  }
392
  // Make sure ui.theme is replaced as well.
393
  $javascript['ui']['css']['misc/ui/jquery.ui.theme.css']['data'] = $csspath . 'jquery.ui.theme' . $min . '.css';
394

    
395
  // Replace jQuery UI's JavaScript, beginning by defining the mapping.
396
  $names = drupal_map_assoc(array(
397
    'ui.accordion', 'ui.autocomplete', 'ui.button', 'ui.datepicker', 'ui.dialog', 'ui.draggable',
398
    'ui.droppable', 'ui.mouse', 'ui.position', 'ui.progressbar', 'ui.resizable', 'ui.selectable',
399
    'ui.slider', 'ui.sortable', 'ui.tabs', 'ui.widget', 'ui.spinner', 'ui.menu', 'ui.tooltip',
400
  ));
401
  $names['ui'] = 'ui.core';
402
  $names['effects'] = array('effects.core', 'ui.effect'); // map[library_hook] = array(core_fn, updated_fn)
403
  $names = jquery_update_make_library_hook_to_file_name_segment_map_for_effects($names);
404

    
405
  switch ($cdn) {
406
    case 'google':
407
      $cdn = '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui' . $min . '.js';
408
      jquery_update_jqueryui_cdn($cdn, $javascript, $path, $min, $names);
409
      jquery_update_jqueryui_backup($javascript, $path, $min);
410
      break;
411

    
412
    case 'microsoft':
413
      $cdn = '//ajax.aspnetcdn.com/ajax/jquery.ui/1.10.2/jquery-ui' . $min . '.js';
414
      jquery_update_jqueryui_cdn($cdn, $javascript, $path, $min, $names);
415
      jquery_update_jqueryui_backup($javascript, $path, $min);
416
      break;
417

    
418
    case 'jquery':
419
      $cdn = '//code.jquery.com/ui/1.10.2/jquery-ui' . $min . '.js';
420
      jquery_update_jqueryui_cdn($cdn, $javascript, $path, $min, $names);
421
      jquery_update_jqueryui_backup($javascript, $path, $min);
422
      break;
423

    
424
    case 'none':
425
      jquery_update_jqueryui_local($javascript, $path, $min, $names);
426
      break;
427
  }
428
}
429

    
430
/**
431
 * Create a mapping from system.module library hooks to file name segments.
432
 *
433
 * @param array $map Optional. If given, append to it.
434
 * @return array The keys are library hooks  and the values are each arrays of
435
 * 2 file name segments as values. The first file name segment can be used to
436
 * reach Drupal core's jQuery UI effect files, and the second file name segment
437
 * can be used to construct a path to the equivalent replacement
438
 * jQuery UI effect file provided by jquery_update.module.
439
 */
440
function jquery_update_make_library_hook_to_file_name_segment_map_for_effects($map = array()) {
441
  $effect_names = array(
442
    'blind', 'bounce', 'clip', 'drop', 'explode', 'fade', 'fold',
443
    'highlight', 'pulsate', 'scale', 'shake', 'slide', 'transfer',
444
  );
445
  foreach ($effect_names as $effect_name) {
446
    $library_hook = 'effects.' . $effect_name;
447
    $file_name_segment_core = $library_hook; // Yes, for the effect files, this is indeed identical.
448
    $file_name_segment_updated = 'ui.effect-' . $effect_name;
449
    $map[$library_hook] = array($file_name_segment_core, $file_name_segment_updated);
450
  }
451
  return $map;
452
}
453

    
454
/**
455
 * Add the local fallback in case jQuery UI from the CDN is unavailable.
456
 *
457
 * @param array $javascript
458
 *   The $libraries array as seen in hook_library_alter()
459
 * @param string $path
460
 *   The path to the module where replacements can be found.
461
 * @param string $min
462
 *   The '.min' to include in the file name if we are requesting a minified
463
 *   version.
464
 */
465
function jquery_update_jqueryui_backup(&$javascript, $path, $min) {
466
  $js_path = ($min == '.min') ? '/replace/ui/ui/minified/jquery-ui.min.js' : '/replace/ui/ui/jquery-ui.js';
467
  $javascript['ui']['js'][] = array(
468
    'data' => 'window.jQuery.ui || document.write("<script src=\'' . base_path() . $path . $js_path . '\'>\x3C/script>")',
469
    'type' => 'inline',
470
    'group' => JS_LIBRARY,
471
    'weight' => -10.999999999,
472
  );
473
}
474

    
475
/**
476
 * Handle when jQuery UI is updated to the cdn version.
477
 *
478
 * @param string $cdn
479
 *   The name of the CDN option to use. Possible options are:
480
 *   - none
481
 *   - google
482
 *   - microsoft
483
 * @param array $javascript
484
 *   The $libraries array as seen in hook_library_alter()
485
 * @param string $path
486
 *   The path to the module where replacements can be found.
487
 * @param string $min
488
 *   The '.min' to include in the file name if we are requesting a minified
489
 *   version.
490
 * * @param array $names
491
 *   An array mapping jquery ui parts to their file names.
492
 */
493
function jquery_update_jqueryui_cdn($cdn, &$javascript, $path, $min, $names) {
494

    
495
  // Construct the jQuery UI path and replace the JavaScript.
496
  $jspath = $path . '/replace/ui/ui/' . ($min == '.min' ? 'minified/' : '');
497
  foreach ($names as $name => $file) {
498
    list($file_core, $file_updated) = is_array($file) ? $file : array($file, $file);
499
    $corefile = 'misc/ui/jquery.' . $file_core . '.min.js';
500
    // Remove the core files.
501
    unset($javascript[$name]['js'][$corefile]);
502
    $javascript[$name]['version'] = '1.10.2';
503
  }
504

    
505
  // UI is used by all of UI. Add the js cdn here.
506
  $javascript['ui']['js'][$cdn] = array(
507
    'data' => $cdn,
508
    'type' => 'external',
509
    'group' => JS_LIBRARY,
510
    'weight' => -11,
511
  );
512

    
513
  // The cdn puts jQuery UI core and the jQuery UI Effects library in the same
514
  // file, but the latter can normally be used without the former. So we need
515
  // to add a dependency to guarantee that code which uses the Effects library
516
  // has the file loaded regardless of whether they are also using jQuery UI
517
  // core.
518
  $javascript['effects']['dependencies'][] = array('system', 'ui');
519
}
520

    
521
/**
522
 * Handle when jQuery UI is updated to the local version.
523
 *
524
 * @param array $javascript
525
 *   The $libraries array as seen in hook_library_alter()
526
 * @param string $path
527
 *   The path to the module where replacements can be found.
528
 * @param string $min
529
 *   The '.min' to include in the file name if we are requesting a minified
530
 *   version.
531
 * @param array $names
532
 *   An array mapping jquery ui parts to their file names.
533
 */
534
function jquery_update_jqueryui_local(&$javascript, $path, $min, $names) {
535

    
536
  // Construct the jQuery UI path and replace the JavaScript.
537
  $jspath = $path . '/replace/ui/ui/' . ($min == '.min' ? 'minified/' : '');
538
  foreach ($names as $name => $file) {
539
    list($file_core, $file_updated) = is_array($file) ? $file : array($file, $file);
540
    $corefile = 'misc/ui/jquery.' . $file_core . '.min.js';
541
    $javascript[$name]['js'][$corefile]['data'] = $jspath . 'jquery.' . $file_updated . $min . '.js';
542
    $javascript[$name]['version'] = '1.10.2';
543
  }
544
}