Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added CodeMirror; application folder refactor

  • Loading branch information...
commit ab09dcc4f1f6117da54148f9ff2bdf5dc2009acc 1 parent 49d9511
@benkeen authored
Showing with 32,855 additions and 15 deletions.
  1. +1 −2  classes/Core.class.php
  2. +1 −1  classes/Language.class.php
  3. +1 −1  classes/Translations.class.php
  4. +8 −6 classes/Utils.class.php
  5. +9 −0 docs/contribute.php
  6. +18 −0 docs/countryData.php
  7. +405 −0 docs/dataTypes.php
  8. +388 −0 docs/exportTypes.php
  9. +2 −2 docs/templates/footer.php
  10. +24 −0 docs/thanks.php
  11. +2 −1  index.php
  12. +1 −1  install.php
  13. +1 −1  library.php
  14. +2 −0  libs/codemirror/.gitignore
  15. +3 −0  libs/codemirror/.travis.yml
  16. +23 −0 libs/codemirror/LICENSE
  17. +472 −0 libs/codemirror/index.html
  18. +29 −0 libs/codemirror/keymap/emacs.js
  19. +789 −0 libs/codemirror/keymap/vim.js
  20. +173 −0 libs/codemirror/lib/codemirror.css
  21. +3,143 −0 libs/codemirror/lib/codemirror.js
  22. +164 −0 libs/codemirror/lib/util/closetag.js
  23. +27 −0 libs/codemirror/lib/util/dialog.css
  24. +70 −0 libs/codemirror/lib/util/dialog.js
  25. +196 −0 libs/codemirror/lib/util/foldcode.js
  26. +193 −0 libs/codemirror/lib/util/formatting.js
  27. +134 −0 libs/codemirror/lib/util/javascript-hint.js
  28. +51 −0 libs/codemirror/lib/util/loadmode.js
  29. +44 −0 libs/codemirror/lib/util/match-highlighter.js
  30. +77 −0 libs/codemirror/lib/util/multiplex.js
  31. +54 −0 libs/codemirror/lib/util/overlay.js
  32. +123 −0 libs/codemirror/lib/util/pig-hint.js
  33. +90 −0 libs/codemirror/lib/util/runmode-standalone.js
  34. +53 −0 libs/codemirror/lib/util/runmode.js
  35. +118 −0 libs/codemirror/lib/util/search.js
  36. +119 −0 libs/codemirror/lib/util/searchcursor.js
  37. +16 −0 libs/codemirror/lib/util/simple-hint.css
  38. +97 −0 libs/codemirror/lib/util/simple-hint.js
  39. +137 −0 libs/codemirror/lib/util/xml-hint.js
  40. +284 −0 libs/codemirror/mode/clike/clike.js
  41. +102 −0 libs/codemirror/mode/clike/index.html
  42. +766 −0 libs/codemirror/mode/clike/scala.html
  43. +206 −0 libs/codemirror/mode/clojure/clojure.js
  44. +67 −0 libs/codemirror/mode/clojure/index.html
  45. +22 −0 libs/codemirror/mode/coffeescript/LICENSE
  46. +346 −0 libs/codemirror/mode/coffeescript/coffeescript.js
  47. +728 −0 libs/codemirror/mode/coffeescript/index.html
  48. +101 −0 libs/codemirror/mode/commonlisp/commonlisp.js
  49. +165 −0 libs/codemirror/mode/commonlisp/index.html
  50. +448 −0 libs/codemirror/mode/css/css.js
  51. +58 −0 libs/codemirror/mode/css/index.html
  52. +501 −0 libs/codemirror/mode/css/test.js
  53. +32 −0 libs/codemirror/mode/diff/diff.js
  54. +105 −0 libs/codemirror/mode/diff/index.html
  55. +203 −0 libs/codemirror/mode/ecl/ecl.js
  56. +42 −0 libs/codemirror/mode/ecl/index.html
  57. +463 −0 libs/codemirror/mode/erlang/erlang.js
  58. +63 −0 libs/codemirror/mode/erlang/index.html
  59. +150 −0 libs/codemirror/mode/gfm/gfm.js
  60. +48 −0 libs/codemirror/mode/gfm/index.html
  61. +170 −0 libs/codemirror/mode/go/go.js
  62. +73 −0 libs/codemirror/mode/go/index.html
  63. +210 −0 libs/codemirror/mode/groovy/groovy.js
  64. +72 −0 libs/codemirror/mode/groovy/index.html
  65. +242 −0 libs/codemirror/mode/haskell/haskell.js
  66. +61 −0 libs/codemirror/mode/haskell/index.html
  67. +429 −0 libs/codemirror/mode/haxe/haxe.js
  68. +91 −0 libs/codemirror/mode/haxe/index.html
  69. +72 −0 libs/codemirror/mode/htmlembedded/htmlembedded.js
  70. +50 −0 libs/codemirror/mode/htmlembedded/index.html
  71. +84 −0 libs/codemirror/mode/htmlmixed/htmlmixed.js
  72. +52 −0 libs/codemirror/mode/htmlmixed/index.html
  73. +78 −0 libs/codemirror/mode/javascript/index.html
  74. +361 −0 libs/codemirror/mode/javascript/javascript.js
  75. +38 −0 libs/codemirror/mode/jinja2/index.html
  76. +42 −0 libs/codemirror/mode/jinja2/jinja2.js
  77. +740 −0 libs/codemirror/mode/less/index.html
  78. +266 −0 libs/codemirror/mode/less/less.js
  79. +73 −0 libs/codemirror/mode/lua/index.html
  80. +140 −0 libs/codemirror/mode/lua/lua.js
  81. +343 −0 libs/codemirror/mode/markdown/index.html
  82. +382 −0 libs/codemirror/mode/markdown/markdown.js
  83. +1,084 −0 libs/codemirror/mode/markdown/test.js
  84. +42 −0 libs/codemirror/mode/mysql/index.html
  85. +186 −0 libs/codemirror/mode/mysql/mysql.js
  86. +33 −0 libs/codemirror/mode/ntriples/index.html
  87. +172 −0 libs/codemirror/mode/ntriples/ntriples.js
  88. +130 −0 libs/codemirror/mode/ocaml/index.html
  89. +114 −0 libs/codemirror/mode/ocaml/ocaml.js
  90. +7 −0 libs/codemirror/mode/pascal/LICENSE
  91. +49 −0 libs/codemirror/mode/pascal/index.html
  92. +94 −0 libs/codemirror/mode/pascal/pascal.js
  93. +19 −0 libs/codemirror/mode/perl/LICENSE
  94. +63 −0 libs/codemirror/mode/perl/index.html
  95. +816 −0 libs/codemirror/mode/perl/perl.js
  96. +49 −0 libs/codemirror/mode/php/index.html
  97. +148 −0 libs/codemirror/mode/php/php.js
  98. +43 −0 libs/codemirror/mode/pig/index.html
  99. +172 −0 libs/codemirror/mode/pig/pig.js
  100. +63 −0 libs/codemirror/mode/plsql/index.html
  101. +217 −0 libs/codemirror/mode/plsql/plsql.js
  102. +41 −0 libs/codemirror/mode/properties/index.html
  103. +63 −0 libs/codemirror/mode/properties/properties.js
  104. +21 −0 libs/codemirror/mode/python/LICENSE.txt
  105. +123 −0 libs/codemirror/mode/python/index.html
  106. +338 −0 libs/codemirror/mode/python/python.js
  107. +24 −0 libs/codemirror/mode/r/LICENSE
  108. +74 −0 libs/codemirror/mode/r/index.html
  109. +141 −0 libs/codemirror/mode/r/r.js
  110. +19 −0 libs/codemirror/mode/rpm/changes/changes.js
  111. +54 −0 libs/codemirror/mode/rpm/changes/index.html
  112. +100 −0 libs/codemirror/mode/rpm/spec/index.html
  113. +5 −0 libs/codemirror/mode/rpm/spec/spec.css
  114. +66 −0 libs/codemirror/mode/rpm/spec/spec.js
  115. +526 −0 libs/codemirror/mode/rst/index.html
  116. +326 −0 libs/codemirror/mode/rst/rst.js
  117. +24 −0 libs/codemirror/mode/ruby/LICENSE
  118. +172 −0 libs/codemirror/mode/ruby/index.html
  119. +195 −0 libs/codemirror/mode/ruby/ruby.js
  120. +49 −0 libs/codemirror/mode/rust/index.html
  121. +432 −0 libs/codemirror/mode/rust/rust.js
  122. +65 −0 libs/codemirror/mode/scheme/index.html
  123. +230 −0 libs/codemirror/mode/scheme/scheme.js
  124. +50 −0 libs/codemirror/mode/shell/index.html
  125. +118 −0 libs/codemirror/mode/shell/shell.js
  126. +23 −0 libs/codemirror/mode/sieve/LICENSE
  127. +81 −0 libs/codemirror/mode/sieve/index.html
  128. +156 −0 libs/codemirror/mode/sieve/sieve.js
  129. +56 −0 libs/codemirror/mode/smalltalk/index.html
  130. +139 −0 libs/codemirror/mode/smalltalk/smalltalk.js
  131. +83 −0 libs/codemirror/mode/smarty/index.html
  132. +148 −0 libs/codemirror/mode/smarty/smarty.js
  133. +41 −0 libs/codemirror/mode/sparql/index.html
  134. +143 −0 libs/codemirror/mode/sparql/sparql.js
  135. +98 −0 libs/codemirror/mode/stex/index.html
  136. +182 −0 libs/codemirror/mode/stex/stex.js
  137. +343 −0 libs/codemirror/mode/stex/test.js
  138. +141 −0 libs/codemirror/mode/tiddlywiki/index.html
  139. +14 −0 libs/codemirror/mode/tiddlywiki/tiddlywiki.css
  140. +384 −0 libs/codemirror/mode/tiddlywiki/tiddlywiki.js
  141. +83 −0 libs/codemirror/mode/tiki/index.html
  142. +26 −0 libs/codemirror/mode/tiki/tiki.css
  143. +309 −0 libs/codemirror/mode/tiki/tiki.js
  144. +21 −0 libs/codemirror/mode/vb/LICENSE.txt
  145. +89 −0 libs/codemirror/mode/vb/index.html
  146. +260 −0 libs/codemirror/mode/vb/vb.js
  147. +43 −0 libs/codemirror/mode/vbscript/index.html
  148. +26 −0 libs/codemirror/mode/vbscript/vbscript.js
  149. +104 −0 libs/codemirror/mode/velocity/index.html
  150. +146 −0 libs/codemirror/mode/velocity/velocity.js
  151. +211 −0 libs/codemirror/mode/verilog/index.html
  152. +194 −0 libs/codemirror/mode/verilog/verilog.js
  153. +45 −0 libs/codemirror/mode/xml/index.html
  154. +318 −0 libs/codemirror/mode/xml/xml.js
  155. +20 −0 libs/codemirror/mode/xquery/LICENSE
  156. +223 −0 libs/codemirror/mode/xquery/index.html
  157. +27 −0 libs/codemirror/mode/xquery/test/index.html
  158. +42 −0 libs/codemirror/mode/xquery/test/testBase.js
  159. +16 −0 libs/codemirror/mode/xquery/test/testEmptySequenceKeyword.js
  160. +16 −0 libs/codemirror/mode/xquery/test/testMultiAttr.js
  161. +91 −0 libs/codemirror/mode/xquery/test/testNamespaces.js
  162. +16 −0 libs/codemirror/mode/xquery/test/testProcessingInstructions.js
  163. +19 −0 libs/codemirror/mode/xquery/test/testQuotes.js
  164. +451 −0 libs/codemirror/mode/xquery/xquery.js
  165. +68 −0 libs/codemirror/mode/yaml/index.html
  166. +95 −0 libs/codemirror/mode/yaml/yaml.js
  167. +81 −0 libs/codemirror/theme/ambiance.css
  168. +25 −0 libs/codemirror/theme/blackboard.css
  169. +18 −0 libs/codemirror/theme/cobalt.css
  170. +25 −0 libs/codemirror/theme/eclipse.css
  171. +10 −0 libs/codemirror/theme/elegant.css
  172. +21 −0 libs/codemirror/theme/erlang-dark.css
  173. +44 −0 libs/codemirror/theme/lesser-dark.css
  174. +28 −0 libs/codemirror/theme/monokai.css
  175. +9 −0 libs/codemirror/theme/neat.css
  176. +21 −0 libs/codemirror/theme/night.css
  177. +21 −0 libs/codemirror/theme/rubyblue.css
  178. +27 −0 libs/codemirror/theme/vibrant-ink.css
  179. +46 −0 libs/codemirror/theme/xq-dark.css
  180. +1,510 −0 libs/smarty/Smarty.class.php
  181. +460 −0 libs/smarty/SmartyBC.class.php
  182. +133 −0 libs/smarty/debug.tpl
  183. +1 −0  libs/smarty/eval.tpl
  184. +113 −0 libs/smarty/plugins/block.textformat.php
  185. +78 −0 libs/smarty/plugins/function.counter.php
  186. +38 −0 libs/smarty/plugins/function.country_list.php
  187. +106 −0 libs/smarty/plugins/function.cycle.php
  188. +27 −0 libs/smarty/plugins/function.data_type_resources.php
  189. +44 −0 libs/smarty/plugins/function.data_types_dropdown.php
  190. +25 −0 libs/smarty/plugins/function.export_types.php
  191. +35 −0 libs/smarty/plugins/function.export_types_dropdown.php
  192. +214 −0 libs/smarty/plugins/function.fetch.php
  193. +216 −0 libs/smarty/plugins/function.html_checkboxes.php
  194. +159 −0 libs/smarty/plugins/function.html_image.php
  195. +174 −0 libs/smarty/plugins/function.html_options.php
  196. +200 −0 libs/smarty/plugins/function.html_radios.php
  197. +394 −0 libs/smarty/plugins/function.html_select_date.php
  198. +366 −0 libs/smarty/plugins/function.html_select_time.php
  199. +177 −0 libs/smarty/plugins/function.html_table.php
  200. +34 −0 libs/smarty/plugins/function.language_dropdown.php
