collection = new EmoticonCollection; if (!$this->configurator->tags->exists($this->tagName)) { $this->configurator->tags->add($this->tagName); } } /** * Create the template used for emoticons * * @return void */ public function finalize() { $tag = $this->getTag(); if (!isset($tag->template)) { $tag->template = $this->getTemplate(); } } /** * @return array */ public function asConfig() { if (!count($this->collection)) { return; } // Grab the emoticons from the collection $codes = array_keys(iterator_to_array($this->collection)); // Build the regexp used to match emoticons $regexp = '/'; if ($this->notAfter !== '') { $regexp .= '(?notAfter . ')'; } $regexp .= RegexpBuilder::fromList($codes); if ($this->notBefore !== '') { $regexp .= '(?!' . $this->notBefore . ')'; } $regexp .= '/S'; // Set the Unicode mode if Unicode properties are used if (preg_match('/\\\\[pP](?>\\{\\^?\\w+\\}|\\w\\w?)/', $regexp)) { $regexp .= 'u'; } // Force the regexp to use atomic grouping for performance $regexp = preg_replace('/(?\\\\\\\\)*)\\(\\?:/', '$1(?>', $regexp); // Prepare the config array $config = [ 'quickMatch' => $this->quickMatch, 'regexp' => $regexp, 'tagName' => $this->tagName ]; // If notAfter is used, we need to create a JavaScript-specific regexp that does not use a // lookbehind assertion, and we add the notAfter subpattern to the config as a variant if ($this->notAfter !== '') { // Skip the first assertion by skipping the first N characters, where N equals the // length of $this->notAfter plus 1 for the first "/" and 5 for "(?notAfter); $rpos = strrpos($regexp, '/'); $jsRegexp = RegexpConvertor::toJS('/' . substr($regexp, $lpos, $rpos - $lpos) . '/', true); $config['regexp'] = new Regexp($regexp); $config['regexp']->setJS($jsRegexp); $config['notAfter'] = new Regexp('/' . $this->notAfter . '/'); } // Try to find a quickMatch if none is set if ($this->quickMatch === false) { $config['quickMatch'] = ConfigHelper::generateQuickMatchFromList($codes); } return $config; } /** * {@inheritdoc} */ public function getJSHints() { return ['EMOTICONS_NOT_AFTER' => (int) !empty($this->notAfter)]; } /** * Generate the dynamic template that renders all emoticons * * @return string */ public function getTemplate() { // Build the node $xsl = ''; // First, test whether the emoticon should be rendered as text if applicable if (!empty($this->notIfCondition)) { $xsl .= '' . '' . '' . '' . ''; } // Iterate over codes, create an for each emote foreach ($this->collection as $code => $template) { $xsl .= '' . $template . ''; } // Finish it with an that displays the unknown codes as text $xsl .= ''; // Close the emote switch $xsl .= ''; // Close the "notIf" condition if applicable if (!empty($this->notIfCondition)) { $xsl .= ''; } return $xsl; } }