advagg_mod.module

  1. cis7 sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module
  2. cle7 sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module
  3. ecd7 sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module
  4. elmsmedia7 sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module
  5. harmony7 sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module
  6. icor7 sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module
  7. meedjum_blog7 sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module
  8. mooc7 sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module

Advanced aggregation modifier module.

Functions

Namesort descending Description
advagg_mod_advagg_current_hooks_hash_array_alter Implements hook_advagg_current_hooks_hash_array_alter().
advagg_mod_advagg_get_root_files_dir_alter Implements hook_advagg_get_root_files_dir_alter().
advagg_mod_advagg_modify_js_pre_render_alter Implements hook_advagg_modify_js_pre_render_alter().
advagg_mod_css_alter Implements hook_css_alter().
advagg_mod_init Implements hook_init().
advagg_mod_inline_css Transforms all CSS files into inline CSS.
advagg_mod_inline_js Transforms all JS files into inline JS.
advagg_mod_inline_page Returns TRUE if this page should have inline CSS/JS.
advagg_mod_js_alter Implements hook_js_alter().
advagg_mod_js_contains_jquery_drupal See if JavaScript file contains drupal and/or jquery.
advagg_mod_magic Implements hook_magic().
advagg_mod_magic_form_validate Form validation handler. Disable certain magic settings before being saved.
advagg_mod_match_path Transforms all CSS files into inline CSS.
advagg_mod_menu Implements hook_menu().
advagg_mod_sort_css_js Rearrange CSS/JS so that aggregates are better grouped.
advagg_remove_js_if_not_used Remove JS if not in use on current page.

Constants

Namesort descending Description
ADVAGG_MOD_CSS_ADJUST_SORT_BROWSERS Default value to adjust the sorting of browser conditional CSS.
ADVAGG_MOD_CSS_ADJUST_SORT_EXTERNAL Default value to adjust the sorting of external CSS.
ADVAGG_MOD_CSS_ADJUST_SORT_INLINE Default value to adjust the sorting of inline CSS.
ADVAGG_MOD_CSS_PREPROCESS Default value to turn on preprocessing for all CSS files.
ADVAGG_MOD_CSS_TRANSLATE Default value to translate the content attributes of CSS files.
ADVAGG_MOD_JS_ADJUST_SORT_BROWSERS Default value to adjust the sorting of browser conditional JavaScript.
ADVAGG_MOD_JS_ADJUST_SORT_EXTERNAL Default value to adjust the sorting of external JavaScript.
ADVAGG_MOD_JS_ADJUST_SORT_INLINE Default value to adjust the sorting of inline JavaScript.
ADVAGG_MOD_JS_ASYNC_SHIM Default value to add use the async script shim for script tags.
ADVAGG_MOD_JS_DEFER Default value to add the defer tag to all script tags.
ADVAGG_MOD_JS_FOOTER Default value to move all JS to the footer.
ADVAGG_MOD_JS_PREPROCESS Default value to turn on preprocessing for all JavaScript files.
ADVAGG_MOD_JS_REMOVE_UNUSED Default value to remove JavaScript if none was added on the page.

File