Sorry, we could not display the entire diff because too many files (401) changed.
View
3  classes/Core.class.php
@@ -78,7 +78,6 @@ public function loadSettingsFile() {
if (file_exists($settingsFilePath)) {
self::$settingsFileExists = true;
require_once($settingsFilePath);
-
self::$dbHostname = (isset($dbHostname)) ? $dbHostname : null;
self::$dbName = (isset($dbName)) ? $dbName : null;
self::$dbUsername = (isset($dbUsername)) ? $dbUsername : null;
@@ -101,7 +100,7 @@ public function loadSettingsFile() {
private function initSmarty() {
self::$smarty = new Smarty();
- self::$smarty->template_dir = realpath(dirname(__FILE__) . "/../templates/");
+ self::$smarty->template_dir = realpath(dirname(__FILE__) . "/../resources/templates/");
self::$smarty->compile_dir = realpath(dirname(__FILE__) . "/../cache/");
self::$smarty->assign("version", self::getVersion());
self::$smarty->assign("samePage", Utils::getCleanPhpSelf());
View
2  classes/Language.class.php
@@ -31,7 +31,7 @@ function __construct($languageFile, $overrideDefault = true) {
// TODO exception handling here
- $fileAndPath = realpath(dirname(__FILE__) . "/../lang/" . $this->currentLanguageFile . ".php");
+ $fileAndPath = realpath(dirname(__FILE__) . "/../resources/lang/" . $this->currentLanguageFile . ".php");
require($fileAndPath);
$this->currentLanguageStrings = $L;
}
View
2  classes/Translations.class.php
@@ -11,7 +11,7 @@ class Translations {
* @return array a hash of filename => language name
*/
function __construct() {
- $translationsFolder = realpath(dirname(__FILE__) . "/../lang/");
+ $translationsFolder = realpath(dirname(__FILE__) . "/../resources/lang/");
$translations = array();
if ($handle = opendir($translationsFolder)) {
while (false !== ($item = readdir($handle))) {
View
14 classes/Utils.class.php
@@ -157,7 +157,7 @@ public static function getCleanPhpSelf() {
static function displayPage($template, $pageVars = array()) {
// check the compile directory has the write permissions
- if (!is_writable(Core::$smarty->compile_dir)) {
+ if (!is_writable(Core::$smarty->compile_dir) && is_readable(Core::$smarty->compile_dir)) {
Utils::displaySeriousError("The <b>/cache</b> folder isn't writable. This folder is used by Smarty to generate temporary files for speedy page loads. You'll need to update that folder's permissions to allow read and write permissions (777 on unix/mac).");
exit;
}
@@ -172,7 +172,6 @@ static function displayPage($template, $pageVars = array()) {
}
Core::$smarty->assign("L", Core::$language->getCurrentLanguageStrings());
- //Core::$smarty->assign("SESSION", $_SESSION["gd"]);
Core::$smarty->assign("queryString", $_SERVER["QUERY_STRING"]);
// now add the custom variables for this template, as defined in $page_vars
@@ -180,9 +179,12 @@ static function displayPage($template, $pageVars = array()) {
Core::$smarty->assign($key, $value);
}
- Core::$smarty->display(realpath(dirname(__FILE__) . "/../$template"));
-
- //gd_db_disconnect($g_link);
+ try {
+ Core::$smarty->display(realpath(dirname(__FILE__) . "/../$template"));
+ } catch (Exception $e) {
+ Utils::displaySeriousError("Smarty encountered a problem writing to the /cache folder. The (probably quite abstruse) error message returned is:<br /><br /><i>{$e}</i>");
+ exit;
+ }
}
@@ -206,7 +208,7 @@ static function displaySeriousError($error) {
<html>
<head>
<title>Things just ain't right.</title>
- <link rel="stylesheet" type="text/css" href="css/styles.css">
+ <link rel="stylesheet" type="text/css" href="resources/css/styles.css">
<script src="scripts/libs/jquery.js"></script>
<script>
$(function() {
View
9 docs/contribute.php
@@ -0,0 +1,9 @@
+<?php
+$page = "translations";
+require_once("templates/header.php");
+?>
+
+
+<?php
+require_once("templates/footer.php");
+?>
View
18 docs/countryData.php
@@ -0,0 +1,18 @@
+<?php
+$page = "country";
+require_once("templates/header.php");
+?>
+
+ <div class="container">
+ <div class="row">
+ <div class="span12">
+ <section>
+
+ </section>
+ </div>
+ </div>
+ </div>
+
+<?php
+require_once("templates/footer.php");
+?>
View
405 docs/dataTypes.php
@@ -0,0 +1,405 @@
+<?php
+$page = "data_types";
+require_once("templates/header.php");
+?>
+
+ <div class="container">
+ <div class="row">
+
+ <div class="span3 bs-docs-sidebar">
+ <ul class="nav nav-list bs-docs-sidenav affix">
+ <li><a href="#overview"><i class="icon-chevron-right"></i> Overview</a></li>
+ <li><a href="#anatomy"><i class="icon-chevron-right"></i> Anatomy of a Data Type</a></li>
+ <li><a href="#installation"><i class="icon-chevron-right"></i> Installation Script</a></li>
+ <li><a href="#database"><i class="icon-chevron-right"></i> Database / raw Data</a></li>
+ <li><a href="#i18n"><i class="icon-chevron-right"></i> I18N</a></li>
+ </ul>
+ </div>
+ <div class="span9">
+
+ <a name="overview"></a>
+
+ <section>
+ <div class="hero-unit">
+ <div>
+ <h1>Data Types</h1>
+ </div>
+ <p>
+ This page explains how to construct new Data Types.
+ </p>
+ </div>
+ </section>
+
+ <section>
+ <h2>Overview</h2>
+
+
+<!--
+ <p>
+ Data Types are self-contained plugins that generate a single random data item, like a name, email address, country name,
+ country code, image, picture, URL, barcode image, binary string - really anything you want! At the time of writing,
+ there are 20 separate data types. Many are very generic, like ÒNumber RangeÓ, and ÒCustom ListÓ, allowing to get maximum
+ use out of them; others are more specific, like "Latitude / Longitude"
+ </p>
+ <p>
+ Data Types can offer basic functionality, like ÒEmail AddressÓ which has no options, examples or help doc.; or they can be
+ more advanced, like the ÒDateÓ Data Type, which contains examples of date formats for easy generation, contains a date
+ picker dialog (courtesy of jQuery UI), and a custom help dialog window.
+
+Data Types can be standalone and generate data that has no bearing on other fields (like the ÒAlpha NumericÓ Data Type), or make decisions about its content based on other rows in the data set (like ÒState / Province / CountyÓ, which shows an appropriate value if the data set contains a country field so that provinces are listed for Canada and states for the US).
+-->
+
+ <p>
+ This document explains how to add your own data types so you can generate pretty much whatever information you want.
+ </p>
+ <p>
+ The Data Generator was designed to be entirely <i>modular</i> in terms of the data it is generating. All the
+ default data types (names, phone number, email addresses etc.) are now actually distinct modules, separate from the
+ core script. This adds a level of flexibility that the previous version lacked.
+ </p>
+ <p>
+ When creating your new data type, you can add anything you need - from client-side validation to
+ custom dynamic JS/DOM manipulation, to the actual data generated, whether it has any dependencies on the
+ other fields in the submission and whether is should show something different, depending on the export type. There's a
+ great deal of flexibility provided, so hopefully you won't run into any brick walls.
+ </p>
+ <p>
+ If you feel that your data type could be of use to other people, send it our way! We'd love to take a look at it,
+ and maybe even include it in the core script for others to download.
+ </p>
+ <p>
+ Let's start with looking at the actual files and folders that make up a data type.
+ </p>
+ </section>
+
+ <section>
+ <a name="anatomy"></a>
+ <h2>Anatomy of a Data Type</h2>
+
+ <p>
+ All data types are found in the /data_types folder, each with its own unique subfolder name. The folder name acts
+ as its namespace for both the language file key prefixes, PHP function and javascript function namespaces. We'll cover
+ that in more detail in the sections below. We strongly recommend you look at the files in an existing data type to
+ get a sense of what's in each file. We'll discuss each file below, but it can often be more helpful to just go straight
+ to the source and use this document as a reference for clearing up the less obvious details.
+ </p>
+ <p>
+ Inside the data type's folder, there are three files that have special significance to the script:
+ </p>
+
+ <ul>
+ <li><b>ui.php</b> (required)</li>
+ <li><b>include.php</b> (optional)</li>
+ <li><b>generate.php</b> (required)</li>
+ </ul>
+
+ <p>
+ These files MUST have those names in order to be recognized by the core script. You may add any additional files and
+ folders if you wish.
+ </p>
+
+ <a name="ui_php"></a>
+ <h3>ui.php</h3>
+
+ <p>
+ The ui.php file contains the information needed for the user interface. If you try selecting different data types in
+ the generator, you'll notice that different content appears for the Examples, Options and
+ </p>
+
+ <h4>General variables</h4>
+
+ <ul>
+ <li>$data_folder_name - the name of the data type folder</li>
+ <li>$data_type_field_group_index - the option group in which this field will appear. If you look in the existing interface,
+ you'll notice that for each row, the data type column dropdown values are grouped. Those group names are defined
+ in /library.php. You need to pick one of those values in the $g_field_groups variable and assign it to this variable.</li>
+ <li>$data_type_field_group_order - this determines the order in that group in which you want your data type to appear.</li>
+ </ul>
+
+ <h4>Examples column</h4>
+
+ <p>
+ The examples column is used in the UI to the give the user suggestions on how to use your data type. For example,
+ if you look at the Names data type you'll see a dropdown of name examples. When you select one (e.g. "Alex J. Smith"),
+ the value in the Options column becomes "Name Initial. Surname". This column provides the user with a simple way to learn
+ about your data type and how it works.
+ </p>
+
+ <p>
+ Back in the ui.php file, to provide your data type with an example, you need to define the <b>$data_type_example_html</b>
+ variable (a string). When the user selects your data type, the core script will automatically insert the contents of that
+ variable into the appropriate location in the page. If it's not defined, the default string "No examples defined." will be
+ inserted instead.
+ </p>
+
+ <p>
+ Here's an example from the Alpha-numeric data type:
+ </p>
+
+ <blockquote><pre>$data_type_example_html =<<<EOF
+ <select name="dt_\$ROW\$" id="dt_\$ROW\$" onchange="$('#option_\$ROW\$').val(this.value)">
+ <option value="">{$LANG["please_select"]}</option>
+ <option value="LxL xLx">V6M 4C1 {$LANG["AlphaNumeric_example_CanPostalCode"]}</option>
+ <option value="xxxxx">90210 {$LANG["AlphaNumeric_example_USZipCode"]}</option>
+ <option value="LLLxxLLLxLL">eZg29gdF5K1 {$DT["AlphaNumeric_example_Password"]}</option>
+ </select>
+ EOF;
+ </pre></blockquote>
+
+ <p>
+ First, note that there are numerous <b>\$ROW\$</b> strings littered throughout the code (the dollar signs are escaped since the variable
+ is having the value applied via heredoc syntax. $ROW$ is a special placeholder that will be replaced with the row number in
+ the interface when the core script inserts it into the page. This provides a handy way to uniquely locate the relevant HTML
+ elements.
+ </p>
+
+ <p>
+ Secondly, note that the onchange handler uses a $ function. The generator includes jQuery (1.4.2 at the time of writing)
+ which you can use in your own client-side code. Also notice that the onchange handler references an element with the id
+ "option_$ROW$" (where $ROW$ would have been converted to n integer value by the time it's inserted into the page). Every
+ row in the generator provides a unique ID to the various columns: <b>example_N</b>, <b>option_N</b>, <b>help_N</b>. You
+ can use those values to target your content. In this example, the alpha-numeric data type automatically inserts the
+ selected value in the example dropdown into the options field.
+ </p>
+
+ <h4>Options column</h4>
+
+ <p>
+ The options column is where you should place any configurable values for your data type. Depending on what you
+ are trying to generate, this may be empty. As with the previous examples column, you can define the markup to appear
+ in the options column by storing HTML within a variable - this time called <b>$data_type_options_html</b>. You can
+ store whatever HTML you want in that field, but if you want information to be passed to the server, make sure the
+ input fields have unique name attributes (i.e. include "$ROW$" in the name string, as illustrated in the previous
+ section). You can then pull out the POST values to figure out what configuration settings the user has selected - thus
+ catering the generated data to their individual request.
+ </p>
+
+ <h4>Help column</h4>
+
+ <p>
+ As with the previous two columns, the help column is also optional. Some basic data types like email, street address and
+ city are self-explanatory, so no help text is needed. However, if your data type does need a little explanation, just
+ define a <b>$help_html_content</b> variable containing whatever help text you want. The core script will then automatically
+ display a "help" icon and open that information in a popup when the user clicks it.
+ </p>
+
+
+ <a name="include_php"></a>
+ <h3>include.php</h3>
+
+ <p>
+ The second file in a data type is the optional include.php file. This file is included as-is into the main generator
+ page in a hidden element. It provides you with a convenient way to insert javascript or raw HTML content into the page for use
+ by your data type.
+ </p>
+
+ <p>
+ This file can be used to add validation to your data type (to ensure the user filled it in properly when the user
+ clicks "generate"). But also, if you want people to be able to save and load your data type settings
+ (and you should!) you'll need to include a couple of specially named javascript functions for that purpose. Each of these
+ three cases is discussed below in the <a href="#actions">Actions</a> section.
+ </p>
+
+ <a name="generate_php"></a>
+ <h3>generate.php</h3>
+
+ <p>
+ The third and final data type file contains certain pre-defined functions that are called to actually process
+ and generate the random data for your data type. The idea is actually quite simple: this file contains a few functions
+ and variables with specific names. The core script then accesses that information and calls those functions for those
+ row(s) that the user selected as your data type. Your code then generates the random data and the core script inserts
+ the data into the right spot in the XML, CSV, Excel, HTML or SQL.
+ </p>
+
+ <h4>Namespace</h4>
+
+ <p>
+ As with the javascript, the PHP functions and variables in this file MUST be namespaced to be recognized. We use the term
+ "namespace" rather loosely - it's just a prefix to the PHP functions, variables and javascript object that contains your
+ client-side code. The namespace (prefix) is the same as your folder name. It is case sensitive. For the next few sections
+ we're going to assume your data type has a folder name of <b>MyGreatDataType</b>.
+ </p>
+
+ <h4>Variables</h4>
+
+ <p>
+ The following variable is required. For the moment, just leave it to 1. See the <a href="#dependencies">Dependencies</a>
+ section below for more information on what this variable does and how it can help your scripts.
+ </p>
+
+ <blockquote><pre>$MyGreatDataType_process_order = 1;</pre></blockquote>
+
+ <p>
+ It's not as complicated as it sounds, honest.
+ </p>
+
+ <h4>Functions</h4>
+
+ <p>
+ The generate.php should contain the following functions:
+ </p>
+
+ <ul>
+ <li>[FOLDER NAME]_get_template_options</li>
+ <li>[FOLDER NAME]_generate_item</li>
+ <li>[FOLDER NAME]_get_export_type_info</li>
+ </ul>
+
+ <p>
+ (where [FOLDER NAME] is the name of your folder).
+ </p>
+ </section>
+
+
+<a name="actions"></a>
+<h2>Actions</h2>
+
+<p>
+ So far so good. Now let's leave the server-side code along and spend some time in the client. Certain key
+ user actions: submitting the generator form, loading and saving - are all handled 100% with javascript.
+ Note: we didn't bother adding server-side validation because the generator is fundamentally a client-side
+ script. With JS disabled, nothing would work, so we can assume the user hasn't disabled it. All three
+ of these actions are defined in the include.php file.
+</p>
+
+<p>
+ For this section, we're going to use the include.php file for the Names data type as an example. Here's the
+ full contents of the file, comments and all.
+</p>
+
+<blockquote><pre><script>
+var Names_ns = {
+
+ /**
+ * Called when the user submits the form to generate some data. If the selected data set contains
+ * one or more rows of this data type, this function is called with the list of row numbers. Note that
+ * the row numbers passed are the original row numbers of the rows on creation. It's possible that the
+ * user has re-sorted or deleted some rows. So to get the visible row number for a row, called
+ * gd._getVisibleRowOrderByRowNum(row).
+ */
+ validate: function(rows)
+ {
+ var visibleProblemRows = [];
+ var problemFields = [];
+ for (var i=0; i<rows.length; i++)
+ {
+ if ($("#option_" + rows[i]).val() == "")
+ {
+ var visibleRowNum = gd._getVisibleRowOrderByRowNum(rows[i]);
+ visibleProblemRows.push(visibleRowNum);
+ problemFields.push($("#option_" + rows[i]));
+ }
+ }
+
+ if (visibleProblemRows.length)
+ gd.errors.push({ els: problemFields, error: L.Names_incomplete_fields + " <b>" + visibleProblemRows.join(", ") + "</b>"});
+ },
+
+ /**
+ * Called when a form is loaded that contains this data type. This is passed the row number and
+ * the custom data type data to populate the fields. loadRow functions all must return an array
+ * with two indexes - both functions:
+ * [0] code to execute (generally inserting data into fields)
+ * [1] a boolean test to determine WHEN to execute the code.
+ */
+ loadRow: function(rowNum, data)
+ {
+ return [
+ function() {
+ $("#dt_" + rowNum).val(data.example);
+ $("#option_" + rowNum).val(data.option);
+ },
+ function() { return $("#option_" + rowNum).length > 0; }
+ ];
+ },
+
+ /**
+ * Called when the user saves a form. This function is passed the row number of the row to
+ * save. It should return a well-formatted JSON object (of whatever structure is relevant.
+ */
+ saveRow: function(rowNum)
+ {
+ return {
+ "example": $("#dt_" + rowNum).val(),
+ "option": $("#option_" + rowNum).val()
+ };
+ }
+}
+</script></pre></blockquote>
+
+<a name="validation"></a>
+<h3>Validation of user input</h3>
+
+<p>
+ If you choose to add validation, you need to add a validate function to your ui.php file. As shown in the
+ example above, the object namespace for your data type (here: Names_ns) need to contain a <b>validate</b>
+ property function. That function is passed an array containing the row numbers of all rows that have
+ selected your data type. If the dataset that the user has constructed doesn't contain your data type,
+ this function won't be called.
+</p>
+
+<p class="notify">
+ <b>Important</b>: the row numbers that are passed to your validation function are not necessarily the row
+ numbers that you see in the UI. Here's why. When a row is created, a whole bunch of row numbers
+ are embedded into the markup in things like IDs and name attributes. This lets the javascript uniquely locate
+ fields and lets the server-side code access the settings when it comes time to generate the random data.
+ If you need to use the visual row number, call the gd._getVisibleRowOrderByRowNum() function on the row
+ number, as with the example above.
+</p>
+
+<p>
+ The function
+</p>
+
+
+<a name="saving_data_type"></a>
+<h3>Saving the data type</h3>
+
+
+
+<a name="loading_data_type"></a>
+<h3>Loading the data type</h3>
+
+
+<a name="dependencies"></a>
+<h2>Dependencies</h2>
+
+<p>
+ What if you want to generate some data that is dependent on another field in the result set? No problem! A number of
+ existing data types do exactly this. For example, if a person has selected both Country and State/Province/County fields,
+ the latter will limit the generated states/provinces/counties to whatever country was in the country field. If there
+ IS no mapping for the country, the data type just randomly picks one - it's all it can do!
+</p>
+
+<p>
+ As another example, the Composite data field lets you reference any other field in the generated data so you can manipulate
+ it in whatever way you see fit. For example, you can use that field to do math on other fields, or do string concatenation
+ of other string-like fields.
+</p>
+
+<p>
+ All of this is possible via the <b>process order</b> variable in your generate.php file:
+</p>
+
+<blockquote><pre>$NAMESPACE_process_order = 1;</pre></blockquote>
+
+<p>
+ This is how this works. When it comes time to generating the actual data, for each and every row, the generator loops through
+ the data types that are in the submission (selected by the user in the UI). Now, for each row, the order in which the generator
+ calls the individual data type's generate function depends on this variable. And, every time the generator function is called,
+ <i>it's passed the return values for all data types up to that point</i>.
+</p>
+
+<p>
+ The upshot of all this is that you can use this mechanism to add dependencies between data types. If you have
+ a data type that relies on one of the existing ones, just give it a higher process order. Tada!
+</p>
+
+
+ </div>
+ </div>
+ </div>
+
+<?php
+require_once("templates/footer.php");
+?>
View
388 docs/exportTypes.php
@@ -0,0 +1,388 @@
+<?php
+$page = "export_types";
+require_once("templates/header.php");
+?>
+
+<div class="container">
+ <div class="row">
+
+ <div class="span3 bs-docs-sidebar">
+ <ul class="nav nav-list bs-docs-sidenav affix">
+ <li><a href="#overview"><i class="icon-chevron-right"></i> Overview</a></li>
+ <li><a href="#anatomy"><i class="icon-chevron-right"></i> Anatomy of an Export Type</a></li>
+ <li><a href="#installation"><i class="icon-chevron-right"></i> Installation Script</a></li>
+ <li><a href="#database"><i class="icon-chevron-right"></i> Database / raw Data</a></li>
+ <li><a href="#i18n"><i class="icon-chevron-right"></i> I18N</a></li>
+ </ul>
+ </div>
+ <div class="span9">
+
+ <a name="overview"></a>
+
+ <section>
+ <div class="hero-unit">
+ <div>
+ <h1>Export Types</h1>
+ </div>
+ <p>
+ Constructing new ways to export the data.
+ </p>
+ </div>
+ </section>
+
+ <section>
+ <h2>Overview</h2>
+ <p>
+ This document explains how to add your own data types so you can generate pretty much whatever information you want.
+ </p>
+ <p>
+ The Data Generator was designed to be entirely <i>modular</i> in terms of the data it is generating. All the
+ default data types (names, phone number, email addresses etc.) are now actually distinct modules, separate from the
+ core script. This adds a level of flexibility that the previous version lacked.
+ </p>
+ <p>
+ When creating your new data type, you can add anything you need - from client-side validation to
+ custom dynamic JS/DOM manipulation, to the actual data generated, whether it has any dependencies on the
+ other fields in the submission and whether is should show something different, depending on the export type. There's a
+ great deal of flexibility provided, so hopefully you won't run into any brick walls.
+ </p>
+ <p>
+ If you feel that your data type could be of use to other people, send it our way! We'd love to take a look at it,
+ and maybe even include it in the core script for others to download.
+ </p>
+ <p>
+ Let's start with looking at the actual files and folders that make up a data type.
+ </p>
+ </section>
+
+ <section>
+ <a name="anatomy"></a>
+ <h2>Anatomy of a Data Type</h2>
+
+ <p>
+ All data types are found in the /data_types folder, each with its own unique subfolder name. The folder name acts
+ as its namespace for both the language file key prefixes, PHP function and javascript function namespaces. We'll cover
+ that in more detail in the sections below. We strongly recommend you look at the files in an existing data type to
+ get a sense of what's in each file. We'll discuss each file below, but it can often be more helpful to just go straight
+ to the source and use this document as a reference for clearing up the less obvious details.
+ </p>
+ <p>
+ Inside the data type's folder, there are three files that have special significance to the script:
+ </p>
+
+ <ul>
+ <li><b>ui.php</b> (required)</li>
+ <li><b>include.php</b> (optional)</li>
+ <li><b>generate.php</b> (required)</li>
+ </ul>
+
+ <p>
+ These files MUST have those names in order to be recognized by the core script. You may add any additional files and
+ folders if you wish.
+ </p>
+
+ <a name="ui_php"></a>
+ <h3>ui.php</h3>
+
+ <p>
+ The ui.php file contains the information needed for the user interface. If you try selecting different data types in
+ the generator, you'll notice that different content appears for the Examples, Options and
+ </p>
+
+ <h4>General variables</h4>
+
+ <ul>
+ <li>$data_folder_name - the name of the data type folder</li>
+ <li>$data_type_field_group_index - the option group in which this field will appear. If you look in the existing interface,
+ you'll notice that for each row, the data type column dropdown values are grouped. Those group names are defined
+ in /library.php. You need to pick one of those values in the $g_field_groups variable and assign it to this variable.</li>
+ <li>$data_type_field_group_order - this determines the order in that group in which you want your data type to appear.</li>
+ </ul>
+
+ <h4>Examples column</h4>
+
+ <p>
+ The examples column is used in the UI to the give the user suggestions on how to use your data type. For example,
+ if you look at the Names data type you'll see a dropdown of name examples. When you select one (e.g. "Alex J. Smith"),
+ the value in the Options column becomes "Name Initial. Surname". This column provides the user with a simple way to learn
+ about your data type and how it works.
+ </p>
+
+ <p>
+ Back in the ui.php file, to provide your data type with an example, you need to define the <b>$data_type_example_html</b>
+ variable (a string). When the user selects your data type, the core script will automatically insert the contents of that
+ variable into the appropriate location in the page. If it's not defined, the default string "No examples defined." will be
+ inserted instead.
+ </p>
+
+ <p>
+ Here's an example from the Alpha-numeric data type:
+ </p>
+
+ <blockquote><pre>$data_type_example_html =<<< EOF
+ <select name="dt_\$ROW\$" id="dt_\$ROW\$" onchange="$('#option_\$ROW\$').val(this.value)">
+ <option value="">{$LANG["please_select"]}</option>
+ <option value="LxL xLx">V6M 4C1 {$LANG["AlphaNumeric_example_CanPostalCode"]}</option>
+ <option value="xxxxx">90210 {$LANG["AlphaNumeric_example_USZipCode"]}</option>
+ <option value="LLLxxLLLxLL">eZg29gdF5K1 {$DT["AlphaNumeric_example_Password"]}</option>
+ </select>
+ EOF;
+ </pre></blockquote>
+
+ <p>
+ First, note that there are numerous <b>\$ROW\$</b> strings littered throughout the code (the dollar signs are escaped since the variable
+ is having the value applied via heredoc syntax. $ROW$ is a special placeholder that will be replaced with the row number in
+ the interface when the core script inserts it into the page. This provides a handy way to uniquely locate the relevant HTML
+ elements.
+ </p>
+
+ <p>
+ Secondly, note that the onchange handler uses a $ function. The generator includes jQuery (1.4.2 at the time of writing)
+ which you can use in your own client-side code. Also notice that the onchange handler references an element with the id
+ "option_$ROW$" (where $ROW$ would have been converted to n integer value by the time it's inserted into the page). Every
+ row in the generator provides a unique ID to the various columns: <b>example_N</b>, <b>option_N</b>, <b>help_N</b>. You
+ can use those values to target your content. In this example, the alpha-numeric data type automatically inserts the
+ selected value in the example dropdown into the options field.
+ </p>
+
+ <h4>Options column</h4>
+
+ <p>
+ The options column is where you should place any configurable values for your data type. Depending on what you
+ are trying to generate, this may be empty. As with the previous examples column, you can define the markup to appear
+ in the options column by storing HTML within a variable - this time called <b>$data_type_options_html</b>. You can
+ store whatever HTML you want in that field, but if you want information to be passed to the server, make sure the
+ input fields have unique name attributes (i.e. include "$ROW$" in the name string, as illustrated in the previous
+ section). You can then pull out the POST values to figure out what configuration settings the user has selected - thus
+ catering the generated data to their individual request.
+ </p>
+
+ <h4>Help column</h4>
+
+ <p>
+ As with the previous two columns, the help column is also optional. Some basic data types like email, street address and
+ city are self-explanatory, so no help text is needed. However, if your data type does need a little explanation, just
+ define a <b>$help_html_content</b> variable containing whatever help text you want. The core script will then automatically
+ display a "help" icon and open that information in a popup when the user clicks it.
+ </p>
+
+
+ <a name="include_php"></a>
+ <h3>include.php</h3>
+
+ <p>
+ The second file in a data type is the optional include.php file. This file is included as-is into the main generator
+ page in a hidden element. It provides you with a convenient way to insert javascript or raw HTML content into the page for use
+ by your data type.
+ </p>
+
+ <p>
+ This file can be used to add validation to your data type (to ensure the user filled it in properly when the user
+ clicks "generate"). But also, if you want people to be able to save and load your data type settings
+ (and you should!) you'll need to include a couple of specially named javascript functions for that purpose. Each of these
+ three cases is discussed below in the <a href="#actions">Actions</a> section.
+ </p>
+
+ <a name="generate_php"></a>
+ <h3>generate.php</h3>
+
+ <p>
+ The third and final data type file contains certain pre-defined functions that are called to actually process
+ and generate the random data for your data type. The idea is actually quite simple: this file contains a few functions
+ and variables with specific names. The core script then accesses that information and calls those functions for those
+ row(s) that the user selected as your data type. Your code then generates the random data and the core script inserts
+ the data into the right spot in the XML, CSV, Excel, HTML or SQL.
+ </p>
+
+ <h4>Namespace</h4>
+
+ <p>
+ As with the javascript, the PHP functions and variables in this file MUST be namespaced to be recognized. We use the term
+ "namespace" rather loosely - it's just a prefix to the PHP functions, variables and javascript object that contains your
+ client-side code. The namespace (prefix) is the same as your folder name. It is case sensitive. For the next few sections
+ we're going to assume your data type has a folder name of <b>MyGreatDataType</b>.
+ </p>
+
+ <h4>Variables</h4>
+
+ <p>
+ The following variable is required. For the moment, just leave it to 1. See the <a href="#dependencies">Dependencies</a>
+ section below for more information on what this variable does and how it can help your scripts.
+ </p>
+
+ <blockquote><pre>$MyGreatDataType_process_order = 1;</pre></blockquote>
+
+ <p>
+ It's not as complicated as it sounds, honest.
+ </p>
+
+ <h4>Functions</h4>
+
+ <p>
+ The generate.php should contain the following functions:
+ </p>
+
+ <ul>
+ <li>[FOLDER NAME]_get_template_options</li>
+ <li>[FOLDER NAME]_generate_item</li>
+ <li>[FOLDER NAME]_get_export_type_info</li>
+ </ul>
+
+ <p>
+ (where [FOLDER NAME] is the name of your folder).
+ </p>
+ </section>
+
+
+<a name="actions"></a>
+<h2>Actions</h2>
+
+<p>
+ So far so good. Now let's leave the server-side code along and spend some time in the client. Certain key
+ user actions: submitting the generator form, loading and saving - are all handled 100% with javascript.
+ Note: we didn't bother adding server-side validation because the generator is fundamentally a client-side
+ script. With JS disabled, nothing would work, so we can assume the user hasn't disabled it. All three
+ of these actions are defined in the include.php file.
+</p>
+
+<p>
+ For this section, we're going to use the include.php file for the Names data type as an example. Here's the
+ full contents of the file, comments and all.
+</p>
+
+<blockquote><pre><script>
+var Names_ns = {
+
+ /**
+ * Called when the user submits the form to generate some data. If the selected data set contains
+ * one or more rows of this data type, this function is called with the list of row numbers. Note that
+ * the row numbers passed are the original row numbers of the rows on creation. It's possible that the
+ * user has re-sorted or deleted some rows. So to get the visible row number for a row, called
+ * gd._getVisibleRowOrderByRowNum(row).
+ */
+ validate: function(rows)
+ {
+ var visibleProblemRows = [];
+ var problemFields = [];
+ for (var i=0; i<rows.length; i++)
+ {
+ if ($("#option_" + rows[i]).val() == "")
+ {
+ var visibleRowNum = gd._getVisibleRowOrderByRowNum(rows[i]);
+ visibleProblemRows.push(visibleRowNum);
+ problemFields.push($("#option_" + rows[i]));
+ }
+ }
+
+ if (visibleProblemRows.length)
+ gd.errors.push({ els: problemFields, error: L.Names_incomplete_fields + " <b>" + visibleProblemRows.join(", ") + "</b>"});
+ },
+
+ /**
+ * Called when a form is loaded that contains this data type. This is passed the row number and
+ * the custom data type data to populate the fields. loadRow functions all must return an array
+ * with two indexes - both functions:
+ * [0] code to execute (generally inserting data into fields)
+ * [1] a boolean test to determine WHEN to execute the code.
+ */
+ loadRow: function(rowNum, data)
+ {
+ return [
+ function() {
+ $("#dt_" + rowNum).val(data.example);
+ $("#option_" + rowNum).val(data.option);
+ },
+ function() { return $("#option_" + rowNum).length > 0; }
+ ];
+ },
+
+ /**
+ * Called when the user saves a form. This function is passed the row number of the row to
+ * save. It should return a well-formatted JSON object (of whatever structure is relevant.
+ */
+ saveRow: function(rowNum)
+ {
+ return {
+ "example": $("#dt_" + rowNum).val(),
+ "option": $("#option_" + rowNum).val()
+ };
+ }
+}
+</script></pre></blockquote>
+
+<a name="validation"></a>
+<h3>Validation of user input</h3>
+
+<p>
+ If you choose to add validation, you need to add a validate function to your ui.php file. As shown in the
+ example above, the object namespace for your data type (here: Names_ns) need to contain a <b>validate</b>
+ property function. That function is passed an array containing the row numbers of all rows that have
+ selected your data type. If the dataset that the user has constructed doesn't contain your data type,
+ this function won't be called.
+</p>
+
+<p class="notify">
+ <b>Important</b>: the row numbers that are passed to your validation function are not necessarily the row
+ numbers that you see in the UI. Here's why. When a row is created, a whole bunch of row numbers
+ are embedded into the markup in things like IDs and name attributes. This lets the javascript uniquely locate
+ fields and lets the server-side code access the settings when it comes time to generate the random data.
+ If you need to use the visual row number, call the gd._getVisibleRowOrderByRowNum() function on the row
+ number, as with the example above.
+</p>
+
+<p>
+ The function
+</p>
+
+
+<a name="saving_data_type"></a>
+<h3>Saving the data type</h3>
+
+
+
+<a name="loading_data_type"></a>
+<h3>Loading the data type</h3>
+
+
+<a name="dependencies"></a>
+<h2>Dependencies</h2>
+
+<p>
+ What if you want to generate some data that is dependent on another field in the result set? No problem! A number of
+ existing data types do exactly this. For example, if a person has selected both Country and State/Province/County fields,
+ the latter will limit the generated states/provinces/counties to whatever country was in the country field. If there
+ IS no mapping for the country, the data type just randomly picks one - it's all it can do!
+</p>
+
+<p>
+ As another example, the Composite data field lets you reference any other field in the generated data so you can manipulate
+ it in whatever way you see fit. For example, you can use that field to do math on other fields, or do string concatenation
+ of other string-like fields.
+</p>
+
+<p>
+ All of this is possible via the <b>process order</b> variable in your generate.php file:
+</p>
+
+<blockquote><pre>$NAMESPACE_process_order = 1;</pre></blockquote>
+
+<p>
+ This is how this works. When it comes time to generating the actual data, for each and every row, the generator loops through
+ the data types that are in the submission (selected by the user in the UI). Now, for each row, the order in which the generator
+ calls the individual data type's generate function depends on this variable. And, every time the generator function is called,
+ <i>it's passed the return values for all data types up to that point</i>.
+</p>
+
+<p>
+ The upshot of all this is that you can use this mechanism to add dependencies between data types. If you have
+ a data type that relies on one of the existing ones, just give it a higher process order. Tada!
+</p>
+
+
+ </div>
+ </div>
+ </div>
+
+<?php
+require_once("templates/footer.php");
+?>
View
4 docs/templates/footer.php
@@ -1,8 +1,8 @@
<footer class="footer">
<div class="container">
<ul class="footer-links">
- <li><a href="http://blog.getbootstrap.com">How to contribute</a></li>
- <li><a href="http://blog.getbootstrap.com">Scripts / Tools used</a></li>
+ <li><a href="contribute.php">How to contribute</a></li>
+ <li><a href="thanks.php">Scripts / Tools used</a></li>
</ul>
</div>
</footer>
View
24 docs/thanks.php
@@ -0,0 +1,24 @@
+<?php
+$page = "translations";
+require_once("templates/header.php");
+?>
+
+<ul>
+ <li>jQuery</li>
+ <li>jQuery UI</li>
+ <li>RequireJS</li>
+ <li>CodeMirror</li>
+ <li>Smarty PHP</li>
+ <li>Chosen</li>
+ <li>jQuery JSON plugin</li>
+ <li>Bootstrap</li>
+</ul>
+
+<p>
+ And a big thanks to Addy Osmani for his excellent article: <a href="http://addyosmani.com/largescalejavascript/">Patterns For
+ Large-Scale JavaScript Application Architecture</a>. The client-side code was largely based on his article.
+</p>
+
+<?php
+require_once("templates/footer.php");
+?>
View
3  index.php
@@ -12,6 +12,7 @@
$dataTypes = DataTypePluginHelper::getDataTypeList(Core::$dataTypePlugins);
+
$exportTypeJSModules = ExportTypePluginHelper::getExportTypeJSResources($exportTypes);
$dataTypeJSModules = DataTypePluginHelper::getDataTypeJSResources($dataTypes);
$cssIncludes = DataTypePluginHelper::getDataTypeCSSIncludes($dataTypes);
@@ -23,4 +24,4 @@
$pageParams["settings"] = Settings::getSettings();
$pageParams["cssIncludes"] = $cssIncludes;
-Utils::displayPage("templates/index.tpl", $pageParams);
+Utils::displayPage("resources/templates/index.tpl", $pageParams);
View
2  install.php
@@ -23,4 +23,4 @@
$params["tablePrefix"] = Core::getDbTablePrefix();
$params["currentPage"] = $currentPage;
-Utils::displayPage("templates/install.tpl", $params);
+Utils::displayPage("resources/templates/install.tpl", $params);
View
2  library.php
@@ -25,7 +25,7 @@
require_once(dirname(__FILE__) . "/classes/Settings.class.php");
require_once(dirname(__FILE__) . "/classes/Translations.class.php");
require_once(dirname(__FILE__) . "/classes/Utils.class.php");
-require_once(dirname(__FILE__) . "/smarty/Smarty.class.php");
+require_once(dirname(__FILE__) . "/libs/smarty/Smarty.class.php");
//require_once(dirname(__FILE__) . "/classes/Exceptions.class.php");
//require_once(dirname(__FILE__) . "/classes/GDException.class.php");
View
2  libs/codemirror/.gitignore
@@ -0,0 +1,2 @@
+/node_modules
+/npm-debug.log
View
3  libs/codemirror/.travis.yml
@@ -0,0 +1,3 @@
+language: node_js
+node_js:
+ - 0.8
View
23 libs/codemirror/LICENSE
@@ -0,0 +1,23 @@
+Copyright (C) 2012 by Marijn Haverbeke <marijnh@gmail.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.
+
+Please note that some subdirectories of the CodeMirror distribution
+include their own LICENSE files, and are released under different
+licences.
View
472 libs/codemirror/index.html
@@ -0,0 +1,472 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>CodeMirror</title>
+ <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans:bold"/>
+ <link rel="stylesheet" type="text/css" href="doc/docs.css"/>
+ <link rel="alternate" href="http://twitter.com/statuses/user_timeline/242283288.rss" type="application/rss+xml"/>
+ </head>
+ <body>
+
+<h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMirror</a></h1>
+
+<div class="grey">
+<img src="doc/baboon.png" class="logo" alt="logo"/>
+<pre>
+/* In-browser code editing
+ made bearable */
+</pre>
+</div>
+
+<div class="clear"><div class="left blk">
+
+ <p style="margin-top: 0">CodeMirror is a JavaScript component that
+ provides a code editor in the browser. When a mode is available for
+ the language you are coding in, it will color your code, and
+ optionally help with indentation.</p>
+
+ <p>A <a href="doc/manual.html">rich programming API</a> and a CSS
+ theming system are available for customizing CodeMirror to fit your
+ application, and extending it with new functionality.</p>
+
+ <div class="clear"><div class="left1 blk">
+
+ <h2 style="margin-top: 0">Supported modes:</h2>
+
+ <ul>
+ <li><a href="mode/clike/index.html">C, C++, C#</a></li>
+ <li><a href="mode/clojure/index.html">Clojure</a></li>
+ <li><a href="mode/coffeescript/index.html">CoffeeScript</a></li>
+ <li><a href="mode/commonlisp/index.html">Common Lisp</a></li>
+ <li><a href="mode/css/index.html">CSS</a></li>
+ <li><a href="mode/diff/index.html">diff</a></li>
+ <li><a href="mode/ecl/index.html">ECL</a></li>
+ <li><a href="mode/erlang/index.html">Erlang</a></li>
+ <li><a href="mode/go/index.html">Go</a></li>
+ <li><a href="mode/groovy/index.html">Groovy</a></li>
+ <li><a href="mode/haskell/index.html">Haskell</a></li>
+ <li><a href="mode/haxe/index.html">Haxe</a></li>
+ <li><a href="mode/htmlembedded/index.html">HTML embedded scripts</a></li>
+ <li><a href="mode/htmlmixed/index.html">HTML mixed-mode</a></li>
+ <li><a href="mode/clike/index.html">Java</a></li>
+ <li><a href="mode/javascript/index.html">JavaScript</a></li>
+ <li><a href="mode/jinja2/index.html">Jinja2</a></li>
+ <li><a href="mode/less/index.html">LESS</a></li>
+ <li><a href="mode/lua/index.html">Lua</a></li>
+ <li><a href="mode/markdown/index.html">Markdown</a> (<a href="mode/gfm/index.html">Github-flavour</a>)</li>
+ <li><a href="mode/mysql/index.html">MySQL</a></li>
+ <li><a href="mode/ntriples/index.html">NTriples</a></li>
+ <li><a href="mode/ocaml/index.html">OCaml</a></li>
+ <li><a href="mode/pascal/index.html">Pascal</a></li>
+ <li><a href="mode/perl/index.html">Perl</a></li>
+ <li><a href="mode/php/index.html">PHP</a></li>
+ <li><a href="mode/pig/index.html">Pig Latin</a></li>
+ <li><a href="mode/plsql/index.html">PL/SQL</a></li>
+ <li><a href="mode/properties/index.html">Properties files</a></li>
+ <li><a href="mode/python/index.html">Python</a></li>
+ <li><a href="mode/r/index.html">R</a></li>
+ <li>RPM <a href="mode/rpm/spec/index.html">spec</a> and <a href="mode/rpm/changes/index.html">changelog</a></li>
+ <li><a href="mode/rst/index.html">reStructuredText</a></li>
+ <li><a href="mode/ruby/index.html">Ruby</a></li>
+ <li><a href="mode/rust/index.html">Rust</a></li>
+ <li><a href="mode/clike/scala.html">Scala</a></li>
+ <li><a href="mode/scheme/index.html">Scheme</a></li>
+ <li><a href="mode/shell/index.html">Shell</a></li>
+ <li><a href="mode/sieve/index.html">Sieve</a></li>
+ <li><a href="mode/smalltalk/index.html">Smalltalk</a></li>
+ <li><a href="mode/smarty/index.html">Smarty</a></li>
+ <li><a href="mode/sparql/index.html">SPARQL</a></li>
+ <li><a href="mode/stex/index.html">sTeX, LaTeX</a></li>
+ <li><a href="mode/tiddlywiki/index.html">Tiddlywiki</a></li>
+ <li><a href="mode/tiki/index.html">Tiki wiki</a></li>
+ <li><a href="mode/vb/index.html">VB.NET</a></li>
+ <li><a href="mode/vbscript/index.html">VBScript</a></li>
+ <li><a href="mode/velocity/index.html">Velocity</a></li>
+ <li><a href="mode/verilog/index.html">Verilog</a></li>
+ <li><a href="mode/xml/index.html">XML/HTML</a></li>
+ <li><a href="mode/xquery/index.html">XQuery</a></li>
+ <li><a href="mode/yaml/index.html">YAML</a></li>
+ </ul>
+
+ </div><div class="left2 blk">
+
+ <h2 style="margin-top: 0">Usage demos:</h2>
+
+ <ul>
+ <li><a href="demo/complete.html">Autocompletion</a> (<a href="demo/xmlcomplete.html">XML</a>)</li>
+ <li><a href="demo/search.html">Search/replace</a></li>
+ <li><a href="demo/folding.html">Code folding</a></li>
+ <li><a href="demo/mustache.html">Mode overlays</a></li>
+ <li><a href="demo/multiplex.html">Mode multiplexer</a></li>
+ <li><a href="demo/preview.html">HTML editor with preview</a></li>
+ <li><a href="demo/resize.html">Auto-resizing editor</a></li>
+ <li><a href="demo/marker.html">Setting breakpoints</a></li>
+ <li><a href="demo/activeline.html">Highlighting the current line</a></li>
+ <li><a href="demo/matchhighlighter.html">Highlighting selection matches</a></li>
+ <li><a href="demo/theme.html">Theming</a></li>
+ <li><a href="demo/runmode.html">Stand-alone highlighting</a></li>
+ <li><a href="demo/fullscreen.html">Full-screen editing</a></li>
+ <li><a href="demo/changemode.html">Mode auto-changing</a></li>
+ <li><a href="demo/visibletabs.html">Visible tabs</a></li>
+ <li><a href="demo/formatting.html">Autoformatting of code</a></li>
+ <li><a href="demo/emacs.html">Emacs keybindings</a></li>
+ <li><a href="demo/vim.html">Vim keybindings</a></li>
+ <li><a href="demo/closetag.html">Automatic xml tag closing</a></li>
+ <li><a href="demo/loadmode.html">Lazy mode loading</a></li>
+ </ul>
+
+ <h2>Real-world uses:</h2>
+
+ <ul>
+ <li><a href="http://jsbin.com">jsbin.com</a> (JS playground)</li>
+ <li><a href="http://www.chris-granger.com/2012/04/12/light-table---a-new-ide-concept/">Light Table</a> (experimental IDE)</li>
+ <li><a href="http://brackets.io">Adobe Brackets</a> (code editor)</li>
+ <li><a href="http://www.mergely.com/">Mergely</a> (interactive diffing)</li>
+ <li><a href="https://script.google.com/">Google Apps Script</a></li>
+ <li><a href="https://github.com/github/android">GitHub's Android app</a></li>
+ <li><a href="http://eloquentjavascript.net/chapter1.html">Eloquent JavaScript</a> (book)</li>
+ <li><a href="http://media.chikuyonok.ru/codemirror2/">Zen Coding</a> (fast XML editing)</li>
+ <li><a href="http://paperjs.org/">Paper.js</a> (graphics scripting)</li>
+ <li><a href="http://tour.golang.org">Go language tour</a></li>
+ <li><a href="http://codev.it/">Codev</a> (collaborative IDE)</li>
+ <li><a href="http://enjalot.com/tributary/2636296/sinwaves.js">Tributary</a> (augmented editing)</li>
+ <li><a href="http://prose.io/">Prose.io</a> (github content editor)</li>
+ <li><a href="http://www.wescheme.org/">WeScheme</a> (learning tool)</li>
+ <li><a href="http://webglplayground.net/">WebGL playground</a></li>
+ <li><a href="http://ql.io/">ql.io</a> (http API query helper)</li>
+ <li><a href="http://elm-lang.org/Examples.elm">Elm language examples</a></li>
+ <li><a href="https://thefiletree.com">The File Tree</a> (collab editor)</li>
+ <li><a href="http://bluegriffon.org/">BlueGriffon</a> (HTML editor)</li>
+ <li><a href="http://www.jshint.com/">JSHint</a> (JS linter)</li>
+ <li><a href="http://kl1p.com/cmtest/1">kl1p</a> (paste service)</li>
+ <li><a href="http://sqlfiddle.com">SQLFiddle</a> (SQL playground)</li>
+ <li><a href="http://try.haxe.org">Try Haxe</a> (Haxe Playground) </li>
+ <li><a href="http://cssdeck.com/">CSSDeck</a> (CSS showcase)</li>
+ <li><a href="http://www.ckwnc.com/">CKWNC</a> (UML editor)</li>
+ <li><a href="http://www.sketchpatch.net/labs/livecodelabIntro.html">sketchPatch Livecodelab</a></li>
+ <li><a href="https://notex.ch">NoTex</a> (rST authoring)</li>
+ </ul>
+
+ </div></div>
+
+ <h2 id="code">Getting the code</h2>
+
+ <p>All of CodeMirror is released under a <a
+ href="LICENSE">MIT-style</a> license. To get it, you can download
+ the <a href="http://codemirror.net/codemirror.zip">latest
+ release</a> or the current <a
+ href="http://codemirror.net/codemirror-latest.zip">development
+ snapshot</a> as zip files. To create a custom minified script file,
+ you can use the <a href="doc/compress.html">compression API</a>.</p>
+
+ <p>We use <a href="http://git-scm.com/">git</a> for version control.
+ The main repository can be fetched in this way:</p>
+
+ <pre class="code">git clone http://marijnhaverbeke.nl/git/codemirror</pre>
+
+ <p>CodeMirror can also be found on GitHub at <a
+ href="http://github.com/marijnh/CodeMirror">marijnh/CodeMirror</a>.
+ If you plan to hack on the code and contribute patches, the best way
+ to do it is to create a GitHub fork, and send pull requests.</p>
+
+ <h2 id="documention">Documentation</h2>
+
+ <p>The <a href="doc/manual.html">manual</a> is your first stop for
+ learning how to use this library. It starts with a quick explanation
+ of how to use the editor, and then describes the API in detail.</p>
+
+ <p>For those who want to learn more about the code, there is
+ an <a href="doc/internals.html">overview of the internals</a> available.
+ The <a href="http://github.com/marijnh/CodeMirror">source code</a>
+ itself is, for the most part, also well commented.</p>
+
+ <h2 id="support">Support and bug reports</h2>
+
+ <p>Community discussion, questions, and informal bug reporting is
+ done on
+ the <a href="http://groups.google.com/group/codemirror">CodeMirror
+ Google group</a>. There is a separate
+ group, <a href="http://groups.google.com/group/codemirror-announce">CodeMirror-announce</a>,
+ which is lower-volume, and is only used for major announcements—new
+ versions and such. These will be cross-posted to both groups, so you
+ don't need to subscribe to both.</p>
+
+ <p>Though bug reports through e-mail are responded to, the preferred
+ way to report bugs is to use
+ the <a href="http://github.com/marijnh/CodeMirror/issues">Github
+ issue tracker</a>. Before reporting a
+ bug, <a href="doc/reporting.html">read these pointers</a>. Also,
+ the issue tracker is for <em>bugs</em>, not requests for help.</p>
+
+ <p>When none of these seem fitting, you can
+ simply <a href="mailto:marijnh@gmail.com">e-mail the maintainer</a>
+ directly.</p>
+
+ <h2 id="supported">Supported browsers</h2>
+
+ <p>The following <em>desktop</em> browsers are able to run CodeMirror:</p>
+
+ <ul>
+ <li>Firefox 2 or higher</li>
+ <li>Chrome, any version</li>
+ <li>Safari 3 or higher</li>
+ <li>Opera 9 or higher (with some key-handling problems on OS X)</li>
+ <li>Internet Explorer 7 or higher in standards mode<br>
+ <em>(So not quirks mode. But quasi-standards mode with a
+ transitional doctype is also flaky. <code>&lt;!doctype
+ html></code> is recommended.)</em></li>
+ </ul>
+
+ <p>I am not actively testing against every new browser release, and
+ vendors have a habit of introducing bugs all the time, so I am
+ relying on the community to tell me when something breaks.
+ See <a href="#support">here</a> for information on how to contact
+ me.</p>
+
+ <p>Mobile browsers mostly kind of work, but, because of limitations
+ and their fundamentally different UI assumptions, show a lot of
+ quirks that are hard to work around.</p>
+
+ <h2 id="commercial">Commercial support</h2>
+
+ <p>CodeMirror is developed and maintained by me, Marijn Haverbeke,
+ in my own time. If your company is getting value out of CodeMirror,
+ please consider purchasing a support contract.</p>
+
+ <ul>
+ <li>You'll be funding further work on CodeMirror.</li>
+ <li>You ensure that you get a quick response when you have a
+ problem, even when I am otherwise busy.</li>
+ </ul>
+
+ <p>CodeMirror support contracts exist in two
+ forms—<strong>basic</strong> at €100 per month,
+ and <strong>premium</strong> at €500 per
+ month. <a href="mailto:marijnh@gmail.com">Contact me</a> for further
+ information.</p>
+
+</div>
+
+<div class="right blk">
+
+ <a href="http://codemirror.net/codemirror.zip" class="download">Download the latest release</a>
+
+ <h2>Support CodeMirror</h2>
+
+ <ul>
+ <li>Donate
+ (<span onclick="document.getElementById('paypal').submit();"
+ class="quasilink">Paypal</span>
+ or <span onclick="document.getElementById('bankinfo').style.display = 'block';"
+ class="quasilink">bank</span>)</li>
+ <li>Purchase <a href="#commercial">commercial support</a></li>
+ </ul>
+
+ <p id="bankinfo" style="display: none;">
+ Bank: <i>Rabobank</i><br/>
+ Country: <i>Netherlands</i><br/>
+ SWIFT: <i>RABONL2U</i><br/>
+ Account: <i>147850770</i><br/>
+ Name: <i>Marijn Haverbeke</i><br/>
+ IBAN: <i>NL26 RABO 0147 8507 70</i>
+ </p>
+
+ <h2>Reading material</h2>
+
+ <ul>
+ <li><a href="doc/manual.html">User manual</a></li>
+ <li><a href="http://github.com/marijnh/CodeMirror">Browse the code</a></li>
+ </ul>
+
+ <h2 id=releases>Releases</h2>
+
+ <p class="rel">19-09-2012: <a href="http://codemirror.net/codemirror-2.34.zip">Version 2.34</a>:</p>
+
+ <ul class="rel-note">
+ <li>New mode: <a href="mode/commonlisp/index.html">Common Lisp</a>.</li>
+ <li>Fix right-click select-all on most browsers.</li>
+ <li>Change the way highlighting happens:<br>&nbsp; Saves memory and CPU cycles.<br>&nbsp; <code>compareStates</code> is no longer needed.<br>&nbsp; <code>onHighlightComplete</code> no longer works.</li>
+ <li>Integrate mode (Markdown, XQuery, CSS, sTex) tests in central testsuite.</li>
+ <li>Add a <a href="doc/manual.html#version"><code>CodeMirror.version</code></a> property.</li>
+ <li>More robust handling of nested modes in <a href="demo/formatting.html">formatting</a> and <a href="demo/closetag.html">closetag</a> plug-ins.</li>
+ <li>Un/redo now preserves <a href="doc/manual.html#markText">marked text</a> and bookmarks.</li>
+ <li><a href="https://github.com/marijnh/CodeMirror/compare/v2.33...v2.34">Full list</a> of patches.</li>
+ </ul>
+
+ <p class="rel">19-09-2012: <a href="http://codemirror.net/codemirror-3.0beta1.zip">Version 3.0, beta 1</a>:</p>
+
+ <p class="rel-note"><strong>BETA release, new major version</strong>. Only partially
+ backwards-compatible. See
+ the <a href="http://codemirror.net/3/doc/upgrade_v3.html">upgrading
+ guide</a> for more information. Major new features are:</p>
+
+ <ul class="rel-note">
+ <li>Bi-directional text support.</li>
+ <li>More powerful gutter model.</li>
+ <li>Support for arbitrary text/widget height.</li>
+ <li>In-line widgets.</li>
+ <li>Generalized event handling.</li>
+ </ul>
+
+ <p class="rel">23-08-2012: <a href="http://codemirror.net/codemirror-2.33.zip">Version 2.33</a>:</p>
+
+ <ul class="rel-note">
+ <li>New mode: <a href="mode/sieve/index.html">Sieve</a>.</li>
+ <li>New <a href="doc/manual.html#getViewport"><code>getViewPort</code></a> and <a href="doc/manual.html#option_onViewportChange"><code>onViewportChange</code></a> API.</li>
+ <li><a href="doc/manual.html#option_cursorBlinkRate">Configurable</a> cursor blink rate.</li>
+ <li>Make binding a key to <code>false</code> disabling handling (again).</li>
+ <li>Show non-printing characters as red dots.</li>
+ <li>More tweaks to the scrolling model.</li>
+ <li>Expanded testsuite. Basic linter added.</li>
+ <li>Remove most uses of <code>innerHTML</code>. Remove <code>CodeMirror.htmlEscape</code>.</li>
+ <li><a href="https://github.com/marijnh/CodeMirror/compare/v2.32...v2.33">Full list</a> of patches.</li>
+ </ul>
+
+ <p class="rel">23-07-2012: <a href="http://codemirror.net/codemirror-2.32.zip">Version 2.32</a>:</p>
+
+ <p class="rel-note">Emergency fix for a bug where an editor with
+ line wrapping on IE will break when there is <em>no</em>
+ scrollbar.</p>
+
+ <p class="rel">20-07-2012: <a href="http://codemirror.net/codemirror-2.31.zip">Version 2.31</a>:</p>
+
+ <ul class="rel-note">
+ <li>New modes: <a href="mode/ocaml/index.html">OCaml</a>, <a href="mode/haxe/index.html">Haxe</a>, and <a href="mode/vb/index.html">VB.NET</a>.</li>
+ <li>Several fixes to the new scrolling model.</li>
+ <li>Add a <a href="doc/manual.html#setSize"><code>setSize</code></a> method for programmatic resizing.</li>
+ <li>Add <a href="doc/manual.html#getHistory"><code>getHistory</code></a> and <a href="doc/manual.html#setHistory"><code>setHistory</code></a> methods.</li>
+ <li>Allow custom line separator string in <a href="doc/manual.html#getValue"><code>getValue</code></a> and <a href="doc/manual.html#getRange"><code>getRange</code></a>.</li>
+ <li>Support double- and triple-click drag, double-clicking whitespace.</li>
+ <li>And more... <a href="https://github.com/marijnh/CodeMirror/compare/v2.3...v2.31">(all patches)</a></li>
+ </ul>
+
+ <p class="rel">22-06-2012: <a href="http://codemirror.net/codemirror-2.3.zip">Version 2.3</a>:</p>
+
+ <ul class="rel-note">
+ <li><strong>New scrollbar implementation</strong>. Should flicker less. Changes DOM structure of the editor.</li>
+ <li>New theme: <a href="demo/theme.html?vibrant-ink">vibrant-ink</a>.</li>
+ <li>Many extensions to the VIM keymap (including text objects).</li>
+ <li>Add <a href="demo/multiplex.html">mode-multiplexing</a> utility script.</li>
+ <li>Fix bug where right-click paste works in read-only mode.</li>
+ <li>Add a <a href="doc/manual.html#getScrollInfo"><code>getScrollInfo</code></a> method.</li>
+ <li>Lots of other <a href="https://github.com/marijnh/CodeMirror/compare/v2.25...v2.3">fixes</a>.</li>
+ </ul>
+
+ <p class="rel">23-05-2012: <a href="http://codemirror.net/codemirror-2.25.zip">Version 2.25</a>:</p>
+
+ <ul class="rel-note">
+ <li>New mode: <a href="mode/erlang/index.html">Erlang</a>.</li>
+ <li><strong>Remove xmlpure mode</strong> (use <a href="mode/xml/index.html">xml.js</a>).</li>
+ <li>Fix line-wrapping in Opera.</li>
+ <li>Fix X Windows middle-click paste in Chrome.</li>
+ <li>Fix bug that broke pasting of huge documents.</li>
+ <li>Fix backspace and tab key repeat in Opera.</li>
+ </ul>
+
+ <p class="rel">23-04-2012: <a href="http://codemirror.net/codemirror-2.24.zip">Version 2.24</a>:</p>
+
+ <ul class="rel-note">
+ <li><strong>Drop support for Internet Explorer 6</strong>.</li>
+ <li>New
+ modes: <a href="mode/shell/index.html">Shell</a>, <a href="mode/tiki/index.html">Tiki
+ wiki</a>, <a href="mode/pig/index.html">Pig Latin</a>.</li>
+ <li>New themes: <a href="demo/theme.html?ambiance">Ambiance</a>, <a href="demo/theme.html?blackboard">Blackboard</a>.</li>
+ <li>More control over drag/drop
+ with <a href="doc/manual.html#option_dragDrop"><code>dragDrop</code></a>
+ and <a href="doc/manual.html#option_onDragEvent"><code>onDragEvent</code></a>
+ options.</li>
+ <li>Make HTML mode a bit less pedantic.</li>
+ <li>Add <a href="doc/manual.html#compoundChange"><code>compoundChange</code></a> API method.</li>
+ <li>Several fixes in undo history and line hiding.</li>
+ <li>Remove (broken) support for <code>catchall</code> in key maps,
+ add <code>nofallthrough</code> boolean field instead.</li>
+ </ul>
+
+ <p class="rel">26-03-2012: <a href="http://codemirror.net/codemirror-2.23.zip">Version 2.23</a>:</p>
+
+ <ul class="rel-note">
+ <li>Change <strong>default binding for tab</strong> <a href="javascript:void(document.getElementById('tabbinding').style.display='')">[more]</a>
+ <div style="display: none" id=tabbinding>
+ Starting in 2.23, these bindings are default:
+ <ul><li>Tab: Insert tab character</li>
+ <li>Shift-tab: Reset line indentation to default</li>
+ <li>Ctrl/Cmd-[: Reduce line indentation (old tab behaviour)</li>
+ <li>Ctrl/Cmd-]: Increase line indentation (old shift-tab behaviour)</li>
+ </ul>
+ </div>
+ </li>
+ <li>New modes: <a href="mode/xquery/index.html">XQuery</a> and <a href="mode/vbscript/index.html">VBScript</a>.</li>
+ <li>Two new themes: <a href="mode/less/index.html">lesser-dark</a> and <a href="mode/xquery/index.html">xq-dark</a>.</li>
+ <li>Differentiate between background and text styles in <a href="doc/manual.html#setLineClass"><code>setLineClass</code></a>.</li>
+ <li>Fix drag-and-drop in IE9+.</li>
+ <li>Extend <a href="doc/manual.html#charCoords"><code>charCoords</code></a>
+ and <a href="doc/manual.html#cursorCoords"><code>cursorCoords</code></a> with a <code>mode</code> argument.</li>
+ <li>Add <a href="doc/manual.html#option_autofocus"><code>autofocus</code></a> option.</li>
+ <li>Add <a href="doc/manual.html#findMarksAt"><code>findMarksAt</code></a> method.</li>
+ </ul>
+
+ <p class="rel">27-02-2012: <a href="http://codemirror.net/codemirror-2.22.zip">Version 2.22</a>:</p>
+
+ <ul class="rel-note">
+ <li>Allow <a href="doc/manual.html#keymaps">key handlers</a> to pass up events, allow binding characters.</li>
+ <li>Add <a href="doc/manual.html#option_autoClearEmptyLines"><code>autoClearEmptyLines</code></a> option.</li>
+ <li>Properly use tab stops when rendering tabs.</li>
+ <li>Make PHP mode more robust.</li>
+ <li>Support indentation blocks in <a href="doc/manual.html#util_foldcode">code folder</a>.</li>
+ <li>Add a script for <a href="doc/manual.html#util_match-highlighter">highlighting instances of the selection</a>.</li>
+ <li>New <a href="mode/properties/index.html">.properties</a> mode.</li>
+ <li>Fix many bugs.</li>
+ </ul>
+
+ <p class="rel">27-01-2012: <a href="http://codemirror.net/codemirror-2.21.zip">Version 2.21</a>:</p>
+
+ <ul class="rel-note">
+ <li>Added <a href="mode/less/index.html">LESS</a>, <a href="mode/mysql/index.html">MySQL</a>,
+ <a href="mode/go/index.html">Go</a>, and <a href="mode/verilog/index.html">Verilog</a> modes.</li>
+ <li>Add <a href="doc/manual.html#option_smartIndent"><code>smartIndent</code></a>
+ option.</li>
+ <li>Support a cursor in <a href="doc/manual.html#option_readOnly"><code>readOnly</code></a>-mode.</li>
+ <li>Support assigning multiple styles to a token.</li>
+ <li>Use a new approach to drawing the selection.</li>
+ <li>Add <a href="doc/manual.html#scrollTo"><code>scrollTo</code></a> method.</li>
+ <li>Allow undo/redo events to span non-adjacent lines.</li>
+ <li>Lots and lots of bugfixes.</li>
+ </ul>
+
+ <p class="rel">20-12-2011: <a href="http://codemirror.net/codemirror-2.2.zip">Version 2.2</a>:</p>
+
+ <ul class="rel-note">
+ <li>Slightly incompatible API changes. Read <a href="doc/upgrade_v2.2.html">this</a>.</li>
+ <li>New approach
+ to <a href="doc/manual.html#option_extraKeys">binding</a> keys,
+ support for <a href="doc/manual.html#option_keyMap">custom
+ bindings</a>.</li>
+ <li>Support for overwrite (insert).</li>
+ <li><a href="doc/manual.html#option_tabSize">Custom-width</a>
+ and <a href="demo/visibletabs.html">stylable</a> tabs.</li>
+ <li>Moved more code into <a href="doc/manual.html#addons">add-on scripts</a>.</li>
+ <li>Support for sane vertical cursor movement in wrapped lines.</li>
+ <li>More reliable handling of
+ editing <a href="doc/manual.html#markText">marked text</a>.</li>
+ <li>Add minimal <a href="demo/emacs.html">emacs</a>
+ and <a href="demo/vim.html">vim</a> bindings.</li>
+ <li>Rename <code>coordsFromIndex</code>
+ to <a href="doc/manual.html#posFromIndex"><code>posFromIndex</code></a>,
+ add <a href="doc/manual.html#indexFromPos"><code>indexFromPos</code></a>
+ method.</li>
+ </ul>
+
+ <p><a href="doc/oldrelease.html">Older releases...</a></p>
+
+</div></div>
+
+<div style="height: 2em">&nbsp;</div>
+
+ <form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="paypal">
+ <input type="hidden" name="cmd" value="_s-xclick"/>
+ <input type="hidden" name="hosted_button_id" value="3FVHS5FGUY7CC"/>
+ </form>
+
+ </body>
+</html>
View
29 libs/codemirror/keymap/emacs.js
@@ -0,0 +1,29 @@
+// TODO number prefixes
+(function() {
+ // Really primitive kill-ring implementation.
+ var killRing = [];
+ function addToRing(str) {
+ killRing.push(str);
+ if (killRing.length > 50) killRing.shift();
+ }
+ function getFromRing() { return killRing[killRing.length - 1] || ""; }
+ function popFromRing() { if (killRing.length > 1) killRing.pop(); return getFromRing(); }
+
+ CodeMirror.keyMap.emacs = {
+ "Ctrl-X": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-X");},
+ "Ctrl-W": function(cm) {addToRing(cm.getSelection()); cm.replaceSelection("");},
+ "Ctrl-Alt-W": function(cm) {addToRing(cm.getSelection()); cm.replaceSelection("");},
+ "Alt-W": function(cm) {addToRing(cm.getSelection());},
+ "Ctrl-Y": function(cm) {cm.replaceSelection(getFromRing());},
+ "Alt-Y": function(cm) {cm.replaceSelection(popFromRing());},
+ "Ctrl-/": "undo", "Shift-Ctrl--": "undo", "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
+ "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace",
+ "Ctrl-Z": "undo", "Cmd-Z": "undo", "Alt-/": "autocomplete",
+ fallthrough: ["basic", "emacsy"]
+ };
+
+ CodeMirror.keyMap["emacs-Ctrl-X"] = {
+ "Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": "undo", "K": "close",
+ auto: "emacs", nofallthrough: true
+ };
+})();
View
789 libs/codemirror/keymap/vim.js
@@ -0,0 +1,789 @@
+// Supported keybindings:
+//
+// Cursor movement:
+// h, j, k, l
+// e, E, w, W, b, B
+// Ctrl-f, Ctrl-b
+// Ctrl-n, Ctrl-p
+// $, ^, 0
+// G
+// ge, gE
+// gg
+// f<char>, F<char>, t<char>, T<char>
+// Ctrl-o, Ctrl-i TODO (FIXME - Ctrl-O wont work in Chrome)
+// /, ?, n, N TODO (does not work)
+// #, * TODO
+//
+// Entering insert mode:
+// i, I, a, A, o, O
+// s
+// ce, cb (without support for number of actions like c3e - TODO)
+// cc
+// S, C TODO
+// cf<char>, cF<char>, ct<char>, cT<char>
+//
+// Deleting text:
+// x, X
+// J
+// dd, D
+// de, db (without support for number of actions like d3e - TODO)
+// df<char>, dF<char>, dt<char>, dT<char>
+//
+// Yanking and pasting:
+// yy, Y
+// p, P
+// p'<char> TODO - test
+// y'<char> TODO - test
+// m<char> TODO - test
+//
+// Changing text in place:
+// ~
+// r<char>
+//
+// Visual mode:
+// v, V TODO
+//
+// Misc:
+// . TODO
+//
+
+(function() {
+ var count = "";
+ var sdir = "f";
+ var buf = "";
+ var yank = 0;
+ var mark = [];
+ var reptTimes = 0;
+ function emptyBuffer() { buf = ""; }
+ function pushInBuffer(str) { buf += str; }
+ function pushCountDigit(digit) { return function(cm) {count += digit;}; }
+ function popCount() { var i = parseInt(count, 10); count = ""; return i || 1; }
+ function iterTimes(func) {
+ for (var i = 0, c = popCount(); i < c; ++i) func(i, i == c - 1);
+ }
+ function countTimes(func) {
+ if (typeof func == "string") func = CodeMirror.commands[func];
+ return function(cm) { iterTimes(function () { func(cm); }); };
+ }
+
+ function iterObj(o, f) {
+ for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]);
+ }
+ function iterList(l, f) {
+ for (var i = 0; i < l.length; ++i) f(l[i]);
+ }
+ function toLetter(ch) {
+ // T -> t, Shift-T -> T, '*' -> *, "Space" -> " "
+ if (ch.slice(0, 6) == "Shift-") {
+ return ch.slice(0, 1);
+ } else {
+ if (ch == "Space") return " ";
+ if (ch.length == 3 && ch[0] == "'" && ch[2] == "'") return ch[1];
+ return ch.toLowerCase();
+ }
+ }
+ var SPECIAL_SYMBOLS = "~`!@#$%^&*()_-+=[{}]\\|/?.,<>:;\"\'1234567890";
+ function toCombo(ch) {
+ // t -> T, T -> Shift-T, * -> '*', " " -> "Space"
+ if (ch == " ") return "Space";
+ var specialIdx = SPECIAL_SYMBOLS.indexOf(ch);
+ if (specialIdx != -1) return "'" + ch + "'";
+ if (ch.toLowerCase() == ch) return ch.toUpperCase();
+ return "Shift-" + ch.toUpperCase();
+ }
+
+ var word = [/\w/, /[^\w\s]/], bigWord = [/\S/];
+ function findWord(line, pos, dir, regexps) {
+ var stop = 0, next = -1;
+ if (dir > 0) { stop = line.length; next = 0; }
+ var start = stop, end = stop;
+ // Find bounds of next one.
+ outer: for (; pos != stop; pos += dir) {
+ for (var i = 0; i < regexps.length; ++i) {
+ if (regexps[i].test(line.charAt(pos + next))) {
+ start = pos;
+ for (; pos != stop; pos += dir) {
+ if (!regexps[i].test(line.charAt(pos + next))) break;
+ }
+ end = pos;
+ break outer;
+ }
+ }
+ }
+ return {from: Math.min(start, end), to: Math.max(start, end)};
+ }
+ function moveToWord(cm, regexps, dir, times, where) {
+ var cur = cm.getCursor();
+
+ for (var i = 0; i < times; i++) {
+ var line = cm.getLine(cur.line), startCh = cur.ch, word;
+ while (true) {
+ // If we're at start/end of line, start on prev/next respectivly
+ if (cur.ch == line.length && dir > 0) {
+ cur.line++;
+ cur.ch = 0;
+ line = cm.getLine(cur.line);
+ } else if (cur.ch == 0 && dir < 0) {
+ cur.line--;
+ cur.ch = line.length;
+ line = cm.getLine(cur.line);
+ }
+ if (!line) break;
+
+ // On to the actual searching
+ word = findWord(line, cur.ch, dir, regexps);
+ cur.ch = word[where == "end" ? "to" : "from"];
+ if (startCh == cur.ch && word.from != word.to) cur.ch = word[dir < 0 ? "from" : "to"];
+ else break;
+ }
+ }
+ return cur;
+ }
+ function joinLineNext(cm) {
+ var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line);
+ CodeMirror.commands.goLineEnd(cm);
+ if (cur.line != cm.lineCount()) {
+ CodeMirror.commands.goLineEnd(cm);
+ cm.replaceSelection(" ", "end");
+ CodeMirror.commands.delCharRight(cm);
+ }
+ }
+ function delTillMark(cm, cHar) {
+ var i = mark[cHar];
+ if (i === undefined) {
+ // console.log("Mark not set"); // TODO - show in status bar
+ return;
+ }
+ var l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
+ cm.setCursor(start);
+ for (var c = start; c <= end; c++) {
+ pushInBuffer("\n"+cm.getLine(start));
+ cm.removeLine(start);
+ }
+ }
+ function yankTillMark(cm, cHar) {
+ var i = mark[cHar];
+ if (i === undefined) {
+ // console.log("Mark not set"); // TODO - show in status bar
+ return;
+ }
+ var l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
+ for (var c = start; c <= end; c++) {
+ pushInBuffer("\n"+cm.getLine(c));
+ }
+ cm.setCursor(start);
+ }
+ function goLineStartText(cm) {
+ // Go to the start of the line where the text begins, or the end for whitespace-only lines
+ var cur = cm.getCursor(), firstNonWS = cm.getLine(cur.line).search(/\S/);
+ cm.setCursor(cur.line, firstNonWS == -1 ? line.length : firstNonWS, true);
+ }
+
+ function charIdxInLine(cm, cHar, motion_options) {
+ // Search for cHar in line.
+ // motion_options: {forward, inclusive}
+ // If inclusive = true, include it too.
+ // If forward = true, search forward, else search backwards.
+ // If char is not found on this line, do nothing
+ var cur = cm.getCursor(), line = cm.getLine(cur.line), idx;
+ var ch = toLetter(cHar), mo = motion_options;
+ if (mo.forward) {
+ idx = line.indexOf(ch, cur.ch + 1);
+ if (idx != -1 && mo.inclusive) idx += 1;
+ } else {
+ idx = line.lastIndexOf(ch, cur.ch);
+ if (idx != -1 && !mo.inclusive) idx += 1;
+ }
+ return idx;
+ }
+
+ function moveTillChar(cm, cHar, motion_options) {
+ // Move to cHar in line, as found by charIdxInLine.
+ var idx = charIdxInLine(cm, cHar, motion_options), cur = cm.getCursor();
+ if (idx != -1) cm.setCursor({line: cur.line, ch: idx});
+ }
+
+ function delTillChar(cm, cHar, motion_options) {
+ // delete text in this line, untill cHar is met,
+ // as found by charIdxInLine.
+ // If char is not found on this line, do nothing
+ var idx = charIdxInLine(cm, cHar, motion_options);
+ var cur = cm.getCursor();
+ if (idx !== -1) {
+ if (motion_options.forward) {
+ cm.replaceRange("", {line: cur.line, ch: cur.ch}, {line: cur.line, ch: idx});
+ } else {
+ cm.replaceRange("", {line: cur.line, ch: idx}, {line: cur.line, ch: cur.ch});
+ }
+ }
+ }
+
+ function enterInsertMode(cm) {
+ // enter insert mode: switch mode and cursor
+ popCount();
+ cm.setOption("keyMap", "vim-insert");
+ }
+
+ function dialog(cm, text, shortText, f) {
+ if (cm.openDialog) cm.openDialog(text, f);
+ else f(prompt(shortText, ""));
+ }
+ function showAlert(cm, text) {
+ var esc = text.replace(/[<&]/, function(ch) { return ch == "<" ? "&lt;" : "&amp;"; });
+ if (cm.openDialog) cm.openDialog(esc + " <button type=button>OK</button>");
+ else alert(text);
+ }
+
+ // main keymap
+ var map = CodeMirror.keyMap.vim = {
+ // Pipe (|); TODO: should be *screen* chars, so need a util function to turn tabs into spaces?
+ "'|'": function(cm) {
+ cm.setCursor(cm.getCursor().line, popCount() - 1, true);
+ },
+ "A": function(cm) {
+ cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true);
+ enterInsertMode(cm);
+ },
+ "Shift-A": function(cm) { CodeMirror.commands.goLineEnd(cm); enterInsertMode(cm);},
+ "I": function(cm) { enterInsertMode(cm);},
+ "Shift-I": function(cm) { goLineStartText(cm); enterInsertMode(cm);},
+ "O": function(cm) {
+ CodeMirror.commands.goLineEnd(cm);
+ CodeMirror.commands.newlineAndIndent(cm);
+ enterInsertMode(cm);
+ },
+ "Shift-O": function(cm) {
+ CodeMirror.commands.goLineStart(cm);
+ cm.replaceSelection("\n", "start");
+ cm.indentLine(cm.getCursor().line);
+ enterInsertMode(cm);
+ },
+ "G": function(cm) { cm.setOption("keyMap", "vim-prefix-g");},
+ "Shift-D": function(cm) {
+ // commented out verions works, but I left original, cause maybe
+ // I don't know vim enouth to see what it does
+ /* var cur = cm.getCursor();
+ var f = {line: cur.line, ch: cur.ch}, t = {line: cur.line};
+ pushInBuffer(cm.getRange(f, t));
+ */
+ emptyBuffer();
+ mark["Shift-D"] = cm.getCursor(false).line;
+ cm.setCursor(cm.getCursor(true).line);
+ delTillMark(cm,"Shift-D"); mark = [];
+ },
+
+ "S": function (cm) {
+ countTimes(function (_cm) {
+ CodeMirror.commands.delCharRight(_cm);
+ })(cm);
+ enterInsertMode(cm);
+ },
+ "M": function(cm) {cm.setOption("keyMap", "vim-prefix-m"); mark = [];},
+ "Y": function(cm) {cm.setOption("keyMap", "vim-prefix-y"); emptyBuffer(); yank = 0;},
+ "Shift-Y": function(cm) {