public function filterConfig($target) { $value = $this->getArrayCopy(); if ($target === 'JS') { $value = new Dictionary(ConfigHelper::filterConfig($value, $target)); } return $value; }
/** * @testdox asConfig() returns a list of [attrName, Regexp instance, map] arrays */ public function testGetConfig() { $collection = new AttributePreprocessorCollection(); $collection->add('x', '#(?<x1>x1)#'); $collection->add('x', '#(?<x2>x2)#'); $collection->add('y', '#(?<y1>y1)#'); $collection->add('y', '#(?<y2>y2)#'); $config = $collection->asConfig(); ConfigHelper::filterVariants($config); $this->assertSame([['x', '#(?<x1>x1)#', ['', 'x1']], ['x', '#(?<x2>x2)#', ['', 'x2']], ['y', '#(?<y1>y1)#', ['', 'y1']], ['y', '#(?<y2>y2)#', ['', 'y2']]], $config); }
public function assertHintsContain($str) { $config = $this->configurator->asConfig(); ConfigHelper::filterVariants($config, 'JS'); $xsl = $this->configurator->rendering->engine->getXSL($this->configurator->rendering); $generator = new HintGenerator(); $generator->setConfig($config); $generator->setPlugins($this->configurator->plugins); $generator->setXSL($xsl); $this->assertContains($str, $generator->getHints()); }
/** * {@inheritdoc} */ public function asConfig() { $config = ConfigHelper::toArray(get_object_vars($this)); if (!$this->forceLookahead) { unset($config['forceLookahead']); } if (isset($config['predefinedAttributes'])) { $config['predefinedAttributes'] = new Dictionary($config['predefinedAttributes']); } return $config; }
public function getParser(array $config = \null) { $this->configOptimizer->reset(); $rendererGenerator = new XSLT(); $this->xsl = $rendererGenerator->getXSL($this->configurator->rendering); $this->config = isset($config) ? $config : $this->configurator->asConfig(); ConfigHelper::filterVariants($this->config, 'JS'); $this->config = $this->callbackGenerator->replaceCallbacks($this->config); $src = $this->getHints() . $this->injectConfig($this->getSource()); $src .= $this->getExports(); $src = $this->getMinifier()->get($src); $src = '(function(){' . $src . '})()'; return $src; }
/** * @testdox Filters work * @dataProvider getData */ public function testFilters($filter, $original, $expected, $logs = [], $setup = null) { $this->configurator->tags->add('FOO')->attributes->add('foo')->filterChain->append($filter); if (isset($setup)) { $setup($this->configurator); } $config = $this->configurator->asConfig(); ConfigHelper::filterVariants($config); $logger = new Logger(); $parser = new ReflectionClass('s9e\\TextFormatter\\Parser'); $method = $parser->getMethod('executeFilter'); $method->setAccessible(true); $actual = $method->invoke(null, $config['tags']['FOO']['attributes']['foo']['filterChain'][0], ['attrName' => 'foo', 'attrValue' => $original, 'logger' => $logger, 'registeredVars' => $config['registeredVars']]); $this->assertSame($expected, $actual); if ($logs instanceof Closure) { $logs = $logs(); } $this->assertSame($logs, $logger->get(), "Logs don't match"); }
/** * @testdox asConfig() returns the regexps in a "generics" array where each element is in the form [<tagName>,<regexp>,<passthrough index>,<map>] */ public function testAsConfig() { $plugin = $this->configurator->plugins->load('Preg'); $plugin->replace('/(?<foo>[0-9]+)/', ''); $plugin->replace('/(?<bar>[a-z]+)/', ''); $config = $plugin->asConfig(); ConfigHelper::filterVariants($config); $this->assertEquals(['generics' => [['PREG_C53BB427', '/(?<foo>[0-9]+)/', 0, ['', 'foo']], ['PREG_DCEA6E9C', '/(?<bar>[a-z]+)/', 0, ['', 'bar']]]], $config); }
/** * @testdox executeAttributePreprocessors() returns TRUE even if no source attribute was present */ public function testExecuteAttributePreprocessorsReturnsTrue() { $tagConfig = new TagConfig(); $tagConfig->attributePreprocessors->add('foo', '/^(?<bar>[a-z])(?<baz>[a-z])$/i'); $tagConfig = $tagConfig->asConfig(); ConfigHelper::filterVariants($tagConfig); $tag = new Tag(Tag::SELF_CLOSING_TAG, 'X', 0, 0); $this->assertTrue(Parser::executeAttributePreprocessors($tag, $tagConfig)); }
public function asConfig() { if (!\count($this->collection)) { return; } $codes = \array_keys(\iterator_to_array($this->collection)); $regexp = '/'; if ($this->notAfter !== '') { $regexp .= '(?<!' . $this->notAfter . ')'; } $regexp .= RegexpBuilder::fromList($codes); if ($this->notBefore !== '') { $regexp .= '(?!' . $this->notBefore . ')'; } $regexp .= '/S'; if (\preg_match('/\\\\[pP](?>\\{\\^?\\w+\\}|\\w\\w?)/', $regexp)) { $regexp .= 'u'; } $regexp = \preg_replace('/(?<!\\\\)((?>\\\\\\\\)*)\\(\\?:/', '$1(?>', $regexp); $config = array('quickMatch' => $this->quickMatch, 'regexp' => $regexp, 'tagName' => $this->tagName); if ($this->notAfter !== '') { $lpos = 6 + \strlen($this->notAfter); $rpos = \strrpos($regexp, '/'); $jsRegexp = RegexpConvertor::toJS('/' . \substr($regexp, $lpos, $rpos - $lpos) . '/', \true); $config['regexp'] = new Variant($regexp); $config['regexp']->set('JS', $jsRegexp); $config['notAfter'] = new Variant(); $config['notAfter']->set('JS', RegexpConvertor::toJS('/' . $this->notAfter . '/')); } if ($this->quickMatch === \false) { $config['quickMatch'] = ConfigHelper::generateQuickMatchFromList($codes); } return $config; }
/** * {@inheritdoc} */ public function asConfig() { $vars = get_object_vars($this); // Remove properties that are not needed during parsing unset($vars['defaultChildRule']); unset($vars['defaultDescendantRule']); unset($vars['template']); // If there are no attribute preprocessors defined, we can remove the step from this tag's // filterChain if (!count($this->attributePreprocessors)) { $callback = 's9e\\TextFormatter\\Parser::executeAttributePreprocessors'; // We operate on a copy of the filterChain, without modifying the original $filterChain = clone $vars['filterChain']; // Process the chain in reverse order so that we don't skip indices $i = count($filterChain); while (--$i >= 0) { if ($filterChain[$i]->getCallback() === $callback) { unset($filterChain[$i]); } } $vars['filterChain'] = $filterChain; } return ConfigHelper::toArray($vars); }
/** * {@inheritdoc} */ public function getJSHints() { $quickMatch = ConfigHelper::generateQuickMatchFromList(array_keys($this->aliases)); return ['EMOJI_HAS_ALIASES' => !empty($this->aliases), 'EMOJI_HAS_ALIAS_QUICKMATCH' => $quickMatch !== false]; }
/** * Return an instance of s9e\TextFormatter\Plugins\Censor\Helper * * @return Helper */ public function getHelper() { $config = $this->asConfig(); if (isset($config)) { ConfigHelper::filterVariants($config); } else { // Use a dummy config with a regexp that doesn't match anything $config = ['attrName' => $this->attrName, 'regexp' => '/(?!)/', 'tagName' => $this->tagName]; } return new Helper($config); }
/** * @return mixed */ public function asConfig() { return ConfigHelper::toArray($this->items, true); }
/** * {@inheritdoc} */ public function asConfig() { $vars = get_object_vars($this); unset($vars['markedSafe']); return ConfigHelper::toArray($vars); }
/** * Get a JavaScript parser * * @param array $config Config array returned by the configurator * @return string JavaScript parser */ public function getParser(array $config = null) { $this->configOptimizer->reset(); // Get the stylesheet used for rendering $this->xsl = (new XSLT())->getXSL($this->configurator->rendering); // Prepare the parser's config $this->config = isset($config) ? $config : $this->configurator->asConfig(); ConfigHelper::filterVariants($this->config, 'JS'); $this->config = $this->callbackGenerator->replaceCallbacks($this->config); // Get the parser's source and inject its config $src = $this->getHints() . $this->injectConfig($this->getSource()); // Export the public API $src .= $this->getExports(); // Minify the source $src = $this->getMinifier()->get($src); // Wrap the source in a function to protect the global scope $src = '(function(){' . $src . '})()'; return $src; }
/** * {@inheritdoc} */ public function asConfig() { $config = ['callback' => $this->callback]; foreach ($this->params as $k => $v) { if (is_numeric($k)) { // By value $config['params'][] = $v; } elseif (isset($this->vars[$k])) { // By name, but the value is readily available in $this->vars $config['params'][] = $this->vars[$k]; } else { // By name $config['params'][$k] = null; } } if (isset($config['params'])) { $config['params'] = ConfigHelper::toArray($config['params'], true, true); } // Add the callback's JavaScript representation $config['js'] = new Variant(); $config['js']->set('JS', $this->js); return $config; }
/** * @testdox The regexp has the Unicode modifier if notBefore contains a Unicode property */ public function testNotBeforeUnicode() { $plugin = $this->configurator->plugins->load('Emoticons'); $plugin->add('x', 'x'); $plugin->notBefore = '\\pL'; $config = $plugin->asConfig(); ConfigHelper::filterVariants($config); $this->assertSame('/x(?!\\pL)/Su', $config['regexp']); }
/** * @testdox asConfig() preserves aliased attributes' keys in a JS variant */ public function testAsConfigAliasAttribute() { $plugin = $this->configurator->plugins->load('HTMLElements'); $plugin->aliasAttribute('A', 'HREF', 'URL'); $pluginConfig = $plugin->asConfig(); ConfigHelper::filterVariants($pluginConfig, 'JS'); $this->assertEquals(new Dictionary(['a' => new Dictionary(['href' => 'url'])]), $pluginConfig['aliases']); }
public function getHelper() { $config = $this->asConfig(); if (isset($config)) { $config = ConfigHelper::filterConfig($config, 'PHP'); } else { $config = array('attrName' => $this->attrName, 'regexp' => '/(?!)/', 'tagName' => $this->tagName); } return new Helper($config); }
public function asConfig() { $config = array('attrName' => $this->attrName, 'tagName' => $this->tagName); if (!empty($this->aliases)) { $aliases = \array_keys($this->aliases); $regexp = '/' . RegexpBuilder::fromList($aliases) . '/'; $config['aliases'] = $this->aliases; $config['aliasesRegexp'] = new Regexp($regexp, \true); $quickMatch = ConfigHelper::generateQuickMatchFromList($aliases); if ($quickMatch !== \false) { $config['aliasesQuickMatch'] = $quickMatch; } } return $config; }
/** * @testdox asConfig() uses target names as keys for closeParent */ public function testAsConfigFlipsCloseParent() { $ruleset = new Ruleset(); $ruleset->closeParent('X'); $ruleset->closeParent('Y'); $config = $ruleset->asConfig(); ConfigHelper::filterVariants($config); $this->assertArrayHasKey('closeParent', $config); $this->assertArrayHasKey('X', $config['closeParent']); $this->assertArrayHasKey('Y', $config['closeParent']); }
/** * @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 .= '(?<!' . $this->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 "(?<!)" $lpos = 6 + strlen($this->notAfter); $rpos = strrpos($regexp, '/'); $jsRegexp = RegexpConvertor::toJS('/' . substr($regexp, $lpos, $rpos - $lpos) . '/', true); $config['regexp'] = new Variant($regexp); $config['regexp']->set('JS', $jsRegexp); $config['notAfter'] = new Variant(); $config['notAfter']->set('JS', RegexpConvertor::toJS('/' . $this->notAfter . '/')); } // Try to find a quickMatch if none is set if ($this->quickMatch === false) { $config['quickMatch'] = ConfigHelper::generateQuickMatchFromList($codes); } return $config; }
/** * @testdox asConfig() returns predefinedAttributes in a Dictionary */ public function testAsConfigPreservesPredefinedAttributeNames() { $plugin = $this->configurator->plugins->load('BBCodes'); $plugin->add('FOO')->predefinedAttributes['k'] = 'v'; $config = $plugin->asConfig(); ConfigHelper::filterVariants($config, 'JS'); $this->assertInstanceOf('s9e\\TextFormatter\\Configurator\\JavaScript\\Dictionary', $config['bbcodes']['FOO']['predefinedAttributes']); $this->assertArrayHasKey('k', $config['bbcodes']['FOO']['predefinedAttributes']); }
/** * @testdox Words using the default replacement do not appear in the replacements */ public function testAsConfigDefaultReplacement() { $plugin = $this->configurator->plugins->load('Censor', ['defaultReplacement' => '**']); $plugin->add('apple', '**'); $plugin->add('cherry', 'banana'); $config = $plugin->asConfig(); ConfigHelper::filterVariants($config); $this->assertSame([['/^cherry$/Diu', 'banana']], $config['replacements']); }
public function asConfig() { return ConfigHelper::toArray(\get_object_vars($this)); }
/** * @return array|null This plugin's config, or NULL to disable this plugin */ public function asConfig() { $properties = get_object_vars($this); unset($properties['configurator']); return ConfigHelper::toArray($properties); }
/** * Generate and return the complete config array * * @return array */ public function asConfig() { // Finalize the plugins' config $this->plugins->finalize(); // Remove properties that shouldn't be turned into config arrays $properties = get_object_vars($this); unset($properties['attributeFilters']); unset($properties['bundleGenerator']); unset($properties['javascript']); unset($properties['rendering']); unset($properties['rulesGenerator']); unset($properties['registeredVars']); unset($properties['templateChecker']); unset($properties['templateNormalizer']); unset($properties['stylesheet']); // Create the config array $config = ConfigHelper::toArray($properties); $bitfields = RulesHelper::getBitfields($this->tags, $this->rootRules); // Save the root context $config['rootContext'] = $bitfields['root']; $config['rootContext']['flags'] = $config['rootRules']['flags']; // Save the registered vars (including the empty ones) $config['registeredVars'] = ConfigHelper::toArray($this->registeredVars, true); // Make sure those keys exist even if they're empty $config += ['plugins' => [], 'tags' => []]; // Remove unused tags $config['tags'] = array_intersect_key($config['tags'], $bitfields['tags']); // Add the bitfield information to each tag foreach ($bitfields['tags'] as $tagName => $tagBitfields) { $config['tags'][$tagName] += $tagBitfields; } // Remove unused entries unset($config['rootRules']); return $config; }