Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge
This commit is contained in:
commit
ce45a1cf94
2
boot.php
2
boot.php
@ -47,7 +47,7 @@ require_once('include/account.php');
|
||||
|
||||
define ( 'PLATFORM_NAME', 'hubzilla' );
|
||||
define ( 'RED_VERSION', trim(file_get_contents('version.inc')));
|
||||
define ( 'STD_VERSION', '1.4.2' );
|
||||
define ( 'STD_VERSION', '1.4.3' );
|
||||
define ( 'ZOT_REVISION', 1 );
|
||||
|
||||
define ( 'DB_UPDATE_VERSION', 1166 );
|
||||
|
@ -143,19 +143,17 @@ EOT;
|
||||
if((App::$module != 'home') && (! (local_channel())))
|
||||
$nav['home'] = array($homelink, t('Home'), "", t('Home Page'),'home_nav_btn');
|
||||
|
||||
|
||||
if((App::$config['system']['register_policy'] == REGISTER_OPEN) && (! local_channel()) && (! remote_channel()))
|
||||
$nav['register'] = array('register',t('Register'), "", t('Create an account'),'register_nav_btn');
|
||||
|
||||
$help_url = z_root() . '/help?f=&cmd=' . App::$cmd;
|
||||
|
||||
if(! get_config('system','hide_help')) {
|
||||
$help_url = z_root() . '/help?f=&cmd=' . App::$cmd;
|
||||
$context_help = '';
|
||||
$enable_context_help = ((intval(get_config('system','enable_context_help')) === 1 || get_config('system','enable_context_help') === false) ? true : false);
|
||||
if($enable_context_help === true) {
|
||||
require_once('include/help.php');
|
||||
$context_help = load_context_help();
|
||||
//direct directly to /help if $context_help is empty - this can be removed once we have context help for all modules
|
||||
//point directly to /help if $context_help is empty - this can be removed once we have context help for all modules
|
||||
$enable_context_help = (($context_help) ? true : false);
|
||||
}
|
||||
$nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help);
|
||||
@ -166,7 +164,6 @@ EOT;
|
||||
|
||||
$nav['search'] = array('search', t('Search'), "", t('Search site @name, #tag, ?docs, content'));
|
||||
|
||||
|
||||
$nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory'),'directory_nav_btn');
|
||||
|
||||
|
||||
@ -240,16 +237,10 @@ $powered_by = '';
|
||||
|
||||
// $powered_by = '<strong>red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="r#" />matrix</strong>';
|
||||
|
||||
$tpl = get_markup_template('nav_header.tpl');
|
||||
|
||||
App::$page['htmlhead'] .= replace_macros($tpl, array(
|
||||
'$enable_context_help' => $enable_context_help
|
||||
));
|
||||
|
||||
$tpl = get_markup_template('nav.tpl');
|
||||
|
||||
App::$page['nav'] .= replace_macros($tpl, array(
|
||||
'$baseurl' => z_root(),
|
||||
'$baseurl' => z_root(),
|
||||
'$sitelocation' => $sitelocation,
|
||||
'$nav' => $x['nav'],
|
||||
'$banner' => $banner,
|
||||
@ -260,7 +251,7 @@ $powered_by = '';
|
||||
'$powered_by' => $powered_by,
|
||||
'$help' => t('@name, #tag, ?doc, content'),
|
||||
'$pleasewait' => t('Please wait...')
|
||||
));
|
||||
));
|
||||
|
||||
call_hooks('page_header', App::$page['nav']);
|
||||
}
|
||||
|
@ -21,17 +21,17 @@ Smarty 3.1.28
|
||||
fetch() and display()
|
||||
=====================
|
||||
The fetch() and display() methods of the template object accept now optionally the same parameter
|
||||
as the corresponding Smarty methods to get tne content of another template.
|
||||
as the corresponding Smarty methods to get the content of another template.
|
||||
Example:
|
||||
$template->display(); Does display template of template object
|
||||
$template->dispaly('foo.tpl'); Does display template 'foo.bar'
|
||||
$template->display('foo.tpl'); Does display template 'foo.bar'
|
||||
|
||||
File: resource
|
||||
==============
|
||||
Multiple template_dir entries can now be selected by a comma separated list of indices.
|
||||
The template_dir array is searched in the order of the indices. (Could be used to change the default search order)
|
||||
Example:
|
||||
$smarty->display([1],[0]foo.bar');
|
||||
$smarty->display('[1],[0]foo.bar');
|
||||
|
||||
Filter support
|
||||
==============
|
||||
@ -130,4 +130,4 @@ Smarty 3.1.22
|
||||
Smarty::DEBUG_INDIVIDUAL will create for each display() and fetch() call an individual debug window.
|
||||
|
||||
.
|
||||
|
||||
|
||||
|
@ -1,14 +1,50 @@
|
||||
===== 3.1.28 ===== (13.12.2015)
|
||||
===== 3.1.29 ===== (21.12.2015)
|
||||
21.12.2015
|
||||
- optimization improve speed of filetime checks on extends and extendsall resource
|
||||
|
||||
20.12.2015
|
||||
- bugfix failure when the default resource type was set to 'extendsall' https://github.com/smarty-php/smarty/issues/123
|
||||
- update compilation of Smarty special variables
|
||||
- bugfix add addition check for OS type on normalizaition of file path https://github.com/smarty-php/smarty/issues/134
|
||||
- bugfix the source uid of the extendsall resource must contain $template_dir settings https://github.com/smarty-php/smarty/issues/123
|
||||
|
||||
19.12.2015
|
||||
- bugfix using $smarty.capture.foo in expressions could fail https://github.com/smarty-php/smarty/pull/138
|
||||
- bugfix broken PHP 5.2 compatibility https://github.com/smarty-php/smarty/issues/139
|
||||
- remove no longer used code
|
||||
- improvement make sure that compiled and cache templates never can contain a trailing '?>?
|
||||
|
||||
18.12.2015
|
||||
- bugfix regression when modifier parameter was follow by math https://github.com/smarty-php/smarty/issues/132
|
||||
|
||||
17.12.2015
|
||||
- bugfix {$smarty.capture.nameFail} did lowercase capture name https://github.com/smarty-php/smarty/issues/135
|
||||
- bugfix using {block append/prepend} on same block in multiple levels of inheritance templates could fail (forum topic 25827)
|
||||
- bugfix text content consisting of just a single '0' like in {if true}0{/if} was suppressed (forum topic 25834)
|
||||
|
||||
16.12.2015
|
||||
- bugfix {foreach} did fail if from atrribute is a Generator class https://github.com/smarty-php/smarty/issues/128
|
||||
- bugfix direct access $smarty->template_dir = 'foo'; should call Smarty::setTemplateDir() https://github.com/smarty-php/smarty/issues/121
|
||||
|
||||
15.12.2015
|
||||
- bugfix {$smarty.cookies.foo} did return the $_COOKIE array not the 'foo' value https://github.com/smarty-php/smarty/issues/122
|
||||
- bugfix a call to clearAllCache() and other should clear all internal template object caches (forum topic 25828)
|
||||
|
||||
14.12.2015
|
||||
- bugfix {$smarty.config.foo} broken in 3.1.28 https://github.com/smarty-php/smarty/issues/120
|
||||
- bugfix multiple calls of {section} with same name droped E_NOTICE error https://github.com/smarty-php/smarty/issues/118
|
||||
|
||||
===== 3.1.28 ===== (13.12.2015)
|
||||
13.12.2015
|
||||
- bugfix {foreach} and {section} with uppercase characters in name attribute did not work (forum topic 25819)
|
||||
- bugfix $smarty->debugging_ctrl = 'URL' did not work (forum topic 25811)
|
||||
- bugfix Debug Console could display incorrect data when using subtemplates
|
||||
|
||||
09.12.2015
|
||||
- bugix Smarty did fail under PHP 7.0.0 with use_include_path = true;
|
||||
- bugfix Smarty did fail under PHP 7.0.0 with use_include_path = true;
|
||||
|
||||
09.12.2015
|
||||
-bugfix {strip} should exclude some html tags from stripping, related to fix for https://github.com/smarty-php/smarty/issues/111
|
||||
- bugfix {strip} should exclude some html tags from stripping, related to fix for https://github.com/smarty-php/smarty/issues/111
|
||||
|
||||
08.12.2015
|
||||
- bugfix internal template function data got stored in wrong compiled file https://github.com/smarty-php/smarty/issues/114
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @author Uwe Tews
|
||||
* @author Rodney Rehm
|
||||
* @package Smarty
|
||||
* @version 3.1.28
|
||||
* @version 3.1.29
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -118,7 +118,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
/**
|
||||
* smarty version
|
||||
*/
|
||||
const SMARTY_VERSION = '3.1.28';
|
||||
const SMARTY_VERSION = '3.1.29';
|
||||
|
||||
/**
|
||||
* define variable scopes
|
||||
@ -677,15 +677,20 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
/**
|
||||
* removed properties
|
||||
*
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
private static $obsoleteProperties = array('resource_caching', 'template_resource_caching',
|
||||
'direct_access_security', '_dir_perms', '_file_perms',
|
||||
'plugin_search_order', 'inheritance_merge_compiled_includes');
|
||||
|
||||
private static $accessMap = array('template_dir' => 'getTemplateDir', 'config_dir' => 'getConfigDir',
|
||||
'plugins_dir' => 'getPluginsDir', 'compile_dir' => 'getCompileDir',
|
||||
'cache_dir' => 'getCacheDir',);
|
||||
/**
|
||||
* List of private properties which will call getter/setter ona direct access
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $accessMap = array('template_dir' => 'TemplateDir', 'config_dir' => 'ConfigDir',
|
||||
'plugins_dir' => 'PluginsDir', 'compile_dir' => 'CompileDir',
|
||||
'cache_dir' => 'CacheDir',);
|
||||
|
||||
/**#@-*/
|
||||
|
||||
@ -1173,7 +1178,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
$path = str_replace($nds, DS, $path);
|
||||
}
|
||||
|
||||
if ($realpath === true && $path[0] !== '/' && $path[1] !== ':') {
|
||||
if ($realpath === true && (($path[0] !== '/' && DS == '/') || ($path[1] !== ':' && DS != '/'))) {
|
||||
$path = getcwd() . DS . $path;
|
||||
}
|
||||
while ((strpos($path, '.' . DS) !== false) || (strpos($path, DS . DS) !== false)) {
|
||||
@ -1344,7 +1349,8 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
{
|
||||
|
||||
if (isset(self::$accessMap[$name])) {
|
||||
return $this->{self::$accessMap[$name]}();
|
||||
$method = 'get' . self::$accessMap[$name];
|
||||
return $this->{$method}();
|
||||
} elseif (in_array($name, self::$obsoleteProperties)) {
|
||||
return null;
|
||||
} else {
|
||||
@ -1363,7 +1369,8 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
public function __set($name, $value)
|
||||
{
|
||||
if (isset(self::$accessMap[$name])) {
|
||||
$this->{self::$accessMap[$name]}($value);
|
||||
$method = 'set' . self::$accessMap[$name];
|
||||
$this->{$method}($value);
|
||||
} elseif (in_array($name, self::$obsoleteProperties)) {
|
||||
return;
|
||||
} else {
|
||||
|
@ -215,12 +215,9 @@ abstract class Smarty_CacheResource
|
||||
*/
|
||||
public function invalidLoadedCache(Smarty $smarty)
|
||||
{
|
||||
if (isset($smarty->_cache['template_objects'])) {
|
||||
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
|
||||
if (isset($tpl->cached)) {
|
||||
unset ($smarty->_cache['template_objects'][$key]);
|
||||
}
|
||||
}
|
||||
$smarty->_cache['isCached'] = array();
|
||||
if (isset($smarty->ext->_subtemplate)) {
|
||||
$smarty->ext->_subtemplate->tplObjects = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher
|
||||
}
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
$compiler->has_code = true;
|
||||
$output = "<?php \n\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 3, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n";
|
||||
$output = "<?php \n\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 4, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n";
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
@ -69,13 +69,12 @@ class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase
|
||||
*/
|
||||
public static function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
// make all lower case
|
||||
$parameter = array_map('strtolower', $parameter);
|
||||
$tag = trim($parameter[0], '"\'');
|
||||
if (!isset($parameter[1]) || false === $name = $compiler->getId($parameter[1])) {
|
||||
$tag = strtolower(trim($parameter[ 0 ], '"\''));
|
||||
$name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
|
||||
if (!$name) {
|
||||
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
|
||||
}
|
||||
return "isset(\$_smarty_tpl->_cache['__smarty_capture']['{$name}']) ? \$_smarty_tpl->_cache['__smarty_capture']['{$name}'] : null";
|
||||
return "(isset(\$_smarty_tpl->_cache['__smarty_capture']['{$name}']) ? \$_smarty_tpl->_cache['__smarty_capture']['{$name}'] : null)";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $nameProperties = array('first', 'last', 'index', 'iteration', 'show', 'total');
|
||||
public $nameProperties = array('first', 'last', 'index', 'iteration', 'show', 'total');
|
||||
|
||||
/**
|
||||
* Valid properties of $item@xxx variable
|
||||
@ -183,8 +183,10 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo
|
||||
foreach ($saveVars as $k => $code) {
|
||||
$output .= "{$local}{$k} = {$code}\n";
|
||||
}
|
||||
if (isset($itemAttr['show']) || isset($itemAttr['total']) || isset($namedAttr['total']) || isset($namedAttr['show']) || isset($itemAttr['last']) || isset($namedAttr['last'])) {
|
||||
$output .= "{$local}total = \$_smarty_tpl->smarty->ext->_foreach->count(\$_from);\n";
|
||||
}
|
||||
$output .= "{$itemVar} = new Smarty_Variable();\n";
|
||||
$output .= "{$local}total = \$_smarty_tpl->smarty->ext->_foreach->count(\$_from);\n";
|
||||
if (isset($itemAttr['show'])) {
|
||||
$output .= "{$itemVar}->show = ({$local}total > 0);\n";
|
||||
}
|
||||
@ -210,7 +212,6 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo
|
||||
$output .= "{$foreachVar} = new Smarty_Variable({$_vars});\n";
|
||||
}
|
||||
}
|
||||
$output .= "if ({$local}total) {\n";
|
||||
if (isset($attributes['key'])) {
|
||||
$output .= "\$_smarty_tpl->tpl_vars['{$key}'] = new Smarty_Variable();\n";
|
||||
}
|
||||
@ -226,7 +227,9 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo
|
||||
if ($needIteration) {
|
||||
$output .= "{$local}iteration=0;\n";
|
||||
}
|
||||
$output .= "{$itemVar}->_loop = false;\n";
|
||||
$output .= "foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n";
|
||||
$output .= "{$itemVar}->_loop = true;\n";
|
||||
if (isset($attributes['key']) && isset($itemAttr['key'])) {
|
||||
$output .= "\$_smarty_tpl->tpl_vars['{$key}']->value = {$itemVar}->key;\n";
|
||||
}
|
||||
@ -296,7 +299,7 @@ class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase
|
||||
$output = "<?php\n";
|
||||
$output .= "{$itemVar} = {$local}saved_local_item;\n";
|
||||
$output .= "}\n";
|
||||
$output .= "} else {\n?>";
|
||||
$output .= "if (!{$itemVar}->_loop) {\n?>";
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@ -332,7 +335,6 @@ class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase
|
||||
|
||||
if ($restore) {
|
||||
$output .= "{$itemVar} = {$local}saved_local_item;\n";
|
||||
$output .= "}\n";
|
||||
}
|
||||
$output .= "}\n";
|
||||
foreach ($restoreVars as $restore) {
|
||||
|
@ -50,7 +50,7 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $nameProperties = array();
|
||||
public $nameProperties = array();
|
||||
|
||||
/**
|
||||
* {section} tag has no item properties
|
||||
@ -112,8 +112,7 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
|
||||
if ($named) {
|
||||
$this->resultOffsets['named'] = $this->startOffset + 3;
|
||||
$this->propertyPreg .= "([\$]smarty[.]{$this->tagName}[.]{$attributes['name']}[.](";
|
||||
$className = get_class($this);
|
||||
$properties = $className::$nameProperties;
|
||||
$properties = $this->nameProperties;
|
||||
} else {
|
||||
$this->resultOffsets['item'] = $this->startOffset + 3;
|
||||
$this->propertyPreg .= "([\$]{$attributes['item']}[@](";
|
||||
@ -204,17 +203,15 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
|
||||
* @return string compiled code
|
||||
* @throws \SmartyCompilerException
|
||||
*/
|
||||
public static function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
public function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
$tag = strtolower(trim($parameter[ 0 ], '"\''));
|
||||
$name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
|
||||
if (!$name) {
|
||||
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
|
||||
}
|
||||
/* @var Smarty_Internal_Compile_Foreach|Smarty_Internal_Compile_Section $className */
|
||||
$className = 'Smarty_Internal_Compile_' . ucfirst($tag);
|
||||
$property = isset($parameter[ 2 ]) ? strtolower($compiler->getId($parameter[ 2 ])) : false;
|
||||
if (!$property || !in_array($property, $className::$nameProperties)) {
|
||||
if (!$property || !in_array($property, $this->nameProperties)) {
|
||||
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", null, true);
|
||||
}
|
||||
$tagVar = "'__smarty_{$tag}_{$name}'";
|
||||
|
@ -29,7 +29,7 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||
{
|
||||
$_index = preg_split("/\]\[/", substr($parameter, 1, strlen($parameter) - 2));
|
||||
$variable = strtolower($compiler->getId($_index[0]));
|
||||
$variable = strtolower($compiler->getId($_index[ 0 ]));
|
||||
if ($variable === false) {
|
||||
$compiler->trigger_template_error("special \$Smarty variable name index can not be variable", null, true);
|
||||
}
|
||||
@ -39,7 +39,11 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
||||
switch ($variable) {
|
||||
case 'foreach':
|
||||
case 'section':
|
||||
return Smarty_Internal_Compile_Private_ForeachSection::compileSpecialVariable(array(), $compiler, $_index);
|
||||
if (!isset($compiler->_tag_objects[ $variable ])) {
|
||||
$class = 'Smarty_Internal_Compile_' . ucfirst($variable);
|
||||
$compiler->_tag_objects[ $variable ] = new $class;
|
||||
}
|
||||
return $compiler->_tag_objects[ $variable ]->compileSpecialVariable(array(), $compiler, $_index);
|
||||
case 'capture':
|
||||
if (class_exists('Smarty_Internal_Compile_Capture')) {
|
||||
return Smarty_Internal_Compile_Capture::compileSpecialVariable(array(), $compiler, $_index);
|
||||
@ -54,7 +58,8 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
||||
$compiler->trigger_template_error("(secure mode) super globals not permitted");
|
||||
break;
|
||||
}
|
||||
return '$_COOKIE';
|
||||
$compiled_ref = '$_COOKIE';
|
||||
break;
|
||||
case 'get':
|
||||
case 'post':
|
||||
case 'env':
|
||||
@ -80,9 +85,7 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
||||
return 'dirname($_smarty_tpl->source->filepath)';
|
||||
|
||||
case 'version':
|
||||
$_version = Smarty::SMARTY_VERSION;
|
||||
|
||||
return "'$_version'";
|
||||
return "Smarty::SMARTY_VERSION";
|
||||
|
||||
case 'const':
|
||||
if (isset($compiler->smarty->security_policy) &&
|
||||
@ -91,33 +94,27 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
||||
$compiler->trigger_template_error("(secure mode) constants not permitted");
|
||||
break;
|
||||
}
|
||||
if (strpos($_index[1], '$') === false && strpos($_index[1], '\'') === false) {
|
||||
if (strpos($_index[ 1 ], '$') === false && strpos($_index[ 1 ], '\'') === false) {
|
||||
return "@constant('{$_index[1]}')";
|
||||
} else {
|
||||
return "@constant({$_index[1]})";
|
||||
}
|
||||
|
||||
case 'config':
|
||||
if (isset($_index[2])) {
|
||||
return "(is_array(\$tmp = \$_smarty_tpl->smarty->ext->_config->_getConfigVariable(\$_smarty_tpl, $_index[1])) ? \$tmp[$_index[2]] : null)";
|
||||
if (isset($_index[ 2 ])) {
|
||||
return "(is_array(\$tmp = \$_smarty_tpl->smarty->ext->configload->_getConfigVariable(\$_smarty_tpl, $_index[1])) ? \$tmp[$_index[2]] : null)";
|
||||
} else {
|
||||
return "\$_smarty_tpl->smarty->ext->_config->_getConfigVariable(\$_smarty_tpl, $_index[1])";
|
||||
return "\$_smarty_tpl->smarty->ext->configload->_getConfigVariable(\$_smarty_tpl, $_index[1])";
|
||||
}
|
||||
case 'ldelim':
|
||||
$_ldelim = $compiler->smarty->left_delimiter;
|
||||
|
||||
return "'$_ldelim'";
|
||||
|
||||
return "\$_smarty_tpl->smarty->left_delimiter";
|
||||
case 'rdelim':
|
||||
$_rdelim = $compiler->smarty->right_delimiter;
|
||||
|
||||
return "'$_rdelim'";
|
||||
|
||||
return "\$_smarty_tpl->smarty->right_delimiter";
|
||||
default:
|
||||
$compiler->trigger_template_error('$smarty.' . trim($_index[0], "'") . ' is invalid');
|
||||
$compiler->trigger_template_error('$smarty.' . trim($_index[ 0 ], "'") . ' is not defined');
|
||||
break;
|
||||
}
|
||||
if (isset($_index[1])) {
|
||||
if (isset($_index[ 1 ])) {
|
||||
array_shift($_index);
|
||||
foreach ($_index as $_ind) {
|
||||
$compiled_ref = $compiled_ref . "[$_ind]";
|
||||
|
@ -59,7 +59,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $nameProperties = array('first', 'last', 'index', 'iteration', 'show', 'total', 'rownum',
|
||||
public $nameProperties = array('first', 'last', 'index', 'iteration', 'show', 'total', 'rownum',
|
||||
'index_prev', 'index_next');
|
||||
|
||||
/**
|
||||
@ -103,7 +103,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo
|
||||
// maybe nocache because of nocache variables
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
$initLocal = array('saved' => "isset(\$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}']) ? \$_smarty_tpl->tpl_vars['__section_{$attributes['name']}'] : false",);
|
||||
$initLocal = array('saved' => "isset(\$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}']) ? \$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}'] : false",);
|
||||
$initNamedProperty = array();
|
||||
$initFor = array();
|
||||
$incFor = array();
|
||||
|
@ -187,6 +187,21 @@ class Smarty_Internal_Data
|
||||
return $this->ext->getTemplateVars->getTemplateVars($this, $varName, $_ptr, $searchParents);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the object of a Smarty variable
|
||||
*
|
||||
* @param string $variable the name of the Smarty variable
|
||||
* @param Smarty_Internal_Data $_ptr optional pointer to data object
|
||||
* @param boolean $searchParents search also in parent data
|
||||
* @param bool $error_enable
|
||||
*
|
||||
* @return Smarty_Variable|Smarty_Undefined_Variable the object of the variable
|
||||
* @deprecated since 3.1.28 please use Smarty_Internal_Data::getTemplateVars() instead.
|
||||
*/
|
||||
public function getVariable($variable = null, Smarty_Internal_Data $_ptr = null, $searchParents = true, $error_enable = true){
|
||||
return $this->ext->getTemplateVars->_getVariable($this, $variable, $_ptr, $searchParents, $error_enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Follow the parent chain an merge template and config variables
|
||||
*
|
||||
|
@ -114,14 +114,6 @@ class Smarty_Internal_Extension_Clear
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove from template cache
|
||||
if (isset($smarty->_cache['template_objects'])) {
|
||||
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
|
||||
if (isset($tpl->cached) && $tpl->cached->filepath == (string) $_file) {
|
||||
unset($smarty->_cache['template_objects'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$_count += @unlink((string) $_file) ? 1 : 0;
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate((string) $_file);
|
||||
|
@ -34,10 +34,7 @@ class Smarty_Internal_Method_ClearAllCache
|
||||
{
|
||||
// load cache resource and call clearAll
|
||||
$_cache_resource = Smarty_CacheResource::load($smarty, $type);
|
||||
if ($smarty->caching_type != 'file') {
|
||||
$_cache_resource->invalidLoadedCache($smarty);
|
||||
}
|
||||
|
||||
$_cache_resource->invalidLoadedCache($smarty);
|
||||
return $_cache_resource->clearAll($smarty, $exp_time);
|
||||
}
|
||||
}
|
@ -37,10 +37,7 @@ class Smarty_Internal_Method_ClearCache
|
||||
{
|
||||
// load cache resource and call clear
|
||||
$_cache_resource = Smarty_CacheResource::load($smarty, $type);
|
||||
if ($smarty->caching_type != 'file' && !isset($template_name)) {
|
||||
$_cache_resource->invalidLoadedCache($smarty);
|
||||
}
|
||||
|
||||
$_cache_resource->invalidLoadedCache($smarty);
|
||||
return $_cache_resource->clear($smarty, $template_name, $cache_id, $compile_id, $exp_time);
|
||||
}
|
||||
}
|
@ -107,13 +107,6 @@ class Smarty_Internal_Method_ClearCompiledTemplate
|
||||
}
|
||||
|
||||
if ($unlink && @unlink($_filepath)) {
|
||||
if (isset($smarty->_cache['template_objects'])) {
|
||||
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
|
||||
if (isset($tpl->compiled) && $tpl->compiled->filepath == $_filepath) {
|
||||
unset($smarty->_cache['template_objects'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$_count ++;
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate($_filepath);
|
||||
@ -121,11 +114,10 @@ class Smarty_Internal_Method_ClearCompiledTemplate
|
||||
}
|
||||
}
|
||||
}
|
||||
// clear compiled cache
|
||||
if (!isset($resource_name) && isset($smarty->_cache['source_objects'])) {
|
||||
foreach ($smarty->_cache['source_objects'] as $source) {
|
||||
$source->compileds = array();
|
||||
}
|
||||
// clear template objects cache
|
||||
$smarty->_cache['isCached'] = array();
|
||||
if (isset($smarty->ext->_subtemplate)) {
|
||||
$smarty->ext->_subtemplate->tplObjects = array();
|
||||
}
|
||||
return $_count;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ class Smarty_Internal_Method_ConfigLoad
|
||||
*
|
||||
* @return mixed the value of the config variable
|
||||
*/
|
||||
public function _getConfigVariable(\Smarty_Internal_Template $tpl, $varName, $errorEnable = true)
|
||||
public function _getConfigVariable(Smarty_Internal_Template $tpl, $varName, $errorEnable = true)
|
||||
{
|
||||
$_ptr = $tpl;
|
||||
while ($_ptr !== null) {
|
||||
|
@ -44,7 +44,7 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource
|
||||
if ($_s->type == 'php') {
|
||||
throw new SmartyException("Resource type {$_s->type} cannot be used with the extends resource type");
|
||||
}
|
||||
$sources[$_s->uid] = $_s;
|
||||
$sources[ $_s->uid ] = $_s;
|
||||
$uid .= $_s->filepath;
|
||||
if ($_template) {
|
||||
$exists = $exists && $_s->exists;
|
||||
@ -110,4 +110,15 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource
|
||||
{
|
||||
return str_replace(':', '.', basename($source->filepath));
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable timestamp checks for extends resource.
|
||||
* The individual source components will be checked.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkTimestamps()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,6 @@ class Smarty_Internal_Runtime_CodeFrame
|
||||
$output .= $functions;
|
||||
$output .= "<?php }\n";
|
||||
// remove unneeded PHP tags
|
||||
return preg_replace('/\s*\?>[\n]?<\?php\s*/', "\n", $output);
|
||||
return preg_replace(array('/\s*\?>[\n]?<\?php\s*/', '/\?>\s*$/'), array("\n", ''), $output);
|
||||
}
|
||||
}
|
@ -27,6 +27,9 @@ class Smarty_Internal_Runtime_Foreach
|
||||
// thus rewind() and valid() methods may not be present
|
||||
return iterator_count($value->getIterator());
|
||||
} elseif ($value instanceof Iterator) {
|
||||
if ($value instanceof Generator) {
|
||||
return 1;
|
||||
}
|
||||
return iterator_count($value);
|
||||
} elseif ($value instanceof PDOStatement) {
|
||||
return $value->rowCount();
|
||||
|
@ -127,8 +127,11 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
* - search in inheritance template hierarchy for child blocks
|
||||
* if found call it, otherwise ignore
|
||||
*
|
||||
* $type 3 = {$smarty.block.parent}:
|
||||
* - get block id from parent stack and call parent block
|
||||
* $type 3 = {block append} {block prepend}:
|
||||
* - call parent block
|
||||
*
|
||||
* $type 4 = {$smarty.block.parent}:
|
||||
* - call parent block
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||
* @param int $type call type see above
|
||||
@ -140,16 +143,22 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
*/
|
||||
public function processBlock(Smarty_Internal_Template $tpl, $type = 0, $name, $block, $callStack = array())
|
||||
{
|
||||
if (!isset($this->blockParameter[$name])) {
|
||||
$this->blockParameter[$name] = array();
|
||||
if (!isset($this->blockParameter[ $name ])) {
|
||||
$this->blockParameter[ $name ] = array();
|
||||
}
|
||||
if ($this->state == 1) {
|
||||
$block[2] = count($this->blockParameter[$name]);
|
||||
$block[3] = $this->tplIndex;
|
||||
$this->blockParameter[$name][] = $block;
|
||||
$block[ 2 ] = count($this->blockParameter[ $name ]);
|
||||
$block[ 3 ] = $this->tplIndex;
|
||||
$this->blockParameter[ $name ][] = $block;
|
||||
return;
|
||||
}
|
||||
if ($type == 3) {
|
||||
if (!empty($callStack)) {
|
||||
$block = array_shift($callStack);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} elseif ($type == 4) {
|
||||
if (!empty($callStack)) {
|
||||
array_shift($callStack);
|
||||
if (empty($callStack)) {
|
||||
@ -160,23 +169,23 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$blockParameter = &$this->blockParameter[$name];
|
||||
$index = 0;
|
||||
$blockParameter = &$this->blockParameter[ $name ];
|
||||
if ($type == 0) {
|
||||
$index = $block[2] = count($blockParameter);
|
||||
$block[3] = $this->tplIndex;
|
||||
$index = $block[ 2 ] = count($blockParameter);
|
||||
$block[ 3 ] = $this->tplIndex;
|
||||
$callStack = array(&$block);
|
||||
} elseif ($type == 1) {
|
||||
$block[3] = $callStack[0][3];
|
||||
$index = 0;
|
||||
$block[ 3 ] = $callStack[ 0 ][ 3 ];
|
||||
for ($i = 0; $i < count($blockParameter); $i ++) {
|
||||
if ($blockParameter[$i][3] <= $block[3]) {
|
||||
$index = $blockParameter[$i][2];
|
||||
if ($blockParameter[ $i ][ 3 ] <= $block[ 3 ]) {
|
||||
$index = $blockParameter[ $i ][ 2 ];
|
||||
}
|
||||
}
|
||||
$block[2] = $index;
|
||||
$block[ 2 ] = $index;
|
||||
$callStack = array(&$block);
|
||||
} else {
|
||||
$index = $callStack[0][2];
|
||||
} elseif ($type == 2) {
|
||||
$index = $callStack[ 0 ][ 2 ];
|
||||
if ($index == 0) {
|
||||
return;
|
||||
}
|
||||
@ -184,29 +193,40 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
}
|
||||
$index --;
|
||||
// find lowest level child block
|
||||
while ($index >= 0 && ($type || !$block[1])) {
|
||||
$block = &$blockParameter[$index];
|
||||
while ($index >= 0 && ($type || !$block[ 1 ])) {
|
||||
$block = &$blockParameter[ $index ];
|
||||
array_unshift($callStack, $block);
|
||||
if ($block[1]) {
|
||||
if ($block[ 1 ]) {
|
||||
break;
|
||||
}
|
||||
$index --;
|
||||
}
|
||||
if (isset($block['hide']) && $index <= 0) {
|
||||
if (isset($block[ 'hide' ]) && $index <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->blockNesting ++;
|
||||
if (isset($block['append'])) {
|
||||
$this->processBlock($tpl, 3, $name, null, $callStack);
|
||||
// {block append} ?
|
||||
if (isset($block[ 'append' ])) {
|
||||
$appendStack = $callStack;
|
||||
if ($type == 0) {
|
||||
array_shift($appendStack);
|
||||
}
|
||||
$this->processBlock($tpl, 3, $name, null, $appendStack);
|
||||
}
|
||||
// call block of current stack level
|
||||
if (isset($block[6])) {
|
||||
$block[6]($tpl, $callStack);
|
||||
} else {
|
||||
$block[0]($tpl, $callStack);
|
||||
}
|
||||
if (isset($block['prepend'])) {
|
||||
$this->processBlock($tpl, 3, $name, null, $callStack);
|
||||
// {block prepend} ?
|
||||
if (isset($block[ 'prepend' ])) {
|
||||
$prependStack = $callStack;
|
||||
if ($type == 0) {
|
||||
array_shift($prependStack);
|
||||
}
|
||||
$this->processBlock($tpl, 3, $name, null, $prependStack);
|
||||
}
|
||||
$this->blockNesting --;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class Smarty_Internal_Runtime_TplFunction
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function callTemplateFunction(\Smarty_Internal_Template $tpl, $name, $params, $nocache)
|
||||
public function callTemplateFunction(Smarty_Internal_Template $tpl, $name, $params, $nocache)
|
||||
{
|
||||
if (isset($tpl->tpl_function[$name])) {
|
||||
if (!$tpl->caching || ($tpl->caching && $nocache)) {
|
||||
|
@ -73,7 +73,7 @@ class Smarty_Internal_Runtime_UpdateCache
|
||||
|
||||
/**
|
||||
* Cache was invalid , so render from compiled and write to cache
|
||||
*
|
||||
*
|
||||
* @param \Smarty_Template_Cached $cached
|
||||
* @param \Smarty_Internal_Template $_template
|
||||
* @param $no_output_filter
|
||||
@ -129,20 +129,6 @@ class Smarty_Internal_Runtime_UpdateCache
|
||||
return false;
|
||||
}
|
||||
$content = $_template->smarty->ext->_codeFrame->create($_template, $content, '', true);
|
||||
if (!empty($_template->cached->tpl_function)) {
|
||||
foreach ($_template->cached->tpl_function as $funcParam) {
|
||||
if (is_file($funcParam['compiled_filepath'])) {
|
||||
// read compiled file
|
||||
$code = file_get_contents($funcParam['compiled_filepath']);
|
||||
// grab template function
|
||||
if (preg_match("/\/\* {$funcParam['call_name']} \*\/([\S\s]*?)\/\*\/ {$funcParam['call_name']} \*\//",
|
||||
$code, $match)) {
|
||||
unset($code);
|
||||
$content .= "<?php " . $match[0] . "?>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->write($cached, $_template, $content);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class Smarty_Internal_Runtime_UpdateScope
|
||||
* @param string $varName variable name
|
||||
* @param int $scope scope to which bubble up variable value
|
||||
*/
|
||||
public function updateScope(\Smarty_Internal_Template $tpl, $varName, $scope = Smarty::SCOPE_LOCAL)
|
||||
public function updateScope(Smarty_Internal_Template $tpl, $varName, $scope = Smarty::SCOPE_LOCAL)
|
||||
{
|
||||
if (!$scope && !$tpl->scope) {
|
||||
return;
|
||||
|
@ -43,8 +43,13 @@ class Smarty_Internal_Runtime_ValidateCompiled
|
||||
} elseif ($_file_to_check[2] == 'string') {
|
||||
continue;
|
||||
} else {
|
||||
$source = Smarty_Template_Source::load(null, $tpl->smarty, $_file_to_check[0]);
|
||||
$mtime = $source->getTimeStamp();
|
||||
$handler = Smarty_Resource::load($tpl->smarty, $_file_to_check[2]);
|
||||
if ($handler->checkTimestamps()) {
|
||||
$source = Smarty_Template_Source::load($tpl, $tpl->smarty, $_file_to_check[ 0 ]);
|
||||
$mtime = $source->getTimeStamp();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!$mtime || $mtime > $_file_to_check[1]) {
|
||||
$is_valid = false;
|
||||
|
@ -17,7 +17,7 @@ class Smarty_Internal_Runtime_Var
|
||||
* @param string $varName template variable name
|
||||
* @param bool $nocache cache mode of variable
|
||||
*/
|
||||
public function createLocalArrayVariable(\Smarty_Internal_Template $tpl, $varName, $nocache = false)
|
||||
public function createLocalArrayVariable(Smarty_Internal_Template $tpl, $varName, $nocache = false)
|
||||
{
|
||||
if (!isset($tpl->tpl_vars[$varName])) {
|
||||
$tpl->tpl_vars[$varName] = new Smarty_Variable(array(), $nocache);
|
||||
|
@ -328,7 +328,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$this->compileTemplateSource($template, $nocache,
|
||||
$parent_compiler),
|
||||
$this->postFilter($this->blockOrFunctionCode) .
|
||||
join('', $this->mergedSubTemplatesCode), false, $this);
|
||||
join('', $this->mergedSubTemplatesCode), false,
|
||||
$this);
|
||||
return $_compiled_code;
|
||||
}
|
||||
|
||||
@ -374,7 +375,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$this->has_variable_string = false;
|
||||
$this->prefix_code = array();
|
||||
// add file dependency
|
||||
$this->parent_compiler->template->compiled->file_dependency[$this->template->source->uid] =
|
||||
$this->parent_compiler->template->compiled->file_dependency[ $this->template->source->uid ] =
|
||||
array($this->template->source->filepath, $this->template->source->getTimeStamp(),
|
||||
$this->template->source->type);
|
||||
$this->smarty->_current_file = $this->template->source->filepath;
|
||||
@ -423,7 +424,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
{
|
||||
// run post filter if on code
|
||||
if (!empty($code) &&
|
||||
(isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post']))
|
||||
(isset($this->smarty->autoload_filters[ 'post' ]) || isset($this->smarty->registered_filters[ 'post' ]))
|
||||
) {
|
||||
return $this->smarty->ext->_filterHandler->runFilter('post', $code, $this->template);
|
||||
} else {
|
||||
@ -443,7 +444,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
{
|
||||
// run pre filter if required
|
||||
if ($_content != '' &&
|
||||
((isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])))
|
||||
((isset($this->smarty->autoload_filters[ 'pre' ]) || isset($this->smarty->registered_filters[ 'pre' ])))
|
||||
) {
|
||||
return $this->smarty->ext->_filterHandler->runFilter('pre', $_content, $this->template);
|
||||
} else {
|
||||
@ -496,8 +497,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$this->has_code = true;
|
||||
$this->has_output = false;
|
||||
// log tag/attributes
|
||||
if (isset($this->smarty->_cache['get_used_tags'])) {
|
||||
$this->template->_cache['used_tags'][] = array($tag, $args);
|
||||
if (isset($this->smarty->_cache[ 'get_used_tags' ])) {
|
||||
$this->template->_cache[ 'used_tags' ][] = array($tag, $args);
|
||||
}
|
||||
// check nocache option flag
|
||||
if (in_array("'nocache'", $args) || in_array(array('nocache' => 'true'), $args) ||
|
||||
@ -507,9 +508,9 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
}
|
||||
// compile the smarty tag (required compile classes to compile the tag are auto loaded)
|
||||
if (($_output = $this->callTagCompiler($tag, $args, $parameter)) === false) {
|
||||
if (isset($this->parent_compiler->template->tpl_function[$tag])) {
|
||||
if (isset($this->parent_compiler->template->tpl_function[ $tag ])) {
|
||||
// template defined by {template} tag
|
||||
$args['_attr']['name'] = "'" . $tag . "'";
|
||||
$args[ '_attr' ][ 'name' ] = "'" . $tag . "'";
|
||||
$_output = $this->callTagCompiler('call', $args, $parameter);
|
||||
}
|
||||
}
|
||||
@ -529,8 +530,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
return null;
|
||||
} else {
|
||||
// map_named attributes
|
||||
if (isset($args['_attr'])) {
|
||||
foreach ($args['_attr'] as $key => $attribute) {
|
||||
if (isset($args[ '_attr' ])) {
|
||||
foreach ($args[ '_attr' ] as $key => $attribute) {
|
||||
if (is_array($attribute)) {
|
||||
$args = array_merge($args, $attribute);
|
||||
}
|
||||
@ -539,14 +540,14 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
// not an internal compiler tag
|
||||
if (strlen($tag) < 6 || substr($tag, - 5) != 'close') {
|
||||
// check if tag is a registered object
|
||||
if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_method'])) {
|
||||
$method = $parameter['object_method'];
|
||||
if (!in_array($method, $this->smarty->registered_objects[$tag][3]) &&
|
||||
(empty($this->smarty->registered_objects[$tag][1]) ||
|
||||
in_array($method, $this->smarty->registered_objects[$tag][1]))
|
||||
if (isset($this->smarty->registered_objects[ $tag ]) && isset($parameter[ 'object_method' ])) {
|
||||
$method = $parameter[ 'object_method' ];
|
||||
if (!in_array($method, $this->smarty->registered_objects[ $tag ][ 3 ]) &&
|
||||
(empty($this->smarty->registered_objects[ $tag ][ 1 ]) ||
|
||||
in_array($method, $this->smarty->registered_objects[ $tag ][ 1 ]))
|
||||
) {
|
||||
return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $method);
|
||||
} elseif (in_array($method, $this->smarty->registered_objects[$tag][3])) {
|
||||
} elseif (in_array($method, $this->smarty->registered_objects[ $tag ][ 3 ])) {
|
||||
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag,
|
||||
$method);
|
||||
} else {
|
||||
@ -558,7 +559,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
// check if tag is registered
|
||||
foreach (array(Smarty::PLUGIN_COMPILER, Smarty::PLUGIN_FUNCTION, Smarty::PLUGIN_BLOCK) as $plugin_type)
|
||||
{
|
||||
if (isset($this->smarty->registered_plugins[$plugin_type][$tag])) {
|
||||
if (isset($this->smarty->registered_plugins[ $plugin_type ][ $tag ])) {
|
||||
// if compiler function plugin call it now
|
||||
if ($plugin_type == Smarty::PLUGIN_COMPILER) {
|
||||
$new_args = array();
|
||||
@ -566,18 +567,18 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
if (is_array($mixed)) {
|
||||
$new_args = array_merge($new_args, $mixed);
|
||||
} else {
|
||||
$new_args[$key] = $mixed;
|
||||
$new_args[ $key ] = $mixed;
|
||||
}
|
||||
}
|
||||
if (!$this->smarty->registered_plugins[$plugin_type][$tag][1]) {
|
||||
if (!$this->smarty->registered_plugins[ $plugin_type ][ $tag ][ 1 ]) {
|
||||
$this->tag_nocache = true;
|
||||
}
|
||||
$function = $this->smarty->registered_plugins[$plugin_type][$tag][0];
|
||||
$function = $this->smarty->registered_plugins[ $plugin_type ][ $tag ][ 0 ];
|
||||
if (!is_array($function)) {
|
||||
return $function($new_args, $this);
|
||||
} elseif (is_object($function[0])) {
|
||||
return $this->smarty->registered_plugins[$plugin_type][$tag][0][0]->{$function[1]}($new_args,
|
||||
$this);
|
||||
} elseif (is_object($function[ 0 ])) {
|
||||
return $this->smarty->registered_plugins[ $plugin_type ][ $tag ][ 0 ][ 0 ]->{$function[ 1 ]}($new_args,
|
||||
$this);
|
||||
} else {
|
||||
return call_user_func_array($function, array($new_args, $this));
|
||||
}
|
||||
@ -604,7 +605,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
if (is_array($mixed)) {
|
||||
$new_args = array_merge($new_args, $mixed);
|
||||
} else {
|
||||
$new_args[$key] = $mixed;
|
||||
$new_args[ $key ] = $mixed;
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,7 +633,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$found = false;
|
||||
// look for already resolved tags
|
||||
foreach ($this->plugin_search_order as $plugin_type) {
|
||||
if (isset($this->default_handler_plugins[$plugin_type][$tag])) {
|
||||
if (isset($this->default_handler_plugins[ $plugin_type ][ $tag ])) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
@ -653,12 +654,12 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
foreach ($args as $mixed) {
|
||||
$new_args = array_merge($new_args, $mixed);
|
||||
}
|
||||
$function = $this->default_handler_plugins[$plugin_type][$tag][0];
|
||||
$function = $this->default_handler_plugins[ $plugin_type ][ $tag ][ 0 ];
|
||||
if (!is_array($function)) {
|
||||
return $function($new_args, $this);
|
||||
} elseif (is_object($function[0])) {
|
||||
return $this->default_handler_plugins[$plugin_type][$tag][0][0]->$function[1]($new_args,
|
||||
$this);
|
||||
} elseif (is_object($function[ 0 ])) {
|
||||
return $this->default_handler_plugins[ $plugin_type ][ $tag ][ 0 ][ 0 ]->$function[ 1 ]($new_args,
|
||||
$this);
|
||||
} else {
|
||||
return call_user_func_array($function, array($new_args, $this));
|
||||
}
|
||||
@ -672,9 +673,9 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
// compile closing tag of block function
|
||||
$base_tag = substr($tag, 0, - 5);
|
||||
// check if closing tag is a registered object
|
||||
if (isset($this->smarty->registered_objects[$base_tag]) && isset($parameter['object_method'])) {
|
||||
$method = $parameter['object_method'];
|
||||
if (in_array($method, $this->smarty->registered_objects[$base_tag][3])) {
|
||||
if (isset($this->smarty->registered_objects[ $base_tag ]) && isset($parameter[ 'object_method' ])) {
|
||||
$method = $parameter[ 'object_method' ];
|
||||
if (in_array($method, $this->smarty->registered_objects[ $base_tag ][ 3 ])) {
|
||||
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag,
|
||||
$method);
|
||||
} else {
|
||||
@ -684,13 +685,13 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
}
|
||||
}
|
||||
// registered block tag ?
|
||||
if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag]) ||
|
||||
isset($this->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag])
|
||||
if (isset($this->smarty->registered_plugins[ Smarty::PLUGIN_BLOCK ][ $base_tag ]) ||
|
||||
isset($this->default_handler_plugins[ Smarty::PLUGIN_BLOCK ][ $base_tag ])
|
||||
) {
|
||||
return $this->callTagCompiler('private_registered_block', $args, $parameter, $tag);
|
||||
}
|
||||
// registered function tag ?
|
||||
if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION][$tag])) {
|
||||
if (isset($this->smarty->registered_plugins[ Smarty::PLUGIN_FUNCTION ][ $tag ])) {
|
||||
return $this->callTagCompiler('private_registered_function', $args, $parameter, $tag);
|
||||
}
|
||||
// block plugin?
|
||||
@ -706,18 +707,18 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
}
|
||||
}
|
||||
// registered compiler plugin ?
|
||||
if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag])) {
|
||||
if (isset($this->smarty->registered_plugins[ Smarty::PLUGIN_COMPILER ][ $tag ])) {
|
||||
// if compiler function plugin call it now
|
||||
$args = array();
|
||||
if (!$this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][1]) {
|
||||
if (!$this->smarty->registered_plugins[ Smarty::PLUGIN_COMPILER ][ $tag ][ 1 ]) {
|
||||
$this->tag_nocache = true;
|
||||
}
|
||||
$function = $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0];
|
||||
$function = $this->smarty->registered_plugins[ Smarty::PLUGIN_COMPILER ][ $tag ][ 0 ];
|
||||
if (!is_array($function)) {
|
||||
return $function($args, $this);
|
||||
} elseif (is_object($function[0])) {
|
||||
return $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0][0]->$function[1]($args,
|
||||
$this);
|
||||
} elseif (is_object($function[ 0 ])) {
|
||||
return $this->smarty->registered_plugins[ Smarty::PLUGIN_COMPILER ][ $tag ][ 0 ][ 0 ]->$function[ 1 ]($args,
|
||||
$this);
|
||||
} else {
|
||||
return call_user_func_array($function, array($args, $this));
|
||||
}
|
||||
@ -783,58 +784,57 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
*/
|
||||
public function processText($text)
|
||||
{
|
||||
$store = array();
|
||||
$_store = 0;
|
||||
$_offset = 0;
|
||||
if ($this->parser->strip) {
|
||||
if (strpos($text, '<') !== false) {
|
||||
// capture html elements not to be messed with
|
||||
$_offset = 0;
|
||||
if (preg_match_all('#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
|
||||
$text, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
|
||||
foreach ($matches as $match) {
|
||||
$store[] = $match[ 0 ][ 0 ];
|
||||
$_length = strlen($match[ 0 ][ 0 ]);
|
||||
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
|
||||
$text = substr_replace($text, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
|
||||
if ((string) $text != '') {
|
||||
$store = array();
|
||||
$_store = 0;
|
||||
$_offset = 0;
|
||||
if ($this->parser->strip) {
|
||||
if (strpos($text, '<') !== false) {
|
||||
// capture html elements not to be messed with
|
||||
$_offset = 0;
|
||||
if (preg_match_all('#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
|
||||
$text, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
|
||||
foreach ($matches as $match) {
|
||||
$store[] = $match[ 0 ][ 0 ];
|
||||
$_length = strlen($match[ 0 ][ 0 ]);
|
||||
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
|
||||
$text = substr_replace($text, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
|
||||
|
||||
$_offset += $_length - strlen($replace);
|
||||
$_store ++;
|
||||
$_offset += $_length - strlen($replace);
|
||||
$_store ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$expressions = array(// replace multiple spaces between tags by a single space
|
||||
// can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
|
||||
'#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
|
||||
// remove spaces between attributes (but not in attribute values!)
|
||||
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
|
||||
'#^\s+<#Ss' => '<',
|
||||
'#>\s+$#Ss' => '>',
|
||||
$this->stripRegEx => ''
|
||||
);
|
||||
$expressions = array(// replace multiple spaces between tags by a single space
|
||||
// can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
|
||||
'#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
|
||||
// remove spaces between attributes (but not in attribute values!)
|
||||
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
|
||||
'#^\s+<#Ss' => '<',
|
||||
'#>\s+$#Ss' => '>',
|
||||
$this->stripRegEx => '');
|
||||
|
||||
$text = preg_replace(array_keys($expressions), array_values($expressions), $text);
|
||||
$_offset = 0;
|
||||
if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $text, $matches,
|
||||
PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
|
||||
foreach ($matches as $match) {
|
||||
$_length = strlen($match[ 0 ][ 0 ]);
|
||||
$replace = $store[ $match[ 1 ][ 0 ] ];
|
||||
$text = substr_replace($text, $replace, $match[ 0 ][ 1 ] + $_offset, $_length);
|
||||
$text = preg_replace(array_keys($expressions), array_values($expressions), $text);
|
||||
$_offset = 0;
|
||||
if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $text, $matches,
|
||||
PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
|
||||
foreach ($matches as $match) {
|
||||
$_length = strlen($match[ 0 ][ 0 ]);
|
||||
$replace = $store[ $match[ 1 ][ 0 ] ];
|
||||
$text = substr_replace($text, $replace, $match[ 0 ][ 1 ] + $_offset, $_length);
|
||||
|
||||
$_offset += strlen($replace) - $_length;
|
||||
$_store ++;
|
||||
$_offset += strlen($replace) - $_length;
|
||||
$_store ++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$text = preg_replace($this->stripRegEx, '', $text);
|
||||
}
|
||||
} else {
|
||||
$text = preg_replace($this->stripRegEx, '', $text);
|
||||
}
|
||||
}
|
||||
if ($text) {
|
||||
return new Smarty_Internal_ParseTree_Text($text);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lazy loads internal compile plugin for tag and calls the compile method
|
||||
@ -853,7 +853,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null)
|
||||
{
|
||||
// re-use object if already exists
|
||||
if (!isset($this->_tag_objects[$tag])) {
|
||||
if (!isset($this->_tag_objects[ $tag ])) {
|
||||
// lazy load internal compiler plugin
|
||||
$_tag = explode('_', $tag);
|
||||
$_tag = array_map('ucfirst', $_tag);
|
||||
@ -861,15 +861,15 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
if (class_exists($class_name) &&
|
||||
(!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))
|
||||
) {
|
||||
$this->_tag_objects[$tag] = new $class_name;
|
||||
$this->_tag_objects[ $tag ] = new $class_name;
|
||||
} else {
|
||||
$this->_tag_objects[$tag] = false;
|
||||
$this->_tag_objects[ $tag ] = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// compile this tag
|
||||
return $this->_tag_objects[$tag] === false ? false :
|
||||
$this->_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
|
||||
return $this->_tag_objects[ $tag ] === false ? false :
|
||||
$this->_tag_objects[ $tag ]->compile($args, $this, $param1, $param2, $param3);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -884,29 +884,29 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
{
|
||||
$function = null;
|
||||
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
|
||||
if (isset($this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name][$plugin_type])) {
|
||||
if (isset($this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ])) {
|
||||
$function =
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name][$plugin_type]['function'];
|
||||
} elseif (isset($this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name][$plugin_type])) {
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name][$plugin_type] =
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name][$plugin_type];
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ];
|
||||
} elseif (isset($this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ])) {
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ];
|
||||
$function =
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name][$plugin_type]['function'];
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ];
|
||||
}
|
||||
} else {
|
||||
if (isset($this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name][$plugin_type])) {
|
||||
if (isset($this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ])) {
|
||||
$function =
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name][$plugin_type]['function'];
|
||||
} elseif (isset($this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name][$plugin_type])) {
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name][$plugin_type] =
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name][$plugin_type];
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ];
|
||||
} elseif (isset($this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ])) {
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ];
|
||||
$function =
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name][$plugin_type]['function'];
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ];
|
||||
}
|
||||
}
|
||||
if (isset($function)) {
|
||||
if ($plugin_type == 'modifier') {
|
||||
$this->modifier_plugins[$plugin_name] = true;
|
||||
$this->modifier_plugins[ $plugin_name ] = true;
|
||||
}
|
||||
|
||||
return $function;
|
||||
@ -917,18 +917,18 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
|
||||
if (is_string($file)) {
|
||||
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name][$plugin_type]['file'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'file' ] =
|
||||
$file;
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name][$plugin_type]['function'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ] =
|
||||
$function;
|
||||
} else {
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name][$plugin_type]['file'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'file' ] =
|
||||
$file;
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name][$plugin_type]['function'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ] =
|
||||
$function;
|
||||
}
|
||||
if ($plugin_type == 'modifier') {
|
||||
$this->modifier_plugins[$plugin_name] = true;
|
||||
$this->modifier_plugins[ $plugin_name ] = true;
|
||||
}
|
||||
|
||||
return $function;
|
||||
@ -961,14 +961,14 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
if ($script !== null) {
|
||||
if (is_file($script)) {
|
||||
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$tag][$plugin_type]['file'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $tag ][ $plugin_type ][ 'file' ] =
|
||||
$script;
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$tag][$plugin_type]['function'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $tag ][ $plugin_type ][ 'function' ] =
|
||||
$callback;
|
||||
} else {
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$tag][$plugin_type]['file'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $tag ][ $plugin_type ][ 'file' ] =
|
||||
$script;
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$tag][$plugin_type]['function'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $tag ][ $plugin_type ][ 'function' ] =
|
||||
$callback;
|
||||
}
|
||||
require_once $script;
|
||||
@ -976,11 +976,13 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found");
|
||||
}
|
||||
}
|
||||
if (!is_string($callback) && !(is_array($callback) && is_string($callback[0]) && is_string($callback[1]))) {
|
||||
if (!is_string($callback) &&
|
||||
!(is_array($callback) && is_string($callback[ 0 ]) && is_string($callback[ 1 ]))
|
||||
) {
|
||||
$this->trigger_template_error("Default plugin handler: Returned callback for \"{$tag}\" must be a static function name or array of class and function name");
|
||||
}
|
||||
if (is_callable($callback)) {
|
||||
$this->default_handler_plugins[$plugin_type][$tag] = array($callback, true, array());
|
||||
$this->default_handler_plugins[ $plugin_type ][ $tag ] = array($callback, true, array());
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@ -1036,9 +1038,9 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
"/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
|
||||
// make sure we include modifier plugins for nocache code
|
||||
foreach ($this->modifier_plugins as $plugin_name => $dummy) {
|
||||
if (isset($this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name]['modifier'])) {
|
||||
$this->parent_compiler->template->compiled->required_plugins['nocache'][$plugin_name]['modifier'] =
|
||||
$this->parent_compiler->template->compiled->required_plugins['compiled'][$plugin_name]['modifier'];
|
||||
if (isset($this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ 'modifier' ])) {
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ 'modifier' ] =
|
||||
$this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ 'modifier' ];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1064,7 +1066,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
public function getId($input)
|
||||
{
|
||||
if (preg_match('~^[\'"]*([0-9]*[a-zA-Z_]\w*)[\'"]*$~', $input, $match)) {
|
||||
return $match[1];
|
||||
return $match[ 1 ];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1079,7 +1081,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
public function getVariableName($input)
|
||||
{
|
||||
if (preg_match('~^[$]_smarty_tpl->tpl_vars\[[\'"]*([0-9]*[a-zA-Z_]\w*)[\'"]*\]->value$~', $input, $match)) {
|
||||
return $match[1];
|
||||
return $match[ 1 ];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1136,7 +1138,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$error_text =
|
||||
'Syntax error in template "' . (empty($this->trace_filepath) ? $templateName : $this->trace_filepath) .
|
||||
'" on line ' . ($line + $this->trace_line_offset) . ' "' .
|
||||
trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1])) . '" ';
|
||||
trim(preg_replace('![\t\r\n]+!', ' ', $match[ $line - 1 ])) . '" ';
|
||||
if (isset($args)) {
|
||||
// individual error message
|
||||
$error_text .= $args;
|
||||
@ -1146,13 +1148,13 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$error_text .= ' - Unexpected "' . $lex->value . '"';
|
||||
if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4) {
|
||||
foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
|
||||
$exp_token = $this->parser->yyTokenName[$token];
|
||||
if (isset($lex->smarty_token_names[$exp_token])) {
|
||||
$exp_token = $this->parser->yyTokenName[ $token ];
|
||||
if (isset($lex->smarty_token_names[ $exp_token ])) {
|
||||
// token type from lexer
|
||||
$expect[] = '"' . $lex->smarty_token_names[$exp_token] . '"';
|
||||
$expect[] = '"' . $lex->smarty_token_names[ $exp_token ] . '"';
|
||||
} else {
|
||||
// otherwise internal token name
|
||||
$expect[] = $this->parser->yyTokenName[$token];
|
||||
$expect[] = $this->parser->yyTokenName[ $token ];
|
||||
}
|
||||
}
|
||||
$error_text .= ', expected one of: ' . implode(' , ', $expect);
|
||||
@ -1160,7 +1162,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
}
|
||||
$e = new SmartyCompilerException($error_text);
|
||||
$e->line = $line;
|
||||
$e->source = trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1]));
|
||||
$e->source = trim(preg_replace('![\t\r\n]+!', ' ', $match[ $line - 1 ]));
|
||||
$e->desc = $args;
|
||||
$e->template = $this->template->source->filepath;
|
||||
throw $e;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -240,6 +240,16 @@ abstract class Smarty_Resource
|
||||
return $resource->buildUniqueResourceName($smarty, $name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if resource must check time stamps when when loading complied or cached templates.
|
||||
* Resources like 'extends' which use source components my disable timestamp checks on own resource.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkTimestamps() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize Source Object for given resource
|
||||
* wrapper for backward compatibility to versions < 3.1.22
|
||||
|
@ -79,13 +79,6 @@ abstract class Smarty_Template_Resource_Base
|
||||
*/
|
||||
public $required_plugins = array();
|
||||
|
||||
/**
|
||||
* Known template functions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tpl_function = array();
|
||||
|
||||
/**
|
||||
* Included subtemplates
|
||||
*
|
||||
|
@ -1,3 +1,16 @@
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === "object" && module.exports) {
|
||||
var $ = require('jquery');
|
||||
module.exports = factory($);
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function (jQuery) {
|
||||
|
||||
/*!
|
||||
* jQuery.textcomplete
|
||||
*
|
||||
@ -17,13 +30,18 @@ if (typeof jQuery === 'undefined') {
|
||||
if (console.warn) { console.warn(message); }
|
||||
};
|
||||
|
||||
var id = 1;
|
||||
|
||||
$.fn.textcomplete = function (strategies, option) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return this.each(function () {
|
||||
var self = this;
|
||||
var $this = $(this);
|
||||
var completer = $this.data('textComplete');
|
||||
if (!completer) {
|
||||
completer = new $.fn.textcomplete.Completer(this, option || {});
|
||||
option || (option = {});
|
||||
option._oid = id++; // unique object id
|
||||
completer = new $.fn.textcomplete.Completer(this, option);
|
||||
$this.data('textComplete', completer);
|
||||
}
|
||||
if (typeof strategies === 'string') {
|
||||
@ -45,7 +63,10 @@ if (typeof jQuery === 'undefined') {
|
||||
}
|
||||
});
|
||||
});
|
||||
completer.register($.fn.textcomplete.Strategy.parse(strategies));
|
||||
completer.register($.fn.textcomplete.Strategy.parse(strategies, {
|
||||
el: self,
|
||||
$el: $this
|
||||
}));
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -115,6 +136,10 @@ if (typeof jQuery === 'undefined') {
|
||||
return Object.prototype.toString.call(obj) === '[object String]';
|
||||
};
|
||||
|
||||
var isFunction = function (obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Function]';
|
||||
};
|
||||
|
||||
var uniqueId = 0;
|
||||
|
||||
function Completer(element, option) {
|
||||
@ -124,7 +149,7 @@ if (typeof jQuery === 'undefined') {
|
||||
this.views = [];
|
||||
this.option = $.extend({}, Completer._getDefaults(), option);
|
||||
|
||||
if (!this.$el.is('input[type=text]') && !this.$el.is('textarea') && !element.isContentEditable && element.contentEditable != 'true') {
|
||||
if (!this.$el.is('input[type=text]') && !this.$el.is('input[type=search]') && !this.$el.is('textarea') && !element.isContentEditable && element.contentEditable != 'true') {
|
||||
throw new Error('textcomplete must be called on a Textarea or a ContentEditable.');
|
||||
}
|
||||
|
||||
@ -171,7 +196,7 @@ if (typeof jQuery === 'undefined') {
|
||||
if (this.option.adapter) {
|
||||
Adapter = this.option.adapter;
|
||||
} else {
|
||||
if (this.$el.is('textarea') || this.$el.is('input[type=text]')) {
|
||||
if (this.$el.is('textarea') || this.$el.is('input[type=text]') || this.$el.is('input[type=search]')) {
|
||||
viewName = typeof element.selectionEnd === 'number' ? 'Textarea' : 'IETextarea';
|
||||
} else {
|
||||
viewName = 'ContentEditable';
|
||||
@ -192,6 +217,12 @@ if (typeof jQuery === 'undefined') {
|
||||
this.$el = this.adapter = this.dropdown = null;
|
||||
},
|
||||
|
||||
deactivate: function () {
|
||||
if (this.dropdown) {
|
||||
this.dropdown.deactivate();
|
||||
}
|
||||
},
|
||||
|
||||
// Invoke textcomplete.
|
||||
trigger: function (text, skipUnchangedTerm) {
|
||||
if (!this.dropdown) { this.initialize(); }
|
||||
@ -200,7 +231,7 @@ if (typeof jQuery === 'undefined') {
|
||||
if (searchQuery.length) {
|
||||
var term = searchQuery[1];
|
||||
// Ignore shift-key, ctrl-key and so on.
|
||||
if (skipUnchangedTerm && this._term === term) { return; }
|
||||
if (skipUnchangedTerm && this._term === term && term !== "") { return; }
|
||||
this._term = term;
|
||||
this._search.apply(this, searchQuery);
|
||||
} else {
|
||||
@ -224,8 +255,10 @@ if (typeof jQuery === 'undefined') {
|
||||
//
|
||||
// value - The selected element of the array callbacked from search func.
|
||||
// strategy - The Strategy object.
|
||||
select: function (value, strategy) {
|
||||
this.adapter.select(value, strategy);
|
||||
// e - Click or keydown event object.
|
||||
select: function (value, strategy, e) {
|
||||
this._term = null;
|
||||
this.adapter.select(value, strategy, e);
|
||||
this.fire('change').fire('textComplete:select', value, strategy);
|
||||
this.adapter.focus();
|
||||
},
|
||||
@ -248,8 +281,9 @@ if (typeof jQuery === 'undefined') {
|
||||
var strategy = this.strategies[i];
|
||||
var context = strategy.context(text);
|
||||
if (context || context === '') {
|
||||
var matchRegexp = isFunction(strategy.match) ? strategy.match(text) : strategy.match;
|
||||
if (isString(context)) { text = context; }
|
||||
var match = text.match(strategy.match);
|
||||
var match = text.match(matchRegexp);
|
||||
if (match) { return [strategy, match[strategy.index], match]; }
|
||||
}
|
||||
}
|
||||
@ -262,14 +296,14 @@ if (typeof jQuery === 'undefined') {
|
||||
strategy.search(term, function (data, stillSearching) {
|
||||
if (!self.dropdown.shown) {
|
||||
self.dropdown.activate();
|
||||
self.dropdown.setPosition(self.adapter.getCaretPosition());
|
||||
}
|
||||
if (self._clearAtNext) {
|
||||
// The first callback in the current lock.
|
||||
self.dropdown.clear();
|
||||
self._clearAtNext = false;
|
||||
}
|
||||
self.dropdown.render(self._zip(data, strategy));
|
||||
self.dropdown.setPosition(self.adapter.getCaretPosition());
|
||||
self.dropdown.render(self._zip(data, strategy, term));
|
||||
if (!stillSearching) {
|
||||
// The last callback in the current lock.
|
||||
free();
|
||||
@ -284,9 +318,9 @@ if (typeof jQuery === 'undefined') {
|
||||
//
|
||||
// this._zip(['a', 'b'], 's');
|
||||
// //=> [{ value: 'a', strategy: 's' }, { value: 'b', strategy: 's' }]
|
||||
_zip: function (data, strategy) {
|
||||
_zip: function (data, strategy, term) {
|
||||
return $.map(data, function (value) {
|
||||
return { value: value, strategy: strategy };
|
||||
return { value: value, strategy: strategy, term: term };
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -297,6 +331,8 @@ if (typeof jQuery === 'undefined') {
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
var $window = $(window);
|
||||
|
||||
var include = function (zippedData, datum) {
|
||||
var i, elem;
|
||||
var idProperty = datum.strategy.idProperty
|
||||
@ -320,6 +356,16 @@ if (typeof jQuery === 'undefined') {
|
||||
});
|
||||
});
|
||||
|
||||
var commands = {
|
||||
SKIP_DEFAULT: 0,
|
||||
KEY_UP: 1,
|
||||
KEY_DOWN: 2,
|
||||
KEY_ENTER: 3,
|
||||
KEY_PAGEUP: 4,
|
||||
KEY_PAGEDOWN: 5,
|
||||
KEY_ESCAPE: 6
|
||||
};
|
||||
|
||||
// Dropdown view
|
||||
// =============
|
||||
|
||||
@ -327,7 +373,7 @@ if (typeof jQuery === 'undefined') {
|
||||
//
|
||||
// element - Textarea or contenteditable element.
|
||||
function Dropdown(element, completer, option) {
|
||||
this.$el = Dropdown.findOrCreateElement(option);
|
||||
this.$el = Dropdown.createElement(option);
|
||||
this.completer = completer;
|
||||
this.id = completer.id + 'dropdown';
|
||||
this._data = []; // zipped data.
|
||||
@ -338,7 +384,7 @@ if (typeof jQuery === 'undefined') {
|
||||
if (option.listPosition) { this.setPosition = option.listPosition; }
|
||||
if (option.height) { this.$el.height(option.height); }
|
||||
var self = this;
|
||||
$.each(['maxCount', 'placement', 'footer', 'header', 'className'], function (_i, name) {
|
||||
$.each(['maxCount', 'placement', 'footer', 'header', 'noResultsMessage', 'className'], function (_i, name) {
|
||||
if (option[name] != null) { self[name] = option[name]; }
|
||||
});
|
||||
this._bindEvents(element);
|
||||
@ -349,18 +395,19 @@ if (typeof jQuery === 'undefined') {
|
||||
// Class methods
|
||||
// -------------
|
||||
|
||||
findOrCreateElement: function (option) {
|
||||
createElement: function (option) {
|
||||
var $parent = option.appendTo;
|
||||
if (!($parent instanceof $)) { $parent = $($parent); }
|
||||
var $el = $parent.children('.dropdown-menu')
|
||||
if (!$el.length) {
|
||||
$el = $('<ul class="dropdown-menu"></ul>').css({
|
||||
var $el = $('<ul></ul>')
|
||||
.addClass('dropdown-menu textcomplete-dropdown')
|
||||
.attr('id', 'textcomplete-dropdown-' + option._oid)
|
||||
.css({
|
||||
display: 'none',
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
zIndex: option.zIndex
|
||||
}).appendTo($parent);
|
||||
}
|
||||
})
|
||||
.appendTo($parent);
|
||||
return $el;
|
||||
}
|
||||
});
|
||||
@ -391,6 +438,7 @@ if (typeof jQuery === 'undefined') {
|
||||
this.$el.off('.' + this.id);
|
||||
this.$inputEl.off('.' + this.id);
|
||||
this.clear();
|
||||
this.$el.remove();
|
||||
this.$el = this.$inputEl = this.completer = null;
|
||||
delete dropdownViews[this.id]
|
||||
},
|
||||
@ -399,34 +447,45 @@ if (typeof jQuery === 'undefined') {
|
||||
var contentsHtml = this._buildContents(zippedData);
|
||||
var unzippedData = $.map(this.data, function (d) { return d.value; });
|
||||
if (this.data.length) {
|
||||
var strategy = zippedData[0].strategy;
|
||||
if (strategy.id) {
|
||||
this.$el.attr('data-strategy', strategy.id);
|
||||
} else {
|
||||
this.$el.removeAttr('data-strategy');
|
||||
}
|
||||
this._renderHeader(unzippedData);
|
||||
this._renderFooter(unzippedData);
|
||||
if (contentsHtml) {
|
||||
this._renderContents(contentsHtml);
|
||||
this._fitToBottom();
|
||||
this._fitToRight();
|
||||
this._activateIndexedItem();
|
||||
}
|
||||
this._setScroll();
|
||||
} else if (this.noResultsMessage) {
|
||||
this._renderNoResultsMessage(unzippedData);
|
||||
} else if (this.shown) {
|
||||
this.deactivate();
|
||||
}
|
||||
},
|
||||
|
||||
setPosition: function (position) {
|
||||
this.$el.css(this._applyPlacement(position));
|
||||
|
||||
setPosition: function (pos) {
|
||||
// Make the dropdown fixed if the input is also fixed
|
||||
// This can't be done during init, as textcomplete may be used on multiple elements on the same page
|
||||
// Because the same dropdown is reused behind the scenes, we need to recheck every time the dropdown is showed
|
||||
var position = 'absolute';
|
||||
// Check if input or one of its parents has positioning we need to care about
|
||||
this.$inputEl.add(this.$inputEl.parents()).each(function() {
|
||||
this.$inputEl.add(this.$inputEl.parents()).each(function() {
|
||||
if($(this).css('position') === 'absolute') // The element has absolute positioning, so it's all OK
|
||||
return false;
|
||||
if($(this).css('position') === 'fixed') {
|
||||
pos.top -= $window.scrollTop();
|
||||
pos.left -= $window.scrollLeft();
|
||||
position = 'fixed';
|
||||
return false;
|
||||
}
|
||||
});
|
||||
this.$el.css(this._applyPlacement(pos));
|
||||
this.$el.css({ position: position }); // Update positioning
|
||||
|
||||
return this;
|
||||
@ -436,7 +495,7 @@ if (typeof jQuery === 'undefined') {
|
||||
this.$el.html('');
|
||||
this.data = [];
|
||||
this._index = 0;
|
||||
this._$header = this._$footer = null;
|
||||
this._$header = this._$footer = this._$noResultsMessage = null;
|
||||
},
|
||||
|
||||
activate: function () {
|
||||
@ -481,19 +540,25 @@ if (typeof jQuery === 'undefined') {
|
||||
return e.keyCode === 34; // PAGEDOWN
|
||||
},
|
||||
|
||||
isEscape: function (e) {
|
||||
return e.keyCode === 27; // ESCAPE
|
||||
},
|
||||
|
||||
// Private properties
|
||||
// ------------------
|
||||
|
||||
_data: null, // Currently shown zipped data.
|
||||
_index: null,
|
||||
_$header: null,
|
||||
_$noResultsMessage: null,
|
||||
_$footer: null,
|
||||
|
||||
// Private methods
|
||||
// ---------------
|
||||
|
||||
_bindEvents: function () {
|
||||
this.$el.on('mousedown.' + this.id, '.textcomplete-item', $.proxy(this._onClick, this))
|
||||
this.$el.on('mousedown.' + this.id, '.textcomplete-item', $.proxy(this._onClick, this));
|
||||
this.$el.on('touchstart.' + this.id, '.textcomplete-item', $.proxy(this._onClick, this));
|
||||
this.$el.on('mouseover.' + this.id, '.textcomplete-item', $.proxy(this._onMouseover, this));
|
||||
this.$inputEl.on('keydown.' + this.id, $.proxy(this._onKeydown, this));
|
||||
},
|
||||
@ -506,11 +571,16 @@ if (typeof jQuery === 'undefined') {
|
||||
$el = $el.closest('.textcomplete-item');
|
||||
}
|
||||
var datum = this.data[parseInt($el.data('index'), 10)];
|
||||
this.completer.select(datum.value, datum.strategy);
|
||||
this.completer.select(datum.value, datum.strategy, e);
|
||||
var self = this;
|
||||
// Deactive at next tick to allow other event handlers to know whether
|
||||
// the dropdown has been shown or not.
|
||||
setTimeout(function () { self.deactivate(); }, 0);
|
||||
setTimeout(function () {
|
||||
self.deactivate();
|
||||
if (e.type === 'touchstart') {
|
||||
self.$inputEl.focus();
|
||||
}
|
||||
}, 0);
|
||||
},
|
||||
|
||||
// Activate hovered item.
|
||||
@ -526,21 +596,58 @@ if (typeof jQuery === 'undefined') {
|
||||
|
||||
_onKeydown: function (e) {
|
||||
if (!this.shown) { return; }
|
||||
|
||||
var command;
|
||||
|
||||
if ($.isFunction(this.option.onKeydown)) {
|
||||
command = this.option.onKeydown(e, commands);
|
||||
}
|
||||
|
||||
if (command == null) {
|
||||
command = this._defaultKeydown(e);
|
||||
}
|
||||
|
||||
switch (command) {
|
||||
case commands.KEY_UP:
|
||||
e.preventDefault();
|
||||
this._up();
|
||||
break;
|
||||
case commands.KEY_DOWN:
|
||||
e.preventDefault();
|
||||
this._down();
|
||||
break;
|
||||
case commands.KEY_ENTER:
|
||||
e.preventDefault();
|
||||
this._enter(e);
|
||||
break;
|
||||
case commands.KEY_PAGEUP:
|
||||
e.preventDefault();
|
||||
this._pageup();
|
||||
break;
|
||||
case commands.KEY_PAGEDOWN:
|
||||
e.preventDefault();
|
||||
this._pagedown();
|
||||
break;
|
||||
case commands.KEY_ESCAPE:
|
||||
e.preventDefault();
|
||||
this.deactivate();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_defaultKeydown: function (e) {
|
||||
if (this.isUp(e)) {
|
||||
e.preventDefault();
|
||||
this._up();
|
||||
return commands.KEY_UP;
|
||||
} else if (this.isDown(e)) {
|
||||
e.preventDefault();
|
||||
this._down();
|
||||
return commands.KEY_DOWN;
|
||||
} else if (this.isEnter(e)) {
|
||||
e.preventDefault();
|
||||
this._enter();
|
||||
return commands.KEY_ENTER;
|
||||
} else if (this.isPageup(e)) {
|
||||
e.preventDefault();
|
||||
this._pageup();
|
||||
return commands.KEY_PAGEUP;
|
||||
} else if (this.isPagedown(e)) {
|
||||
e.preventDefault();
|
||||
this._pagedown();
|
||||
return commands.KEY_PAGEDOWN;
|
||||
} else if (this.isEscape(e)) {
|
||||
return commands.KEY_ESCAPE;
|
||||
}
|
||||
},
|
||||
|
||||
@ -564,10 +671,10 @@ if (typeof jQuery === 'undefined') {
|
||||
this._setScroll();
|
||||
},
|
||||
|
||||
_enter: function () {
|
||||
_enter: function (e) {
|
||||
var datum = this.data[parseInt(this._getActiveElement().data('index'), 10)];
|
||||
this.completer.select(datum.value, datum.strategy);
|
||||
this._setScroll();
|
||||
this.completer.select(datum.value, datum.strategy, e);
|
||||
this.deactivate();
|
||||
},
|
||||
|
||||
_pageup: function () {
|
||||
@ -630,7 +737,7 @@ if (typeof jQuery === 'undefined') {
|
||||
index = this.data.length;
|
||||
this.data.push(datum);
|
||||
html += '<li class="textcomplete-item" data-index="' + index + '"><a>';
|
||||
html += datum.strategy.template(datum.value);
|
||||
html += datum.strategy.template(datum.value, datum.term);
|
||||
html += '</a></li>';
|
||||
}
|
||||
return html;
|
||||
@ -656,6 +763,16 @@ if (typeof jQuery === 'undefined') {
|
||||
}
|
||||
},
|
||||
|
||||
_renderNoResultsMessage: function (unzippedData) {
|
||||
if (this.noResultsMessage) {
|
||||
if (!this._$noResultsMessage) {
|
||||
this._$noResultsMessage = $('<li class="textcomplete-no-results-message"></li>').appendTo(this.$el);
|
||||
}
|
||||
var html = $.isFunction(this.noResultsMessage) ? this.noResultsMessage(unzippedData) : this.noResultsMessage;
|
||||
this._$noResultsMessage.html(html);
|
||||
}
|
||||
},
|
||||
|
||||
_renderContents: function (html) {
|
||||
if (this._$footer) {
|
||||
this._$footer.before(html);
|
||||
@ -664,7 +781,32 @@ if (typeof jQuery === 'undefined') {
|
||||
}
|
||||
},
|
||||
|
||||
_applyPlacement: function (position) {
|
||||
_fitToBottom: function() {
|
||||
var windowScrollBottom = $window.scrollTop() + $window.height();
|
||||
var height = this.$el.height();
|
||||
if ((this.$el.position().top + height) > windowScrollBottom) {
|
||||
this.$el.offset({top: windowScrollBottom - height});
|
||||
}
|
||||
},
|
||||
|
||||
_fitToRight: function() {
|
||||
// We don't know how wide our content is until the browser positions us, and at that point it clips us
|
||||
// to the document width so we don't know if we would have overrun it. As a heuristic to avoid that clipping
|
||||
// (which makes our elements wrap onto the next line and corrupt the next item), if we're close to the right
|
||||
// edge, move left. We don't know how far to move left, so just keep nudging a bit.
|
||||
var tolerance = 30; // pixels. Make wider than vertical scrollbar because we might not be able to use that space.
|
||||
var lastOffset = this.$el.offset().left, offset;
|
||||
var width = this.$el.width();
|
||||
var maxLeft = $window.width() - tolerance;
|
||||
while (lastOffset + width > maxLeft) {
|
||||
this.$el.offset({left: lastOffset - tolerance});
|
||||
offset = this.$el.offset().left;
|
||||
if (offset >= lastOffset) { break; }
|
||||
lastOffset = offset;
|
||||
}
|
||||
},
|
||||
|
||||
_applyPlacement: function (position) {
|
||||
// If the 'placement' option set to 'top', move the position above the element.
|
||||
if (this.placement.indexOf('top') !== -1) {
|
||||
// Overwrite the position object to set the 'bottom' property instead of the top.
|
||||
@ -688,6 +830,7 @@ if (typeof jQuery === 'undefined') {
|
||||
});
|
||||
|
||||
$.fn.textcomplete.Dropdown = Dropdown;
|
||||
$.extend($.fn.textcomplete, commands);
|
||||
}(jQuery);
|
||||
|
||||
+function ($) {
|
||||
@ -713,9 +856,12 @@ if (typeof jQuery === 'undefined') {
|
||||
if (this.cache) { this.search = memoize(this.search); }
|
||||
}
|
||||
|
||||
Strategy.parse = function (optionsArray) {
|
||||
return $.map(optionsArray, function (options) {
|
||||
return new Strategy(options);
|
||||
Strategy.parse = function (strategiesArray, params) {
|
||||
return $.map(strategiesArray, function (strategy) {
|
||||
var strategyObj = new Strategy(strategy);
|
||||
strategyObj.el = params.el;
|
||||
strategyObj.$el = params.$el;
|
||||
return strategyObj;
|
||||
});
|
||||
};
|
||||
|
||||
@ -729,6 +875,7 @@ if (typeof jQuery === 'undefined') {
|
||||
search: null,
|
||||
|
||||
// Optional
|
||||
id: null,
|
||||
cache: false,
|
||||
context: function () { return true; },
|
||||
index: 2,
|
||||
@ -818,11 +965,19 @@ if (typeof jQuery === 'undefined') {
|
||||
},
|
||||
|
||||
// Returns the caret's relative coordinates from body's left top corner.
|
||||
//
|
||||
// FIXME: Calculate the left top corner of `this.option.appendTo` element.
|
||||
getCaretPosition: function () {
|
||||
var position = this._getCaretRelativePosition();
|
||||
var offset = this.$el.offset();
|
||||
|
||||
// Calculate the left top corner of `this.option.appendTo` element.
|
||||
var $parent = this.option.appendTo;
|
||||
if ($parent) {
|
||||
if (!($parent instanceof $)) { $parent = $($parent); }
|
||||
var parentOffset = $parent.offsetParent().offset();
|
||||
offset.top -= parentOffset.top;
|
||||
offset.left -= parentOffset.left;
|
||||
}
|
||||
|
||||
position.top += offset.top;
|
||||
position.left += offset.left;
|
||||
return position;
|
||||
@ -848,6 +1003,8 @@ if (typeof jQuery === 'undefined') {
|
||||
// Suppress searching if it returns true.
|
||||
_skipSearch: function (clickEvent) {
|
||||
switch (clickEvent.keyCode) {
|
||||
case 9: // TAB
|
||||
case 13: // ENTER
|
||||
case 40: // DOWN
|
||||
case 38: // UP
|
||||
return true;
|
||||
@ -874,89 +1031,58 @@ if (typeof jQuery === 'undefined') {
|
||||
this.initialize(element, completer, option);
|
||||
}
|
||||
|
||||
Textarea.DIV_PROPERTIES = {
|
||||
left: -9999,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
whiteSpace: 'pre-wrap'
|
||||
}
|
||||
|
||||
Textarea.COPY_PROPERTIES = [
|
||||
'border-width', 'font-family', 'font-size', 'font-style', 'font-variant',
|
||||
'font-weight', 'height', 'letter-spacing', 'word-spacing', 'line-height',
|
||||
'text-decoration', 'text-align', 'width', 'padding-top', 'padding-right',
|
||||
'padding-bottom', 'padding-left', 'margin-top', 'margin-right',
|
||||
'margin-bottom', 'margin-left', 'border-style', 'box-sizing', 'tab-size'
|
||||
];
|
||||
|
||||
$.extend(Textarea.prototype, $.fn.textcomplete.Adapter.prototype, {
|
||||
// Public methods
|
||||
// --------------
|
||||
|
||||
// Update the textarea with the given value and strategy.
|
||||
select: function (value, strategy) {
|
||||
select: function (value, strategy, e) {
|
||||
var pre = this.getTextFromHeadToCaret();
|
||||
var post = this.el.value.substring(this.el.selectionEnd);
|
||||
var newSubstr = strategy.replace(value);
|
||||
if ($.isArray(newSubstr)) {
|
||||
post = newSubstr[1] + post;
|
||||
newSubstr = newSubstr[0];
|
||||
var newSubstr = strategy.replace(value, e);
|
||||
if (typeof newSubstr !== 'undefined') {
|
||||
if ($.isArray(newSubstr)) {
|
||||
post = newSubstr[1] + post;
|
||||
newSubstr = newSubstr[0];
|
||||
}
|
||||
pre = pre.replace(strategy.match, newSubstr);
|
||||
this.$el.val(pre + post);
|
||||
this.el.selectionStart = this.el.selectionEnd = pre.length;
|
||||
}
|
||||
pre = pre.replace(strategy.match, newSubstr);
|
||||
this.$el.val(pre + post);
|
||||
this.el.selectionStart = this.el.selectionEnd = pre.length;
|
||||
},
|
||||
|
||||
getTextFromHeadToCaret: function () {
|
||||
return this.el.value.substring(0, this.el.selectionEnd);
|
||||
},
|
||||
|
||||
// Private methods
|
||||
// ---------------
|
||||
|
||||
// Returns the caret's relative coordinates from textarea's left top corner.
|
||||
//
|
||||
// Browser native API does not provide the way to know the position of
|
||||
// caret in pixels, so that here we use a kind of hack to accomplish
|
||||
// the aim. First of all it puts a dummy div element and completely copies
|
||||
// the textarea's style to the element, then it inserts the text and a
|
||||
// span element into the textarea.
|
||||
// Consequently, the span element's position is the thing what we want.
|
||||
_getCaretRelativePosition: function () {
|
||||
var dummyDiv = $('<div></div>').css(this._copyCss())
|
||||
.text(this.getTextFromHeadToCaret());
|
||||
var span = $('<span></span>').text('.').appendTo(dummyDiv);
|
||||
this.$el.before(dummyDiv);
|
||||
var position = span.position();
|
||||
position.top += span.height() - this.$el.scrollTop();
|
||||
position.lineHeight = span.height();
|
||||
dummyDiv.remove();
|
||||
return position;
|
||||
var p = $.fn.textcomplete.getCaretCoordinates(this.el, this.el.selectionStart);
|
||||
return {
|
||||
top: p.top + this._calculateLineHeight() - this.$el.scrollTop(),
|
||||
left: p.left - this.$el.scrollLeft()
|
||||
};
|
||||
},
|
||||
|
||||
_copyCss: function () {
|
||||
return $.extend({
|
||||
// Set 'scroll' if a scrollbar is being shown; otherwise 'auto'.
|
||||
overflow: this.el.scrollHeight > this.el.offsetHeight ? 'scroll' : 'auto'
|
||||
}, Textarea.DIV_PROPERTIES, this._getStyles());
|
||||
},
|
||||
|
||||
_getStyles: (function ($) {
|
||||
var color = $('<div></div>').css(['color']).color;
|
||||
if (typeof color !== 'undefined') {
|
||||
return function () {
|
||||
return this.$el.css(Textarea.COPY_PROPERTIES);
|
||||
};
|
||||
} else { // jQuery < 1.8
|
||||
return function () {
|
||||
var $el = this.$el;
|
||||
var styles = {};
|
||||
$.each(Textarea.COPY_PROPERTIES, function (i, property) {
|
||||
styles[property] = $el.css(property);
|
||||
});
|
||||
return styles;
|
||||
};
|
||||
_calculateLineHeight: function () {
|
||||
var lineHeight = parseInt(this.$el.css('line-height'), 10);
|
||||
if (isNaN(lineHeight)) {
|
||||
// http://stackoverflow.com/a/4515470/1297336
|
||||
var parentNode = this.el.parentNode;
|
||||
var temp = document.createElement(this.el.nodeName);
|
||||
var style = this.el.style;
|
||||
temp.setAttribute(
|
||||
'style',
|
||||
'margin:0px;padding:0px;font-family:' + style.fontFamily + ';font-size:' + style.fontSize
|
||||
);
|
||||
temp.innerHTML = 'test';
|
||||
parentNode.appendChild(temp);
|
||||
lineHeight = temp.clientHeight;
|
||||
parentNode.removeChild(temp);
|
||||
}
|
||||
})($),
|
||||
|
||||
getTextFromHeadToCaret: function () {
|
||||
return this.el.value.substring(0, this.el.selectionEnd);
|
||||
return lineHeight;
|
||||
}
|
||||
});
|
||||
|
||||
@ -981,22 +1107,24 @@ if (typeof jQuery === 'undefined') {
|
||||
// Public methods
|
||||
// --------------
|
||||
|
||||
select: function (value, strategy) {
|
||||
select: function (value, strategy, e) {
|
||||
var pre = this.getTextFromHeadToCaret();
|
||||
var post = this.el.value.substring(pre.length);
|
||||
var newSubstr = strategy.replace(value);
|
||||
if ($.isArray(newSubstr)) {
|
||||
post = newSubstr[1] + post;
|
||||
newSubstr = newSubstr[0];
|
||||
var newSubstr = strategy.replace(value, e);
|
||||
if (typeof newSubstr !== 'undefined') {
|
||||
if ($.isArray(newSubstr)) {
|
||||
post = newSubstr[1] + post;
|
||||
newSubstr = newSubstr[0];
|
||||
}
|
||||
pre = pre.replace(strategy.match, newSubstr);
|
||||
this.$el.val(pre + post);
|
||||
this.el.focus();
|
||||
var range = this.el.createTextRange();
|
||||
range.collapse(true);
|
||||
range.moveEnd('character', pre.length);
|
||||
range.moveStart('character', pre.length);
|
||||
range.select();
|
||||
}
|
||||
pre = pre.replace(strategy.match, newSubstr);
|
||||
this.$el.val(pre + post);
|
||||
this.el.focus();
|
||||
var range = this.el.createTextRange();
|
||||
range.collapse(true);
|
||||
range.moveEnd('character', pre.length);
|
||||
range.moveStart('character', pre.length);
|
||||
range.select();
|
||||
},
|
||||
|
||||
getTextFromHeadToCaret: function () {
|
||||
@ -1032,7 +1160,7 @@ if (typeof jQuery === 'undefined') {
|
||||
|
||||
// Update the content with the given value and strategy.
|
||||
// When an dropdown item is selected, it is executed.
|
||||
select: function (value, strategy) {
|
||||
select: function (value, strategy, e) {
|
||||
var pre = this.getTextFromHeadToCaret();
|
||||
var sel = window.getSelection()
|
||||
var range = sel.getRangeAt(0);
|
||||
@ -1040,20 +1168,41 @@ if (typeof jQuery === 'undefined') {
|
||||
selection.selectNodeContents(range.startContainer);
|
||||
var content = selection.toString();
|
||||
var post = content.substring(range.startOffset);
|
||||
var newSubstr = strategy.replace(value);
|
||||
if ($.isArray(newSubstr)) {
|
||||
post = newSubstr[1] + post;
|
||||
newSubstr = newSubstr[0];
|
||||
var newSubstr = strategy.replace(value, e);
|
||||
if (typeof newSubstr !== 'undefined') {
|
||||
if ($.isArray(newSubstr)) {
|
||||
post = newSubstr[1] + post;
|
||||
newSubstr = newSubstr[0];
|
||||
}
|
||||
pre = pre.replace(strategy.match, newSubstr);
|
||||
range.selectNodeContents(range.startContainer);
|
||||
range.deleteContents();
|
||||
|
||||
// create temporary elements
|
||||
var preWrapper = document.createElement("div");
|
||||
preWrapper.innerHTML = pre;
|
||||
var postWrapper = document.createElement("div");
|
||||
postWrapper.innerHTML = post;
|
||||
|
||||
// create the fragment thats inserted
|
||||
var fragment = document.createDocumentFragment();
|
||||
var childNode;
|
||||
var lastOfPre;
|
||||
while (childNode = preWrapper.firstChild) {
|
||||
lastOfPre = fragment.appendChild(childNode);
|
||||
}
|
||||
while (childNode = postWrapper.firstChild) {
|
||||
fragment.appendChild(childNode);
|
||||
}
|
||||
|
||||
// insert the fragment & jump behind the last node in "pre"
|
||||
range.insertNode(fragment);
|
||||
range.setStartAfter(lastOfPre);
|
||||
|
||||
range.collapse(true);
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
}
|
||||
pre = pre.replace(strategy.match, newSubstr);
|
||||
range.selectNodeContents(range.startContainer);
|
||||
range.deleteContents();
|
||||
var node = document.createTextNode(pre + post);
|
||||
range.insertNode(node);
|
||||
range.setStart(node, pre.length);
|
||||
range.collapse(true);
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
},
|
||||
|
||||
// Private methods
|
||||
@ -1079,8 +1228,7 @@ if (typeof jQuery === 'undefined') {
|
||||
position.left -= this.$el.offset().left;
|
||||
position.top += $node.height() - this.$el.offset().top;
|
||||
position.lineHeight = $node.height();
|
||||
var dir = this.$el.attr('dir') || this.$el.css('direction');
|
||||
if (dir === 'rtl') { position.left -= this.listView.$el.width(); }
|
||||
$node.remove();
|
||||
return position;
|
||||
},
|
||||
|
||||
@ -1102,3 +1250,152 @@ if (typeof jQuery === 'undefined') {
|
||||
|
||||
$.fn.textcomplete.ContentEditable = ContentEditable;
|
||||
}(jQuery);
|
||||
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 Jonathan Ong me@jongleberry.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
// associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
// including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// https://github.com/component/textarea-caret-position
|
||||
|
||||
(function ($) {
|
||||
|
||||
// The properties that we copy into a mirrored div.
|
||||
// Note that some browsers, such as Firefox,
|
||||
// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,
|
||||
// so we have to do every single property specifically.
|
||||
var properties = [
|
||||
'direction', // RTL support
|
||||
'boxSizing',
|
||||
'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does
|
||||
'height',
|
||||
'overflowX',
|
||||
'overflowY', // copy the scrollbar for IE
|
||||
|
||||
'borderTopWidth',
|
||||
'borderRightWidth',
|
||||
'borderBottomWidth',
|
||||
'borderLeftWidth',
|
||||
'borderStyle',
|
||||
|
||||
'paddingTop',
|
||||
'paddingRight',
|
||||
'paddingBottom',
|
||||
'paddingLeft',
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/font
|
||||
'fontStyle',
|
||||
'fontVariant',
|
||||
'fontWeight',
|
||||
'fontStretch',
|
||||
'fontSize',
|
||||
'fontSizeAdjust',
|
||||
'lineHeight',
|
||||
'fontFamily',
|
||||
|
||||
'textAlign',
|
||||
'textTransform',
|
||||
'textIndent',
|
||||
'textDecoration', // might not make a difference, but better be safe
|
||||
|
||||
'letterSpacing',
|
||||
'wordSpacing',
|
||||
|
||||
'tabSize',
|
||||
'MozTabSize'
|
||||
|
||||
];
|
||||
|
||||
var isBrowser = (typeof window !== 'undefined');
|
||||
var isFirefox = (isBrowser && window.mozInnerScreenX != null);
|
||||
|
||||
function getCaretCoordinates(element, position, options) {
|
||||
if(!isBrowser) {
|
||||
throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');
|
||||
}
|
||||
|
||||
var debug = options && options.debug || false;
|
||||
if (debug) {
|
||||
var el = document.querySelector('#input-textarea-caret-position-mirror-div');
|
||||
if ( el ) { el.parentNode.removeChild(el); }
|
||||
}
|
||||
|
||||
// mirrored div
|
||||
var div = document.createElement('div');
|
||||
div.id = 'input-textarea-caret-position-mirror-div';
|
||||
document.body.appendChild(div);
|
||||
|
||||
var style = div.style;
|
||||
var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9
|
||||
|
||||
// default textarea styles
|
||||
style.whiteSpace = 'pre-wrap';
|
||||
if (element.nodeName !== 'INPUT')
|
||||
style.wordWrap = 'break-word'; // only for textarea-s
|
||||
|
||||
// position off-screen
|
||||
style.position = 'absolute'; // required to return coordinates properly
|
||||
if (!debug)
|
||||
style.visibility = 'hidden'; // not 'display: none' because we want rendering
|
||||
|
||||
// transfer the element's properties to the div
|
||||
properties.forEach(function (prop) {
|
||||
style[prop] = computed[prop];
|
||||
});
|
||||
|
||||
if (isFirefox) {
|
||||
// Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
|
||||
if (element.scrollHeight > parseInt(computed.height))
|
||||
style.overflowY = 'scroll';
|
||||
} else {
|
||||
style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
|
||||
}
|
||||
|
||||
div.textContent = element.value.substring(0, position);
|
||||
// the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
|
||||
if (element.nodeName === 'INPUT')
|
||||
div.textContent = div.textContent.replace(/\s/g, '\u00a0');
|
||||
|
||||
var span = document.createElement('span');
|
||||
// Wrapping must be replicated *exactly*, including when a long word gets
|
||||
// onto the next line, with whitespace at the end of the line before (#7).
|
||||
// The *only* reliable way to do that is to copy the *entire* rest of the
|
||||
// textarea's content into the <span> created at the caret position.
|
||||
// for inputs, just '.' would be enough, but why bother?
|
||||
span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all
|
||||
div.appendChild(span);
|
||||
|
||||
var coordinates = {
|
||||
top: span.offsetTop + parseInt(computed['borderTopWidth']),
|
||||
left: span.offsetLeft + parseInt(computed['borderLeftWidth'])
|
||||
};
|
||||
|
||||
if (debug) {
|
||||
span.style.backgroundColor = '#aaa';
|
||||
} else {
|
||||
document.body.removeChild(div);
|
||||
}
|
||||
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
$.fn.textcomplete.getCaretCoordinates = getCaretCoordinates;
|
||||
|
||||
}(jQuery));
|
||||
|
||||
return jQuery;
|
||||
}));
|
||||
|
3
library/jquery-textcomplete/jquery.textcomplete.min.js
vendored
Normal file
3
library/jquery-textcomplete/jquery.textcomplete.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -443,6 +443,32 @@ function NavUpdate() {
|
||||
timer = setTimeout(NavUpdate, updateInterval);
|
||||
}
|
||||
|
||||
function contextualHelp() {
|
||||
var container = $("#contextual-help-content");
|
||||
|
||||
if(container.hasClass('contextual-help-content-open')) {
|
||||
container.removeClass('contextual-help-content-open');
|
||||
$('main').css('top', '')
|
||||
}
|
||||
else {
|
||||
container.addClass('contextual-help-content-open');
|
||||
var mainTop = container.outerHeight(true);
|
||||
$('main').css('top', mainTop + 'px');
|
||||
}
|
||||
}
|
||||
|
||||
function contextualHelpFocus(target, openSidePanel) {
|
||||
if (openSidePanel) {
|
||||
$("main").addClass('region_1-on'); // Open the side panel to highlight element
|
||||
}
|
||||
else {
|
||||
$("main").removeClass('region_1-on');
|
||||
}
|
||||
$('html,body').animate({ scrollTop: $(target).offset().top - $('nav').outerHeight(true) - $('#contextual-help-content').outerHeight(true)}, 'slow');
|
||||
for (i = 0; i < 3; i++) {
|
||||
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
function updatePageItems(mode, data) {
|
||||
|
||||
|
@ -21,7 +21,7 @@ head_add_js('spin.js');
|
||||
head_add_js('jquery.spin.js');
|
||||
head_add_js('jquery.textinputs.js');
|
||||
head_add_js('autocomplete.js');
|
||||
head_add_js('library/jquery-textcomplete/jquery.textcomplete.js');
|
||||
head_add_js('library/jquery-textcomplete/jquery.textcomplete.min.js');
|
||||
//head_add_js('library/colorbox/jquery.colorbox.js');
|
||||
head_add_js('library/jquery.timeago.js');
|
||||
head_add_js('library/readmore.js/readmore.js');
|
||||
|
@ -56,4 +56,8 @@
|
||||
top: 30px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.contextual-help-content-open {
|
||||
top: 32px;
|
||||
}
|
||||
}
|
||||
|
@ -201,29 +201,26 @@ header #banner #logo-text {
|
||||
}
|
||||
|
||||
/* contextual help */
|
||||
.help-content {
|
||||
background: $comment_item_colour;
|
||||
color: $font_colour;
|
||||
position: fixed;
|
||||
top: -50%;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
max-height: 50%;
|
||||
padding: 20px;
|
||||
/*transition: top 300ms cubic-bezier(0.17, 0.04, 0.03, 0.94);*/
|
||||
border-bottom: #CCC 1px solid;
|
||||
overflow: auto;
|
||||
.contextual-help-content {
|
||||
display: none;
|
||||
|
||||
}
|
||||
|
||||
.help-content-open {
|
||||
.contextual-help-content-open {
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 51px;
|
||||
max-height: 50%;
|
||||
background: $comment_item_colour;
|
||||
padding: 20px;
|
||||
border-bottom: #ccc 1px solid;
|
||||
overflow: auto;
|
||||
-moz-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
|
||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
|
||||
/*transition: top 300ms cubic-bezier(0.17, 0.04, 0.03, 0.94);*/
|
||||
}
|
||||
|
||||
.help-content dd {
|
||||
.contextual-help-content dd {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
/* contextual help end */
|
||||
@ -1608,6 +1605,7 @@ nav ul li .notify-unseen
|
||||
}
|
||||
|
||||
blockquote {
|
||||
display: inline-block;
|
||||
font-size: $font_size;
|
||||
font-style: italic;
|
||||
border-left: 3px solid #ccc;
|
||||
@ -1703,10 +1701,9 @@ nav .badge.mail-update:hover {
|
||||
|
||||
#expand-aside,
|
||||
#expand-tabs,
|
||||
#help_nav_btn_collapsed {
|
||||
#context-help-btn {
|
||||
color: $nav_active_icon_colour;
|
||||
padding: 7px 10px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-tabs.nav-justified {
|
||||
|
@ -11,9 +11,11 @@
|
||||
<button id="expand-aside" type="button" class="navbar-toggle" data-toggle="offcanvas" data-target="#region_1">
|
||||
<i class="icon-circle-arrow-right" id="expand-aside-icon"></i>
|
||||
</button>
|
||||
<a class="navbar-toggle" target="hubzilla-help" href="{{$nav.help.0}}" title="{{$nav.help.3}}" id="{{$nav.help.4}}_collapsed"{{if $nav.help.6}} onclick="return false;"{{/if}}>
|
||||
{{if $nav.help.6}}<i class="icon-question-sign"></i>{{else}}<i class="icon-question"></i>{{/if}}
|
||||
</a>
|
||||
{{if $nav.help.6}}
|
||||
<button id="context-help-btn"class="navbar-toggle" type="button" onclick="contextualHelp(); return false;">
|
||||
<i class="icon-question-sign"></i>
|
||||
</button>
|
||||
{{/if}}
|
||||
{{if $userinfo}}
|
||||
<img class="dropdown-toggle fakelink" data-toggle="dropdown" id="avatar" src="{{$userinfo.icon}}" alt="{{$userinfo.name}}"><span class="caret" id="usermenu-caret"></span>
|
||||
{{if $localuser}}
|
||||
@ -34,6 +36,10 @@
|
||||
<li role="presentation" class="divider"></li>
|
||||
<li role="presentation"><a href="{{$nav.admin.0}}" title="{{$nav.admin.3}}" role="menuitem" id="{{$nav.admin.4}}">{{$nav.admin.1}}</a></li>
|
||||
{{/if}}
|
||||
{{if $nav.help.6}}
|
||||
<li role="presentation" class="divider"></li>
|
||||
<li role="presentation"><a href="{{$nav.help.0}}" title="{{$nav.help.3}}" role="menuitem" id="{{$nav.help.4}}">{{$nav.help.1}}</a></li>
|
||||
{{/if}}
|
||||
{{if $nav.logout}}
|
||||
<li role="presentation" class="divider"></li>
|
||||
<li role="presentation"><a href="{{$nav.logout.0}}" title="{{$nav.logout.3}}" role="menuitem" id="{{$nav.logout.4}}">{{$nav.logout.1}}</a></li>
|
||||
@ -191,16 +197,16 @@
|
||||
{{/if}}
|
||||
|
||||
{{if $nav.help}}
|
||||
<li class="{{$sel.help}} hidden-xs">
|
||||
<a class="{{$nav.help.2}}" target="hubzilla-help" href="{{$nav.help.0}}" title="{{$nav.help.3}}" id="{{$nav.help.4}}"{{if $nav.help.6}} onclick="return false;"{{/if}}>{{if $nav.help.6}}<i class="icon-question-sign"></i>{{else}}<i class="icon-question"></i>{{/if}}</a>
|
||||
<li class="{{$sel.help}}{{if $nav.help.6}} hidden-xs{{/if}}">
|
||||
<a class="{{$nav.help.2}}" target="hubzilla-help" href="{{$nav.help.0}}" title="{{$nav.help.3}}" id="{{$nav.help.4}}"{{if $nav.help.6}} onclick="contextualHelp(); return false;"{{/if}}>{{if $nav.help.6}}<i class="icon-question-sign"></i>{{else}}<i class="icon-question"></i>{{/if}}</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{if $nav.help.6}}
|
||||
<div id="help-content" class="help-content">
|
||||
<div id="contextual-help-content" class="contextual-help-content">
|
||||
{{$nav.help.5}}
|
||||
<p class="pull-right"><a href="{{$nav.help.0}}">Click here for more documentation...</a></p>
|
||||
<button type="button" class="close" onclick="contextualHelp();">×</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
@ -1,49 +0,0 @@
|
||||
<script>
|
||||
/* contextual help */
|
||||
{{if $enable_context_help}}
|
||||
$('.help-content').css('top', '-' + $('#help-content').height() + 'px')
|
||||
$(document).mouseup(function (e)
|
||||
{
|
||||
e.preventDefault;
|
||||
|
||||
var container = $("#help-content");
|
||||
|
||||
if ((!container.is(e.target) // if the target of the click isn't the container...
|
||||
&& container.has(e.target).length === 0 // ... nor a descendant of the container
|
||||
&& container.hasClass('help-content-open'))
|
||||
||
|
||||
(
|
||||
($('#help_nav_btn, #help_nav_btn_collapsed').is(e.target) || $('#help_nav_btn, #help_nav_btn_collapsed').has(e.target).length !== 0)
|
||||
&& container.hasClass('help-content-open')
|
||||
)) {
|
||||
container.removeClass('help-content-open');
|
||||
$('main').removeClass('help-content-open');
|
||||
$('main').css('top', '')
|
||||
}
|
||||
else if (($('#help_nav_btn, #help_nav_btn_collapsed').is(e.target) || $('#help_nav_btn, #help_nav_btn_collapsed').has(e.target).length !== 0)
|
||||
&& !container.hasClass('help-content-open')) {
|
||||
$('#help-content').addClass('help-content-open');
|
||||
$('main').removeClass('help-content-open');
|
||||
var mainTop = $('#navbar-collapse-1').height();
|
||||
if ($('#navbar-collapse-1').outerHeight(true) < $('#help-content').height()) {
|
||||
mainTop = $('#help-content').outerHeight(true);
|
||||
}
|
||||
|
||||
$('main').css('top', mainTop + 'px');
|
||||
}
|
||||
|
||||
});
|
||||
{{/if}}
|
||||
var contextualHelpFocus = function (target, openSidePanel) {
|
||||
if (openSidePanel) {
|
||||
$("main").addClass('region_1-on'); // Open the side panel to highlight element
|
||||
} else {
|
||||
$("main").removeClass('region_1-on');
|
||||
}
|
||||
// Animate the page scroll to the element and then pulse the element to direct attention
|
||||
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - $('#help-content').height() - 50}, 'slow');
|
||||
for (i = 0; i < 3; i++) {
|
||||
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
|
||||
}
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user