diff --git a/application/nicewebpage.class.inc.php b/application/nicewebpage.class.inc.php
index f940ac17d..4dc6d0c13 100644
--- a/application/nicewebpage.class.inc.php
+++ b/application/nicewebpage.class.inc.php
@@ -41,6 +41,7 @@ class NiceWebPage extends WebPage
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-migrate-1.4.1.min.js'); // Needed since many other plugins still rely on oldies like $.browser
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/ui-lightness/jquery-ui-1.11.4.custom.css');
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-ui-1.11.4.custom.min.js');
+ $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/utils.js');
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/hovertip.js');
// table sorting
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.tablesorter.js');
diff --git a/application/webpage.class.inc.php b/application/webpage.class.inc.php
index e0c01d997..018d57251 100644
--- a/application/webpage.class.inc.php
+++ b/application/webpage.class.inc.php
@@ -58,6 +58,7 @@ class WebPage implements Page
protected $s_deferred_content;
protected $a_scripts;
protected $a_dict_entries;
+ protected $a_dict_entries_prefixes;
protected $a_styles;
protected $a_include_scripts;
protected $a_include_stylesheets;
@@ -80,6 +81,7 @@ class WebPage implements Page
$this->s_deferred_content = '';
$this->a_scripts = array();
$this->a_dict_entries = array();
+ $this->a_dict_entries_prefixes = array();
$this->a_styles = array();
$this->a_linked_scripts = array();
$this->a_linked_stylesheets = array();
@@ -243,10 +245,39 @@ class WebPage implements Page
/**
* Add a dictionary entry for the Javascript side
*/
- public function add_dict_entry($s_entryId)
- {
- $this->a_dict_entries[$s_entryId] = Dict::S($s_entryId);
- }
+ public function add_dict_entry($s_entryId)
+ {
+ $this->a_dict_entries[] = $s_entryId;
+ }
+
+ /**
+ * Add a set of dictionary entries (based on the given prefix) for the Javascript side
+ */
+ public function add_dict_entries($s_entriesPrefix)
+ {
+ $this->a_dict_entries_prefixes[] = $s_entriesPrefix;
+ }
+
+ protected function get_dict_signature()
+ {
+ return str_replace('_', '', Dict::GetUserLanguage()).'-'.md5(implode(',', $this->a_dict_entries).'|'.implode(',', $this->a_dict_entries_prefixes));
+ }
+
+ protected function get_dict_file_content()
+ {
+ $aEntries = array();
+ foreach($this->a_dict_entries as $sCode)
+ {
+ $aEntries[$sCode] = Dict::S($sCode);
+ }
+ foreach($this->a_dict_entries_prefixes as $sPrefix)
+ {
+ $aEntries = array_merge($aEntries, Dict::ExportEntries($sPrefix));
+ }
+ $sJSFile = 'var aDictEntries = '.json_encode($aEntries);
+
+ return $sJSFile;
+ }
/**
@@ -501,6 +532,9 @@ class WebPage implements Page
echo "";
echo "
".htmlentities($this->s_title, ENT_QUOTES, 'UTF-8')."\n";
echo $this->get_base_tag();
+
+ $this->output_dict_entries();
+
foreach($this->a_linked_scripts as $s_script)
{
// Make sure that the URL to the script contains the application's version number
@@ -524,7 +558,6 @@ class WebPage implements Page
}
echo "\n";
}
- $this->output_dict_entries();
foreach($this->a_linked_stylesheets as $a_stylesheet)
{
if (strpos($a_stylesheet['link'], '?') === false)
@@ -778,36 +811,21 @@ class WebPage implements Page
protected function output_dict_entries($bReturnOutput = false)
{
- $sHtml = '';
- if (count($this->a_dict_entries)>0)
+ if ((count($this->a_dict_entries) > 0) || (count($this->a_dict_entries_prefixes) > 0))
{
- $sHtml .= "\n";
- }
-
- if ($bReturnOutput)
- {
- return $sHtml;
- }
- else
- {
- echo $sHtml;
}
}
}
diff --git a/core/dict.class.inc.php b/core/dict.class.inc.php
index 6d68757a5..e3a2a9c8e 100644
--- a/core/dict.class.inc.php
+++ b/core/dict.class.inc.php
@@ -357,5 +357,25 @@ class Dict
// No need to actually load the strings since it's only used to know the list of languages
// at setup time !!
}
+
+ /**
+ * Export all the dictionary entries - of the given language - whose code matches the given prefix
+ * @param string $sStartingWith
+ * @return string[]
+ */
+ public static function ExportEntries($sStartingWith)
+ {
+ self::InitLangIfNeeded(self::GetUserLanguage());
+ $aEntries = array();
+ $iLength = strlen($sStartingWith);
+ foreach(self::$m_aData[self::GetUserLanguage()] as $sCode => $sEntry)
+ {
+ if (substr($sCode, 0, $iLength) == $sStartingWith)
+ {
+ $aEntries[$sCode] = $sEntry;
+ }
+ }
+ return $aEntries;
+ }
}
?>
diff --git a/js/utils.js b/js/utils.js
index 957b429db..b6bd92c03 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -694,4 +694,59 @@ function DisplayHistory(sSelector, sFilter, iCount, iStart)
$(sSelector).html(data).unblock();
}
);
+}
+
+// Very simple equivalent to format: placeholders are %1$s %2$d ...
+function Format()
+{
+ var args = [];
+ var str = '';
+ if (arguments[0] instanceof Array)
+ {
+ str = arguments[0][0].toString();
+ args = arguments[0];
+ }
+ else
+ {
+ str = arguments[0].toString();
+ if (arguments.length > 1)
+ {
+ var t = typeof arguments[1];
+ args = ("string" === t || "number" === t) ? Array.prototype.slice.call(arguments) : arguments[1];
+ }
+ }
+ var key;
+ for (key in args)
+ {
+ str = str.replace(new RegExp("\\%" + key + "\\$.", "gi"), args[key]);
+ }
+
+ return str;
+}
+
+var Dict = {};
+if (aDictEntries == undefined)
+{
+ Dict._entries = {}; // Entries have not been loaded (we are in the setup ?)
+}
+else
+{
+ Dict._entries = aDictEntries; // Entries were loaded asynchronously via their own js files
+}
+Dict.S = function(sEntry)
+{
+ if (sEntry in Dict._entries)
+ {
+ return Dict._entries[sEntry];
+ }
+ else
+ {
+ return sEntry;
+ }
+};
+Dict.Format = function()
+{
+ var args = Array.from(arguments);
+ args[0] = Dict.S(arguments[0]);
+ return Format(args);
}
\ No newline at end of file
diff --git a/pages/ajax.render.php b/pages/ajax.render.php
index 4a246c570..598630070 100644
--- a/pages/ajax.render.php
+++ b/pages/ajax.render.php
@@ -2528,6 +2528,15 @@ EOF
$oPage->add(json_encode($aResult));
break;
+ case 'dict':
+ $sSignature = Utils::ReadParam('s', ''); // Sanitization prevents / and ..
+ $oPage = new ajax_page(""); // New page to cleanup the no_cache done above
+ $oPage->SetContentType('text/javascript');
+ $oPage->add_header('Cache-control: public, max-age=86400'); // Cache for 24 hours
+ $oPage->add_header("Pragma: cache"); // Reset the value set .... where ?
+ $oPage->add(file_get_contents(Utils::GetCachePath().$sSignature.'.js'));
+ break;
+
default:
$oPage->p("Invalid query.");
}