diff --git a/browsersync.info b/browsersync.info deleted file mode 100755 index 5581b74..0000000 --- a/browsersync.info +++ /dev/null @@ -1,5 +0,0 @@ -name = Browsersync -description = Integrates the Browsersync (Node.js module) with Drupal. -package = Nodejs -core = 7.x -files[] = browsersync.test diff --git a/browsersync.info.yml b/browsersync.info.yml new file mode 100755 index 0000000..4ec7a8e --- /dev/null +++ b/browsersync.info.yml @@ -0,0 +1,5 @@ +name: Browsersync +type: module +description: Integrates Browsersync (Node.js module) with Drupal. +package: Nodejs +core: 8.x diff --git a/browsersync.module b/browsersync.module index fc6e3f6..ab496bc 100755 --- a/browsersync.module +++ b/browsersync.module @@ -5,6 +5,8 @@ * Code for the Browsersync module. */ +use Drupal\Core\Form\FormStateInterface; + /** * Browsersync default host. * @@ -20,31 +22,17 @@ define('BROWSERSYNC_DEFAULT_HOST', 'HOST'); define('BROWSERSYNC_DEFAULT_PORT', '3000'); /** - * Implements hook_permission(). - */ -function browsersync_permission() { - return array( - 'use browsersync' => array( - 'title' => t('Use Browsersync'), - ), - ); -} - -/** * Implements hook_theme(). */ function browsersync_theme($existing, $type, $theme, $path) { - return array( - 'browsersync_snippet' => array( - 'variables' => array( - 'host' => '', - 'port' => '', - ), - 'file' => 'browsersync.theme.inc', - 'path' => $path . '/theme', - 'template' => 'browsersync-snippet', - ), - ); + return [ + 'browsersync_snippet' => [ + 'variables' => [ + 'host' => BROWSERSYNC_DEFAULT_HOST, + 'port' => BROWSERSYNC_DEFAULT_PORT, + ], + ], + ]; } /** @@ -56,11 +44,12 @@ function browsersync_theme($existing, $type, $theme, $path) { * @link https://github.com/shakyShane/browser-sync/issues/10 */ function browsersync_css_alter(&$css) { - if (browsersync_get_setting('enabled', FALSE) && !variable_get('preprocess_css')) { + $system_css_preprocess = \Drupal::config('system.performance')->get('css.preprocess'); + + if (browsersync_get_setting('enabled') && !$system_css_preprocess) { foreach ($css as $key => $value) { // Skip core files. - $is_core = (strpos($value['data'], 'misc/') === 0 || strpos($value['data'], 'modules/') === 0); - if (!$is_core && file_exists($value['data'])) { + if (strpos($value['data'], 'core/') !== 0) { $css[$key]['preprocess'] = FALSE; } } @@ -68,68 +57,98 @@ function browsersync_css_alter(&$css) { } /** - * Implements hook_form_system_theme_settings_alter(). + * Implements hook_form_FORM_ID_alter(). * * Adds the Browsersync configuration options to the theme settings form. * - * @see system_theme_settings() + * @see \Drupal\system\Form\ThemeSettingsForm */ -function browsersync_form_system_theme_settings_alter(&$form, &$form_state, $form_id) { +function browsersync_form_system_theme_settings_alter(&$form, FormStateInterface $form_state) { // Extract the theme key from the form arguments. If not present, it means // that we are altering the global theme settings form. - $args = $form_state['build_info']['args']; + $args = $form_state->getBuildInfo()['args']; $theme_key = !empty($args[0]) ? $args[0] : NULL; - $form['browsersync'] = array( - '#type' => 'fieldset', + $form['browsersync'] = [ + '#type' => 'details', '#title' => 'Browsersync settings', '#collapsible' => TRUE, '#collapsed' => TRUE, - ); + ]; - $form['browsersync']['browsersync_enabled'] = array( + $form['browsersync']['browsersync_enabled'] = [ '#title' => 'Enable Browsersync', '#type' => 'checkbox', - '#default_value' => browsersync_get_setting('enabled', FALSE, $theme_key), - ); + '#default_value' => browsersync_get_setting('enabled', $theme_key), + ]; - $form['browsersync']['settings'] = array( + $form['browsersync']['settings'] = [ '#type' => 'container', - '#states' => array( - 'visible' => array( - 'input[name="browsersync_enabled"]' => array('checked' => TRUE), - ), - ), - ); - - $form['browsersync']['settings']['browsersync_host'] = array( + '#states' => [ + 'visible' => [ + 'input[name="browsersync_enabled"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['browsersync']['settings']['browsersync_host'] = [ '#title' => 'Host', '#type' => 'textfield', '#description' => t('Override host detection if you know the correct IP to use.'), - '#default_value' => browsersync_get_setting('host', '', $theme_key), - ); + '#default_value' => browsersync_get_setting('host', $theme_key), + ]; - $form['browsersync']['settings']['browsersync_port'] = array( + $form['browsersync']['settings']['browsersync_port'] = [ '#title' => 'Port', '#type' => 'textfield', '#description' => t('Use a specific port (instead of the one auto-detected by Browsersync).'), - '#default_value' => browsersync_get_setting('port', '', $theme_key), - ); + '#default_value' => browsersync_get_setting('port', $theme_key), + ]; + + $form['#submit'][] = 'browsersync_theme_settings_form_submit'; +} + +/** + * Form submission handler for theme settings form. + * + * @see browsersync_form_system_theme_settings_alter() + */ +function browsersync_theme_settings_form_submit($form, FormStateInterface $form_state) { + $args = $form_state->getBuildInfo()['args']; + $theme_key = !empty($args[0]) ? $args[0] : NULL; + + if ($theme_key) { + $config_key = $theme_key . '.settings'; + } + else { + $config_key = 'system.theme.global'; + } + + $user_input = $form_state->getUserInput(); + + \Drupal::configFactory()->getEditable($config_key) + ->set('third_party_settings.browsersync.enabled', $user_input['browsersync_enabled']) + ->set('third_party_settings.browsersync.host', $user_input['browsersync_host']) + ->set('third_party_settings.browsersync.port', $user_input['browsersync_port']) + ->save(); } /** - * Implements hook_page_build(). + * Implements hook_page_bottom(). * * Adds the Browsersync snippet to the bottom of the page. */ -function browsersync_page_build(&$page) { - if (browsersync_get_setting('enabled', FALSE) && user_access('use browsersync')) { - $page['page_bottom']['browsersync'] = array( +function browsersync_page_bottom(array &$page_bottom) { + if (browsersync_get_setting('enabled') && \Drupal::currentUser()->hasPermission('use browsersync')) { + $page_bottom['browsersync'] = [ '#theme' => 'browsersync_snippet', - '#host' => browsersync_get_setting('host', ''), - '#port' => browsersync_get_setting('port', ''), '#weight' => 100, - ); + ]; + foreach (['host', 'port'] as $setting) { + if ($value = browsersync_get_setting($setting)) { + $page_bottom['browsersync']['#' . $setting] = $value; + } + } } } @@ -138,27 +157,24 @@ function browsersync_page_build(&$page) { * * @param string $setting_name * The name of the setting to be retrieved. - * @param mixed $default - * (optional) A default value. Defaults to NULL. * @param string $theme * (optional) The name of a given theme. Defaults to the current theme. * * @return mixed - * The value of the requested setting, or the $default value if the setting - * does not exist. + * The value of the requested setting. * * @see theme_get_setting() */ -function browsersync_get_setting($setting_name, $default = NULL, $theme = NULL) { - $cache = &drupal_static('theme_get_setting', array()); +function browsersync_get_setting($setting_name, $theme = NULL) { + $cache = &drupal_static('theme_get_setting', []); // If no key is given, use the current theme if we can determine it. if (!isset($theme)) { - $theme = !empty($GLOBALS['theme_key']) ? $GLOBALS['theme_key'] : ''; + $theme = \Drupal::theme()->getActiveTheme()->getName(); } // Prefix the setting name with the module's namespace. - $setting_name = 'browsersync_' . $setting_name; + $setting_name = 'third_party_settings.browsersync.' . $setting_name; if (empty($cache[$theme])) { // If the cache has not been filled yet, invoke theme_get_setting to @@ -166,13 +182,9 @@ function browsersync_get_setting($setting_name, $default = NULL, $theme = NULL) // for subsequent requests. $setting = theme_get_setting($setting_name, $theme); } - elseif (isset($cache[$theme][$setting_name])) { - // Retrieve the value from the cache. - $setting = $cache[$theme][$setting_name]; - } else { - // Use the default value, setting does not exist. - $setting = $default; + // Retrieve the value from the cache. + $setting = $cache[$theme]->get($setting_name); } return $setting; diff --git a/browsersync.permissions.yml b/browsersync.permissions.yml new file mode 100644 index 0000000..70e7125 --- /dev/null +++ b/browsersync.permissions.yml @@ -0,0 +1,2 @@ +use browsersync: + title: 'Use Browsersync' diff --git a/browsersync.test b/browsersync.test deleted file mode 100644 index c2b0763..0000000 --- a/browsersync.test +++ /dev/null @@ -1,46 +0,0 @@ - 'Browsersync', - 'description' => 'Tests for the Browsersync module.', - 'group' => 'Browsersync', - ); - } - - /** - * {@inheritdoc} - */ - public function setUp() { - parent::setUp(array('browsersync')); - - // Create a dev user who can use Browsersync. - $this->dev_user = $this->drupalCreateUser(array('use browsersync')); - $this->drupalLogin($this->dev_user); - - // Enable Browsersync globally. - $theme_settings = variable_get('theme_settings', array()); - $theme_settings['browsersync_enabled'] = TRUE; - variable_set('theme_settings', $theme_settings); - } - - /** - * Checks for the presence of the snippet in the markup. - */ - public function testSnippet() { - $this->drupalGet(''); - $elements = $this->xpath('//script[@id=:id]', array(':id' => '__bs_script__')); - $this->assertTrue(!empty($elements), 'Page contains the Browsersync snippet.'); - } - -} diff --git a/config/schema/browsersync.schema.yml b/config/schema/browsersync.schema.yml new file mode 100644 index 0000000..97cddcd --- /dev/null +++ b/config/schema/browsersync.schema.yml @@ -0,0 +1,15 @@ +# Schema for the configuration files of the Browsersync module. + +theme_settings.third_party.browsersync: + type: mapping + label: 'Browsersync settings' + mapping: + enabled: + type: boolean + label: 'Browsersync enabled' + host: + type: string + label: 'Browsersync host' + port: + type: string + label: 'Browsersync port' diff --git a/src/Tests/BrowsersyncTest.php b/src/Tests/BrowsersyncTest.php new file mode 100644 index 0000000..4486ae9 --- /dev/null +++ b/src/Tests/BrowsersyncTest.php @@ -0,0 +1,57 @@ +drupalCreateUser(['use browsersync']); + $this->drupalLogin($dev_user); + + // Enable Browsersync globally. + \Drupal::configFactory()->getEditable('system.theme.global') + ->set('third_party_settings.browsersync.enabled', TRUE) + ->save(); + } + + /** + * Checks for the Browsersync snippet in the markup. + */ + public function testSnippet() { + $this->drupalGet(''); + $elements = $this->xpath('//script[@id=:id]', [':id' => '__bs_script__']); + $this->assertTrue(!empty($elements), 'Page contains the Browsersync snippet.'); + + // Log out and check that the snippet is gone. + $this->drupalLogout(); + $this->drupalGet(''); + $elements = $this->xpath('//script[@id=:id]', [':id' => '__bs_script__']); + $this->assertTrue(empty($elements), 'Page does not contain the Browsersync snippet.'); + } + +} diff --git a/theme/browsersync-snippet.tpl.php b/templates/browsersync-snippet.html.twig similarity index 64% rename from theme/browsersync-snippet.tpl.php rename to templates/browsersync-snippet.html.twig index 41f3d4a..3179e42 100644 --- a/theme/browsersync-snippet.tpl.php +++ b/templates/browsersync-snippet.html.twig @@ -1,5 +1,4 @@ - +#} diff --git a/theme/browsersync.theme.inc b/theme/browsersync.theme.inc deleted file mode 100755 index 53d3fc9..0000000 --- a/theme/browsersync.theme.inc +++ /dev/null @@ -1,14 +0,0 @@ -