/**
  * @param ResourceLoaderContext $context
  * @return array
  */
 public function getStyles(ResourceLoaderContext $context)
 {
     global $wgUser;
     if (!$this->getConfig()->get('AllowUserCssPrefs')) {
         return array();
     }
     $options = $wgUser->getOptions();
     // Build CSS rules
     $rules = array();
     // Underline: 2 = browser default, 1 = always, 0 = never
     if ($options['underline'] < 2) {
         $rules[] = "a { text-decoration: " . ($options['underline'] ? 'underline' : 'none') . "; }";
     } else {
         # The scripts of these languages are very hard to read with underlines
         $rules[] = 'a:lang(ar), a:lang(kk-arab), a:lang(mzn), ' . 'a:lang(ps), a:lang(ur) { text-decoration: none; }';
     }
     if ($options['editfont'] !== 'default') {
         // Double-check that $options['editfont'] consists of safe characters only
         if (preg_match('/^[a-zA-Z0-9_, -]+$/', $options['editfont'])) {
             $rules[] = "textarea { font-family: {$options['editfont']}; }\n";
         }
     }
     $style = implode("\n", $rules);
     if ($this->getFlip($context)) {
         $style = CSSJanus::transform($style, true, false);
     } else {
         $style = CSSJanus::nullTransform($style);
     }
     return array('all' => $style);
 }
 /**
  * Reads a style file.
  *
  * This method can be used as a callback for array_map()
  *
  * @param string $path File path of style file to read
  * @param bool $flip
  *
  * @return string CSS data in script file
  * @throws MWException If the file doesn't exist
  */
 protected function readStyleFile($path, $flip)
 {
     $localPath = $this->getLocalPath($path);
     $remotePath = $this->getRemotePath($path);
     if (!file_exists($localPath)) {
         $msg = __METHOD__ . ": style file not found: \"{$localPath}\"";
         wfDebugLog('resourceloader', $msg);
         throw new MWException($msg);
     }
     if ($this->getStyleSheetLang($localPath) === 'less') {
         $style = $this->compileLessFile($localPath);
         $this->hasGeneratedStyles = true;
     } else {
         $style = file_get_contents($localPath);
     }
     if ($flip) {
         $style = CSSJanus::transform($style, true, false);
     } else {
         $style = CSSJanus::nullTransform($style);
     }
     $localDir = dirname($localPath);
     $remoteDir = dirname($remotePath);
     // Get and register local file references
     $this->localFileRefs = array_merge($this->localFileRefs, CSSMin::getLocalFileReferences($style, $localDir));
     return CSSMin::remap($style, $localDir, $remoteDir, true);
 }
 /**
  * @param ResourceLoaderContext $context
  * @return array
  */
 public function getStyles(ResourceLoaderContext $context)
 {
     $styles = array();
     foreach ($this->getPages($context) as $titleText => $options) {
         if ($options['type'] !== 'style') {
             continue;
         }
         $title = Title::newFromText($titleText);
         if (!$title || $title->isRedirect()) {
             continue;
         }
         $media = isset($options['media']) ? $options['media'] : 'all';
         $style = $this->getContent($title);
         if (strval($style) === '') {
             continue;
         }
         if ($this->getFlip($context)) {
             $style = CSSJanus::transform($style, true, false);
         } else {
             $style = CSSJanus::nullTransform($style);
         }
         $style = CSSMin::remap($style, false, $this->getConfig()->get('ScriptPath'), true);
         if (!isset($styles[$media])) {
             $styles[$media] = array();
         }
         $style = ResourceLoader::makeComment($titleText) . $style;
         $styles[$media][] = $style;
     }
     return $styles;
 }
 /**
  * Build a set of "<link>" elements for the stylesheets specified in the $this->styles array.
  * These will be applied to various media & IE conditionals.
  *
  * @return string
  */
 public function buildCssLinks()
 {
     global $wgContLang;
     $this->getSkin()->setupSkinUserCss($this);
     // Add ResourceLoader styles
     // Split the styles into these groups
     $styles = array('other' => array(), 'user' => array(), 'site' => array(), 'private' => array(), 'noscript' => array());
     $links = array();
     $otherTags = '';
     // Tags to append after the normal <link> tags
     $resourceLoader = $this->getResourceLoader();
     $moduleStyles = $this->getModuleStyles();
     // Per-site custom styles
     $moduleStyles[] = 'site';
     $moduleStyles[] = 'noscript';
     $moduleStyles[] = 'user.groups';
     // Per-user custom styles
     if ($this->getConfig()->get('AllowUserCss') && $this->getTitle()->isCssSubpage() && $this->userCanPreview()) {
         // We're on a preview of a CSS subpage
         // Exclude this page from the user module in case it's in there (bug 26283)
         $link = $this->makeResourceLoaderLink('user', ResourceLoaderModule::TYPE_STYLES, false, array('excludepage' => $this->getTitle()->getPrefixedDBkey()));
         $otherTags .= $link['html'];
         // Load the previewed CSS
         // If needed, Janus it first. This is user-supplied CSS, so it's
         // assumed to be right for the content language directionality.
         $previewedCSS = $this->getRequest()->getText('wpTextbox1');
         if ($this->getLanguage()->getDir() !== $wgContLang->getDir()) {
             $previewedCSS = CSSJanus::transform($previewedCSS, true, false);
         } else {
             $previewedCSS = CSSJanus::nullTransform($previewedCSS);
         }
         $otherTags .= Html::inlineStyle($previewedCSS) . "\n";
     } else {
         // Load the user styles normally
         $moduleStyles[] = 'user';
     }
     // Per-user preference styles
     $moduleStyles[] = 'user.cssprefs';
     foreach ($moduleStyles as $name) {
         $module = $resourceLoader->getModule($name);
         if (!$module) {
             continue;
         }
         $group = $module->getGroup();
         // Modules in groups different than the ones listed on top (see $styles assignment)
         // will be placed in the "other" group
         $styles[isset($styles[$group]) ? $group : 'other'][] = $name;
     }
     // We want site, private and user styles to override dynamically added
     // styles from modules, but we want dynamically added styles to override
     // statically added styles from other modules. So the order has to be
     // other, dynamic, site, private, user. Add statically added styles for
     // other modules
     $links[] = $this->makeResourceLoaderLink($styles['other'], ResourceLoaderModule::TYPE_STYLES);
     // Add normal styles added through addStyle()/addInlineStyle() here
     $links[] = implode("\n", $this->buildCssLinksArray()) . $this->mInlineStyles;
     // Add marker tag to mark the place where the client-side loader should inject dynamic styles
     // We use a <meta> tag with a made-up name for this because that's valid HTML
     $links[] = Html::element('meta', array('name' => 'ResourceLoaderDynamicStyles', 'content' => '')) . "\n";
     // Add site, private and user styles
     // 'private' at present only contains user.options, so put that before 'user'
     // Any future private modules will likely have a similar user-specific character
     foreach (array('site', 'noscript', 'private', 'user') as $group) {
         $links[] = $this->makeResourceLoaderLink($styles[$group], ResourceLoaderModule::TYPE_STYLES);
     }
     // Add stuff in $otherTags (previewed user CSS if applicable)
     return self::getHtmlFromLoaderLinks($links) . $otherTags;
 }