sites/all/modules/ulmus/advagg/advagg_mod/advagg_mod.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * Advanced aggregation modifier module.
  5. */
  6. // Define default variables.
  7. /**
  8. * Default value to move all JS to the footer.
  9. */
  10. define('ADVAGG_MOD_JS_FOOTER', 0);
  11. /**
  12. * Default value to turn on preprocessing for all JavaScript files.
  13. */
  14. define('ADVAGG_MOD_JS_PREPROCESS', FALSE);
  15. /**
  16. * Default value to add the defer tag to all script tags.
  17. */
  18. define('ADVAGG_MOD_JS_DEFER', FALSE);
  19. /**
  20. * Default value to add use the async script shim for script tags.
  21. */
  22. define('ADVAGG_MOD_JS_ASYNC_SHIM', TRUE);
  23. /**
  24. * Default value to remove JavaScript if none was added on the page.
  25. */
  26. define('ADVAGG_MOD_JS_REMOVE_UNUSED', FALSE);
  27. /**
  28. * Default value to turn on preprocessing for all CSS files.
  29. */
  30. define('ADVAGG_MOD_CSS_PREPROCESS', FALSE);
  31. /**
  32. * Default value to translate the content attributes of CSS files.
  33. */
  34. define('ADVAGG_MOD_CSS_TRANSLATE', FALSE);
  35. /**
  36. * Default value to adjust the sorting of external JavaScript.
  37. */
  38. define('ADVAGG_MOD_JS_ADJUST_SORT_EXTERNAL', FALSE);
  39. /**
  40. * Default value to adjust the sorting of inline JavaScript.
  41. */
  42. define('ADVAGG_MOD_JS_ADJUST_SORT_INLINE', FALSE);
  43. /**
  44. * Default value to adjust the sorting of browser conditional JavaScript.
  45. */
  46. define('ADVAGG_MOD_JS_ADJUST_SORT_BROWSERS', FALSE);
  47. /**
  48. * Default value to adjust the sorting of external CSS.
  49. */
  50. define('ADVAGG_MOD_CSS_ADJUST_SORT_EXTERNAL', FALSE);
  51. /**
  52. * Default value to adjust the sorting of inline CSS.
  53. */
  54. define('ADVAGG_MOD_CSS_ADJUST_SORT_INLINE', FALSE);
  55. /**
  56. * Default value to adjust the sorting of browser conditional CSS.
  57. */
  58. define('ADVAGG_MOD_CSS_ADJUST_SORT_BROWSERS', FALSE);
  59. // Core hook implementations.
  60. /**
  61. * Implements hook_init().
  62. */
  63. function advagg_mod_init() {
  64. // Return if unified_multisite_dir is not set.
  65. $dir = rtrim(variable_get('advagg_mod_unified_multisite_dir', ''), '/');
  66. if (empty($dir) || !file_exists($dir) || !is_dir($dir)) {
  67. return;
  68. }
  69. $counter_filename = $dir . '/' . ADVAGG_SPACE . 'advagg_global_counter';
  70. $local_counter = advagg_get_global_counter();
  71. if (!file_exists($counter_filename)) {
  72. module_load_include('inc', 'advagg', 'advagg.missing');
  73. advagg_save_data($counter_filename, $local_counter);
  74. }
  75. else {
  76. $shared_counter = (int) file_get_contents($counter_filename);
  77. if ($shared_counter == $local_counter) {
  78. // Counters are the same, return.
  79. return;
  80. }
  81. elseif ($shared_counter < $local_counter) {
  82. // Local counter is higher, update saved file and return.
  83. module_load_include('inc', 'advagg', 'advagg.missing');
  84. advagg_save_data($counter_filename, $local_counter, TRUE);
  85. return;
  86. }
  87. elseif ($shared_counter > $local_counter) {
  88. // Shared counter is higher, update local copy and return.
  89. variable_set('advagg_global_counter', $shared_counter);
  90. return;
  91. }
  92. }
  93. }
  94. /**
  95. * Implements hook_menu().
  96. */
  97. function advagg_mod_menu() {
  98. $file_path = drupal_get_path('module', 'advagg_mod');
  99. $config_path = advagg_admin_config_root_path();
  100. $items[$config_path . '/advagg/mod'] = array(
  101. 'title' => 'Modifications',
  102. 'description' => 'Turn on or off various mods for CSS/JS.',
  103. 'page callback' => 'drupal_get_form',
  104. 'page arguments' => array('advagg_mod_admin_settings_form'),
  105. 'type' => MENU_LOCAL_TASK,
  106. 'access arguments' => array('administer site configuration'),
  107. 'file path' => $file_path,
  108. 'file' => 'advagg_mod.admin.inc',
  109. 'weight' => 10,
  110. );
  111. return $items;
  112. }
  113. /**
  114. * Implements hook_js_alter().
  115. */
  116. function advagg_mod_js_alter(&$js) {
  117. if (module_exists('advagg') && !advagg_enabled()) {
  118. return;
  119. }
  120. // Only add JS if it's actually needed.
  121. if (variable_get('advagg_mod_js_remove_unused', ADVAGG_MOD_JS_REMOVE_UNUSED)) {
  122. advagg_remove_js_if_not_used($js);
  123. }
  124. // @ignore sniffer_whitespace_openbracketspacing_openingwhitespace:5
  125. // Change sort order so aggregates do not get split up.
  126. if ( variable_get('advagg_mod_js_adjust_sort_external', ADVAGG_MOD_JS_ADJUST_SORT_EXTERNAL)
  127. || variable_get('advagg_mod_js_adjust_sort_inline', ADVAGG_MOD_JS_ADJUST_SORT_INLINE)
  128. || variable_get('advagg_mod_js_adjust_sort_browsers', ADVAGG_MOD_JS_ADJUST_SORT_BROWSERS)
  129. ) {
  130. advagg_mod_sort_css_js($js, 'js');
  131. }
  132. // Move all JS to the footer.
  133. $move_js_to_footer = variable_get('advagg_mod_js_footer', ADVAGG_MOD_JS_FOOTER);
  134. if (!empty($move_js_to_footer)) {
  135. foreach ($js as $name => &$values) {
  136. if ($move_js_to_footer == 1 && $values['group'] <= JS_LIBRARY) {
  137. continue;
  138. }
  139. // If JS is not in the header increase group by 10000.
  140. if ($values['scope'] != 'header') {
  141. $values['group'] += 10000;
  142. }
  143. // If JS is already in the footer increase group by 10000.
  144. if ($values['scope'] == 'footer') {
  145. $values['group'] += 10000;
  146. }
  147. $values['scope'] = 'footer';
  148. }
  149. }
  150. // Do not use preprocessing if JS is inlined.
  151. // Do not use defer if JS is inlined.
  152. if (advagg_mod_inline_page()) {
  153. advagg_mod_inline_js($js);
  154. return;
  155. }
  156. // Force all JS to be preprocessed.
  157. if (variable_get('advagg_mod_js_preprocess', ADVAGG_MOD_JS_PREPROCESS)) {
  158. foreach ($js as $name => &$values) {
  159. $values['preprocess'] = TRUE;
  160. }
  161. }
  162. // Add the defer tag to all JS.
  163. if (variable_get('advagg_mod_js_defer', ADVAGG_MOD_JS_DEFER)) {
  164. foreach ($js as $name => &$values) {
  165. // Everything is defer.
  166. $values['defer'] = TRUE;
  167. if (strpos($name, 'jquery.js') !== FALSE || strpos($name, 'jquery.min.js') !== FALSE) {
  168. // Do not defer the loading of jquery.js
  169. $values['defer'] = FALSE;
  170. // jquery_update fallback.
  171. if (module_exists('jquery_update')) {
  172. $values['onload'] = "if (typeof window.init_drupal_jquery_update_fallback === 'function') {init_drupal_jquery_update_fallback();}";
  173. }
  174. }
  175. if (strpos($name, 'jquery-ui.js') !== FALSE || strpos($name, 'jquery-ui.min.js') !== FALSE) {
  176. // Do not defer the loading of jquery-ui.js
  177. $values['defer'] = FALSE;
  178. // jquery_update fallback.
  179. if (module_exists('jquery_update')) {
  180. $values['onload'] = "if (typeof window.init_drupal_jquery_ui_update_fallback === 'function') {init_drupal_jquery_ui_update_fallback();}";
  181. }
  182. }
  183. // Drupal settings.
  184. if ($name == 'misc/drupal.js') {
  185. $values['onload'] = "if (typeof window.init_drupal_core_settings === 'function') {init_drupal_core_settings();}";
  186. }
  187. }
  188. }
  189. }
  190. /**
  191. * Rearrange CSS/JS so that aggregates are better grouped.
  192. *
  193. * This can move all external assets to the top, thus in one group.
  194. * This can move all inline assets to the bottom, thus in one group.
  195. * This can move all browser conditional assets together.
  196. *
  197. * @param array $array
  198. * The CSS or JS array.
  199. * @param string $type
  200. * css or js.
  201. */
  202. function advagg_mod_sort_css_js(&$array, $type) {
  203. // @ignore sniffer_whitespace_openbracketspacing_openingwhitespace:3
  204. if ( ($type == 'js' && variable_get('advagg_mod_js_adjust_sort_external', ADVAGG_MOD_JS_ADJUST_SORT_EXTERNAL))
  205. || ($type == 'css' && variable_get('advagg_mod_css_adjust_sort_external', ADVAGG_MOD_CSS_ADJUST_SORT_EXTERNAL))
  206. ) {
  207. // Find all external items.
  208. $external = array();
  209. $group = NULL;
  210. $every_page = NULL;
  211. $weight = NULL;
  212. foreach ($array as $key => $value) {
  213. // Set values if not set.
  214. if (is_null($group)) {
  215. $group = $value['group'];
  216. }
  217. if (is_null($every_page)) {
  218. $every_page = $value['every_page'];
  219. }
  220. if (is_null($weight)) {
  221. $weight = $value['weight'];
  222. }
  223. // Find "lightest" item.
  224. if ($value['group'] < $group) {
  225. $group = $value['group'];
  226. }
  227. if ($value['every_page'] && !$every_page) {
  228. $every_page = $value['every_page'];
  229. }
  230. if ($value['weight'] < $weight) {
  231. $weight = $value['weight'];
  232. }
  233. if (!empty($value['type']) && $value['type'] == 'external') {
  234. $external[$key] = $value;
  235. unset($array[$key]);
  236. }
  237. if (!empty($value['type']) && $value['type'] == 'inline') {
  238. // Move jQuery fallback as well.
  239. if (strpos($value['data'], 'window.jQuery') === 0) {
  240. $external[$key] = $value;
  241. unset($array[$key]);
  242. }
  243. // Move jQuery ui fallback as well.
  244. if (strpos($value['data'], 'window.jQuery.ui') === 0) {
  245. $external[$key] = $value;
  246. unset($array[$key]);
  247. }
  248. }
  249. }
  250. // Sort the array so that it appears in the correct order.
  251. if (is_callable('drupal_sort_css_js')) {
  252. uasort($external, 'drupal_sort_css_js');
  253. }
  254. else {
  255. advagg_drupal_sort_css_js_stable($external);
  256. }
  257. // Group all external together.
  258. $offset = 0.0001;
  259. $weight += -1;
  260. foreach ($external as $key => $value) {
  261. if (isset($value['moveable']) && empty($value['moveable'])) {
  262. $array[$key] = $value;
  263. continue;
  264. }
  265. $value['group'] = $group;
  266. $value['every_page'] = $every_page;
  267. $value['weight'] = $weight;
  268. $weight += $offset;
  269. $array[$key] = $value;
  270. }
  271. }
  272. // @ignore sniffer_whitespace_openbracketspacing_openingwhitespace:3
  273. if ( ($type == 'js' && variable_get('advagg_mod_js_adjust_sort_inline', ADVAGG_MOD_JS_ADJUST_SORT_INLINE))
  274. || ($type == 'css' && variable_get('advagg_mod_css_adjust_sort_inline', ADVAGG_MOD_CSS_ADJUST_SORT_INLINE))
  275. ) {
  276. // Find all inline items.
  277. $inline = array();
  278. $group = NULL;
  279. $every_page = NULL;
  280. $weight = NULL;
  281. foreach ($array as $key => $value) {
  282. // Set values if not set.
  283. if (is_null($group)) {
  284. $group = $value['group'];
  285. }
  286. if (is_null($every_page)) {
  287. $every_page = $value['every_page'];
  288. }
  289. if (is_null($weight)) {
  290. $weight = $value['weight'];
  291. }
  292. // Find "heaviest" item.
  293. if ($value['group'] > $group) {
  294. $group = $value['group'];
  295. }
  296. if (!$value['every_page'] && $every_page) {
  297. $every_page = $value['every_page'];
  298. }
  299. if ($value['weight'] > $weight) {
  300. $weight = $value['weight'];
  301. }
  302. if (!empty($value['type']) && $value['type'] == 'inline') {
  303. // Do not move jQuery fallback.
  304. if (strpos($value['data'], 'window.jQuery') === 0) {
  305. continue;
  306. }
  307. // Do not move jQuery.ui fallback.
  308. if (strpos($value['data'], 'window.jQuery.ui') === 0) {
  309. continue;
  310. }
  311. $inline[$key] = $value;
  312. unset($array[$key]);
  313. }
  314. }
  315. // Sort the array so that it appears in the correct order.
  316. if (is_callable('drupal_sort_css_js')) {
  317. uasort($inline, 'drupal_sort_css_js');
  318. }
  319. else {
  320. advagg_drupal_sort_css_js_stable($inline);
  321. }
  322. // Group all inline together.
  323. $offset = 0.0001;
  324. $weight += 1;
  325. foreach ($inline as $key => $value) {
  326. if (isset($value['moveable']) && empty($value['moveable'])) {
  327. $array[$key] = $value;
  328. continue;
  329. }
  330. $value['group'] = $group;
  331. $value['every_page'] = $every_page;
  332. $value['weight'] = $weight;
  333. $weight += $offset;
  334. $array[$key] = $value;
  335. }
  336. }
  337. // @ignore sniffer_whitespace_openbracketspacing_openingwhitespace:3
  338. if ( ($type == 'js' && variable_get('advagg_mod_js_adjust_sort_browsers', ADVAGG_MOD_JS_ADJUST_SORT_BROWSERS))
  339. || ($type == 'css' && variable_get('advagg_mod_css_adjust_sort_browsers', ADVAGG_MOD_CSS_ADJUST_SORT_BROWSERS))
  340. ) {
  341. // Get a list of browsers.
  342. $browsers_list = array();
  343. foreach ($array as $key => $value) {
  344. if (isset($value['browsers']['IE']) && $value['browsers']['IE'] !== TRUE) {
  345. $browsers_list['IE'][] = $value['browsers']['IE'];
  346. }
  347. }
  348. // Group browsers CSS together.
  349. if (isset($browsers_list['IE'])) {
  350. $browsers_list['IE'] = array_values(array_unique($browsers_list['IE']));
  351. foreach ($browsers_list['IE'] as $browser) {
  352. $browsers = array();
  353. $group = NULL;
  354. $every_page = NULL;
  355. $weight = NULL;
  356. foreach ($array as $key => $value) {
  357. if (isset($value['browsers']['IE']) && $browser === $value['browsers']['IE']) {
  358. // Set values if not set.
  359. if (is_null($group)) {
  360. $group = $value['group'];
  361. }
  362. if (is_null($every_page)) {
  363. $every_page = $value['every_page'];
  364. }
  365. if (is_null($weight)) {
  366. $weight = $value['weight'];
  367. }
  368. // Find "heaviest" item.
  369. if ($value['group'] > $group) {
  370. $group = $value['group'];
  371. }
  372. if (!$value['every_page'] && $every_page) {
  373. $every_page = $value['every_page'];
  374. }
  375. if ($value['weight'] > $weight) {
  376. $weight = $value['weight'];
  377. }
  378. $browsers[$key] = $value;
  379. unset($array[$key]);
  380. }
  381. }
  382. // Sort the array so that it appears in the correct order.
  383. if (is_callable('drupal_sort_css_js')) {
  384. uasort($browsers, 'drupal_sort_css_js');
  385. }
  386. else {
  387. advagg_drupal_sort_css_js_stable($browsers);
  388. }
  389. // Group all browsers together.
  390. $offset = 0.0001;
  391. foreach ($browsers as $key => $value) {
  392. if (isset($value['moveable']) && empty($value['moveable'])) {
  393. $array[$key] = $value;
  394. continue;
  395. }
  396. $value['group'] = $group;
  397. $value['every_page'] = $every_page;
  398. $value['weight'] = $weight;
  399. $weight += $offset;
  400. $array[$key] = $value;
  401. }
  402. }
  403. }
  404. }
  405. }
  406. /**
  407. * Implements hook_css_alter().
  408. */
  409. function advagg_mod_css_alter(&$css) {
  410. if (module_exists('advagg') && !advagg_enabled()) {
  411. return;
  412. }
  413. // @ignore sniffer_whitespace_openbracketspacing_openingwhitespace:5
  414. // Change sort order so aggregates do not get split up.
  415. if ( variable_get('advagg_mod_css_adjust_sort_external', ADVAGG_MOD_CSS_ADJUST_SORT_EXTERNAL)
  416. || variable_get('advagg_mod_css_adjust_sort_inline', ADVAGG_MOD_CSS_ADJUST_SORT_INLINE)
  417. || variable_get('advagg_mod_css_adjust_sort_browsers', ADVAGG_MOD_CSS_ADJUST_SORT_BROWSERS)
  418. ) {
  419. advagg_mod_sort_css_js($css, 'css');
  420. }
  421. // Do not use preprocessing if CSS is inlined.
  422. if (advagg_mod_inline_page()) {
  423. advagg_mod_inline_css($css);
  424. return;
  425. }
  426. // Force all CSS to be preprocessed.
  427. if (variable_get('advagg_mod_css_preprocess', ADVAGG_MOD_CSS_PREPROCESS)) {
  428. foreach ($css as $name => &$values) {
  429. $values['preprocess'] = TRUE;
  430. }
  431. }
  432. }
  433. // AdvAgg hook implementations.
  434. /**
  435. * Implements hook_advagg_modify_js_pre_render_alter().
  436. */
  437. function advagg_mod_advagg_modify_js_pre_render_alter(&$children, &$elements) {
  438. if (module_exists('advagg') && !advagg_enabled()) {
  439. return;
  440. }
  441. // Do not use defer/async shim if JS is inlined.
  442. if (advagg_mod_inline_page()) {
  443. return;
  444. }
  445. if (variable_get('advagg_mod_js_defer', ADVAGG_MOD_JS_DEFER)) {
  446. foreach ($children as &$values) {
  447. $values['#attributes']['defer'] = TRUE;
  448. if (empty($values['#value'])) {
  449. continue;
  450. }
  451. // Workaround bug with onload and jquery update.
  452. if (!empty($values['#attributes']['onload'])) {
  453. unset($values['#attributes']['onload']);
  454. }
  455. // Core.
  456. if (strpos($values['#value'], 'jQuery.extend(Drupal.settings') !== FALSE) {
  457. $values['#value'] = 'function init_drupal_core_settings() {' . $values['#value'] . '}';
  458. }
  459. // JQuery Update.
  460. if (strpos($values['#value'], 'window.jQuery') !== FALSE) {
  461. $values['#value'] = 'function init_drupal_jquery_update_fallback() {' . $values['#value'] . '}';
  462. }
  463. if (strpos($values['#value'], 'window.jQuery.ui') !== FALSE) {
  464. $values['#value'] = 'function init_drupal_jquery_ui_update_fallback() {' . $values['#value'] . '}';
  465. }
  466. }
  467. }
  468. if (variable_get('advagg_mod_js_async_shim', ADVAGG_MOD_JS_ASYNC_SHIM)) {
  469. foreach ($children as &$values) {
  470. if (isset($values['#attributes']) && isset($values['#attributes']['async']) && $values['#attributes']['async'] == 'async') {
  471. $source = url($values['#attributes']['src']);
  472. $values['#value'] = "(function() {
  473. var s = document.createElement('script');
  474. s.type = 'text/javascript';
  475. s.async = true;
  476. s.src = '$source';
  477. var d = document.getElementsByTagName('script')[0];
  478. d.parentNode.insertBefore(s, d);
  479. })();";
  480. unset($values['#attributes']['async']);
  481. unset($values['#attributes']['src']);
  482. }
  483. }
  484. }
  485. }
  486. /**
  487. * Implements hook_advagg_get_root_files_dir_alter().
  488. */
  489. function advagg_mod_advagg_get_root_files_dir_alter(&$css_paths, &$js_paths) {
  490. $dir = rtrim(variable_get('advagg_mod_unified_multisite_dir', ''), '/');
  491. if (empty($dir) || !file_exists($dir) || !is_dir($dir)) {
  492. return;
  493. }
  494. // Change directory.
  495. $css_paths[0] = $dir . '/advagg_css';
  496. $js_paths[0] = $dir . '/advagg_js';
  497. file_prepare_directory($css_paths[0], FILE_CREATE_DIRECTORY);
  498. file_prepare_directory($js_paths[0], FILE_CREATE_DIRECTORY);
  499. // Set the URI of the directory.
  500. $css_paths[1] = parse_url(file_create_url($css_paths[0]), PHP_URL_PATH);
  501. if (substr($css_paths[1], 0, strlen($GLOBALS['base_path'])) == $GLOBALS['base_path']) {
  502. $css_paths[1] = substr($css_paths[1], strlen($GLOBALS['base_path']));
  503. }
  504. $js_paths[1] = parse_url(file_create_url($js_paths[0]), PHP_URL_PATH);
  505. if (substr($js_paths[1], 0, strlen($GLOBALS['base_path'])) == $GLOBALS['base_path']) {
  506. $js_paths[1] = substr($js_paths[1], strlen($GLOBALS['base_path']));
  507. }
  508. }
  509. /**
  510. * Implements hook_advagg_current_hooks_hash_array_alter().
  511. */
  512. function advagg_mod_advagg_current_hooks_hash_array_alter(&$aggregate_settings) {
  513. $aggregate_settings['variables']['advagg_mod_css_translate'] = variable_get('advagg_mod_css_translate', ADVAGG_MOD_CSS_TRANSLATE);
  514. if (variable_get('advagg_mod_css_translate', ADVAGG_MOD_CSS_TRANSLATE)) {
  515. $aggregate_settings['variables']['advagg_mod_css_translate_lang'] = isset($GLOBALS['language']->language) ? $GLOBALS['language']->language : 'en';
  516. }
  517. }
  518. // Helper Functions.
  519. /**
  520. * Returns TRUE if this page should have inline CSS/JS.
  521. *
  522. * @return bool
  523. * TRUE or FALSE.
  524. */
  525. function advagg_mod_inline_page() {
  526. $visibility = variable_get('advagg_mod_inline_visibility', BLOCK_VISIBILITY_LISTED);
  527. $pages = variable_get('advagg_mod_inline_pages', '');
  528. return advagg_mod_match_path($pages, $visibility);
  529. }
  530. /**
  531. * Transforms all JS files into inline JS.
  532. *
  533. * @param array $js
  534. * JS array.
  535. */
  536. function advagg_mod_inline_js(&$js) {
  537. $aggregate_settings = advagg_current_hooks_hash_array();
  538. foreach ($js as $name => &$values) {
  539. // Only process files.
  540. if ($values['type'] != 'file') {
  541. continue;
  542. }
  543. $filename = $values['data'];
  544. if (file_exists($filename)) {
  545. $contents = file_get_contents($filename);
  546. }
  547. // Allow other modules to modify this files contents.
  548. // Call hook_advagg_get_js_file_contents_alter().
  549. drupal_alter('advagg_get_js_file_contents', $contents, $filename, $aggregate_settings);
  550. $values['data'] = $contents;
  551. $values['type'] = 'inline';
  552. }
  553. }
  554. /**
  555. * Transforms all CSS files into inline CSS.
  556. *
  557. * @param array $css
  558. * CSS array.
  559. *
  560. * @see advagg_get_css_aggregate_contents()
  561. * @see drupal_build_css_cache()
  562. */
  563. function advagg_mod_inline_css(&$css) {
  564. $aggregate_settings = advagg_current_hooks_hash_array();
  565. $optimize = TRUE;
  566. module_load_include('inc', 'advagg', 'advagg');
  567. foreach ($css as $name => &$values) {
  568. // Only process files.
  569. if ($values['type'] != 'file') {
  570. continue;
  571. }
  572. $file = $values['data'];
  573. if (file_exists($file)) {
  574. $contents = advagg_load_css_stylesheet($file, $optimize, $aggregate_settings);
  575. // Allow other modules to modify this files contents.
  576. // Call hook_advagg_get_css_file_contents_alter().
  577. drupal_alter('advagg_get_css_file_contents', $contents, $file, $aggregate_settings);
  578. // Per the W3C specification at
  579. // http://www.w3.org/TR/REC-CSS2/cascade.html#at-import, @import rules
  580. // must proceed any other style, so we move those to the top.
  581. $regexp = '/@import[^;]+;/i';
  582. preg_match_all($regexp, $contents, $matches);
  583. $contents = preg_replace($regexp, '', $contents);
  584. $contents = implode('', $matches[0]) . $contents;
  585. $values['data'] = $contents;
  586. $values['type'] = 'inline';
  587. }
  588. }
  589. }
  590. /**
  591. * Transforms all CSS files into inline CSS.
  592. *
  593. * @param string $pages
  594. * string from the advagg_mod_inline_pages variable.
  595. * @param int $visibility
  596. * visibility setting from the advagg_mod_inline_visibility variable.
  597. *
  598. * @return bool
  599. * TRUE if the current path matches the given pages.
  600. *
  601. * @see block_block_list_alter()
  602. */
  603. function advagg_mod_match_path($pages, $visibility) {
  604. // Limited visibility blocks must list at least one page.
  605. if ($visibility == BLOCK_VISIBILITY_LISTED && empty($pages)) {
  606. $page_match = FALSE;
  607. }
  608. elseif ($pages) {
  609. // Match path if necessary.
  610. // Convert path to lowercase. This allows comparison of the same path
  611. // with different case. Ex: /Page, /page, /PAGE.
  612. $pages = drupal_strtolower($pages);
  613. if ($visibility < BLOCK_VISIBILITY_PHP) {
  614. // Convert the Drupal path to lowercase.
  615. $path = drupal_strtolower(drupal_get_path_alias($_GET['q']));
  616. // Compare the lowercase internal and lowercase path alias (if any).
  617. $page_match = drupal_match_path($path, $pages);
  618. if ($path != $_GET['q']) {
  619. $page_match = $page_match || drupal_match_path($_GET['q'], $pages);
  620. }
  621. // When $visibility has a value of 0 (BLOCK_VISIBILITY_NOTLISTED),
  622. // the block is displayed on all pages except those listed in $pages.
  623. // When set to 1 (BLOCK_VISIBILITY_LISTED), it is displayed only on those
  624. // pages listed in $block->pages.
  625. $page_match = !($visibility xor $page_match);
  626. }
  627. elseif (module_exists('php')) {
  628. $page_match = php_eval($pages);
  629. }
  630. else {
  631. $page_match = FALSE;
  632. }
  633. }
  634. else {
  635. $page_match = TRUE;
  636. }
  637. return $page_match;
  638. }
  639. /**
  640. * See if JavaScript file contains drupal and/or jquery.
  641. *
  642. * @param string $filename
  643. * filename or full URL.
  644. * @param string $type
  645. * file or external
  646. *
  647. * @return array
  648. * Returns an array stating if this JS file contains drupal or jquery.
  649. *
  650. * @see block_block_list_alter()
  651. */
  652. function advagg_mod_js_contains_jquery_drupal($filename, $type) {
  653. module_load_include('inc', 'advagg', 'advagg');
  654. $info = advagg_get_info_on_file($filename);
  655. if (empty($info['advagg_mod']['contents'])) {
  656. if ($type == 'file') {
  657. $contents = file_get_contents($filename);
  658. }
  659. if ($type == 'external') {
  660. $result = drupal_http_request($filename);
  661. if (($result->code == 200 || (isset($result->redirect_code) && $result->redirect_code == 200)) && !empty($result->data)) {
  662. $contents = $result->data;
  663. }
  664. }
  665. if (!empty($contents) && stripos($contents, 'drupal.') !== FALSE) {
  666. $info['advagg_mod']['contents']['drupal'] = TRUE;
  667. if (stripos($contents, 'drupal.settings.') !== FALSE) {
  668. $info['advagg_mod']['contents']['drupal.settings'] = TRUE;
  669. }
  670. else {
  671. $info['advagg_mod']['contents']['drupal.settings'] = FALSE;
  672. }
  673. if (stripos($contents, 'drupal.behaviors.') !== FALSE) {
  674. $info['advagg_mod']['contents']['drupal.behaviors'] = TRUE;
  675. }
  676. else {
  677. $info['advagg_mod']['contents']['drupal.behaviors'] = FALSE;
  678. }
  679. }
  680. else {
  681. $info['advagg_mod']['contents']['drupal'] = FALSE;
  682. $info['advagg_mod']['contents']['drupal.settings'] = FALSE;
  683. $info['advagg_mod']['contents']['drupal.behaviors'] = FALSE;
  684. }
  685. if (!empty($contents) && stripos($contents, 'jquery') !== FALSE) {
  686. $info['advagg_mod']['contents']['jquery'] = TRUE;
  687. }
  688. else {
  689. $info['advagg_mod']['contents']['jquery'] = FALSE;
  690. }
  691. // Cache info.
  692. $filename_hashes = &drupal_static('advagg_get_info_on_file');
  693. $cache_id = 'advagg:file:' . $info['filename_hash'];
  694. // Save results.
  695. $filename_hashes[$cache_id] = $info;
  696. cache_set($cache_id, $info, 'cache_advagg_info', CACHE_PERMANENT);
  697. }
  698. return array($info['advagg_mod']['contents']['drupal'], $info['advagg_mod']['contents']['jquery']);
  699. }
  700. /**
  701. * Remove JS if not in use on current page.
  702. *
  703. * @param array $js
  704. * JS array.
  705. */
  706. function advagg_remove_js_if_not_used(&$js) {
  707. // Do not run the following code if drupal_add_js_page_defaults exists.
  708. if (function_exists('drupal_add_js_page_defaults')) {
  709. return;
  710. }
  711. $files_skiplist = array(
  712. 'drupal.js',
  713. 'jquery.js',
  714. 'jquery.min.js',
  715. 'jquery.once.js',
  716. );
  717. $inline_skiplist = array(
  718. '/jquery_update/replace/jquery/1.5/jquery.min.js',
  719. 'var $L = $LAB.setGlobalDefaults',
  720. );
  721. $include_jquery = FALSE;
  722. $include_drupal = FALSE;
  723. // Look at each JavaScript entry.
  724. foreach ($js as $name => &$values) {
  725. if ($values['type'] == 'file' || $values['type'] == 'external') {
  726. $skip = FALSE;
  727. foreach ($files_skiplist as $skip_name) {
  728. if (substr_compare($name, $skip_name, -strlen($skip_name), strlen($skip_name)) === 0) {
  729. $skip = TRUE;
  730. break;
  731. }
  732. }
  733. if (!$skip) {
  734. list($drupal, $jquery) = advagg_mod_js_contains_jquery_drupal($name, $values['type']);
  735. if ($drupal) {
  736. $include_jquery = TRUE;
  737. $include_drupal = TRUE;
  738. }
  739. elseif ($jquery) {
  740. $include_jquery = TRUE;
  741. }
  742. }
  743. }
  744. if ($values['type'] == 'inline') {
  745. $skip = FALSE;
  746. foreach ($inline_skiplist as $skip_string) {
  747. if (stripos($values['data'], $skip_string) !== FALSE) {
  748. $skip = TRUE;
  749. break;
  750. }
  751. }
  752. if (!$skip) {
  753. $include_jquery = TRUE;
  754. $include_drupal = TRUE;
  755. }
  756. }
  757. }
  758. // Kill only drupal JavaScript.
  759. if (!$include_drupal) {
  760. unset($js['settings']);
  761. foreach ($js as $name => &$values) {
  762. $drupal = 'drupal.js';
  763. if (substr_compare($name, $drupal, -strlen($drupal), strlen($drupal)) === 0) {
  764. unset($js[$name]);
  765. }
  766. }
  767. // Kill all default JavaScript.
  768. if (!$include_jquery) {
  769. foreach ($js as $name => &$values) {
  770. if ($values['type'] == 'file' || $values['type'] == 'external') {
  771. foreach ($files_skiplist as $skip_name) {
  772. if (substr_compare($name, $skip_name, -strlen($skip_name), strlen($skip_name)) === 0) {
  773. unset($js[$name]);
  774. }
  775. }
  776. }
  777. elseif ($values['type'] == 'inline') {
  778. foreach ($inline_skiplist as $skip_string) {
  779. if (stripos($values['data'], $skip_string) !== FALSE) {
  780. unset($js[$name]);
  781. }
  782. }
  783. }
  784. }
  785. }
  786. }
  787. }
  788. // @ignore sniffer_commenting_functioncomment_hookreturndoc:12
  789. // @ignore sniffer_commenting_functioncomment_hookparamdoc:8
  790. /**
  791. * Implements hook_magic().
  792. *
  793. * @param array $magic_settings
  794. * The renderable form array of the magic module theme settings. READ ONLY
  795. * @param string $theme
  796. * The theme that the settings will be editing.
  797. *
  798. * @return array
  799. * The array of settings within the magic module theme page. Must not contain
  800. * anything from the $magic_settings array.
  801. */
  802. function advagg_mod_magic($magic_settings, $theme) {
  803. $settings = array();
  804. // If possible disable access and set default to false.
  805. if (!isset($magic_settings['css']['magic_embedded_mqs']['#access'])) {
  806. $settings['css']['magic_embedded_mqs']['#access'] = FALSE;
  807. }
  808. if (!isset($magic_settings['css']['magic_embedded_mqs']['#default_value'])) {
  809. $settings['css']['magic_embedded_mqs']['#default_value'] = FALSE;
  810. }
  811. if (!isset($magic_settings['js']['magic_footer_js']['#access'])) {
  812. $settings['js']['magic_footer_js']['#access'] = FALSE;
  813. }
  814. if (!isset($magic_settings['js']['magic_footer_js']['#default_value'])) {
  815. $settings['js']['magic_footer_js']['#default_value'] = FALSE;
  816. }
  817. if (!isset($magic_settings['js']['magic_library_head']['#access'])) {
  818. $settings['js']['magic_library_head']['#access'] = FALSE;
  819. }
  820. if (!isset($magic_settings['js']['magic_library_head']['#default_value'])) {
  821. $settings['js']['magic_library_head']['#default_value'] = FALSE;
  822. }
  823. if (!isset($magic_settings['js']['magic_experimental_js']['#access'])) {
  824. $settings['js']['magic_experimental_js']['#access'] = FALSE;
  825. }
  826. if (!isset($magic_settings['js']['magic_experimental_js']['#default_value'])) {
  827. $settings['js']['magic_experimental_js']['#default_value'] = FALSE;
  828. }
  829. // Add in our own validate function so we can preprocess variables before
  830. // they are saved.
  831. $settings['#validate'] = array('advagg_mod_magic_form_validate');
  832. return $settings;
  833. }
  834. /**
  835. * Form validation handler. Disable certain magic settings before being saved.
  836. */
  837. function advagg_mod_magic_form_validate($form, &$form_state) {
  838. // Disable magic functionality if it is a duplicate of AdvAgg.
  839. $form_state['values']['magic_embedded_mqs'] = 0;
  840. $form_state['values']['magic_footer_js'] = 0;
  841. $form_state['values']['magic_library_head'] = 0;
  842. $form_state['values']['magic_experimental_js'] = 0;
  843. }