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 ( 'PLATFORM_NAME', 'hubzilla' );
|
||||||
define ( 'RED_VERSION', trim(file_get_contents('version.inc')));
|
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 ( 'ZOT_REVISION', 1 );
|
||||||
|
|
||||||
define ( 'DB_UPDATE_VERSION', 1166 );
|
define ( 'DB_UPDATE_VERSION', 1166 );
|
||||||
|
@ -143,19 +143,17 @@ EOT;
|
|||||||
if((App::$module != 'home') && (! (local_channel())))
|
if((App::$module != 'home') && (! (local_channel())))
|
||||||
$nav['home'] = array($homelink, t('Home'), "", t('Home Page'),'home_nav_btn');
|
$nav['home'] = array($homelink, t('Home'), "", t('Home Page'),'home_nav_btn');
|
||||||
|
|
||||||
|
|
||||||
if((App::$config['system']['register_policy'] == REGISTER_OPEN) && (! local_channel()) && (! remote_channel()))
|
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');
|
$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')) {
|
if(! get_config('system','hide_help')) {
|
||||||
|
$help_url = z_root() . '/help?f=&cmd=' . App::$cmd;
|
||||||
$context_help = '';
|
$context_help = '';
|
||||||
$enable_context_help = ((intval(get_config('system','enable_context_help')) === 1 || get_config('system','enable_context_help') === false) ? true : false);
|
$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) {
|
if($enable_context_help === true) {
|
||||||
require_once('include/help.php');
|
require_once('include/help.php');
|
||||||
$context_help = load_context_help();
|
$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);
|
$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);
|
$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['search'] = array('search', t('Search'), "", t('Search site @name, #tag, ?docs, content'));
|
||||||
|
|
||||||
|
|
||||||
$nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory'),'directory_nav_btn');
|
$nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory'),'directory_nav_btn');
|
||||||
|
|
||||||
|
|
||||||
@ -240,12 +237,6 @@ $powered_by = '';
|
|||||||
|
|
||||||
// $powered_by = '<strong>red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="r#" />matrix</strong>';
|
// $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');
|
$tpl = get_markup_template('nav.tpl');
|
||||||
|
|
||||||
App::$page['nav'] .= replace_macros($tpl, array(
|
App::$page['nav'] .= replace_macros($tpl, array(
|
||||||
|
@ -21,17 +21,17 @@ Smarty 3.1.28
|
|||||||
fetch() and display()
|
fetch() and display()
|
||||||
=====================
|
=====================
|
||||||
The fetch() and display() methods of the template object accept now optionally the same parameter
|
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:
|
Example:
|
||||||
$template->display(); Does display template of template object
|
$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
|
File: resource
|
||||||
==============
|
==============
|
||||||
Multiple template_dir entries can now be selected by a comma separated list of indices.
|
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)
|
The template_dir array is searched in the order of the indices. (Could be used to change the default search order)
|
||||||
Example:
|
Example:
|
||||||
$smarty->display([1],[0]foo.bar');
|
$smarty->display('[1],[0]foo.bar');
|
||||||
|
|
||||||
Filter support
|
Filter support
|
||||||
==============
|
==============
|
||||||
|
@ -1,11 +1,47 @@
|
|||||||
===== 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
|
13.12.2015
|
||||||
- bugfix {foreach} and {section} with uppercase characters in name attribute did not work (forum topic 25819)
|
- 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 $smarty->debugging_ctrl = 'URL' did not work (forum topic 25811)
|
||||||
- bugfix Debug Console could display incorrect data when using subtemplates
|
- bugfix Debug Console could display incorrect data when using subtemplates
|
||||||
|
|
||||||
09.12.2015
|
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
|
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
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
* @author Uwe Tews
|
* @author Uwe Tews
|
||||||
* @author Rodney Rehm
|
* @author Rodney Rehm
|
||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @version 3.1.28
|
* @version 3.1.29
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,7 +118,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
/**
|
/**
|
||||||
* smarty version
|
* smarty version
|
||||||
*/
|
*/
|
||||||
const SMARTY_VERSION = '3.1.28';
|
const SMARTY_VERSION = '3.1.29';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* define variable scopes
|
* define variable scopes
|
||||||
@ -677,15 +677,20 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
/**
|
/**
|
||||||
* removed properties
|
* removed properties
|
||||||
*
|
*
|
||||||
* @var array
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
private static $obsoleteProperties = array('resource_caching', 'template_resource_caching',
|
private static $obsoleteProperties = array('resource_caching', 'template_resource_caching',
|
||||||
'direct_access_security', '_dir_perms', '_file_perms',
|
'direct_access_security', '_dir_perms', '_file_perms',
|
||||||
'plugin_search_order', 'inheritance_merge_compiled_includes');
|
'plugin_search_order', 'inheritance_merge_compiled_includes');
|
||||||
|
|
||||||
private static $accessMap = array('template_dir' => 'getTemplateDir', 'config_dir' => 'getConfigDir',
|
/**
|
||||||
'plugins_dir' => 'getPluginsDir', 'compile_dir' => 'getCompileDir',
|
* List of private properties which will call getter/setter ona direct access
|
||||||
'cache_dir' => 'getCacheDir',);
|
*
|
||||||
|
* @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);
|
$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;
|
$path = getcwd() . DS . $path;
|
||||||
}
|
}
|
||||||
while ((strpos($path, '.' . DS) !== false) || (strpos($path, DS . DS) !== false)) {
|
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])) {
|
if (isset(self::$accessMap[$name])) {
|
||||||
return $this->{self::$accessMap[$name]}();
|
$method = 'get' . self::$accessMap[$name];
|
||||||
|
return $this->{$method}();
|
||||||
} elseif (in_array($name, self::$obsoleteProperties)) {
|
} elseif (in_array($name, self::$obsoleteProperties)) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@ -1363,7 +1369,8 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
public function __set($name, $value)
|
public function __set($name, $value)
|
||||||
{
|
{
|
||||||
if (isset(self::$accessMap[$name])) {
|
if (isset(self::$accessMap[$name])) {
|
||||||
$this->{self::$accessMap[$name]}($value);
|
$method = 'set' . self::$accessMap[$name];
|
||||||
|
$this->{$method}($value);
|
||||||
} elseif (in_array($name, self::$obsoleteProperties)) {
|
} elseif (in_array($name, self::$obsoleteProperties)) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,12 +215,9 @@ abstract class Smarty_CacheResource
|
|||||||
*/
|
*/
|
||||||
public function invalidLoadedCache(Smarty $smarty)
|
public function invalidLoadedCache(Smarty $smarty)
|
||||||
{
|
{
|
||||||
if (isset($smarty->_cache['template_objects'])) {
|
$smarty->_cache['isCached'] = array();
|
||||||
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
|
if (isset($smarty->ext->_subtemplate)) {
|
||||||
if (isset($tpl->cached)) {
|
$smarty->ext->_subtemplate->tplObjects = array();
|
||||||
unset ($smarty->_cache['template_objects'][$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher
|
|||||||
}
|
}
|
||||||
$compiler->suppressNocacheProcessing = true;
|
$compiler->suppressNocacheProcessing = true;
|
||||||
$compiler->has_code = 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;
|
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)
|
public static function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||||
{
|
{
|
||||||
// make all lower case
|
$tag = strtolower(trim($parameter[ 0 ], '"\''));
|
||||||
$parameter = array_map('strtolower', $parameter);
|
$name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
|
||||||
$tag = trim($parameter[0], '"\'');
|
if (!$name) {
|
||||||
if (!isset($parameter[1]) || false === $name = $compiler->getId($parameter[1])) {
|
|
||||||
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
|
$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
|
* @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
|
* 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) {
|
foreach ($saveVars as $k => $code) {
|
||||||
$output .= "{$local}{$k} = {$code}\n";
|
$output .= "{$local}{$k} = {$code}\n";
|
||||||
}
|
}
|
||||||
$output .= "{$itemVar} = new Smarty_Variable();\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 .= "{$local}total = \$_smarty_tpl->smarty->ext->_foreach->count(\$_from);\n";
|
||||||
|
}
|
||||||
|
$output .= "{$itemVar} = new Smarty_Variable();\n";
|
||||||
if (isset($itemAttr['show'])) {
|
if (isset($itemAttr['show'])) {
|
||||||
$output .= "{$itemVar}->show = ({$local}total > 0);\n";
|
$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 .= "{$foreachVar} = new Smarty_Variable({$_vars});\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$output .= "if ({$local}total) {\n";
|
|
||||||
if (isset($attributes['key'])) {
|
if (isset($attributes['key'])) {
|
||||||
$output .= "\$_smarty_tpl->tpl_vars['{$key}'] = new Smarty_Variable();\n";
|
$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) {
|
if ($needIteration) {
|
||||||
$output .= "{$local}iteration=0;\n";
|
$output .= "{$local}iteration=0;\n";
|
||||||
}
|
}
|
||||||
|
$output .= "{$itemVar}->_loop = false;\n";
|
||||||
$output .= "foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n";
|
$output .= "foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n";
|
||||||
|
$output .= "{$itemVar}->_loop = true;\n";
|
||||||
if (isset($attributes['key']) && isset($itemAttr['key'])) {
|
if (isset($attributes['key']) && isset($itemAttr['key'])) {
|
||||||
$output .= "\$_smarty_tpl->tpl_vars['{$key}']->value = {$itemVar}->key;\n";
|
$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 = "<?php\n";
|
||||||
$output .= "{$itemVar} = {$local}saved_local_item;\n";
|
$output .= "{$itemVar} = {$local}saved_local_item;\n";
|
||||||
$output .= "}\n";
|
$output .= "}\n";
|
||||||
$output .= "} else {\n?>";
|
$output .= "if (!{$itemVar}->_loop) {\n?>";
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,7 +335,6 @@ class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase
|
|||||||
|
|
||||||
if ($restore) {
|
if ($restore) {
|
||||||
$output .= "{$itemVar} = {$local}saved_local_item;\n";
|
$output .= "{$itemVar} = {$local}saved_local_item;\n";
|
||||||
$output .= "}\n";
|
|
||||||
}
|
}
|
||||||
$output .= "}\n";
|
$output .= "}\n";
|
||||||
foreach ($restoreVars as $restore) {
|
foreach ($restoreVars as $restore) {
|
||||||
|
@ -50,7 +50,7 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
|
|||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $nameProperties = array();
|
public $nameProperties = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {section} tag has no item properties
|
* {section} tag has no item properties
|
||||||
@ -112,8 +112,7 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
|
|||||||
if ($named) {
|
if ($named) {
|
||||||
$this->resultOffsets['named'] = $this->startOffset + 3;
|
$this->resultOffsets['named'] = $this->startOffset + 3;
|
||||||
$this->propertyPreg .= "([\$]smarty[.]{$this->tagName}[.]{$attributes['name']}[.](";
|
$this->propertyPreg .= "([\$]smarty[.]{$this->tagName}[.]{$attributes['name']}[.](";
|
||||||
$className = get_class($this);
|
$properties = $this->nameProperties;
|
||||||
$properties = $className::$nameProperties;
|
|
||||||
} else {
|
} else {
|
||||||
$this->resultOffsets['item'] = $this->startOffset + 3;
|
$this->resultOffsets['item'] = $this->startOffset + 3;
|
||||||
$this->propertyPreg .= "([\$]{$attributes['item']}[@](";
|
$this->propertyPreg .= "([\$]{$attributes['item']}[@](";
|
||||||
@ -204,17 +203,15 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
|
|||||||
* @return string compiled code
|
* @return string compiled code
|
||||||
* @throws \SmartyCompilerException
|
* @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 ], '"\''));
|
$tag = strtolower(trim($parameter[ 0 ], '"\''));
|
||||||
$name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
|
$name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
|
||||||
if (!$name) {
|
if (!$name) {
|
||||||
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
|
$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;
|
$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);
|
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", null, true);
|
||||||
}
|
}
|
||||||
$tagVar = "'__smarty_{$tag}_{$name}'";
|
$tagVar = "'__smarty_{$tag}_{$name}'";
|
||||||
|
@ -39,7 +39,11 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
|||||||
switch ($variable) {
|
switch ($variable) {
|
||||||
case 'foreach':
|
case 'foreach':
|
||||||
case 'section':
|
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':
|
case 'capture':
|
||||||
if (class_exists('Smarty_Internal_Compile_Capture')) {
|
if (class_exists('Smarty_Internal_Compile_Capture')) {
|
||||||
return Smarty_Internal_Compile_Capture::compileSpecialVariable(array(), $compiler, $_index);
|
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");
|
$compiler->trigger_template_error("(secure mode) super globals not permitted");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return '$_COOKIE';
|
$compiled_ref = '$_COOKIE';
|
||||||
|
break;
|
||||||
case 'get':
|
case 'get':
|
||||||
case 'post':
|
case 'post':
|
||||||
case 'env':
|
case 'env':
|
||||||
@ -80,9 +85,7 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
|||||||
return 'dirname($_smarty_tpl->source->filepath)';
|
return 'dirname($_smarty_tpl->source->filepath)';
|
||||||
|
|
||||||
case 'version':
|
case 'version':
|
||||||
$_version = Smarty::SMARTY_VERSION;
|
return "Smarty::SMARTY_VERSION";
|
||||||
|
|
||||||
return "'$_version'";
|
|
||||||
|
|
||||||
case 'const':
|
case 'const':
|
||||||
if (isset($compiler->smarty->security_policy) &&
|
if (isset($compiler->smarty->security_policy) &&
|
||||||
@ -99,22 +102,16 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
|||||||
|
|
||||||
case 'config':
|
case 'config':
|
||||||
if (isset($_index[ 2 ])) {
|
if (isset($_index[ 2 ])) {
|
||||||
return "(is_array(\$tmp = \$_smarty_tpl->smarty->ext->_config->_getConfigVariable(\$_smarty_tpl, $_index[1])) ? \$tmp[$_index[2]] : null)";
|
return "(is_array(\$tmp = \$_smarty_tpl->smarty->ext->configload->_getConfigVariable(\$_smarty_tpl, $_index[1])) ? \$tmp[$_index[2]] : null)";
|
||||||
} else {
|
} 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':
|
case 'ldelim':
|
||||||
$_ldelim = $compiler->smarty->left_delimiter;
|
return "\$_smarty_tpl->smarty->left_delimiter";
|
||||||
|
|
||||||
return "'$_ldelim'";
|
|
||||||
|
|
||||||
case 'rdelim':
|
case 'rdelim':
|
||||||
$_rdelim = $compiler->smarty->right_delimiter;
|
return "\$_smarty_tpl->smarty->right_delimiter";
|
||||||
|
|
||||||
return "'$_rdelim'";
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$compiler->trigger_template_error('$smarty.' . trim($_index[0], "'") . ' is invalid');
|
$compiler->trigger_template_error('$smarty.' . trim($_index[ 0 ], "'") . ' is not defined');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (isset($_index[ 1 ])) {
|
if (isset($_index[ 1 ])) {
|
||||||
|
@ -59,7 +59,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo
|
|||||||
*
|
*
|
||||||
* @var array
|
* @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');
|
'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
|
// maybe nocache because of nocache variables
|
||||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
$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();
|
$initNamedProperty = array();
|
||||||
$initFor = array();
|
$initFor = array();
|
||||||
$incFor = array();
|
$incFor = array();
|
||||||
|
@ -187,6 +187,21 @@ class Smarty_Internal_Data
|
|||||||
return $this->ext->getTemplateVars->getTemplateVars($this, $varName, $_ptr, $searchParents);
|
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
|
* 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;
|
$_count += @unlink((string) $_file) ? 1 : 0;
|
||||||
if (function_exists('opcache_invalidate')) {
|
if (function_exists('opcache_invalidate')) {
|
||||||
opcache_invalidate((string) $_file);
|
opcache_invalidate((string) $_file);
|
||||||
|
@ -34,10 +34,7 @@ class Smarty_Internal_Method_ClearAllCache
|
|||||||
{
|
{
|
||||||
// load cache resource and call clearAll
|
// load cache resource and call clearAll
|
||||||
$_cache_resource = Smarty_CacheResource::load($smarty, $type);
|
$_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);
|
return $_cache_resource->clearAll($smarty, $exp_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,10 +37,7 @@ class Smarty_Internal_Method_ClearCache
|
|||||||
{
|
{
|
||||||
// load cache resource and call clear
|
// load cache resource and call clear
|
||||||
$_cache_resource = Smarty_CacheResource::load($smarty, $type);
|
$_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);
|
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 ($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 ++;
|
$_count ++;
|
||||||
if (function_exists('opcache_invalidate')) {
|
if (function_exists('opcache_invalidate')) {
|
||||||
opcache_invalidate($_filepath);
|
opcache_invalidate($_filepath);
|
||||||
@ -121,11 +114,10 @@ class Smarty_Internal_Method_ClearCompiledTemplate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// clear compiled cache
|
// clear template objects cache
|
||||||
if (!isset($resource_name) && isset($smarty->_cache['source_objects'])) {
|
$smarty->_cache['isCached'] = array();
|
||||||
foreach ($smarty->_cache['source_objects'] as $source) {
|
if (isset($smarty->ext->_subtemplate)) {
|
||||||
$source->compileds = array();
|
$smarty->ext->_subtemplate->tplObjects = array();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return $_count;
|
return $_count;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ class Smarty_Internal_Method_ConfigLoad
|
|||||||
*
|
*
|
||||||
* @return mixed the value of the config variable
|
* @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;
|
$_ptr = $tpl;
|
||||||
while ($_ptr !== null) {
|
while ($_ptr !== null) {
|
||||||
|
@ -110,4 +110,15 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource
|
|||||||
{
|
{
|
||||||
return str_replace(':', '.', basename($source->filepath));
|
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 .= $functions;
|
||||||
$output .= "<?php }\n";
|
$output .= "<?php }\n";
|
||||||
// remove unneeded PHP tags
|
// 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
|
// thus rewind() and valid() methods may not be present
|
||||||
return iterator_count($value->getIterator());
|
return iterator_count($value->getIterator());
|
||||||
} elseif ($value instanceof Iterator) {
|
} elseif ($value instanceof Iterator) {
|
||||||
|
if ($value instanceof Generator) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return iterator_count($value);
|
return iterator_count($value);
|
||||||
} elseif ($value instanceof PDOStatement) {
|
} elseif ($value instanceof PDOStatement) {
|
||||||
return $value->rowCount();
|
return $value->rowCount();
|
||||||
|
@ -127,8 +127,11 @@ class Smarty_Internal_Runtime_Inheritance
|
|||||||
* - search in inheritance template hierarchy for child blocks
|
* - search in inheritance template hierarchy for child blocks
|
||||||
* if found call it, otherwise ignore
|
* if found call it, otherwise ignore
|
||||||
*
|
*
|
||||||
* $type 3 = {$smarty.block.parent}:
|
* $type 3 = {block append} {block prepend}:
|
||||||
* - get block id from parent stack and call parent block
|
* - call parent block
|
||||||
|
*
|
||||||
|
* $type 4 = {$smarty.block.parent}:
|
||||||
|
* - call parent block
|
||||||
*
|
*
|
||||||
* @param \Smarty_Internal_Template $tpl template object of caller
|
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||||
* @param int $type call type see above
|
* @param int $type call type see above
|
||||||
@ -150,6 +153,12 @@ class Smarty_Internal_Runtime_Inheritance
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($type == 3) {
|
if ($type == 3) {
|
||||||
|
if (!empty($callStack)) {
|
||||||
|
$block = array_shift($callStack);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} elseif ($type == 4) {
|
||||||
if (!empty($callStack)) {
|
if (!empty($callStack)) {
|
||||||
array_shift($callStack);
|
array_shift($callStack);
|
||||||
if (empty($callStack)) {
|
if (empty($callStack)) {
|
||||||
@ -160,6 +169,7 @@ class Smarty_Internal_Runtime_Inheritance
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
$index = 0;
|
||||||
$blockParameter = &$this->blockParameter[ $name ];
|
$blockParameter = &$this->blockParameter[ $name ];
|
||||||
if ($type == 0) {
|
if ($type == 0) {
|
||||||
$index = $block[ 2 ] = count($blockParameter);
|
$index = $block[ 2 ] = count($blockParameter);
|
||||||
@ -167,7 +177,6 @@ class Smarty_Internal_Runtime_Inheritance
|
|||||||
$callStack = array(&$block);
|
$callStack = array(&$block);
|
||||||
} elseif ($type == 1) {
|
} elseif ($type == 1) {
|
||||||
$block[ 3 ] = $callStack[ 0 ][ 3 ];
|
$block[ 3 ] = $callStack[ 0 ][ 3 ];
|
||||||
$index = 0;
|
|
||||||
for ($i = 0; $i < count($blockParameter); $i ++) {
|
for ($i = 0; $i < count($blockParameter); $i ++) {
|
||||||
if ($blockParameter[ $i ][ 3 ] <= $block[ 3 ]) {
|
if ($blockParameter[ $i ][ 3 ] <= $block[ 3 ]) {
|
||||||
$index = $blockParameter[ $i ][ 2 ];
|
$index = $blockParameter[ $i ][ 2 ];
|
||||||
@ -175,7 +184,7 @@ class Smarty_Internal_Runtime_Inheritance
|
|||||||
}
|
}
|
||||||
$block[ 2 ] = $index;
|
$block[ 2 ] = $index;
|
||||||
$callStack = array(&$block);
|
$callStack = array(&$block);
|
||||||
} else {
|
} elseif ($type == 2) {
|
||||||
$index = $callStack[ 0 ][ 2 ];
|
$index = $callStack[ 0 ][ 2 ];
|
||||||
if ($index == 0) {
|
if ($index == 0) {
|
||||||
return;
|
return;
|
||||||
@ -197,16 +206,27 @@ class Smarty_Internal_Runtime_Inheritance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->blockNesting ++;
|
$this->blockNesting ++;
|
||||||
|
// {block append} ?
|
||||||
if (isset($block[ 'append' ])) {
|
if (isset($block[ 'append' ])) {
|
||||||
$this->processBlock($tpl, 3, $name, null, $callStack);
|
$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])) {
|
if (isset($block[6])) {
|
||||||
$block[6]($tpl, $callStack);
|
$block[6]($tpl, $callStack);
|
||||||
} else {
|
} else {
|
||||||
$block[0]($tpl, $callStack);
|
$block[0]($tpl, $callStack);
|
||||||
}
|
}
|
||||||
|
// {block prepend} ?
|
||||||
if (isset($block[ 'prepend' ])) {
|
if (isset($block[ 'prepend' ])) {
|
||||||
$this->processBlock($tpl, 3, $name, null, $callStack);
|
$prependStack = $callStack;
|
||||||
|
if ($type == 0) {
|
||||||
|
array_shift($prependStack);
|
||||||
|
}
|
||||||
|
$this->processBlock($tpl, 3, $name, null, $prependStack);
|
||||||
}
|
}
|
||||||
$this->blockNesting --;
|
$this->blockNesting --;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ class Smarty_Internal_Runtime_TplFunction
|
|||||||
*
|
*
|
||||||
* @throws \SmartyException
|
* @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 (isset($tpl->tpl_function[$name])) {
|
||||||
if (!$tpl->caching || ($tpl->caching && $nocache)) {
|
if (!$tpl->caching || ($tpl->caching && $nocache)) {
|
||||||
|
@ -129,20 +129,6 @@ class Smarty_Internal_Runtime_UpdateCache
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$content = $_template->smarty->ext->_codeFrame->create($_template, $content, '', true);
|
$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);
|
return $this->write($cached, $_template, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class Smarty_Internal_Runtime_UpdateScope
|
|||||||
* @param string $varName variable name
|
* @param string $varName variable name
|
||||||
* @param int $scope scope to which bubble up variable value
|
* @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) {
|
if (!$scope && !$tpl->scope) {
|
||||||
return;
|
return;
|
||||||
|
@ -43,8 +43,13 @@ class Smarty_Internal_Runtime_ValidateCompiled
|
|||||||
} elseif ($_file_to_check[2] == 'string') {
|
} elseif ($_file_to_check[2] == 'string') {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
$source = Smarty_Template_Source::load(null, $tpl->smarty, $_file_to_check[0]);
|
$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();
|
$mtime = $source->getTimeStamp();
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!$mtime || $mtime > $_file_to_check[1]) {
|
if (!$mtime || $mtime > $_file_to_check[1]) {
|
||||||
$is_valid = false;
|
$is_valid = false;
|
||||||
|
@ -17,7 +17,7 @@ class Smarty_Internal_Runtime_Var
|
|||||||
* @param string $varName template variable name
|
* @param string $varName template variable name
|
||||||
* @param bool $nocache cache mode of variable
|
* @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])) {
|
if (!isset($tpl->tpl_vars[$varName])) {
|
||||||
$tpl->tpl_vars[$varName] = new Smarty_Variable(array(), $nocache);
|
$tpl->tpl_vars[$varName] = new Smarty_Variable(array(), $nocache);
|
||||||
|
@ -328,7 +328,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
$this->compileTemplateSource($template, $nocache,
|
$this->compileTemplateSource($template, $nocache,
|
||||||
$parent_compiler),
|
$parent_compiler),
|
||||||
$this->postFilter($this->blockOrFunctionCode) .
|
$this->postFilter($this->blockOrFunctionCode) .
|
||||||
join('', $this->mergedSubTemplatesCode), false, $this);
|
join('', $this->mergedSubTemplatesCode), false,
|
||||||
|
$this);
|
||||||
return $_compiled_code;
|
return $_compiled_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,6 +784,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
*/
|
*/
|
||||||
public function processText($text)
|
public function processText($text)
|
||||||
{
|
{
|
||||||
|
if ((string) $text != '') {
|
||||||
$store = array();
|
$store = array();
|
||||||
$_store = 0;
|
$_store = 0;
|
||||||
$_offset = 0;
|
$_offset = 0;
|
||||||
@ -810,8 +812,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
|
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
|
||||||
'#^\s+<#Ss' => '<',
|
'#^\s+<#Ss' => '<',
|
||||||
'#>\s+$#Ss' => '>',
|
'#>\s+$#Ss' => '>',
|
||||||
$this->stripRegEx => ''
|
$this->stripRegEx => '');
|
||||||
);
|
|
||||||
|
|
||||||
$text = preg_replace(array_keys($expressions), array_values($expressions), $text);
|
$text = preg_replace(array_keys($expressions), array_values($expressions), $text);
|
||||||
$_offset = 0;
|
$_offset = 0;
|
||||||
@ -830,7 +831,6 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
$text = preg_replace($this->stripRegEx, '', $text);
|
$text = preg_replace($this->stripRegEx, '', $text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($text) {
|
|
||||||
return new Smarty_Internal_ParseTree_Text($text);
|
return new Smarty_Internal_ParseTree_Text($text);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -976,7 +976,9 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
$this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found");
|
$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");
|
$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)) {
|
if (is_callable($callback)) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -240,6 +240,16 @@ abstract class Smarty_Resource
|
|||||||
return $resource->buildUniqueResourceName($smarty, $name);
|
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
|
* initialize Source Object for given resource
|
||||||
* wrapper for backward compatibility to versions < 3.1.22
|
* wrapper for backward compatibility to versions < 3.1.22
|
||||||
|
@ -79,13 +79,6 @@ abstract class Smarty_Template_Resource_Base
|
|||||||
*/
|
*/
|
||||||
public $required_plugins = array();
|
public $required_plugins = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* Known template functions
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $tpl_function = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Included subtemplates
|
* 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
|
* jQuery.textcomplete
|
||||||
*
|
*
|
||||||
@ -17,13 +30,18 @@ if (typeof jQuery === 'undefined') {
|
|||||||
if (console.warn) { console.warn(message); }
|
if (console.warn) { console.warn(message); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var id = 1;
|
||||||
|
|
||||||
$.fn.textcomplete = function (strategies, option) {
|
$.fn.textcomplete = function (strategies, option) {
|
||||||
var args = Array.prototype.slice.call(arguments);
|
var args = Array.prototype.slice.call(arguments);
|
||||||
return this.each(function () {
|
return this.each(function () {
|
||||||
|
var self = this;
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
var completer = $this.data('textComplete');
|
var completer = $this.data('textComplete');
|
||||||
if (!completer) {
|
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);
|
$this.data('textComplete', completer);
|
||||||
}
|
}
|
||||||
if (typeof strategies === 'string') {
|
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]';
|
return Object.prototype.toString.call(obj) === '[object String]';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var isFunction = function (obj) {
|
||||||
|
return Object.prototype.toString.call(obj) === '[object Function]';
|
||||||
|
};
|
||||||
|
|
||||||
var uniqueId = 0;
|
var uniqueId = 0;
|
||||||
|
|
||||||
function Completer(element, option) {
|
function Completer(element, option) {
|
||||||
@ -124,7 +149,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
this.views = [];
|
this.views = [];
|
||||||
this.option = $.extend({}, Completer._getDefaults(), option);
|
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.');
|
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) {
|
if (this.option.adapter) {
|
||||||
Adapter = this.option.adapter;
|
Adapter = this.option.adapter;
|
||||||
} else {
|
} 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';
|
viewName = typeof element.selectionEnd === 'number' ? 'Textarea' : 'IETextarea';
|
||||||
} else {
|
} else {
|
||||||
viewName = 'ContentEditable';
|
viewName = 'ContentEditable';
|
||||||
@ -192,6 +217,12 @@ if (typeof jQuery === 'undefined') {
|
|||||||
this.$el = this.adapter = this.dropdown = null;
|
this.$el = this.adapter = this.dropdown = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deactivate: function () {
|
||||||
|
if (this.dropdown) {
|
||||||
|
this.dropdown.deactivate();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Invoke textcomplete.
|
// Invoke textcomplete.
|
||||||
trigger: function (text, skipUnchangedTerm) {
|
trigger: function (text, skipUnchangedTerm) {
|
||||||
if (!this.dropdown) { this.initialize(); }
|
if (!this.dropdown) { this.initialize(); }
|
||||||
@ -200,7 +231,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
if (searchQuery.length) {
|
if (searchQuery.length) {
|
||||||
var term = searchQuery[1];
|
var term = searchQuery[1];
|
||||||
// Ignore shift-key, ctrl-key and so on.
|
// 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._term = term;
|
||||||
this._search.apply(this, searchQuery);
|
this._search.apply(this, searchQuery);
|
||||||
} else {
|
} else {
|
||||||
@ -224,8 +255,10 @@ if (typeof jQuery === 'undefined') {
|
|||||||
//
|
//
|
||||||
// value - The selected element of the array callbacked from search func.
|
// value - The selected element of the array callbacked from search func.
|
||||||
// strategy - The Strategy object.
|
// strategy - The Strategy object.
|
||||||
select: function (value, strategy) {
|
// e - Click or keydown event object.
|
||||||
this.adapter.select(value, strategy);
|
select: function (value, strategy, e) {
|
||||||
|
this._term = null;
|
||||||
|
this.adapter.select(value, strategy, e);
|
||||||
this.fire('change').fire('textComplete:select', value, strategy);
|
this.fire('change').fire('textComplete:select', value, strategy);
|
||||||
this.adapter.focus();
|
this.adapter.focus();
|
||||||
},
|
},
|
||||||
@ -248,8 +281,9 @@ if (typeof jQuery === 'undefined') {
|
|||||||
var strategy = this.strategies[i];
|
var strategy = this.strategies[i];
|
||||||
var context = strategy.context(text);
|
var context = strategy.context(text);
|
||||||
if (context || context === '') {
|
if (context || context === '') {
|
||||||
|
var matchRegexp = isFunction(strategy.match) ? strategy.match(text) : strategy.match;
|
||||||
if (isString(context)) { text = context; }
|
if (isString(context)) { text = context; }
|
||||||
var match = text.match(strategy.match);
|
var match = text.match(matchRegexp);
|
||||||
if (match) { return [strategy, match[strategy.index], match]; }
|
if (match) { return [strategy, match[strategy.index], match]; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,14 +296,14 @@ if (typeof jQuery === 'undefined') {
|
|||||||
strategy.search(term, function (data, stillSearching) {
|
strategy.search(term, function (data, stillSearching) {
|
||||||
if (!self.dropdown.shown) {
|
if (!self.dropdown.shown) {
|
||||||
self.dropdown.activate();
|
self.dropdown.activate();
|
||||||
self.dropdown.setPosition(self.adapter.getCaretPosition());
|
|
||||||
}
|
}
|
||||||
if (self._clearAtNext) {
|
if (self._clearAtNext) {
|
||||||
// The first callback in the current lock.
|
// The first callback in the current lock.
|
||||||
self.dropdown.clear();
|
self.dropdown.clear();
|
||||||
self._clearAtNext = false;
|
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) {
|
if (!stillSearching) {
|
||||||
// The last callback in the current lock.
|
// The last callback in the current lock.
|
||||||
free();
|
free();
|
||||||
@ -284,9 +318,9 @@ if (typeof jQuery === 'undefined') {
|
|||||||
//
|
//
|
||||||
// this._zip(['a', 'b'], 's');
|
// this._zip(['a', 'b'], 's');
|
||||||
// //=> [{ value: 'a', strategy: 's' }, { value: 'b', strategy: 's' }]
|
// //=> [{ value: 'a', strategy: 's' }, { value: 'b', strategy: 's' }]
|
||||||
_zip: function (data, strategy) {
|
_zip: function (data, strategy, term) {
|
||||||
return $.map(data, function (value) {
|
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 ($) {
|
+function ($) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var $window = $(window);
|
||||||
|
|
||||||
var include = function (zippedData, datum) {
|
var include = function (zippedData, datum) {
|
||||||
var i, elem;
|
var i, elem;
|
||||||
var idProperty = datum.strategy.idProperty
|
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
|
// Dropdown view
|
||||||
// =============
|
// =============
|
||||||
|
|
||||||
@ -327,7 +373,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
//
|
//
|
||||||
// element - Textarea or contenteditable element.
|
// element - Textarea or contenteditable element.
|
||||||
function Dropdown(element, completer, option) {
|
function Dropdown(element, completer, option) {
|
||||||
this.$el = Dropdown.findOrCreateElement(option);
|
this.$el = Dropdown.createElement(option);
|
||||||
this.completer = completer;
|
this.completer = completer;
|
||||||
this.id = completer.id + 'dropdown';
|
this.id = completer.id + 'dropdown';
|
||||||
this._data = []; // zipped data.
|
this._data = []; // zipped data.
|
||||||
@ -338,7 +384,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
if (option.listPosition) { this.setPosition = option.listPosition; }
|
if (option.listPosition) { this.setPosition = option.listPosition; }
|
||||||
if (option.height) { this.$el.height(option.height); }
|
if (option.height) { this.$el.height(option.height); }
|
||||||
var self = this;
|
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]; }
|
if (option[name] != null) { self[name] = option[name]; }
|
||||||
});
|
});
|
||||||
this._bindEvents(element);
|
this._bindEvents(element);
|
||||||
@ -349,18 +395,19 @@ if (typeof jQuery === 'undefined') {
|
|||||||
// Class methods
|
// Class methods
|
||||||
// -------------
|
// -------------
|
||||||
|
|
||||||
findOrCreateElement: function (option) {
|
createElement: function (option) {
|
||||||
var $parent = option.appendTo;
|
var $parent = option.appendTo;
|
||||||
if (!($parent instanceof $)) { $parent = $($parent); }
|
if (!($parent instanceof $)) { $parent = $($parent); }
|
||||||
var $el = $parent.children('.dropdown-menu')
|
var $el = $('<ul></ul>')
|
||||||
if (!$el.length) {
|
.addClass('dropdown-menu textcomplete-dropdown')
|
||||||
$el = $('<ul class="dropdown-menu"></ul>').css({
|
.attr('id', 'textcomplete-dropdown-' + option._oid)
|
||||||
|
.css({
|
||||||
display: 'none',
|
display: 'none',
|
||||||
left: 0,
|
left: 0,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
zIndex: option.zIndex
|
zIndex: option.zIndex
|
||||||
}).appendTo($parent);
|
})
|
||||||
}
|
.appendTo($parent);
|
||||||
return $el;
|
return $el;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -391,6 +438,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
this.$el.off('.' + this.id);
|
this.$el.off('.' + this.id);
|
||||||
this.$inputEl.off('.' + this.id);
|
this.$inputEl.off('.' + this.id);
|
||||||
this.clear();
|
this.clear();
|
||||||
|
this.$el.remove();
|
||||||
this.$el = this.$inputEl = this.completer = null;
|
this.$el = this.$inputEl = this.completer = null;
|
||||||
delete dropdownViews[this.id]
|
delete dropdownViews[this.id]
|
||||||
},
|
},
|
||||||
@ -399,21 +447,29 @@ if (typeof jQuery === 'undefined') {
|
|||||||
var contentsHtml = this._buildContents(zippedData);
|
var contentsHtml = this._buildContents(zippedData);
|
||||||
var unzippedData = $.map(this.data, function (d) { return d.value; });
|
var unzippedData = $.map(this.data, function (d) { return d.value; });
|
||||||
if (this.data.length) {
|
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._renderHeader(unzippedData);
|
||||||
this._renderFooter(unzippedData);
|
this._renderFooter(unzippedData);
|
||||||
if (contentsHtml) {
|
if (contentsHtml) {
|
||||||
this._renderContents(contentsHtml);
|
this._renderContents(contentsHtml);
|
||||||
|
this._fitToBottom();
|
||||||
|
this._fitToRight();
|
||||||
this._activateIndexedItem();
|
this._activateIndexedItem();
|
||||||
}
|
}
|
||||||
this._setScroll();
|
this._setScroll();
|
||||||
|
} else if (this.noResultsMessage) {
|
||||||
|
this._renderNoResultsMessage(unzippedData);
|
||||||
} else if (this.shown) {
|
} else if (this.shown) {
|
||||||
this.deactivate();
|
this.deactivate();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setPosition: function (position) {
|
setPosition: function (pos) {
|
||||||
this.$el.css(this._applyPlacement(position));
|
|
||||||
|
|
||||||
// Make the dropdown fixed if the input is also fixed
|
// 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
|
// 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
|
// Because the same dropdown is reused behind the scenes, we need to recheck every time the dropdown is showed
|
||||||
@ -423,10 +479,13 @@ if (typeof jQuery === 'undefined') {
|
|||||||
if($(this).css('position') === 'absolute') // The element has absolute positioning, so it's all OK
|
if($(this).css('position') === 'absolute') // The element has absolute positioning, so it's all OK
|
||||||
return false;
|
return false;
|
||||||
if($(this).css('position') === 'fixed') {
|
if($(this).css('position') === 'fixed') {
|
||||||
|
pos.top -= $window.scrollTop();
|
||||||
|
pos.left -= $window.scrollLeft();
|
||||||
position = 'fixed';
|
position = 'fixed';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.$el.css(this._applyPlacement(pos));
|
||||||
this.$el.css({ position: position }); // Update positioning
|
this.$el.css({ position: position }); // Update positioning
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -436,7 +495,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
this.$el.html('');
|
this.$el.html('');
|
||||||
this.data = [];
|
this.data = [];
|
||||||
this._index = 0;
|
this._index = 0;
|
||||||
this._$header = this._$footer = null;
|
this._$header = this._$footer = this._$noResultsMessage = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
activate: function () {
|
activate: function () {
|
||||||
@ -481,19 +540,25 @@ if (typeof jQuery === 'undefined') {
|
|||||||
return e.keyCode === 34; // PAGEDOWN
|
return e.keyCode === 34; // PAGEDOWN
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isEscape: function (e) {
|
||||||
|
return e.keyCode === 27; // ESCAPE
|
||||||
|
},
|
||||||
|
|
||||||
// Private properties
|
// Private properties
|
||||||
// ------------------
|
// ------------------
|
||||||
|
|
||||||
_data: null, // Currently shown zipped data.
|
_data: null, // Currently shown zipped data.
|
||||||
_index: null,
|
_index: null,
|
||||||
_$header: null,
|
_$header: null,
|
||||||
|
_$noResultsMessage: null,
|
||||||
_$footer: null,
|
_$footer: null,
|
||||||
|
|
||||||
// Private methods
|
// Private methods
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
||||||
_bindEvents: function () {
|
_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.$el.on('mouseover.' + this.id, '.textcomplete-item', $.proxy(this._onMouseover, this));
|
||||||
this.$inputEl.on('keydown.' + this.id, $.proxy(this._onKeydown, this));
|
this.$inputEl.on('keydown.' + this.id, $.proxy(this._onKeydown, this));
|
||||||
},
|
},
|
||||||
@ -506,11 +571,16 @@ if (typeof jQuery === 'undefined') {
|
|||||||
$el = $el.closest('.textcomplete-item');
|
$el = $el.closest('.textcomplete-item');
|
||||||
}
|
}
|
||||||
var datum = this.data[parseInt($el.data('index'), 10)];
|
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;
|
var self = this;
|
||||||
// Deactive at next tick to allow other event handlers to know whether
|
// Deactive at next tick to allow other event handlers to know whether
|
||||||
// the dropdown has been shown or not.
|
// 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.
|
// Activate hovered item.
|
||||||
@ -526,21 +596,58 @@ if (typeof jQuery === 'undefined') {
|
|||||||
|
|
||||||
_onKeydown: function (e) {
|
_onKeydown: function (e) {
|
||||||
if (!this.shown) { return; }
|
if (!this.shown) { return; }
|
||||||
if (this.isUp(e)) {
|
|
||||||
|
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();
|
e.preventDefault();
|
||||||
this._up();
|
this._up();
|
||||||
} else if (this.isDown(e)) {
|
break;
|
||||||
|
case commands.KEY_DOWN:
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._down();
|
this._down();
|
||||||
} else if (this.isEnter(e)) {
|
break;
|
||||||
|
case commands.KEY_ENTER:
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._enter();
|
this._enter(e);
|
||||||
} else if (this.isPageup(e)) {
|
break;
|
||||||
|
case commands.KEY_PAGEUP:
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._pageup();
|
this._pageup();
|
||||||
} else if (this.isPagedown(e)) {
|
break;
|
||||||
|
case commands.KEY_PAGEDOWN:
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._pagedown();
|
this._pagedown();
|
||||||
|
break;
|
||||||
|
case commands.KEY_ESCAPE:
|
||||||
|
e.preventDefault();
|
||||||
|
this.deactivate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_defaultKeydown: function (e) {
|
||||||
|
if (this.isUp(e)) {
|
||||||
|
return commands.KEY_UP;
|
||||||
|
} else if (this.isDown(e)) {
|
||||||
|
return commands.KEY_DOWN;
|
||||||
|
} else if (this.isEnter(e)) {
|
||||||
|
return commands.KEY_ENTER;
|
||||||
|
} else if (this.isPageup(e)) {
|
||||||
|
return commands.KEY_PAGEUP;
|
||||||
|
} else if (this.isPagedown(e)) {
|
||||||
|
return commands.KEY_PAGEDOWN;
|
||||||
|
} else if (this.isEscape(e)) {
|
||||||
|
return commands.KEY_ESCAPE;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -564,10 +671,10 @@ if (typeof jQuery === 'undefined') {
|
|||||||
this._setScroll();
|
this._setScroll();
|
||||||
},
|
},
|
||||||
|
|
||||||
_enter: function () {
|
_enter: function (e) {
|
||||||
var datum = this.data[parseInt(this._getActiveElement().data('index'), 10)];
|
var datum = this.data[parseInt(this._getActiveElement().data('index'), 10)];
|
||||||
this.completer.select(datum.value, datum.strategy);
|
this.completer.select(datum.value, datum.strategy, e);
|
||||||
this._setScroll();
|
this.deactivate();
|
||||||
},
|
},
|
||||||
|
|
||||||
_pageup: function () {
|
_pageup: function () {
|
||||||
@ -630,7 +737,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
index = this.data.length;
|
index = this.data.length;
|
||||||
this.data.push(datum);
|
this.data.push(datum);
|
||||||
html += '<li class="textcomplete-item" data-index="' + index + '"><a>';
|
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>';
|
html += '</a></li>';
|
||||||
}
|
}
|
||||||
return html;
|
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) {
|
_renderContents: function (html) {
|
||||||
if (this._$footer) {
|
if (this._$footer) {
|
||||||
this._$footer.before(html);
|
this._$footer.before(html);
|
||||||
@ -664,6 +781,31 @@ if (typeof jQuery === 'undefined') {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_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) {
|
_applyPlacement: function (position) {
|
||||||
// If the 'placement' option set to 'top', move the position above the element.
|
// If the 'placement' option set to 'top', move the position above the element.
|
||||||
if (this.placement.indexOf('top') !== -1) {
|
if (this.placement.indexOf('top') !== -1) {
|
||||||
@ -688,6 +830,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$.fn.textcomplete.Dropdown = Dropdown;
|
$.fn.textcomplete.Dropdown = Dropdown;
|
||||||
|
$.extend($.fn.textcomplete, commands);
|
||||||
}(jQuery);
|
}(jQuery);
|
||||||
|
|
||||||
+function ($) {
|
+function ($) {
|
||||||
@ -713,9 +856,12 @@ if (typeof jQuery === 'undefined') {
|
|||||||
if (this.cache) { this.search = memoize(this.search); }
|
if (this.cache) { this.search = memoize(this.search); }
|
||||||
}
|
}
|
||||||
|
|
||||||
Strategy.parse = function (optionsArray) {
|
Strategy.parse = function (strategiesArray, params) {
|
||||||
return $.map(optionsArray, function (options) {
|
return $.map(strategiesArray, function (strategy) {
|
||||||
return new Strategy(options);
|
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,
|
search: null,
|
||||||
|
|
||||||
// Optional
|
// Optional
|
||||||
|
id: null,
|
||||||
cache: false,
|
cache: false,
|
||||||
context: function () { return true; },
|
context: function () { return true; },
|
||||||
index: 2,
|
index: 2,
|
||||||
@ -818,11 +965,19 @@ if (typeof jQuery === 'undefined') {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Returns the caret's relative coordinates from body's left top corner.
|
// 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 () {
|
getCaretPosition: function () {
|
||||||
var position = this._getCaretRelativePosition();
|
var position = this._getCaretRelativePosition();
|
||||||
var offset = this.$el.offset();
|
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.top += offset.top;
|
||||||
position.left += offset.left;
|
position.left += offset.left;
|
||||||
return position;
|
return position;
|
||||||
@ -848,6 +1003,8 @@ if (typeof jQuery === 'undefined') {
|
|||||||
// Suppress searching if it returns true.
|
// Suppress searching if it returns true.
|
||||||
_skipSearch: function (clickEvent) {
|
_skipSearch: function (clickEvent) {
|
||||||
switch (clickEvent.keyCode) {
|
switch (clickEvent.keyCode) {
|
||||||
|
case 9: // TAB
|
||||||
|
case 13: // ENTER
|
||||||
case 40: // DOWN
|
case 40: // DOWN
|
||||||
case 38: // UP
|
case 38: // UP
|
||||||
return true;
|
return true;
|
||||||
@ -874,30 +1031,16 @@ if (typeof jQuery === 'undefined') {
|
|||||||
this.initialize(element, completer, option);
|
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, {
|
$.extend(Textarea.prototype, $.fn.textcomplete.Adapter.prototype, {
|
||||||
// Public methods
|
// Public methods
|
||||||
// --------------
|
// --------------
|
||||||
|
|
||||||
// Update the textarea with the given value and strategy.
|
// Update the textarea with the given value and strategy.
|
||||||
select: function (value, strategy) {
|
select: function (value, strategy, e) {
|
||||||
var pre = this.getTextFromHeadToCaret();
|
var pre = this.getTextFromHeadToCaret();
|
||||||
var post = this.el.value.substring(this.el.selectionEnd);
|
var post = this.el.value.substring(this.el.selectionEnd);
|
||||||
var newSubstr = strategy.replace(value);
|
var newSubstr = strategy.replace(value, e);
|
||||||
|
if (typeof newSubstr !== 'undefined') {
|
||||||
if ($.isArray(newSubstr)) {
|
if ($.isArray(newSubstr)) {
|
||||||
post = newSubstr[1] + post;
|
post = newSubstr[1] + post;
|
||||||
newSubstr = newSubstr[0];
|
newSubstr = newSubstr[0];
|
||||||
@ -905,58 +1048,41 @@ if (typeof jQuery === 'undefined') {
|
|||||||
pre = pre.replace(strategy.match, newSubstr);
|
pre = pre.replace(strategy.match, newSubstr);
|
||||||
this.$el.val(pre + post);
|
this.$el.val(pre + post);
|
||||||
this.el.selectionStart = this.el.selectionEnd = pre.length;
|
this.el.selectionStart = this.el.selectionEnd = pre.length;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getTextFromHeadToCaret: function () {
|
||||||
|
return this.el.value.substring(0, this.el.selectionEnd);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Private methods
|
// 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 () {
|
_getCaretRelativePosition: function () {
|
||||||
var dummyDiv = $('<div></div>').css(this._copyCss())
|
var p = $.fn.textcomplete.getCaretCoordinates(this.el, this.el.selectionStart);
|
||||||
.text(this.getTextFromHeadToCaret());
|
return {
|
||||||
var span = $('<span></span>').text('.').appendTo(dummyDiv);
|
top: p.top + this._calculateLineHeight() - this.$el.scrollTop(),
|
||||||
this.$el.before(dummyDiv);
|
left: p.left - this.$el.scrollLeft()
|
||||||
var position = span.position();
|
};
|
||||||
position.top += span.height() - this.$el.scrollTop();
|
|
||||||
position.lineHeight = span.height();
|
|
||||||
dummyDiv.remove();
|
|
||||||
return position;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_copyCss: function () {
|
_calculateLineHeight: function () {
|
||||||
return $.extend({
|
var lineHeight = parseInt(this.$el.css('line-height'), 10);
|
||||||
// Set 'scroll' if a scrollbar is being shown; otherwise 'auto'.
|
if (isNaN(lineHeight)) {
|
||||||
overflow: this.el.scrollHeight > this.el.offsetHeight ? 'scroll' : 'auto'
|
// http://stackoverflow.com/a/4515470/1297336
|
||||||
}, Textarea.DIV_PROPERTIES, this._getStyles());
|
var parentNode = this.el.parentNode;
|
||||||
},
|
var temp = document.createElement(this.el.nodeName);
|
||||||
|
var style = this.el.style;
|
||||||
_getStyles: (function ($) {
|
temp.setAttribute(
|
||||||
var color = $('<div></div>').css(['color']).color;
|
'style',
|
||||||
if (typeof color !== 'undefined') {
|
'margin:0px;padding:0px;font-family:' + style.fontFamily + ';font-size:' + style.fontSize
|
||||||
return function () {
|
);
|
||||||
return this.$el.css(Textarea.COPY_PROPERTIES);
|
temp.innerHTML = 'test';
|
||||||
};
|
parentNode.appendChild(temp);
|
||||||
} else { // jQuery < 1.8
|
lineHeight = temp.clientHeight;
|
||||||
return function () {
|
parentNode.removeChild(temp);
|
||||||
var $el = this.$el;
|
|
||||||
var styles = {};
|
|
||||||
$.each(Textarea.COPY_PROPERTIES, function (i, property) {
|
|
||||||
styles[property] = $el.css(property);
|
|
||||||
});
|
|
||||||
return styles;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
})($),
|
return lineHeight;
|
||||||
|
|
||||||
getTextFromHeadToCaret: function () {
|
|
||||||
return this.el.value.substring(0, this.el.selectionEnd);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -981,10 +1107,11 @@ if (typeof jQuery === 'undefined') {
|
|||||||
// Public methods
|
// Public methods
|
||||||
// --------------
|
// --------------
|
||||||
|
|
||||||
select: function (value, strategy) {
|
select: function (value, strategy, e) {
|
||||||
var pre = this.getTextFromHeadToCaret();
|
var pre = this.getTextFromHeadToCaret();
|
||||||
var post = this.el.value.substring(pre.length);
|
var post = this.el.value.substring(pre.length);
|
||||||
var newSubstr = strategy.replace(value);
|
var newSubstr = strategy.replace(value, e);
|
||||||
|
if (typeof newSubstr !== 'undefined') {
|
||||||
if ($.isArray(newSubstr)) {
|
if ($.isArray(newSubstr)) {
|
||||||
post = newSubstr[1] + post;
|
post = newSubstr[1] + post;
|
||||||
newSubstr = newSubstr[0];
|
newSubstr = newSubstr[0];
|
||||||
@ -997,6 +1124,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
range.moveEnd('character', pre.length);
|
range.moveEnd('character', pre.length);
|
||||||
range.moveStart('character', pre.length);
|
range.moveStart('character', pre.length);
|
||||||
range.select();
|
range.select();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getTextFromHeadToCaret: function () {
|
getTextFromHeadToCaret: function () {
|
||||||
@ -1032,7 +1160,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
|
|
||||||
// Update the content with the given value and strategy.
|
// Update the content with the given value and strategy.
|
||||||
// When an dropdown item is selected, it is executed.
|
// When an dropdown item is selected, it is executed.
|
||||||
select: function (value, strategy) {
|
select: function (value, strategy, e) {
|
||||||
var pre = this.getTextFromHeadToCaret();
|
var pre = this.getTextFromHeadToCaret();
|
||||||
var sel = window.getSelection()
|
var sel = window.getSelection()
|
||||||
var range = sel.getRangeAt(0);
|
var range = sel.getRangeAt(0);
|
||||||
@ -1040,7 +1168,8 @@ if (typeof jQuery === 'undefined') {
|
|||||||
selection.selectNodeContents(range.startContainer);
|
selection.selectNodeContents(range.startContainer);
|
||||||
var content = selection.toString();
|
var content = selection.toString();
|
||||||
var post = content.substring(range.startOffset);
|
var post = content.substring(range.startOffset);
|
||||||
var newSubstr = strategy.replace(value);
|
var newSubstr = strategy.replace(value, e);
|
||||||
|
if (typeof newSubstr !== 'undefined') {
|
||||||
if ($.isArray(newSubstr)) {
|
if ($.isArray(newSubstr)) {
|
||||||
post = newSubstr[1] + post;
|
post = newSubstr[1] + post;
|
||||||
newSubstr = newSubstr[0];
|
newSubstr = newSubstr[0];
|
||||||
@ -1048,12 +1177,32 @@ if (typeof jQuery === 'undefined') {
|
|||||||
pre = pre.replace(strategy.match, newSubstr);
|
pre = pre.replace(strategy.match, newSubstr);
|
||||||
range.selectNodeContents(range.startContainer);
|
range.selectNodeContents(range.startContainer);
|
||||||
range.deleteContents();
|
range.deleteContents();
|
||||||
var node = document.createTextNode(pre + post);
|
|
||||||
range.insertNode(node);
|
// create temporary elements
|
||||||
range.setStart(node, pre.length);
|
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);
|
range.collapse(true);
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
sel.addRange(range);
|
sel.addRange(range);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Private methods
|
// Private methods
|
||||||
@ -1079,8 +1228,7 @@ if (typeof jQuery === 'undefined') {
|
|||||||
position.left -= this.$el.offset().left;
|
position.left -= this.$el.offset().left;
|
||||||
position.top += $node.height() - this.$el.offset().top;
|
position.top += $node.height() - this.$el.offset().top;
|
||||||
position.lineHeight = $node.height();
|
position.lineHeight = $node.height();
|
||||||
var dir = this.$el.attr('dir') || this.$el.css('direction');
|
$node.remove();
|
||||||
if (dir === 'rtl') { position.left -= this.listView.$el.width(); }
|
|
||||||
return position;
|
return position;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1102,3 +1250,152 @@ if (typeof jQuery === 'undefined') {
|
|||||||
|
|
||||||
$.fn.textcomplete.ContentEditable = ContentEditable;
|
$.fn.textcomplete.ContentEditable = ContentEditable;
|
||||||
}(jQuery);
|
}(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);
|
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) {
|
function updatePageItems(mode, data) {
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ head_add_js('spin.js');
|
|||||||
head_add_js('jquery.spin.js');
|
head_add_js('jquery.spin.js');
|
||||||
head_add_js('jquery.textinputs.js');
|
head_add_js('jquery.textinputs.js');
|
||||||
head_add_js('autocomplete.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/colorbox/jquery.colorbox.js');
|
||||||
head_add_js('library/jquery.timeago.js');
|
head_add_js('library/jquery.timeago.js');
|
||||||
head_add_js('library/readmore.js/readmore.js');
|
head_add_js('library/readmore.js/readmore.js');
|
||||||
|
@ -56,4 +56,8 @@
|
|||||||
top: 30px;
|
top: 30px;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.contextual-help-content-open {
|
||||||
|
top: 32px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,29 +201,26 @@ header #banner #logo-text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* contextual help */
|
/* contextual help */
|
||||||
.help-content {
|
.contextual-help-content {
|
||||||
background: $comment_item_colour;
|
display: none;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-content-open {
|
.contextual-help-content-open {
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
top: 51px;
|
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);
|
-moz-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
|
||||||
-webkit-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);
|
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;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
/* contextual help end */
|
/* contextual help end */
|
||||||
@ -1608,6 +1605,7 @@ nav ul li .notify-unseen
|
|||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
|
display: inline-block;
|
||||||
font-size: $font_size;
|
font-size: $font_size;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
border-left: 3px solid #ccc;
|
border-left: 3px solid #ccc;
|
||||||
@ -1703,10 +1701,9 @@ nav .badge.mail-update:hover {
|
|||||||
|
|
||||||
#expand-aside,
|
#expand-aside,
|
||||||
#expand-tabs,
|
#expand-tabs,
|
||||||
#help_nav_btn_collapsed {
|
#context-help-btn {
|
||||||
color: $nav_active_icon_colour;
|
color: $nav_active_icon_colour;
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
text-decoration: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs.nav-justified {
|
.nav-tabs.nav-justified {
|
||||||
|
@ -11,9 +11,11 @@
|
|||||||
<button id="expand-aside" type="button" class="navbar-toggle" data-toggle="offcanvas" data-target="#region_1">
|
<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>
|
<i class="icon-circle-arrow-right" id="expand-aside-icon"></i>
|
||||||
</button>
|
</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}}
|
||||||
{{if $nav.help.6}}<i class="icon-question-sign"></i>{{else}}<i class="icon-question"></i>{{/if}}
|
<button id="context-help-btn"class="navbar-toggle" type="button" onclick="contextualHelp(); return false;">
|
||||||
</a>
|
<i class="icon-question-sign"></i>
|
||||||
|
</button>
|
||||||
|
{{/if}}
|
||||||
{{if $userinfo}}
|
{{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>
|
<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}}
|
{{if $localuser}}
|
||||||
@ -34,6 +36,10 @@
|
|||||||
<li role="presentation" class="divider"></li>
|
<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>
|
<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}}
|
||||||
|
{{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}}
|
{{if $nav.logout}}
|
||||||
<li role="presentation" class="divider"></li>
|
<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>
|
<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}}
|
||||||
|
|
||||||
{{if $nav.help}}
|
{{if $nav.help}}
|
||||||
<li class="{{$sel.help}} hidden-xs">
|
<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="return false;"{{/if}}>{{if $nav.help.6}}<i class="icon-question-sign"></i>{{else}}<i class="icon-question"></i>{{/if}}</a>
|
<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>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{if $nav.help.6}}
|
{{if $nav.help.6}}
|
||||||
<div id="help-content" class="help-content">
|
<div id="contextual-help-content" class="contextual-help-content">
|
||||||
{{$nav.help.5}}
|
{{$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>
|
</div>
|
||||||
{{/if}}
|
{{/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