Index: nodereference_explorer.module =================================================================== --- nodereference_explorer.module (revision 81) +++ nodereference_explorer.module (working copy) @@ -307,4 +307,70 @@ } } } +} + +/** + * Implementation of hook_theme_registry_alter(). + * + * Make Nodereference page preprocess function run *after* everything else's, + * so that a theme can't call drupal_get_js() and mess everything up. + * + * @source jquery_update_theme_registry_alter() + * @see nodereference_explorer_preprocess_page() + */ +function nodereference_explorer_theme_registry_alter(&$theme_registry) { + if (isset($theme_registry['page'])) { + // If jquery_update's preprocess function is there already, remove it. + if ($key = array_search('nodereference_explorer_preprocess_page', $theme_registry['page']['preprocess functions'])) { + unset($theme_registry['page']['preprocess functions'][$key]); + } + // Now tack it on at the end so it runs after everything else. + $theme_registry['page']['preprocess functions'][] = 'nodereference_explorer_preprocess_page'; + } +} + +/** + * Implementation of moduleName_preprocess_hook(). + * + * A theme preprocess function to allow content type plugins to use page + * template variables which are not yet available when the content type is + * rendered. + * + * We need to store which JS and CSS files were included in the page, because + * when JS and CSS optimalization is enabled, all these files are aggregrated into the + * single file and this information is lost. Duplicate loading is causing errors or + * unwanted behavior, ie. conflicts caused by duplicate javascript event handlers or + * reset of the color scheme. + * + * In this hook we capture all JS and CSS files which are going to be included in the page + * and we add them to the Drupal.settings.jsInit and Drupal.settings.cssInit arrays + */ +function nodereference_explorer_preprocess_page(&$vars) { + $sections = array('core', 'module', 'theme'); + // load all javascript + $javascript = drupal_add_js(); + $styles = drupal_add_css(); + $js = $css = array(); + // we dont have 'theme' styles at this phase, so we add main theme file "style.css" manually + // this will prevent override of color.module customized theme + $css[] = 'style.css'; + + // iterate through all sections and add all js and css files to our Drupal.settings storage + foreach ($sections as $section) { + $js += isset($javascript[$section]) ? array_keys($javascript[$section]) : array(); + $css += isset($styles['all'][$section]) ? array_keys($styles['all'][$section]) : array(); + } + + // process javascript files + $js = array_filter($js); + $js = array_fill_keys($js , TRUE); + $javascript['setting'][] = array('jsInit' => $js); + + // process css files + $css = array_map('basename', array_filter($css)); + $css = array_fill_keys($css , TRUE); + $javascript['setting'][] = array('cssInit' => $css); + + // save processed settings back to header variable + $vars['scripts'] = drupal_get_js('header', $javascript); } \ No newline at end of file Index: js/explorer.modalframe.js =================================================================== --- js/explorer.modalframe.js (revision 81) +++ js/explorer.modalframe.js (working copy) @@ -7,7 +7,7 @@ * to use the Modal Frames API module to open the popup views. */ -Drupal.nodereference_explorer.modalframe = {}; +Drupal.nodereference_explorer.modalframe = Drupal.nodereference_explorer.modalframe || {}; /** * Open a modalframe dialog @@ -37,4 +37,4 @@ Drupal.nodereference_explorer.actions.setValue(widget, type, args.selection); } }; -} +}; Index: js/explorer.tabs.js =================================================================== --- js/explorer.tabs.js (revision 81) +++ js/explorer.tabs.js (working copy) @@ -43,4 +43,4 @@ var display = $(ui.panel).attr('id'); $('#filter-'+display).show(); }); -} \ No newline at end of file +}; \ No newline at end of file Index: js/explorer.dialog.js =================================================================== --- js/explorer.dialog.js (revision 81) +++ js/explorer.dialog.js (working copy) @@ -7,7 +7,7 @@ * id collisions with the underlying form. */ -Drupal.nodereference_explorer.dialog = {}; +Drupal.nodereference_explorer.dialog = Drupal.nodereference_explorer.dialog || {}; /** * Open the dialog with the specified options @@ -45,7 +45,7 @@ ); $(dialog).dialog(options); -} +}; /** * Adds the action buttons to the dialog's button pane @@ -81,7 +81,7 @@ }; return buttons; -} +}; /** * Sets the dialog content to its correct size when using a button pane @@ -107,7 +107,7 @@ $buttonpane_height = buttonpane.height()/2; } $(dialog).height($container_height - titlebar.outerHeight() - $buttonpane_height); -} +}; /** * Masking of node form widgets Index: js/explorer.actions.js =================================================================== --- js/explorer.actions.js (revision 81) +++ js/explorer.actions.js (working copy) @@ -7,7 +7,7 @@ * already there from a former request, e. g. loading of node form. */ -Drupal.nodereference_explorer.actions = {}; +Drupal.nodereference_explorer.actions = Drupal.nodereference_explorer.actions || {}; /** * Attaches actions to the core widget, e. g. buttons @@ -21,7 +21,7 @@ //removes the value $('.nodereference-explorer-action-remove-value:not(.nodereference-explorer-processed)', context) .click(Drupal.nodereference_explorer.actions.remove).addClass('nodereference-explorer-processed'); -} +}; /** * Action for opening the dialog @@ -96,7 +96,7 @@ */ Drupal.nodereference_explorer.actions.setValue = function(widget, type, value) { eval('nodereference_explorer_plugin_cck_' +type+ '_setValue(widget, value);'); -} +}; /** * Clears the select item value. Like setValue() this is type specific @@ -107,7 +107,7 @@ */ Drupal.nodereference_explorer.actions.removeValue = function(widget, type) { eval('nodereference_explorer_plugin_cck_' +type+ '_removeValue(widget);'); -} +}; /** * Add a progress throbber, simulating progress @@ -118,7 +118,7 @@ $(element).after(' '); if ($('input', element)) //if the action element is an input disable it, preventing multiple clicking $(element).attr('disabled', 'disabled'); -} +}; /** * Stop progress when action done @@ -129,4 +129,4 @@ $(element).next().remove(); if ($('input', element)) //enable button again $(element).removeAttr("disabled"); -} \ No newline at end of file +}; Index: js/explorer.settings.js =================================================================== --- js/explorer.settings.js (revision 81) +++ js/explorer.settings.js (working copy) @@ -30,4 +30,4 @@ if ($('#edit-advanced-view:not(.nodereference-explorer-processed)', context)) $('#edit-advanced-view', context).change().addClass('nodereference-explorer-processed'); -} \ No newline at end of file +}; \ No newline at end of file Index: js/explorer.js =================================================================== --- js/explorer.js (revision 81) +++ js/explorer.js (working copy) @@ -8,21 +8,23 @@ * and css files inline, i. e. on a JSON request. */ //define name space -Drupal.nodereference_explorer = {}; +Drupal.nodereference_explorer = Drupal.nodereference_explorer || {}; //cache added javascript sources and stylesheets Drupal.nodereference_explorer.addedJS = []; Drupal.nodereference_explorer.addedCSS = []; /** - * Behavior of core widget - * @param - * DOM context + * Return filename without path + * + * @param file + * Filepath + * @return basename Filename without path */ -Drupal.behaviors.NodereferenceExplorer = function(context) { - //add css class to surrounding wrapper, needed for theming - $('.nodereference-explorer .form-autocomplete', context).parent().addClass('nodereference-explorer-wrapper'); -} +Drupal.nodereference_explorer.getBasename = function(file) { + var parts = file.split('/'); + return parts[parts.length - 1]; +}; /** * Get the nodereference_explorer settings. The component (subwidget) id @@ -36,18 +38,18 @@ Drupal.nodereference_explorer.getSettings = function(id) { var settings = Drupal.settings.nodereference_explorer; for (var field in settings) { //field settings - var field_settings = settings[field]; - for (var widget in field_settings['widgets']) { //widget settings - var widget_settings = field_settings['widgets']; - for (var subwidget in widget_settings[widget]) { //subwidgets - if (widget_settings[widget][subwidget] == id) { //check if match with subwidget - Drupal.settings.nodereference_explorer[field]['widget'] = widget; //add widget id to be found easily - return Drupal.settings.nodereference_explorer[field]; //return field - } - } - } + var field_settings = settings[field]; + for (var widget in field_settings['widgets']) { //widget settings + var widget_settings = field_settings['widgets']; + for (var subwidget in widget_settings[widget]) { //subwidgets + if (widget_settings[widget][subwidget] == id) { //check if match with subwidget + Drupal.settings.nodereference_explorer[field]['widget'] = widget; //add widget id to be found easily + return Drupal.settings.nodereference_explorer[field]; //return field + } + } + } } -} +}; /** * Add additional CSS to the page (see popups.js). @@ -57,7 +59,9 @@ for (var file in css[type]) { var link = css[type][file]; // Does the page already contain this stylesheet? - if (!$('link[href='+ $(link).attr('href') + ']').length) { + // Does the page already contain this stylesheet? + var basename = Drupal.nodereference_explorer.getBasename(file); + if (!Drupal.settings.cssInit[basename] && !$('link[href='+ $(link).attr('href') + ']').length) { $('head').append(link); Drupal.nodereference_explorer.addedCSS.push(link); // Keep a list, so we can remove them later. } @@ -80,7 +84,11 @@ inlines.push($(js[type][file]).text()); } else { - scripts.push($(js[type][file]).attr('src')); + var source = $(js[type][file]).attr('src'); + scripts.push(source); + if (Drupal.settings.jsInit[file]) { + Drupal.nodereference_explorer.addedJS[source] = true; + } } } } @@ -126,4 +134,14 @@ eval(inlines[n]); } } +}; + +/** + * Behavior of core widget + * @param + * DOM context + */ +Drupal.behaviors.NodereferenceExplorer = function(context) { + //add css class to surrounding wrapper, needed for theming + $('.nodereference-explorer .form-autocomplete', context).parent().addClass('nodereference-explorer-wrapper'); }; \ No newline at end of file Index: js/explorer.preview.js =================================================================== --- js/explorer.preview.js (revision 81) +++ js/explorer.preview.js (working copy) @@ -7,7 +7,7 @@ * CCK fields. */ -Drupal.nodereference_explorer.preview = {}; +Drupal.nodereference_explorer.preview = Drupal.nodereference_explorer.preview || {}; /** * Preview behavior. Each preview wrapper loads the preview if the core widget changes @@ -37,7 +37,7 @@ $(widget).blur(); }) .addClass('nodereference-explorer-processed'); -} +}; /** * Load the preview via JSON @@ -61,7 +61,7 @@ $(preview).text(''); } }); -} +}; /** * Fix for id collisions between node form and view filter form. @@ -71,4 +71,4 @@ Drupal.nodereference_explorer.preview.showTitle = function () { $('#edit-title-wrapper').show(); $('#edit-title').show(); -} \ No newline at end of file +}; \ No newline at end of file