Compare commits

...

122 Commits

Author SHA1 Message Date
Deven Bansod
019bc58ea2
Merge pull request #14639 from Piyush3079/Mod_Js_Common_Files
Modular code for some of the common files
2018-10-18 18:23:59 +05:30
Piyush Vijay
673e82e6a6
version fixture for webpack to prevent updated version installation.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-10-10 08:37:05 +05:30
Piyush Vijay
fd4e5f0c54
Remove some of the duplicate files for code cleanup.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-09-20 05:25:39 +05:30
Piyush Vijay
b5824ef13e
Structure some code for replication.js and tbl_operation.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-09-20 05:24:35 +05:30
Piyush Vijay
074c5063ab
Whitelist RTE.js in modular code and add some related function for sliding messages in show_ajax_messages.js.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-09-20 04:38:09 +05:30
Piyush Vijay
12781a3f97
Add Routines, Triggers and Events in the modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-09-20 04:36:42 +05:30
Piyush Vijay
b7371e418d
Add Table Normalization in modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-09-07 19:59:12 +05:30
Piyush Vijay
66ddb3a6af
Add Drag and Drop Import in modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-09-07 18:56:52 +05:30
Piyush Vijay
747bf54f99
Add KeyHandler and CrossFramingProtection file in modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-09-07 18:24:57 +05:30
Deven Bansod
e12e38bd37
Merge pull request #14584 from Piyush3079/Mod_Js_DST_Cleanup
Code cleanup for Server, Database and Table related files
2018-08-28 10:30:16 +05:30
Piyush Vijay
f08db2e8a8
Some code structured for PMA Console
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-23 07:28:10 +05:30
Piyush Vijay
2950e2b269
Some common files removed for code cleanup.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-23 06:46:16 +05:30
Piyush Vijay
2bd0206f22
Some code structuring for database related files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-21 06:10:48 +05:30
Piyush Vijay
1084952b1f
Remove duplicate files for database related pages.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-21 06:08:09 +05:30
Piyush Vijay
bb72bc2ddc Some code structuring for table related files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-21 05:52:53 +05:30
Piyush Vijay
181bfb5849 Remove table related files not needed in modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-21 05:52:41 +05:30
Piyush Vijay
f7b33b00e9 Code restructuring and comments for serve related files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-21 05:51:53 +05:30
Piyush Vijay
d1e4477191 Sync the branch with master.
Remove server related files for code cleanup.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-21 05:51:40 +05:30
Deven Bansod
d031dec87a
Merge pull request #14564 from Piyush3079/Mod_Js_Tbl_Structure
Modular code for table structure and table related files
2018-08-19 16:24:09 +05:30
Piyush Vijay
5f4db91d71
Resolve merge conflicts and add tbl import and export in modular code
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 15:29:58 +05:30
Piyush Vijay
0ce9714c19 Modular code for tbl_find_replace.php
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
65a54b8d74 Modular code for tbl_select.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
c1f6c86a6d Edit php files for changes related to tbl_change.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
0f7a7c33c8 Modular code for tbl_change.php.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
5647d8c84c Modular code for tbl_tracking.php
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
302eaf5767 Remove .js extention from tbl_operations.php file to allow dynamic import.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
dcad9d0c79 Modular code for tbl_operations.php
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
0e44376dc8 Remove .js extension from files and remove jqplot plugins which are not deened to be loaded in head of page.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
f6b5d2d345 Modular code for tbl_chart for dawing charts on Table Browsing
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
8ac17c037e Remove .js extension from tbl_relation.php related files for dynamic loading.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
d521643f7d Modular code for tbl_relation.php.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
83519079bb Remove .js extension from tbl_structure.php related files to allow dynamic imports.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
aebde04e00 Modular code for tbl_structure.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
17958e8d8b Remove .js extension from php files for indexes.js to allow dynami import.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:44:00 +05:30
Piyush Vijay
3e8e825d35 Modular code for indexes.js being used on different pages.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:43:58 +05:30
Piyush Vijay
2558661648 Add PMA_showHints function in show_ajax_messages.js in js/src/utils and PMA_initSlider in Slider.js.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-19 13:34:04 +05:30
Deven Bansod
0c3411587a
Merge pull request #14533 from Piyush3079/Mod_Js_Db_Structure
Modular code for Database Structure and some other database related files
2018-08-19 10:01:20 +05:30
Piyush Vijay
03c0067343
Bug fix for multi table actions on db_structure.php
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-18 12:26:48 +05:30
Piyush Vijay
c0856b2310
Resolve merge conflicts and some code cleanup for functions.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:57:21 +05:30
Piyush Vijay
bfc9d62d43 Replace .js extension from db_export and db_import.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:55:25 +05:30
Piyush Vijay
b8bbd86558 Add central columns to the modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:55:25 +05:30
Piyush Vijay
353fa83e2a Add db_tracking.js for tracking tables of database in modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:55:25 +05:30
Piyush Vijay
9fc572d4fc Create FileHandler class to manage loading of files on the basis of page and on the basis of user preferences.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:55:25 +05:30
Piyush Vijay
0a979865e1 Add db_operations.js to modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:55:24 +05:30
Piyush Vijay
5e10b2c6b7 Edit js/src/functions.js to add functions required for create table in db_structure.php.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:55:12 +05:30
Piyush Vijay
6e790e72e5 Add CreateTable and TableColumns module for adding table in db_structure.php.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:55:12 +05:30
Piyush Vijay
eae0c753bb Add prepare_ajax_request and preview_sql to modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:55:10 +05:30
Piyush Vijay
f2cc2344d5 Bug fix for ajax server side error.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-17 13:54:29 +05:30
Piyush Vijay
65943162ae Add db_structure.js in modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-16 20:37:21 +05:30
Deven Bansod
5b1c1a2ce1
Merge pull request #14518 from Piyush3079/Mod_Js_Sql_Profiling
Add modular code for profiling of sql queries on related pages and structured some code
2018-08-16 20:26:51 +05:30
Piyush Vijay
fd21247e53
Resolve merge conflicts
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-15 15:28:25 +05:30
Piyush Vijay
6a4496ee42 Add multi column sort for tbl_sql.php and db_sql.php
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-15 15:15:00 +05:30
Piyush Vijay
a407ac90fc Bug fix for teardown of page.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-15 15:15:00 +05:30
Piyush Vijay
5b7079e9ff Profiling working on table browsing and on running sql queries.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-15 15:14:42 +05:30
Deven Bansod
fc72f0d739
Merge pull request #14493 from Piyush3079/Mod_Js_Sql_Js
Add Modular code for sql query box (page) and codemirror related pages
2018-08-14 09:52:04 -07:00
Piyush Vijay
5240ca612d Add jsoc to create documentation of JavaScript code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-14 18:31:52 +05:30
Piyush Vijay
6f20ffdf64 Resolving merge errors.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-14 18:31:51 +05:30
Piyush Vijay
1e00de8e3a Separating sorting functions from multi_column_sort file.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-14 18:11:20 +05:30
Piyush Vijay
1c3660d213 Comment code in js/functions.js to disable tirggering of codemirror loading from js/functions.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-14 18:11:18 +05:30
Piyush Vijay
5e3e36e61d Add multi column sort in server_sql for add and remove column sort on table browse.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:38:47 +05:30
Piyush Vijay
3ae93ad307 Add modular Sql.js to table sql and database sql and SqlQueryForm modified accordingly
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:38:47 +05:30
Piyush Vijay
661c9f74d4 Ctrl plus enter to submit query event in functions.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:38:47 +05:30
Piyush Vijay
cc754839e7 Updating Sql utility function file, sql source file containing code for various sql related events, adding function for sql editor and inline sql editor in functions.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:38:47 +05:30
Piyush Vijay
7d472508b7 Adding variable used for codemirror in the head of the page at the top of the scripts.
Imports changes as per new directory stucture for sql.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:38:42 +05:30
Piyush Vijay
8506ce9d91 Adding codemirror in pma console.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:38:32 +05:30
Piyush Vijay
2c9118e781 Edit codemirror sql plugin for modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:38:21 +05:30
Piyush Vijay
c9ac456d97 Separating basic functions needed for initialising codemirror and inline codemirror, saving and getting saved queries and making profiling charts.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:37:39 +05:30
Piyush Vijay
91afae1798 No need to review this commit as these files are directly copied from old vendor and plugins folder. These files can be ignored during review.
They are not availabe as npm mpdule right now and their alternative are largerr in size with the same functionality.
So they are being used as it is.
Their size will be reduced in the outpul bundle after using webpack plugins to emove comments from js files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:37:39 +05:30
Piyush Vijay
63a54d14f3 Adding jQplot package and its plugins and tablesorter are as module in js files and removed from php files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:37:25 +05:30
Piyush Vijay
2c643597fd Edit package.json for updated-jqplot package. Adding eslint scripts and script for creating production build edited
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:36:58 +05:30
Piyush Vijay
8c986d8308 Weekly progress.
1). Microhistory added in classes for modular code
2). Code is structured and camel casing of varables is done for removing linter warnings.
3). JQuery plugins are added in some files.
4). jQplot is working for server_status_queries and server_status_monitor.
5). Work started for Dabatase, SQl and Table files.
Some changes are stll left for server_status_monitor and sql.js
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-10 13:36:58 +05:30
Deven Bansod
24f91b16f9
Merge pull request #14524 from Piyush3079/Mod_Js_Structuring_1
Modularize JS files related to Structure
2018-08-09 06:52:30 -07:00
Piyush Vijay
b4237acf18
Use import * for files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-09 19:12:28 +05:30
Piyush Vijay
c0810f98b2 Some more javascript files structured properly.
Shortcut handler and page settings js files added in modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-09 18:44:36 +05:30
Piyush Vijay
91340d18e5 Test files changed as per the new chages in FormDisplayTemplate.
Js code is stuctured properly with comments.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-07 18:34:12 +05:30
Deven Bansod
0e16cc519e
Merge pull request #14470 from Piyush3079/Mod_Js_Config_Js
Modularized Config.js and add build script
2018-08-06 17:41:04 -07:00
Piyush Vijay
733b0296b3
Test fixtures for travis.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-03 18:04:59 +05:30
Piyush Vijay
61e97801d4 Pass env variable to webpack.config file for making production build.
Build script for js files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-02 20:54:53 +05:30
Piyush Vijay
0b5c9b3eea Add isStorageSupport in functions.js for code compatibility and add config.js in file loading object.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-02 20:54:53 +05:30
Piyush Vijay
5463dabca7 Commented code removed and debug statements removed.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-02 20:54:50 +05:30
Piyush Vijay
3a754dc340 Config.js is modularised.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-01 20:03:06 +05:30
Piyush Vijay
5e04669d74
Add config related imports in files to use config.js in modular code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-08-01 20:02:33 +05:30
Deven Bansod
5e9d70540b
Merge pull request #14469 from Piyush3079/Mod_Js_Import_Export
Modularize Import and Export related JS files
2018-08-01 16:48:17 +05:30
Piyush Vijay
d111a2ca81 Add event for submit of export sql form to remove error of undefined function.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-30 23:10:53 +05:30
Piyush Vijay
85c16c14f8 Remove some functions to make this pr reproduceable on local machine.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-30 23:10:44 +05:30
Piyush Vijay
a99acfef71 Modularize server related remaining files like replication, plugins, queries, processes.
Sever monitor is also modularised and is not working but jQplot is not imported as it is giving error with webpack.
Another issue with these files is that table sorter is also not woking
working properly as it is not available on npm as plugin.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-30 23:08:28 +05:30
Piyush Vijay
f92e1ebccd Edit ndex files and more files whitelisted in ajax.js and files.js for
adding them in modular code.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-30 23:07:43 +05:30
Deven Bansod
00e9049f44
Merge pull request #14468 from Piyush3079/Mod_Js_Navigation
Modularize PMA Navigation JS files
2018-07-30 16:05:27 +05:30
Piyush Vijay
9727a9450f Remove caching of common_params.php to avoid stoing token in cache on login and logout again.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-30 01:37:44 +05:30
Piyush Vijay
2f3eeae68d Fallback for new Modularize navigation. Both old and new code included in Header.php
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-30 01:37:44 +05:30
Piyush Vijay
5c54cdcb69 File names changed for revamped javascript files in php files.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-30 01:37:42 +05:30
Piyush Vijay
b52b7a3422 Navigation revamped, navigation functions separated from main file. More file names added in ajax and index.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-29 17:08:10 +05:30
Piyush Vijay
0ae42e5aa9 Import highlight_sql module in show_ajax_messages.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-29 17:07:42 +05:30
Deven Bansod
ed6f106470
Merge pull request #14467 from Piyush3079/Mod_Js_Server_Status
Modularize Server Status JS files
2018-07-28 18:19:16 +05:30
Piyush Vijay
84d0e8045b
Big fix for kill button and autoRefresh button on server_status_processes.php page.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-28 18:02:58 +05:30
Piyush Vijay
b7ee22a203 remove .js extension from relevant php files and add those files in ajax for dynamic loading.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-27 22:19:42 +05:30
Piyush Vijay
30b5f072f9 Commented code and debug statements removed from server status related files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-27 22:19:42 +05:30
Piyush Vijay
a85fb3d3f6 Revamp server_status_advisor, server_status_variables, sever_status_processes.
Add codemirror package in server_privileges.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-27 22:19:17 +05:30
Deven Bansod
ff81454539
Merge pull request #14466 from Piyush3079/Mod_Js_Console
Modularize Console and Error Report files
2018-07-27 20:55:01 +05:30
Piyush Vijay
de78e7911b Bug fix for undefined variables and PMA_Console in working state now.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-27 20:53:09 +05:30
Piyush Vijay
e18c6b9818 Fix error reporting functionality ajax callback errors .
TODO: To find a way to wrap the exported functions containing PMA_ prefix into the error handler to generate backtrace.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-27 20:52:15 +05:30
Piyush Vijay
91178f0029 Break PMA_Console JS code into classes and imports.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-27 20:51:52 +05:30
Deven Bansod
dfcca3c46e
Merge pull request #14465 from Piyush3079/Mod_Js_Server_Privileges
server_privileges and server_databases modularized
2018-07-26 19:50:48 +05:30
Piyush Vijay
ae20a38e97 Add babel-eslint package to use eslint for features not yet included in eslint.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:26 +05:30
Piyush Vijay
d5eb59bb62 Bug fix for token mismatch error on server_databases.php page.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:26 +05:30
Piyush Vijay
177e101379 Bux fix for onload and teardown of pages on refresh and ajax requests.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:26 +05:30
Piyush Vijay
5402f43840 Modify ajax.js and Header.php for compatibility of both old code and new code.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:26 +05:30
Piyush Vijay
ce8d11c858 Add todo for code that will not be used in future after revamping all
the files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:26 +05:30
Piyush Vijay
8111151049 Replace default validation strings with custom strings to enable localization for validation messages with jquery.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:26 +05:30
Piyush Vijay
9d51a83625 Review changes for adding file level comments for some files.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:26 +05:30
Piyush Vijay
491b4871a7 Commented code, debug statements and unused variable in Script.php is removed.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:25 +05:30
Piyush Vijay
b712019735 AJAX handler modified and initial loading of the first page handled
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:25 +05:30
Piyush Vijay
56ea9d27fc server_privilages and server_databases modularized
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:25 +05:30
Piyush Vijay
c67854e2a3 New directory Stucture having modules imported and exported.
This commit needs proper discussion as many of the upcoming changes are based on this commit.
These files contains the working code only.
Right now the code has the functionality to work with both old js files and new js files.
Commeting style is yet to decide
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:25 +05:30
Piyush Vijay
38cfa4630c Some functions moved from server_privilages.js to functions.js and typo error removed
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-26 02:31:25 +05:30
Deven Bansod
224ae6d86b
Merge pull request #14464 from Piyush3079/Mod_Js_Config
* Files for babel, eslint and webpack base configuration and add respective modules in package manager.
Add script in package.json for building js files using webpack.

* Module for importing variable defined in messages.php.

* Some changes in the configuration to revamp file by file not whole directory, environment variable introduced

* Update documentation for the new configuration variables introduced
and adding comments for some code handleing new js files.

* Update node version for scrutinizer. Add webpack environment directives in default.config. Introduce webpack_host and webpack_port
directive and updating package.json build scripts.

* Typo fixes for documentation and comments and webpack configuration directives are added in webpack.config
2018-07-18 17:12:43 +05:30
Piyush Vijay
4d3a8c9e5c
Typo fixes for documentation and comments and webpack configuration directives are added in webpack.config
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-16 20:58:33 +05:30
Piyush Vijay
3d9e65674c Update node version for scrutinizer. Add webpack environment directives in default.config. Introduce webpack_host and webpack_port
directive and updating package.json build scripts.
Signed-Off-By: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-15 22:00:49 +05:30
Piyush Vijay
3e56b17bc6 Update documentation for the new configuration variables introduced
and adding comments for some code handleing new js files.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-15 22:00:31 +05:30
Piyush Vijay
59ef2b9159 Some changes in the configuration to revamp file by file not whole directory, environment variable introduced
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-15 22:00:21 +05:30
Piyush Vijay
10d545c621 Module for importing variable defined in messages.php.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-15 22:00:17 +05:30
Piyush Vijay
d80a8ba3dd Files for babel, eslint and webpack base configuration and add respective modules in package manager.
Add script in package.json for building js files using webpack.
Signed-off-by: Piyush Vijay <piyushvijay.1997@gmail.com>
2018-07-15 21:58:14 +05:30
202 changed files with 21939 additions and 6822 deletions

4
.babelrc Normal file
View File

@ -0,0 +1,4 @@
{
"presets": ["env"],
"plugins": ["syntax-dynamic-import"]
}

View File

@ -1,3 +1,6 @@
js/vendor/
tmp/
vendor/
js/dist/
js/lib/
js/src/plugins/

View File

@ -1,7 +1,19 @@
{
"env": {
"browser": true,
"jquery": true
"jquery": true,
"node": true,
"es6": true
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"allowImportExportEverywhere": true,
"codeFrame": false,
"ecmaFeatures": {
"jsx": false
}
},
"rules": {
"array-bracket-spacing": "error",

4
.gitignore vendored
View File

@ -55,3 +55,7 @@ composer.lock
/vendor/
# NPM
/node_modules/
yarn.lock
# Javascript Bundle
js/dist/
js/lib/

30
.jsdoc.json Normal file
View File

@ -0,0 +1,30 @@
{
"tags": {
"allowUnknownTags": true,
"dictionaries": ["jsdoc", "closure"]
},
"recurseDepth": 10,
"source": {
"include": ["js/src/", "package.json"],
"includePattern": ".js$",
"exclude": ["js/src/plugins"],
"excludePattern": "(node_modules/|docs)"
},
"sourceType": "module",
"plugins": [
"plugins/markdown"
],
"templates": {
"cleverLinks": true,
"monospaceLinks": true,
"useLongnameInNav": false,
"showInheritedInNav": true
},
"opts": {
"destination": "./doc/js/",
"encoding": "utf8",
"private": true,
"recurse": true,
"template": "./node_modules/minami"
}
}

View File

@ -5,6 +5,9 @@
// Globals
"jquery" : true,
// ES6
"esversion": 6,
// Stricter checking
"curly" : true,
"immed" : true,

View File

@ -12,6 +12,7 @@ build:
test:
environment:
php: 7.1
node: '8.11.3'
dependencies:
before:
- composer install

View File

@ -93,9 +93,7 @@ if (isset($_POST['add_column'])) {
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('db_central_columns.js');
$scripts->addFile('db_central_columns');
$cfgCentralColumns = $centralColumns->getParams();
$pmadb = $cfgCentralColumns['db'];
$pmatable = $cfgCentralColumns['table'];

View File

@ -24,7 +24,7 @@ PageSettings::showGroup('Export');
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('export.js');
$scripts->addFile('export');
$export = new Export();

View File

@ -18,7 +18,7 @@ PageSettings::showGroup('Import');
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('import.js');
$scripts->addFile('import');
$import = new Import();

View File

@ -38,7 +38,7 @@ require_once 'libraries/check_user_privileges.inc.php';
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('db_operations.js');
$scripts->addFile('db_operations');
$sql_query = '';

View File

@ -21,9 +21,8 @@ require_once 'libraries/common.inc.php';
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('db_search.js');
$scripts->addFile('sql.js');
$scripts->addFile('makegrid.js');
$scripts->addFile('db_search');
$scripts->addFile('sql');
require 'libraries/db_common.inc.php';

View File

@ -24,9 +24,7 @@ PageSettings::showGroup('Sql');
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('makegrid.js');
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('sql.js');
$scripts->addFile('sql');
require 'libraries/db_common.inc.php';

View File

@ -24,8 +24,7 @@ require_once 'libraries/common.inc.php';
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('db_tracking.js');
$scripts->addFile('db_tracking');
$tracking = new Tracking();

View File

@ -217,8 +217,8 @@ Basic settings
Setting this to ``true`` allows phpMyAdmin to be included inside a frame,
and is a potential security hole allowing cross-frame scripting attacks or
clickjacking. Setting this to 'sameorigin' prevents phpMyAdmin to be
included from another document in a frame, unless that document belongs
clickjacking. Setting this to 'sameorigin' prevents phpMyAdmin to be
included from another document in a frame, unless that document belongs
to the same domain.
Server connection settings
@ -3402,6 +3402,29 @@ Developer
These settings might have huge effect on performance or security.
.. config:option:: $cfg['environment']
:type: string
:default: `'production'`
Sets the working environment for loading JavaScript files for webpack development
Possible values are 'production' or 'development'
.. config:option:: $cfg['webpack_host']
:type: string
:default: `'http://localhost'`
Webpack development server hostname for serving JavaScript files. Requires $cfg['environment'] to be development.
.. config:option:: $cfg['webpack_port']
:type: number
:default: 3307
Webpack development server port for serving JavaScript files. Requires $cfg['environment'] to be development.
.. config:option:: $cfg['DBG']
:type: array

View File

@ -639,7 +639,24 @@ var AJAX = {
var self = this;
script.type = 'text/javascript';
script.src = 'js/' + name + '?' + 'v=' + encodeURIComponent(PMA_commonParams.get('PMA_VERSION'));
/**
* This piece of code is for appending the new revamped files into the
* DOM so that both new and old files can be used simultaneously
* It checks whether the file contains new in its name or not
*/
var check = name.split('_');
if (check[check.length - 1] === 'new.js') {
var script_src;
if (PMA_commonParams.get('environment') === 'development') {
script_src = PMA_commonParams.get('webpack_host') + ':'
+ PMA_commonParams.get('webpack_port') + '/js/dist/';
} else {
script_src = 'js/dist/';
}
script.src = script_src + name + '?' + 'v=' + encodeURIComponent(PMA_commonParams.get('PMA_VERSION'));
} else {
script.src = 'js/' + name + '?' + 'v=' + encodeURIComponent(PMA_commonParams.get('PMA_VERSION'));
}
script.async = false;
script.onload = function () {
self.done(name, callback);

43
js/common_params.php Normal file
View File

@ -0,0 +1,43 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Exporting of common params defined in Header.php to make them available in
* the global window object and then serialize these variables in the modules.
*
* @package PhpMyAdmin
*/
if (!defined('TESTSUITE')) {
chdir('..');
// Send correct type:
header('Content-Type: text/javascript; charset=UTF-8');
// Preventing caching of this file
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
// Cache output in client - the nocache query parameter makes sure that this
// file is reloaded when config changes
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
// Avoid loading the full common.inc.php because this would add many
// non-js-compatible stuff like DOCTYPE
define('PMA_MINIMUM_COMMON', true);
define('PMA_PATH_TO_BASEDIR', '../');
require_once './libraries/common.inc.php';
// Close session early as we won't write anything there
session_write_close();
}
// But this one is needed for Sanitize::escapeJsString()
use PhpMyAdmin\Header;
use PhpMyAdmin\Sanitize;
$header = new Header();
echo "var common_params = new Array();\n";
foreach ($header->getJsParams() as $name => $value) {
Sanitize::printJsValue("common_params['" . $name . "']", $value);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Conditionally included if framing is not allowed
*/
if (self === top) {
var style_element = document.getElementById('cfs-style');
// check if style_element has already been removed
// to avoid frequently reported js error
if (typeof(style_element) !== 'undefined' && style_element !== null) {
style_element.parentNode.removeChild(style_element);
}
} else {
top.location = self.location;
}

View File

@ -1,996 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Functions used in the export tab
*
*/
/**
* Disables the "Dump some row(s)" sub-options
*/
function disable_dump_some_rows_sub_options () {
$('label[for=\'limit_to\']').fadeTo('fast', 0.4);
$('label[for=\'limit_from\']').fadeTo('fast', 0.4);
$('input[type=\'text\'][name=\'limit_to\']').prop('disabled', 'disabled');
$('input[type=\'text\'][name=\'limit_from\']').prop('disabled', 'disabled');
}
/**
* Enables the "Dump some row(s)" sub-options
*/
function enable_dump_some_rows_sub_options () {
$('label[for=\'limit_to\']').fadeTo('fast', 1);
$('label[for=\'limit_from\']').fadeTo('fast', 1);
$('input[type=\'text\'][name=\'limit_to\']').prop('disabled', '');
$('input[type=\'text\'][name=\'limit_from\']').prop('disabled', '');
}
/**
* Return template data as a json object
*
* @returns template data
*/
function getTemplateData () {
var $form = $('form[name="dump"]');
var blacklist = ['token', 'server', 'db', 'table', 'single_table',
'export_type', 'export_method', 'sql_query', 'template_id'];
var obj = {};
var arr = $form.serializeArray();
$.each(arr, function () {
if ($.inArray(this.name, blacklist) < 0) {
if (obj[this.name] !== undefined) {
if (! obj[this.name].push) {
obj[this.name] = [obj[this.name]];
}
obj[this.name].push(this.value || '');
} else {
obj[this.name] = this.value || '';
}
}
});
// include unchecked checboxes (which are ignored by serializeArray()) with null
// to uncheck them when loading the template
$form.find('input[type="checkbox"]:not(:checked)').each(function () {
if (obj[this.name] === undefined) {
obj[this.name] = null;
}
});
// include empty multiselects
$form.find('select').each(function () {
if ($(this).find('option:selected').length === 0) {
obj[this.name] = [];
}
});
return obj;
}
/**
* Create a template with selected options
*
* @param name name of the template
*/
function createTemplate (name) {
var templateData = getTemplateData();
var params = {
ajax_request : true,
server : PMA_commonParams.get('server'),
db : PMA_commonParams.get('db'),
table : PMA_commonParams.get('table'),
exportType : $('input[name="export_type"]').val(),
templateAction : 'create',
templateName : name,
templateData : JSON.stringify(templateData)
};
PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
$('#templateName').val('');
$('#template').html(response.data);
$('#template').find('option').each(function () {
if ($(this).text() === name) {
$(this).prop('selected', true);
}
});
PMA_ajaxShowMessage(PMA_messages.strTemplateCreated);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Loads a template
*
* @param id ID of the template to load
*/
function loadTemplate (id) {
var params = {
ajax_request : true,
server : PMA_commonParams.get('server'),
db : PMA_commonParams.get('db'),
table : PMA_commonParams.get('table'),
exportType : $('input[name="export_type"]').val(),
templateAction : 'load',
templateId : id,
};
PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
var $form = $('form[name="dump"]');
var options = JSON.parse(response.data);
$.each(options, function (key, value) {
var $element = $form.find('[name="' + key + '"]');
if ($element.length) {
if (($element.is('input') && $element.attr('type') === 'checkbox') && value === null) {
$element.prop('checked', false);
} else {
if (($element.is('input') && $element.attr('type') === 'checkbox') ||
($element.is('input') && $element.attr('type') === 'radio') ||
($element.is('select') && $element.attr('multiple') === 'multiple')) {
if (! value.push) {
value = [value];
}
}
$element.val(value);
}
$element.trigger('change');
}
});
$('input[name="template_id"]').val(id);
PMA_ajaxShowMessage(PMA_messages.strTemplateLoaded);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Updates an existing template with current options
*
* @param id ID of the template to update
*/
function updateTemplate (id) {
var templateData = getTemplateData();
var params = {
ajax_request : true,
server : PMA_commonParams.get('server'),
db : PMA_commonParams.get('db'),
table : PMA_commonParams.get('table'),
exportType : $('input[name="export_type"]').val(),
templateAction : 'update',
templateId : id,
templateData : JSON.stringify(templateData)
};
PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
PMA_ajaxShowMessage(PMA_messages.strTemplateUpdated);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Delete a template
*
* @param id ID of the template to delete
*/
function deleteTemplate (id) {
var params = {
ajax_request : true,
server : PMA_commonParams.get('server'),
db : PMA_commonParams.get('db'),
table : PMA_commonParams.get('table'),
exportType : $('input[name="export_type"]').val(),
templateAction : 'delete',
templateId : id,
};
PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
$('#template').find('option[value="' + id + '"]').remove();
PMA_ajaxShowMessage(PMA_messages.strTemplateDeleted);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('export.js', function () {
$('#plugins').off('change');
$('input[type=\'radio\'][name=\'sql_structure_or_data\']').off('change');
$('input[type=\'radio\'][name$=\'_structure_or_data\']').off('change');
$('input[type=\'radio\'][name=\'output_format\']').off('change');
$('#checkbox_sql_include_comments').off('change');
$('input[type=\'radio\'][name=\'quick_or_custom\']').off('change');
$('input[type=\'radio\'][name=\'allrows\']').off('change');
$('#btn_alias_config').off('click');
$('.alias_remove').off('click');
$('#db_alias_button').off('click');
$('#table_alias_button').off('click');
$('#column_alias_button').off('click');
$('input[name="table_select[]"]').off('change');
$('input[name="table_structure[]"]').off('change');
$('input[name="table_data[]"]').off('change');
$('#table_structure_all').off('change');
$('#table_data_all').off('change');
$('input[name="createTemplate"]').off('click');
$('select[name="template"]').off('change');
$('input[name="updateTemplate"]').off('click');
$('input[name="deleteTemplate"]').off('click');
});
AJAX.registerOnload('export.js', function () {
/**
* Export template handling code
*/
// create a new template
$('input[name="createTemplate"]').on('click', function (e) {
e.preventDefault();
var name = $('input[name="templateName"]').val();
if (name.length) {
createTemplate(name);
}
});
// load an existing template
$('select[name="template"]').on('change', function (e) {
e.preventDefault();
var id = $(this).val();
if (id.length) {
loadTemplate(id);
}
});
// udpate an existing template with new criteria
$('input[name="updateTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
updateTemplate(id);
}
});
// delete an existing template
$('input[name="deleteTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
deleteTemplate(id);
}
});
/**
* Toggles the hiding and showing of each plugin's options
* according to the currently selected plugin from the dropdown list
*/
$('#plugins').on('change', function () {
$('#format_specific_opts').find('div.format_specific_options').hide();
var selected_plugin_name = $('#plugins').find('option:selected').val();
$('#' + selected_plugin_name + '_options').show();
});
/**
* Toggles the enabling and disabling of the SQL plugin's comment options that apply only when exporting structure
*/
$('input[type=\'radio\'][name=\'sql_structure_or_data\']').on('change', function () {
var comments_are_present = $('#checkbox_sql_include_comments').prop('checked');
var show = $('input[type=\'radio\'][name=\'sql_structure_or_data\']:checked').val();
if (show === 'data') {
// disable the SQL comment options
if (comments_are_present) {
$('#checkbox_sql_dates').prop('disabled', true).parent().fadeTo('fast', 0.4);
}
$('#checkbox_sql_relation').prop('disabled', true).parent().fadeTo('fast', 0.4);
$('#checkbox_sql_mime').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
// enable the SQL comment options
if (comments_are_present) {
$('#checkbox_sql_dates').prop('disabled', false).parent().fadeTo('fast', 1);
}
$('#checkbox_sql_relation').prop('disabled', false).parent().fadeTo('fast', 1);
$('#checkbox_sql_mime').prop('disabled', false).parent().fadeTo('fast', 1);
}
if (show === 'structure') {
$('#checkbox_sql_auto_increment').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$('#checkbox_sql_auto_increment').prop('disabled', false).parent().fadeTo('fast', 1);
}
});
// For separate-file exports only ZIP compression is allowed
$('input[type="checkbox"][name="as_separate_files"]').on('change', function () {
if ($(this).is(':checked')) {
$('#compression').val('zip');
}
});
$('#compression').on('change', function () {
if ($('option:selected').val() !== 'zip') {
$('input[type="checkbox"][name="as_separate_files"]').prop('checked', false);
}
});
});
function setup_table_structure_or_data () {
if ($('input[name=\'export_type\']').val() !== 'database') {
return;
}
var pluginName = $('#plugins').find('option:selected').val();
var formElemName = pluginName + '_structure_or_data';
var force_structure_or_data = !($('input[name=\'' + formElemName + '_default\']').length);
if (force_structure_or_data === true) {
$('input[name="structure_or_data_forced"]').val(1);
$('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]')
.prop('disabled', true);
$('.export_structure, .export_data').fadeTo('fast', 0.4);
} else {
$('input[name="structure_or_data_forced"]').val(0);
$('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]')
.prop('disabled', false);
$('.export_structure, .export_data').fadeTo('fast', 1);
var structure_or_data = $('input[name="' + formElemName + '_default"]').val();
if (structure_or_data === 'structure') {
$('.export_data input[type="checkbox"]')
.prop('checked', false);
} else if (structure_or_data === 'data') {
$('.export_structure input[type="checkbox"]')
.prop('checked', false);
}
if (structure_or_data === 'structure' || structure_or_data === 'structure_and_data') {
if (!$('.export_structure input[type="checkbox"]:checked').length) {
$('input[name="table_select[]"]:checked')
.closest('tr')
.find('.export_structure input[type="checkbox"]')
.prop('checked', true);
}
}
if (structure_or_data === 'data' || structure_or_data === 'structure_and_data') {
if (!$('.export_data input[type="checkbox"]:checked').length) {
$('input[name="table_select[]"]:checked')
.closest('tr')
.find('.export_data input[type="checkbox"]')
.prop('checked', true);
}
}
check_selected_tables();
check_table_select_all();
check_table_select_struture_or_data();
}
}
/**
* Toggles the hiding and showing of plugin structure-specific and data-specific
* options
*/
function toggle_structure_data_opts () {
var pluginName = $('select#plugins').val();
var radioFormName = pluginName + '_structure_or_data';
var dataDiv = '#' + pluginName + '_data';
var structureDiv = '#' + pluginName + '_structure';
var show = $('input[type=\'radio\'][name=\'' + radioFormName + '\']:checked').val();
if (show === 'data') {
$(dataDiv).slideDown('slow');
$(structureDiv).slideUp('slow');
} else {
$(structureDiv).slideDown('slow');
if (show === 'structure') {
$(dataDiv).slideUp('slow');
} else {
$(dataDiv).slideDown('slow');
}
}
}
/**
* Toggles the disabling of the "save to file" options
*/
function toggle_save_to_file () {
var $ulSaveAsfile = $('#ul_save_asfile');
if (!$('#radio_dump_asfile').prop('checked')) {
$ulSaveAsfile.find('> li').fadeTo('fast', 0.4);
$ulSaveAsfile.find('> li > input').prop('disabled', true);
$ulSaveAsfile.find('> li > select').prop('disabled', true);
} else {
$ulSaveAsfile.find('> li').fadeTo('fast', 1);
$ulSaveAsfile.find('> li > input').prop('disabled', false);
$ulSaveAsfile.find('> li > select').prop('disabled', false);
}
}
AJAX.registerOnload('export.js', function () {
toggle_save_to_file();
$('input[type=\'radio\'][name=\'output_format\']').on('change', toggle_save_to_file);
});
/**
* For SQL plugin, toggles the disabling of the "display comments" options
*/
function toggle_sql_include_comments () {
$('#checkbox_sql_include_comments').on('change', function () {
var $ulIncludeComments = $('#ul_include_comments');
if (!$('#checkbox_sql_include_comments').prop('checked')) {
$ulIncludeComments.find('> li').fadeTo('fast', 0.4);
$ulIncludeComments.find('> li > input').prop('disabled', true);
} else {
// If structure is not being exported, the comment options for structure should not be enabled
if ($('#radio_sql_structure_or_data_data').prop('checked')) {
$('#text_sql_header_comment').prop('disabled', false).parent('li').fadeTo('fast', 1);
} else {
$ulIncludeComments.find('> li').fadeTo('fast', 1);
$ulIncludeComments.find('> li > input').prop('disabled', false);
}
}
});
}
function check_table_select_all () {
var total = $('input[name="table_select[]"]').length;
var str_checked = $('input[name="table_structure[]"]:checked').length;
var data_checked = $('input[name="table_data[]"]:checked').length;
var str_all = $('#table_structure_all');
var data_all = $('#table_data_all');
if (str_checked === total) {
str_all
.prop('indeterminate', false)
.prop('checked', true);
} else if (str_checked === 0) {
str_all
.prop('indeterminate', false)
.prop('checked', false);
} else {
str_all
.prop('indeterminate', true)
.prop('checked', false);
}
if (data_checked === total) {
data_all
.prop('indeterminate', false)
.prop('checked', true);
} else if (data_checked === 0) {
data_all
.prop('indeterminate', false)
.prop('checked', false);
} else {
data_all
.prop('indeterminate', true)
.prop('checked', false);
}
}
function check_table_select_struture_or_data () {
var str_checked = $('input[name="table_structure[]"]:checked').length;
var data_checked = $('input[name="table_data[]"]:checked').length;
var auto_increment = $('#checkbox_sql_auto_increment');
var pluginName = $('select#plugins').val();
var dataDiv = '#' + pluginName + '_data';
var structureDiv = '#' + pluginName + '_structure';
if (str_checked === 0) {
$(structureDiv).slideUp('slow');
} else {
$(structureDiv).slideDown('slow');
}
if (data_checked === 0) {
$(dataDiv).slideUp('slow');
auto_increment.prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$(dataDiv).slideDown('slow');
auto_increment.prop('disabled', false).parent().fadeTo('fast', 1);
}
}
function toggle_table_select_all_str () {
var str_all = $('#table_structure_all').is(':checked');
if (str_all) {
$('input[name="table_structure[]"]').prop('checked', true);
} else {
$('input[name="table_structure[]"]').prop('checked', false);
}
}
function toggle_table_select_all_data () {
var data_all = $('#table_data_all').is(':checked');
if (data_all) {
$('input[name="table_data[]"]').prop('checked', true);
} else {
$('input[name="table_data[]"]').prop('checked', false);
}
}
function check_selected_tables (argument) {
$('.export_table_select tbody tr').each(function () {
check_table_selected(this);
});
}
function check_table_selected (row) {
var $row = $(row);
var table_select = $row.find('input[name="table_select[]"]');
var str_check = $row.find('input[name="table_structure[]"]');
var data_check = $row.find('input[name="table_data[]"]');
var data = data_check.is(':checked:not(:disabled)');
var structure = str_check.is(':checked:not(:disabled)');
if (data && structure) {
table_select.prop({ checked: true, indeterminate: false });
$row.addClass('marked');
} else if (data || structure) {
table_select.prop({ checked: true, indeterminate: true });
$row.removeClass('marked');
} else {
table_select.prop({ checked: false, indeterminate: false });
$row.removeClass('marked');
}
}
function toggle_table_select (row) {
var $row = $(row);
var table_selected = $row.find('input[name="table_select[]"]').is(':checked');
if (table_selected) {
$row.find('input[type="checkbox"]:not(:disabled)').prop('checked', true);
$row.addClass('marked');
} else {
$row.find('input[type="checkbox"]:not(:disabled)').prop('checked', false);
$row.removeClass('marked');
}
}
function handleAddProcCheckbox () {
if ($('#table_structure_all').is(':checked') === true
&& $('#table_data_all').is(':checked') === true
) {
$('#checkbox_sql_procedure_function').prop('checked', true);
} else {
$('#checkbox_sql_procedure_function').prop('checked', false);
}
}
AJAX.registerOnload('export.js', function () {
/**
* For SQL plugin, if "CREATE TABLE options" is checked/unchecked, check/uncheck each of its sub-options
*/
var $create = $('#checkbox_sql_create_table_statements');
var $create_options = $('#ul_create_table_statements').find('input');
$create.on('change', function () {
$create_options.prop('checked', $(this).prop('checked'));
});
$create_options.on('change', function () {
if ($create_options.is(':checked')) {
$create.prop('checked', true);
}
});
/**
* Disables the view output as text option if the output must be saved as a file
*/
$('#plugins').on('change', function () {
var active_plugin = $('#plugins').find('option:selected').val();
var force_file = $('#force_file_' + active_plugin).val();
if (force_file === 'true') {
if ($('#radio_dump_asfile').prop('checked') !== true) {
$('#radio_dump_asfile').prop('checked', true);
toggle_save_to_file();
}
$('#radio_view_as_text').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$('#radio_view_as_text').prop('disabled', false).parent().fadeTo('fast', 1);
}
});
$('input[type=\'radio\'][name$=\'_structure_or_data\']').on('change', function () {
toggle_structure_data_opts();
});
$('input[name="table_select[]"]').on('change', function () {
toggle_table_select($(this).closest('tr'));
check_table_select_all();
handleAddProcCheckbox();
check_table_select_struture_or_data();
});
$('input[name="table_structure[]"]').on('change', function () {
check_table_selected($(this).closest('tr'));
check_table_select_all();
handleAddProcCheckbox();
check_table_select_struture_or_data();
});
$('input[name="table_data[]"]').on('change', function () {
check_table_selected($(this).closest('tr'));
check_table_select_all();
handleAddProcCheckbox();
check_table_select_struture_or_data();
});
$('#table_structure_all').on('change', function () {
toggle_table_select_all_str();
check_selected_tables();
handleAddProcCheckbox();
check_table_select_struture_or_data();
});
$('#table_data_all').on('change', function () {
toggle_table_select_all_data();
check_selected_tables();
handleAddProcCheckbox();
check_table_select_struture_or_data();
});
if ($('input[name=\'export_type\']').val() === 'database') {
// Hide structure or data radio buttons
$('input[type=\'radio\'][name$=\'_structure_or_data\']').each(function () {
var $this = $(this);
var name = $this.prop('name');
var val = $('input[name="' + name + '"]:checked').val();
var name_default = name + '_default';
if (!$('input[name="' + name_default + '"]').length) {
$this
.after(
$('<input type="hidden" name="' + name_default + '" value="' + val + '" disabled>')
)
.after(
$('<input type="hidden" name="' + name + '" value="structure_and_data">')
);
$this.parent().find('label').remove();
} else {
$this.parent().remove();
}
});
$('input[type=\'radio\'][name$=\'_structure_or_data\']').remove();
// Disable CREATE table checkbox for sql
var createTableCheckbox = $('#checkbox_sql_create_table');
createTableCheckbox.prop('checked', true);
var dummyCreateTable = $('#checkbox_sql_create_table')
.clone()
.removeAttr('id')
.attr('type', 'hidden');
createTableCheckbox
.prop('disabled', true)
.after(dummyCreateTable)
.parent()
.fadeTo('fast', 0.4);
setup_table_structure_or_data();
}
/**
* Handle force structure_or_data
*/
$('#plugins').on('change', setup_table_structure_or_data);
});
/**
* Toggles display of options when quick and custom export are selected
*/
function toggle_quick_or_custom () {
if ($('input[name=\'quick_or_custom\']').length === 0 // custom_no_form option
|| $('#radio_custom_export').prop('checked') // custom
) {
$('#databases_and_tables').show();
$('#rows').show();
$('#output').show();
$('#format_specific_opts').show();
$('#output_quick_export').hide();
var selected_plugin_name = $('#plugins').find('option:selected').val();
$('#' + selected_plugin_name + '_options').show();
} else { // quick
$('#databases_and_tables').hide();
$('#rows').hide();
$('#output').hide();
$('#format_specific_opts').hide();
$('#output_quick_export').show();
}
}
var time_out;
function check_time_out (time_limit) {
if (typeof time_limit === 'undefined' || time_limit === 0) {
return true;
}
// margin of one second to avoid race condition to set/access session variable
time_limit = time_limit + 1;
var href = 'export.php';
var params = {
'ajax_request' : true,
'check_time_out' : true
};
clearTimeout(time_out);
time_out = setTimeout(function () {
$.get(href, params, function (data) {
if (data.message === 'timeout') {
PMA_ajaxShowMessage(
'<div class="error">' +
PMA_messages.strTimeOutError +
'</div>',
false
);
}
});
}, time_limit * 1000);
}
/**
* Handler for Database/table alias select
*
* @param event object the event object
*
* @return void
*/
function aliasSelectHandler (event) {
var sel = event.data.sel;
var type = event.data.type;
var inputId = $(this).val();
var $label = $(this).next('label');
$('input#' + $label.attr('for')).addClass('hide');
$('input#' + inputId).removeClass('hide');
$label.attr('for', inputId);
$('#alias_modal ' + sel + '[id$=' + type + ']:visible').addClass('hide');
var $inputWrapper = $('#alias_modal ' + sel + '#' + inputId + type);
$inputWrapper.removeClass('hide');
if (type === '_cols' && $inputWrapper.length > 0) {
var outer = $inputWrapper[0].outerHTML;
// Replace opening tags
var regex = /<dummy_inp/gi;
if (outer.match(regex)) {
var newTag = outer.replace(regex, '<input');
// Replace closing tags
regex = /<\/dummy_inp/gi;
newTag = newTag.replace(regex, '</input');
// Assign replacement
$inputWrapper.replaceWith(newTag);
}
} else if (type === '_tables') {
$('.table_alias_select:visible').trigger('change');
}
$('#alias_modal').dialog('option', 'position', 'center');
}
/**
* Handler for Alias dialog box
*
* @param event object the event object
*
* @return void
*/
function createAliasModal (event) {
event.preventDefault();
var dlgButtons = {};
dlgButtons[PMA_messages.strSaveAndClose] = function () {
$(this).dialog('close');
$('#alias_modal').parent().appendTo($('form[name="dump"]'));
};
$('#alias_modal').dialog({
width: Math.min($(window).width() - 100, 700),
maxHeight: $(window).height(),
modal: true,
dialogClass: 'alias-dialog',
buttons: dlgButtons,
create: function () {
$(this).css('maxHeight', $(window).height() - 150);
var db = PMA_commonParams.get('db');
if (db) {
var option = $('<option></option>');
option.text(db);
option.attr('value', db);
$('#db_alias_select').append(option).val(db).trigger('change');
} else {
var params = {
ajax_request : true,
server : PMA_commonParams.get('server'),
type: 'list-databases'
};
$.post('ajax.php', params, function (response) {
if (response.success === true) {
$.each(response.databases, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#db_alias_select').append(option);
});
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
},
close: function () {
var isEmpty = true;
$(this).find('input[type="text"]').each(function () {
// trim empty input fields on close
if ($(this).val()) {
isEmpty = false;
} else {
$(this).parents('tr').remove();
}
});
// Toggle checkbox based on aliases
$('input#btn_alias_config').prop('checked', !isEmpty);
},
position: { my: 'center top', at: 'center top', of: window }
});
}
function aliasToggleRow (elm) {
var inputs = elm.parents('tr').find('input,button');
if (elm.val()) {
inputs.attr('disabled', false);
} else {
inputs.attr('disabled', true);
}
}
function addAlias (type, name, field, value) {
if (value === '') {
return;
}
var row = $('#alias_data tfoot tr').clone();
row.find('th').text(type);
row.find('td:first').text(name);
row.find('input').attr('name', field);
row.find('input').val(value);
row.find('.alias_remove').on('click', function () {
$(this).parents('tr').remove();
});
var matching = $('#alias_data [name="' + $.escapeSelector(field) + '"]');
if (matching.length > 0) {
matching.parents('tr').remove();
}
$('#alias_data tbody').append(row);
}
AJAX.registerOnload('export.js', function () {
$('input[type=\'radio\'][name=\'quick_or_custom\']').on('change', toggle_quick_or_custom);
$('#scroll_to_options_msg').hide();
$('#format_specific_opts').find('div.format_specific_options')
.hide()
.css({
'border': 0,
'margin': 0,
'padding': 0
})
.find('h3')
.remove();
toggle_quick_or_custom();
toggle_structure_data_opts();
toggle_sql_include_comments();
check_table_select_all();
handleAddProcCheckbox();
/**
* Initially disables the "Dump some row(s)" sub-options
*/
disable_dump_some_rows_sub_options();
/**
* Disables the "Dump some row(s)" sub-options when it is not selected
*/
$('input[type=\'radio\'][name=\'allrows\']').on('change', function () {
if ($('input[type=\'radio\'][name=\'allrows\']').prop('checked')) {
enable_dump_some_rows_sub_options();
} else {
disable_dump_some_rows_sub_options();
}
});
// Open Alias Modal Dialog on click
$('#btn_alias_config').on('click', createAliasModal);
$('.alias_remove').on('click', function () {
$(this).parents('tr').remove();
});
$('#db_alias_select').on('change', function () {
aliasToggleRow($(this));
var db = $(this).val();
var table = PMA_commonParams.get('table');
if (table) {
var option = $('<option></option>');
option.text(table);
option.attr('value', table);
$('#table_alias_select').append(option).val(table).trigger('change');
} else {
var params = {
ajax_request : true,
server : PMA_commonParams.get('server'),
db : $(this).val(),
type: 'list-tables'
};
$.post('ajax.php', params, function (response) {
if (response.success === true) {
$.each(response.tables, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#table_alias_select').append(option);
});
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
});
$('#table_alias_select').on('change', function () {
aliasToggleRow($(this));
var params = {
ajax_request : true,
server : PMA_commonParams.get('server'),
db : $('#db_alias_select').val(),
table: $(this).val(),
type: 'list-columns'
};
$.post('ajax.php', params, function (response) {
if (response.success === true) {
$.each(response.columns, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#column_alias_select').append(option);
});
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
});
$('#column_alias_select').on('change', function () {
aliasToggleRow($(this));
});
$('#db_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
addAlias(
PMA_messages.strAliasDatabase,
db,
'aliases[' + db + '][alias]',
$('#db_alias_name').val()
);
$('#db_alias_name').val('');
});
$('#table_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
var table = $('#table_alias_select').val();
addAlias(
PMA_messages.strAliasTable,
db + '.' + table,
'aliases[' + db + '][tables][' + table + '][alias]',
$('#table_alias_name').val()
);
$('#table_alias_name').val('');
});
$('#column_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
var table = $('#table_alias_select').val();
var column = $('#column_alias_select').val();
addAlias(
PMA_messages.strAliasColumn,
db + '.' + table + '.' + column,
'aliases[' + db + '][tables][' + table + '][colums][' + column + ']',
$('#column_alias_name').val()
);
$('#column_alias_name').val('');
});
});

View File

@ -87,128 +87,6 @@ $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
}
});
/*
* Adds a date/time picker to an element
*
* @param object $this_element a jQuery object pointing to the element
*/
function PMA_addDatepicker ($this_element, type, options) {
var showTimepicker = true;
if (type === 'date') {
showTimepicker = false;
}
var defaultOptions = {
showOn: 'button',
buttonImage: themeCalendarImage, // defined in js/messages.php
buttonImageOnly: true,
stepMinutes: 1,
stepHours: 1,
showSecond: true,
showMillisec: true,
showMicrosec: true,
showTimepicker: showTimepicker,
showButtonPanel: false,
dateFormat: 'yy-mm-dd', // yy means year with four digits
timeFormat: 'HH:mm:ss.lc',
constrainInput: false,
altFieldTimeOnly: false,
showAnim: '',
beforeShow: function (input, inst) {
// Remember that we came from the datepicker; this is used
// in tbl_change.js by verificationsAfterFieldChange()
$this_element.data('comes_from', 'datepicker');
if ($(input).closest('.cEdit').length > 0) {
setTimeout(function () {
inst.dpDiv.css({
top: 0,
left: 0,
position: 'relative'
});
}, 0);
}
setTimeout(function () {
// Fix wrong timepicker z-index, doesn't work without timeout
$('#ui-timepicker-div').css('z-index', $('#ui-datepicker-div').css('z-index'));
// Integrate tooltip text into dialog
var tooltip = $this_element.tooltip('instance');
if (typeof tooltip !== 'undefined') {
tooltip.disable();
var $note = $('<p class="note"></div>');
$note.text(tooltip.option('content'));
$('div.ui-datepicker').append($note);
}
}, 0);
},
onSelect: function () {
$this_element.data('datepicker').inline = true;
},
onClose: function (dateText, dp_inst) {
// The value is no more from the date picker
$this_element.data('comes_from', '');
if (typeof $this_element.data('datepicker') !== 'undefined') {
$this_element.data('datepicker').inline = false;
}
var tooltip = $this_element.tooltip('instance');
if (typeof tooltip !== 'undefined') {
tooltip.enable();
}
}
};
if (type === 'time') {
$this_element.timepicker($.extend(defaultOptions, options));
// Add a tip regarding entering MySQL allowed-values for TIME data-type
PMA_tooltip($this_element, 'input', PMA_messages.strMysqlAllowedValuesTipTime);
} else {
$this_element.datetimepicker($.extend(defaultOptions, options));
}
}
/**
* Add a date/time picker to each element that needs it
* (only when jquery-ui-timepicker-addon.js is loaded)
*/
function addDateTimePicker () {
if ($.timepicker !== undefined) {
$('input.timefield, input.datefield, input.datetimefield').each(function () {
var decimals = $(this).parent().attr('data-decimals');
var type = $(this).parent().attr('data-type');
var showMillisec = false;
var showMicrosec = false;
var timeFormat = 'HH:mm:ss';
var hourMax = 23;
// check for decimal places of seconds
if (decimals > 0 && type.indexOf('time') !== -1) {
if (decimals > 3) {
showMillisec = true;
showMicrosec = true;
timeFormat = 'HH:mm:ss.lc';
} else {
showMillisec = true;
timeFormat = 'HH:mm:ss.l';
}
}
if (type === 'time') {
hourMax = 99;
}
PMA_addDatepicker($(this), type, {
showMillisec: showMillisec,
showMicrosec: showMicrosec,
timeFormat: timeFormat,
hourMax: hourMax
});
// Add a tip regarding entering MySQL allowed-values
// for TIME and DATE data-type
if ($(this).hasClass('timefield')) {
PMA_tooltip($(this), 'input', PMA_messages.strMysqlAllowedValuesTipTime);
} else if ($(this).hasClass('datefield')) {
PMA_tooltip($(this), 'input', PMA_messages.strMysqlAllowedValuesTipDate);
}
});
}
}
/**
* Handle redirect and reload flags sent as part of AJAX requests
*
@ -999,93 +877,6 @@ AJAX.registerOnload('functions.js', function () {
updateTimeout = window.setTimeout(UpdateIdleTime, interval);
}
});
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('functions.js', function () {
$(document).off('click', 'input:checkbox.checkall');
});
AJAX.registerOnload('functions.js', function () {
/**
* Row marking in horizontal mode (use "on" so that it works also for
* next pages reached via AJAX); a tr may have the class noclick to remove
* this behavior.
*/
$(document).on('click', 'input:checkbox.checkall', function (e) {
$this = $(this);
var $tr = $this.closest('tr');
var $table = $this.closest('table');
if (!e.shiftKey || last_clicked_row === -1) {
// usual click
var $checkbox = $tr.find(':checkbox.checkall');
var checked = $this.prop('checked');
$checkbox.prop('checked', checked).trigger('change');
if (checked) {
$tr.addClass('marked');
} else {
$tr.removeClass('marked');
}
last_click_checked = checked;
// remember the last clicked row
last_clicked_row = last_click_checked ? $table.find('tr:not(.noclick)').index($tr) : -1;
last_shift_clicked_row = -1;
} else {
// handle the shift click
PMA_clearSelection();
var start;
var end;
// clear last shift click result
if (last_shift_clicked_row >= 0) {
if (last_shift_clicked_row >= last_clicked_row) {
start = last_clicked_row;
end = last_shift_clicked_row;
} else {
start = last_shift_clicked_row;
end = last_clicked_row;
}
$tr.parent().find('tr:not(.noclick)')
.slice(start, end + 1)
.removeClass('marked')
.find(':checkbox')
.prop('checked', false)
.trigger('change');
}
// handle new shift click
var curr_row = $table.find('tr:not(.noclick)').index($tr);
if (curr_row >= last_clicked_row) {
start = last_clicked_row;
end = curr_row;
} else {
start = curr_row;
end = last_clicked_row;
}
$tr.parent().find('tr:not(.noclick)')
.slice(start, end)
.addClass('marked')
.find(':checkbox')
.prop('checked', true)
.trigger('change');
// remember the last shift clicked row
last_shift_clicked_row = curr_row;
}
});
addDateTimePicker();
/**
* Add attribute to text boxes for iOS devices (based on bugID: 3508912)
*/
if (navigator.userAgent.match(/(iphone|ipod|ipad)/i)) {
$('input[type=text]').attr('autocapitalize', 'off').attr('autocorrect', 'off');
}
});
/**
* Checks/unchecks all options of a <select> element
@ -1808,121 +1599,6 @@ function getJSConfirmCommonParam (elem, params) {
return params;
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('functions.js', function () {
$(document).off('click', 'a.inline_edit_sql');
$(document).off('click', 'input#sql_query_edit_save');
$(document).off('click', 'input#sql_query_edit_discard');
$('input.sqlbutton').off('click');
if (codemirror_editor) {
codemirror_editor.off('blur');
} else {
$(document).off('blur', '#sqlquery');
}
$(document).off('change', '#parameterized');
$(document).off('click', 'input.sqlbutton');
$('#sqlquery').off('keydown');
$('#sql_query_edit').off('keydown');
if (codemirror_inline_editor) {
// Copy the sql query to the text area to preserve it.
$('#sql_query_edit').text(codemirror_inline_editor.getValue());
$(codemirror_inline_editor.getWrapperElement()).off('keydown');
codemirror_inline_editor.toTextArea();
codemirror_inline_editor = false;
}
if (codemirror_editor) {
$(codemirror_editor.getWrapperElement()).off('keydown');
}
});
/**
* Jquery Coding for inline editing SQL_QUERY
*/
AJAX.registerOnload('functions.js', function () {
// If we are coming back to the page by clicking forward button
// of the browser, bind the code mirror to inline query editor.
bindCodeMirrorToInlineEditor();
$(document).on('click', 'a.inline_edit_sql', function () {
if ($('#sql_query_edit').length) {
// An inline query editor is already open,
// we don't want another copy of it
return false;
}
var $form = $(this).prev('form');
var sql_query = $form.find('input[name=\'sql_query\']').val().trim();
var $inner_sql = $(this).parent().prev().find('code.sql');
var old_text = $inner_sql.html();
var new_content = '<textarea name="sql_query_edit" id="sql_query_edit">' + escapeHtml(sql_query) + '</textarea>\n';
new_content += getForeignKeyCheckboxLoader();
new_content += '<input type="submit" id="sql_query_edit_save" class="button btnSave" value="' + PMA_messages.strGo + '"/>\n';
new_content += '<input type="button" id="sql_query_edit_discard" class="button btnDiscard" value="' + PMA_messages.strCancel + '"/>\n';
var $editor_area = $('div#inline_editor');
if ($editor_area.length === 0) {
$editor_area = $('<div id="inline_editor_outer"></div>');
$editor_area.insertBefore($inner_sql);
}
$editor_area.html(new_content);
loadForeignKeyCheckbox();
$inner_sql.hide();
bindCodeMirrorToInlineEditor();
return false;
});
$(document).on('click', 'input#sql_query_edit_save', function () {
// hide already existing success message
var sql_query;
if (codemirror_inline_editor) {
codemirror_inline_editor.save();
sql_query = codemirror_inline_editor.getValue();
} else {
sql_query = $(this).parent().find('#sql_query_edit').val();
}
var fk_check = $(this).parent().find('#fk_checks').is(':checked');
var $form = $('a.inline_edit_sql').prev('form');
var $fake_form = $('<form>', { action: 'import.php', method: 'post' })
.append($form.find('input[name=server], input[name=db], input[name=table], input[name=token]').clone())
.append($('<input/>', { type: 'hidden', name: 'show_query', value: 1 }))
.append($('<input/>', { type: 'hidden', name: 'is_js_confirmed', value: 0 }))
.append($('<input/>', { type: 'hidden', name: 'sql_query', value: sql_query }))
.append($('<input/>', { type: 'hidden', name: 'fk_checks', value: fk_check ? 1 : 0 }));
if (! checkSqlQuery($fake_form[0])) {
return false;
}
$('.success').hide();
$fake_form.appendTo($('body')).submit();
});
$(document).on('click', 'input#sql_query_edit_discard', function () {
var $divEditor = $('div#inline_editor_outer');
$divEditor.siblings('code.sql').show();
$divEditor.remove();
});
$(document).on('click', 'input.sqlbutton', function (evt) {
insertQuery(evt.target.id);
PMA_handleSimulateQueryButton();
return false;
});
$(document).on('change', '#parameterized', updateQueryParameters);
var $inputUsername = $('#input_username');
if ($inputUsername) {
if ($inputUsername.val() === '') {
$inputUsername.trigger('focus');
} else {
$('#input_password').trigger('focus');
}
}
});
/**
* "inputRead" event handler for CodeMirror SQL query editors for autocompletion
*/
@ -2808,196 +2484,6 @@ AJAX.registerTeardown('functions.js', function () {
$(document).off('change', 'input[name=partition_count],input[name=subpartition_count],select[name=partition_by]');
});
/**
* jQuery coding for 'Create Table'. Used on db_operations.php,
* db_structure.php and db_tracking.php (i.e., wherever
* PhpMyAdmin\Display\CreateTable is used)
*
* Attach Ajax Event handlers for Create Table
*/
AJAX.registerOnload('functions.js', function () {
/**
* Attach event handler for submission of create table form (save)
*/
$(document).on('submit', 'form.create_table_form.ajax', function (event) {
event.preventDefault();
/**
* @var the_form object referring to the create table form
*/
var $form = $(this);
/*
* First validate the form; if there is a problem, avoid submitting it
*
* checkTableEditForm() needs a pure element and not a jQuery object,
* this is why we pass $form[0] as a parameter (the jQuery object
* is actually an array of DOM elements)
*/
if (checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) {
PMA_prepareForAjaxRequest($form);
if (PMA_checkReservedWordColumns($form)) {
PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
// User wants to submit the form
$.post($form.attr('action'), $form.serialize() + PMA_commonParams.get('arg_separator') + 'do_save_data=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$('#properties_message')
.removeClass('error')
.html('');
PMA_ajaxShowMessage(data.message);
// Only if the create table dialog (distinct panel) exists
var $createTableDialog = $('#create_table_dialog');
if ($createTableDialog.length > 0) {
$createTableDialog.dialog('close').remove();
}
$('#tableslistcontainer').before(data.formatted_sql);
/**
* @var tables_table Object referring to the <tbody> element that holds the list of tables
*/
var tables_table = $('#tablesForm').find('tbody').not('#tbl_summary_row');
// this is the first table created in this db
if (tables_table.length === 0) {
PMA_commonActions.refreshMain(
PMA_commonParams.get('opendb_url')
);
} else {
/**
* @var curr_last_row Object referring to the last <tr> element in {@link tables_table}
*/
var curr_last_row = $(tables_table).find('tr:last');
/**
* @var curr_last_row_index_string String containing the index of {@link curr_last_row}
*/
var curr_last_row_index_string = $(curr_last_row).find('input:checkbox').attr('id').match(/\d+/)[0];
/**
* @var curr_last_row_index Index of {@link curr_last_row}
*/
var curr_last_row_index = parseFloat(curr_last_row_index_string);
/**
* @var new_last_row_index Index of the new row to be appended to {@link tables_table}
*/
var new_last_row_index = curr_last_row_index + 1;
/**
* @var new_last_row_id String containing the id of the row to be appended to {@link tables_table}
*/
var new_last_row_id = 'checkbox_tbl_' + new_last_row_index;
data.new_table_string = data.new_table_string.replace(/checkbox_tbl_/, new_last_row_id);
// append to table
$(data.new_table_string)
.appendTo(tables_table);
// Sort the table
$(tables_table).PMA_sort_table('th');
// Adjust summary row
PMA_adjustTotals();
}
// Refresh navigation as a new table has been added
PMA_reloadNavigation();
// Redirect to table structure page on creation of new table
var argsep = PMA_commonParams.get('arg_separator');
var params_12 = 'ajax_request=true' + argsep + 'ajax_page_request=true';
if (! (history && history.pushState)) {
params_12 += PMA_MicroHistory.menus.getRequestParam();
}
tblStruct_url = 'tbl_structure.php?server=' + data._params.server +
argsep + 'db=' + data._params.db + argsep + 'token=' + data._params.token +
argsep + 'goto=db_structure.php' + argsep + 'table=' + data._params.table + '';
$.get(tblStruct_url, params_12, AJAX.responseHandler);
} else {
PMA_ajaxShowMessage(
'<div class="error">' + data.error + '</div>',
false
);
}
}); // end $.post()
}
} // end if (checkTableEditForm() )
}); // end create table form (save)
/**
* Submits the intermediate changes in the table creation form
* to refresh the UI accordingly
*/
function submitChangesInCreateTableForm (actionParam) {
/**
* @var the_form object referring to the create table form
*/
var $form = $('form.create_table_form.ajax');
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
PMA_prepareForAjaxRequest($form);
// User wants to add more fields to the table
$.post($form.attr('action'), $form.serialize() + '&' + actionParam, function (data) {
if (typeof data !== 'undefined' && data.success) {
var $pageContent = $('#page_content');
$pageContent.html(data.message);
PMA_highlightSQL($pageContent);
PMA_verifyColumnsProperties();
PMA_hideShowConnection($('.create_table_form select[name=tbl_storage_engine]'));
PMA_ajaxRemoveMessage($msgbox);
} else {
PMA_ajaxShowMessage(data.error);
}
}); // end $.post()
}
/**
* Attach event handler for create table form (add fields)
*/
$(document).on('click', 'form.create_table_form.ajax input[name=submit_num_fields]', function (event) {
event.preventDefault();
submitChangesInCreateTableForm('submit_num_fields=1');
}); // end create table form (add fields)
$(document).on('keydown', 'form.create_table_form.ajax input[name=added_fields]', function (event) {
if (event.keyCode === 13) {
event.preventDefault();
event.stopImmediatePropagation();
$(this)
.closest('form')
.find('input[name=submit_num_fields]')
.trigger('click');
}
});
/**
* Attach event handler to manage changes in number of partitions and subpartitions
*/
$(document).on('change', 'input[name=partition_count],input[name=subpartition_count],select[name=partition_by]', function (event) {
$this = $(this);
$form = $this.parents('form');
if ($form.is('.create_table_form.ajax')) {
submitChangesInCreateTableForm('submit_partition_change=1');
} else {
$form.submit();
}
});
$(document).on('change', 'input[value=AUTO_INCREMENT]', function () {
if (this.checked) {
var col = /\d/.exec($(this).attr('name'));
col = col[0];
var $selectFieldKey = $('select[name="field_key[' + col + ']"]');
if ($selectFieldKey.val() === 'none_' + col) {
$selectFieldKey.val('primary_' + col).trigger('change');
}
}
});
$('body')
.off('click', 'input.preview_sql')
.on('click', 'input.preview_sql', function () {
var $form = $(this).closest('form');
PMA_previewSQL($form);
});
});
/**
* Validates the password field in a form
*
@ -4316,30 +3802,6 @@ function PMA_slidingMessage (msg, $obj) {
return true;
} // end PMA_slidingMessage()
/**
* Attach CodeMirror2 editor to SQL edit area.
*/
AJAX.registerOnload('functions.js', function () {
var $elm = $('#sqlquery');
if ($elm.length > 0) {
if (typeof CodeMirror !== 'undefined') {
codemirror_editor = PMA_getSQLEditor($elm);
codemirror_editor.focus();
codemirror_editor.on('blur', updateQueryParameters);
} else {
// without codemirror
$elm.focus().on('blur', updateQueryParameters);
}
}
PMA_highlightSQL($('body'));
});
AJAX.registerTeardown('functions.js', function () {
if (codemirror_editor) {
$('#sqlquery').text(codemirror_editor.getValue());
codemirror_editor.toTextArea();
codemirror_editor = false;
}
});
AJAX.registerOnload('functions.js', function () {
// initializes all lock-page elements lock-id and
// val-hash data property
@ -4397,49 +3859,6 @@ $(window).on('popstate', function (event, data) {
return true;
});
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('functions.js', function () {
$(document).off('click', 'a.themeselect');
$(document).off('change', '.autosubmit');
$('a.take_theme').off('click');
});
AJAX.registerOnload('functions.js', function () {
/**
* Theme selector.
*/
$(document).on('click', 'a.themeselect', function (e) {
window.open(
e.target,
'themes',
'left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes'
);
return false;
});
/**
* Automatic form submission on change.
*/
$(document).on('change', '.autosubmit', function (e) {
$(this).closest('form').submit();
});
/**
* Theme changer.
*/
$('a.take_theme').on('click', function (e) {
var what = this.name;
if (window.opener && window.opener.document.forms.setTheme.elements.set_theme) {
window.opener.document.forms.setTheme.elements.set_theme.value = what;
window.opener.document.forms.setTheme.submit();
window.close();
return false;
}
return true;
});
});
/**
* Produce print preview
@ -5105,3 +4524,81 @@ jQuery.fn.getPostData = function () {
}
return dataPost;
};
/**
* @todo REMOVE THESE FUNCTIONS AFTER COMPLETE CODE BEING MODULAR
*
* Copy of functions copied from different files to make them globally
* available so that build does not break during modularisation
*/
/**
* server_privilages.js
*/
/**
* Validates the "add a user" form
*
* @return boolean whether the form is validated or not
*/
function checkAddUser (the_form) {
if (the_form.elements.pred_hostname.value === 'userdefined' && the_form.elements.hostname.value === '') {
alert(PMA_messages.strHostEmpty);
the_form.elements.hostname.focus();
return false;
}
if (the_form.elements.pred_username.value === 'userdefined' && the_form.elements.username.value === '') {
alert(PMA_messages.strUserEmpty);
the_form.elements.username.focus();
return false;
}
return PMA_checkPassword($(the_form));
} // end of the 'checkAddUser()' function
function checkPasswordStrength (value, meter_obj, meter_object_label, username) {
// List of words we don't want to appear in the password
var customDict = [
'phpmyadmin',
'mariadb',
'mysql',
'php',
'my',
'admin',
];
if (username !== null) {
customDict.push(username);
}
var zxcvbn_obj = zxcvbn(value, customDict);
var strength = zxcvbn_obj.score;
strength = parseInt(strength);
meter_obj.val(strength);
switch (strength) {
case 0: meter_object_label.html(PMA_messages.strExtrWeak);
break;
case 1: meter_object_label.html(PMA_messages.strVeryWeak);
break;
case 2: meter_object_label.html(PMA_messages.strWeak);
break;
case 3: meter_object_label.html(PMA_messages.strGood);
break;
case 4: meter_object_label.html(PMA_messages.strStrong);
}
}
function isStorageSupported (type, warn) {
try {
window[type].setItem('PMATest', 'test');
// Check whether key-value pair was set successfully
if (window[type].getItem('PMATest') === 'test') {
// Supported, remove test variable from storage
window[type].removeItem('PMATest');
return true;
}
} catch (error) {
// Not supported
if (warn) {
PMA_ajaxShowMessage(PMA_messages.strNoLocalStorage, false);
}
}
return false;
}

View File

@ -746,6 +746,9 @@ $js_messages['strWeak'] = __('Weak');
$js_messages['strGood'] = __('Good');
$js_messages['strStrong'] = __('Strong');
/* for js/config.js */
$js_messages['strSavedOn'] = __('Saved on: @DATE@');
/* U2F errors */
$js_messages['strU2FTimeout'] = __('Timed out waiting for security key activation.');
$js_messages['strU2FError'] = __('Failed security key activation (%s).');
@ -755,6 +758,26 @@ foreach ($js_messages as $name => $js_message) {
Sanitize::printJsValue("PMA_messages['" . $name . "']", $js_message);
}
/* for new js code */
/* Calendar */
echo "var globalVars = new Array();\n";
echo "globalVars['themeCalendarImage'] = '" , $GLOBALS['pmaThemeImage']
, 'b_calendar.png' , "';\n";
/* Image path */
echo "globalVars['pmaThemeImage'] = '" , $GLOBALS['pmaThemeImage'] , "';\n";
echo "globalVars['mysql_doc_template'] = '" , PhpMyAdmin\Util::getMySQLDocuURL('%s')
, "';\n";
//Max input vars allowed by PHP.
$maxInputVars = ini_get('max_input_vars');
echo "globalVars['maxInputVars'] = '"
, (false === $maxInputVars || '' == $maxInputVars ? 'false' : (int)$maxInputVars)
, ';' . "'\n";
/* for new js code */
/* for old js code */
/* Calendar */
echo "var themeCalendarImage = '" , $GLOBALS['pmaThemeImage']
, 'b_calendar.png' , "';\n";
@ -770,7 +793,144 @@ $maxInputVars = ini_get('max_input_vars');
echo 'var maxInputVars = '
, (false === $maxInputVars || '' == $maxInputVars ? 'false' : (int)$maxInputVars)
, ';' . "\n";
/* for old js code */
/* for new js code */
echo "datePicker = new Array();\n";
echo "timePicker = new Array();\n";
/* l10n: Display text for calendar close link */
Sanitize::printJsValue("datePicker['closeText']", __('Done'));
/* l10n: Display text for previous month link in calendar */
Sanitize::printJsValue(
"datePicker['prevText']",
_pgettext('Previous month', 'Prev')
);
/* l10n: Display text for next month link in calendar */
Sanitize::printJsValue(
"datePicker['nextText']",
_pgettext('Next month', 'Next')
);
/* l10n: Display text for current month link in calendar */
Sanitize::printJsValue("datePicker['currentText']", __('Today'));
Sanitize::printJsValue(
"datePicker['monthNames']",
array(
__('January'),
__('February'),
__('March'),
__('April'),
__('May'),
__('June'),
__('July'),
__('August'),
__('September'),
__('October'),
__('November'),
__('December')
)
);
Sanitize::printJsValue(
"datePicker['monthNamesShort']",
array(
/* l10n: Short month name */
__('Jan'),
/* l10n: Short month name */
__('Feb'),
/* l10n: Short month name */
__('Mar'),
/* l10n: Short month name */
__('Apr'),
/* l10n: Short month name */
_pgettext('Short month name', 'May'),
/* l10n: Short month name */
__('Jun'),
/* l10n: Short month name */
__('Jul'),
/* l10n: Short month name */
__('Aug'),
/* l10n: Short month name */
__('Sep'),
/* l10n: Short month name */
__('Oct'),
/* l10n: Short month name */
__('Nov'),
/* l10n: Short month name */
__('Dec')
)
);
Sanitize::printJsValue(
"datePicker['dayNames']",
array(
__('Sunday'),
__('Monday'),
__('Tuesday'),
__('Wednesday'),
__('Thursday'),
__('Friday'),
__('Saturday')
)
);
Sanitize::printJsValue(
"datePicker['dayNamesShort']",
array(
/* l10n: Short week day name */
__('Sun'),
/* l10n: Short week day name */
__('Mon'),
/* l10n: Short week day name */
__('Tue'),
/* l10n: Short week day name */
__('Wed'),
/* l10n: Short week day name */
__('Thu'),
/* l10n: Short week day name */
__('Fri'),
/* l10n: Short week day name */
__('Sat')
)
);
Sanitize::printJsValue(
"datePicker['dayNamesMin']",
array(
/* l10n: Minimal week day name */
__('Su'),
/* l10n: Minimal week day name */
__('Mo'),
/* l10n: Minimal week day name */
__('Tu'),
/* l10n: Minimal week day name */
__('We'),
/* l10n: Minimal week day name */
__('Th'),
/* l10n: Minimal week day name */
__('Fr'),
/* l10n: Minimal week day name */
__('Sa')
)
);
/* l10n: Column header for week of the year in calendar */
Sanitize::printJsValue("datePicker['weekHeader']", __('Wk'));
Sanitize::printJsValue(
"datePicker['showMonthAfterYear']",
/* l10n: Month-year order for calendar, use either "calendar-month-year"
* or "calendar-year-month".
*/
(__('calendar-month-year') == 'calendar-year-month')
);
/* l10n: Year suffix for calendar, "none" is empty. */
$year_suffix = _pgettext('Year suffix', 'none');
Sanitize::printJsValue(
"datePicker['yearSuffix']",
($year_suffix == 'none' ? '' : $year_suffix)
);
Sanitize::printJsValue("timePicker['timeText']", __('Time'));
Sanitize::printJsValue("timePicker['hourText']", __('Hour'));
Sanitize::printJsValue("timePicker['minuteText']", __('Minute'));
Sanitize::printJsValue("timePicker['secondText']", __('Second'));
/* for new js code */
/* for old js code */
echo "if ($.datepicker) {\n";
/* l10n: Display text for calendar close link */
Sanitize::printJsValue("$.datepicker.regional['']['closeText']", __('Done'));
@ -908,11 +1068,78 @@ Sanitize::printJsValue("$.timepicker.regional['']['timeText']", __('Time'));
Sanitize::printJsValue("$.timepicker.regional['']['hourText']", __('Hour'));
Sanitize::printJsValue("$.timepicker.regional['']['minuteText']", __('Minute'));
Sanitize::printJsValue("$.timepicker.regional['']['secondText']", __('Second'));
/* for old js code */
?>
$.extend($.timepicker._defaults, $.timepicker.regional['']);
} /* if ($.timepicker) */
<?php
/* for new js code */
/* Form validation */
/* Default validation functions */
echo "validationMessage = {\n";
Sanitize::printJsValueForFormValidation('required', __('This field is required'));
Sanitize::printJsValueForFormValidation('remote', __('Please fix this field'));
Sanitize::printJsValueForFormValidation('email', __('Please enter a valid email address'));
Sanitize::printJsValueForFormValidation('url', __('Please enter a valid URL'));
Sanitize::printJsValueForFormValidation('date', __('Please enter a valid date'));
Sanitize::printJsValueForFormValidation(
'dateISO',
__('Please enter a valid date ( ISO )')
);
Sanitize::printJsValueForFormValidation('number', __('Please enter a valid number'));
Sanitize::printJsValueForFormValidation(
'creditcard',
__('Please enter a valid credit card number')
);
Sanitize::printJsValueForFormValidation('digits', __('Please enter only digits'));
Sanitize::printJsValueForFormValidation(
'equalTo',
__('Please enter the same value again')
);
echo "\n};\n";
echo "validationFormat = {\n";
Sanitize::printJsValueForFormValidation(
'maxlength',
__('Please enter no more than {0} characters')
);
Sanitize::printJsValueForFormValidation(
'minlength',
__('Please enter at least {0} characters')
);
Sanitize::printJsValueForFormValidation(
'rangelength',
__('Please enter a value between {0} and {1} characters long')
);
Sanitize::printJsValueForFormValidation(
'range',
__('Please enter a value between {0} and {1}')
);
Sanitize::printJsValueForFormValidation(
'max',
__('Please enter a value less than or equal to {0}')
);
Sanitize::printJsValueForFormValidation(
'min',
__('Please enter a value greater than or equal to {0}')
);
/* customed functions */
Sanitize::printJsValueForFormValidation(
'validationFunctionForDateTime',
__('Please enter a valid date or time')
);
Sanitize::printJsValueForFormValidation(
'validationFunctionForHex',
__('Please enter a valid HEX input')
);
Sanitize::printJsValueForFormValidation(
'validationFunctionForFuns',
__('Error')
);
echo "\n};\n";
/* for new js code */
/* for old js code */
/* Form validation */
echo "function extendingValidatorMessages() {\n";
@ -986,4 +1213,5 @@ Sanitize::printJsValueForFormValidation(
);
echo "\n});";
echo "\n} /* if ($.validator) */";
/* for old js code */
?>

View File

@ -271,388 +271,6 @@ function traverseNavigationForPaths () {
return params;
}
/**
* Executed on page load
*/
$(function () {
if (! $('#pma_navigation').length) {
// Don't bother running any code if the navigation is not even on the page
return;
}
// Do not let the page reload on submitting the fast filter
$(document).on('submit', '.fast_filter', function (event) {
event.preventDefault();
});
// Fire up the resize handlers
new ResizeHandler();
/**
* opens/closes (hides/shows) tree elements
* loads data via ajax
*/
$(document).on('click', '#pma_navigation_tree a.expander', function (event) {
event.preventDefault();
event.stopImmediatePropagation();
var $icon = $(this).find('img');
if ($icon.is('.ic_b_plus')) {
expandTreeNode($(this));
} else {
collapseTreeNode($(this));
}
});
/**
* Register event handler for click on the reload
* navigation icon at the top of the panel
*/
$(document).on('click', '#pma_navigation_reload', function (event) {
event.preventDefault();
// reload icon object
var $icon = $(this).find('img');
// source of the hidden throbber icon
var icon_throbber_src = $('#pma_navigation').find('.throbber').attr('src');
// source of the reload icon
var icon_reload_src = $icon.attr('src');
// replace the source of the reload icon with the one for throbber
$icon.attr('src', icon_throbber_src);
PMA_reloadNavigation();
// after one second, put back the reload icon
setTimeout(function () {
$icon.attr('src', icon_reload_src);
}, 1000);
});
$(document).on('change', '#navi_db_select', function (event) {
if (! $(this).val()) {
PMA_commonParams.set('db', '');
PMA_reloadNavigation();
}
$(this).closest('form').trigger('submit');
});
/**
* Register event handler for click on the collapse all
* navigation icon at the top of the navigation tree
*/
$(document).on('click', '#pma_navigation_collapse', function (event) {
event.preventDefault();
$('#pma_navigation_tree').find('a.expander').each(function () {
var $icon = $(this).find('img');
if ($icon.is('.ic_b_minus')) {
$(this).trigger('click');
}
});
});
/**
* Register event handler to toggle
* the 'link with main panel' icon on mouseenter.
*/
$(document).on('mouseenter', '#pma_navigation_sync', function (event) {
event.preventDefault();
var synced = $('#pma_navigation_tree').hasClass('synced');
var $img = $('#pma_navigation_sync').children('img');
if (synced) {
$img.removeClass('ic_s_link').addClass('ic_s_unlink');
} else {
$img.removeClass('ic_s_unlink').addClass('ic_s_link');
}
});
/**
* Register event handler to toggle
* the 'link with main panel' icon on mouseout.
*/
$(document).on('mouseout', '#pma_navigation_sync', function (event) {
event.preventDefault();
var synced = $('#pma_navigation_tree').hasClass('synced');
var $img = $('#pma_navigation_sync').children('img');
if (synced) {
$img.removeClass('ic_s_unlink').addClass('ic_s_link');
} else {
$img.removeClass('ic_s_link').addClass('ic_s_unlink');
}
});
/**
* Register event handler to toggle
* the linking with main panel behavior
*/
$(document).on('click', '#pma_navigation_sync', function (event) {
event.preventDefault();
var synced = $('#pma_navigation_tree').hasClass('synced');
var $img = $('#pma_navigation_sync').children('img');
if (synced) {
$img
.removeClass('ic_s_unlink')
.addClass('ic_s_link')
.attr('alt', PMA_messages.linkWithMain)
.attr('title', PMA_messages.linkWithMain);
$('#pma_navigation_tree')
.removeClass('synced')
.find('li.selected')
.removeClass('selected');
} else {
$img
.removeClass('ic_s_link')
.addClass('ic_s_unlink')
.attr('alt', PMA_messages.unlinkWithMain)
.attr('title', PMA_messages.unlinkWithMain);
$('#pma_navigation_tree').addClass('synced');
PMA_showCurrentNavigation();
}
});
/**
* Bind all "fast filter" events
*/
$(document).on('click', '#pma_navigation_tree li.fast_filter span', PMA_fastFilter.events.clear);
$(document).on('focus', '#pma_navigation_tree li.fast_filter input.searchClause', PMA_fastFilter.events.focus);
$(document).on('blur', '#pma_navigation_tree li.fast_filter input.searchClause', PMA_fastFilter.events.blur);
$(document).on('keyup', '#pma_navigation_tree li.fast_filter input.searchClause', PMA_fastFilter.events.keyup);
/**
* Ajax handler for pagination
*/
$(document).on('click', '#pma_navigation_tree div.pageselector a.ajax', function (event) {
event.preventDefault();
PMA_navigationTreePagination($(this));
});
/**
* Node highlighting
*/
$(document).on(
'mouseover',
'#pma_navigation_tree.highlight li:not(.fast_filter)',
function () {
if ($('li:visible', this).length === 0) {
$(this).addClass('activePointer');
}
}
);
$(document).on(
'mouseout',
'#pma_navigation_tree.highlight li:not(.fast_filter)',
function () {
$(this).removeClass('activePointer');
}
);
/** Create a Routine, Trigger or Event */
$(document).on('click', 'li.new_procedure a.ajax, li.new_function a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('routine');
dialog.editorDialog(1, $(this));
});
$(document).on('click', 'li.new_trigger a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('trigger');
dialog.editorDialog(1, $(this));
});
$(document).on('click', 'li.new_event a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('event');
dialog.editorDialog(1, $(this));
});
/** Edit Routines, Triggers or Events */
$(document).on('click', 'li.procedure > a.ajax, li.function > a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('routine');
dialog.editorDialog(0, $(this));
});
$(document).on('click', 'li.trigger > a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('trigger');
dialog.editorDialog(0, $(this));
});
$(document).on('click', 'li.event > a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('event');
dialog.editorDialog(0, $(this));
});
/** Execute Routines */
$(document).on('click', 'li.procedure div a.ajax img,' +
' li.function div a.ajax img', function (event) {
event.preventDefault();
var dialog = new RTE.object('routine');
dialog.executeDialog($(this).parent());
});
/** Export Triggers and Events */
$(document).on('click', 'li.trigger div:eq(1) a.ajax img,' +
' li.event div:eq(1) a.ajax img', function (event) {
event.preventDefault();
var dialog = new RTE.object();
dialog.exportDialog($(this).parent());
});
/** New index */
$(document).on('click', '#pma_navigation_tree li.new_index a.ajax', function (event) {
event.preventDefault();
var url = $(this).attr('href').substr(
$(this).attr('href').indexOf('?') + 1
) + PMA_commonParams.get('arg_separator') + 'ajax_request=true';
var title = PMA_messages.strAddIndex;
indexEditorDialog(url, title);
});
/** Edit index */
$(document).on('click', 'li.index a.ajax', function (event) {
event.preventDefault();
var url = $(this).attr('href').substr(
$(this).attr('href').indexOf('?') + 1
) + PMA_commonParams.get('arg_separator') + 'ajax_request=true';
var title = PMA_messages.strEditIndex;
indexEditorDialog(url, title);
});
/** New view */
$(document).on('click', 'li.new_view a.ajax', function (event) {
event.preventDefault();
PMA_createViewDialog($(this));
});
/** Hide navigation tree item */
$(document).on('click', 'a.hideNavItem.ajax', function (event) {
event.preventDefault();
$.ajax({
type: 'POST',
data: {
server: PMA_commonParams.get('server'),
},
url: $(this).attr('href') + PMA_commonParams.get('arg_separator') + 'ajax_request=true',
success: function (data) {
if (typeof data !== 'undefined' && data.success === true) {
PMA_reloadNavigation();
} else {
PMA_ajaxShowMessage(data.error);
}
}
});
});
/** Display a dialog to choose hidden navigation items to show */
$(document).on('click', 'a.showUnhide.ajax', function (event) {
event.preventDefault();
var $msg = PMA_ajaxShowMessage();
$.get($(this).attr('href') + PMA_commonParams.get('arg_separator') + 'ajax_request=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
PMA_ajaxRemoveMessage($msg);
var buttonOptions = {};
buttonOptions[PMA_messages.strClose] = function () {
$(this).dialog('close');
};
$('<div/>')
.attr('id', 'unhideNavItemDialog')
.append(data.message)
.dialog({
width: 400,
minWidth: 200,
modal: true,
buttons: buttonOptions,
title: PMA_messages.strUnhideNavItem,
close: function () {
$(this).remove();
}
});
} else {
PMA_ajaxShowMessage(data.error);
}
});
});
/** Show a hidden navigation tree item */
$(document).on('click', 'a.unhideNavItem.ajax', function (event) {
event.preventDefault();
var $tr = $(this).parents('tr');
var $msg = PMA_ajaxShowMessage();
$.ajax({
type: 'POST',
data: {
server: PMA_commonParams.get('server'),
},
url: $(this).attr('href') + PMA_commonParams.get('arg_separator') + 'ajax_request=true',
success: function (data) {
PMA_ajaxRemoveMessage($msg);
if (typeof data !== 'undefined' && data.success === true) {
$tr.remove();
PMA_reloadNavigation();
} else {
PMA_ajaxShowMessage(data.error);
}
}
});
});
// Add/Remove favorite table using Ajax.
$(document).on('click', '.favorite_table_anchor', function (event) {
event.preventDefault();
$self = $(this);
var anchor_id = $self.attr('id');
if ($self.data('favtargetn') !== null) {
if ($('a[data-favtargets="' + $self.data('favtargetn') + '"]').length > 0) {
$('a[data-favtargets="' + $self.data('favtargetn') + '"]').trigger('click');
return;
}
}
$.ajax({
url: $self.attr('href'),
cache: false,
type: 'POST',
data: {
favorite_tables: (isStorageSupported('localStorage') && typeof window.localStorage.favorite_tables !== 'undefined')
? window.localStorage.favorite_tables
: '',
server: PMA_commonParams.get('server'),
},
success: function (data) {
if (data.changes) {
$('#pma_favorite_list').html(data.list);
$('#' + anchor_id).parent().html(data.anchor);
PMA_tooltip(
$('#' + anchor_id),
'a',
$('#' + anchor_id).attr('title')
);
// Update localStorage.
if (isStorageSupported('localStorage')) {
window.localStorage.favorite_tables = data.favorite_tables;
}
} else {
PMA_ajaxShowMessage(data.message);
}
}
});
});
// Check if session storage is supported
if (isStorageSupported('sessionStorage')) {
var storage = window.sessionStorage;
// remove tree from storage if Navi_panel config form is submitted
$(document).on('submit', 'form.config-form', function (event) {
storage.removeItem('navTreePaths');
});
// Initialize if no previous state is defined
if ($('#pma_navigation_tree_content').length &&
typeof storage.navTreePaths === 'undefined'
) {
PMA_reloadNavigation();
} else if (PMA_commonParams.get('server') === storage.server &&
PMA_commonParams.get('token') === storage.token
) {
// Reload the tree to the state before page refresh
PMA_reloadNavigation(navFilterStateRestore, JSON.parse(storage.navTreePaths));
} else {
// If the user is different
navTreeStateUpdate();
}
}
});
/**
* Expands a node in navigation tree.
*

View File

@ -1,187 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Server Status Processes
*
* @package PhpMyAdmin
*/
// object to store process list state information
var processList = {
// denotes whether auto refresh is on or off
autoRefresh: false,
// stores the GET request which refresh process list
refreshRequest: null,
// stores the timeout id returned by setTimeout
refreshTimeout: null,
// the refresh interval in seconds
refreshInterval: null,
// the refresh URL (required to save last used option)
// i.e. full or sorting url
refreshUrl: null,
/**
* Handles killing of a process
*
* @return void
*/
init: function () {
processList.setRefreshLabel();
if (processList.refreshUrl === null) {
processList.refreshUrl = 'server_status_processes.php' +
PMA_commonParams.get('common_query');
}
if (processList.refreshInterval === null) {
processList.refreshInterval = $('#id_refreshRate').val();
} else {
$('#id_refreshRate').val(processList.refreshInterval);
}
},
/**
* Handles killing of a process
*
* @param object the event object
*
* @return void
*/
killProcessHandler: function (event) {
event.preventDefault();
var url = $(this).attr('href');
// Get row element of the process to be killed.
var $tr = $(this).closest('tr');
$.getJSON(url, function (data) {
// Check if process was killed or not.
if (data.hasOwnProperty('success') && data.success) {
// remove the row of killed process.
$tr.remove();
// As we just removed a row, reapply odd-even classes
// to keep table stripes consistent
var $tableProcessListTr = $('#tableprocesslist').find('> tbody > tr');
$tableProcessListTr.filter(':even').removeClass('odd').addClass('even');
$tableProcessListTr.filter(':odd').removeClass('even').addClass('odd');
// Show process killed message
PMA_ajaxShowMessage(data.message, false);
} else {
// Show process error message
PMA_ajaxShowMessage(data.error, false);
}
});
},
/**
* Handles Auto Refreshing
*
* @param object the event object
*
* @return void
*/
refresh: function (event) {
// abort any previous pending requests
// this is necessary, it may go into
// multiple loops causing unnecessary
// requests even after leaving the page.
processList.abortRefresh();
// if auto refresh is enabled
if (processList.autoRefresh) {
var interval = parseInt(processList.refreshInterval, 10) * 1000;
var urlParams = processList.getUrlParams();
processList.refreshRequest = $.get(processList.refreshUrl,
urlParams,
function (data) {
if (data.hasOwnProperty('success') && data.success) {
$newTable = $(data.message);
$('#tableprocesslist').html($newTable.html());
PMA_highlightSQL($('#tableprocesslist'));
}
processList.refreshTimeout = setTimeout(
processList.refresh,
interval
);
});
}
},
/**
* Stop current request and clears timeout
*
* @return void
*/
abortRefresh: function () {
if (processList.refreshRequest !== null) {
processList.refreshRequest.abort();
processList.refreshRequest = null;
}
clearTimeout(processList.refreshTimeout);
},
/**
* Set label of refresh button
* change between play & pause
*
* @return void
*/
setRefreshLabel: function () {
var img = 'play';
var label = PMA_messages.strStartRefresh;
if (processList.autoRefresh) {
img = 'pause';
label = PMA_messages.strStopRefresh;
processList.refresh();
}
$('a#toggleRefresh').html(PMA_getImage(img) + escapeHtml(label));
},
/**
* Return the Url Parameters
* for autorefresh request,
* includes showExecuting if the filter is checked
*
* @return urlParams - url parameters with autoRefresh request
*/
getUrlParams: function () {
var urlParams = { 'ajax_request': true, 'refresh': true };
if ($('#showExecuting').is(':checked')) {
urlParams.showExecuting = true;
return urlParams;
}
return urlParams;
}
};
AJAX.registerOnload('server_status_processes.js', function () {
processList.init();
// Bind event handler for kill_process
$('#tableprocesslist').on(
'click',
'a.kill_process',
processList.killProcessHandler
);
// Bind event handler for toggling refresh of process list
$('a#toggleRefresh').on('click', function (event) {
event.preventDefault();
processList.autoRefresh = !processList.autoRefresh;
processList.setRefreshLabel();
});
// Bind event handler for change in refresh rate
$('#id_refreshRate').on('change', function (event) {
processList.refreshInterval = $(this).val();
processList.refresh();
});
// Bind event handler for table header links
$('#tableprocesslist').on('click', 'thead a', function () {
processList.refreshUrl = $(this).attr('href');
});
});
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server_status_processes.js', function () {
$('#tableprocesslist').off('click', 'a.kill_process');
$('a#toggleRefresh').off('click');
$('#id_refreshRate').off('change');
$('#tableprocesslist').off('click', 'thead a');
// stop refreshing further
processList.abortRefresh();
});

View File

@ -1,100 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
*
* @package PhpMyAdmin
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server_status_variables.js', function () {
$('#filterAlert').off('change');
$('#filterText').off('keyup');
$('#filterCategory').off('change');
$('#dontFormat').off('change');
});
AJAX.registerOnload('server_status_variables.js', function () {
// Filters for status variables
var textFilter = null;
var alertFilter = $('#filterAlert').prop('checked');
var categoryFilter = $('#filterCategory').find(':selected').val();
var text = ''; // Holds filter text
/* 3 Filtering functions */
$('#filterAlert').on('change', function () {
alertFilter = this.checked;
filterVariables();
});
$('#filterCategory').on('change', function () {
categoryFilter = $(this).val();
filterVariables();
});
$('#dontFormat').on('change', function () {
// Hiding the table while changing values speeds up the process a lot
$('#serverstatusvariables').hide();
$('#serverstatusvariables').find('td.value span.original').toggle(this.checked);
$('#serverstatusvariables').find('td.value span.formatted').toggle(! this.checked);
$('#serverstatusvariables').show();
}).trigger('change');
$('#filterText').on('keyup', function (e) {
var word = $(this).val().replace(/_/g, ' ');
if (word.length === 0) {
textFilter = null;
} else {
try {
textFilter = new RegExp('(^| )' + word, 'i');
$(this).removeClass('error');
} catch (e) {
if (e instanceof SyntaxError) {
$(this).addClass('error');
textFilter = null;
}
}
}
text = word;
filterVariables();
}).trigger('keyup');
/* Filters the status variables by name/category/alert in the variables tab */
function filterVariables () {
var useful_links = 0;
var section = text;
if (categoryFilter.length > 0) {
section = categoryFilter;
}
if (section.length > 1) {
$('#linkSuggestions').find('span').each(function () {
if ($(this).attr('class').indexOf('status_' + section) !== -1) {
useful_links++;
$(this).css('display', '');
} else {
$(this).css('display', 'none');
}
});
}
if (useful_links > 0) {
$('#linkSuggestions').css('display', '');
} else {
$('#linkSuggestions').css('display', 'none');
}
$('#serverstatusvariables').find('th.name').each(function () {
if ((textFilter === null || textFilter.exec($(this).text())) &&
(! alertFilter || $(this).next().find('span.attention').length > 0) &&
(categoryFilter.length === 0 || $(this).parent().hasClass('s_' + categoryFilter))
) {
$(this).parent().css('display', '');
} else {
$(this).parent().css('display', 'none');
}
});
}
});

View File

@ -1,112 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server_variables.js', function () {
$(document).off('click', 'a.editLink');
$('#serverVariables').find('.var-name').find('a img').remove();
});
AJAX.registerOnload('server_variables.js', function () {
var $editLink = $('a.editLink');
var $saveLink = $('a.saveLink');
var $cancelLink = $('a.cancelLink');
$('#serverVariables').find('.var-name').find('a').append(
$('#docImage').clone().css('display', 'inline-block')
);
/* Launches the variable editor */
$(document).on('click', 'a.editLink', function (event) {
event.preventDefault();
editVariable(this);
});
/* Allows the user to edit a server variable */
function editVariable (link) {
var $link = $(link);
var $cell = $link.parent();
var $valueCell = $link.parents('.var-row').find('.var-value');
var varName = $link.data('variable');
var $mySaveLink = $saveLink.clone().css('display', 'inline-block');
var $myCancelLink = $cancelLink.clone().css('display', 'inline-block');
var $msgbox = PMA_ajaxShowMessage();
var $myEditLink = $cell.find('a.editLink');
$cell.addClass('edit'); // variable is being edited
$myEditLink.remove(); // remove edit link
$mySaveLink.on('click', function () {
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
$.post($(this).attr('href'), {
ajax_request: true,
type: 'setval',
varName: varName,
varValue: $valueCell.find('input').val()
}, function (data) {
if (data.success) {
$valueCell
.html(data.variable)
.data('content', data.variable);
PMA_ajaxRemoveMessage($msgbox);
} else {
if (data.error === '') {
PMA_ajaxShowMessage(PMA_messages.strRequestFailed, false);
} else {
PMA_ajaxShowMessage(data.error, false);
}
$valueCell.html($valueCell.data('content'));
}
$cell.removeClass('edit').html($myEditLink);
});
return false;
});
$myCancelLink.on('click', function () {
$valueCell.html($valueCell.data('content'));
$cell.removeClass('edit').html($myEditLink);
return false;
});
$.get($mySaveLink.attr('href'), {
ajax_request: true,
type: 'getval',
varName: varName
}, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
var $links = $('<div />')
.append($myCancelLink)
.append('&nbsp;&nbsp;&nbsp;')
.append($mySaveLink);
var $editor = $('<div />', { 'class': 'serverVariableEditor' })
.append(
$('<div/>').append(
$('<input />', { type: 'text' }).val(data.message)
)
);
// Save and replace content
$cell
.html($links)
.children()
.css('display', 'flex');
$valueCell
.data('content', $valueCell.html())
.html($editor)
.find('input')
.focus()
.on('keydown', function (event) { // Keyboard shortcuts
if (event.keyCode === 13) { // Enter key
$mySaveLink.trigger('click');
} else if (event.keyCode === 27) { // Escape key
$myCancelLink.trigger('click');
}
});
PMA_ajaxRemoveMessage($msgbox);
} else {
$cell.removeClass('edit').html($myEditLink);
PMA_ajaxShowMessage(data.error);
}
});
}
});

840
js/src/ajax.js Normal file
View File

@ -0,0 +1,840 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_ajaxShowMessage,
PMA_ajaxRemoveMessage
} from './utils/show_ajax_messages';
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import CommonParams from './variables/common_params';
import { $ } from './utils/JqueryExtended';
import { PMA_getImage } from './functions/get_image';
import { PMA_ensureNaviSettings,
PMA_reloadNavigation,
PMA_disableNaviSettings
} from './functions/navigation';
import { isStorageSupported } from './functions/config';
import PMA_MicroHistory from './classes/MicroHistory';
import { escapeHtml } from './utils/Sanitise';
import { PMA_sprintf } from './utils/sprintf';
import { JsFileList } from './consts/files';
/**
* This object handles ajax requests for pages. It also
* handles the reloading of the main menu and scripts.
*/
/**
* @todo this function is to be removed when complete code is modularised
*/
function checkNewCode (script) {
var check = script.split('.js');
// console.log(check);
if (check.length === 2) {
return false;
} else {
return true;
}
}
export let AJAX = {
/**
* @var bool test variable for checking this object
*/
test: false,
/**
* @var bool active Whether we are busy
*/
active: false,
/**
* @var object source The object whose event initialized the request
*/
source: null,
/**
* @var object xhr A reference to the ajax request that is currently running
*/
xhr: null,
/**
* @var object lockedTargets, list of locked targets
*/
lockedTargets: {},
/**
* @var function Callback to execute after a successful request
* Used by PMA_commonFunctions from common.js
*/
_callback: function () {},
/**
* @var bool _debug Makes noise in your Firebug console
*/
_debug: false,
/**
* @var object $msgbox A reference to a jQuery object that links to a message
* box that is generated by PMA_ajaxShowMessage()
*/
$msgbox: null,
/**
* Given the filename of a script, returns a hash to be
* used to refer to all the events registered for the file
*
* @param key string key The filename for which to get the event name
*
* @return int
*/
hash: function (key) {
/* http://burtleburtle.net/bob/hash/doobs.html#one */
key += '';
var len = key.length;
var hash = 0;
var i = 0;
for (; i < len; ++i) {
hash += key.charCodeAt(i);
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return Math.abs(hash);
},
/**
* Registers an onload event for a file
*
* @param file string file The filename for which to register the event
* @param func function func The function to execute when the page is ready
*
* @return self For chaining
*/
registerOnload: function (file, func) {
var eventName = 'onload_' + this.hash(file);
$(document).on(eventName, func);
if (this._debug) {
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file
);
}
return this;
},
/**
* Registers a teardown event for a file. This is useful to execute functions
* that unbind events for page elements that are about to be removed.
*
* @param string file The filename for which to register the event
* @param function func The function to execute when
* the page is about to be torn down
*
* @return self For chaining
*/
registerTeardown: function (file, func) {
var eventName = 'teardown_' + this.hash(file);
$(document).on(eventName, func);
if (this._debug) {
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file
);
}
return this;
},
/**
* Called when a page has finished loading, once for every
* file that registered to the onload event of that file.
*
* @param string file The filename for which to fire the event
*
* @return void
*/
fireOnload: function (file) {
var eventName = 'onload_' + this.hash(file);
$(document).trigger(eventName);
if (this._debug) {
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file
);
}
},
/**
* Called just before a page is torn down, once for every
* file that registered to the teardown event of that file.
*
* @param string file The filename for which to fire the event
*
* @return void
*/
fireTeardown: function (file) {
var eventName = 'teardown_' + this.hash(file);
$(document).triggerHandler(eventName);
if (this._debug) {
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file
);
}
},
/**
* function to handle lock page mechanism
*
* @param event the event object
*
* @return void
*/
lockPageHandler: function (event) {
var newHash = null;
var oldHash = null;
var lockId;
// CodeMirror lock
if (event.data.value === 3) {
newHash = event.data.content;
oldHash = true;
lockId = 'cm';
} else {
// Don't lock on enter.
if (0 === event.charCode) {
return;
}
lockId = $(this).data('lock-id');
if (typeof lockId === 'undefined') {
return;
}
/*
* @todo Fix Code mirror does not give correct full value (query)
* in textarea, it returns only the change in content.
*/
if (event.data.value === 1) {
newHash = AJAX.hash($(this).val());
} else {
newHash = AJAX.hash($(this).is(':checked'));
}
oldHash = $(this).data('val-hash');
}
// Set lock if old value !== new value
// otherwise release lock
if (oldHash !== newHash) {
AJAX.lockedTargets[lockId] = true;
} else {
delete AJAX.lockedTargets[lockId];
}
// Show lock icon if locked targets is not empty.
// otherwise remove lock icon
if (!$.isEmptyObject(AJAX.lockedTargets)) {
$('#lock_page_icon').html(PMA_getImage('s_lock', PMA_messages.strLockToolTip).toString());
} else {
$('#lock_page_icon').html('');
}
},
/**
* resets the lock
*
* @return void
*/
resetLock: function () {
AJAX.lockedTargets = {};
$('#lock_page_icon').html('');
},
handleMenu: {
replace: function (content) {
$('#floating_menubar').html(content)
// Remove duplicate wrapper
// TODO: don't send it in the response
.children().first().remove();
$('#topmenu').menuResizer(PMA_mainMenuResizerCallback);
}
},
/**
* Event handler for clicks on links and form submissions
*
* @param object e Event data
*
* @return void
*/
requestHandler: function (event) {
// In some cases we don't want to handle the request here and either
// leave the browser deal with it natively (e.g: file download)
// or leave an existing ajax event handler present elsewhere deal with it
var href = $(this).attr('href');
if (typeof event !== 'undefined' && (event.shiftKey || event.ctrlKey)) {
return true;
} else if ($(this).attr('target')) {
return true;
} else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) {
// reset the lockedTargets object, as specified AJAX operation has finished
AJAX.resetLock();
return true;
} else if (href && href.match(/^#/)) {
return true;
} else if (href && href.match(/^mailto/)) {
return true;
} else if ($(this).hasClass('ui-datepicker-next') ||
$(this).hasClass('ui-datepicker-prev')
) {
return true;
}
if (typeof event !== 'undefined') {
event.preventDefault();
event.stopImmediatePropagation();
}
// triggers a confirm dialog if:
// the user has performed some operations on loaded page
// the user clicks on some link, (won't trigger for buttons)
// the click event is not triggered by script
if (typeof event !== 'undefined' && event.type === 'click' &&
event.isTrigger !== true &&
!$.isEmptyObject(AJAX.lockedTargets)
) {
if (confirm(PMA_messages.strConfirmNavigation) === false) {
return false;
} else {
if (isStorageSupported('localStorage')) {
window.localStorage.removeItem('auto_saved_sql');
} else {
Cookies.set('auto_saved_sql', '');
}
}
}
AJAX.resetLock();
var isLink = !! href || false;
var previousLinkAborted = false;
if (AJAX.active === true) {
// Cancel the old request if abortable, when the user requests
// something else. Otherwise silently bail out, as there is already
// a request well in progress.
if (AJAX.xhr) {
// In case of a link request, attempt aborting
AJAX.xhr.abort();
if (AJAX.xhr.status === 0 && AJAX.xhr.statusText === 'abort') {
// If aborted
AJAX.$msgbox = PMA_ajaxShowMessage(PMA_messages.strAbortedRequest);
AJAX.active = false;
AJAX.xhr = null;
previousLinkAborted = true;
} else {
// If can't abort
return false;
}
} else {
// In case submitting a form, don't attempt aborting
return false;
}
}
AJAX.source = $(this);
$('html, body').animate({ scrollTop: 0 }, 'fast');
var url = isLink ? href : $(this).attr('action');
var argsep = CommonParams.get('arg_separator');
var params = 'ajax_request=true' + argsep + 'ajax_page_request=true';
var dataPost = AJAX.source.getPostData();
if (! isLink) {
params += argsep + $(this).serialize();
} else if (dataPost) {
params += argsep + dataPost;
isLink = false;
}
if (! (history && history.pushState)) {
// Add a list of menu hashes that we have in the cache to the request
params += PMA_MicroHistory.menus.getRequestParam();
}
if (AJAX._debug) {
console.log('Loading: ' + url); // no need to translate
}
if (isLink) {
AJAX.active = true;
AJAX.$msgbox = PMA_ajaxShowMessage();
// Save reference for the new link request
AJAX.xhr = $.get(url, params, AJAX.responseHandler);
if (history && history.pushState) {
var state = {
url : href
};
if (previousLinkAborted) {
// hack: there is already an aborted entry on stack
// so just modify the aborted one
history.replaceState(state, null, href);
} else {
history.pushState(state, null, href);
}
}
} else {
/**
* Manually fire the onsubmit event for the form, if any.
* The event was saved in the jQuery data object by an onload
* handler defined below. Workaround for bug #3583316
*/
var onsubmit = $(this).data('onsubmit');
// Submit the request if there is no onsubmit handler
// or if it returns a value that evaluates to true
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
AJAX.active = true;
AJAX.$msgbox = PMA_ajaxShowMessage();
$.post(url, params, AJAX.responseHandler);
}
}
},
/**
* Called after the request that was initiated by this.requestHandler()
* has completed successfully or with a caught error. For completely
* failed requests or requests with uncaught errors, see the .ajaxError
* handler at the bottom of this file.
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param object e Event data
*
* @return void
*/
responseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
if (typeof data.success !== 'undefined' && data.success) {
$('html, body').animate({ scrollTop: 0 }, 'fast');
PMA_ajaxRemoveMessage(AJAX.$msgbox);
if (data._redirect) {
PMA_ajaxShowMessage(data._redirect, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
AJAX.scriptHandler.reset(function () {
if (data._reloadNavigation) {
PMA_reloadNavigation();
}
if (data._title) {
$('title').replaceWith(data._title);
}
if (data._menu) {
if (history && history.pushState) {
var state = {
url : data._selflink,
menu : data._menu
};
history.replaceState(state, null);
AJAX.handleMenu.replace(data._menu);
} else {
PMA_MicroHistory.menus.replace(data._menu);
PMA_MicroHistory.menus.add(data._menuHash, data._menu);
}
} else if (data._menuHash) {
if (! (history && history.pushState)) {
PMA_MicroHistory.menus.replace(PMA_MicroHistory.menus.get(data._menuHash));
}
}
if (data._disableNaviSettings) {
PMA_disableNaviSettings();
} else {
PMA_ensureNaviSettings(data._selflink);
}
// Remove all containers that may have
// been added outside of #page_content
$('body').children()
.not('#pma_navigation')
.not('#floating_menubar')
.not('#page_nav_icons')
.not('#page_content')
.not('#selflink')
.not('#pma_header')
.not('#pma_footer')
.not('#pma_demo')
.not('#pma_console_container')
.not('#prefs_autoload')
.remove();
// Replace #page_content with new content
if (data.message && data.message.length > 0) {
$('#page_content').replaceWith(
'<div id=\'page_content\'>' + data.message + '</div>'
);
PMA_highlightSQL($('#page_content'));
checkNumberOfFields();
}
if (data._selflink) {
var source = data._selflink.split('?')[0];
// Check for faulty links
var $selflink_replace = {
'import.php': 'tbl_sql.php',
'tbl_chart.php': 'sql.php',
'tbl_gis_visualization.php': 'sql.php'
};
if ($selflink_replace[source]) {
var replacement = $selflink_replace[source];
data._selflink = data._selflink.replace(source, replacement);
}
$('#selflink').find('> a').attr('href', data._selflink);
}
if (data._params) {
CommonParams.setAll(data._params);
}
if (data._scripts) {
AJAX.scriptHandler.load(data._scripts);
}
if (data._selflink && data._scripts && data._menuHash && data._params) {
if (! (history && history.pushState)) {
PMA_MicroHistory.add(
data._selflink,
data._scripts,
data._menuHash,
data._params,
AJAX.source.attr('rel')
);
}
}
if (data._displayMessage) {
$('#page_content').prepend(data._displayMessage);
PMA_highlightSQL($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data._errSubmitMsg) {
msg = data._errSubmitMsg;
}
if (data._errors) {
$('<div/>', { id : 'pma_errors', class : 'clearfloat' })
.insertAfter('#selflink')
.append(data._errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
PMA_ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
PMA_ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data._sendErrorAlways === '1' &&
data._stopErrorReportLoop !== '1'
) {
$('#pma_report_errors_form').submit();
PMA_ajaxShowMessage(PMA_messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
} else if (data._promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + PMA_messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
}
}
PMA_ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
PMA_ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
PMA_ignorePhpErrors(false);
});
if (typeof AJAX._callback === 'function') {
AJAX._callback.call();
}
AJAX._callback = function () {};
});
} else {
PMA_ajaxShowMessage(data.error, false);
AJAX.active = false;
AJAX.xhr = null;
PMA_handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* This object is in charge of downloading scripts,
* keeping track of what's downloaded and firing
* the onload event for them when the page is ready.
*/
scriptHandler: {
/**
* @var array _scripts The list of files already downloaded
*/
_scripts: [],
/**
* @var string _scriptsVersion version of phpMyAdmin from which the
* scripts have been loaded
*/
_scriptsVersion: null,
/**
* @var array _scriptsToBeLoaded The list of files that
* need to be downloaded
*/
_scriptsToBeLoaded: [],
/**
* @var array _scriptsToBeFired The list of files for which
* to fire the onload and unload events
*/
_scriptsToBeFired: [],
_scriptsCompleted: false,
/**
* Records that a file has been downloaded
*
* @param string file The filename
* @param string fire Whether this file will be registering
* onload/teardown events
*
* @return self For chaining
*/
add: function (file, fire, callback) {
var self = this;
this._scripts.push(file);
if (fire) {
// Record whether to fire any events for the file
// This is necessary to correctly tear down the initial page
this._scriptsToBeFired.push(file);
}
/**
* @todo This condition is to be removed once all the files are modularised
*/
if (checkNewCode(file)) {
if ($.inArray(file, JsFileList) !== -1) {
// Dynamic import to load the files dynamically
// This is used for the purpose of code splitting
import(`./${file}`)
.then((module) => {
/**
* setTimeout is used so that scripts run only when content is
* available.
*/
setTimeout(function () {
/**
* @var i The name of the module exported in corresponding file
*/
for (var i in module) {
// If the export has onload in its name, register onload for that export
if (i.indexOf('onload') !== -1) {
AJAX.registerOnload(`${file}`, module[i]);
} else if (i.indexOf('teardown') !== -1) {
// If the export has teardown in its name, register teardown for that export
AJAX.registerTeardown(file, module[i]);
}
}
// Firinf onload for the files being dynamically imported.
AJAX.fireOnload(file);
}, 250);
// AJAX.fireTeardown('server_databases_new.js');
})
// Error of Dynamica Imoprts need to be handled with Tracekit gracefully
.catch(e => console.log(e));
}
}
return this;
},
/**
* Download a list of js files in one request
*
* @param array files An array of filenames and flags
*
* @return void
*/
load: function (files, callback) {
var self = this;
var i;
// Clear loaded scripts if they are from another version of phpMyAdmin.
// Depends on common params being set before loading scripts in responseHandler
if (self._scriptsVersion === null) {
self._scriptsVersion = CommonParams.get('PMA_VERSION');
} else if (self._scriptsVersion !== CommonParams.get('PMA_VERSION')) {
self._scripts = [];
self._scriptsVersion = CommonParams.get('PMA_VERSION');
}
self._scriptsCompleted = false;
self._scriptsToBeFired = [];
// We need to first complete list of files to load
// as next loop will directly fire requests to load them
// and that triggers removal of them from
// self._scriptsToBeLoaded
for (i in files) {
self._scriptsToBeLoaded.push(files[i].name);
if (files[i].fire) {
self._scriptsToBeFired.push(files[i].name);
}
}
for (i in files) {
var script = files[i].name;
// Only for scripts that we don't already have
if ($.inArray(script, self._scripts) === -1) {
this.add(script, 0, callback);
/**
* @todo To be removed once complete code is modularised
* Only for appending js files in the header if not already present
*/
if (!checkNewCode(script)) {
this.appendScript(script, callback);
}
}
self.done(script, callback);
}
// Trigger callback if there is nothing else to load
self.done(null, callback);
},
/**
* Called whenever all files are loaded
*
* @return void
*/
done: function (script, callback) {
if (typeof ErrorReport !== 'undefined') {
ErrorReport.wrap_global_functions();
}
if ($.inArray(script, this._scriptsToBeFired)) {
AJAX.fireOnload(script);
}
if ($.inArray(script, this._scriptsToBeLoaded)) {
this._scriptsToBeLoaded.splice($.inArray(script, this._scriptsToBeLoaded), 1);
}
if (script === null) {
this._scriptsCompleted = true;
}
/* We need to wait for last signal (with null) or last script load */
AJAX.active = (this._scriptsToBeLoaded.length > 0) || ! this._scriptsCompleted;
/* Run callback on last script */
if (! AJAX.active && $.isFunction(callback)) {
callback();
}
},
/**
* Appends a script element to the head to load the scripts
*
* @return void
* this is to be removed in modularised code
* no appending of scripts is needed
*
* @todo This method will be of no use in modular code
*/
appendScript: function (name, callback) {
var head = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var self = this;
script.type = 'text/javascript';
script.src = 'js/' + name + '?' + 'v=' + encodeURIComponent(PMA_commonParams.get('PMA_VERSION'));
script.async = false;
script.onload = function () {
self.done(name, callback);
};
head.appendChild(script);
},
/**
* Fires all the teardown event handlers for the current page
* and rebinds all forms and links to the request handler
*
* @param function callback The callback to call after resetting
*
* @return void
*/
reset: function (callback) {
for (var i in this._scriptsToBeFired) {
AJAX.fireTeardown(this._scriptsToBeFired[i]);
}
this._scriptsToBeFired = [];
/**
* Re-attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).off('click', 'a').on('click', 'a', AJAX.requestHandler);
$(document).off('submit', 'form').on('submit', 'form', AJAX.requestHandler);
if (! (history && history.pushState)) {
PMA_MicroHistory.update();
}
callback();
}
}
};
/**
* @todo Below mentioned two events and functions are added in this file as these
* events and functions are making ajax call to the server for fetching resources
* and data.
* For now there are are two jquery instances, one which is globally available in
* the window object and another which is being exported as module.
* Once all the code work on new imported jQuery instance, these events and functions
* can be copied to index.js
*/
/**
* Attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).on('click', 'a', AJAX.requestHandler);
$(document).on('submit', 'form', AJAX.requestHandler);
/**
* @todo this is to be removed when complete code is modularised * Gracefully handle fatal server errors
* (e.g: 500 - Internal server error)
*/
$(document).ajaxError(function (event, request, settings) {
if (AJAX._debug) {
console.log('AJAX error: status=' + request.status + ', text=' + request.statusText);
}
// Don't handle aborted requests
if (request.status !== 0 || request.statusText !== 'abort') {
var details = '';
var state = request.state();
if (request.status !== 0) {
details += '<div>' + escapeHtml(PMA_sprintf(PMA_messages.strErrorCode, request.status)) + '</div>';
}
details += '<div>' + escapeHtml(PMA_sprintf(PMA_messages.strErrorText, request.statusText + ' (' + state + ')')) + '</div>';
if (state === 'rejected' || state === 'timeout') {
details += '<div>' + escapeHtml(PMA_messages.strErrorConnection) + '</div>';
}
PMA_ajaxShowMessage(
'<div class="error">' +
PMA_messages.strErrorProcessingRequest +
details +
'</div>',
false
);
AJAX.active = false;
AJAX.xhr = null;
}
});
/**
* Gracefully handle fatal server errors
* (e.g: 500 - Internal server error)
*/
$(document).ajaxError(function (event, request, settings) {
if (AJAX._debug) {
console.log('AJAX error: status=' + request.status + ', text=' + request.statusText);
}
// Don't handle aborted requests
if (request.status !== 0 || request.statusText !== 'abort') {
var details = '';
var state = request.state();
if (request.status !== 0) {
details += '<div>' + escapeHtml(PMA_sprintf(PMA_messages.strErrorCode, request.status)) + '</div>';
}
details += '<div>' + escapeHtml(PMA_sprintf(PMA_messages.strErrorText, request.statusText + ' (' + state + ')')) + '</div>';
if (state === 'rejected' || state === 'timeout') {
details += '<div>' + escapeHtml(PMA_messages.strErrorConnection) + '</div>';
}
PMA_ajaxShowMessage(
'<div class="error">' +
PMA_messages.strErrorProcessingRequest +
details +
'</div>',
false
);
AJAX.active = false;
AJAX.xhr = null;
}
});
/**
* Exporsing module to window for use with non modular code
*/
window.AJAX = AJAX;

691
js/src/classes/Chart.js vendored Normal file
View File

@ -0,0 +1,691 @@
import { $ } from '../utils/JqueryExtended';
import 'updated-jqplot';
import 'updated-jqplot/dist/plugins/jqplot.pieRenderer';
import 'updated-jqplot/dist/plugins/jqplot.highlighter';
import 'updated-jqplot/dist/plugins/jqplot.enhancedPieLegendRenderer';
import 'updated-jqplot/dist/plugins/jqplot.barRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.canvasAxisLabelRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.canvasTextRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.categoryAxisRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.dateAxisRenderer.js';
import 'updated-jqplot/dist/plugins/jqplot.pointLabels.js';
/**
* Chart type enumerations
*/
export var ChartType = {
LINE : 'line',
SPLINE : 'spline',
AREA : 'area',
BAR : 'bar',
COLUMN : 'column',
PIE : 'pie',
TIMELINE: 'timeline',
SCATTER: 'scatter'
};
/**
* Column type enumeration
*/
export var ColumnType = {
STRING : 'string',
NUMBER : 'number',
BOOLEAN : 'boolean',
DATE : 'date'
};
/**
* Abstract chart factory which defines the contract for chart factories
*/
var ChartFactory = function () {
};
ChartFactory.prototype = {
createChart : function (type, options) {
throw new Error('createChart must be implemented by a subclass');
}
};
/**
* Abstract chart which defines the contract for charts
*
* @param elementId
* id of the div element the chart is drawn in
*/
var Chart = function (elementId) {
this.elementId = elementId;
};
Chart.prototype = {
draw : function (data, options) {
throw new Error('draw must be implemented by a subclass');
},
redraw : function (options) {
throw new Error('redraw must be implemented by a subclass');
},
destroy : function () {
throw new Error('destroy must be implemented by a subclass');
},
toImageString : function () {
throw new Error('toImageString must be implemented by a subclass');
}
};
/**
* Abstract representation of charts that operates on DataTable where,<br />
* <ul>
* <li>First column provides index to the data.</li>
* <li>Each subsequent columns are of type
* <code>ColumnType.NUMBER<code> and represents a data series.</li>
* </ul>
* Line chart, area chart, bar chart, column chart are typical examples.
*
* @param elementId
* id of the div element the chart is drawn in
*/
var BaseChart = function (elementId) {
Chart.call(this, elementId);
};
BaseChart.prototype = new Chart();
BaseChart.prototype.constructor = BaseChart;
BaseChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length < 2) {
throw new Error('Minimum of two columns are required for this chart');
}
for (var i = 1; i < columns.length; i++) {
if (columns[i].type !== ColumnType.NUMBER) {
throw new Error('Column ' + (i + 1) + ' should be of type \'Number\'');
}
}
return true;
};
/**
* Abstract pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var PieChart = function (elementId) {
BaseChart.call(this, elementId);
};
PieChart.prototype = new BaseChart();
PieChart.prototype.constructor = PieChart;
PieChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length > 2) {
throw new Error('Pie charts can draw only one series');
}
return BaseChart.prototype.validateColumns.call(this, dataTable);
};
/**
* Abstract timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var TimelineChart = function (elementId) {
BaseChart.call(this, elementId);
};
TimelineChart.prototype = new BaseChart();
TimelineChart.prototype.constructor = TimelineChart;
TimelineChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.DATE) {
throw new Error('First column of timeline chart need to be a date column');
}
}
return result;
};
/**
* Abstract scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var ScatterChart = function (elementId) {
BaseChart.call(this, elementId);
};
ScatterChart.prototype = new BaseChart();
ScatterChart.prototype.constructor = ScatterChart;
ScatterChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.NUMBER) {
throw new Error('First column of scatter chart need to be a numeric column');
}
}
return result;
};
/**
* The data table contains column information and data for the chart.
*/
export var DataTable = function () {
var columns = [];
var data = null;
this.addColumn = function (type, name) {
columns.push({
'type' : type,
'name' : name
});
};
this.getColumns = function () {
return columns;
};
this.setData = function (rows) {
data = rows;
fillMissingValues();
};
this.getData = function () {
return data;
};
var fillMissingValues = function () {
if (columns.length === 0) {
throw new Error('Set columns first');
}
var row;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row.length > columns.length) {
row.splice(columns.length - 1, row.length - columns.length);
} else if (row.length < columns.length) {
for (var j = row.length; j < columns.length; j++) {
row.push(null);
}
}
}
};
};
/** *****************************************************************************
* JQPlot specific code
******************************************************************************/
/**
* Abstract JQplot chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotChart = function (elementId) {
Chart.call(this, elementId);
this.plot = null;
this.validator = null;
};
JQPlotChart.prototype = new Chart();
JQPlotChart.prototype.constructor = JQPlotChart;
JQPlotChart.prototype.draw = function (data, options) {
if (this.validator.validateColumns(data)) {
this.plot = $.jqplot(this.elementId, this.prepareData(data), this
.populateOptions(data, options));
}
};
JQPlotChart.prototype.destroy = function () {
if (this.plot !== null) {
this.plot.destroy();
}
};
JQPlotChart.prototype.redraw = function (options) {
if (this.plot !== null) {
this.plot.replot(options);
}
};
JQPlotChart.prototype.toImageString = function (options) {
if (this.plot !== null) {
return $('#' + this.elementId).jqplotToImageStr({});
}
};
JQPlotChart.prototype.populateOptions = function (dataTable, options) {
throw new Error('populateOptions must be implemented by a subclass');
};
JQPlotChart.prototype.prepareData = function (dataTable) {
throw new Error('prepareData must be implemented by a subclass');
};
/**
* JQPlot line chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotLineChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = BaseChart.prototype;
};
JQPlotLineChart.prototype = new JQPlotChart();
JQPlotLineChart.prototype.constructor = JQPlotLineChart;
JQPlotLineChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
xaxis : {
label : columns[0].name,
renderer : $.jqplot.CategoryAxisRenderer,
ticks : []
},
yaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'y',
formatString:'%d'
},
series : []
};
$.extend(true, optional, options);
if (optional.series.length === 0) {
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label : columns[i].name.toString()
});
}
}
if (optional.axes.xaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var j = 0; j < data.length; j++) {
optional.axes.xaxis.ticks.push(data[j][0].toString());
}
}
return optional;
};
JQPlotLineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push(row[j]);
}
}
return retData;
};
/**
* JQPlot spline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotSplineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotSplineChart.prototype = new JQPlotLineChart();
JQPlotSplineChart.prototype.constructor = JQPlotSplineChart;
JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
rendererOptions : {
smooth : true
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotScatterChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = ScatterChart.prototype;
};
JQPlotScatterChart.prototype = new JQPlotChart();
JQPlotScatterChart.prototype.constructor = JQPlotScatterChart;
JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
xaxis : {
label : columns[0].name
},
yaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString:'%d, %d'
},
series : []
};
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label : columns[i].name.toString()
});
}
var compulsory = {
seriesDefaults : {
showLine: false,
markerOptions: {
size: 7,
style: 'x'
}
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotScatterChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row[0]) {
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push([row[0], row[j]]);
}
}
}
return retData;
};
/**
* JQPlot timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotTimelineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
this.validator = TimelineChart.prototype;
};
JQPlotTimelineChart.prototype = new JQPlotLineChart();
JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart;
JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
axes : {
xaxis : {
tickOptions : {
formatString: '%b %#d, %y'
}
}
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
var compulsory = {
axes : {
xaxis : {
renderer : $.jqplot.DateAxisRenderer
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
JQPlotTimelineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var d;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
d = row[0];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
if (d !== null) {
retRow.push([d.getTime(), row[j]]);
}
}
}
return retData;
};
/**
* JQPlot area chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotAreaChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotAreaChart.prototype = new JQPlotLineChart();
JQPlotAreaChart.prototype.constructor = JQPlotAreaChart;
JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults : {
fillToZero : true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
fill : true
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot column chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotColumnChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotColumnChart.prototype = new JQPlotLineChart();
JQPlotColumnChart.prototype.constructor = JQPlotColumnChart;
JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults : {
fillToZero : true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
renderer : $.jqplot.BarRenderer
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot bar chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotBarChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotBarChart.prototype = new JQPlotLineChart();
JQPlotBarChart.prototype.constructor = JQPlotBarChart;
JQPlotBarChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
yaxis : {
label : columns[0].name,
labelRenderer : $.jqplot.CanvasAxisLabelRenderer,
renderer : $.jqplot.CategoryAxisRenderer,
ticks : []
},
xaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'x',
formatString:'%d'
},
series : [],
seriesDefaults : {
fillToZero : true
}
};
var compulsory = {
seriesDefaults : {
renderer : $.jqplot.BarRenderer,
rendererOptions : {
barDirection : 'horizontal'
}
}
};
$.extend(true, optional, options, compulsory);
if (optional.axes.yaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var i = 0; i < data.length; i++) {
optional.axes.yaxis.ticks.push(data[i][0].toString());
}
}
if (optional.series.length === 0) {
for (var j = 1; j < columns.length; j++) {
optional.series.push({
label : columns[j].name.toString()
});
}
}
return optional;
};
/**
* JQPlot pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotPieChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = PieChart.prototype;
};
JQPlotPieChart.prototype = new JQPlotChart();
JQPlotPieChart.prototype.constructor = JQPlotPieChart;
JQPlotPieChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString:'%s, %d',
useAxesFormatters: false
},
legend: {
renderer: $.jqplot.EnhancedPieLegendRenderer,
},
};
var compulsory = {
seriesDefaults : {
shadow: false,
renderer : $.jqplot.PieRenderer,
rendererOptions: { sliceMargin: 1, showDataLabels: true }
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotPieChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
for (var i = 0; i < data.length; i++) {
row = data[i];
retData.push([row[0], row[1]]);
}
return [retData];
};
/**
* Chart factory that returns JQPlotCharts
*/
var JQPlotChartFactory = function () {
};
JQPlotChartFactory.prototype = new ChartFactory();
JQPlotChartFactory.prototype.createChart = function (type, elementId) {
var chart = null;
switch (type) {
case ChartType.LINE:
chart = new JQPlotLineChart(elementId);
break;
case ChartType.SPLINE:
chart = new JQPlotSplineChart(elementId);
break;
case ChartType.TIMELINE:
chart = new JQPlotTimelineChart(elementId);
break;
case ChartType.AREA:
chart = new JQPlotAreaChart(elementId);
break;
case ChartType.BAR:
chart = new JQPlotBarChart(elementId);
break;
case ChartType.COLUMN:
chart = new JQPlotColumnChart(elementId);
break;
case ChartType.PIE:
chart = new JQPlotPieChart(elementId);
break;
case ChartType.SCATTER:
chart = new JQPlotScatterChart(elementId);
break;
}
return chart;
};
export default JQPlotChartFactory;

View File

@ -0,0 +1,59 @@
import CommonParams from '../variables/common_params';
import { AJAX } from '../ajax';
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*/
export var PMA_commonActions = {
/**
* Saves the database name when it's changed
* and reloads the query window, if necessary
*
* @param {string} newDb newDb The name of the new database
*
* @return {void}
*/
setDb: function (newDb) {
if (newDb !== CommonParams.get('db')) {
CommonParams.setAll({ 'db': newDb, 'table': '' });
}
},
/**
* Opens a database in the main part of the page
*
* @param {string} newDb The name of the new database
*
* @return void
*/
openDb: function (newDb) {
CommonParams
.set('db', newDb)
.set('table', '');
this.refreshMain(
CommonParams.get('opendb_url')
);
},
/**
* Refreshes the main frame
*
* @param mixed url Undefined to refresh to the same page
* String to go to a different page, e.g: 'index.php'
*
* @return void
*/
refreshMain: function (url, callback) {
if (! url) {
url = $('#selflink').find('a').attr('href');
url = url.substring(0, url.indexOf('?'));
}
url += CommonParams.getUrlQuery();
$('<a />', { href: url })
.appendTo('body')
.trigger('click')
.remove();
AJAX._callback = callback;
}
};

80
js/src/classes/Config.js Normal file
View File

@ -0,0 +1,80 @@
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
import { PMA_sprintf } from '../utils/sprintf';
// form validator list
export var validators = {
// regexp: numeric value
_regexp_numeric: /^[0-9]+$/,
// regexp: extract parts from PCRE expression
_regexp_pcre_extract: /(.)(.*)\1(.*)?/,
/**
* Validates positive number
*
* @param {boolean} isKeyUp
*/
PMA_validatePositiveNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = this.value !== '0' && validators._regexp_numeric.test(this.value);
return result ? true : PMA_messages.error_nan_p;
},
/**
* Validates non-negative number
*
* @param {boolean} isKeyUp
*/
PMA_validateNonNegativeNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = validators._regexp_numeric.test(this.value);
return result ? true : PMA_messages.error_nan_nneg;
},
/**
* Validates port number
*
* @param {boolean} isKeyUp
*/
PMA_validatePortNumber: function () {
if (this.value === '') {
return true;
}
var result = validators._regexp_numeric.test(this.value) && this.value !== '0';
return result && this.value <= 65535 ? true : PMA_messages.error_incorrect_port;
},
/**
* Validates value according to given regular expression
*
* @param {boolean} isKeyUp
* @param {string} regexp
*/
PMA_validateByRegex: function (isKeyUp, regexp) {
if (isKeyUp && this.value === '') {
return true;
}
// convert PCRE regexp
var parts = regexp.match(validators._regexp_pcre_extract);
var valid = this.value.match(new RegExp(parts[2], parts[3])) !== null;
return valid ? true : PMA_messages.error_invalid_value;
},
/**
* Validates upper bound for numeric inputs
*
* @param {boolean} isKeyUp
* @param {int} max_value
*/
PMA_validateUpperBound: function (isKeyUp, max_value) {
var val = parseInt(this.value, 10);
if (isNaN(val)) {
return true;
}
return val <= max_value ? true : PMA_sprintf(PMA_messages.error_value_lte, max_value);
},
// field validators
_field: {
},
// fieldset validators
_fieldset: {
}
};

View File

@ -0,0 +1,101 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Resizer object
* Careful: this object UI logics highly related with functions under PMA_console
* Resizing min-height is 32, if small than it, console will collapse
* @class ConsoleResizer
*/
export default class ConsoleResizer {
/**
* @param {Object} instance Instance of PMA Console
*/
constructor (instance) {
this._posY = 0;
this._height = 0;
this._resultHeight = 0;
this.pmaConsole = null;
this.initialize = this.initialize.bind(this);
this._mousedown = this._mousedown.bind(this);
this._mousemove = this._mousemove.bind(this);
this._mouseup = this._mouseup.bind(this);
this.setPmaConsole(instance);
}
/**
* @param {Object} instance Instance of PMA Console
* @return {void}
*/
setPmaConsole (instance) {
this.pmaConsole = instance;
this.initialize();
}
/**
* Mousedown event handler for bind to resizer
*
* @return void
*/
_mousedown (event) {
if (this.pmaConsole.config.Mode !== 'show') {
return;
}
this._posY = event.pageY;
this._height = this.pmaConsole.$consoleContent.height();
$(document).mousemove(this._mousemove);
$(document).mouseup(this._mouseup);
// Disable text selection while resizing
$(document).on('selectstart', function () {
return false;
});
}
/**
* Mousemove event handler for bind to resizer
*
* @return void
*/
_mousemove (event) {
if (event.pageY < 35) {
event.pageY = 35;
}
this._resultHeight = this._height + (this._posY - event.pageY);
// Content min-height is 32, if adjusting height small than it we'll move it out of the page
if (this._resultHeight <= 32) {
this.pmaConsole.$consoleAllContents.height(32);
this.pmaConsole.$consoleContent.css('margin-bottom', this._resultHeight - 32);
} else {
// Logic below makes viewable area always at bottom when adjusting height and content already at bottom
if (this.pmaConsole.$consoleContent.scrollTop() + this.pmaConsole.$consoleContent.innerHeight() + 16
>= this.pmaConsole.$consoleContent.prop('scrollHeight')) {
this.pmaConsole.$consoleAllContents.height(this._resultHeight);
this.pmaConsole.scrollBottom();
} else {
this.pmaConsole.$consoleAllContents.height(this._resultHeight);
}
}
}
/**
* Mouseup event handler for bind to resizer
*
* @return void
*/
_mouseup () {
this.pmaConsole.setConfig('Height', this._resultHeight);
this.pmaConsole.show();
$(document).off('mousemove');
$(document).off('mouseup');
$(document).off('selectstart');
}
/**
* Used for console resizer initialize
*
* @return void
*/
initialize () {
$('#pma_console').find('.toolbar').off('mousedown');
$('#pma_console').find('.toolbar').mousedown(this._mousedown);
}
}

View File

@ -0,0 +1,130 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import CommonParams from '../../variables/common_params';
import { PMA_Messages as messages } from '../../variables/export_variables';
/**
* @class ConsoleBookmarks
* Console bookmarks card, and bookmarks items management object
*/
export default class ConsoleBookmarks {
/**
* @constructor
* @param {Object} instance Instance of the PMA Console
* @return {void}
*/
constructor (instance) {
this._bookmarks = [];
this.pmaConsole = null;
this.setPmaConsole = this.setPmaConsole.bind(this);
this.addBookmark = this.addBookmark.bind(this);
this.refresh = this.refresh.bind(this);
this.initialize = this.initialize.bind(this);
this.setPmaConsole(instance);
}
/**
* @param {Object} instance Instance of PMA Console
* @return {void}
*/
setPmaConsole (instance) {
this.pmaConsole = instance;
this.initialize();
}
/**
* @param {string} queryString Query string to be bookmarked
* @param {string} targetDb Target database for the query string
* @param {string} label Label for the query
* @param {bool} isShared Is the query shared
* @return {void}
*/
addBookmark (queryString, targetDb, label, isShared) {
$('#pma_bookmarks').find('.add [name=shared]').prop('checked', false);
$('#pma_bookmarks').find('.add [name=label]').val('');
$('#pma_bookmarks').find('.add [name=targetdb]').val('');
$('#pma_bookmarks').find('.add [name=id_bookmark]').val('');
this.pmaConsole.pmaConsoleInput.setText('', 'bookmark');
switch (arguments.length) {
case 4:
$('#pma_bookmarks').find('.add [name=shared]').prop('checked', isShared);
break;
case 3:
$('#pma_bookmarks').find('.add [name=label]').val(label);
break;
case 2:
$('#pma_bookmarks').find('.add [name=targetdb]').val(targetDb);
break;
case 1:
this.pmaConsole.pmaConsoleInput.setText(queryString, 'bookmark');
break;
default:
break;
}
}
/**
* Method to refresh the bookmak list
* @return {void}
*/
refresh () {
$.get('import.php',
{ ajax_request: true,
server: CommonParams.get('server'),
console_bookmark_refresh: 'refresh' },
function (data) {
if (data.console_message_bookmark) {
$('#pma_bookmarks').find('.content.bookmark').html(data.console_message_bookmark);
this.pmaConsole.pmaConsoleMessages._msgEventBinds($('#pma_bookmarks').find('.message:not(.binded)'));
}
}.bind(this));
}
/**
* Used for console bookmarks initialize
* message events are already binded by PMA_consoleMsg._msgEventBinds
*
* @return void
*/
initialize () {
var self = this;
if ($('#pma_bookmarks').length === 0) {
return;
}
$('#pma_console').find('.button.bookmarks').click(function () {
self.pmaConsole.showCard('#pma_bookmarks');
});
$('#pma_bookmarks').find('.button.add').click(function () {
self.pmaConsole.showCard('#pma_bookmarks .card.add');
});
$('#pma_bookmarks').find('.card.add [name=submit]').click(function () {
if ($('#pma_bookmarks').find('.card.add [name=label]').val().length === 0
|| self.pmaConsole.pmaConsoleInput.getText('bookmark').length === 0) {
alert(messages.strFormEmpty);
return;
}
$(this).prop('disabled', true);
$.post('import.php',
{
ajax_request: true,
console_bookmark_add: 'true',
label: $('#pma_bookmarks').find('.card.add [name=label]').val(),
server: CommonParams.get('server'),
db: $('#pma_bookmarks').find('.card.add [name=targetdb]').val(),
bookmark_query: self.pmaConsole.pmaConsoleInput.getText('bookmark'),
shared: $('#pma_bookmarks').find('.card.add [name=shared]').prop('checked') },
function () {
self.refresh();
$('#pma_bookmarks').find('.card.add [name=submit]').prop('disabled', false);
self.pmaConsole.hideCard($('#pma_bookmarks').find('.card.add'));
});
});
$('#pma_console').find('.button.refresh').click(function () {
self.refresh();
});
}
}

View File

@ -0,0 +1,441 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_Messages as messages } from '../../variables/export_variables';
import { PMA_sprintf } from '../../utils/sprintf';
import { escapeHtml } from '../../utils/Sanitise';
/**
* Console debug object
* @class ConsoleDebug
*/
export default class ConsoleDebug {
/**
* @constructor
* @param {Object} instance Instance of PMA Console
*/
constructor (instance) {
this.pmaConsole = null;
this._config = {
groupQueries: false,
orderBy: 'exec', // Possible 'exec' => Execution order, 'time' => Time taken, 'count'
order: 'asc' // Possible 'asc', 'desc'
};
this._lastDebugInfo = {
debugInfo: null,
url: null
};
this.initialize = this.initialize.bind(this);
this.setPmaConsole = this.setPmaConsole.bind(this);
this._formatFunctionCall = this._formatFunctionCall.bind(this);
this._formatFunctionArgs = this._formatFunctionArgs.bind(this);
this._formatFileName = this._formatFileName.bind(this);
this._formatBackTrace = this._formatBackTrace.bind(this);
this._formatQueryOrGroup = this._formatQueryOrGroup.bind(this);
this._appendQueryExtraInfo = this._appendQueryExtraInfo.bind(this);
this.getQueryDetails = this.getQueryDetails.bind(this);
this.showLog = this.showLog.bind(this);
this.refresh = this.refresh.bind(this);
this.setPmaConsole(instance);
}
/**
* @param {Object} instance Instance of PMA Console
* @return {void}
*/
setPmaConsole (instance) {
this.pmaConsole = instance;
this.initialize();
}
/**
* Used for Console Debug initialise
* @return {void}
*/
initialize () {
var self = this;
// Try to get debug info after every AJAX request
$(document).ajaxSuccess(function (event, xhr, settings, data) {
if (data._debug) {
self.showLog(data._debug, settings.url);
}
});
if (self.pmaConsole.config.GroupQueries) {
$('#debug_console').addClass('grouped');
} else {
$('#debug_console').addClass('ungrouped');
if (self.pmaConsole.config.OrderBy === 'count') {
$('#debug_console').find('.button.order_by.sort_exec').addClass('active');
}
}
var orderBy = self.pmaConsole.config.OrderBy;
var order = self.pmaConsole.config.Order;
$('#debug_console').find('.button.order_by.sort_' + orderBy).addClass('active');
$('#debug_console').find('.button.order.order_' + order).addClass('active');
// Initialize actions in toolbar
$('#debug_console').find('.button.group_queries').click(function () {
$('#debug_console').addClass('grouped');
$('#debug_console').removeClass('ungrouped');
self.pmaConsole.setConfig('GroupQueries', true);
self.refresh();
if (self.pmaConsole.config.OrderBy === 'count') {
$('#debug_console').find('.button.order_by.sort_exec').removeClass('active');
}
});
$('#debug_console').find('.button.ungroup_queries').click(function () {
$('#debug_console').addClass('ungrouped');
$('#debug_console').removeClass('grouped');
self.pmaConsole.setConfig('GroupQueries', false);
self.refresh();
if (self.pmaConsole.config.OrderBy === 'count') {
$('#debug_console').find('.button.order_by.sort_exec').addClass('active');
}
});
$('#debug_console').find('.button.order_by').click(function () {
var $this = $(this);
$('#debug_console').find('.button.order_by').removeClass('active');
$this.addClass('active');
if ($this.hasClass('sort_time')) {
self.pmaConsole.setConfig('OrderBy', 'time');
} else if ($this.hasClass('sort_exec')) {
self.pmaConsole.setConfig('OrderBy', 'exec');
} else if ($this.hasClass('sort_count')) {
self.pmaConsole.setConfig('OrderBy', 'count');
}
self.refresh();
});
$('#debug_console').find('.button.order').click(function () {
var $this = $(this);
$('#debug_console').find('.button.order').removeClass('active');
$this.addClass('active');
if ($this.hasClass('order_asc')) {
self.pmaConsole.setConfig('Order', 'asc');
} else if ($this.hasClass('order_desc')) {
self.pmaConsole.setConfig('Order', 'desc');
}
self.refresh();
});
// Show SQL debug info for first page load
if (typeof debugSQLInfo !== 'undefined' && debugSQLInfo !== 'null') {
$('#pma_console').find('.button.debug').removeClass('hide');
} else {
return;
}
self.showLog(debugSQLInfo);
}
_formatFunctionCall (dbgStep) {
var functionName = '';
if ('class' in dbgStep) {
functionName += dbgStep.class;
functionName += dbgStep.type;
}
functionName += dbgStep.function;
if (dbgStep.args && dbgStep.args.length) {
functionName += '(...)';
} else {
functionName += '()';
}
return functionName;
}
_formatFunctionArgs (dbgStep) {
var $args = $('<div>');
if (dbgStep.args.length) {
$args.append('<div class="message welcome">')
.append(
$('<div class="message welcome">')
.text(
PMA_sprintf(
messages.strConsoleDebugArgsSummary,
dbgStep.args.length
)
)
);
for (var i = 0; i < dbgStep.args.length; i++) {
$args.append(
$('<div class="message">')
.html(
'<pre>' +
escapeHtml(JSON.stringify(dbgStep.args[i], null, ' ')) +
'</pre>'
)
);
}
}
return $args;
}
_formatFileName (dbgStep) {
var fileName = '';
if ('file' in dbgStep) {
fileName += dbgStep.file;
fileName += '#' + dbgStep.line;
}
return fileName;
}
_formatBackTrace (dbgTrace) {
var $traceElem = $('<div class="trace">');
$traceElem.append(
$('<div class="message welcome">')
);
var step;
var $stepElem;
for (var stepId in dbgTrace) {
if (dbgTrace.hasOwnProperty(stepId)) {
step = dbgTrace[stepId];
if (!Array.isArray(step) && typeof step !== 'object') {
$stepElem =
$('<div class="message traceStep collapsed hide_args">')
.append(
$('<span>').text(step)
);
} else {
if (typeof step.args === 'string' && step.args) {
step.args = [step.args];
}
$stepElem =
$('<div class="message traceStep collapsed hide_args">')
.append(
$('<span class="function">').text(this._formatFunctionCall(step))
)
.append(
$('<span class="file">').text(this._formatFileName(step))
);
if (step.args && step.args.length) {
$stepElem
.append(
$('<span class="args">').html(this._formatFunctionArgs(step))
)
.prepend(
$('<div class="action_content">')
.append(
'<span class="action dbg_show_args">' +
messages.strConsoleDebugShowArgs +
'</span> '
)
.append(
'<span class="action dbg_hide_args">' +
messages.strConsoleDebugHideArgs +
'</span> '
)
);
}
}
$traceElem.append($stepElem);
}
}
return $traceElem;
}
_formatQueryOrGroup (queryInfo, totalTime) {
var grouped;
var queryText;
var queryTime;
var count;
var i;
if (Array.isArray(queryInfo)) {
// It is grouped
grouped = true;
queryText = queryInfo[0].query;
queryTime = 0;
for (i in queryInfo) {
queryTime += queryInfo[i].time;
}
count = queryInfo.length;
} else {
queryText = queryInfo.query;
queryTime = queryInfo.time;
}
var $query = $('<div class="message collapsed hide_trace">')
.append(
$('#debug_console').find('.templates .debug_query').clone()
)
.append(
$('<div class="query">')
.text(queryText)
)
.data('queryInfo', queryInfo)
.data('totalTime', totalTime);
if (grouped) {
$query.find('.text.count').removeClass('hide');
$query.find('.text.count span').text(count);
}
$query.find('.text.time span').text(queryTime + 's (' + ((queryTime * 100) / totalTime).toFixed(3) + '%)');
return $query;
}
_appendQueryExtraInfo (query, $elem) {
if ('error' in query) {
$elem.append(
$('<div>').html(query.error)
);
}
$elem.append(this._formatBackTrace(query.trace));
}
getQueryDetails (queryInfo, totalTime, $query) {
if (Array.isArray(queryInfo)) {
var $singleQuery;
for (var i in queryInfo) {
$singleQuery = $('<div class="message welcome trace">')
.text((parseInt(i) + 1) + '.')
.append(
$('<span class="time">').text(
messages.strConsoleDebugTimeTaken +
' ' + queryInfo[i].time + 's' +
' (' + ((queryInfo[i].time * 100) / totalTime).toFixed(3) + '%)'
)
);
this._appendQueryExtraInfo(queryInfo[i], $singleQuery);
$query
.append('<div class="message welcome trace">')
.append($singleQuery);
}
} else {
this._appendQueryExtraInfo(queryInfo, $query);
}
}
showLog (debugInfo, url) {
this._lastDebugInfo.debugInfo = debugInfo;
this._lastDebugInfo.url = url;
$('#debug_console').find('.debugLog').empty();
$('#debug_console').find('.debug>.welcome').empty();
var debugJson = false;
var i;
if (typeof debugInfo === 'object' && 'queries' in debugInfo) {
// Copy it to debugJson, so that it doesn't get changed
if (!('queries' in debugInfo)) {
debugJson = false;
} else {
debugJson = { queries: [] };
for (i in debugInfo.queries) {
debugJson.queries[i] = debugInfo.queries[i];
}
}
} else if (typeof debugInfo === 'string') {
try {
debugJson = JSON.parse(debugInfo);
} catch (e) {
debugJson = false;
}
if (debugJson && !('queries' in debugJson)) {
debugJson = false;
}
}
if (debugJson === false) {
$('#debug_console').find('.debug>.welcome').text(
messages.strConsoleDebugError
);
return;
}
var allQueries = debugJson.queries;
var uniqueQueries = {};
var totalExec = allQueries.length;
// Calculate total time and make unique query array
var totalTime = 0;
for (i = 0; i < totalExec; ++i) {
totalTime += allQueries[i].time;
if (!(allQueries[i].hash in uniqueQueries)) {
uniqueQueries[allQueries[i].hash] = [];
}
uniqueQueries[allQueries[i].hash].push(allQueries[i]);
}
// Count total unique queries, convert uniqueQueries to Array
var totalUnique = 0;
var uniqueArray = [];
for (var hash in uniqueQueries) {
if (uniqueQueries.hasOwnProperty(hash)) {
++totalUnique;
uniqueArray.push(uniqueQueries[hash]);
}
}
uniqueQueries = uniqueArray;
// Show summary
$('#debug_console').find('.debug>.welcome').append(
$('<span class="debug_summary">').text(
PMA_sprintf(
messages.strConsoleDebugSummary,
totalUnique,
totalExec,
totalTime
)
)
);
if (url) {
$('#debug_console').find('.debug>.welcome').append(
$('<span class="script_name">').text(url.split('?')[0])
);
}
// For sorting queries
function sortByTime (a, b) {
var order = ((this.pmaConsole.config.Order === 'asc') ? 1 : -1);
if (Array.isArray(a) && Array.isArray(b)) {
// It is grouped
var timeA = 0;
var timeB = 0;
var i;
for (i in a) {
timeA += a[i].time;
}
for (i in b) {
timeB += b[i].time;
}
return (timeA - timeB) * order;
} else {
return (a.time - b.time) * order;
}
}
function sortByCount (a, b) {
var order = ((this.pmaConsole.config.Order === 'asc') ? 1 : -1);
return (a.length - b.length) * order;
}
var orderBy = this.pmaConsole.config.OrderBy;
var order = this.pmaConsole.config.Order;
if (this.pmaConsole.config.GroupQueries) {
// Sort queries
if (orderBy === 'time') {
uniqueQueries.sort(sortByTime);
} else if (orderBy === 'count') {
uniqueQueries.sort(sortByCount);
} else if (orderBy === 'exec' && order === 'desc') {
uniqueQueries.reverse();
}
for (i in uniqueQueries) {
if (orderBy === 'time') {
uniqueQueries[i].sort(sortByTime);
} else if (orderBy === 'exec' && order === 'desc') {
uniqueQueries[i].reverse();
}
$('#debug_console').find('.debugLog').append(this._formatQueryOrGroup(uniqueQueries[i], totalTime));
}
} else {
if (orderBy === 'time') {
allQueries.sort(sortByTime);
} else if (order === 'desc') {
allQueries.reverse();
}
for (i = 0; i < totalExec; ++i) {
$('#debug_console').find('.debugLog').append(this._formatQueryOrGroup(allQueries[i], totalTime));
}
}
this.pmaConsole.pmaConsoleMessages._msgEventBinds($('#debug_console').find('.message:not(.binded)'));
}
refresh () {
var last = this._lastDebugInfo;
this.showLog(last.debugInfo, last.url);
}
}

View File

@ -0,0 +1,312 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import CodeMirror from 'codemirror';
import 'codemirror/mode/sql/sql.js';
import 'codemirror/addon/runmode/runmode.js';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/sql-hint.js';
import 'codemirror/addon/lint/lint.js';
import '../../plugins/codemirror/sql-lint';
import { codemirrorAutocompleteOnInputRead } from '../../utils/sql';
import CommonParams from '../../variables/common_params';
/**
* Console input object
* @class ConsoleInput
*/
export default class ConsoleInput {
/**
* @constructor
* @param {object} instance Instance of PMA Console
*/
constructor (instance) {
/**
* @var array, contains Codemirror objects or input jQuery objects
* @access private
*/
this._inputs = null;
/**
* @var bool, if codemirror enabled
* @access private
*/
this._codemirror = false;
/**
* @var int, count for history navigation, 0 for current input
* @access private
*/
this._historyCount = 0;
/**
* @var string, current input when navigating through history
* @access private
*/
this._historyPreserveCurrent = null;
/**
* @var object
* @access private
*/
this.pmaConsole = null;
/**
* Bindings for accessing the instance of the class using this
* insde the methods.
*/
this.setPmaConsole = this.setPmaConsole.bind(this);
this.initialize = this.initialize.bind(this);
this._historyNavigate = this._historyNavigate.bind(this);
this._keydown = this._keydown.bind(this);
this.execute = this.execute.bind(this);
this.clear = this.clear.bind(this);
this.focus = this.focus.bind(this);
this.blur = this.blur.bind(this);
this.setText = this.setText.bind(this);
this.getText = this.getText.bind(this);
this.setPmaConsole(instance);
}
/**
* @param {Object} instance Instance of PMA Console
* @return {void}
*/
setPmaConsole (instance) {
this.pmaConsole = instance;
this.initialize();
}
/**
* Used for Console Input initialise
* @return {void}
*/
initialize () {
// _cm object can't be reinitialize
if (this._inputs !== null) {
return;
}
if (CommonParams.get('CodemirrorEnable') === true) {
this._codemirror = true;
}
this._inputs = [];
if (this._codemirror) {
this._inputs.console = CodeMirror($('#pma_console').find('.console_query_input')[0], {
theme: 'pma',
mode: 'text/x-sql',
lineWrapping: true,
extraKeys: { 'Ctrl-Space': 'autocomplete' },
hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true },
gutters: ['CodeMirror-lint-markers'],
lint: {
'getAnnotations': CodeMirror.sqlLint,
'async': true,
}
});
this._inputs.console.on('inputRead', codemirrorAutocompleteOnInputRead);
this._inputs.console.on('keydown', function (instance, event) {
this._historyNavigate(event);
}.bind(this));
if ($('#pma_bookmarks').length !== 0) {
this._inputs.bookmark = CodeMirror($('#pma_console').find('.bookmark_add_input')[0], {
theme: 'pma',
mode: 'text/x-sql',
lineWrapping: true,
extraKeys: { 'Ctrl-Space': 'autocomplete' },
hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true },
gutters: ['CodeMirror-lint-markers'],
lint: {
'getAnnotations': CodeMirror.sqlLint,
'async': true,
}
});
this._inputs.bookmark.on('inputRead', codemirrorAutocompleteOnInputRead);
}
} else {
this._inputs.console =
$('<textarea>').appendTo('#pma_console .console_query_input')
.on('keydown', this._historyNavigate);
if ($('#pma_bookmarks').length !== 0) {
this._inputs.bookmark =
$('<textarea>').appendTo('#pma_console .bookmark_add_input');
}
}
$('#pma_console').find('.console_query_input').keydown(this._keydown);
}
/**
* @param {jQueryEvent} event
* @return {void}
*/
_historyNavigate (event) {
if (event.keyCode === 38 || event.keyCode === 40) {
var upPermitted = false;
var downPermitted = false;
var editor = this._inputs.console;
var cursorLine;
var totalLine;
if (this._codemirror) {
cursorLine = editor.getCursor().line;
totalLine = editor.lineCount();
} else {
// Get cursor position from textarea
var text = this.getText();
cursorLine = text.substr(0, editor.prop('selectionStart')).split('\n').length - 1;
totalLine = text.split(/\r*\n/).length;
}
if (cursorLine === 0) {
upPermitted = true;
}
if (cursorLine === totalLine - 1) {
downPermitted = true;
}
var nextCount;
var queryString = false;
if (upPermitted && event.keyCode === 38) {
// Navigate up in history
if (this._historyCount === 0) {
this._historyPreserveCurrent = this.getText();
}
nextCount = this._historyCount + 1;
queryString = this.pmaConsole.pmaConsoleMessages.getHistory(nextCount);
} else if (downPermitted && event.keyCode === 40) {
// Navigate down in history
if (this._historyCount === 0) {
return;
}
nextCount = this._historyCount - 1;
if (nextCount === 0) {
queryString = this._historyPreserveCurrent;
} else {
queryString = this.pmaConsole.pmaConsoleMessages.getHistory(nextCount);
}
}
if (queryString !== false) {
this._historyCount = nextCount;
this.setText(queryString, 'console');
if (this._codemirror) {
editor.setCursor(editor.lineCount(), 0);
}
event.preventDefault();
}
}
}
/**
* Mousedown event handler for bind to input
* Shortcut is Ctrl+Enter key or just ENTER, depending on console's
* configuration.
*
* @return void
*/
_keydown (event) {
if (this.pmaConsole.config.EnterExecutes) {
// Enter, but not in combination with Shift (which writes a new line).
if (!event.shiftKey && event.keyCode === 13) {
this.execute();
}
} else {
// Ctrl+Enter
if (event.ctrlKey && event.keyCode === 13) {
this.execute();
}
}
}
/**
* Used for send text to PMA_console.execute()
*
* @return void
*/
execute () {
if (this._codemirror) {
this.pmaConsole.execute(this._inputs.console.getValue());
} else {
this.pmaConsole.execute(this._inputs.console.val());
}
}
/**
* Used for clear the input
*
* @param string target, default target is console input
* @return void
*/
clear (target) {
this.setText('', target);
}
/**
* Used for set focus to input
*
* @return void
*/
focus () {
this._inputs.console.focus();
}
/**
* Used for blur input
*
* @return void
*/
blur () {
if (this._codemirror) {
this._inputs.console.getInputField().blur();
} else {
this._inputs.console.blur();
}
}
/**
* Used for set text in input
*
* @param string text
* @param string target
*
* @return void
*/
setText (text, target) {
if (this._codemirror) {
switch (target) {
case 'bookmark':
this.pmaConsole.execute(this._inputs.bookmark.setValue(text));
break;
default:
case 'console':
this.pmaConsole.execute(this._inputs.console.setValue(text));
}
} else {
switch (target) {
case 'bookmark':
this.pmaConsole.execute(this._inputs.bookmark.val(text));
break;
default:
case 'console':
this.pmaConsole.execute(this._inputs.console.val(text));
}
}
}
/**
* Used for getting the text of input
*
* @param {string} target
*
* @return {string}
*/
getText (target) {
if (this._codemirror) {
switch (target) {
case 'bookmark':
return this._inputs.bookmark.getValue();
default:
case 'console':
return this._inputs.console.getValue();
}
} else {
switch (target) {
case 'bookmark':
return this._inputs.bookmark.val();
default:
case 'console':
return this._inputs.console.val();
}
}
}
}

View File

@ -0,0 +1,337 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import CodeMirror from 'codemirror';
import PMA_commonParams from '../../variables/common_params';
import { PMA_Messages as messages } from '../../variables/export_variables';
/**
* Console messages, and message items management object
* @class ConsoleMessages
*/
export default class ConsoleMessages {
/**
* @param {Object} instance Instance of PMA Console
*/
constructor (instance) {
this.pmaConsole = null;
this.clear = this.clear.bind(this);
this.showHistory = this.showHistory.bind(this);
this.getHistory = this.getHistory.bind(this);
this.showInstructions = this.showInstructions.bind(this);
this.append = this.append.bind(this);
this.appendQuery = this.appendQuery.bind(this);
this._msgEventBinds = this._msgEventBinds.bind(this);
this.msgAppend = this.msgAppend.bind(this);
this.updateQuery = this.updateQuery.bind(this);
this.initialize = this.initialize.bind(this);
this.setPmaConsole = this.setPmaConsole.bind(this);
this.setPmaConsole(instance);
}
/**
* @param {Object} instance Instance of PMA Console
* @return {void}
*/
setPmaConsole (instance) {
this.pmaConsole = instance;
this.initialize();
}
/**
* Used for clear the messages
*
* @return void
*/
clear () {
$('#pma_console').find('.content .console_message_container .message:not(.welcome)').addClass('hide');
$('#pma_console').find('.content .console_message_container .message.failed').remove();
$('#pma_console').find('.content .console_message_container .message.expanded').find('.action.collapse').click();
}
/**
* Used for show history messages
*
* @return void
*/
showHistory () {
$('#pma_console').find('.content .console_message_container .message.hide').removeClass('hide');
}
/**
* Used for getting a perticular history query
*
* @param int nthLast get nth query message from latest, i.e 1st is last
* @return string message
*/
getHistory (nthLast) {
var $queries = $('#pma_console').find('.content .console_message_container .query');
var length = $queries.length;
var $query = $queries.eq(length - nthLast);
if (!$query || (length - nthLast) < 0) {
return false;
} else {
return $query.text();
}
}
/**
* Used to show the correct message depending on which key
* combination executes the query (Ctrl+Enter or Enter).
*
* @param bool enterExecutes Only Enter has to be pressed to execute query.
* @return void
*/
showInstructions (enterExecutes) {
enterExecutes = +enterExecutes || 0; // conversion to int
var $welcomeMsg = $('#pma_console').find('.content .console_message_container .message.welcome span');
$welcomeMsg.children('[id^=instructions]').hide();
$welcomeMsg.children('#instructions-' + enterExecutes).show();
}
/**
* Used for log new message
*
* @param string msgString Message to show
* @param string msgType Message type
* @return object, {message_id, $message}
*/
append (msgString, msgType) {
if (typeof(msgString) !== 'string') {
return false;
}
// Generate an ID for each message, we can find them later
var msgId = Math.round(Math.random() * (899999999999) + 100000000000);
var now = new Date();
var $newMessage =
$('<div class="message ' +
(this.pmaConsole.config.AlwaysExpand ? 'expanded' : 'collapsed') +
'" msgid="' + msgId + '"><div class="action_content"></div></div>');
switch (msgType) {
case 'query':
$newMessage.append('<div class="query highlighted"></div>');
if (this.pmaConsole.pmaConsoleInput._codemirror) {
CodeMirror.runMode(msgString,
'text/x-sql', $newMessage.children('.query')[0]);
} else {
$newMessage.children('.query').text(msgString);
}
$newMessage.children('.action_content')
.append(this.pmaConsole.$consoleTemplates.children('.query_actions').html());
break;
default:
case 'normal':
$newMessage.append('<div>' + msgString + '</div>');
}
this._msgEventBinds($newMessage);
$newMessage.find('span.text.query_time span')
.text(now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds())
.parent().attr('title', now);
return { message_id: msgId,
$message: $newMessage.appendTo('#pma_console .content .console_message_container') };
}
/**
* Used for log new query
*
* @param string queryData Struct should be
* {sql_query: "Query string", db: "Target DB", table: "Target Table"}
* @param string state Message state
* @return object, {message_id: string message id, $message: JQuery object}
*/
appendQuery (queryData, state) {
var targetMessage = this.append(queryData.sql_query, 'query');
if (! targetMessage) {
return false;
}
if (queryData.db && queryData.table) {
targetMessage.$message.attr('targetdb', queryData.db);
targetMessage.$message.attr('targettable', queryData.table);
targetMessage.$message.find('.text.targetdb span').text(queryData.db);
}
if (this.pmaConsole.isSelect(queryData.sql_query)) {
targetMessage.$message.addClass('select');
}
switch (state) {
case 'failed':
targetMessage.$message.addClass('failed');
break;
case 'successed':
targetMessage.$message.addClass('successed');
break;
default:
case 'pending':
targetMessage.$message.addClass('pending');
}
return targetMessage;
}
_msgEventBinds ($targetMessage) {
var self = this;
// Leave unbinded elements, remove binded.
$targetMessage = $targetMessage.filter(':not(.binded)');
if ($targetMessage.length === 0) {
return;
}
$targetMessage.addClass('binded');
$targetMessage.find('.action.expand').click(function () {
$(this).closest('.message').removeClass('collapsed');
$(this).closest('.message').addClass('expanded');
});
$targetMessage.find('.action.collapse').click(function () {
$(this).closest('.message').addClass('collapsed');
$(this).closest('.message').removeClass('expanded');
});
$targetMessage.find('.action.edit').click(function () {
self.pmaConsole.pmaConsoleInput.setText($(this).parent().siblings('.query').text());
self.pmaConsole.pmaConsoleInput.focus();
});
$targetMessage.find('.action.requery').click(function () {
var query = $(this).parent().siblings('.query').text();
var $message = $(this).closest('.message');
if (confirm(messages.strConsoleRequeryConfirm + '\n' +
(query.length < 100 ? query : query.slice(0, 100) + '...'))
) {
self.pmaConsole.execute(query, { db: $message.attr('targetdb'), table: $message.attr('targettable') });
}
});
$targetMessage.find('.action.bookmark').click(function () {
var query = $(this).parent().siblings('.query').text();
var $message = $(this).closest('.message');
self.pmaConsole.pmaConsoleBookmarks.addBookmark(query, $message.attr('targetdb'));
self.pmaConsole.showCard('#pma_bookmarks .card.add');
});
$targetMessage.find('.action.edit_bookmark').click(function () {
var query = $(this).parent().siblings('.query').text();
var $message = $(this).closest('.message');
var isShared = $message.find('span.bookmark_label').hasClass('shared');
var label = $message.find('span.bookmark_label').text();
self.pmaConsole.pmaConsoleBookmarks.addBookmark(query, $message.attr('targetdb'), label, isShared);
self.pmaConsole.showCard('#pma_bookmarks .card.add');
});
$targetMessage.find('.action.delete_bookmark').click(function () {
var $message = $(this).closest('.message');
if (confirm(messages.strConsoleDeleteBookmarkConfirm + '\n' + $message.find('.bookmark_label').text())) {
$.post('import.php',
{
server: PMA_commonParams.get('server'),
action_bookmark: 2,
ajax_request: true,
id_bookmark: $message.attr('bookmarkid') },
function () {
self.pmaConsole.pmaConsoleBookmarks.refresh();
});
}
});
$targetMessage.find('.action.profiling').click(function () {
var $message = $(this).closest('.message');
self.pmaConsole.execute($(this).parent().siblings('.query').text(),
{ db: $message.attr('targetdb'),
table: $message.attr('targettable'),
profiling: true });
});
$targetMessage.find('.action.explain').click(function () {
var $message = $(this).closest('.message');
self.pmaConsole.execute('EXPLAIN ' + $(this).parent().siblings('.query').text(),
{ db: $message.attr('targetdb'),
table: $message.attr('targettable') });
});
$targetMessage.find('.action.dbg_show_trace').click(function () {
var $message = $(this).closest('.message');
if (!$message.find('.trace').length) {
self.pmaConsole.pmaConsoleDebug.getQueryDetails(
$message.data('queryInfo'),
$message.data('totalTime'),
$message
);
self._msgEventBinds($message.find('.message:not(.binded)'));
}
$message.addClass('show_trace');
$message.removeClass('hide_trace');
});
$targetMessage.find('.action.dbg_hide_trace').click(function () {
var $message = $(this).closest('.message');
$message.addClass('hide_trace');
$message.removeClass('show_trace');
});
$targetMessage.find('.action.dbg_show_args').click(function () {
var $message = $(this).closest('.message');
$message.addClass('show_args expanded');
$message.removeClass('hide_args collapsed');
});
$targetMessage.find('.action.dbg_hide_args').click(function () {
var $message = $(this).closest('.message');
$message.addClass('hide_args collapsed');
$message.removeClass('show_args expanded');
});
if (self.pmaConsole.pmaConsoleInput._codemirror) {
$targetMessage.find('.query:not(.highlighted)').each(function (index, elem) {
CodeMirror.runMode($(elem).text(),
'text/x-sql', elem);
$(this).addClass('highlighted');
});
}
}
/**
* @param {string} msgId Id of the message
* @param {string} msgString Message string
* @param {string} msgType Type of message
*/
msgAppend (msgId, msgString, msgType) {
var $targetMessage = $('#pma_console').find('.content .console_message_container .message[msgid=' + msgId + ']');
if ($targetMessage.length === 0 || isNaN(parseInt(msgId)) || typeof(msgString) !== 'string') {
return false;
}
$targetMessage.append('<div>' + msgString + '</div>');
}
/**
* @param {string} msgId Id of the message
* @param {bool} isSuccessed is update succeded
* @param {Object} queryData Data associated with the query
*/
updateQuery (msgId, isSuccessed, queryData) {
var $targetMessage = $('#pma_console').find('.console_message_container .message[msgid=' + parseInt(msgId) + ']');
if ($targetMessage.length === 0 || isNaN(parseInt(msgId))) {
return false;
}
$targetMessage.removeClass('pending failed successed');
if (isSuccessed) {
$targetMessage.addClass('successed');
if (queryData) {
$targetMessage.children('.query').text('');
$targetMessage.removeClass('select');
if (this.pmaConsole.isSelect(queryData.sql_query)) {
$targetMessage.addClass('select');
}
if (this.pmaConsole.pmaConsoleInput._codemirror) {
CodeMirror.runMode(queryData.sql_query, 'text/x-sql', $targetMessage.children('.query')[0]);
} else {
$targetMessage.children('.query').text(queryData.sql_query);
}
$targetMessage.attr('targetdb', queryData.db);
$targetMessage.attr('targettable', queryData.table);
$targetMessage.find('.text.targetdb span').text(queryData.db);
}
} else {
$targetMessage.addClass('failed');
}
}
/**
* Used for console messages initialize
*
* @return void
*/
initialize () {
this._msgEventBinds($('#pma_console').find('.message:not(.binded)'));
if (this.pmaConsole.config.StartHistory) {
this.showHistory();
}
this.showInstructions(this.pmaConsole.config.EnterExecutes);
}
}

View File

@ -1,12 +1,19 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/
/**
* Module import
*/
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
import PMA_commonParams from '../variables/common_params';
import { escapeHtml } from '../utils/Sanitise';
import { AJAX } from '../ajax';
/**
* Class to handle PMA Drag and Drop Import
* feature
*/
PMA_DROP_IMPORT = {
var DragDropImport = {
/**
* @var int, count of total uploads in this view
*/
@ -36,17 +43,17 @@ PMA_DROP_IMPORT = {
*/
_getExtension: function (file) {
var arr = file.split('.');
ext = arr[arr.length - 1];
var ext = arr[arr.length - 1];
// check if compressed
if (jQuery.inArray(ext.toLowerCase(),
PMA_DROP_IMPORT.allowedCompressedExtensions) !== -1) {
DragDropImport.allowedCompressedExtensions) !== -1) {
ext = arr[arr.length - 2];
}
// Now check for extension
if (jQuery.inArray(ext.toLowerCase(),
PMA_DROP_IMPORT.allowedExtensions) !== -1) {
DragDropImport.allowedExtensions) !== -1) {
return ext;
}
return '';
@ -86,7 +93,7 @@ PMA_DROP_IMPORT = {
percent = Math.ceil(position / total * 100);
}
// Set progress
PMA_DROP_IMPORT._setProgress(hash, percent);
DragDropImport._setProgress(hash, percent);
}, false);
}
return xhrobj;
@ -98,9 +105,9 @@ PMA_DROP_IMPORT = {
cache: false,
data: formData,
success: function (data) {
PMA_DROP_IMPORT._importFinished(hash, false, data.success);
DragDropImport._importFinished(hash, false, data.success);
if (!data.success) {
PMA_DROP_IMPORT.importStatus[PMA_DROP_IMPORT.importStatus.length] = {
DragDropImport.importStatus[DragDropImport.importStatus.length] = {
hash: hash,
message: data.error
};
@ -121,12 +128,12 @@ PMA_DROP_IMPORT = {
if ($(this).attr('task') === 'cancel') {
jqXHR.abort();
$(this).html('<span>' + PMA_messages.dropImportMessageAborted + '</span>');
PMA_DROP_IMPORT._importFinished(hash, true, false);
DragDropImport._importFinished(hash, true, false);
} else if ($(this).children('span').html() ===
PMA_messages.dropImportMessageFailed) {
// -- view information
var $this = $(this);
$.each(PMA_DROP_IMPORT.importStatus,
$.each(DragDropImport.importStatus,
function (key, value) {
if (value.hash === hash) {
$('.pma_drop_result:visible').remove();
@ -156,7 +163,7 @@ PMA_DROP_IMPORT = {
event.stopPropagation();
event.preventDefault();
if (!PMA_DROP_IMPORT._hasFiles(event)) {
if (!DragDropImport._hasFiles(event)) {
return;
}
if (PMA_commonParams.get('db') === '') {
@ -197,7 +204,7 @@ PMA_DROP_IMPORT = {
event.stopPropagation();
event.preventDefault();
if (!PMA_DROP_IMPORT._hasFiles(event)) {
if (!DragDropImport._hasFiles(event)) {
return;
}
$('.pma_drop_handler').fadeIn();
@ -261,8 +268,8 @@ PMA_DROP_IMPORT = {
icon + '"> ');
// Decrease liveUploadCount by one
$('.pma_import_count').html(--PMA_DROP_IMPORT.liveUploadCount);
if (!PMA_DROP_IMPORT.liveUploadCount) {
$('.pma_import_count').html(--DragDropImport.liveUploadCount);
if (!DragDropImport.liveUploadCount) {
$('.pma_sql_import_status h2 .close').fadeIn();
}
},
@ -296,8 +303,8 @@ PMA_DROP_IMPORT = {
}
$('.pma_sql_import_status').slideDown();
for (var i = 0; i < files.length; i++) {
var ext = (PMA_DROP_IMPORT._getExtension(files[i].name));
var hash = AJAX.hash(++PMA_DROP_IMPORT.uploadCount);
var ext = (DragDropImport._getExtension(files[i].name));
var hash = AJAX.hash(++DragDropImport.uploadCount);
var $pma_sql_import_status_div = $('.pma_sql_import_status div');
$pma_sql_import_status_div.append('<li data-hash="' + hash + '">' +
@ -313,7 +320,7 @@ PMA_DROP_IMPORT = {
if (ext !== '') {
// Increment liveUploadCount by one
$('.pma_import_count').html(++PMA_DROP_IMPORT.liveUploadCount);
$('.pma_import_count').html(++DragDropImport.liveUploadCount);
$('.pma_sql_import_status h2 .close').fadeOut();
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
@ -341,8 +348,8 @@ PMA_DROP_IMPORT = {
fd.append('hash', hash);
// init uploading
PMA_DROP_IMPORT._sendFileToServer(fd, hash);
} else if (!PMA_DROP_IMPORT.liveUploadCount) {
DragDropImport._sendFileToServer(fd, hash);
} else if (!DragDropImport.liveUploadCount) {
$('.pma_sql_import_status h2 .close').fadeIn();
}
}
@ -353,41 +360,4 @@ PMA_DROP_IMPORT = {
}
};
/**
* Called when some user drags, dragover, leave
* a file to the PMA UI
* @param object Event data
* @return void
*/
$(document).on('dragenter', PMA_DROP_IMPORT._dragenter);
$(document).on('dragover', PMA_DROP_IMPORT._dragover);
$(document).on('dragleave', '.pma_drop_handler', PMA_DROP_IMPORT._dragleave);
// when file is dropped to PMA UI
$(document).on('drop', 'body', PMA_DROP_IMPORT._drop);
// minimizing-maximising the sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .minimize', function () {
if ($(this).attr('toggle') === 'off') {
$('.pma_sql_import_status div').css('height','270px');
$(this).attr('toggle','on');
$(this).html('-'); // to minimize
} else {
$('.pma_sql_import_status div').css('height','0px');
$(this).attr('toggle','off');
$(this).html('+'); // to maximise
}
});
// closing sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .close', function () {
$('.pma_sql_import_status').fadeOut(function () {
$('.pma_sql_import_status div').html('');
PMA_DROP_IMPORT.importStatus = []; // clear the message array
});
});
// Closing the import result box
$(document).on('click', '.pma_drop_result h2 .close', function () {
$(this).parent('h2').parent('div').remove();
});
export default DragDropImport;

View File

@ -0,0 +1,336 @@
/**
* general function, usually for data manipulation pages
*
*/
import { AJAX } from '../ajax';
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
import CommonParams from '../variables/common_params';
import { PMA_ajaxShowMessage } from '../utils/show_ajax_messages';
import { PMA_getImage } from '../functions/get_image';
import TraceKit from 'tracekit';
import { $ } from '../utils/JqueryExtended';
/**
* This Object uses the library TraceKit to generate the backtrace of the
* error but since we are using webpack and the development and production
* mode have different url leading to cross origin query, the error
* report cannot be generated in development mode with context.
* The context will be null in deveopment mode.
*
* @see TraceKit url checking implemented to avoid Cross Origin
* https://github.com/csnover/TraceKit/blob/d38d48765f089309e4f4c7a1baacd96dd0534187/tracekit.js#L445
*
* @see TraceKit How context of the error is being gennerated
* https://github.com/csnover/TraceKit/blob/d38d48765f089309e4f4c7a1baacd96dd0534187/tracekit.js#L499
*
* Due to usage of webpack, the production output is creating backtrace context
* containing single line only and that single line is the complete generated
* webpack bundle in the uglify mode.
*/
var ErrorReport = {
/**
* @var object stores the last exception info
*/
_last_exception: null,
/**
* handles thrown error exceptions based on user preferences
*
* @return void
*/
error_handler: function (exception) {
console.error(exception);
if (exception.name === null || typeof(exception.name) === 'undefined') {
exception.name = ErrorReport._extractExceptionName(exception);
}
ErrorReport._last_exception = exception;
$.get('error_report.php', {
ajax_request: true,
server: CommonParams.get('server'),
get_settings: true,
exception_type: 'js'
}, function (data) {
if (data.success !== true) {
PMA_ajaxShowMessage(data.error, false);
return;
}
if (data.report_setting === 'ask') {
ErrorReport._showErrorNotification();
} else if (data.report_setting === 'always') {
var report_data = ErrorReport._get_report_data(exception);
var post_data = $.extend(report_data, {
send_error_report: true,
automatic: true
});
$.post('error_report.php', post_data, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxShowMessage(data.message, false);
}
});
}
});
},
/**
* Shows the modal dialog previewing the report
*
* @param exception object error report info
*
* @return void
*/
_showReportDialog: function (exception) {
var report_data = ErrorReport._get_report_data(exception);
/* Remove the hidden dialogs if there are*/
if ($('#error_report_dialog').length !== 0) {
$('#error_report_dialog').remove();
}
var $div = $('<div id="error_report_dialog"></div>');
$div.css('z-index', '1000');
var button_options = {};
button_options[PMA_messages.strSendErrorReport] = function () {
var $dialog = $(this);
var post_data = $.extend(report_data, {
send_error_report: true,
description: $('#report_description').val(),
always_send: $('#always_send_checkbox')[0].checked
});
$.post('error_report.php', post_data, function (data) {
$dialog.dialog('close');
if (data.success === false) {
// in the case of an error, show the error message returned.
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxShowMessage(data.message, 3000);
}
});
};
button_options[PMA_messages.strCancel] = function () {
$(this).dialog('close');
};
$.post('error_report.php', report_data, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
PMA_ajaxShowMessage(data.error, false);
} else {
// Show dialog if the request was successful
$div
.append(data.message)
.dialog({
title: PMA_messages.strSubmitErrorReport,
width: 650,
modal: true,
buttons: button_options,
close: function () {
$(this).remove();
}
});
}
}); // end $.get()
},
/**
* Shows the small notification that asks for user permission
*
* @return void
*/
_showErrorNotification: function () {
ErrorReport._removeErrorNotification();
var $div = $(
'<div style="position:fixed;bottom:0;left:0;right:0;margin:0;' +
'z-index:1000" class="error" id="error_notification"></div>'
).append(
PMA_getImage('s_error') + PMA_messages.strErrorOccurred
);
var $buttons = $('<div class="floatright"></div>');
var button_html = '<button id="show_error_report">';
button_html += PMA_messages.strShowReportDetails;
button_html += '</button>';
button_html += '<a id="change_error_settings">';
button_html += PMA_getImage('s_cog', PMA_messages.strChangeReportSettings);
button_html += '</a>';
button_html += '<a href="#" id="ignore_error">';
button_html += PMA_getImage('b_close', PMA_messages.strIgnore);
button_html += '</a>';
$buttons.html(button_html);
$div.append($buttons);
$div.appendTo(document.body);
$(document).on('click', '#change_error_settings', ErrorReport._redirect_to_settings);
$(document).on('click', '#show_error_report', ErrorReport._createReportDialog);
$(document).on('click', '#ignore_error', ErrorReport._removeErrorNotification);
},
/**
* Removes the notification if it was displayed before
*
* @return void
*/
_removeErrorNotification: function (e) {
if (e) {
// don't remove the hash fragment by navigating to #
e.preventDefault();
}
$('#error_notification').fadeOut(function () {
$(this).remove();
});
},
/**
* Extracts Exception name from message if it exists
*
* @return String
*/
_extractExceptionName: function (exception) {
if (exception.message === null || typeof(exception.message) === 'undefined') {
return '';
}
var reg = /([a-zA-Z]+):/;
var regex_result = reg.exec(exception.message);
if (regex_result && regex_result.length === 2) {
return regex_result[1];
}
return '';
},
/**
* Shows the modal dialog previewing the report
*
* @return void
*/
_createReportDialog: function () {
ErrorReport._removeErrorNotification();
ErrorReport._showReportDialog(ErrorReport._last_exception);
},
/**
* Redirects to the settings page containing error report
* preferences
*
* @return void
*/
_redirect_to_settings: function () {
window.location.href = 'prefs_forms.php?form=Features';
},
/**
* Returns the report data to send to the server
*
* @param exception object exception info
*
* @return object
*/
_get_report_data: function (exception) {
var report_data = {
'ajax_request': true,
'exception': exception,
'current_url': window.location.href,
'exception_type': 'js'
};
if (AJAX.scriptHandler._scripts.length > 0) {
report_data.scripts = AJAX.scriptHandler._scripts.map(
function (script) {
return script;
}
);
}
return report_data;
},
/**
* Wraps all global functions that start with PMA_
*
* @return void
*
* This function needs to be changes as no objects are available
* in the global scope so window does not contain any function
*/
wrap_global_functions: function () {
for (var key in window) {
if (key.indexOf('PMA_') === 0) {
var global = window[key];
if (typeof(global) === 'function') {
window[key] = ErrorReport.wrap_function(global);
}
}
}
},
/**
* Wraps given function in error reporting code and returns wrapped function
*
* @param func function to be wrapped
*
* @return function
*/
wrap_function: function (func) {
if (!func.wrapped) {
var new_func = function () {
try {
return func.apply(this, arguments);
} catch (x) {
TraceKit.report(x);
}
};
new_func.wrapped = true;
// Set guid of wrapped function same as original function, so it can be removed
// See bug#4146 (problem with jquery draggable and sortable)
new_func.guid = func.guid = func.guid || new_func.guid || jQuery.guid++;
return new_func;
} else {
return func;
}
},
/**
* Automatically wraps the callback in AJAX.registerOnload
*
* @return void
*/
_wrap_ajax_onload_callback: function () {
var oldOnload = AJAX.registerOnload;
AJAX.registerOnload = function (file, func) {
func = ErrorReport.wrap_function(func);
oldOnload.call(this, file, func);
};
},
/**
* Automatically wraps the callback in $.fn.on
*
* @return void
*
* Since we are exporting the instance of jQuery from
* '/util/extend_jquery', therefore this method will work
* fine and wrap the callback of $.fn.on of jQuery instance.
*/
_wrap_$_on_callback: function () {
var oldOn = $.fn.on;
$.fn.on = function () {
for (var i = 1; i <= 3; i++) {
if (typeof(arguments[i]) === 'function') {
arguments[i] = ErrorReport.wrap_function(arguments[i]);
break;
}
}
return oldOn.apply(this, arguments);
};
},
/**
* Wraps all global functions that start with PMA_
* also automatically wraps the callback in AJAX.registerOnload
*
* @return void
*/
set_up_error_reporting: function () {
ErrorReport.wrap_global_functions();
ErrorReport._wrap_ajax_onload_callback();
ErrorReport._wrap_$_on_callback();
}
};
export default ErrorReport;

View File

@ -0,0 +1,82 @@
/**
* FileHandler to handle loading of files on a particular page
* and for particular user preferences
*/
import { AJAX } from '../ajax';
import { PhpToJsFileMapping } from '../consts/files';
export default class FileHandler {
constructor () {
this.fileMapping = PhpToJsFileMapping;
this.indexPage = null;
}
/**
* Method to initialise loading of files on first page
*
* @return void
*/
init () {
this.getIndexPage();
this.addUserPreferenceFiles();
this.loadCommonFiles();
this.loafIndexFiles();
}
/**
* Method to find the first loading page. Possible values
* index.php?target=fileName.php
* fileName.php
*
* @return void
*/
getIndexPage () {
let firstPage = window.location.pathname.replace('/', '').replace('.php', '');
let indexStart = window.location.search.indexOf('target') + 7;
let indexEnd = window.location.search.indexOf('.php');
let indexPage = window.location.search.slice(indexStart, indexEnd);
if (firstPage.toLocaleLowerCase() !== 'index') {
this.indexPage = firstPage;
} else {
this.indexPage = indexPage;
}
}
/**
* Method to add user preference files.
*
* @return void
*/
addUserPreferenceFiles () {
/**
* Add files required on the basis of user preference like ErrorReport,
* PMA_Console, CodeMirror and so on.
*/
return;
}
/**
* Method to load Common files required for all the pages.
*
* @return void
*/
loadCommonFiles () {
/**
* Adding common files for every page
*/
for (let i in this.fileMapping.global) {
AJAX.scriptHandler.add(this.fileMapping.global[i], 1);
}
}
/**
* Method to load page related files.
*
* @return void
*/
loafIndexFiles () {
if (typeof this.fileMapping[this.indexPage] !== 'undefined') {
for (let i in this.fileMapping[this.indexPage]) {
AJAX.scriptHandler.add(this.fileMapping[this.indexPage][i], 1);
}
}
}
}

View File

@ -1,10 +1,14 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import { PMA_ajaxShowMessage } from '../utils/show_ajax_messages';
import { AJAX } from '../ajax';
import { PMA_Messages as messages } from '../variables/export_variables';
import CommonParams from '../variables/common_params';
import SetUrlHash from './SetUrlHash';
/**
* An implementation of a client-side page cache.
* This object also uses the cache to provide a simple microhistory,
* that is the ability to use the back and forward buttons in the browser
*/
PMA_MicroHistory = {
var MicroHistory = {
/**
* @var int The maximum number of pages to keep in the cache
*/
@ -31,7 +35,7 @@ PMA_MicroHistory = {
* @param array scripts A list of scripts that is required for the page
* @param string menu A hash that links to a menu stored
* in a dedicated menu cache
* @param array params A list of parameters used by PMA_commonParams()
* @param array params A list of parameters used by CommonParams()
* @param string rel A relationship to the current page:
* 'samepage': Forces the response to be treated as
* the same page as the current one
@ -44,7 +48,7 @@ PMA_MicroHistory = {
* @return void
*/
add: function (hash, scripts, menu, params, rel) {
if (this.pages.length > PMA_MicroHistory.MAX) {
if (this.pages.length > MicroHistory.MAX) {
// Trim the cache, to the maximum number of allowed entries
// This way we will have a cached menu for every page
for (var i = 0; i < this.pages.length - this.MAX; i++) {
@ -72,7 +76,7 @@ PMA_MicroHistory = {
menu: menu,
params: params
});
PMA_SetUrlHash(this.current, hash);
SetUrlHash(this.current, hash);
this.current++;
}
},
@ -88,10 +92,10 @@ PMA_MicroHistory = {
if (typeof this.pages[index] === 'undefined' ||
typeof this.pages[index].content === 'undefined' ||
typeof this.pages[index].menu === 'undefined' ||
! PMA_MicroHistory.menus.get(this.pages[index].menu)
! MicroHistory.menus.get(this.pages[index].menu)
) {
PMA_ajaxShowMessage(
'<div class="error">' + PMA_messages.strInvalidPage + '</div>',
'<div class="error">' + messages.strInvalidPage + '</div>',
false
);
} else {
@ -100,10 +104,10 @@ PMA_MicroHistory = {
AJAX.scriptHandler.reset(function () {
$('#page_content').html(record.content);
$('#selflink').html(record.selflink);
PMA_MicroHistory.menus.replace(PMA_MicroHistory.menus.get(record.menu));
PMA_commonParams.setAll(record.params);
MicroHistory.menus.replace(MicroHistory.menus.get(record.menu));
CommonParams.setAll(record.params);
AJAX.scriptHandler.load(record.scripts);
PMA_MicroHistory.current = ++index;
MicroHistory.current = ++index;
});
}
},
@ -151,7 +155,7 @@ PMA_MicroHistory = {
* @return void
*/
add: function (hash, content) {
if (this.size(this.data) > PMA_MicroHistory.MAX) {
if (this.size(this.data) > MicroHistory.MAX) {
// when the cache grows, we remove the oldest entry
var oldest;
var key;
@ -202,7 +206,7 @@ PMA_MicroHistory = {
}
var menuHashesParam = menuHashes.join('-');
if (menuHashesParam) {
param = PMA_commonParams.get('arg_separator') + 'menuHashes=' + menuHashesParam;
param = CommonParams.get('arg_separator') + 'menuHashes=' + menuHashesParam;
}
return param;
},
@ -221,115 +225,4 @@ PMA_MicroHistory = {
}
};
/**
* URL hash management module.
* Allows direct bookmarking and microhistory.
*/
PMA_SetUrlHash = (function (jQuery, window) {
'use strict';
/**
* Indictaes whether we have already completed
* the initialisation of the hash
*
* @access private
*/
var ready = false;
/**
* Stores a hash that needed to be set when we were not ready
*
* @access private
*/
var savedHash = '';
/**
* Flag to indicate if the change of hash was triggered
* by a user pressing the back/forward button or if
* the change was triggered internally
*
* @access private
*/
var userChange = true;
// Fix favicon disappearing in Firefox when setting location.hash
function resetFavicon () {
if (navigator.userAgent.indexOf('Firefox') > -1) {
// Move the link tags for the favicon to the bottom
// of the head element to force a reload of the favicon
$('head > link[href="favicon\\.ico"]').appendTo('head');
}
}
/**
* Sets the hash part of the URL
*
* @access public
*/
function setUrlHash (index, hash) {
/*
* Known problem:
* Setting hash leads to reload in webkit:
* http://www.quirksmode.org/bugreports/archives/2005/05/Safari_13_visual_anomaly_with_windowlocationhref.html
*
* so we expect that users are not running an ancient Safari version
*/
userChange = false;
if (ready) {
window.location.hash = 'PMAURL-' + index + ':' + hash;
resetFavicon();
} else {
savedHash = 'PMAURL-' + index + ':' + hash;
}
}
/**
* Start initialisation
*/
var urlhash = window.location.hash;
if (urlhash.substring(0, 8) === '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
var colon_position = urlhash.indexOf(':');
var questionmark_position = urlhash.indexOf('?');
if (colon_position !== -1 && questionmark_position !== -1 && colon_position < questionmark_position) {
var hash_url = urlhash.substring(colon_position + 1, questionmark_position);
if (PMA_gotoWhitelist.indexOf(hash_url) !== -1) {
window.location = urlhash.substring(
colon_position + 1
);
}
}
} else {
// We don't have a valid hash, so we'll set it up
// when the page finishes loading
jQuery(function () {
/* Check if we should set URL */
if (savedHash !== '') {
window.location.hash = savedHash;
savedHash = '';
resetFavicon();
}
// Indicate that we're done initialising
ready = true;
});
}
/**
* Register an event handler for when the url hash changes
*/
jQuery(function () {
jQuery(window).hashchange(function () {
if (userChange === false) {
// Ignore internally triggered hash changes
userChange = true;
} else if (/^#PMAURL-\d+:/.test(window.location.hash)) {
// Change page if the hash changed was triggered by a user action
var index = window.location.hash.substring(
8, window.location.hash.indexOf(':')
);
PMA_MicroHistory.navigate(index);
}
});
});
/**
* Publicly exposes a reference to the otherwise private setUrlHash function
*/
return setUrlHash;
}(jQuery, window));
export default MicroHistory;

View File

@ -1,4 +1,15 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
import { PMA_ajaxShowMessage,
PMA_ajaxRemoveMessage,
PMA_slidingMessage
} from '../utils/show_ajax_messages';
import { PMA_addDatepicker } from '../utils/DateTime';
import { PMA_getSQLEditor } from '../functions/Sql/SqlEditor';
import { PMA_reloadNavigation } from '../functions/navigation';
import { getJSConfirmCommonParam } from '../functions/Common';
/**
* JavaScript functionality for Routines, Triggers and Events.
*
@ -457,7 +468,7 @@ RTE.COMMON = {
dropMultipleDialog: function ($this) {
// We ask for confirmation here
$this.PMA_confirm(PMA_messages.strDropRTEitems, '', function (url) {
$this.PMA_confirm(PMA_messages.strDropRTEitems, '', function () {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
@ -610,7 +621,7 @@ RTE.ROUTINE = {
$('.routine_params_table tbody').sortable({
containment: '.routine_params_table tbody',
handle: '.dragHandle',
stop: function (event, ui) {
stop: function () {
that.reindexParameters();
},
});
@ -914,164 +925,4 @@ RTE.ROUTINE = {
}
};
/**
* Attach Ajax event handlers for the Routines, Triggers and Events editor
*/
$(function () {
/**
* Attach Ajax event handlers for the Add/Edit functionality.
*/
$(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) {
event.preventDefault();
var type = $(this).attr('href').substr(0, $(this).attr('href').indexOf('?'));
if (type.indexOf('routine') !== -1) {
type = 'routine';
} else if (type.indexOf('trigger') !== -1) {
type = 'trigger';
} else if (type.indexOf('event') !== -1) {
type = 'event';
} else {
type = '';
}
var dialog = new RTE.object(type);
dialog.editorDialog($(this).hasClass('add_anchor'), $(this));
}); // end $(document).on()
/**
* Attach Ajax event handlers for the Execute routine functionality
*/
$(document).on('click', 'a.ajax.exec_anchor', function (event) {
event.preventDefault();
var dialog = new RTE.object('routine');
dialog.executeDialog($(this));
}); // end $(document).on()
/**
* Attach Ajax event handlers for Export of Routines, Triggers and Events
*/
$(document).on('click', 'a.ajax.export_anchor', function (event) {
event.preventDefault();
var dialog = new RTE.object();
dialog.exportDialog($(this));
}); // end $(document).on()
$(document).on('click', '#rteListForm.ajax .mult_submit[value="export"]', function (event) {
event.preventDefault();
var dialog = new RTE.object();
dialog.exportDialog($(this));
}); // end $(document).on()
/**
* Attach Ajax event handlers for Drop functionality
* of Routines, Triggers and Events.
*/
$(document).on('click', 'a.ajax.drop_anchor', function (event) {
event.preventDefault();
var dialog = new RTE.object();
dialog.dropDialog($(this));
}); // end $(document).on()
$(document).on('click', '#rteListForm.ajax .mult_submit[value="drop"]', function (event) {
event.preventDefault();
var dialog = new RTE.object();
dialog.dropMultipleDialog($(this));
}); // end $(document).on()
/**
* Attach Ajax event handlers for the "Change event/routine type"
* functionality in the events editor, so that the correct
* rows are shown in the editor when changing the event type
*/
$(document).on('change', 'select[name=item_type]', function () {
$(this)
.closest('table')
.find('tr.recurring_event_row, tr.onetime_event_row, tr.routine_return_row, .routine_direction_cell')
.toggle();
}); // end $(document).on()
/**
* Attach Ajax event handlers for the "Change parameter type"
* functionality in the routines editor, so that the correct
* option/length fields, if any, are shown when changing
* a parameter type
*/
$(document).on('change', 'select[name^=item_param_type]', function () {
/**
* @var row jQuery object containing the reference to
* a row in the routine parameters table
*/
var $row = $(this).parents('tr').first();
var rte = new RTE.object('routine');
rte.setOptionsForParameter(
$row.find('select[name^=item_param_type]'),
$row.find('input[name^=item_param_length]'),
$row.find('select[name^=item_param_opts_text]'),
$row.find('select[name^=item_param_opts_num]')
);
}); // end $(document).on()
/**
* Attach Ajax event handlers for the "Change the type of return
* variable of function" functionality, so that the correct fields,
* if any, are shown when changing the function return type type
*/
$(document).on('change', 'select[name=item_returntype]', function () {
var rte = new RTE.object('routine');
var $table = $(this).closest('table.rte_table');
rte.setOptionsForParameter(
$table.find('select[name=item_returntype]'),
$table.find('input[name=item_returnlength]'),
$table.find('select[name=item_returnopts_text]'),
$table.find('select[name=item_returnopts_num]')
);
}); // end $(document).on()
/**
* Attach Ajax event handlers for the "Add parameter to routine" functionality
*/
$(document).on('click', 'input[name=routine_addparameter]', function (event) {
event.preventDefault();
/**
* @var routine_params_table jQuery object containing the reference
* to the routine parameters table
*/
var $routine_params_table = $(this).closest('div.ui-dialog').find('.routine_params_table');
/**
* @var new_param_row A string containing the HTML code for the
* new row for the routine parameters table
*/
var new_param_row = RTE.param_template.replace(/%s/g, $routine_params_table.find('tr').length - 1);
// Append the new row to the parameters table
$routine_params_table.append(new_param_row);
// Make sure that the row is correctly shown according to the type of routine
if ($(this).closest('div.ui-dialog').find('table.rte_table select[name=item_type]').val() === 'FUNCTION') {
$('tr.routine_return_row').show();
$('td.routine_direction_cell').hide();
}
/**
* @var newrow jQuery object containing the reference to the newly
* inserted row in the routine parameters table
*/
var $newrow = $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').last();
// Enable/disable the 'options' dropdowns for parameters as necessary
var rte = new RTE.object('routine');
rte.setOptionsForParameter(
$newrow.find('select[name^=item_param_type]'),
$newrow.find('input[name^=item_param_length]'),
$newrow.find('select[name^=item_param_opts_text]'),
$newrow.find('select[name^=item_param_opts_num]')
);
}); // end $(document).on()
/**
* Attach Ajax event handlers for the
* "Remove parameter from routine" functionality
*/
$(document).on('click', 'a.routine_param_remove_anchor', function (event) {
event.preventDefault();
$(this).parent().parent().remove();
// After removing a parameter, the indices of the name attributes in
// the input fields lose the correct order and need to be reordered.
RTE.ROUTINE.reindexParameters();
}); // end $(document).on()
}); // end of $()
export default RTE;

View File

@ -0,0 +1,177 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from '../../utils/JqueryExtended';
import CommonParams from '../../variables/common_params';
import { escapeHtml } from '../../utils/Sanitise';
import { PMA_ajaxShowMessage } from '../../utils/show_ajax_messages';
import { PMA_getImage } from '../../functions/get_image';
import { PMA_highlightSQL } from '../../utils/sql';
import { PMA_Messages as messages } from '../../variables/export_variables';
/**
* @class Object to store process list state information
*/
class ProcessList {
/**
* @constructor Create a ProcessList
*/
constructor () {
// denotes whether auto refresh is on or off
this.autoRefresh = false;
// stores the GET request which refresh process list
this.refreshRequest = null;
// stores the timeout id returned by setTimeout
this.refreshTimeout = null;
// the refresh interval in seconds
this.refreshInterval = null;
// the refresh URL (required to save last used option)
// i.e. full or sorting url
this.refreshUrl = null;
// Bindings for methods
this.init = this.init.bind(this);
this.killProcessHandler = this.killProcessHandler.bind(this);
this.refresh = this.refresh.bind(this);
this.abortRefresh = this.abortRefresh.bind(this);
this.setRefreshLabel = this.setRefreshLabel.bind(this);
this.getUrlParams = this.getUrlParams.bind(this);
}
/**
* Handles killing of a process
*
* @return void
*/
init () {
this.setRefreshLabel();
if (this.refreshUrl === null) {
this.refreshUrl = 'server_status_processes.php' +
CommonParams.get('common_query');
}
if (this.refreshInterval === null) {
this.refreshInterval = $('#id_refreshRate').val();
} else {
$('#id_refreshRate').val(this.refreshInterval);
}
}
/**
* Handles killing of a process
*
* @param object the event object
*
* @return void
*/
killProcessHandler (event, elementRef) {
event.preventDefault();
var url = $(elementRef).attr('href');
// Get row element of the process to be killed.
var $tr = $(elementRef).closest('tr');
$.getJSON(url, function (data) {
// Check if process was killed or not.
if (data.hasOwnProperty('success') && data.success) {
// remove the row of killed process.
$tr.remove();
// As we just removed a row, reapply odd-even classes
// to keep table stripes consistent
var $tableProcessListTr = $('#tableprocesslist').find('> tbody > tr');
$tableProcessListTr.filter(':even').removeClass('odd').addClass('even');
$tableProcessListTr.filter(':odd').removeClass('even').addClass('odd');
// Show process killed message
PMA_ajaxShowMessage(data.message, false);
} else {
// Show process error message
PMA_ajaxShowMessage(data.error, false);
}
});
}
/**
* Handles Auto Refreshing
*
* @param object the event object
*
* @return void
*/
refresh () {
// abort any previous pending requests
// this is necessary, it may go into
// multiple loops causing unnecessary
// requests even after leaving the page.
this.abortRefresh();
// if auto refresh is enabled
if (this.autoRefresh) {
var interval = parseInt(this.refreshInterval, 10) * 1000;
var urlParams = this.getUrlParams();
this.refreshRequest = $.get(this.refreshUrl,
urlParams,
function (data) {
if (data.hasOwnProperty('success') && data.success) {
var $newTable = $(data.message);
$('#tableprocesslist').html($newTable.html());
PMA_highlightSQL($('#tableprocesslist'));
}
this.refreshTimeout = setTimeout(
this.refresh,
interval
);
}.bind(this));
}
}
/**
* Stop current request and clears timeout
*
* @return void
*/
abortRefresh () {
if (this.refreshRequest !== null) {
this.refreshRequest.abort();
this.refreshRequest = null;
}
clearTimeout(this.refreshTimeout);
}
/**
* Set label of refresh button
* change between play & pause
*
* @return void
*/
setRefreshLabel () {
var img = 'play';
var label = messages.strStartRefresh;
if (this.autoRefresh) {
img = 'pause';
label = messages.strStopRefresh;
this.refresh();
}
$('a#toggleRefresh').html(PMA_getImage(img) + escapeHtml(label));
}
/**
* Return the Url Parameters
* for autorefresh request,
* includes showExecuting if the filter is checked
*
* @return urlParams - url parameters with autoRefresh request
*/
getUrlParams () {
var urlParams = { 'ajax_request': true, 'refresh': true };
if ($('#showExecuting').is(':checked')) {
urlParams.showExecuting = true;
return urlParams;
}
return urlParams;
}
}
/**
* Instance is exported to ensure that every time the import
* will have the instance only and not the class itself
*/
let processList = new ProcessList();
export default processList;

View File

@ -0,0 +1,117 @@
import MicroHistory from './MicroHistory';
import '../plugins/jquery/jquery.ba-hashchange-1.3';
/**
* URL hash management module.
* Allows direct bookmarking and microhistory.
*/
var SetUrlHash = (function (jQuery, window) {
/**
* Indictaes whether we have already completed
* the initialisation of the hash
*
* @access private
*/
var ready = false;
/**
* Stores a hash that needed to be set when we were not ready
*
* @access private
*/
var savedHash = '';
/**
* Flag to indicate if the change of hash was triggered
* by a user pressing the back/forward button or if
* the change was triggered internally
*
* @access private
*/
var userChange = true;
// Fix favicon disappearing in Firefox when setting location.hash
function resetFavicon () {
if (navigator.userAgent.indexOf('Firefox') > -1) {
// Move the link tags for the favicon to the bottom
// of the head element to force a reload of the favicon
$('head > link[href="favicon\\.ico"]').appendTo('head');
}
}
/**
* Sets the hash part of the URL
*
* @access public
*/
function setUrlHash (index, hash) {
/*
* Known problem:
* Setting hash leads to reload in webkit:
* http://www.quirksmode.org/bugreports/archives/2005/05/Safari_13_visual_anomaly_with_windowlocationhref.html
*
* so we expect that users are not running an ancient Safari version
*/
userChange = false;
if (ready) {
window.location.hash = 'PMAURL-' + index + ':' + hash;
resetFavicon();
} else {
savedHash = 'PMAURL-' + index + ':' + hash;
}
}
/**
* Start initialisation
*/
var urlhash = window.location.hash;
if (urlhash.substring(0, 8) === '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
var colon_position = urlhash.indexOf(':');
var questionmark_position = urlhash.indexOf('?');
if (colon_position !== -1 && questionmark_position !== -1 && colon_position < questionmark_position) {
var hash_url = urlhash.substring(colon_position + 1, questionmark_position);
if (window.PMA_gotoWhitelist.indexOf(hash_url) !== -1) {
window.location = urlhash.substring(
colon_position + 1
);
}
}
} else {
// We don't have a valid hash, so we'll set it up
// when the page finishes loading
jQuery(function () {
/* Check if we should set URL */
if (savedHash !== '') {
window.location.hash = savedHash;
savedHash = '';
resetFavicon();
}
// Indicate that we're done initialising
ready = true;
});
}
/**
* Register an event handler for when the url hash changes
*/
jQuery(function () {
jQuery(window).hashchange(function () {
if (userChange === false) {
// Ignore internally triggered hash changes
userChange = true;
} else if (/^#PMAURL-\d+:/.test(window.location.hash)) {
// Change page if the hash changed was triggered by a user action
var index = window.location.hash.substring(
8, window.location.hash.indexOf(':')
);
MicroHistory.navigate(index);
}
});
});
/**
* Publicly exposes a reference to the otherwise private setUrlHash function
*/
return setUrlHash;
}(jQuery, window));
export default SetUrlHash;

185
js/src/config.js Normal file
View File

@ -0,0 +1,185 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import * as Config from './functions/config';
import { defaultValues } from './variables/get_config';
/**
* @package PhpMyAdmin
*
* Config
*/
/**
* Unbind all event handlers before tearing down a page
*/
function teardownConfig () {
$('.optbox input[id], .optbox select[id], .optbox textarea[id]').off('change').off('keyup');
$('.optbox input[type=button][name=submit_reset]').off('click');
$('div.tabs_contents').off();
$('#import_local_storage, #export_local_storage').off('click');
$('form.prefs-form').off('change').off('submit');
$(document).off('click', 'div.click-hide-message');
$('#prefs_autoload').find('a').off('click');
}
function onloadConfigPrefsTab () {
var $topmenu_upt = $('#topmenu2.user_prefs_tabs');
$topmenu_upt.find('li.active a').attr('rel', 'samepage');
$topmenu_upt.find('li:not(.active) a').attr('rel', 'newpage');
}
// ------------------------------------------------------------------
// Form validation and field operations
//
function onloadConfigValidations () {
Config.setupValidation();
}
//
// END: Form validation and field operations
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Tabbed forms
//
function onloadConfigTabs () {
Config.setupConfigTabs();
Config.adjustPrefsNotification();
// tab links handling, check each 200ms
// (works with history in FF, further browser support here would be an overkill)
var prev_hash;
var tab_check_fnc = function () {
if (location.hash !== prev_hash) {
prev_hash = location.hash;
if (prev_hash.match(/^#tab_[a-zA-Z0-9_]+$/)) {
// session ID is sometimes appended here
var hash = prev_hash.substr(5).split('&')[0];
if ($('#' + hash).length) {
Config.setTab(hash);
}
}
}
};
tab_check_fnc();
setInterval(tab_check_fnc, 200);
}
//
// END: Tabbed forms
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Form reset buttons
//
function onloadConfigResetDefault () {
$('.optbox input[type=button][name=submit_reset]').on('click', function () {
var fields = $(this).closest('fieldset').find('input, select, textarea');
for (var i = 0, imax = fields.length; i < imax; i++) {
Config.setFieldValue(fields[i], Config.getFieldType(fields[i]), defaultValues[fields[i].id]);
}
});
}
//
// END: Form reset buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// "Restore default" and "set value" buttons
//
function onloadConfigRestore () {
Config.setupRestoreField();
}
//
// END: "Restore default" and "set value" buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// User preferences import/export
//
function onloadPreferenceExport () {
Config.offerPrefsAutoimport();
var $radios = $('#import_local_storage, #export_local_storage');
if (!$radios.length) {
return;
}
// enable JavaScript dependent fields
$radios
.prop('disabled', false)
.add('#export_text_file, #import_text_file')
.on('click', function () {
var enableId = $(this).attr('id');
var disableId;
if (enableId.match(/local_storage$/)) {
disableId = enableId.replace(/local_storage$/, 'text_file');
} else {
disableId = enableId.replace(/text_file$/, 'local_storage');
}
$('#opts_' + disableId).addClass('disabled').find('input').prop('disabled', true);
$('#opts_' + enableId).removeClass('disabled').find('input').prop('disabled', false);
});
// detect localStorage state
var ls_supported = Config.isStorageSupported('localStorage', true);
var ls_exists = ls_supported ? (window.localStorage.config || false) : false;
$('div.localStorage-' + (ls_supported ? 'un' : '') + 'supported').hide();
$('div.localStorage-' + (ls_exists ? 'empty' : 'exists')).hide();
if (ls_exists) {
Config.updatePrefsDate();
}
$('form.prefs-form').on('change', function () {
var $form = $(this);
var disabled = false;
if (!lsSupported) {
disabled = $form.find('input[type=radio][value$=local_storage]').prop('checked');
} else if (!lsExists && $form.attr('name') === 'prefs_import' &&
$('#import_local_storage')[0].checked
) {
disabled = true;
}
$form.find('input[type=submit]').prop('disabled', disabled);
}).submit(function (e) {
var $form = $(this);
if ($form.attr('name') === 'prefs_export' && $('#export_local_storage')[0].checked) {
e.preventDefault();
// use AJAX to read JSON settings and save them
Config.savePrefsToLocalStorage($form);
} else if ($form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) {
// set 'json' input and submit form
$form.find('input[name=json]').val(window.localStorage.config);
}
});
$(document).on('click', 'div.click-hide-message', function () {
$(this)
.hide()
.parent('.group')
.css('height', '')
.next('form')
.show();
});
}
//
// END: User preferences import/export
// ------------------------------------------------------------------
/**
* Module export
*/
export {
teardownConfig,
onloadConfigPrefsTab,
onloadConfigResetDefault,
onloadConfigRestore,
onloadConfigTabs,
onloadConfigValidations,
onloadPreferenceExport
};

454
js/src/console.js Normal file
View File

@ -0,0 +1,454 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Used in or for console
*
* @package phpMyAdmin-Console
*/
/**
* Module import
*/
import ConsoleBookmarks from './classes/Console/PMA_consoleBookmarks';
import ConsoleDebug from './classes/Console/PMA_consoleDebug';
import ConsoleInput from './classes/Console/PMA_consoleInput';
import ConsoleMessages from './classes/Console/PMA_consoleMessages';
import ConsoleResizer from './classes/Console/PMA_ConsoleResizer';
/**
* Console object
*/
var Console = {
/**
* @var object, jQuery object, selector is '#pma_console>.content'
* @access private
*/
$consoleContent: null,
/**
* @var object, jQuery object, selector is '#pma_console .content',
* used for resizer
* @access private
*/
$consoleAllContents: null,
/**
* @var object, jQuery object, selector is '#pma_console .toolbar'
* @access private
*/
$consoleToolbar: null,
/**
* @var object, jQuery object, selector is '#pma_console .template'
* @access private
*/
$consoleTemplates: null,
/**
* @var object, jQuery object, form for submit
* @access private
*/
$requestForm: null,
/**
* @var object, contain console config
* @access private
*/
config: null,
/**
* @var bool, if console element exist, it'll be true
* @access public
*/
isEnabled: false,
/**
* @var bool, make sure console events bind only once
* @access private
*/
isInitialized: false,
/**
* @var object, instance of PMA Console Resizer
*/
pmaConsoleResizer: null,
/**
* @var object, instance of PMA Console Input
*/
pmaConsoleInput: null,
/**
* @var object, instance of PMA Console Messages
*/
pmaConsoleMessages: null,
/**
* @var object, instance of PMA Console Bookmaks
*/
pmaConsoleBookmarks: null,
/**
* @var object, instance of PMA Console Debug
*/
pmaConsoleDebug: null,
/**
* Used for console initialize, reinit is ok, just some variable assignment
*
* @return void
*/
initialize: function () {
if ($('#pma_console').length === 0) {
return;
}
Console.config = configGet('Console', false);
Console.isEnabled = true;
// Vars init
Console.$consoleToolbar = $('#pma_console').find('>.toolbar');
Console.$consoleContent = $('#pma_console').find('>.content');
Console.$consoleAllContents = $('#pma_console').find('.content');
Console.$consoleTemplates = $('#pma_console').find('>.templates');
// Generate a from for post
Console.$requestForm = $('<form method="post" action="import.php">' +
'<input name="is_js_confirmed" value="0">' +
'<textarea name="sql_query"></textarea>' +
'<input name="console_message_id" value="0">' +
'<input name="server" value="">' +
'<input name="db" value="">' +
'<input name="table" value="">' +
'<input name="token" value="">' +
'</form>'
);
Console.$requestForm.children('[name=token]').val(PMA_commonParams.get('token'));
Console.$requestForm.on('submit', AJAX.requestHandler);
// Event binds shouldn't run again
if (Console.isInitialized === false) {
// Load config first
if (Console.config.AlwaysExpand === true) {
$('#pma_console_options input[name=always_expand]').prop('checked', true);
}
if (Console.config.StartHistory === true) {
$('#pma_console_options').find('input[name=start_history]').prop('checked', true);
}
if (Console.config.CurrentQuery === true) {
$('#pma_console_options').find('input[name=current_query]').prop('checked', true);
}
if (Console.config.EnterExecutes === true) {
$('#pma_console_options').find('input[name=enter_executes]').prop('checked', true);
}
if (Console.config.DarkTheme === true) {
$('#pma_console_options').find('input[name=dark_theme]').prop('checked', true);
$('#pma_console').find('>.content').addClass('console_dark_theme');
}
// Instances of helper classes
Console.pmaConsoleResizer = new ConsoleResizer(Console);
Console.pmaConsoleInput = new ConsoleInput(Console);
Console.pmaConsoleMessages = new ConsoleMessages(Console);
Console.pmaConsoleBookmarks = new ConsoleBookmarks(Console);
Console.pmaConsoleDebug = new ConsoleDebug(Console);
Console.$consoleToolbar.children('.console_switch').click(Console.toggle);
$('#pma_console').find('.toolbar').children().mousedown(function (event) {
event.preventDefault();
event.stopImmediatePropagation();
});
$('#pma_console').find('.button.clear').click(function () {
Console.pmaConsoleMessages.clear();
});
$('#pma_console').find('.button.history').click(function () {
Console.pmaConsoleMessages.showHistory();
});
$('#pma_console').find('.button.options').click(function () {
Console.showCard('#pma_console_options');
});
$('#pma_console').find('.button.debug').click(function () {
Console.showCard('#debug_console');
});
Console.$consoleContent.click(function (event) {
if (event.target === this) {
Console.pmaConsoleInput.focus();
}
});
$('#pma_console').find('.mid_layer').click(function () {
Console.hideCard($(this).parent().children('.card'));
});
$('#debug_console').find('.switch_button').click(function () {
Console.hideCard($(this).closest('.card'));
});
$('#pma_bookmarks').find('.switch_button').click(function () {
Console.hideCard($(this).closest('.card'));
});
$('#pma_console_options').find('.switch_button').click(function () {
Console.hideCard($(this).closest('.card'));
});
$('#pma_console_options').find('input[type=checkbox]').change(function () {
Console.updateConfig();
});
$('#pma_console_options').find('.button.default').click(function () {
$('#pma_console_options input[name=always_expand]').prop('checked', false);
$('#pma_console_options').find('input[name=start_history]').prop('checked', false);
$('#pma_console_options').find('input[name=current_query]').prop('checked', true);
$('#pma_console_options').find('input[name=enter_executes]').prop('checked', false);
$('#pma_console_options').find('input[name=dark_theme]').prop('checked', false);
Console.updateConfig();
});
$('#pma_console_options').find('input[name=enter_executes]').change(function () {
Console.pmaConsoleMessages.showInstructions(Console.config.EnterExecutes);
});
$(document).ajaxComplete(function (event, xhr, ajaxOptions) {
if (ajaxOptions.dataType && ajaxOptions.dataType.indexOf('json') !== -1) {
return;
}
if (xhr.status !== 200) {
return;
}
try {
var data = JSON.parse(xhr.responseText);
Console.ajaxCallback(data);
} catch (e) {
console.trace();
console.log('Failed to parse JSON: ' + e.message);
}
});
Console.isInitialized = true;
}
// Change console mode from cookie
switch (Console.config.Mode) {
case 'collapse':
Console.collapse();
break;
/* jshint -W086 */// no break needed in default section
case 'info':
/* jshint +W086 */
Console.info();
break;
case 'show':
Console.show(true);
Console.scrollBottom();
break;
default:
Console.setConfig('Mode', 'info');
}
},
/**
* Execute query and show results in console
*
* @return void
*/
execute: function (queryString, options) {
if (typeof(queryString) !== 'string' || ! /[a-z]|[A-Z]/.test(queryString)) {
return;
}
Console.$requestForm.children('textarea').val(queryString);
Console.$requestForm.children('[name=server]').attr('value', PMA_commonParams.get('server'));
if (options && options.db) {
Console.$requestForm.children('[name=db]').val(options.db);
if (options.table) {
Console.$requestForm.children('[name=table]').val(options.table);
} else {
Console.$requestForm.children('[name=table]').val('');
}
} else {
Console.$requestForm.children('[name=db]').val(
(PMA_commonParams.get('db').length > 0 ? PMA_commonParams.get('db') : ''));
}
Console.$requestForm.find('[name=profiling]').remove();
if (options && options.profiling === true) {
Console.$requestForm.append('<input name="profiling" value="on">');
}
if (! confirmQuery(Console.$requestForm[0], Console.$requestForm.children('textarea')[0].value)) {
return;
}
Console.$requestForm.children('[name=console_message_id]')
.val(Console.pmaConsoleMessages.appendQuery({ sql_query: queryString }).message_id);
Console.$requestForm.trigger('submit');
Console.pmaConsoleInput.clear();
PMA_reloadNavigation();
},
ajaxCallback: function (data) {
if (data && data.console_message_id) {
Console.pmaConsoleMessages.updateQuery(data.console_message_id, data.success,
(data._reloadQuerywindow ? data._reloadQuerywindow : false));
} else if (data && data._reloadQuerywindow) {
if (data._reloadQuerywindow.sql_query.length > 0) {
Console.pmaConsoleMessages.appendQuery(data._reloadQuerywindow, 'successed')
.$message.addClass(Console.config.CurrentQuery ? '' : 'hide');
}
}
},
/**
* Change console to collapse mode
*
* @return void
*/
collapse: function () {
Console.setConfig('Mode', 'collapse');
var pmaConsoleHeight = Math.max(92, Console.config.Height);
Console.$consoleToolbar.addClass('collapsed');
Console.$consoleAllContents.height(pmaConsoleHeight);
Console.$consoleContent.stop();
Console.$consoleContent.animate({ 'margin-bottom': -1 * Console.$consoleContent.outerHeight() + 'px' },
'fast', 'easeOutQuart', function () {
Console.$consoleContent.css({ display:'none' });
$(window).trigger('resize');
});
Console.hideCard();
},
/**
* Show console
*
* @param bool inputFocus If true, focus the input line after show()
* @return void
*/
show: function (inputFocus) {
Console.setConfig('Mode', 'show');
var pmaConsoleHeight = Math.max(92, Console.config.Height);
pmaConsoleHeight = Math.min(Console.config.Height, (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - 25);
Console.$consoleContent.css({ display:'block' });
if (Console.$consoleToolbar.hasClass('collapsed')) {
Console.$consoleToolbar.removeClass('collapsed');
}
Console.$consoleAllContents.height(pmaConsoleHeight);
Console.$consoleContent.stop();
Console.$consoleContent.animate({ 'margin-bottom': 0 },
'fast', 'easeOutQuart', function () {
$(window).trigger('resize');
if (inputFocus) {
Console.pmaConsoleInput.focus();
}
});
},
/**
* Change console to SQL information mode
* this mode shows current SQL query
* This mode is the default mode
*
* @return void
*/
info: function () {
// Under construction
Console.collapse();
},
/**
* Toggle console mode between collapse/show
* Used for toggle buttons and shortcuts
*
* @return void
*/
toggle: function () {
switch (Console.config.Mode) {
case 'collapse':
case 'info':
Console.show(true);
break;
case 'show':
Console.collapse();
break;
default:
PMA_consoleInitialize();
}
},
/**
* Scroll console to bottom
*
* @return void
*/
scrollBottom: function () {
Console.$consoleContent.scrollTop(Console.$consoleContent.prop('scrollHeight'));
},
/**
* Show card
*
* @param string cardSelector Selector, select string will be "#pma_console " + cardSelector
* this param also can be JQuery object, if you need.
*
* @return void
*/
showCard: function (cardSelector) {
var $card = null;
if (typeof(cardSelector) !== 'string') {
if (cardSelector.length > 0) {
$card = cardSelector;
} else {
return;
}
} else {
$card = $('#pma_console ' + cardSelector);
}
if ($card.length === 0) {
return;
}
$card.parent().children('.mid_layer').show().fadeTo(0, 0.15);
$card.addClass('show');
Console.pmaConsoleInput.blur();
if ($card.parents('.card').length > 0) {
Console.showCard($card.parents('.card'));
}
},
/**
* Scroll console to bottom
*
* @param object $targetCard Target card JQuery object, if it's empty, function will hide all cards
* @return void
*/
hideCard: function ($targetCard) {
if (! $targetCard) {
$('#pma_console').find('.mid_layer').fadeOut(140);
$('#pma_console').find('.card').removeClass('show');
} else if ($targetCard.length > 0) {
$targetCard.parent().find('.mid_layer').fadeOut(140);
$targetCard.find('.card').removeClass('show');
$targetCard.removeClass('show');
}
},
/**
* Used for update console config
*
* @return void
*/
updateConfig: function () {
Console.setConfig('AlwaysExpand', $('#pma_console_options input[name=always_expand]').prop('checked'));
Console.setConfig('StartHistory', $('#pma_console_options').find('input[name=start_history]').prop('checked'));
Console.setConfig('CurrentQuery', $('#pma_console_options').find('input[name=current_query]').prop('checked'));
Console.setConfig('EnterExecutes', $('#pma_console_options').find('input[name=enter_executes]').prop('checked'));
Console.setConfig('DarkTheme', $('#pma_console_options').find('input[name=dark_theme]').prop('checked'));
/* Setting the dark theme of the console*/
if (Console.config.DarkTheme) {
$('#pma_console').find('>.content').addClass('console_dark_theme');
} else {
$('#pma_console').find('>.content').removeClass('console_dark_theme');
}
},
setConfig: function (key, value) {
Console.config[key] = value;
configSet('Console/' + key, value);
},
isSelect: function (queryString) {
var reg_exp = /^SELECT\s+/i;
return reg_exp.test(queryString);
}
};
export default Console;

365
js/src/consts/doclinks.js Normal file
View File

@ -0,0 +1,365 @@
/**
* Definition of links to MySQL documentation.
*/
export const mysql_doc_keyword = {
/* Multi word */
'CHARACTER SET': Array('charset'),
'SHOW AUTHORS': Array('show-authors'),
'SHOW BINARY LOGS': Array('show-binary-logs'),
'SHOW BINLOG EVENTS': Array('show-binlog-events'),
'SHOW CHARACTER SET': Array('show-character-set'),
'SHOW COLLATION': Array('show-collation'),
'SHOW COLUMNS': Array('show-columns'),
'SHOW CONTRIBUTORS': Array('show-contributors'),
'SHOW CREATE DATABASE': Array('show-create-database'),
'SHOW CREATE EVENT': Array('show-create-event'),
'SHOW CREATE FUNCTION': Array('show-create-function'),
'SHOW CREATE PROCEDURE': Array('show-create-procedure'),
'SHOW CREATE TABLE': Array('show-create-table'),
'SHOW CREATE TRIGGER': Array('show-create-trigger'),
'SHOW CREATE VIEW': Array('show-create-view'),
'SHOW DATABASES': Array('show-databases'),
'SHOW ENGINE': Array('show-engine'),
'SHOW ENGINES': Array('show-engines'),
'SHOW ERRORS': Array('show-errors'),
'SHOW EVENTS': Array('show-events'),
'SHOW FUNCTION CODE': Array('show-function-code'),
'SHOW FUNCTION STATUS': Array('show-function-status'),
'SHOW GRANTS': Array('show-grants'),
'SHOW INDEX': Array('show-index'),
'SHOW MASTER STATUS': Array('show-master-status'),
'SHOW OPEN TABLES': Array('show-open-tables'),
'SHOW PLUGINS': Array('show-plugins'),
'SHOW PRIVILEGES': Array('show-privileges'),
'SHOW PROCEDURE CODE': Array('show-procedure-code'),
'SHOW PROCEDURE STATUS': Array('show-procedure-status'),
'SHOW PROCESSLIST': Array('show-processlist'),
'SHOW PROFILE': Array('show-profile'),
'SHOW PROFILES': Array('show-profiles'),
'SHOW RELAYLOG EVENTS': Array('show-relaylog-events'),
'SHOW SLAVE HOSTS': Array('show-slave-hosts'),
'SHOW SLAVE STATUS': Array('show-slave-status'),
'SHOW STATUS': Array('show-status'),
'SHOW TABLE STATUS': Array('show-table-status'),
'SHOW TABLES': Array('show-tables'),
'SHOW TRIGGERS': Array('show-triggers'),
'SHOW VARIABLES': Array('show-variables'),
'SHOW WARNINGS': Array('show-warnings'),
'LOAD DATA INFILE': Array('load-data'),
'LOAD XML': Array('load-xml'),
'LOCK TABLES': Array('lock-tables'),
'UNLOCK TABLES': Array('lock-tables'),
'ALTER DATABASE': Array('alter-database'),
'ALTER EVENT': Array('alter-event'),
'ALTER LOGFILE GROUP': Array('alter-logfile-group'),
'ALTER FUNCTION': Array('alter-function'),
'ALTER PROCEDURE': Array('alter-procedure'),
'ALTER SERVER': Array('alter-server'),
'ALTER TABLE': Array('alter-table'),
'ALTER TABLESPACE': Array('alter-tablespace'),
'ALTER VIEW': Array('alter-view'),
'CREATE DATABASE': Array('create-database'),
'CREATE EVENT': Array('create-event'),
'CREATE FUNCTION': Array('create-function'),
'CREATE INDEX': Array('create-index'),
'CREATE LOGFILE GROUP': Array('create-logfile-group'),
'CREATE PROCEDURE': Array('create-procedure'),
'CREATE SERVER': Array('create-server'),
'CREATE TABLE': Array('create-table'),
'CREATE TABLESPACE': Array('create-tablespace'),
'CREATE TRIGGER': Array('create-trigger'),
'CREATE VIEW': Array('create-view'),
'DROP DATABASE': Array('drop-database'),
'DROP EVENT': Array('drop-event'),
'DROP FUNCTION': Array('drop-function'),
'DROP INDEX': Array('drop-index'),
'DROP LOGFILE GROUP': Array('drop-logfile-group'),
'DROP PROCEDURE': Array('drop-procedure'),
'DROP SERVER': Array('drop-server'),
'DROP TABLE': Array('drop-table'),
'DROP TABLESPACE': Array('drop-tablespace'),
'DROP TRIGGER': Array('drop-trigger'),
'DROP VIEW': Array('drop-view'),
'RENAME TABLE': Array('rename-table'),
'TRUNCATE TABLE': Array('truncate-table'),
/* Statements */
'SELECT': Array('select'),
'SET': Array('set'),
'EXPLAIN': Array('explain'),
'DESCRIBE': Array('describe'),
'DELETE': Array('delete'),
'SHOW': Array('show'),
'UPDATE': Array('update'),
'INSERT': Array('insert'),
'REPLACE': Array('replace'),
'CALL': Array('call'),
'DO': Array('do'),
'HANDLER': Array('handler'),
'COLLATE': Array('charset-collations'),
/* Functions */
'ABS': Array('mathematical-functions', 'function_abs'),
'ACOS': Array('mathematical-functions', 'function_acos'),
'ADDDATE': Array('date-and-time-functions', 'function_adddate'),
'ADDTIME': Array('date-and-time-functions', 'function_addtime'),
'AES_DECRYPT': Array('encryption-functions', 'function_aes_decrypt'),
'AES_ENCRYPT': Array('encryption-functions', 'function_aes_encrypt'),
'AND': Array('logical-operators', 'operator_and'),
'ASCII': Array('string-functions', 'function_ascii'),
'ASIN': Array('mathematical-functions', 'function_asin'),
'ATAN2': Array('mathematical-functions', 'function_atan2'),
'ATAN': Array('mathematical-functions', 'function_atan'),
'AVG': Array('group-by-functions', 'function_avg'),
'BENCHMARK': Array('information-functions', 'function_benchmark'),
'BIN': Array('string-functions', 'function_bin'),
'BINARY': Array('cast-functions', 'operator_binary'),
'BIT_AND': Array('group-by-functions', 'function_bit_and'),
'BIT_COUNT': Array('bit-functions', 'function_bit_count'),
'BIT_LENGTH': Array('string-functions', 'function_bit_length'),
'BIT_OR': Array('group-by-functions', 'function_bit_or'),
'BIT_XOR': Array('group-by-functions', 'function_bit_xor'),
'CASE': Array('control-flow-functions', 'operator_case'),
'CAST': Array('cast-functions', 'function_cast'),
'CEIL': Array('mathematical-functions', 'function_ceil'),
'CEILING': Array('mathematical-functions', 'function_ceiling'),
'CHAR_LENGTH': Array('string-functions', 'function_char_length'),
'CHAR': Array('string-functions', 'function_char'),
'CHARACTER_LENGTH': Array('string-functions', 'function_character_length'),
'CHARSET': Array('information-functions', 'function_charset'),
'COALESCE': Array('comparison-operators', 'function_coalesce'),
'COERCIBILITY': Array('information-functions', 'function_coercibility'),
'COLLATION': Array('information-functions', 'function_collation'),
'COMPRESS': Array('encryption-functions', 'function_compress'),
'CONCAT_WS': Array('string-functions', 'function_concat_ws'),
'CONCAT': Array('string-functions', 'function_concat'),
'CONNECTION_ID': Array('information-functions', 'function_connection_id'),
'CONV': Array('mathematical-functions', 'function_conv'),
'CONVERT_TZ': Array('date-and-time-functions', 'function_convert_tz'),
'Convert': Array('cast-functions', 'function_convert'),
'COS': Array('mathematical-functions', 'function_cos'),
'COT': Array('mathematical-functions', 'function_cot'),
'COUNT': Array('group-by-functions', 'function_count'),
'CRC32': Array('mathematical-functions', 'function_crc32'),
'CURDATE': Array('date-and-time-functions', 'function_curdate'),
'CURRENT_DATE': Array('date-and-time-functions', 'function_current_date'),
'CURRENT_TIME': Array('date-and-time-functions', 'function_current_time'),
'CURRENT_TIMESTAMP': Array('date-and-time-functions', 'function_current_timestamp'),
'CURRENT_USER': Array('information-functions', 'function_current_user'),
'CURTIME': Array('date-and-time-functions', 'function_curtime'),
'DATABASE': Array('information-functions', 'function_database'),
'DATE_ADD': Array('date-and-time-functions', 'function_date_add'),
'DATE_FORMAT': Array('date-and-time-functions', 'function_date_format'),
'DATE_SUB': Array('date-and-time-functions', 'function_date_sub'),
'DATE': Array('date-and-time-functions', 'function_date'),
'DATEDIFF': Array('date-and-time-functions', 'function_datediff'),
'DAY': Array('date-and-time-functions', 'function_day'),
'DAYNAME': Array('date-and-time-functions', 'function_dayname'),
'DAYOFMONTH': Array('date-and-time-functions', 'function_dayofmonth'),
'DAYOFWEEK': Array('date-and-time-functions', 'function_dayofweek'),
'DAYOFYEAR': Array('date-and-time-functions', 'function_dayofyear'),
'DECLARE': Array('declare', 'declare'),
'DECODE': Array('encryption-functions', 'function_decode'),
'DEFAULT': Array('miscellaneous-functions', 'function_default'),
'DEGREES': Array('mathematical-functions', 'function_degrees'),
'DES_DECRYPT': Array('encryption-functions', 'function_des_decrypt'),
'DES_ENCRYPT': Array('encryption-functions', 'function_des_encrypt'),
'DIV': Array('arithmetic-functions', 'operator_div'),
'ELT': Array('string-functions', 'function_elt'),
'ENCODE': Array('encryption-functions', 'function_encode'),
'ENCRYPT': Array('encryption-functions', 'function_encrypt'),
'EXP': Array('mathematical-functions', 'function_exp'),
'EXPORT_SET': Array('string-functions', 'function_export_set'),
'EXTRACT': Array('date-and-time-functions', 'function_extract'),
'ExtractValue': Array('xml-functions', 'function_extractvalue'),
'FIELD': Array('string-functions', 'function_field'),
'FIND_IN_SET': Array('string-functions', 'function_find_in_set'),
'FLOOR': Array('mathematical-functions', 'function_floor'),
'FORMAT': Array('string-functions', 'function_format'),
'FOUND_ROWS': Array('information-functions', 'function_found_rows'),
'FROM_DAYS': Array('date-and-time-functions', 'function_from_days'),
'FROM_UNIXTIME': Array('date-and-time-functions', 'function_from_unixtime'),
'GET_FORMAT': Array('date-and-time-functions', 'function_get_format'),
'GET_LOCK': Array('miscellaneous-functions', 'function_get_lock'),
'GREATEST': Array('comparison-operators', 'function_greatest'),
'GROUP_CONCAT': Array('group-by-functions', 'function_group_concat'),
'HEX': Array('string-functions', 'function_hex'),
'HOUR': Array('date-and-time-functions', 'function_hour'),
'IF': Array('control-flow-functions', 'function_if'),
'IFNULL': Array('control-flow-functions', 'function_ifnull'),
'IN': Array('comparison-operators', 'function_in'),
'INET_ATON': Array('miscellaneous-functions', 'function_inet_aton'),
'INET_NTOA': Array('miscellaneous-functions', 'function_inet_ntoa'),
'INSTR': Array('string-functions', 'function_instr'),
'INTERVAL': Array('comparison-operators', 'function_interval'),
'IS_FREE_LOCK': Array('miscellaneous-functions', 'function_is_free_lock'),
'IS_USED_LOCK': Array('miscellaneous-functions', 'function_is_used_lock'),
'IS': Array('comparison-operators', 'operator_is'),
'ISNULL': Array('comparison-operators', 'function_isnull'),
'LAST_DAY': Array('date-and-time-functions', 'function_last_day'),
'LAST_INSERT_ID': Array('information-functions', 'function_last_insert_id'),
'LCASE': Array('string-functions', 'function_lcase'),
'LEAST': Array('comparison-operators', 'function_least'),
'LEFT': Array('string-functions', 'function_left'),
'LENGTH': Array('string-functions', 'function_length'),
'LIKE': Array('string-comparison-functions', 'operator_like'),
'LN': Array('mathematical-functions', 'function_ln'),
'LOAD_FILE': Array('string-functions', 'function_load_file'),
'LOCALTIME': Array('date-and-time-functions', 'function_localtime'),
'LOCALTIMESTAMP': Array('date-and-time-functions', 'function_localtimestamp'),
'LOCATE': Array('string-functions', 'function_locate'),
'LOG10': Array('mathematical-functions', 'function_log10'),
'LOG2': Array('mathematical-functions', 'function_log2'),
'LOG': Array('mathematical-functions', 'function_log'),
'LOWER': Array('string-functions', 'function_lower'),
'LPAD': Array('string-functions', 'function_lpad'),
'LTRIM': Array('string-functions', 'function_ltrim'),
'MAKE_SET': Array('string-functions', 'function_make_set'),
'MAKEDATE': Array('date-and-time-functions', 'function_makedate'),
'MAKETIME': Array('date-and-time-functions', 'function_maketime'),
'MASTER_POS_WAIT': Array('miscellaneous-functions', 'function_master_pos_wait'),
'MATCH': Array('fulltext-search', 'function_match'),
'MAX': Array('group-by-functions', 'function_max'),
'MD5': Array('encryption-functions', 'function_md5'),
'MICROSECOND': Array('date-and-time-functions', 'function_microsecond'),
'MID': Array('string-functions', 'function_mid'),
'MIN': Array('group-by-functions', 'function_min'),
'MINUTE': Array('date-and-time-functions', 'function_minute'),
'MOD': Array('mathematical-functions', 'function_mod'),
'MONTH': Array('date-and-time-functions', 'function_month'),
'MONTHNAME': Array('date-and-time-functions', 'function_monthname'),
'NAME_CONST': Array('miscellaneous-functions', 'function_name_const'),
'NOT': Array('logical-operators', 'operator_not'),
'NOW': Array('date-and-time-functions', 'function_now'),
'NULLIF': Array('control-flow-functions', 'function_nullif'),
'OCT': Array('mathematical-functions', 'function_oct'),
'OCTET_LENGTH': Array('string-functions', 'function_octet_length'),
'OLD_PASSWORD': Array('encryption-functions', 'function_old_password'),
'OR': Array('logical-operators', 'operator_or'),
'ORD': Array('string-functions', 'function_ord'),
'PASSWORD': Array('encryption-functions', 'function_password'),
'PERIOD_ADD': Array('date-and-time-functions', 'function_period_add'),
'PERIOD_DIFF': Array('date-and-time-functions', 'function_period_diff'),
'PI': Array('mathematical-functions', 'function_pi'),
'POSITION': Array('string-functions', 'function_position'),
'POW': Array('mathematical-functions', 'function_pow'),
'POWER': Array('mathematical-functions', 'function_power'),
'QUARTER': Array('date-and-time-functions', 'function_quarter'),
'QUOTE': Array('string-functions', 'function_quote'),
'RADIANS': Array('mathematical-functions', 'function_radians'),
'RAND': Array('mathematical-functions', 'function_rand'),
'REGEXP': Array('regexp', 'operator_regexp'),
'RELEASE_LOCK': Array('miscellaneous-functions', 'function_release_lock'),
'REPEAT': Array('string-functions', 'function_repeat'),
'REVERSE': Array('string-functions', 'function_reverse'),
'RIGHT': Array('string-functions', 'function_right'),
'RLIKE': Array('regexp', 'operator_rlike'),
'ROUND': Array('mathematical-functions', 'function_round'),
'ROW_COUNT': Array('information-functions', 'function_row_count'),
'RPAD': Array('string-functions', 'function_rpad'),
'RTRIM': Array('string-functions', 'function_rtrim'),
'SCHEMA': Array('information-functions', 'function_schema'),
'SEC_TO_TIME': Array('date-and-time-functions', 'function_sec_to_time'),
'SECOND': Array('date-and-time-functions', 'function_second'),
'SESSION_USER': Array('information-functions', 'function_session_user'),
'SHA': Array('encryption-functions', 'function_sha1'),
'SHA1': Array('encryption-functions', 'function_sha1'),
'SIGN': Array('mathematical-functions', 'function_sign'),
'SIN': Array('mathematical-functions', 'function_sin'),
'SLEEP': Array('miscellaneous-functions', 'function_sleep'),
'SOUNDEX': Array('string-functions', 'function_soundex'),
'SPACE': Array('string-functions', 'function_space'),
'SQRT': Array('mathematical-functions', 'function_sqrt'),
'STD': Array('group-by-functions', 'function_std'),
'STDDEV_POP': Array('group-by-functions', 'function_stddev_pop'),
'STDDEV_SAMP': Array('group-by-functions', 'function_stddev_samp'),
'STDDEV': Array('group-by-functions', 'function_stddev'),
'STR_TO_DATE': Array('date-and-time-functions', 'function_str_to_date'),
'STRCMP': Array('string-comparison-functions', 'function_strcmp'),
'SUBDATE': Array('date-and-time-functions', 'function_subdate'),
'SUBSTR': Array('string-functions', 'function_substr'),
'SUBSTRING_INDEX': Array('string-functions', 'function_substring_index'),
'SUBSTRING': Array('string-functions', 'function_substring'),
'SUBTIME': Array('date-and-time-functions', 'function_subtime'),
'SUM': Array('group-by-functions', 'function_sum'),
'SYSDATE': Array('date-and-time-functions', 'function_sysdate'),
'SYSTEM_USER': Array('information-functions', 'function_system_user'),
'TAN': Array('mathematical-functions', 'function_tan'),
'TIME_FORMAT': Array('date-and-time-functions', 'function_time_format'),
'TIME_TO_SEC': Array('date-and-time-functions', 'function_time_to_sec'),
'TIME': Array('date-and-time-functions', 'function_time'),
'TIMEDIFF': Array('date-and-time-functions', 'function_timediff'),
'TIMESTAMP': Array('date-and-time-functions', 'function_timestamp'),
'TIMESTAMPADD': Array('date-and-time-functions', 'function_timestampadd'),
'TIMESTAMPDIFF': Array('date-and-time-functions', 'function_timestampdiff'),
'TO_DAYS': Array('date-and-time-functions', 'function_to_days'),
'TRIM': Array('string-functions', 'function_trim'),
'TRUNCATE': Array('mathematical-functions', 'function_truncate'),
'UCASE': Array('string-functions', 'function_ucase'),
'UNCOMPRESS': Array('encryption-functions', 'function_uncompress'),
'UNCOMPRESSED_LENGTH': Array('encryption-functions', 'function_uncompressed_length'),
'UNHEX': Array('string-functions', 'function_unhex'),
'UNIX_TIMESTAMP': Array('date-and-time-functions', 'function_unix_timestamp'),
'UpdateXML': Array('xml-functions', 'function_updatexml'),
'UPPER': Array('string-functions', 'function_upper'),
'USER': Array('information-functions', 'function_user'),
'UTC_DATE': Array('date-and-time-functions', 'function_utc_date'),
'UTC_TIME': Array('date-and-time-functions', 'function_utc_time'),
'UTC_TIMESTAMP': Array('date-and-time-functions', 'function_utc_timestamp'),
'UUID_SHORT': Array('miscellaneous-functions', 'function_uuid_short'),
'UUID': Array('miscellaneous-functions', 'function_uuid'),
'VALUES': Array('miscellaneous-functions', 'function_values'),
'VAR_POP': Array('group-by-functions', 'function_var_pop'),
'VAR_SAMP': Array('group-by-functions', 'function_var_samp'),
'VARIANCE': Array('group-by-functions', 'function_variance'),
'VERSION': Array('information-functions', 'function_version'),
'WEEK': Array('date-and-time-functions', 'function_week'),
'WEEKDAY': Array('date-and-time-functions', 'function_weekday'),
'WEEKOFYEAR': Array('date-and-time-functions', 'function_weekofyear'),
'XOR': Array('logical-operators', 'operator_xor'),
'YEAR': Array('date-and-time-functions', 'function_year'),
'YEARWEEK': Array('date-and-time-functions', 'function_yearweek'),
'SOUNDS_LIKE': Array('string-functions', 'operator_sounds-like'),
'IS_NOT_NULL': Array('comparison-operators', 'operator_is-not-null'),
'IS_NOT': Array('comparison-operators', 'operator_is-not'),
'IS_NULL': Array('comparison-operators', 'operator_is-null'),
'NOT_LIKE': Array('string-comparison-functions', 'operator_not-like'),
'NOT_REGEXP': Array('regexp', 'operator_not-regexp'),
'COUNT_DISTINCT': Array('group-by-functions', 'function_count-distinct'),
'NOT_IN': Array('comparison-operators', 'function_not-in')
};
export const mysql_doc_builtin = {
'TINYINT': Array('numeric-types'),
'SMALLINT': Array('numeric-types'),
'MEDIUMINT': Array('numeric-types'),
'INT': Array('numeric-types'),
'BIGINT': Array('numeric-types'),
'DECIMAL': Array('numeric-types'),
'FLOAT': Array('numeric-types'),
'DOUBLE': Array('numeric-types'),
'REAL': Array('numeric-types'),
'BIT': Array('numeric-types'),
'BOOLEAN': Array('numeric-types'),
'SERIAL': Array('numeric-types'),
'DATE': Array('date-and-time-types'),
'DATETIME': Array('date-and-time-types'),
'TIMESTAMP': Array('date-and-time-types'),
'TIME': Array('date-and-time-types'),
'YEAR': Array('date-and-time-types'),
'CHAR': Array('string-types'),
'VARCHAR': Array('string-types'),
'TINYTEXT': Array('string-types'),
'TEXT': Array('string-types'),
'MEDIUMTEXT': Array('string-types'),
'LONGTEXT': Array('string-types'),
'BINARY': Array('string-types'),
'VARBINARY': Array('string-types'),
'TINYBLOB': Array('string-types'),
'MEDIUMBLOB': Array('string-types'),
'BLOB': Array('string-types'),
'LONGBLOB': Array('string-types'),
'ENUM': Array('string-types'),
'SET': Array('string-types')
};

111
js/src/consts/files.js Normal file
View File

@ -0,0 +1,111 @@
/**
* List of JS files need to be loaded at the time of initial page load.
* Eg. For server_privileges.php, server_privileges.js is required
*/
/**
* @type {Object} files
*/
const PhpToJsFileMapping = {
global: [
'error_report',
'config',
'navigation',
'page_settings',
'shortcuts_handler',
'functions',
'indexes',
'key_handler',
'cross_framing_protection',
'drag_drop_import',
'rte'
],
server_privileges: ['server_privileges'],
server_databases: ['server_databases'],
server_status_advisor: ['server_status_advisor'],
server_status_processes: ['server_status_processes'],
server_status_variables: ['server_status_variables'],
user_password: ['server_privileges'],
server_plugins: ['server_plugins'],
server_status_queries: ['server_status_sorter', 'server_status_queries'],
server_status_monitor: ['server_status_monitor', 'server_status_sorter'],
server_variables: ['server_variables'],
server_user_groups: ['server_user_groups'],
server_replication: ['server_privileges', 'replication'],
server_export: ['export'],
server_import: ['import'],
db_search: ['db_search', 'sql'],
server_sql: ['sql', 'multi_column_sort'],
tbl_sql: ['sql', 'multi_column_sort', 'tbl_change'],
db_sql: ['sql', 'multi_column_sort'],
sql: ['sql', 'multi_column_sort'],
db_structure: ['db_structure', 'tbl_change'],
db_operations: ['db_operations'],
db_tracking: ['db_tracking'],
db_central_columns: ['db_central_columns'],
db_export: ['export'],
db_import: ['import'],
tbl_structure: ['tbl_structure'],
tbl_indexes: [],
tbl_relation: ['tbl_relation'],
tbl_replace: ['tbl_change', 'sql'],
tbl_chart: ['tbl_chart'],
tbl_operations: ['tbl_operations'],
tbl_tracking: ['tbl_tracking'],
tbl_change: ['sql', 'tbl_change'],
tbl_select: ['sql', 'tbl_change', 'tbl_select'],
tbl_zoom_select: ['sql', 'tbl_change'],
tbl_find_replace: ['tbl_find_replace'],
tbl_import: ['import'],
tbl_export: ['export'],
normalization: ['normalization']
};
const JsFileList = [
'server_privileges',
'server_databases',
'error_report',
'navigation',
'server_status_advisor',
'server_status_processes',
'server_status_variables',
'server_plugins',
'server_status_sorter',
'server_status_queries',
'server_status_monitor',
'server_variables',
'server_user_groups',
'replication',
'export',
'import',
'config',
'page_settings',
'shortcuts_handler',
'db_search',
'sql',
'functions',
'multi_column_sort',
'db_structure',
'db_operations',
'db_tracking',
'db_central_columns',
'indexes',
'tbl_structure',
'tbl_relation',
'tbl_chart',
'tbl_operations',
'tbl_tracking',
'tbl_change',
'tbl_select',
'tbl_find_replace',
'key_handler',
'cross_framing_protection',
'drag_drop_import',
'normalization',
'rte'
];
export {
PhpToJsFileMapping,
JsFileList
};

View File

@ -0,0 +1,16 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Conditionally included if framing is not allowed
*/
if (self === top) {
var styleElement = document.getElementById('cfs-style');
// check if styleElement has already been removed
// to avoid frequently reported js error
if (typeof(styleElement) !== 'undefined' && styleElement !== null) {
styleElement.parentNode.removeChild(styleElement);
}
} else {
top.location = self.location;
}

View File

@ -1,4 +1,15 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from './utils/JqueryExtended';
import './plugins/jquery/jquery.tablesorter';
import { AJAX } from './ajax';
import CommonParams from './variables/common_params';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
import { PMA_Messages as messages } from './variables/export_variables';
/**
* @fileoverview events handling from central columns page
* @name Central columns
@ -16,7 +27,7 @@
*
*/
AJAX.registerTeardown('db_central_columns.js', function () {
export function teardownDbCentralColumns () {
$('.edit').off('click');
$('.edit_save_form').off('click');
$('.edit_cancel_form').off('click');
@ -31,9 +42,9 @@ AJAX.registerTeardown('db_central_columns.js', function () {
$('select.default_type').off('change');
$('button[name=\'delete_central_columns\']').off('click');
$('button[name=\'edit_central_columns\']').off('click');
});
}
AJAX.registerOnload('db_central_columns.js', function () {
export function onloadDbCentralColumns () {
$('#tableslistcontainer input,#tableslistcontainer select,#tableslistcontainer .default_value,#tableslistcontainer .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
$('#tableslistcontainer').find('.checkall_box').show();
@ -50,7 +61,7 @@ AJAX.registerOnload('db_central_columns.js', function () {
event.preventDefault();
var multi_delete_columns = $('.checkall:checkbox:checked').serialize();
if (multi_delete_columns === '') {
PMA_ajaxShowMessage(PMA_messages.strRadioUnchecked);
PMA_ajaxShowMessage(messages.strRadioUnchecked);
return false;
}
PMA_ajaxShowMessage();
@ -61,11 +72,11 @@ AJAX.registerOnload('db_central_columns.js', function () {
event.preventDefault();
var editColumnList = $('.checkall:checkbox:checked').serialize();
if (editColumnList === '') {
PMA_ajaxShowMessage(PMA_messages.strRadioUnchecked);
PMA_ajaxShowMessage(messages.strRadioUnchecked);
return false;
}
var argsep = PMA_commonParams.get('arg_separator');
var editColumnData = editColumnList + '' + argsep + 'edit_central_columns_page=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + PMA_commonParams.get('db');
var argsep = CommonParams.get('arg_separator');
var editColumnData = editColumnList + '' + argsep + 'edit_central_columns_page=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + CommonParams.get('db');
PMA_ajaxShowMessage();
AJAX.source = $(this);
$.get('db_central_columns.php', editColumnData, AJAX.responseHandler);
@ -73,8 +84,8 @@ AJAX.registerOnload('db_central_columns.js', function () {
$('#multi_edit_central_columns').submit(function (event) {
event.preventDefault();
event.stopPropagation();
var argsep = PMA_commonParams.get('arg_separator');
var multi_column_edit_data = $('#multi_edit_central_columns').serialize() + argsep + 'multi_edit_central_column_save=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(PMA_commonParams.get('db'));
var argsep = CommonParams.get('arg_separator');
var multi_column_edit_data = $('#multi_edit_central_columns').serialize() + argsep + 'multi_edit_central_column_save=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db'));
PMA_ajaxShowMessage();
AJAX.source = $(this);
$.post('db_central_columns.php', multi_column_edit_data, AJAX.responseHandler);
@ -116,7 +127,7 @@ AJAX.registerOnload('db_central_columns.js', function () {
event.preventDefault();
event.stopPropagation();
var $td = $(this);
var question = PMA_messages.strDeleteCentralColumnWarning;
var question = messages.strDeleteCentralColumnWarning;
$td.PMA_confirm(question, null, function (url) {
var rownum = $td.data('rownum');
$('#del_col_name').val('selected_fld%5B%5D=' + $('#checkbox_row_' + rownum).val());
@ -154,7 +165,7 @@ AJAX.registerOnload('db_central_columns.js', function () {
$.ajax({
type: 'POST',
url: 'db_central_columns.php',
data: datastring + PMA_commonParams.get('arg_separator') + 'ajax_request=true',
data: datastring + CommonParams.get('arg_separator') + 'ajax_request=true',
dataType: 'json',
success: function (data) {
if (data.message !== '1') {
@ -184,7 +195,7 @@ AJAX.registerOnload('db_central_columns.js', function () {
error: function () {
PMA_ajaxShowMessage(
'<div class="error">' +
PMA_messages.strErrorProcessingRequest +
messages.strErrorProcessingRequest +
'</div>',
false
);
@ -197,12 +208,12 @@ AJAX.registerOnload('db_central_columns.js', function () {
var href = 'db_central_columns.php';
var params = {
'ajax_request' : true,
'server' : PMA_commonParams.get('server'),
'db' : PMA_commonParams.get('db'),
'server' : CommonParams.get('server'),
'db' : CommonParams.get('db'),
'selectedTable' : selectvalue,
'populateColumns' : true
};
$('#column-select').html('<option value="">' + PMA_messages.strLoading + '</option>');
$('#column-select').html('<option value="">' + messages.strLoading + '</option>');
if (selectvalue !== '') {
$.post(href, params, function (data) {
$('#column-select').empty().append(default_column_select);
@ -238,4 +249,4 @@ AJAX.registerOnload('db_central_columns.js', function () {
$(this).siblings('.default_value').attr('name','col_default_val');
}
});
});
}

View File

@ -1,4 +1,19 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from './utils/JqueryExtended';
import CommonParams from './variables/common_params';
import { PMA_commonActions } from './classes/CommonActions';
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
import { escapeHtml } from './utils/Sanitise';
import { PMA_prepareForAjaxRequest } from './functions/AjaxRequest';
import { PMA_sprintf } from './utils/sprintf';
import { getJSConfirmCommonParam } from './functions/Common';
import { PMA_reloadNavigation } from './functions/navigation';
/**
* @fileoverview function used in server privilege pages
* @name Database Operations
@ -22,21 +37,21 @@
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('db_operations.js', function () {
export function teardownDbOperations () {
$(document).off('submit', '#rename_db_form.ajax');
$(document).off('submit', '#copy_db_form.ajax');
$(document).off('submit', '#change_db_charset_form.ajax');
$(document).off('click', '#drop_db_anchor.ajax');
});
}
AJAX.registerOnload('db_operations.js', function () {
export function onloadDbOperations () {
/**
* Ajax event handlers for 'Rename Database'
*/
$(document).on('submit', '#rename_db_form.ajax', function (event) {
event.preventDefault();
var old_db_name = PMA_commonParams.get('db');
var old_db_name = CommonParams.get('db');
var new_db_name = $('#new_db_name').val();
if (new_db_name === old_db_name) {
@ -52,15 +67,15 @@ AJAX.registerOnload('db_operations.js', function () {
$form.PMA_confirm(question, $form.attr('action'), function (url) {
PMA_ajaxShowMessage(PMA_messages.strRenamingDatabases, false);
$.post(url, $('#rename_db_form').serialize() + PMA_commonParams.get('arg_separator') + 'is_js_confirmed=1', function (data) {
$.post(url, $('#rename_db_form').serialize() + CommonParams.get('arg_separator') + 'is_js_confirmed=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
PMA_ajaxShowMessage(data.message);
PMA_commonParams.set('db', data.newname);
CommonParams.set('db', data.newname);
PMA_reloadNavigation(function () {
$('#pma_navigation_tree')
.find('a:not(\'.expander\')')
.each(function (index) {
.each(function () {
var $thisAnchor = $(this);
if ($thisAnchor.text() === data.newname) {
// simulate a click on the new db name
@ -89,12 +104,12 @@ AJAX.registerOnload('db_operations.js', function () {
$('div.success, div.error').fadeOut();
if (typeof data !== 'undefined' && data.success === true) {
if ($('#checkbox_switch').is(':checked')) {
PMA_commonParams.set('db', data.newname);
CommonParams.set('db', data.newname);
PMA_commonActions.refreshMain(false, function () {
PMA_ajaxShowMessage(data.message);
});
} else {
PMA_commonParams.set('db', data.db);
CommonParams.set('db', data.db);
PMA_ajaxShowMessage(data.message);
}
PMA_reloadNavigation();
@ -120,7 +135,7 @@ AJAX.registerOnload('db_operations.js', function () {
var $form = $(this);
PMA_prepareForAjaxRequest($form);
PMA_ajaxShowMessage(PMA_messages.strChangingCharset);
$.post($form.attr('action'), $form.serialize() + PMA_commonParams.get('arg_separator') + 'submitcollation=1', function (data) {
$.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'submitcollation=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
PMA_ajaxShowMessage(data.message);
} else {
@ -141,7 +156,7 @@ AJAX.registerOnload('db_operations.js', function () {
var question = PMA_messages.strDropDatabaseStrongWarning + ' ';
question += PMA_sprintf(
PMA_messages.strDoYouReally,
'DROP DATABASE `' + escapeHtml(PMA_commonParams.get('db') + '`')
'DROP DATABASE `' + escapeHtml(CommonParams.get('db') + '`')
);
var params = getJSConfirmCommonParam(this, $link.getPostData());
@ -151,7 +166,7 @@ AJAX.registerOnload('db_operations.js', function () {
if (typeof data !== 'undefined' && data.success) {
// Database deleted successfully, refresh both the frames
PMA_reloadNavigation();
PMA_commonParams.set('db', '');
CommonParams.set('db', '');
PMA_commonActions.refreshMain(
'server_databases.php',
function () {
@ -164,4 +179,4 @@ AJAX.registerOnload('db_operations.js', function () {
});
});
});
});
}

View File

@ -1,4 +1,14 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from './utils/JqueryExtended';
import { PMA_Messages as messages } from './variables/export_variables';
import { PMA_ajaxShowMessage, PMA_sprintf, PMA_ajaxRemoveMessage } from './utils/show_ajax_messages';
import CommonParams from './variables/common_params';
import { PMA_makegrid } from './utils/makegrid';
/**
* JavaScript functions used on Database Search page
*
@ -18,7 +28,7 @@
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('db_search.js', function () {
export function teardownDbSearch () {
$('a.browse_results').off('click');
$('a.delete_results').off('click');
$('#buttonGo').off('click');
@ -26,15 +36,15 @@ AJAX.registerTeardown('db_search.js', function () {
$('#togglequerybox').off('click');
$('#togglesearchformlink').off('click');
$(document).off('submit', '#db_search_form.ajax');
});
}
AJAX.registerOnload('db_search.js', function () {
export function onloadDbSearch () {
/** Hide the table link in the initial search result */
var icon = PMA_getImage('s_tbl', '', { 'id': 'table-image' }).toString();
let icon = PMA_getImage('s_tbl', '', { 'id': 'table-image' }).toString();
$('#table-info').prepend(icon).hide();
/** Hide the browse and deleted results in the new search criteria */
$('#buttonGo').on('click', function () {
$('#buttonGo').click(function () {
$('#table-info').hide();
$('#browse-results').hide();
$('#sqlqueryform').hide();
@ -52,14 +62,14 @@ AJAX.registerOnload('db_search.js', function () {
* the hide/show criteria in search result forms
*/
$('#togglesearchresultlink')
.html(PMA_messages.strHideSearchResults)
.html(messages.strHideSearchResults)
.on('click', function () {
var $link = $(this);
let $link = $(this);
$('#searchresults').slideToggle();
if ($link.text() === PMA_messages.strHideSearchResults) {
$link.text(PMA_messages.strShowSearchResults);
if ($link.text() === messages.strHideSearchResults) {
$link.text(messages.strShowSearchResults);
} else {
$link.text(PMA_messages.strHideSearchResults);
$link.text(messages.strHideSearchResults);
}
/** avoid default click action */
return false;
@ -79,12 +89,12 @@ AJAX.registerOnload('db_search.js', function () {
$('#togglequerybox')
.hide()
.on('click', function () {
var $link = $(this);
let $link = $(this);
$('#sqlqueryform').slideToggle('medium');
if ($link.text() === PMA_messages.strHideQueryBox) {
$link.text(PMA_messages.strShowQueryBox);
if ($link.text() === messages.strHideQueryBox) {
$link.text(messages.strShowQueryBox);
} else {
$link.text(PMA_messages.strHideQueryBox);
$link.text(messages.strHideQueryBox);
}
/** avoid default click action */
return false;
@ -97,14 +107,14 @@ AJAX.registerOnload('db_search.js', function () {
* the hide/show criteria in search criteria form
*/
$('#togglesearchformlink')
.html(PMA_messages.strShowSearchCriteria)
.html(messages.strShowSearchCriteria)
.on('click', function () {
var $link = $(this);
let $link = $(this);
$('#db_search_form').slideToggle();
if ($link.text() === PMA_messages.strHideSearchCriteria) {
$link.text(PMA_messages.strShowSearchCriteria);
if ($link.text() === messages.strHideSearchCriteria) {
$link.text(messages.strShowSearchCriteria);
} else {
$link.text(PMA_messages.strHideSearchCriteria);
$link.text(messages.strHideSearchCriteria);
}
/** avoid default click action */
return false;
@ -116,17 +126,19 @@ AJAX.registerOnload('db_search.js', function () {
$(document).on('click', 'a.browse_results', function (e) {
e.preventDefault();
/** Hides the results shown by the delete criteria */
var $msg = PMA_ajaxShowMessage(PMA_messages.strBrowsing, false);
let $msg = PMA_ajaxShowMessage(messages.strBrowsing, false);
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Load the browse results to the page */
$('#table-info').show();
var table_name = $(this).data('table-name');
let table_name = $(this).data('table-name');
$('#table-link').attr({ 'href' : $(this).attr('href') }).text(table_name);
var url = $(this).attr('href') + '#searchresults';
var browse_sql = $(this).data('browse-sql');
var params = {
let url = `${$(this).attr('href')}
#searchresults`;
let browse_sql = $(this).data('browse-sql');
let params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query' : browse_sql
@ -136,7 +148,7 @@ AJAX.registerOnload('db_search.js', function () {
$('#browse-results').html(data.message);
PMA_ajaxRemoveMessage($msg);
$('.table_results').each(function () {
PMA_makegrid(this, true, true, true, true);
PMA_makegrid(this);
});
$('#browse-results').show();
PMA_highlightSQL($('#browse-results'));
@ -160,20 +172,20 @@ AJAX.registerOnload('db_search.js', function () {
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Conformation message for deletion */
var msg = PMA_sprintf(
PMA_messages.strConfirmDeleteResults,
let msg = PMA_sprintf(
messages.strConfirmDeleteResults,
$(this).data('table-name')
);
if (confirm(msg)) {
var $msg = PMA_ajaxShowMessage(PMA_messages.strDeleting, false);
let $msg = PMA_ajaxShowMessage(messages.strDeleting, false);
/** Load the deleted option to the page*/
$('#sqlqueryform').html('');
var params = {
let params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query': $(this).data('delete-sql')
};
var url = $(this).attr('href');
let url = $(this).attr('href');
$.post(url, params, function (data) {
if (typeof data === 'undefined' || !data.success) {
@ -183,8 +195,8 @@ AJAX.registerOnload('db_search.js', function () {
$('#sqlqueryform').html(data.sql_query);
/** Refresh the search results after the deletion */
document.getElementById('buttonGo').trigger('click');
$('#togglequerybox').html(PMA_messages.strHideQueryBox);
document.getElementById('buttonGo').click();
$('#togglequerybox').html(messages.strHideQueryBox);
/** Show the results of the deletion option */
$('#browse-results').hide();
$('#sqlqueryform').show();
@ -203,14 +215,14 @@ AJAX.registerOnload('db_search.js', function () {
*/
$(document).on('submit', '#db_search_form.ajax', function (event) {
event.preventDefault();
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strSearching, false);
var $msgbox = PMA_ajaxShowMessage(messages.strSearching, false);
// jQuery object to reuse
var $form = $(this);
PMA_prepareForAjaxRequest($form);
var url = $form.serialize() + PMA_commonParams.get('arg_separator') + 'submit_search=' + $('#buttonGo').val();
var url = `${$form.serialize()}
${CommonParams.get('arg_separator')}submit_search=${$('#buttonGo').val()}`;
$.post($form.attr('action'), url, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
// found results
@ -218,7 +230,7 @@ AJAX.registerOnload('db_search.js', function () {
$('#togglesearchresultlink')
// always start with the Show message
.text(PMA_messages.strHideSearchResults);
.text(messages.strHideSearchResults);
$('#togglesearchresultsdiv')
// now it's time to show the div containing the link
.show();
@ -231,7 +243,7 @@ AJAX.registerOnload('db_search.js', function () {
.hide();
$('#togglesearchformlink')
// always start with the Show message
.text(PMA_messages.strShowSearchCriteria);
.text(messages.strShowSearchCriteria);
$('#togglesearchformdiv')
// now it's time to show the div containing the link
.show();
@ -243,4 +255,4 @@ AJAX.registerOnload('db_search.js', function () {
PMA_ajaxRemoveMessage($msgbox);
});
});
}); // end $()
}

View File

@ -1,4 +1,17 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from './utils/JqueryExtended';
import { PMA_Messages as messages } from './variables/export_variables';
import { PMA_sprintf } from './utils/sprintf';
import { escapeHtml } from './utils/Sanitise';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage, PMA_tooltip } from './utils/show_ajax_messages';
import { getForeignKeyCheckboxLoader, loadForeignKeyCheckbox, getJSConfirmCommonParam } from './functions/Sql/ForeignKey';
import { PMA_adjustTotals, PMA_fetchRealRowCount } from './functions/Database/Structure';
import { printPreview } from './functions/Print';
import { PMA_reloadNavigation } from './functions/navigation';
/**
* @fileoverview functions used on the database structure page
* @name Database Structure
@ -21,7 +34,7 @@
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('db_structure.js', function () {
export function teardownDbStructure () {
$(document).off('click', 'a.truncate_table_anchor.ajax');
$(document).off('click', 'a.drop_table_anchor.ajax');
$(document).off('click', '#real_end_input');
@ -30,160 +43,9 @@ AJAX.registerTeardown('db_structure.js', function () {
$('a.real_row_count').off('click');
$('a.row_count_sum').off('click');
$('select[name=submit_mult]').off('change');
});
/**
* Adjust number of rows and total size in the summary
* when truncating, creating, dropping or inserting into a table
*/
function PMA_adjustTotals () {
var byteUnits = [
PMA_messages.strB,
PMA_messages.strKiB,
PMA_messages.strMiB,
PMA_messages.strGiB,
PMA_messages.strTiB,
PMA_messages.strPiB,
PMA_messages.strEiB
];
/**
* @var $allTr jQuery object that references all the rows in the list of tables
*/
var $allTr = $('#tablesForm').find('table.data tbody:first tr');
// New summary values for the table
var tableSum = $allTr.size();
var rowsSum = 0;
var sizeSum = 0;
var overheadSum = 0;
var rowSumApproximated = false;
$allTr.each(function () {
var $this = $(this);
var i;
var tmpVal;
// Get the number of rows for this SQL table
var strRows = $this.find('.tbl_rows').text();
// If the value is approximated
if (strRows.indexOf('~') === 0) {
rowSumApproximated = true;
// The approximated value contains a preceding ~ (Eg 100 --> ~100)
strRows = strRows.substring(1, strRows.length);
}
strRows = strRows.replace(/[,.]/g, '');
var intRow = parseInt(strRows, 10);
if (! isNaN(intRow)) {
rowsSum += intRow;
}
// Extract the size and overhead
var valSize = 0;
var valOverhead = 0;
var strSize = $.trim($this.find('.tbl_size span:not(.unit)').text());
var strSizeUnit = $.trim($this.find('.tbl_size span.unit').text());
var strOverhead = $.trim($this.find('.tbl_overhead span:not(.unit)').text());
var strOverheadUnit = $.trim($this.find('.tbl_overhead span.unit').text());
// Given a value and a unit, such as 100 and KiB, for the table size
// and overhead calculate their numeric values in bytes, such as 102400
for (i = 0; i < byteUnits.length; i++) {
if (strSizeUnit === byteUnits[i]) {
tmpVal = parseFloat(strSize);
valSize = tmpVal * Math.pow(1024, i);
break;
}
}
for (i = 0; i < byteUnits.length; i++) {
if (strOverheadUnit === byteUnits[i]) {
tmpVal = parseFloat(strOverhead);
valOverhead = tmpVal * Math.pow(1024, i);
break;
}
}
sizeSum += valSize;
overheadSum += valOverhead;
});
// Add some commas for readability:
// 1000000 becomes 1,000,000
var strRowSum = rowsSum + '';
var regex = /(\d+)(\d{3})/;
while (regex.test(strRowSum)) {
strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2');
}
// If approximated total value add ~ in front
if (rowSumApproximated) {
strRowSum = '~' + strRowSum;
}
// Calculate the magnitude for the size and overhead values
var size_magnitude = 0;
var overhead_magnitude = 0;
while (sizeSum >= 1024) {
sizeSum /= 1024;
size_magnitude++;
}
while (overheadSum >= 1024) {
overheadSum /= 1024;
overhead_magnitude++;
}
sizeSum = Math.round(sizeSum * 10) / 10;
overheadSum = Math.round(overheadSum * 10) / 10;
// Update summary with new data
var $summary = $('#tbl_summary_row');
$summary.find('.tbl_num').text(PMA_sprintf(PMA_messages.strNTables, tableSum));
if (rowSumApproximated) {
$summary.find('.row_count_sum').text(strRowSum);
} else {
$summary.find('.tbl_rows').text(strRowSum);
}
$summary.find('.tbl_size').text(sizeSum + ' ' + byteUnits[size_magnitude]);
$summary.find('.tbl_overhead').text(overheadSum + ' ' + byteUnits[overhead_magnitude]);
}
/**
* Gets the real row count for a table or DB.
* @param object $target Target for appending the real count value.
*/
function PMA_fetchRealRowCount ($target) {
var $throbber = $('#pma_navigation').find('.throbber')
.first()
.clone()
.css({ visibility: 'visible', display: 'inline-block' })
.on('click', false);
$target.html($throbber);
$.ajax({
type: 'GET',
url: $target.attr('href'),
cache: false,
dataType: 'json',
success: function (response) {
if (response.success) {
// If to update all row counts for a DB.
if (response.real_row_count_all) {
$.each(JSON.parse(response.real_row_count_all),
function (index, table) {
// Update each table row count.
$('table.data td[data-table*="' + table.table + '"]')
.text(table.row_count);
}
);
}
// If to update a particular table's row count.
if (response.real_row_count) {
// Append the parent cell with real row count.
$target.parent().text(response.real_row_count);
}
// Adjust the 'Sum' displayed at the bottom.
PMA_adjustTotals();
} else {
PMA_ajaxShowMessage(PMA_messages.strErrorRealRowCount);
}
},
error: function () {
PMA_ajaxShowMessage(PMA_messages.strErrorRealRowCount);
}
});
}
AJAX.registerOnload('db_structure.js', function () {
export function onloadDbStructure () {
/**
* function to open the confirmation dialog for making table consistent with central list
*
@ -195,18 +57,18 @@ AJAX.registerOnload('db_structure.js', function () {
var dialogObj = $('<div class=\'hide\'>' + msg + '</div>');
$('body').append(dialogObj);
var buttonOptions = {};
buttonOptions[PMA_messages.strContinue] = function () {
buttonOptions[messages.strContinue] = function () {
success();
$(this).dialog('close');
};
buttonOptions[PMA_messages.strCancel] = function () {
buttonOptions[messages.strCancel] = function () {
$(this).dialog('close');
$('#tablesForm')[0].reset();
};
$(dialogObj).dialog({
resizable: false,
modal: true,
title: PMA_messages.confirmTitle,
title: messages.confirmTitle,
buttons: buttonOptions
});
};
@ -219,7 +81,7 @@ AJAX.registerOnload('db_structure.js', function () {
event.preventDefault();
event.stopPropagation();
jqConfirm(
PMA_messages.makeConsistentMessage, function () {
messages.makeConsistentMessage, function () {
$('#tablesForm').submit();
}
);
@ -233,13 +95,13 @@ AJAX.registerOnload('db_structure.js', function () {
var formData = $('#tablesForm').serialize();
var modalTitle = '';
if ($(this).val() === 'copy_tbl') {
modalTitle = PMA_messages.strCopyTablesTo;
modalTitle = messages.strCopyTablesTo;
} else if ($(this).val() === 'add_prefix_tbl') {
modalTitle = PMA_messages.strAddPrefix;
modalTitle = messages.strAddPrefix;
} else if ($(this).val() === 'replace_prefix_tbl') {
modalTitle = PMA_messages.strReplacePrefix;
modalTitle = messages.strReplacePrefix;
} else if ($(this).val() === 'copy_tbl_change_prefix') {
modalTitle = PMA_messages.strCopyPrefix;
modalTitle = messages.strCopyPrefix;
}
$.ajax({
type: 'POST',
@ -251,11 +113,11 @@ AJAX.registerOnload('db_structure.js', function () {
var dialogObj = $('<div class=\'hide\'>' + data + '</div>');
$('body').append(dialogObj);
var buttonOptions = {};
buttonOptions[PMA_messages.strContinue] = function () {
buttonOptions[messages.strContinue] = function () {
$('#ajax_form').submit();
$(this).dialog('close');
};
buttonOptions[PMA_messages.strCancel] = function () {
buttonOptions[messages.strCancel] = function () {
$(this).dialog('close');
$('#tablesForm')[0].reset();
};
@ -291,12 +153,12 @@ AJAX.registerOnload('db_structure.js', function () {
/**
* @var question String containing the question to be asked for confirmation
*/
var question = PMA_messages.strTruncateTableStrongWarning + ' ' +
PMA_sprintf(PMA_messages.strDoYouReally, 'TRUNCATE `' + escapeHtml(curr_table_name) + '`') +
var question = messages.strTruncateTableStrongWarning + ' ' +
PMA_sprintf(messages.strDoYouReally, 'TRUNCATE `' + escapeHtml(curr_table_name) + '`') +
getForeignKeyCheckboxLoader();
$this_anchor.PMA_confirm(question, $this_anchor.attr('href'), function (url) {
PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
PMA_ajaxShowMessage(messages.strProcessingRequest);
var params = getJSConfirmCommonParam(this, $this_anchor.getPostData());
@ -317,7 +179,7 @@ AJAX.registerOnload('db_structure.js', function () {
.removeClass('truncate_table_anchor');
PMA_adjustTotals();
} else {
PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + ' : ' + data.error, false);
PMA_ajaxShowMessage(messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, loadForeignKeyCheckbox); // end $.PMA_confirm()
@ -349,16 +211,16 @@ AJAX.registerOnload('db_structure.js', function () {
*/
var question;
if (! is_view) {
question = PMA_messages.strDropTableStrongWarning + ' ' +
PMA_sprintf(PMA_messages.strDoYouReally, 'DROP TABLE `' + escapeHtml(curr_table_name) + '`');
question = messages.strDropTableStrongWarning + ' ' +
PMA_sprintf(messages.strDoYouReally, 'DROP TABLE `' + escapeHtml(curr_table_name) + '`');
} else {
question =
PMA_sprintf(PMA_messages.strDoYouReally, 'DROP VIEW `' + escapeHtml(curr_table_name) + '`');
PMA_sprintf(messages.strDoYouReally, 'DROP VIEW `' + escapeHtml(curr_table_name) + '`');
}
question += getForeignKeyCheckboxLoader();
$this_anchor.PMA_confirm(question, $this_anchor.attr('href'), function (url) {
var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
var $msg = PMA_ajaxShowMessage(messages.strProcessingRequest);
var params = getJSConfirmCommonParam(this, $this_anchor.getPostData());
@ -370,7 +232,7 @@ AJAX.registerOnload('db_structure.js', function () {
PMA_reloadNavigation();
PMA_ajaxRemoveMessage($msg);
} else {
PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + ' : ' + data.error, false);
PMA_ajaxShowMessage(messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, loadForeignKeyCheckbox); // end $.PMA_confirm()
@ -397,7 +259,7 @@ AJAX.registerOnload('db_structure.js', function () {
/**
* @var question String containing the question to be asked for confirmation
*/
var question = PMA_messages.strOperationTakesLongTime;
var question = messages.strOperationTakesLongTime;
$(this).PMA_confirm(question, '', function () {
return true;
@ -424,4 +286,4 @@ AJAX.registerOnload('db_structure.js', function () {
event.preventDefault();
PMA_fetchRealRowCount($(this));
});
}); // end $()
} // end $()

View File

@ -1,16 +1,28 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from './utils/JqueryExtended';
import './plugins/jquery/jquery.tablesorter';
import { AJAX } from './ajax';
import CommonParams from './variables/common_params';
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
/**
* Unbind all event handlers before tearing down the page
*/
AJAX.registerTeardown('db_tracking.js', function () {
export function teardownDbTracking () {
$('body').off('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]');
$('body').off('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]');
$('body').off('click', 'a.delete_tracking_anchor.ajax');
});
}
/**
* Bind event handlers
*/
AJAX.registerOnload('db_tracking.js', function () {
export function onloadDbTracking () {
var $versions = $('#versions');
$versions.find('tr:first th').append($('<div class="sorticon"></div>'));
$versions.tablesorter({
@ -43,7 +55,7 @@ AJAX.registerOnload('db_tracking.js', function () {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = PMA_commonParams.get('arg_separator');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
if ($button.val() === 'delete_tracking') {
@ -67,7 +79,7 @@ AJAX.registerOnload('db_tracking.js', function () {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = PMA_commonParams.get('arg_separator');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
PMA_ajaxShowMessage();
AJAX.source = $form;
@ -91,4 +103,4 @@ AJAX.registerOnload('db_tracking.js', function () {
$.post(url, params, AJAX.responseHandler);
});
});
});
}

View File

@ -0,0 +1,59 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import DragDropImport from './classes/DragDropImport';
/* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/
export function teardownDragDropImport () {
$(document).off('dragenter');
$(document).off('dragover');
$(document).off('dragleave', '.pma_drop_handler');
$(document).off('drop', 'body');
$(document).off('click', '.pma_sql_import_status h2 .minimize');
$(document).off('click', '.pma_sql_import_status h2 .close');
$(document).off('click', '.pma_drop_result h2 .close');
}
export function onloadDragDropImport () {
/**
* Called when some user drags, dragover, leave
* a file to the PMA UI
* @param object Event data
* @return void
*/
$(document).on('dragenter', DragDropImport._dragenter);
$(document).on('dragover', DragDropImport._dragover);
$(document).on('dragleave', '.pma_drop_handler', DragDropImport._dragleave);
// when file is dropped to PMA UI
$(document).on('drop', 'body', DragDropImport._drop);
// minimizing-maximising the sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .minimize', function () {
if ($(this).attr('toggle') === 'off') {
$('.pma_sql_import_status div').css('height','270px');
$(this).attr('toggle','on');
$(this).html('-'); // to minimize
} else {
$('.pma_sql_import_status div').css('height','0px');
$(this).attr('toggle','off');
$(this).html('+'); // to maximise
}
});
// closing sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .close', function () {
$('.pma_sql_import_status').fadeOut(function () {
$('.pma_sql_import_status div').html('');
DragDropImport.importStatus = []; // clear the message array
});
});
// Closing the import result box
$(document).on('click', '.pma_drop_result h2 .close', function () {
$(this).parent('h2').parent('div').remove();
});
}

8
js/src/error_report.js Normal file
View File

@ -0,0 +1,8 @@
import ErrorReport from './classes/ErrorReport';
import TraceKit from 'tracekit';
export function onload1 () {
TraceKit.report.subscribe(ErrorReport.error_handler);
ErrorReport.set_up_error_reporting();
ErrorReport.wrap_global_functions();
}

405
js/src/export.js Normal file
View File

@ -0,0 +1,405 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import * as Export from './functions/export';
import { PMA_Messages as messages } from './variables/export_variables';
import CommonParams from './variables/common_params';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
/**
* @package PhpMyAdmin
*
* Export
*/
/**
* Unbind all event handlers before tearing down a page
*/
function teardownExport () {
$('#plugins').off('change');
$('input[type=\'radio\'][name=\'sql_structure_or_data\']').off('change');
$('input[type=\'radio\'][name$=\'_structure_or_data\']').off('change');
$('input[type=\'radio\'][name=\'output_format\']').off('change');
$('#checkbox_sql_include_comments').off('change');
$('input[type=\'radio\'][name=\'quick_or_custom\']').off('change');
$('input[type=\'radio\'][name=\'allrows\']').off('change');
$('#btn_alias_config').off('click');
$('.alias_remove').off('click');
$('#db_alias_button').off('click');
$('#table_alias_button').off('click');
$('#column_alias_button').off('click');
$('input[name="table_select[]"]').off('change');
$('input[name="table_structure[]"]').off('change');
$('input[name="table_data[]"]').off('change');
$('#table_structure_all').off('change');
$('#table_data_all').off('change');
$('input[name="createTemplate"]').off('click');
$('select[name="template"]').off('change');
$('input[name="updateTemplate"]').off('click');
$('input[name="deleteTemplate"]').off('click');
$('form[name=\'dump\']').off('submit');
}
function onloadExportTemplate () {
/**
* Export template handling code
*/
// create a new template
$('input[name="createTemplate"]').on('click', function (e) {
e.preventDefault();
var name = $('input[name="templateName"]').val();
if (name.length) {
Export.createTemplate(name);
}
});
// load an existing template
$('select[name="template"]').on('change', function (e) {
e.preventDefault();
var id = $(this).val();
if (id.length) {
Export.loadTemplate(id);
}
});
// udpate an existing template with new criteria
$('input[name="updateTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
Export.updateTemplate(id);
}
});
// delete an existing template
$('input[name="deleteTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
Export.deleteTemplate(id);
}
});
/**
* Toggles the hiding and showing of each plugin's options
* according to the currently selected plugin from the dropdown list
*/
$('#plugins').on('change', function () {
$('#format_specific_opts').find('div.format_specific_options').hide();
var selectedPluginName = $('#plugins').find('option:selected').val();
$('#' + selectedPluginName + '_options').show();
});
/**
* Toggles the enabling and disabling of the SQL plugin's comment options that apply only when exporting structure
*/
$('input[type=\'radio\'][name=\'sql_structure_or_data\']').on('change', function () {
var commentsArePresent = $('#checkbox_sql_include_comments').prop('checked');
var show = $('input[type=\'radio\'][name=\'sql_structure_or_data\']:checked').val();
if (show === 'data') {
// disable the SQL comment options
if (commentsArePresent) {
$('#checkbox_sql_dates').prop('disabled', true).parent().fadeTo('fast', 0.4);
}
$('#checkbox_sql_relation').prop('disabled', true).parent().fadeTo('fast', 0.4);
$('#checkbox_sql_mime').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
// enable the SQL comment options
if (commentsArePresent) {
$('#checkbox_sql_dates').prop('disabled', false).parent().fadeTo('fast', 1);
}
$('#checkbox_sql_relation').prop('disabled', false).parent().fadeTo('fast', 1);
$('#checkbox_sql_mime').prop('disabled', false).parent().fadeTo('fast', 1);
}
if (show === 'structure') {
$('#checkbox_sql_auto_increment').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$('#checkbox_sql_auto_increment').prop('disabled', false).parent().fadeTo('fast', 1);
}
});
// For separate-file exports only ZIP compression is allowed
$('input[type="checkbox"][name="as_separate_files"]').on('change', function () {
if ($(this).is(':checked')) {
$('#compression').val('zip');
}
});
$('#compression').on('change', function () {
if ($('option:selected').val() !== 'zip') {
$('input[type="checkbox"][name="as_separate_files"]').prop('checked', false);
}
});
// Handle submit of form to export sql
$('form[name=\'dump\']').on('submit', function (e) {
var timeout = $('input[type=\'submit\'][id=\'buttonGo\']').data().timeout;
Export.check_time_out(timeout);
});
}
function onloadSaveToFile () {
Export.toggleSaveToFile();
$('input[type=\'radio\'][name=\'output_format\']').on('change', Export.toggleSaveToFile);
}
function onloadExportOptions () {
/**
* For SQL plugin, if "CREATE TABLE options" is checked/unchecked, check/uncheck each of its sub-options
*/
var $create = $('#checkbox_sql_create_table_statements');
var $createOptions = $('#ul_create_table_statements').find('input');
$create.on('change', function () {
$createOptions.prop('checked', $(this).prop('checked'));
});
$createOptions.on('change', function () {
if ($createOptions.is(':checked')) {
$create.prop('checked', true);
}
});
/**
* Disables the view output as text option if the output must be saved as a file
*/
$('#plugins').on('change', function () {
var activePlugin = $('#plugins').find('option:selected').val();
var forceFile = $('#force_file_' + activePlugin).val();
if (forceFile === 'true') {
if ($('#radio_dump_asfile').prop('checked') !== true) {
$('#radio_dump_asfile').prop('checked', true);
Export.toggleSaveToFile();
}
$('#radio_view_as_text').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$('#radio_view_as_text').prop('disabled', false).parent().fadeTo('fast', 1);
}
});
$('input[type=\'radio\'][name$=\'_structure_or_data\']').on('change', function () {
Export.toggleStructureDataOpts();
});
$('input[name="table_select[]"]').on('change', function () {
Export.toggleTableSelect($(this).closest('tr'));
Export.checkTableSelectAll();
Export.handleAddProcCheckbox();
Export.checkTableSelectStrutureOrData();
});
$('input[name="table_structure[]"]').on('change', function () {
Export.checkTableSelected($(this).closest('tr'));
Export.checkTableSelectAll();
Export.handleAddProcCheckbox();
Export.checkTableSelectStrutureOrData();
});
$('input[name="table_data[]"]').on('change', function () {
Export.checkTableSelected($(this).closest('tr'));
Export.checkTableSelectAll();
Export.handleAddProcCheckbox();
Export.checkTableSelectStrutureOrData();
});
$('#table_structure_all').on('change', function () {
Export.toggleTableSelectAllStr();
Export.checkSelectedTables();
Export.handleAddProcCheckbox();
Export.checkTableSelectStrutureOrData();
});
$('#table_data_all').on('change', function () {
Export.toggleTableSelectAllData();
Export.checkSelectedTables();
Export.handleAddProcCheckbox();
Export.checkTableSelectStrutureOrData();
});
if ($('input[name=\'export_type\']').val() === 'database') {
// Hide structure or data radio buttons
$('input[type=\'radio\'][name$=\'_structure_or_data\']').each(function () {
var $this = $(this);
var name = $this.prop('name');
var val = $('input[name="' + name + '"]:checked').val();
var nameDefault = name + '_default';
if (!$('input[name="' + nameDefault + '"]').length) {
$this
.after(
$('<input type="hidden" name="' + nameDefault + '" value="' + val + '" disabled>')
)
.after(
$('<input type="hidden" name="' + name + '" value="structure_and_data">')
);
$this.parent().find('label').remove();
} else {
$this.parent().remove();
}
});
$('input[type=\'radio\'][name$=\'_structure_or_data\']').remove();
// Disable CREATE table checkbox for sql
var createTableCheckbox = $('#checkbox_sql_create_table');
createTableCheckbox.prop('checked', true);
var dummyCreateTable = $('#checkbox_sql_create_table')
.clone()
.removeAttr('id')
.attr('type', 'hidden');
createTableCheckbox
.prop('disabled', true)
.after(dummyCreateTable)
.parent()
.fadeTo('fast', 0.4);
Export.setupTableStructureOrData();
}
/**
* Handle force structure_or_data
*/
$('#plugins').on('change', Export.setupTableStructureOrData);
}
function onloadExportSubmit () {
$('input[type=\'radio\'][name=\'quick_or_custom\']').on('change', Export.toggleQuickOrCustom);
$('#scroll_to_options_msg').hide();
$('#format_specific_opts').find('div.format_specific_options')
.hide()
.css({
'border': 0,
'margin': 0,
'padding': 0
})
.find('h3')
.remove();
Export.toggleQuickOrCustom();
Export.toggleStructureDataOpts();
Export.toggleSqlIncludeComments();
Export.checkTableSelectAll();
Export.handleAddProcCheckbox();
/**
* Initially disables the "Dump some row(s)" sub-options
*/
Export.disableDumpSomeRowsSubOptions();
/**
* Disables the "Dump some row(s)" sub-options when it is not selected
*/
$('input[type=\'radio\'][name=\'allrows\']').on('change', function () {
if ($('input[type=\'radio\'][name=\'allrows\']').prop('checked')) {
Export.enableDumpSomeRowsSubOptions();
} else {
Export.disableDumpSomeRowsSubOptions();
}
});
// Open Alias Modal Dialog on click
$('#btn_alias_config').on('click', Export.createAliasModal);
$('.alias_remove').on('click', function () {
$(this).parents('tr').remove();
});
$('#db_alias_select').on('change', function () {
Export.aliasToggleRow($(this));
// var db = $(this).val();
var table = CommonParams.get('table');
if (table) {
var option = $('<option></option>');
option.text(table);
option.attr('value', table);
$('#table_alias_select').append(option).val(table).trigger('change');
} else {
var params = {
ajax_request : true,
server : CommonParams.get('server'),
db : $(this).val(),
type: 'list-tables'
};
$.post('ajax.php', params, function (response) {
if (response.success === true) {
$.each(response.tables, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#table_alias_select').append(option);
});
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
});
$('#table_alias_select').on('change', function () {
Export.aliasToggleRow($(this));
var params = {
ajax_request : true,
server : CommonParams.get('server'),
db : $('#db_alias_select').val(),
table: $(this).val(),
type: 'list-columns'
};
$.post('ajax.php', params, function (response) {
if (response.success === true) {
$.each(response.columns, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#column_alias_select').append(option);
});
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
});
$('#column_alias_select').on('change', function () {
Export.aliasToggleRow($(this));
});
$('#db_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
Export.addAlias(
messages.strAliasDatabase,
db,
'aliases[' + db + '][alias]',
$('#db_alias_name').val()
);
$('#db_alias_name').val('');
});
$('#table_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
var table = $('#table_alias_select').val();
Export.addAlias(
messages.strAliasTable,
db + '.' + table,
'aliases[' + db + '][tables][' + table + '][alias]',
$('#table_alias_name').val()
);
$('#table_alias_name').val('');
});
$('#column_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
var table = $('#table_alias_select').val();
var column = $('#column_alias_select').val();
Export.addAlias(
messages.strAliasColumn,
db + '.' + table + '.' + column,
'aliases[' + db + '][tables][' + table + '][colums][' + column + ']',
$('#column_alias_name').val()
);
$('#column_alias_name').val('');
});
}
/**
* Module export
*/
export {
teardownExport,
onloadExportOptions,
onloadExportSubmit,
onloadExportTemplate,
onloadSaveToFile
};

604
js/src/functions.js Normal file
View File

@ -0,0 +1,604 @@
import { AJAX } from './ajax';
import { $ } from './utils/JqueryExtended';
import CommonParams from './variables/common_params';
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import { PMA_prepareForAjaxRequest } from './functions/AjaxRequest';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage } from './utils/show_ajax_messages';
import PMA_MicroHistory from './classes/MicroHistory';
import { PMA_commonActions } from './classes/CommonActions';
// Sql based imports
import { PMA_getSQLEditor, bindCodeMirrorToInlineEditor } from './functions/Sql/SqlEditor';
import { sqlQueryOptions, updateQueryParameters, PMA_highlightSQL } from './utils/sql';
import { PMA_handleSimulateQueryButton, insertQuery, checkSqlQuery } from './functions/Sql/SqlQuery';
import { escapeHtml } from './utils/Sanitise';
import { getForeignKeyCheckboxLoader, loadForeignKeyCheckbox } from './functions/Sql/ForeignKey';
import { PMA_previewSQL } from './functions/Sql/PreviewSql';
// Create Table based imports
import { checkTableEditForm, PMA_checkReservedWordColumns } from './functions/Table/CreateTable';
import { PMA_adjustTotals } from './functions/Database/Structure';
import { PMA_verifyColumnsProperties, PMA_hideShowConnection } from './functions/Table/TableColumns';
import { addDateTimePicker } from './utils/DateTime';
/**
* Here we register a function that will remove the onsubmit event from all
* forms that will be handled by the generic page loader. We then save this
* event handler in the "jQuery data", so that we can fire it up later in
* AJAX.requestHandler().
*
* See bug #3583316
*/
export function onload () {
// Registering the onload event for functions.js
// ensures that it will be fired for all pages
$('form').not('.ajax').not('.disableAjax').each(function () {
if ($(this).attr('onsubmit')) {
$(this).data('onsubmit', this.onsubmit).attr('onsubmit', '');
}
});
var $page_content = $('#page_content');
/**
* Workaround for passing submit button name,value on ajax form submit
* by appending hidden element with submit button name and value.
*/
$page_content.on('click', 'form input[type=submit]', function () {
var buttonName = $(this).attr('name');
if (typeof buttonName === 'undefined') {
return;
}
$(this).closest('form').append($('<input/>', {
'type' : 'hidden',
'name' : buttonName,
'value': $(this).val()
}));
});
/**
* Attach event listener to events when user modify visible
* Input,Textarea and select fields to make changes in forms
*/
$page_content.on(
'keyup change',
'form.lock-page textarea, ' +
'form.lock-page input[type="text"], ' +
'form.lock-page input[type="number"], ' +
'form.lock-page select',
{ value:1 },
AJAX.lockPageHandler
);
$page_content.on(
'change',
'form.lock-page input[type="checkbox"], ' +
'form.lock-page input[type="radio"]',
{ value:2 },
AJAX.lockPageHandler
);
/**
* Reset lock when lock-page form reset event is fired
* Note: reset does not bubble in all browser so attach to
* form directly.
*/
$('form.lock-page').on('reset', function (event) {
AJAX.resetLock();
});
}
/**
* Unbind all event handlers before tearing down a page
*/
export function teardown1 () {
$(document).off('click', 'a.themeselect');
$(document).off('change', '.autosubmit');
$('a.take_theme').off('click');
}
export function onload1 () {
/**
* Theme selector.
*/
$(document).on('click', 'a.themeselect', function (e) {
window.open(
e.target,
'themes',
'left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes'
);
return false;
});
/**
* Automatic form submission on change.
*/
$(document).on('change', '.autosubmit', function (e) {
$(this).closest('form').submit();
});
/**
* Theme changer.
*/
$('a.take_theme').on('click', function (e) {
var what = this.name;
if (window.opener && window.opener.document.forms.setTheme.elements.set_theme) {
window.opener.document.forms.setTheme.elements.set_theme.value = what;
window.opener.document.forms.setTheme.submit();
window.close();
return false;
}
return true;
});
}
/* *************************************** CODEMIRROR EDITOR START *************************************** */
/**
* Attach CodeMirror2 editor to SQL edit area.
*/
export function onloadSqlEditor () {
var $elm = $('#sqlquery');
if ($elm.length > 0) {
if (CommonParams.get('CodemirrorEnable') === true) {
sqlQueryOptions.codemirror_editor = PMA_getSQLEditor($elm);
sqlQueryOptions.codemirror_editor.focus();
sqlQueryOptions.codemirror_editor.on('blur', updateQueryParameters);
} else {
// without codemirror
$elm.focus().on('blur', updateQueryParameters);
}
}
PMA_highlightSQL($('body'));
}
export function teardownSqlEditor () {
if (sqlQueryOptions.codemirror_editor) {
$('#sqlquery').text(sqlQueryOptions.codemirror_editor.getValue());
sqlQueryOptions.codemirror_editor.toTextArea();
sqlQueryOptions.codemirror_editor = false;
}
}
/**
* Unbind all event handlers before tearing down a page
*/
export function teardownSqlInlineEditor () {
$(document).off('click', 'a.inline_edit_sql');
$(document).off('click', 'input#sql_query_edit_save');
$(document).off('click', 'input#sql_query_edit_discard');
$('input.sqlbutton').off('click');
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.off('blur');
} else {
$(document).off('blur', '#sqlquery');
}
$(document).off('change', '#parameterized');
$(document).off('click', 'input.sqlbutton');
$('#sqlquery').off('keydown');
$('#sql_query_edit').off('keydown');
if (sqlQueryOptions.codemirror_inline_editor) {
// Copy the sql query to the text area to preserve it.
$('#sql_query_edit').text(sqlQueryOptions.codemirror_inline_editor.getValue());
$(sqlQueryOptions.codemirror_inline_editor.getWrapperElement()).off('keydown');
sqlQueryOptions.codemirror_inline_editor.toTextArea();
sqlQueryOptions.codemirror_inline_editor = false;
}
if (sqlQueryOptions.codemirror_editor) {
$(sqlQueryOptions.codemirror_editor.getWrapperElement()).off('keydown');
}
}
/**
* Jquery Coding for inline editing SQL_QUERY
*/
export function onloadSqlInlineEditor () {
// If we are coming back to the page by clicking forward button
// of the browser, bind the code mirror to inline query editor.
bindCodeMirrorToInlineEditor();
$(document).on('click', 'a.inline_edit_sql', function () {
if ($('#sql_query_edit').length) {
// An inline query editor is already open,
// we don't want another copy of it
return false;
}
var $form = $(this).prev('form');
var sql_query = $form.find('input[name=\'sql_query\']').val().trim();
var $inner_sql = $(this).parent().prev().find('code.sql');
var old_text = $inner_sql.html();
var new_content = '<textarea name="sql_query_edit" id="sql_query_edit">' + escapeHtml(sql_query) + '</textarea>\n';
new_content += getForeignKeyCheckboxLoader();
new_content += '<input type="submit" id="sql_query_edit_save" class="button btnSave" value="' + PMA_messages.strGo + '"/>\n';
new_content += '<input type="button" id="sql_query_edit_discard" class="button btnDiscard" value="' + PMA_messages.strCancel + '"/>\n';
var $editor_area = $('div#inline_editor');
if ($editor_area.length === 0) {
$editor_area = $('<div id="inline_editor_outer"></div>');
$editor_area.insertBefore($inner_sql);
}
$editor_area.html(new_content);
loadForeignKeyCheckbox();
$inner_sql.hide();
bindCodeMirrorToInlineEditor();
return false;
});
$(document).on('click', 'input#sql_query_edit_save', function (e) {
// hide already existing success message
var sql_query;
if (sqlQueryOptions.codemirror_inline_editor) {
sqlQueryOptions.codemirror_inline_editor.save();
sql_query = sqlQueryOptions.codemirror_inline_editor.getValue();
} else {
sql_query = $(this).parent().find('#sql_query_edit').val();
}
var fk_check = $(this).parent().find('#fk_checks').is(':checked');
var $form = $('a.inline_edit_sql').prev('form');
var $fake_form = $('<form>', { action: 'import.php', method: 'post' })
.append($form.find('input[name=server], input[name=db], input[name=table], input[name=token]').clone())
.append($('<input/>', { type: 'hidden', name: 'show_query', value: 1 }))
.append($('<input/>', { type: 'hidden', name: 'is_js_confirmed', value: 0 }))
.append($('<input/>', { type: 'hidden', name: 'sql_query', value: sql_query }))
.append($('<input/>', { type: 'hidden', name: 'fk_checks', value: fk_check ? 1 : 0 }));
if (! checkSqlQuery($fake_form[0])) {
return false;
}
$('.success').hide();
$fake_form.appendTo($('body')).submit();
});
$(document).on('click', 'input#sql_query_edit_discard', function () {
var $divEditor = $('div#inline_editor_outer');
$divEditor.siblings('code.sql').show();
$divEditor.remove();
});
$(document).on('click', 'input.sqlbutton', function (evt) {
insertQuery(evt.target.id);
PMA_handleSimulateQueryButton();
return false;
});
$(document).on('change', '#parameterized', updateQueryParameters);
var $inputUsername = $('#input_username');
if ($inputUsername) {
if ($inputUsername.val() === '') {
$inputUsername.trigger('focus');
} else {
$('#input_password').trigger('focus');
}
}
}
/* *************************************** CODEMIRROR EDITOR ENDS *************************************** */
/**
* Unbind all event handlers before tearing down a page
*/
export function teardownCtrlEnterFormSubmit () {
$(document).off('keydown', 'form input, form textarea, form select');
}
export function onloadCtrlEnterFormSubmit () {
/**
* Handle 'Ctrl/Alt + Enter' form submits
*/
$('form input, form textarea, form select').on('keydown', function (e) {
if ((e.ctrlKey && e.which === 13) || (e.altKey && e.which === 13)) {
var $form = $(this).closest('form');
if (! $form.find('input[type="submit"]') ||
! $form.find('input[type="submit"]').trigger('click')
) {
$form.submit();
}
}
});
}
/* *************************************** CREATE TABLE STARTS *************************************** */
/**
* Unbind all event handlers before tearing down a page
*/
export function teardownCreateTable () {
$(document).off('submit', '#create_table_form_minimal.ajax');
$(document).off('submit', 'form.create_table_form.ajax');
$(document).off('click', 'form.create_table_form.ajax input[name=submit_num_fields]');
$(document).off('keyup', 'form.create_table_form.ajax input');
$(document).off('change', 'input[name=partition_count],input[name=subpartition_count],select[name=partition_by]');
}
/**
* jQuery coding for 'Create Table'. Used on db_operations.php,
* db_structure.php and db_tracking.php (i.e., wherever
* PhpMyAdmin\Display\CreateTable is used)
*
* Attach Ajax Event handlers for Create Table
*/
export function onloadCreateTable () {
/**
* Attach event handler for submission of create table form (save)
*/
$(document).on('submit', 'form.create_table_form.ajax', function (event) {
event.preventDefault();
/**
* @var the_form object referring to the create table form
*/
var $form = $(this);
/*
* First validate the form; if there is a problem, avoid submitting it
*
* checkTableEditForm() needs a pure element and not a jQuery object,
* this is why we pass $form[0] as a parameter (the jQuery object
* is actually an array of DOM elements)
*/
if (checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) {
PMA_prepareForAjaxRequest($form);
if (PMA_checkReservedWordColumns($form)) {
PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
// User wants to submit the form
$.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$('#properties_message')
.removeClass('error')
.html('');
PMA_ajaxShowMessage(data.message);
// Only if the create table dialog (distinct panel) exists
var $createTableDialog = $('#create_table_dialog');
if ($createTableDialog.length > 0) {
$createTableDialog.dialog('close').remove();
}
$('#tableslistcontainer').before(data.formatted_sql);
/**
* @var tables_table Object referring to the <tbody> element that holds the list of tables
*/
var tables_table = $('#tablesForm').find('tbody').not('#tbl_summary_row');
// this is the first table created in this db
if (tables_table.length === 0) {
PMA_commonActions.refreshMain(
CommonParams.get('opendb_url')
);
} else {
/**
* @var curr_last_row Object referring to the last <tr> element in {@link tables_table}
*/
var curr_last_row = $(tables_table).find('tr:last');
/**
* @var curr_last_row_index_string String containing the index of {@link curr_last_row}
*/
var curr_last_row_index_string = $(curr_last_row).find('input:checkbox').attr('id').match(/\d+/)[0];
/**
* @var curr_last_row_index Index of {@link curr_last_row}
*/
var curr_last_row_index = parseFloat(curr_last_row_index_string);
/**
* @var new_last_row_index Index of the new row to be appended to {@link tables_table}
*/
var new_last_row_index = curr_last_row_index + 1;
/**
* @var new_last_row_id String containing the id of the row to be appended to {@link tables_table}
*/
var new_last_row_id = 'checkbox_tbl_' + new_last_row_index;
data.new_table_string = data.new_table_string.replace(/checkbox_tbl_/, new_last_row_id);
// append to table
$(data.new_table_string)
.appendTo(tables_table);
// Sort the table
$(tables_table).PMA_sort_table('th');
// Adjust summary row
PMA_adjustTotals();
}
// Refresh navigation as a new table has been added
PMA_reloadNavigation();
// Redirect to table structure page on creation of new table
var argsep = CommonParams.get('arg_separator');
var params_12 = 'ajax_request=true' + argsep + 'ajax_page_request=true';
if (! (history && history.pushState)) {
params_12 += PMA_MicroHistory.menus.getRequestParam();
}
var tblStruct_url = 'tbl_structure.php?server=' + data._params.server +
argsep + 'db=' + data._params.db + argsep + 'token=' + data._params.token +
argsep + 'goto=db_structure.php' + argsep + 'table=' + data._params.table + '';
$.get(tblStruct_url, params_12, AJAX.responseHandler);
} else {
PMA_ajaxShowMessage(
'<div class="error">' + data.error + '</div>',
false
);
}
}); // end $.post()
}
} // end if (checkTableEditForm() )
}); // end create table form (save)
/**
* Submits the intermediate changes in the table creation form
* to refresh the UI accordingly
*/
function submitChangesInCreateTableForm (actionParam) {
/**
* @var the_form object referring to the create table form
*/
var $form = $('form.create_table_form.ajax');
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
PMA_prepareForAjaxRequest($form);
// User wants to add more fields to the table
$.post($form.attr('action'), $form.serialize() + '&' + actionParam, function (data) {
if (typeof data !== 'undefined' && data.success) {
var $pageContent = $('#page_content');
$pageContent.html(data.message);
PMA_highlightSQL($pageContent);
PMA_verifyColumnsProperties();
PMA_hideShowConnection($('.create_table_form select[name=tbl_storage_engine]'));
PMA_ajaxRemoveMessage($msgbox);
} else {
PMA_ajaxShowMessage(data.error);
}
}); // end $.post()
}
/**
* Attach event handler for create table form (add fields)
*/
$(document).on('click', 'form.create_table_form.ajax input[name=submit_num_fields]', function (event) {
event.preventDefault();
submitChangesInCreateTableForm('submit_num_fields=1');
}); // end create table form (add fields)
$(document).on('keydown', 'form.create_table_form.ajax input[name=added_fields]', function (event) {
if (event.keyCode === 13) {
event.preventDefault();
event.stopImmediatePropagation();
$(this)
.closest('form')
.find('input[name=submit_num_fields]')
.trigger('click');
}
});
/**
* Attach event handler to manage changes in number of partitions and subpartitions
*/
$(document).on('change', 'input[name=partition_count],input[name=subpartition_count],select[name=partition_by]', function (event) {
var $this = $(this);
var $form = $this.parents('form');
if ($form.is('.create_table_form.ajax')) {
submitChangesInCreateTableForm('submit_partition_change=1');
} else {
$form.submit();
}
});
$(document).on('change', 'input[value=AUTO_INCREMENT]', function () {
if (this.checked) {
var col = /\d/.exec($(this).attr('name'));
col = col[0];
var $selectFieldKey = $('select[name="field_key[' + col + ']"]');
if ($selectFieldKey.val() === 'none_' + col) {
$selectFieldKey.val('primary_' + col).trigger('change');
}
}
});
$('body')
.off('click', 'input.preview_sql')
.on('click', 'input.preview_sql', function () {
var $form = $(this).closest('form');
PMA_previewSQL($form);
});
}
/* *************************************** CREATE TABLE STARTS *************************************** */
/* ************************************** HANDLE CHECKALL CLICK ************************************** */
/**
* True if last click is to check a row.
*/
var last_click_checked = false;
/**
* Zero-based index of last clicked row.
* Used to handle the shift + click event in the code above.
*/
var last_clicked_row = -1;
/**
* Zero-based index of last shift clicked row.
*/
var last_shift_clicked_row = -1;
/**
* Unbind all event handlers before tearing down a page
*/
export function teadownFunctions () {
$(document).off('click', 'input:checkbox.checkall');
}
export function onloadFunctions () {
/**
* Row marking in horizontal mode (use "on" so that it works also for
* next pages reached via AJAX); a tr may have the class noclick to remove
* this behavior.
*/
$(document).on('click', 'input:checkbox.checkall', function (e) {
var $this = $(this);
var $tr = $this.closest('tr');
var $table = $this.closest('table');
if (!e.shiftKey || last_clicked_row === -1) {
// usual click
var $checkbox = $tr.find(':checkbox.checkall');
var checked = $this.prop('checked');
$checkbox.prop('checked', checked).trigger('change');
if (checked) {
$tr.addClass('marked');
} else {
$tr.removeClass('marked');
}
last_click_checked = checked;
// remember the last clicked row
last_clicked_row = last_click_checked ? $table.find('tr:not(.noclick)').index($tr) : -1;
last_shift_clicked_row = -1;
} else {
// handle the shift click
PMA_clearSelection();
var start;
var end;
// clear last shift click result
if (last_shift_clicked_row >= 0) {
if (last_shift_clicked_row >= last_clicked_row) {
start = last_clicked_row;
end = last_shift_clicked_row;
} else {
start = last_shift_clicked_row;
end = last_clicked_row;
}
$tr.parent().find('tr:not(.noclick)')
.slice(start, end + 1)
.removeClass('marked')
.find(':checkbox')
.prop('checked', false)
.trigger('change');
}
// handle new shift click
var curr_row = $table.find('tr:not(.noclick)').index($tr);
if (curr_row >= last_clicked_row) {
start = last_clicked_row;
end = curr_row;
} else {
start = curr_row;
end = last_clicked_row;
}
$tr.parent().find('tr:not(.noclick)')
.slice(start, end)
.addClass('marked')
.find(':checkbox')
.prop('checked', true)
.trigger('change');
// remember the last shift clicked row
last_shift_clicked_row = curr_row;
}
});
addDateTimePicker();
/**
* Add attribute to text boxes for iOS devices (based on bugID: 3508912)
*/
if (navigator.userAgent.match(/(iphone|ipod|ipad)/i)) {
$('input[type=text]').attr('autocapitalize', 'off').attr('autocorrect', 'off');
}
}
/* ************************************** HANDLE CHECKALL CLICK ************************************** */

View File

@ -0,0 +1,11 @@
/**
* Add a hidden field to the form to indicate that this will be an
* Ajax request (only if this hidden field does not exist)
*
* @param $form object the form
*/
export function PMA_prepareForAjaxRequest ($form) {
if (! $form.find('input:hidden').is('#ajax_request_hidden')) {
$form.append('<input type="hidden" id="ajax_request_hidden" name="ajax_request" value="true" />');
}
}

View File

@ -1,11 +1,4 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview Implements the shiftkey + click remove column
* from order by clause funcationality
* @name columndelete
*
* @requires jQuery
*/
import PMA_commonParams from '../variables/common_params';
function captureURL (url) {
var URL = {};
@ -25,7 +18,7 @@ function captureURL (url) {
* @param object parent HTMLDom Object
*/
function removeColumnFromMultiSort (target, parent) {
export function removeColumnFromMultiSort (target, parent) {
var URL = captureURL(target);
var begin = target.indexOf('ORDER+BY') + 8;
var end = target.indexOf(PMA_commonParams.get('arg_separator') + 'session_max_rows');
@ -51,34 +44,6 @@ function removeColumnFromMultiSort (target, parent) {
}
URL.head = URL.head.substring(URL.head.indexOf('?') + 1);
var middle_part = columns.join('%2C+');
params = URL.head + middle_part + URL.tail;
var params = URL.head + middle_part + URL.tail;
return params;
}
AJAX.registerOnload('keyhandler.js', function () {
$('th.draggable.column_heading.pointer.marker a').on('click', function (event) {
var url = $(this).parent().find('input').val();
var argsep = PMA_commonParams.get('arg_separator');
if (event.ctrlKey || event.altKey) {
event.preventDefault();
var params = removeColumnFromMultiSort(url, $(this).parent());
if (params) {
AJAX.source = $(this);
PMA_ajaxShowMessage();
params += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('sql.php', params, AJAX.responseHandler);
}
} else if (event.shiftKey) {
event.preventDefault();
AJAX.source = $(this);
PMA_ajaxShowMessage();
var params = url.substring(url.indexOf('?') + 1);
params += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('sql.php', params, AJAX.responseHandler);
}
});
});
AJAX.registerTeardown('keyhandler.js', function () {
$(document).off('click', 'th.draggable.column_heading.pointer.marker a');
});

View File

@ -0,0 +1,46 @@
import { PMA_messages as PMA_messages } from '../variables//export_variables';
import { PMA_sprintf } from '../utils/sprintf';
import PMA_commonParams from '../variables/common_params';
/**
* Displays a confirmation box before submitting a "DROP/DELETE/ALTER" query.
* This function is called while clicking links
*
* @param theLink object the link
* @param theSqlQuery object the sql query to submit
*
* @return boolean whether to run the query or not
*/
export function confirmLink (theLink, theSqlQuery) {
// Confirmation is not required in the configuration file
// or browser is Opera (crappy js implementation)
if (PMA_messages.strDoYouReally === '' || typeof(window.opera) !== 'undefined') {
return true;
}
var is_confirmed = confirm(PMA_sprintf(PMA_messages.strDoYouReally, theSqlQuery));
if (is_confirmed) {
if (typeof(theLink.href) !== 'undefined') {
theLink.href += PMA_commonParams.get('arg_separator') + 'is_js_confirmed=1';
} else if (typeof(theLink.form) !== 'undefined') {
theLink.form.action += '?is_js_confirmed=1';
}
}
return is_confirmed;
} // end of the 'confirmLink()' function
export function getJSConfirmCommonParam (elem, params) {
var $elem = $(elem);
var sep = PMA_commonParams.get('arg_separator');
if (params) {
// Strip possible leading ?
if (params.substring(0,1) === '?') {
params = params.substr(1);
}
params += sep;
} else {
params = '';
}
params += 'is_js_confirmed=1' + sep + 'ajax_request=true' + sep + 'fk_checks=' + ($elem.find('#fk_checks').is(':checked') ? 1 : 0);
return params;
}

View File

@ -0,0 +1,158 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_Messages as messages } from '../../variables/export_variables';
import { PMA_sprintf } from '../../utils/sprintf';
import { PMA_ajaxShowMessage } from '../../utils/show_ajax_messages';
/**
* Adjust number of rows and total size in the summary
* when truncating, creating, dropping or inserting into a table
*/
export function PMA_adjustTotals () {
var byteUnits = [
messages.strB,
messages.strKiB,
messages.strMiB,
messages.strGiB,
messages.strTiB,
messages.strPiB,
messages.strEiB
];
/**
* @var $allTr jQuery object that references all the rows in the list of tables
*/
var $allTr = $('#tablesForm').find('table.data tbody:first tr');
// New summary values for the table
var tableSum = $allTr.size();
var rowsSum = 0;
var sizeSum = 0;
var overheadSum = 0;
var rowSumApproximated = false;
$allTr.each(function () {
var $this = $(this);
var i;
var tmpVal;
// Get the number of rows for this SQL table
var strRows = $this.find('.tbl_rows').text();
// If the value is approximated
if (strRows.indexOf('~') === 0) {
rowSumApproximated = true;
// The approximated value contains a preceding ~ (Eg 100 --> ~100)
strRows = strRows.substring(1, strRows.length);
}
strRows = strRows.replace(/[,.]/g, '');
var intRow = parseInt(strRows, 10);
if (! isNaN(intRow)) {
rowsSum += intRow;
}
// Extract the size and overhead
var valSize = 0;
var valOverhead = 0;
var strSize = $.trim($this.find('.tbl_size span:not(.unit)').text());
var strSizeUnit = $.trim($this.find('.tbl_size span.unit').text());
var strOverhead = $.trim($this.find('.tbl_overhead span:not(.unit)').text());
var strOverheadUnit = $.trim($this.find('.tbl_overhead span.unit').text());
// Given a value and a unit, such as 100 and KiB, for the table size
// and overhead calculate their numeric values in bytes, such as 102400
for (i = 0; i < byteUnits.length; i++) {
if (strSizeUnit === byteUnits[i]) {
tmpVal = parseFloat(strSize);
valSize = tmpVal * Math.pow(1024, i);
break;
}
}
for (i = 0; i < byteUnits.length; i++) {
if (strOverheadUnit === byteUnits[i]) {
tmpVal = parseFloat(strOverhead);
valOverhead = tmpVal * Math.pow(1024, i);
break;
}
}
sizeSum += valSize;
overheadSum += valOverhead;
});
// Add some commas for readability:
// 1000000 becomes 1,000,000
var strRowSum = rowsSum + '';
var regex = /(\d+)(\d{3})/;
while (regex.test(strRowSum)) {
strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2');
}
// If approximated total value add ~ in front
if (rowSumApproximated) {
strRowSum = '~' + strRowSum;
}
// Calculate the magnitude for the size and overhead values
var size_magnitude = 0;
var overhead_magnitude = 0;
while (sizeSum >= 1024) {
sizeSum /= 1024;
size_magnitude++;
}
while (overheadSum >= 1024) {
overheadSum /= 1024;
overhead_magnitude++;
}
sizeSum = Math.round(sizeSum * 10) / 10;
overheadSum = Math.round(overheadSum * 10) / 10;
// Update summary with new data
var $summary = $('#tbl_summary_row');
$summary.find('.tbl_num').text(PMA_sprintf(messages.strNTables, tableSum));
if (rowSumApproximated) {
$summary.find('.row_count_sum').text(strRowSum);
} else {
$summary.find('.tbl_rows').text(strRowSum);
}
$summary.find('.tbl_size').text(sizeSum + ' ' + byteUnits[size_magnitude]);
$summary.find('.tbl_overhead').text(overheadSum + ' ' + byteUnits[overhead_magnitude]);
}
/**
* Gets the real row count for a table or DB.
* @param object $target Target for appending the real count value.
*/
export function PMA_fetchRealRowCount ($target) {
var $throbber = $('#pma_navigation').find('.throbber')
.first()
.clone()
.css({ visibility: 'visible', display: 'inline-block' })
.on('click', false);
$target.html($throbber);
$.ajax({
type: 'GET',
url: $target.attr('href'),
cache: false,
dataType: 'json',
success: function (response) {
if (response.success) {
// If to update all row counts for a DB.
if (response.real_row_count_all) {
$.each(JSON.parse(response.real_row_count_all),
function (index, table) {
// Update each table row count.
$('table.data td[data-table*="' + table.table + '"]')
.text(table.row_count);
}
);
}
// If to update a particular table's row count.
if (response.real_row_count) {
// Append the parent cell with real row count.
$target.parent().text(response.real_row_count);
}
// Adjust the 'Sum' displayed at the bottom.
PMA_adjustTotals();
} else {
PMA_ajaxShowMessage(messages.strErrorRealRowCount);
}
},
error: function () {
PMA_ajaxShowMessage(messages.strErrorRealRowCount);
}
});
}

View File

@ -0,0 +1,18 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Return value of a cell in a table.
*/
export function PMA_getCellValue (td) {
var $td = $(td);
if ($td.is('.null')) {
return '';
} else if ((! $td.is('.to_be_saved')
|| $td.is('.set'))
&& $td.data('original_data')
) {
return $td.data('original_data');
} else {
return $td.text();
}
}

View File

@ -0,0 +1,43 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Get the field name for the current field. Required to construct the query
* for grid editing
*
* @param $table_results enclosing results table
* @param $this_field jQuery object that points to the current field's tr
*/
export function getFieldName ($table_results, $this_field) {
var this_field_index = $this_field.index();
// ltr or rtl direction does not impact how the DOM was generated
// check if the action column in the left exist
var left_action_exist = !$table_results.find('th:first').hasClass('draggable');
// number of column span for checkbox and Actions
var left_action_skip = left_action_exist ? $table_results.find('th:first').attr('colspan') - 1 : 0;
// If this column was sorted, the text of the a element contains something
// like <small>1</small> that is useful to indicate the order in case
// of a sort on multiple columns; however, we dont want this as part
// of the column name so we strip it ( .clone() to .end() )
var field_name = $table_results
.find('thead')
.find('th:eq(' + (this_field_index - left_action_skip) + ') a')
.clone() // clone the element
.children() // select all the children
.remove() // remove all of them
.end() // go back to the selected element
.text(); // grab the text
// happens when just one row (headings contain no a)
if (field_name === '') {
var $heading = $table_results.find('thead').find('th:eq(' + (this_field_index - left_action_skip) + ')').children('span');
// may contain column comment enclosed in a span - detach it temporarily to read the column name
var $tempColComment = $heading.children().detach();
field_name = $heading.text();
// re-attach the column comment
$heading.append($tempColComment);
}
field_name = $.trim(field_name);
return field_name;
}

View File

@ -0,0 +1,79 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
var prevScrollX = 0;
/*
* Set position, left, top, width of sticky_columns div
*/
function setStickyColumnsPosition ($sticky_columns, $table_results, position, top, left, margin_left) {
$sticky_columns
.css('position', position)
.css('top', top)
.css('left', left ? left : 'auto')
.css('margin-left', margin_left ? margin_left : '0px')
.css('width', $table_results.width());
}
/*
* Initialize sticky columns
*/
export function initStickyColumns ($table_results) {
return $('<table class="sticky_columns"></table>')
.insertBefore($table_results)
.css('position', 'fixed')
.css('z-index', '99')
.css('width', $table_results.width())
.css('margin-left', $('#page_content').css('margin-left'))
.css('top', $('#floating_menubar').height())
.css('display', 'none');
}
/*
* Arrange/Rearrange columns in sticky header
*/
export function rearrangeStickyColumns ($sticky_columns, $table_results) {
var $originalHeader = $table_results.find('thead');
var $originalColumns = $originalHeader.find('tr:first').children();
var $clonedHeader = $originalHeader.clone();
// clone width per cell
$clonedHeader.find('tr:first').children().width(function (i,val) {
var width = $originalColumns.eq(i).width();
var is_firefox = navigator.userAgent.indexOf('Firefox') > -1;
if (! is_firefox) {
width += 1;
}
return width;
});
$sticky_columns.empty().append($clonedHeader);
}
/*
* Adjust sticky columns on horizontal/vertical scroll for all tables
*/
export function handleAllStickyColumns () {
$('.sticky_columns').each(function () {
handleStickyColumns($(this), $(this).next('.table_results'));
});
}
/*
* Adjust sticky columns on horizontal/vertical scroll
*/
export function handleStickyColumns ($sticky_columns, $table_results) {
var currentScrollX = $(window).scrollLeft();
var windowOffset = $(window).scrollTop();
var tableStartOffset = $table_results.offset().top;
var tableEndOffset = tableStartOffset + $table_results.height();
if (windowOffset >= tableStartOffset && windowOffset <= tableEndOffset) {
// for horizontal scrolling
if (prevScrollX !== currentScrollX) {
prevScrollX = currentScrollX;
setStickyColumnsPosition($sticky_columns, $table_results, 'absolute', $('#floating_menubar').height() + windowOffset - tableStartOffset);
// for vertical scrolling
} else {
setStickyColumnsPosition($sticky_columns, $table_results, 'fixed', $('#floating_menubar').height(), $('#pma_navigation').width() - currentScrollX, $('#page_content').css('margin-left'));
}
$sticky_columns.show();
} else {
$sticky_columns.hide();
}
}

View File

@ -1,36 +1,38 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used for index manipulation pages
* @name Table Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
import IndexEnum from '../utils/IndexEnum';
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
import PMA_commonParams from '../variables/common_params';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage, PMA_showHints } from '../utils/show_ajax_messages';
import { PMA_prepareForAjaxRequest } from './AjaxRequest';
import { PMA_highlightSQL } from '../utils/sql';
import { PMA_previewSQL } from './Sql/PreviewSql';
import { PMA_verifyColumnsProperties } from './Table/TableColumns';
import { PMA_sprintf } from '../utils/sprintf';
import { PMA_init_slider } from '../utils/Slider';
import { PMA_reloadNavigation } from './navigation';
/**
* Returns the array of indexes based on the index choice
*
* @param index_choice index choice
*/
function PMA_getIndexArray (index_choice) {
export function PMA_getIndexArray (index_choice) {
var source_array = null;
switch (index_choice.toLowerCase()) {
case 'primary':
source_array = primary_indexes;
source_array = IndexEnum.primary_indexes;
break;
case 'unique':
source_array = unique_indexes;
source_array = IndexEnum.unique_indexes;
break;
case 'index':
source_array = indexes;
source_array = IndexEnum.indexes;
break;
case 'fulltext':
source_array = fulltext_indexes;
source_array = IndexEnum.fulltext_indexes;
break;
case 'spatial':
source_array = spatial_indexes;
source_array = IndexEnum.spatial_indexes;
break;
default:
return null;
@ -42,7 +44,7 @@ function PMA_getIndexArray (index_choice) {
* Hides/shows the inputs and submits appropriately depending
* on whether the index type chosen is 'SPATIAL' or not.
*/
function checkIndexType () {
export function checkIndexType () {
/**
* @var Object Dropdown to select the index choice.
*/
@ -80,7 +82,7 @@ function checkIndexType () {
// Disable and hide the columns of the index other than the first one
var initial = true;
$column_inputs.each(function () {
$column_input = $(this);
var $column_input = $(this);
if (! initial) {
$column_input
.prop('disabled', true)
@ -143,7 +145,7 @@ function PMA_setIndexFormParameters (source_array, index_choice) {
*
* @return void
*/
function PMA_removeColumnFromIndex (col_index) {
export function PMA_removeColumnFromIndex (col_index) {
// Get previous index details.
var previous_index = $('select[name="field_key[' + col_index + ']"]')
.attr('data-index');
@ -295,6 +297,36 @@ function PMA_getCompositeIndexList (source_array, col_index) {
return $composite_index_list;
}
/**
* Ensures indexes names are valid according to their type and, for a primary
* key, lock index name to 'PRIMARY'
* @param string form_id Variable which parses the form name as
* the input
* @return boolean false if there is no index form, true else
*/
export function checkIndexName (form_id) {
if ($('#' + form_id).length === 0) {
return false;
}
// Gets the elements pointers
var $the_idx_name = $('#input_index_name');
var $the_idx_choice = $('#select_index_choice');
// Index is a primary key
if ($the_idx_choice.find('option:selected').val() === 'PRIMARY') {
$the_idx_name.val('PRIMARY');
$the_idx_name.prop('disabled', true);
} else {
if ($the_idx_name.val() === 'PRIMARY') {
$the_idx_name.val('');
}
$the_idx_name.prop('disabled', false);
}
return true;
} // end of the 'checkIndexName()' function
/**
* Shows 'Add Index' dialog.
*
@ -306,7 +338,7 @@ function PMA_getCompositeIndexList (source_array, col_index) {
*
* @return void
*/
function PMA_showAddIndexDialog (source_array, array_index, target_columns, col_index, index) {
export function PMA_showAddIndexDialog (source_array, array_index, target_columns, col_index, index) {
// Prepare post-data.
var $table = $('input[name="table"]');
var table = $table.length > 0 ? $table.val() : '';
@ -418,7 +450,7 @@ function PMA_showAddIndexDialog (source_array, array_index, target_columns, col_
*
* @return void
*/
function PMA_indexTypeSelectionDialog (source_array, index_choice, col_index) {
export function PMA_indexTypeSelectionDialog (source_array, index_choice, col_index) {
var $single_column_radio = $('<input type="radio" id="single_column" name="index_choice"' +
' checked="checked">' +
'<label for="single_column">' + PMA_messages.strCreateSingleColumnIndex + '</label>');
@ -512,244 +544,149 @@ function PMA_indexTypeSelectionDialog (source_array, index_choice, col_index) {
});
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('indexes.js', function () {
$(document).off('click', '#save_index_frm');
$(document).off('click', '#preview_index_frm');
$(document).off('change', '#select_index_choice');
$(document).off('click', 'a.drop_primary_key_index_anchor.ajax');
$(document).off('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax');
$(document).off('click', '#index_frm input[type=submit]');
$('body').off('change', 'select[name*="field_key"]');
$(document).off('click', '.show_index_dialog');
});
/**
* @description <p>Ajax scripts for table index page</p>
*
* Actions ajaxified here:
* <ul>
* <li>Showing/hiding inputs depending on the index type chosen</li>
* <li>create/edit/drop indexes</li>
* </ul>
*/
AJAX.registerOnload('indexes.js', function () {
// Re-initialize variables.
primary_indexes = [];
unique_indexes = [];
indexes = [];
fulltext_indexes = [];
spatial_indexes = [];
// for table creation form
var $engine_selector = $('.create_table_form select[name=tbl_storage_engine]');
if ($engine_selector.length) {
PMA_hideShowConnection($engine_selector);
}
var $form = $('#index_frm');
if ($form.length > 0) {
showIndexEditDialog($form);
}
$(document).on('click', '#save_index_frm', function (event) {
event.preventDefault();
var $form = $('#index_frm');
var argsep = PMA_commonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'do_save_data=1' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
export function showIndexEditDialog ($outer) {
checkIndexType();
checkIndexName('index_frm');
var $indexColumns = $('#index_columns');
$indexColumns.find('td').each(function () {
$(this).css('width', $(this).width() + 'px');
});
$(document).on('click', '#preview_index_frm', function (event) {
event.preventDefault();
PMA_previewSQL($('#index_frm'));
$indexColumns.find('tbody').sortable({
axis: 'y',
containment: $indexColumns.find('tbody'),
tolerance: 'pointer'
});
$(document).on('change', '#select_index_choice', function (event) {
event.preventDefault();
checkIndexType();
checkIndexName('index_frm');
});
/**
* Ajax Event handler for 'Drop Index'
*/
$(document).on('click', 'a.drop_primary_key_index_anchor.ajax', function (event) {
event.preventDefault();
var $anchor = $(this);
/**
* @var $curr_row Object containing reference to the current field's row
*/
var $curr_row = $anchor.parents('tr');
/** @var Number of columns in the key */
var rows = $anchor.parents('td').attr('rowspan') || 1;
/** @var Rows that should be hidden */
var $rows_to_hide = $curr_row;
for (var i = 1, $last_row = $curr_row.next(); i < rows; i++, $last_row = $last_row.next()) {
$rows_to_hide = $rows_to_hide.add($last_row);
}
var question = escapeHtml(
$curr_row.children('td')
.children('.drop_primary_key_index_msg')
.val()
);
$anchor.PMA_confirm(question, $anchor.attr('href'), function (url) {
var $msg = PMA_ajaxShowMessage(PMA_messages.strDroppingPrimaryKeyIndex, false);
var params = getJSConfirmCommonParam(this, $anchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
PMA_ajaxRemoveMessage($msg);
var $table_ref = $rows_to_hide.closest('table');
if ($rows_to_hide.length === $table_ref.find('tbody > tr').length) {
// We are about to remove all rows from the table
$table_ref.hide('medium', function () {
$('div.no_indexes_defined').show('medium');
$rows_to_hide.remove();
});
$table_ref.siblings('div.notice').hide('medium');
} else {
// We are removing some of the rows only
$rows_to_hide.hide('medium', function () {
$(this).remove();
});
}
if ($('.result_query').length) {
$('.result_query').remove();
}
if (data.sql_query) {
$('<div class="result_query"></div>')
.html(data.sql_query)
.prependTo('#structure_content');
PMA_highlightSQL($('#page_content'));
}
PMA_commonActions.refreshMain(false, function () {
$('a.ajax[href^=#indexes]').trigger('click');
});
PMA_reloadNavigation();
} else {
PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}); // end $.PMA_confirm()
}); // end Drop Primary Key/Index
/**
*Ajax event handler for index edit
**/
$(document).on('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax', function (event) {
event.preventDefault();
var url;
var title;
if ($(this).find('a').length === 0) {
// Add index
var valid = checkFormElementInRange(
$(this).closest('form')[0],
'added_fields',
'Column count has to be larger than zero.'
PMA_showHints($outer);
PMA_init_slider();
// Add a slider for selecting how many columns to add to the index
$outer.find('.slider').slider({
animate: true,
value: 1,
min: 1,
max: 16,
slide: function (event, ui) {
$(this).closest('fieldset').find('input[type=submit]').val(
PMA_sprintf(PMA_messages.strAddToIndex, ui.value)
);
if (! valid) {
return;
}
url = $(this).closest('form').serialize();
title = PMA_messages.strAddIndex;
} else {
// Edit index
url = $(this).find('a').attr('href');
if (url.substring(0, 16) === 'tbl_indexes.php?') {
url = url.substring(16, url.length);
}
title = PMA_messages.strEditIndex;
}
url += PMA_commonParams.get('arg_separator') + 'ajax_request=true';
indexEditorDialog(url, title, function () {
// refresh the page using ajax
PMA_commonActions.refreshMain(false, function () {
$('a.ajax[href^=#indexes]').trigger('click');
});
});
});
$('div.add_fields').removeClass('hide');
// focus index size input on column picked
$outer.find('table#index_columns select').on('change', function () {
if ($(this).find('option:selected').val() === '') {
return true;
}
$(this).closest('tr').find('input').focus();
});
// Focus the slider, otherwise it looks nearly transparent
$('a.ui-slider-handle').addClass('ui-state-focus');
// set focus on index name input, if empty
var input = $outer.find('input#input_index_name');
if (! input.val()) {
input.focus();
}
}
export function indexEditorDialog (url, title, callback_success, callback_failure) {
/* Remove the hidden dialogs if there are*/
var $editIndexDialog = $('#edit_index_dialog');
if ($editIndexDialog.length !== 0) {
$editIndexDialog.remove();
}
var $div = $('<div id="edit_index_dialog"></div>');
/**
* Ajax event handler for advanced index creation during table creation
* and column addition.
* @var button_options Object that stores the options
* passed to jQueryUI dialog
*/
$('body').on('change', 'select[name*="field_key"]', function () {
// Index of column on Table edit and create page.
var col_index = /\d+/.exec($(this).attr('name'));
col_index = col_index[0];
// Choice of selected index.
var index_choice = /[a-z]+/.exec($(this).val());
index_choice = index_choice[0];
// Array containing corresponding indexes.
var source_array = null;
if (index_choice === 'none') {
PMA_removeColumnFromIndex(col_index);
return false;
}
// Select a source array.
source_array = PMA_getIndexArray(index_choice);
if (source_array === null) {
return;
}
if (source_array.length === 0) {
var index = {
'Key_name': (index_choice === 'primary' ? 'PRIMARY' : ''),
'Index_choice': index_choice.toUpperCase()
};
PMA_showAddIndexDialog(source_array, 0, [col_index], col_index, index);
} else {
if (index_choice === 'primary') {
var array_index = 0;
var source_length = source_array[array_index].columns.length;
var target_columns = [];
for (var i = 0; i < source_length; i++) {
target_columns.push(source_array[array_index].columns[i].col_index);
}
target_columns.push(col_index);
PMA_showAddIndexDialog(source_array, array_index, target_columns, col_index,
source_array[array_index]);
} else {
// If there are multiple columns selected for an index, show advanced dialog.
PMA_indexTypeSelectionDialog(source_array, index_choice, col_index);
var button_options = {};
button_options[PMA_messages.strGo] = function () {
/**
* @var the_form object referring to the export form
*/
var $form = $('#index_frm');
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
PMA_prepareForAjaxRequest($form);
// User wants to submit the form
$.post($form.attr('action'), $form.serialize() + PMA_commonParams.get('arg_separator') + 'do_save_data=1', function (data) {
var $sqlqueryresults = $('.sqlqueryresults');
if ($sqlqueryresults.length !== 0) {
$sqlqueryresults.remove();
}
if (typeof data !== 'undefined' && data.success === true) {
PMA_ajaxShowMessage(data.message);
var $resultQuery = $('.result_query');
if ($resultQuery.length) {
$resultQuery.remove();
}
if (data.sql_query) {
$('<div class="result_query"></div>')
.html(data.sql_query)
.prependTo('#page_content');
PMA_highlightSQL($('#page_content'));
}
$('.result_query .notice').remove();
$resultQuery.prepend(data.message);
/* Reload the field form*/
$('#table_index').remove();
$('<div id=\'temp_div\'><div>')
.append(data.index_table)
.find('#table_index')
.insertAfter('#index_header');
var $editIndexDialog = $('#edit_index_dialog');
if ($editIndexDialog.length > 0) {
$editIndexDialog.dialog('close');
}
$('div.no_indexes_defined').hide();
if (callback_success) {
callback_success();
}
PMA_reloadNavigation();
} else {
var $temp_div = $('<div id=\'temp_div\'><div>').append(data.error);
var $error;
if ($temp_div.find('.error code').length !== 0) {
$error = $temp_div.find('.error code').addClass('error');
} else {
$error = $temp_div;
}
if (callback_failure) {
callback_failure();
}
PMA_ajaxShowMessage($error, false);
}
}); // end $.post()
};
button_options[PMA_messages.strPreviewSQL] = function () {
// Function for Previewing SQL
var $form = $('#index_frm');
PMA_previewSQL($form);
};
button_options[PMA_messages.strCancel] = function () {
$(this).dialog('close');
};
var $msgbox = PMA_ajaxShowMessage();
$.get('tbl_indexes.php', url, function (data) {
if (typeof data !== 'undefined' && data.success === false) {
// in the case of an error, show the error message returned.
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxRemoveMessage($msgbox);
// Show dialog if the request was successful
$div
.append(data.message)
.dialog({
title: title,
width: 'auto',
open: PMA_verifyColumnsProperties,
modal: true,
buttons: button_options,
close: function () {
$(this).remove();
}
});
$div.find('.tblFooters').remove();
showIndexEditDialog($div);
}
});
$(document).on('click', '.show_index_dialog', function (e) {
e.preventDefault();
// Get index details.
var previous_index = $(this).prev('select')
.attr('data-index')
.split(',');
var index_choice = previous_index[0];
var array_index = previous_index[1];
var source_array = PMA_getIndexArray(index_choice);
var source_length = source_array[array_index].columns.length;
var target_columns = [];
for (var i = 0; i < source_length; i++) {
target_columns.push(source_array[array_index].columns[i].col_index);
}
PMA_showAddIndexDialog(source_array, array_index, target_columns, -1, source_array[array_index]);
});
$('#index_frm').on('submit', function () {
if (typeof(this.elements['index[Key_name]'].disabled) !== 'undefined') {
this.elements['index[Key_name]'].disabled = false;
}
});
});
}); // end $.get()
}

View File

@ -8,7 +8,7 @@ var ctrlKeyHistory = 0;
*
* @param object event data
*/
function onKeyDownArrowsHandler (e) {
export function onKeyDownArrowsHandler (e) {
e = e || window.event;
var o = (e.srcElement || e.target);
@ -71,7 +71,7 @@ function onKeyDownArrowsHandler (e) {
return;
}
var is_firefox = navigator.userAgent.toLowerCase().indexOf('firefox/') > -1;
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox/') > -1;
var id = 'field_' + y + '_' + x;
@ -92,12 +92,12 @@ function onKeyDownArrowsHandler (e) {
nO.focus();
if (is_firefox) {
if (isFirefox) {
var ffcheck = 0;
var ffversion;
for (ffversion = 3 ; ffversion < 25 ; ffversion++) {
var is_firefox_v_24 = navigator.userAgent.toLowerCase().indexOf('firefox/' + ffversion) > -1;
if (is_firefox_v_24) {
var isFirefoxV24 = navigator.userAgent.toLowerCase().indexOf('firefox/' + ffversion) > -1;
if (isFirefoxV24) {
ffcheck = 1;
break;
}
@ -124,17 +124,3 @@ function onKeyDownArrowsHandler (e) {
}
e.returnValue = false;
}
AJAX.registerTeardown('keyhandler.js', function () {
$(document).off('keydown keyup', '#table_columns');
$(document).off('keydown keyup', 'table.insertRowTable');
});
AJAX.registerOnload('keyhandler.js', function () {
$(document).on('keydown keyup', '#table_columns', function (event) {
onKeyDownArrowsHandler(event.originalEvent);
});
$(document).on('keydown keyup', 'table.insertRowTable', function (event) {
onKeyDownArrowsHandler(event.originalEvent);
});
});

47
js/src/functions/Print.js Normal file
View File

@ -0,0 +1,47 @@
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
/**
* Produce print preview
*/
export function printPreview () {
$('#printcss').attr('media','all');
createPrintAndBackButtons();
}
/**
* Create print and back buttons in preview page
*/
function createPrintAndBackButtons () {
var back_button = $('<input/>',{
type: 'button',
value: PMA_messages.back,
id: 'back_button_print_view'
});
back_button.on('click', removePrintAndBackButton);
back_button.appendTo('#page_content');
var print_button = $('<input/>',{
type: 'button',
value: PMA_messages.print,
id: 'print_button_print_view'
});
print_button.on('click', printPage);
print_button.appendTo('#page_content');
}
/**
* Remove print and back buttons and revert to normal view
*/
function removePrintAndBackButton () {
$('#printcss').attr('media','print');
$('#back_button_print_view').remove();
$('#print_button_print_view').remove();
}
/**
* Print page
*/
function printPage () {
if (typeof(window.print) !== 'undefined') {
window.print();
}
}

View File

@ -0,0 +1,144 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_Messages as messages } from '../../variables/export_variables';
/**
* @param {string} serverOs Type of operating system
*
* @param {Object} presetCharts Charts already set
*/
export function getOsDetail (serverOs, presetCharts) {
/* Add OS specific system info charts to the preset chart list */
switch (serverOs) {
case 'WINNT':
$.extend(presetCharts, {
'cpu': {
title: messages.strSystemCPUUsage,
series: [{
label: messages.strAverageLoad
}],
nodes: [{
dataPoints: [{ type: 'cpu', name: 'loadavg' }]
}],
maxYLabel: 100
},
'memory': {
title: messages.strSystemMemory,
series: [{
label: messages.strTotalMemory,
fill: true
}, {
dataType: 'memory',
label: messages.strUsedMemory,
fill: true
}],
nodes: [{ dataPoints: [{ type: 'memory', name: 'MemTotal' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: messages.strSystemSwap,
series: [{
label: messages.strTotalSwap,
fill: true
}, {
label: messages.strUsedSwap,
fill: true
}],
nodes: [{ dataPoints: [{ type: 'memory', name: 'SwapTotal' }] },
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }] }
],
maxYLabel: 0
}
});
break;
case 'Linux':
$.extend(presetCharts, {
'cpu': {
title: messages.strSystemCPUUsage,
series: [{
label: messages.strAverageLoad
}],
nodes: [{ dataPoints: [{ type: 'cpu', name: 'irrelevant' }], transformFn: 'cpu-linux' }],
maxYLabel: 0
},
'memory': {
title: messages.strSystemMemory,
series: [
{ label: messages.strBufferedMemory, fill: true },
{ label: messages.strUsedMemory, fill: true },
{ label: messages.strCachedMemory, fill: true },
{ label: messages.strFreeMemory, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'Buffers' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'Cached' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: messages.strSystemSwap,
series: [
{ label: messages.strCachedSwap, fill: true },
{ label: messages.strUsedSwap, fill: true },
{ label: messages.strFreeSwap, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'SwapCached' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
}
});
break;
case 'SunOS':
$.extend(presetCharts, {
'cpu': {
title: messages.strSystemCPUUsage,
series: [{
label: messages.strAverageLoad
}],
nodes: [{
dataPoints: [{ type: 'cpu', name: 'loadavg' }]
}],
maxYLabel: 0
},
'memory': {
title: messages.strSystemMemory,
series: [
{ label: messages.strUsedMemory, fill: true },
{ label: messages.strFreeMemory, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
},
'swap': {
title: messages.strSystemSwap,
series: [
{ label: messages.strUsedSwap, fill: true },
{ label: messages.strFreeSwap, fill: true }
],
nodes: [
{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 },
{ dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }
],
maxYLabel: 0
}
});
break;
}
}

View File

@ -0,0 +1,43 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from '../../utils/JqueryExtended';
import '../../plugins/jquery/jquery.tablesorter';
// TODO: tablesorter shouldn't sort already sorted columns
/**
* @access public
*
* @param {string} tabid Table id for chart drawing
*
* @return {void}
*/
function initTableSorter (tabid) {
var $table;
var opts;
switch (tabid) {
case 'statustabs_queries':
$table = $('#serverstatusqueriesdetails');
opts = {
sortList: [[3, 1]],
headers: {
1: { sorter: 'fancyNumber' },
2: { sorter: 'fancyNumber' }
}
};
break;
}
$table.tablesorter(opts);
$table.find('tr:first th')
.append('<div class="sorticon"></div>')
.addClass('header');
}
/**
* Module export
*/
export {
initTableSorter
};

View File

@ -0,0 +1,63 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Filters the status variables by name/category/alert in the variables tab
*
* @access public
*
* @param {Object} textFilter Regular expression for filtering text
*
* @param {boolean} alertFilter For filtering alert variables
*
* @param {string} categoryFilter
*
* @param {string} text Text based filtering
*/
function filterVariables (
textFilter,
alertFilter,
categoryFilter,
text
) {
var usefulLinks = 0;
var section = text;
if (categoryFilter.length > 0) {
section = categoryFilter;
}
if (section.length > 1) {
$('#linkSuggestions').find('span').each(function () {
if ($(this).attr('class').indexOf('status_' + section) !== -1) {
usefulLinks++;
$(this).css('display', '');
} else {
$(this).css('display', 'none');
}
});
}
if (usefulLinks > 0) {
$('#linkSuggestions').css('display', '');
} else {
$('#linkSuggestions').css('display', 'none');
}
$('#serverstatusvariables').find('th.name').each(function () {
if ((textFilter === null || textFilter.exec($(this).text())) &&
(! alertFilter || $(this).next().find('span.attention').length > 0) &&
(categoryFilter.length === 0 || $(this).parent().hasClass('s_' + categoryFilter))
) {
$(this).parent().css('display', '');
} else {
$(this).parent().css('display', 'none');
}
});
}
/**
* Module export
*/
export {
filterVariables
};

View File

@ -0,0 +1,114 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_Messages as messages } from '../../variables/export_variables';
import {
PMA_ajaxShowMessage,
PMA_ajaxRemoveMessage
} from '../../utils/show_ajax_messages';
/**
* Allows the user to edit a server variable
*
* @param {Element} link Edit button element
*
* @param {Element} $saveLink Save button element
*
* @param {Element} $cancelLink Cancel button element
*
* @return {void}
*/
function editVariable (link, $saveLink, $cancelLink) {
var $link = $(link);
var $cell = $link.parent();
var $valueCell = $link.parents('.var-row').find('.var-value');
var varName = $link.data('variable');
var $mySaveLink = $saveLink.clone().css('display', 'inline-block');
var $myCancelLink = $cancelLink.clone().css('display', 'inline-block');
var $msgbox = PMA_ajaxShowMessage();
var $myEditLink = $cell.find('a.editLink');
$cell.addClass('edit'); // variable is being edited
$myEditLink.remove(); // remove edit link
$mySaveLink.on('click', function () {
var $msgbox = PMA_ajaxShowMessage(messages.strProcessingRequest);
$.post($(this).attr('href'), {
ajax_request: true,
type: 'setval',
varName: varName,
varValue: $valueCell.find('input').val()
}, function (data) {
if (data.success) {
$valueCell
.html(data.variable)
.data('content', data.variable);
PMA_ajaxRemoveMessage($msgbox);
} else {
if (data.error === '') {
PMA_ajaxShowMessage(messages.strRequestFailed, false);
} else {
PMA_ajaxShowMessage(data.error, false);
}
$valueCell.html($valueCell.data('content'));
}
$cell.removeClass('edit').html($myEditLink);
});
return false;
});
$myCancelLink.on('click', function () {
$valueCell.html($valueCell.data('content'));
$cell.removeClass('edit').html($myEditLink);
return false;
});
$.get($mySaveLink.attr('href'), {
ajax_request: true,
type: 'getval',
varName: varName
}, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
var $links = $('<div />')
.append($myCancelLink)
.append('&nbsp;&nbsp;&nbsp;')
.append($mySaveLink);
var $editor = $('<div />', { 'class': 'serverVariableEditor' })
.append(
$('<div/>').append(
$('<input />', { type: 'text' }).val(data.message)
)
);
// Save and replace content
$cell
.html($links)
.children()
.css('display', 'flex');
$valueCell
.data('content', $valueCell.html())
.html($editor)
.find('input')
.focus()
.on('keydown', function (event) { // Keyboard shortcuts
if (event.keyCode === 13) { // Enter key
$mySaveLink.trigger('click');
} else if (event.keyCode === 27) { // Escape key
$myCancelLink.trigger('click');
}
});
PMA_ajaxRemoveMessage($msgbox);
} else {
$cell.removeClass('edit').html($myEditLink);
PMA_ajaxShowMessage(data.error);
}
});
}
/**
* Module export
*/
export {
editVariable
};

View File

@ -0,0 +1,49 @@
import { PMA_getImage } from '../get_image';
import PMA_commonParams from '../../variables/common_params';
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
/**
* Get checkbox for foreign key checks
*
* @return string
*/
export function getForeignKeyCheckboxLoader () {
var html = '';
html += '<div>';
html += '<div class="load-default-fk-check-value">';
html += PMA_getImage('ajax_clock_small');
html += '</div>';
html += '</div>';
return html;
}
export function loadForeignKeyCheckbox () {
// Load default foreign key check value
var params = {
'ajax_request': true,
'server': PMA_commonParams.get('server'),
'get_default_fk_check_value': true
};
$.get('sql.php', params, function (data) {
var html = '<input type="hidden" name="fk_checks" value="0" />' +
'<input type="checkbox" name="fk_checks" id="fk_checks"' +
(data.default_fk_check_value ? ' checked="checked"' : '') + ' />' +
'<label for="fk_checks">' + PMA_messages.strForeignKeyCheck + '</label>';
$('.load-default-fk-check-value').replaceWith(html);
});
}
export function getJSConfirmCommonParam (elem, params) {
var $elem = $(elem);
var sep = PMA_commonParams.get('arg_separator');
if (params) {
// Strip possible leading ?
if (params.substring(0,1) === '?') {
params = params.substr(1);
}
params += sep;
} else {
params = '';
}
params += 'is_js_confirmed=1' + sep + 'ajax_request=true' + sep + 'fk_checks=' + ($elem.find('#fk_checks').is(':checked') ? 1 : 0);
return params;
}

View File

@ -0,0 +1,54 @@
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
import PMA_commonParams from '../../variables/common_params';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage } from '../../utils/show_ajax_messages';
/**
* Requests SQL for previewing before executing.
*
* @param jQuery Object $form Form containing query data
*
* @return void
*/
export function PMA_previewSQL ($form) {
var form_url = $form.attr('action');
var sep = PMA_commonParams.get('arg_separator');
var form_data = $form.serialize() +
sep + 'do_save_data=1' +
sep + 'preview_sql=1' +
sep + 'ajax_request=1';
var $msgbox = PMA_ajaxShowMessage();
$.ajax({
type: 'POST',
url: form_url,
data: form_data,
success: function (response) {
PMA_ajaxRemoveMessage($msgbox);
if (response.success) {
var $dialog_content = $('<div/>')
.append(response.sql_data);
var button_options = {};
button_options[PMA_messages.strClose] = function () {
$(this).dialog('close');
};
var $response_dialog = $dialog_content.dialog({
minWidth: 550,
maxHeight: 400,
modal: true,
buttons: button_options,
title: PMA_messages.strPreviewSQL,
close: function () {
$(this).remove();
},
open: function () {
// Pretty SQL printing.
PMA_highlightSQL($(this));
}
});
} else {
PMA_ajaxShowMessage(response.message);
}
},
error: function () {
PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest);
}
});
}

View File

@ -0,0 +1,117 @@
import { sqlQueryOptions } from '../../utils/sql';
import CommonParams from '../../variables/common_params';
import { AJAX } from '../../ajax';
import { codemirrorAutocompleteOnInputRead } from '../../utils/sql';
import CodeMirror from 'codemirror';
import 'codemirror/mode/sql/sql.js';
import 'codemirror/addon/runmode/runmode.js';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/sql-hint.js';
import 'codemirror/addon/lint/lint.js';
import '../../plugins/codemirror/sql-lint';
function catchKeypressesFromSqlInlineEdit (event) {
// ctrl-enter is 10 in chrome and ie, but 13 in ff
if ((event.ctrlKey || event.metaKey) && (event.keyCode === 13 || event.keyCode === 10)) {
$('#sql_query_edit_save').trigger('click');
}
}
/**
* Creates an SQL editor which supports auto completing etc.
*
* @param $textarea jQuery object wrapping the textarea to be made the editor
* @param options optional options for CodeMirror
* @param resize optional resizing ('vertical', 'horizontal', 'both')
* @param lintOptions additional options for lint
*/
export function PMA_getSQLEditor ($textarea, options, resize, lintOptions) {
if ($textarea.length > 0 && CommonParams.get('CodemirrorEnable') === true) {
// merge options for CodeMirror
var defaults = {
lineNumbers: true,
matchBrackets: true,
extraKeys: { 'Ctrl-Space': 'autocomplete' },
hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true },
indentUnit: 4,
mode: 'text/x-mysql',
lineWrapping: true
};
if (CommonParams.get('LintEnable')) {
$.extend(defaults, {
gutters: ['CodeMirror-lint-markers'],
lint: {
'getAnnotations': CodeMirror.sqlLint,
'async': true,
'lintOptions': lintOptions
}
});
}
$.extend(true, defaults, options);
// create CodeMirror editor
var codemirrorEditor = CodeMirror.fromTextArea($textarea[0], defaults);
// allow resizing
if (! resize) {
resize = 'vertical';
}
var handles = '';
if (resize === 'vertical') {
handles = 's';
}
if (resize === 'both') {
handles = 'all';
}
if (resize === 'horizontal') {
handles = 'e, w';
}
$(codemirrorEditor.getWrapperElement())
.css('resize', resize)
.resizable({
handles: handles,
resize: function () {
codemirrorEditor.setSize($(this).width(), $(this).height());
}
});
// enable autocomplete
codemirrorEditor.on('inputRead', codemirrorAutocompleteOnInputRead);
// page locking
codemirrorEditor.on('change', function (e) {
e.data = {
value: 3,
content: codemirrorEditor.isClean(),
};
AJAX.lockPageHandler(e);
});
return codemirrorEditor;
}
return null;
}
/**
* Binds the CodeMirror to the text area used to inline edit a query.
*/
export function bindCodeMirrorToInlineEditor () {
var $inline_editor = $('#sql_query_edit');
if ($inline_editor.length > 0) {
if (CommonParams.get('CodemirrorEnable') === true) {
var height = $inline_editor.css('height');
sqlQueryOptions.codemirror_inline_editor = PMA_getSQLEditor($inline_editor);
sqlQueryOptions.codemirror_inline_editor.getWrapperElement().style.height = height;
sqlQueryOptions.codemirror_inline_editor.refresh();
sqlQueryOptions.codemirror_inline_editor.focus();
$(sqlQueryOptions.codemirror_inline_editor.getWrapperElement())
.on('keydown', catchKeypressesFromSqlInlineEdit);
} else {
$inline_editor
.focus()
.on('keydown', catchKeypressesFromSqlInlineEdit);
}
}
}

View File

@ -0,0 +1,59 @@
import { createProfilingChart } from '../chart';
import { $ } from '../../utils/JqueryExtended';
import '../../plugins/jquery/jquery.tablesorter';
/*
* Profiling Chart
*/
export function makeProfilingChart () {
if ($('#profilingchart').length === 0 ||
$('#profilingchart').html().length !== 0 ||
!$.jqplot || !$.jqplot.Highlighter || !$.jqplot.PieRenderer
) {
return;
}
var data = [];
$.each(JSON.parse($('#profilingChartData').html()), function (key, value) {
data.push([key, parseFloat(value)]);
});
// Remove chart and data divs contents
$('#profilingchart').html('').show();
$('#profilingChartData').html('');
createProfilingChart('profilingchart', data);
}
/*
* initialize profiling data tables
*/
export function initProfilingTables () {
if (!$.tablesorter) {
return;
}
$('#profiletable').tablesorter({
widgets: ['zebra'],
sortList: [[0, 0]],
textExtraction: function (node) {
if (node.children.length > 0) {
return node.children[0].innerHTML;
} else {
return node.innerHTML;
}
}
});
$('#profilesummarytable').tablesorter({
widgets: ['zebra'],
sortList: [[1, 1]],
textExtraction: function (node) {
if (node.children.length > 0) {
return node.children[0].innerHTML;
} else {
return node.innerHTML;
}
}
});
}

View File

@ -0,0 +1,371 @@
import { isStorageSupported } from '../config';
import Cookies from 'js-cookie';
import { sqlQueryOptions } from '../../utils/sql';
import { GlobalVariables, PMA_Messages as PMA_messages } from '../../variables/export_variables';
import { PMA_ajaxShowMessage } from '../../utils/show_ajax_messages';
import { PMA_sprintf } from '../../utils/sprintf';
/**
* Handles 'Simulate query' button on SQL query box.
*
* @return void
*/
export function PMA_handleSimulateQueryButton () {
var update_re = new RegExp('^\\s*UPDATE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+SET\\s', 'i');
var delete_re = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
var query = '';
if (sqlQueryOptions.codemirror_editor) {
query = sqlQueryOptions.codemirror_editor.getValue();
} else {
query = $('#sqlquery').val();
}
var $simulateDml = $('#simulate_dml');
if (update_re.test(query) || delete_re.test(query)) {
if (! $simulateDml.length) {
$('#button_submit_query')
.before('<input type="button" id="simulate_dml"' +
'tabindex="199" value="' +
PMA_messages.strSimulateDML +
'" />');
}
} else {
if ($simulateDml.length) {
$simulateDml.remove();
}
}
}
/**
* Sets current value for query box.
*/
export function setQuery (query) {
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.setValue(query);
sqlQueryOptions.codemirror_editor.focus();
} else if (document.sqlform) {
document.sqlform.sql_query.value = query;
document.sqlform.sql_query.focus();
}
}
/**
* Create quick sql statements.
*
*/
export function insertQuery (queryType) {
if (queryType === 'clear') {
setQuery('');
return;
} else if (queryType === 'format') {
if (sqlQueryOptions.codemirror_editor) {
$('#querymessage').html(PMA_messages.strFormatting +
'&nbsp;<img class="ajaxIcon" src="' +
GlobalVariables.pmaThemeImage + 'ajax_clock_small.gif" alt="">');
var href = 'db_sql_format.php';
var params = {
'ajax_request': true,
'sql': sqlQueryOptions.codemirror_editor.getValue()
};
$.ajax({
type: 'POST',
url: href,
data: params,
success: function (data) {
if (data.success) {
sqlQueryOptions.codemirror_editor.setValue(data.sql);
}
$('#querymessage').html('');
}
});
}
return;
} else if (queryType === 'saved') {
if (isStorageSupported('localStorage')
&& typeof window.localStorage.auto_saved_sql !== 'undefined'
) {
setQuery(window.localStorage.auto_saved_sql);
} else if (Cookies.get('auto_saved_sql')) {
setQuery(Cookies.get('auto_saved_sql'));
} else {
PMA_ajaxShowMessage(PMA_messages.strNoAutoSavedQuery);
}
return;
}
var query = '';
var myListBox = document.sqlform.dummy;
var table = document.sqlform.table.value;
if (myListBox.options.length > 0) {
sql_box_locked = true;
var columnsList = '';
var valDis = '';
var editDis = '';
var NbSelect = 0;
for (var i = 0; i < myListBox.options.length; i++) {
NbSelect++;
if (NbSelect > 1) {
columnsList += ', ';
valDis += ',';
editDis += ',';
}
columnsList += myListBox.options[i].value;
valDis += '[value-' + NbSelect + ']';
editDis += myListBox.options[i].value + '=[value-' + NbSelect + ']';
}
if (queryType === 'selectall') {
query = 'SELECT * FROM `' + table + '` WHERE 1';
} else if (queryType === 'select') {
query = 'SELECT ' + columnsList + ' FROM `' + table + '` WHERE 1';
} else if (queryType === 'insert') {
query = 'INSERT INTO `' + table + '`(' + columnsList + ') VALUES (' + valDis + ')';
} else if (queryType === 'update') {
query = 'UPDATE `' + table + '` SET ' + editDis + ' WHERE 1';
} else if (queryType === 'delete') {
query = 'DELETE FROM `' + table + '` WHERE 0';
}
setQuery(query);
sql_box_locked = false;
}
}
/**
* Confirms a "DROP/DELETE/ALTER" query before
* submitting it if required.
* This function is called by the 'checkSqlQuery()' js function.
*
* @param theForm1 object the form
* @param sqlQuery1 string the sql query string
*
* @return boolean whether to run the query or not
*
* @see checkSqlQuery()
*/
function confirmQuery (theForm1, sqlQuery1) {
// Confirmation is not required in the configuration file
if (PMA_messages.strDoYouReally === '') {
return true;
}
// Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement
//
// TODO: find a way (if possible) to use the parser-analyser
// for this kind of verification
// For now, I just added a ^ to check for the statement at
// beginning of expression
var do_confirm_re_0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|PROCEDURE)\\s', 'i');
var do_confirm_re_1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
var do_confirm_re_2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
var do_confirm_re_3 = new RegExp('^\\s*TRUNCATE\\s', 'i');
if (do_confirm_re_0.test(sqlQuery1) ||
do_confirm_re_1.test(sqlQuery1) ||
do_confirm_re_2.test(sqlQuery1) ||
do_confirm_re_3.test(sqlQuery1)) {
var message;
if (sqlQuery1.length > 100) {
message = sqlQuery1.substr(0, 100) + '\n ...';
} else {
message = sqlQuery1;
}
var is_confirmed = confirm(PMA_sprintf(PMA_messages.strDoYouReally, message));
// statement is confirmed -> update the
// "is_js_confirmed" form field so the confirm test won't be
// run on the server side and allows to submit the form
if (is_confirmed) {
theForm1.elements.is_js_confirmed.value = 1;
return true;
} else {
// statement is rejected -> do not submit the form
window.focus();
return false;
} // end if (handle confirm box result)
} // end if (display confirm box)
return true;
} // end of the 'confirmQuery()' function
/**
* Displays an error message if the user submitted the sql query form with no
* sql query, else checks for "DROP/DELETE/ALTER" statements
*
* @param theForm object the form
*
* @return boolean always false
*
* @see confirmQuery()
*/
export function checkSqlQuery (theForm) {
// get the textarea element containing the query
var sqlQuery;
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.save();
sqlQuery = sqlQueryOptions.codemirror_editor.getValue();
} else {
sqlQuery = theForm.elements.sql_query.value;
}
var space_re = new RegExp('\\s+');
if (typeof(theForm.elements.sql_file) !== 'undefined' &&
theForm.elements.sql_file.value.replace(space_re, '') !== '') {
return true;
}
if (typeof(theForm.elements.id_bookmark) !== 'undefined' &&
(theForm.elements.id_bookmark.value !== null || theForm.elements.id_bookmark.value !== '') &&
theForm.elements.id_bookmark.selectedIndex !== 0) {
return true;
}
var result = false;
// Checks for "DROP/DELETE/ALTER" statements
if (sqlQuery.replace(space_re, '') !== '') {
result = confirmQuery(theForm, sqlQuery);
} else {
alert(PMA_messages.strFormEmpty);
}
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.focus();
} else if (sqlQueryOptions.codemirror_inline_editor) {
sqlQueryOptions.codemirror_inline_editor.focus();
}
return result;
} // end of the 'checkSqlQuery()' function
export function checkSavedQuery () {
if (isStorageSupported('localStorage')
&& window.localStorage.auto_saved_sql !== undefined
) {
PMA_ajaxShowMessage(PMA_messages.strPreviousSaveQuery);
}
}
/**
* Set query to codemirror if show this query is
* checked and query for the db and table pair exists
*/
export function setShowThisQuery () {
var db = $('input[name="db"]').val();
var table = $('input[name="table"]').val();
if (isStorageSupported('localStorage')) {
if (window.localStorage.show_this_query_object !== undefined) {
var stored_db = JSON.parse(window.localStorage.show_this_query_object).db;
var stored_table = JSON.parse(window.localStorage.show_this_query_object).table;
var stored_query = JSON.parse(window.localStorage.show_this_query_object).query;
}
if (window.localStorage.show_this_query !== undefined
&& window.localStorage.show_this_query === '1') {
$('input[name="show_query"]').prop('checked', true);
if ((db === stored_db && table === stored_table) || (db === undefined && table === undefined)) {
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.setValue(stored_query);
} else if (document.sqlform) {
document.sqlform.sql_query.value = stored_query;
}
}
} else {
$('input[name="show_query"]').prop('checked', false);
}
}
}
/**
* Saves SQL query in local storage or cookie
*
* @param string database name
* @param string table name
* @param string SQL query
* @return void
*/
export function PMA_showThisQuery (db, table, query) {
var show_this_query_object = {
'db': db,
'table': table,
'query': query
};
if (isStorageSupported('localStorage')) {
window.localStorage.show_this_query = 1;
window.localStorage.show_this_query_object = JSON.stringify(show_this_query_object);
} else {
Cookies.set('show_this_quey', 1);
Cookies.set('show_this_query_object', JSON.stringify(show_this_query_object));
}
}
/**
* Saves SQL query in local storage or cookie
*
* @param string SQL query
* @return void
*/
export function PMA_autosaveSQL (query) {
if (isStorageSupported('localStorage')) {
window.localStorage.auto_saved_sql = query;
} else {
Cookies.set('auto_saved_sql', query);
}
}
/**
* Saves SQL query with sort in local storage or cookie
*
* @param string SQL query
* @return void
*/
export function PMA_autosaveSQLSort (query) {
if (query) {
if (isStorageSupported('localStorage')) {
window.localStorage.auto_saved_sql_sort = query;
} else {
Cookies.set('auto_saved_sql_sort', query);
}
}
}
/**
* Inserts multiple fields.
*
*/
export function insertValueQuery () {
var myQuery = document.sqlform.sql_query;
var myListBox = document.sqlform.dummy;
if (myListBox.options.length > 0) {
sql_box_locked = true;
var columnsList = '';
var NbSelect = 0;
for (var i = 0; i < myListBox.options.length; i++) {
if (myListBox.options[i].selected) {
NbSelect++;
if (NbSelect > 1) {
columnsList += ', ';
}
columnsList += myListBox.options[i].value;
}
}
/* CodeMirror support */
if (sqlQueryOptions.codemirror_editor) {
sqlQueryOptions.codemirror_editor.replaceSelection(columnsList);
sqlQueryOptions.codemirror_editor.focus();
// IE support
} else if (document.selection) {
myQuery.focus();
var sel = document.selection.createRange();
sel.text = columnsList;
// MOZILLA/NETSCAPE support
} else if (document.sqlform.sql_query.selectionStart || document.sqlform.sql_query.selectionStart === '0') {
var startPos = document.sqlform.sql_query.selectionStart;
var endPos = document.sqlform.sql_query.selectionEnd;
var SqlString = document.sqlform.sql_query.value;
myQuery.value = SqlString.substring(0, startPos) + columnsList + SqlString.substring(endPos, SqlString.length);
myQuery.focus();
} else {
myQuery.value += columnsList;
}
sql_box_locked = false;
}
}

View File

@ -0,0 +1,99 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import CommonParams from '../../variables/common_params';
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
/**
* Check if a form's element is empty.
* An element containing only spaces is also considered empty
*
* @param object the form
* @param string the name of the form field to put the focus on
*
* @return boolean whether the form field is empty or not
*/
function emptyCheckTheField (theForm, theFieldName) {
var theField = theForm.elements[theFieldName];
var space_re = new RegExp('\\s+');
return theField.value.replace(space_re, '') === '';
} // end of the 'emptyCheckTheField()' function
export function checkTableEditForm (theForm, fieldsCnt) {
// TODO: avoid sending a message if user just wants to add a line
// on the form but has not completed at least one field name
var atLeastOneField = 0;
var i;
var elm;
var elm2;
var elm3;
var val;
var id;
for (i = 0; i < fieldsCnt; i++) {
id = '#field_' + i + '_2';
elm = $(id);
val = elm.val();
if (val === 'VARCHAR' || val === 'CHAR' || val === 'BIT' || val === 'VARBINARY' || val === 'BINARY') {
elm2 = $('#field_' + i + '_3');
val = parseInt(elm2.val(), 10);
elm3 = $('#field_' + i + '_1');
if (isNaN(val) && elm3.val() !== '') {
elm2.select();
alert(PMA_messages.strEnterValidLength);
elm2.focus();
return false;
}
}
if (atLeastOneField === 0) {
id = 'field_' + i + '_1';
if (!emptyCheckTheField(theForm, id)) {
atLeastOneField = 1;
}
}
}
if (atLeastOneField === 0) {
var theField = theForm.elements.field_0_1;
alert(PMA_messages.strFormEmpty);
theField.focus();
return false;
}
// at least this section is under jQuery
var $input = $('input.textfield[name=\'table\']');
if ($input.val() === '') {
alert(PMA_messages.strFormEmpty);
$input.focus();
return false;
}
return true;
} // enf of the 'checkTableEditForm()' function
/**
* check for reserved keyword column name
*
* @param jQuery Object $form Form
*
* @returns true|false
*/
export function PMA_checkReservedWordColumns ($form) {
var is_confirmed = true;
$.ajax({
type: 'POST',
url: 'tbl_structure.php',
data: $form.serialize() + CommonParams.get('arg_separator') + 'reserved_word_check=1',
success: function (data) {
if (typeof data.success !== 'undefined' && data.success === true) {
is_confirmed = confirm(data.message);
}
},
async:false
});
return is_confirmed;
}

View File

@ -1,20 +1,16 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview events handling from normalization page
* @name normalization
*
* @requires jQuery
*/
/**
* AJAX scripts for normalization.php
*
* Module Import
*/
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
import PMA_commonParams from '../../variables/common_params';
import { PMA_sprintf } from '../../utils/sprintf';
import { escapeHtml, escapeJsString } from '../../utils/Sanitise';
import { PMA_ajaxShowMessage } from '../../utils/show_ajax_messages';
import NormalizationEnum from '../../utils/NormalizationEnum';
var normalizeto = '1nf';
var primary_key;
var data_parsed = null;
function appendHtmlColumnsList () {
export function appendHtmlColumnsList () {
$.get(
'normalization.php',
{
@ -30,6 +26,7 @@ function appendHtmlColumnsList () {
}
);
}
function goTo3NFStep1 (newTables) {
if (Object.keys(newTables).length === 1) {
newTables = [PMA_commonParams.get('table')];
@ -67,6 +64,7 @@ function goTo3NFStep1 (newTables) {
}
);
}
function goTo2NFStep1 () {
$.post(
'normalization.php',
@ -90,7 +88,7 @@ function goTo2NFStep1 () {
})
.appendTo('.tblFooters');
} else {
if (normalizeto === '3nf') {
if (NormalizationEnum.normalizeto === '3nf') {
$('#mainContent #newCols').html(PMA_messages.strToNextStep);
setTimeout(function () {
goTo3NFStep1([PMA_commonParams.get('table')]);
@ -101,7 +99,7 @@ function goTo2NFStep1 () {
}
function goToFinish1NF () {
if (normalizeto !== '1nf') {
if (NormalizationEnum.normalizeto !== '1nf') {
goTo2NFStep1();
return true;
}
@ -130,14 +128,14 @@ function goToStep4 () {
$('#mainContent #extra').html(data.extra);
$('#mainContent #newCols').html('');
$('.tblFooters').html('');
for (var pk in primary_key) {
$('#extra input[value=\'' + escapeJsString(primary_key[pk]) + '\']').attr('disabled','disabled');
for (var pk in NormalizationEnum.primary_key) {
$('#extra input[value=\'' + escapeJsString(NormalizationEnum.primary_key[pk]) + '\']').attr('disabled','disabled');
}
}
);
}
function goToStep3 () {
export function goToStep3 () {
$.post(
'normalization.php',
{
@ -152,15 +150,15 @@ function goToStep3 () {
$('#mainContent #extra').html(data.extra);
$('#mainContent #newCols').html('');
$('.tblFooters').html('');
primary_key = JSON.parse(data.primary_key);
for (var pk in primary_key) {
$('#extra input[value=\'' + escapeJsString(primary_key[pk]) + '\']').attr('disabled','disabled');
NormalizationEnum.primary_key = JSON.parse(data.primary_key);
for (var pk in NormalizationEnum.primary_key) {
$('#extra input[value=\'' + escapeJsString(NormalizationEnum.primary_key[pk]) + '\']').attr('disabled','disabled');
}
}
);
}
function goToStep2 (extra) {
export function goToStep2 (extra) {
$.post(
'normalization.php',
{
@ -199,13 +197,14 @@ function goTo2NFFinish (pd) {
for (var dependson in pd) {
tables[dependson] = $('#extra input[name="' + dependson + '"]').val();
}
datastring = {
var datastring = {
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'pd': JSON.stringify(pd),
'newTablesName':JSON.stringify(tables),
'createNewTables2NF':1 };
'createNewTables2NF':1
};
$.ajax({
type: 'POST',
url: 'normalization.php',
@ -214,7 +213,7 @@ function goTo2NFFinish (pd) {
success: function (data) {
if (data.success === true) {
if (data.queryError === false) {
if (normalizeto === '3nf') {
if (NormalizationEnum.normalizeto === '3nf') {
$('#pma_navigation_reload').trigger('click');
goTo3NFStep1(tables);
return true;
@ -245,11 +244,12 @@ function goTo3NFFinish (newTables) {
}
}
}
datastring = {
var datastring = {
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'newTables':JSON.stringify(newTables),
'createNewTables3NF':1 };
'createNewTables3NF':1
};
$.ajax({
type: 'POST',
url: 'normalization.php',
@ -273,7 +273,7 @@ function goTo3NFFinish (newTables) {
}
});
}
var backup = '';
function goTo2NFStep2 (pd, primary_key) {
$('#newCols').html('');
$('#mainContent legend').html(PMA_messages.strStep + ' 2.2 ' + PMA_messages.strConfirmPd);
@ -292,12 +292,13 @@ function goTo2NFStep2 (pd, primary_key) {
extra += '</div>';
} else {
extra += '</div>';
datastring = {
var datastring = {
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'pd': JSON.stringify(pd),
'getNewTables2NF':1 };
'getNewTables2NF':1
};
$.ajax({
type: 'POST',
url: 'normalization.php',
@ -328,7 +329,7 @@ function goTo3NFStep2 (pd, tablesTds) {
var pdFound = false;
for (var table in tablesTds) {
for (var i in tablesTds[table]) {
dependson = tablesTds[table][i];
var dependson = tablesTds[table][i];
if (dependson !== '' && dependson !== table) {
pdFound = true;
extra += '<p class="displayblock desc">' + escapeHtml(dependson) + ' -> ' + escapeHtml(pd[dependson].toString()) + '</p>';
@ -340,21 +341,22 @@ function goTo3NFStep2 (pd, tablesTds) {
extra += '</div>';
} else {
extra += '</div>';
datastring = {
var datastring = {
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'tables': JSON.stringify(tablesTds),
'pd': JSON.stringify(pd),
'getNewTables3NF':1 };
'getNewTables3NF':1
};
$.ajax({
type: 'POST',
url: 'normalization.php',
data: datastring,
async:false,
success: function (data) {
data_parsed = data;
NormalizationEnum.data_parsed = data;
if (data.success === true) {
extra += data_parsed.html;
extra += NormalizationEnum.data_parsed.html;
} else {
PMA_ajaxShowMessage(data.error, false);
}
@ -367,10 +369,11 @@ function goTo3NFStep2 (pd, tablesTds) {
if (!pdFound) {
goTo3NFFinish([]);
} else {
goTo3NFFinish(data_parsed.newTables);
goTo3NFFinish(NormalizationEnum.data_parsed.newTables);
}
});
}
function processDependencies (primary_key, isTransitive) {
var pd = {};
var tablesTds = {};
@ -411,7 +414,7 @@ function processDependencies (primary_key, isTransitive) {
}
}
});
backup = $('#mainContent').html();
NormalizationEnum.backup = $('#mainContent').html();
if (isTransitive === true) {
goTo3NFStep2(pd, tablesTds);
} else {
@ -420,7 +423,7 @@ function processDependencies (primary_key, isTransitive) {
return false;
}
function moveRepeatingGroup (repeatingCols) {
export function moveRepeatingGroup (repeatingCols) {
var newTable = $('input[name=repeatGroupTable]').val();
var newColumn = $('input[name=repeatGroupColumn]').val();
if (!newTable) {
@ -431,14 +434,14 @@ function moveRepeatingGroup (repeatingCols) {
$('input[name=repeatGroupColumn]').focus();
return false;
}
datastring = {
var datastring = {
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'repeatingColumns': repeatingCols,
'newTable':newTable,
'newColumn':newColumn,
'primary_columns':primary_key.toString()
'newTable': newTable,
'newColumn': newColumn,
'primary_columns': NormalizationEnum.primary_key.toString()
};
$.ajax({
type: 'POST',
@ -458,272 +461,3 @@ function moveRepeatingGroup (repeatingCols) {
}
});
}
AJAX.registerTeardown('normalization.js', function () {
$('#extra').off('click', '#selectNonAtomicCol');
$('#splitGo').off('click');
$('.tblFooters').off('click', '#saveSplit');
$('#extra').off('click', '#addNewPrimary');
$('.tblFooters').off('click', '#saveNewPrimary');
$('#extra').off('click', '#removeRedundant');
$('#mainContent p').off('click', '#createPrimaryKey');
$('#mainContent').off('click', '#backEditPd');
$('#mainContent').off('click', '#showPossiblePd');
$('#mainContent').off('click', '.pickPd');
});
AJAX.registerOnload('normalization.js', function () {
var selectedCol;
normalizeto = $('#mainContent').data('normalizeto');
$('#extra').on('click', '#selectNonAtomicCol', function () {
if ($(this).val() === 'no_such_col') {
goToStep2();
} else {
selectedCol = $(this).val();
}
});
$('#splitGo').on('click', function () {
if (!selectedCol || selectedCol === '') {
return false;
}
var numField = $('#numField').val();
$.get(
'normalization.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'splitColumn': true,
'numFields': numField
},
function (data) {
if (data.success === true) {
$('#newCols').html(data.message);
$('.default_value').hide();
$('.enum_notice').hide();
$('<input />')
.attr({ type: 'submit', id: 'saveSplit', value: PMA_messages.strSave })
.appendTo('.tblFooters');
var cancelSplitButton = $('<input />')
.attr({ type: 'submit', id: 'cancelSplit', value: PMA_messages.strCancel })
.on('click', function () {
$('#newCols').html('');
$(this).parent().html('');
})
.appendTo('.tblFooters');
}
}
);
return false;
});
$('.tblFooters').on('click','#saveSplit', function () {
central_column_list = [];
if ($('#newCols #field_0_1').val() === '') {
$('#newCols #field_0_1').focus();
return false;
}
var argsep = PMA_commonParams.get('arg_separator');
datastring = $('#newCols :input').serialize();
datastring += argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last';
$.post('tbl_addfield.php', datastring, function (data) {
if (data.success) {
$.post(
'sql.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'dropped_column': selectedCol,
'purge' : 1,
'sql_query': 'ALTER TABLE `' + PMA_commonParams.get('table') + '` DROP `' + selectedCol + '`;',
'is_js_confirmed': 1
},
function (data) {
if (data.success === true) {
appendHtmlColumnsList();
$('#newCols').html('');
$('.tblFooters').html('');
} else {
PMA_ajaxShowMessage(data.error, false);
}
selectedCol = '';
}
);
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
$('#extra').on('click', '#addNewPrimary', function () {
$.get(
'normalization.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'addNewPrimary': true
},
function (data) {
if (data.success === true) {
$('#newCols').html(data.message);
$('.default_value').hide();
$('.enum_notice').hide();
$('<input />')
.attr({ type: 'submit', id: 'saveNewPrimary', value: PMA_messages.strSave })
.appendTo('.tblFooters');
$('<input />')
.attr({ type: 'submit', id: 'cancelSplit', value: PMA_messages.strCancel })
.on('click', function () {
$('#newCols').html('');
$(this).parent().html('');
})
.appendTo('.tblFooters');
} else {
PMA_ajaxShowMessage(data.error, false);
}
}
);
return false;
});
$('.tblFooters').on('click', '#saveNewPrimary', function () {
var datastring = $('#newCols :input').serialize();
var argsep = PMA_commonParams.get('arg_separator');
datastring += argsep + 'field_key[0]=primary_0' + argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last';
$.post('tbl_addfield.php', datastring, function (data) {
if (data.success === true) {
$('#mainContent h4').html(PMA_messages.strPrimaryKeyAdded);
$('#mainContent p').html(PMA_messages.strToNextStep);
$('#mainContent #extra').html('');
$('#mainContent #newCols').html('');
$('.tblFooters').html('');
setTimeout(function () {
goToStep3();
}, 2000);
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
$('#extra').on('click', '#removeRedundant', function () {
var dropQuery = 'ALTER TABLE `' + PMA_commonParams.get('table') + '` ';
$('#extra input[type=checkbox]:checked').each(function () {
dropQuery += 'DROP `' + $(this).val() + '`, ';
});
dropQuery = dropQuery.slice(0, -2);
$.post(
'sql.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'sql_query': dropQuery,
'is_js_confirmed': 1
},
function (data) {
if (data.success === true) {
goToStep2('goToFinish1NF');
} else {
PMA_ajaxShowMessage(data.error, false);
}
}
);
});
$('#extra').on('click', '#moveRepeatingGroup', function () {
var repeatingCols = '';
$('#extra input[type=checkbox]:checked').each(function () {
repeatingCols += $(this).val() + ', ';
});
if (repeatingCols !== '') {
var newColName = $('#extra input[type=checkbox]:checked:first').val();
repeatingCols = repeatingCols.slice(0, -2);
var confirmStr = PMA_sprintf(PMA_messages.strMoveRepeatingGroup, escapeHtml(repeatingCols), escapeHtml(PMA_commonParams.get('table')));
confirmStr += '<input type="text" name="repeatGroupTable" placeholder="' + PMA_messages.strNewTablePlaceholder + '"/>' +
'( ' + escapeHtml(primary_key.toString()) + ', <input type="text" name="repeatGroupColumn" placeholder="' + PMA_messages.strNewColumnPlaceholder + '" value="' + escapeHtml(newColName) + '">)' +
'</ol>';
$('#newCols').html(confirmStr);
$('<input />')
.attr({ type: 'submit', value: PMA_messages.strCancel })
.on('click', function () {
$('#newCols').html('');
$('#extra input[type=checkbox]').prop('checked', false);
})
.appendTo('.tblFooters');
$('<input />')
.attr({ type: 'submit', value: PMA_messages.strGo })
.on('click', function () {
moveRepeatingGroup(repeatingCols);
})
.appendTo('.tblFooters');
}
});
$('#mainContent p').on('click', '#createPrimaryKey', function (event) {
event.preventDefault();
var url = { create_index: 1,
server: PMA_commonParams.get('server'),
db: PMA_commonParams.get('db'),
table: PMA_commonParams.get('table'),
added_fields: 1,
add_fields:1,
index: { Key_name:'PRIMARY' },
ajax_request: true
};
var title = PMA_messages.strAddPrimaryKey;
indexEditorDialog(url, title, function () {
// on success
$('.sqlqueryresults').remove();
$('.result_query').remove();
$('.tblFooters').html('');
goToStep2('goToStep3');
});
return false;
});
$('#mainContent').on('click', '#backEditPd', function () {
$('#mainContent').html(backup);
});
$('#mainContent').on('click', '#showPossiblePd', function () {
if ($(this).hasClass('hideList')) {
$(this).html('+ ' + PMA_messages.strShowPossiblePd);
$(this).removeClass('hideList');
$('#newCols').slideToggle('slow');
return false;
}
if ($('#newCols').html() !== '') {
$('#showPossiblePd').html('- ' + PMA_messages.strHidePd);
$('#showPossiblePd').addClass('hideList');
$('#newCols').slideToggle('slow');
return false;
}
$('#newCols').insertAfter('#mainContent h4');
$('#newCols').html('<div class="center">' + PMA_messages.strLoading + '<br/>' + PMA_messages.strWaitForPd + '</div>');
$.post(
'normalization.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'findPdl': true
}, function (data) {
$('#showPossiblePd').html('- ' + PMA_messages.strHidePd);
$('#showPossiblePd').addClass('hideList');
$('#newCols').html(data.message);
});
});
$('#mainContent').on('click', '.pickPd', function () {
var strColsLeft = $(this).next('.determinants').html();
var colsLeft = strColsLeft.split(',');
var strColsRight = $(this).next().next().html();
var colsRight = strColsRight.split(',');
for (var i in colsRight) {
$('form[data-colname="' + colsRight[i].trim() + '"] input[type="checkbox"]').prop('checked', false);
for (var j in colsLeft) {
$('form[data-colname="' + colsRight[i].trim() + '"] input[value="' + colsLeft[j].trim() + '"]').prop('checked', true);
}
}
});
});

View File

@ -1,4 +1,13 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from '../../utils/JqueryExtended';
import CommonParams from '../../variables/common_params';
import { escapeHtml } from '../../utils/Sanitise';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage } from '../../utils/show_ajax_messages';
/**
* for tbl_relation.php
*
@ -32,7 +41,7 @@ function setDropdownValues ($dropdown, values, selectedValue) {
*
* @param $dropdown the dropdown whose value got changed
*/
function getDropdownValues ($dropdown) {
export function getDropdownValues ($dropdown) {
var foreignDb = null;
var foreignTable = null;
var $databaseDd;
@ -71,7 +80,7 @@ function getDropdownValues ($dropdown) {
}
var $msgbox = PMA_ajaxShowMessage();
var $form = $dropdown.parents('form');
var argsep = PMA_commonParams.get('arg_separator');
var argsep = CommonParams.get('arg_separator');
var url = 'tbl_relation.php?getDropdownValues=true' + argsep + 'ajax_request=true' +
argsep + 'db=' + $form.find('input[name="db"]').val() +
argsep + 'table=' + $form.find('input[name="table"]').val() +
@ -112,130 +121,3 @@ function getDropdownValues ($dropdown) {
}
});
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('tbl_relation.js', function () {
$('body').off('change',
'select[name^="destination_db"], ' +
'select[name^="destination_table"], ' +
'select[name^="destination_foreign_db"], ' +
'select[name^="destination_foreign_table"]'
);
$('body').off('click', 'a.add_foreign_key_field');
$('body').off('click', 'a.add_foreign_key');
$('a.drop_foreign_key_anchor.ajax').off('click');
});
AJAX.registerOnload('tbl_relation.js', function () {
/**
* Ajax event handler to fetch table/column dropdown values.
*/
$('body').on('change',
'select[name^="destination_db"], ' +
'select[name^="destination_table"], ' +
'select[name^="destination_foreign_db"], ' +
'select[name^="destination_foreign_table"]',
function () {
getDropdownValues($(this));
}
);
/**
* Ajax event handler to add a column to a foreign key constraint.
*/
$('body').on('click', 'a.add_foreign_key_field', function (event) {
event.preventDefault();
event.stopPropagation();
// Add field.
$(this)
.prev('span')
.clone(true, true)
.insertBefore($(this))
.find('select')
.val('');
// Add foreign field.
var $source_elem = $('select[name^="destination_foreign_column[' +
$(this).attr('data-index') + ']"]:last').parent();
$source_elem
.clone(true, true)
.insertAfter($source_elem)
.find('select')
.val('');
});
/**
* Ajax event handler to add a foreign key constraint.
*/
$('body').on('click', 'a.add_foreign_key', function (event) {
event.preventDefault();
event.stopPropagation();
var $prev_row = $(this).closest('tr').prev('tr');
var $newRow = $prev_row.clone(true, true);
// Update serial number.
var curr_index = $newRow
.find('a.add_foreign_key_field')
.attr('data-index');
var new_index = parseInt(curr_index) + 1;
$newRow.find('a.add_foreign_key_field').attr('data-index', new_index);
// Update form parameter names.
$newRow.find('select[name^="foreign_key_fields_name"]:not(:first), ' +
'select[name^="destination_foreign_column"]:not(:first)'
).each(function () {
$(this).parent().remove();
});
$newRow.find('input, select').each(function () {
$(this).attr('name',
$(this).attr('name').replace(/\d/, new_index)
);
});
$newRow.find('input[type="text"]').each(function () {
$(this).val('');
});
// Finally add the row.
$newRow.insertAfter($prev_row);
});
/**
* Ajax Event handler for 'Drop Foreign key'
*/
$('a.drop_foreign_key_anchor.ajax').on('click', function (event) {
event.preventDefault();
var $anchor = $(this);
// Object containing reference to the current field's row
var $curr_row = $anchor.parents('tr');
var drop_query = escapeHtml(
$curr_row.children('td')
.children('.drop_foreign_key_msg')
.val()
);
var question = PMA_sprintf(PMA_messages.strDoYouReally, drop_query);
$anchor.PMA_confirm(question, $anchor.attr('href'), function (url) {
var $msg = PMA_ajaxShowMessage(PMA_messages.strDroppingForeignKey, false);
var params = getJSConfirmCommonParam(this, $anchor.getPostData());
$.post(url, params, function (data) {
if (data.success === true) {
PMA_ajaxRemoveMessage($msg);
PMA_commonActions.refreshMain(false, function () {
// Do nothing
});
} else {
PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}); // end $.PMA_confirm()
}); // end Drop Foreign key
var windowwidth = $(window).width();
$('.jsresponsive').css('max-width', (windowwidth - 35) + 'px');
});

View File

@ -0,0 +1,301 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from '../../utils/JqueryExtended';
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
/**
* Modify form controls when the "NULL" checkbox is checked
*
* @param theType string the MySQL field type
* @param urlField string the urlencoded field name - OBSOLETE
* @param md5Field string the md5 hashed field name
* @param multi_edit string the multi_edit row sequence number
*
* @return boolean always true
*/
export function nullify (theType, urlField, md5Field, multi_edit) {
var rowForm = document.forms.insertForm;
if (typeof(rowForm.elements['funcs' + multi_edit + '[' + md5Field + ']']) !== 'undefined') {
rowForm.elements['funcs' + multi_edit + '[' + md5Field + ']'].selectedIndex = -1;
}
// "ENUM" field with more than 20 characters
if (theType === 1) {
rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'][1].selectedIndex = -1;
// Other "ENUM" field
} else if (theType === 2) {
var elts = rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'];
// when there is just one option in ENUM:
if (elts.checked) {
elts.checked = false;
} else {
var elts_cnt = elts.length;
for (var i = 0; i < elts_cnt; i++) {
elts[i].checked = false;
} // end for
} // end if
// "SET" field
} else if (theType === 3) {
rowForm.elements['fields' + multi_edit + '[' + md5Field + '][]'].selectedIndex = -1;
// Foreign key field (drop-down)
} else if (theType === 4) {
rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].selectedIndex = -1;
// foreign key field (with browsing icon for foreign values)
} else if (theType === 6) {
rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].value = '';
// Other field types
} else /* if (theType === 5)*/ {
rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].value = '';
} // end if... else if... else
return true;
} // end of the 'nullify()' function
/**
* javascript DateTime format validation.
* its used to prevent adding default (0000-00-00 00:00:00) to database when user enter wrong values
* Start of validation part
*/
// function checks the number of days in febuary
function daysInFebruary (year) {
return (((year % 4 === 0) && (((year % 100 !== 0)) || (year % 400 === 0))) ? 29 : 28);
}
// function to convert single digit to double digit
function fractionReplace (num) {
num = parseInt(num, 10);
return num >= 1 && num <= 9 ? '0' + num : '00';
}
/** function to check the validity of date
* The following patterns are accepted in this validation (accepted in mysql as well)
* 1) 2001-12-23
* 2) 2001-1-2
* 3) 02-12-23
* 4) And instead of using '-' the following punctuations can be used (+,.,*,^,@,/) All these are accepted by mysql as well. Therefore no issues
*/
export function isDate (val, tmstmp) {
val = val.replace(/[.|*|^|+|//|@]/g, '-');
var arrayVal = val.split('-');
for (var a = 0; a < arrayVal.length; a++) {
if (arrayVal[a].length === 1) {
arrayVal[a] = fractionReplace(arrayVal[a]);
}
}
val = arrayVal.join('-');
var pos = 2;
var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[0-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[0-9])|([1-2][0-9])|30))|((00)-(00)))$/);
if (val.length === 8) {
pos = 0;
}
if (dtexp.test(val)) {
var month = parseInt(val.substring(pos + 3, pos + 5), 10);
var day = parseInt(val.substring(pos + 6, pos + 8), 10);
var year = parseInt(val.substring(0, pos + 2), 10);
if (month === 2 && day > daysInFebruary(year)) {
return false;
}
if (val.substring(0, pos + 2).length === 2) {
year = parseInt('20' + val.substring(0, pos + 2), 10);
}
if (tmstmp === true) {
if (year < 1978) {
return false;
}
if (year > 2038 || (year > 2037 && day > 19 && month >= 1) || (year > 2037 && month > 1)) {
return false;
}
}
} else {
return false;
}
return true;
}
/** function to check the validity of time
* The following patterns are accepted in this validation (accepted in mysql as well)
* 1) 2:3:4
* 2) 2:23:43
* 3) 2:23:43.123456
*/
export function isTime (val) {
var arrayVal = val.split(':');
for (var a = 0, l = arrayVal.length; a < l; a++) {
if (arrayVal[a].length === 1) {
arrayVal[a] = fractionReplace(arrayVal[a]);
}
}
val = arrayVal.join(':');
var tmexp = new RegExp(/^(-)?(([0-7]?[0-9][0-9])|(8[0-2][0-9])|(83[0-8])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/);
return tmexp.test(val);
}
/**
* To check whether insert section is ignored or not
*/
function checkForCheckbox (multi_edit) {
if ($('#insert_ignore_' + multi_edit).length) {
return $('#insert_ignore_' + multi_edit).is(':unchecked');
}
return true;
}
export function verificationsAfterFieldChange (urlField, multi_edit, theType) {
var evt = window.event || arguments.callee.caller.arguments[0];
var target = evt.target || evt.srcElement;
var $this_input = $(':input[name^=\'fields[multi_edit][' + multi_edit + '][' +
urlField + ']\']');
// the function drop-down that corresponds to this input field
var $this_function = $('select[name=\'funcs[multi_edit][' + multi_edit + '][' +
urlField + ']\']');
var function_selected = false;
if (typeof $this_function.val() !== 'undefined' &&
$this_function.val() !== null &&
$this_function.val().length > 0
) {
function_selected = true;
}
// To generate the textbox that can take the salt
var new_salt_box = '<br><input type=text name=salt[multi_edit][' + multi_edit + '][' + urlField + ']' +
' id=salt_' + target.id + ' placeholder=\'' + PMA_messages.strEncryptionKey + '\'>';
// If encrypting or decrypting functions that take salt as input is selected append the new textbox for salt
if (target.value === 'AES_ENCRYPT' ||
target.value === 'AES_DECRYPT' ||
target.value === 'DES_ENCRYPT' ||
target.value === 'DES_DECRYPT' ||
target.value === 'ENCRYPT') {
if (!($('#salt_' + target.id).length)) {
$this_input.after(new_salt_box);
}
} else {
// Remove the textbox for salt
$('#salt_' + target.id).prev('br').remove();
$('#salt_' + target.id).remove();
}
// call validate before adding rules
$($this_input[0].form).validate();
if (target.value === 'AES_DECRYPT'
|| target.value === 'AES_ENCRYPT'
|| target.value === 'MD5') {
$('#' + target.id).rules('add', {
validationFunctionForFuns: {
param: $this_input,
depends: function () {
return checkForCheckbox(multi_edit);
}
}
});
}
// Unchecks the corresponding "NULL" control
$('input[name=\'fields_null[multi_edit][' + multi_edit + '][' + urlField + ']\']').prop('checked', false);
// Unchecks the Ignore checkbox for the current row
$('input[name=\'insert_ignore_' + multi_edit + '\']').prop('checked', false);
var charExceptionHandling;
if (theType.substring(0,4) === 'char') {
charExceptionHandling = theType.substring(5,6);
} else if (theType.substring(0,7) === 'varchar') {
charExceptionHandling = theType.substring(8,9);
}
if (function_selected) {
$this_input.removeAttr('min');
$this_input.removeAttr('max');
// @todo: put back attributes if corresponding function is deselected
}
if ($this_input.data('rulesadded') === null && ! function_selected) {
// validate for date time
if (theType === 'datetime' || theType === 'time' || theType === 'date' || theType === 'timestamp') {
$this_input.rules('add', {
validationFunctionForDateTime: {
param: theType,
depends: function () {
return checkForCheckbox(multi_edit);
}
}
});
}
// validation for integer type
if ($this_input.data('type') === 'INT') {
var mini = parseInt($this_input.attr('min'));
var maxi = parseInt($this_input.attr('max'));
$this_input.rules('add', {
number: {
param : true,
depends: function () {
return checkForCheckbox(multi_edit);
}
},
min: {
param: mini,
depends: function () {
if (isNaN($this_input.val())) {
return false;
} else {
return checkForCheckbox(multi_edit);
}
}
},
max: {
param: maxi,
depends: function () {
if (isNaN($this_input.val())) {
return false;
} else {
return checkForCheckbox(multi_edit);
}
}
}
});
// validation for CHAR types
} else if ($this_input.data('type') === 'CHAR') {
var maxlen = $this_input.data('maxlength');
if (typeof maxlen !== 'undefined') {
if (maxlen <= 4) {
maxlen = charExceptionHandling;
}
$this_input.rules('add', {
maxlength: {
param: maxlen,
depends: function () {
return checkForCheckbox(multi_edit);
}
}
});
}
// validate binary & blob types
} else if ($this_input.data('type') === 'HEX') {
$this_input.rules('add', {
validationFunctionForHex: {
param: true,
depends: function () {
return checkForCheckbox(multi_edit);
}
}
});
}
$this_input.data('rulesadded', true);
} else if ($this_input.data('rulesadded') === true && function_selected) {
// remove any rules added
$this_input.rules('remove');
// remove any error messages
$this_input
.removeClass('error')
.removeAttr('aria-invalid')
.siblings('.error')
.remove();
$this_input.data('rulesadded', null);
}
}
window.verificationsAfterFieldChange = verificationsAfterFieldChange;
/* End of fields validation*/

View File

@ -0,0 +1,244 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from '../../utils/JqueryExtended';
import JQPlotChartFactory, { DataTable, ColumnType } from '../../classes/Chart';
import { escapeHtml } from '../../utils/Sanitise';
import { PMA_Messages as PMA_messages } from '../../variables/export_variables';
import { PMA_ajaxShowMessage } from '../../utils/show_ajax_messages';
export var TableChartEnum = {
chart_data: {},
temp_chart_title: null,
currentChart: null,
currentSettings: null,
dateTimeCols: [],
numericCols: []
};
function extractDate (dateString) {
var matches;
var match;
var dateTimeRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/;
var dateRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2}/;
matches = dateTimeRegExp.exec(dateString);
if (matches !== null && matches.length > 0) {
match = matches[0];
return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2), match.substr(11, 2), match.substr(14, 2), match.substr(17, 2));
} else {
matches = dateRegExp.exec(dateString);
if (matches !== null && matches.length > 0) {
match = matches[0];
return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2));
}
}
return null;
}
function PMA_queryChart (data, columnNames, settings) {
if ($('#querychart').length === 0) {
return;
}
var plotSettings = {
title : {
text : settings.title,
escapeHtml: true
},
grid : {
drawBorder : false,
shadow : false,
background : 'rgba(0,0,0,0)'
},
legend : {
show : true,
placement : 'outsideGrid',
location : 'e',
rendererOptions: {
numberColumns: 2
}
},
axes : {
xaxis : {
label : escapeHtml(settings.xaxisLabel)
},
yaxis : {
label : settings.yaxisLabel
}
},
stackSeries : settings.stackSeries
};
// create the chart
var factory = new JQPlotChartFactory();
var chart = factory.createChart(settings.type, 'querychart');
// create the data table and add columns
var dataTable = new DataTable();
if (settings.type === 'timeline') {
dataTable.addColumn(ColumnType.DATE, columnNames[settings.mainAxis]);
} else if (settings.type === 'scatter') {
dataTable.addColumn(ColumnType.NUMBER, columnNames[settings.mainAxis]);
} else {
dataTable.addColumn(ColumnType.STRING, columnNames[settings.mainAxis]);
}
var i;
if (settings.seriesColumn === null) {
$.each(settings.selectedSeries, function (index, element) {
dataTable.addColumn(ColumnType.NUMBER, columnNames[element]);
});
// set data to the data table
var columnsToExtract = [settings.mainAxis];
$.each(settings.selectedSeries, function (index, element) {
columnsToExtract.push(element);
});
var values = [];
var newRow;
var row;
var col;
for (i = 0; i < data.length; i++) {
row = data[i];
newRow = [];
for (var j = 0; j < columnsToExtract.length; j++) {
col = columnNames[columnsToExtract[j]];
if (j === 0) {
if (settings.type === 'timeline') { // first column is date type
newRow.push(extractDate(row[col]));
} else if (settings.type === 'scatter') {
newRow.push(parseFloat(row[col]));
} else { // first column is string type
newRow.push(row[col]);
}
} else { // subsequent columns are of type, number
newRow.push(parseFloat(row[col]));
}
}
values.push(newRow);
}
dataTable.setData(values);
} else {
var seriesNames = {};
var seriesNumber = 1;
var seriesColumnName = columnNames[settings.seriesColumn];
for (i = 0; i < data.length; i++) {
if (! seriesNames[data[i][seriesColumnName]]) {
seriesNames[data[i][seriesColumnName]] = seriesNumber;
seriesNumber++;
}
}
$.each(seriesNames, function (seriesName, seriesNumber) {
dataTable.addColumn(ColumnType.NUMBER, seriesName);
});
var valueMap = {};
var xValue;
var value;
var mainAxisName = columnNames[settings.mainAxis];
var valueColumnName = columnNames[settings.valueColumn];
for (i = 0; i < data.length; i++) {
xValue = data[i][mainAxisName];
value = valueMap[xValue];
if (! value) {
value = [xValue];
valueMap[xValue] = value;
}
seriesNumber = seriesNames[data[i][seriesColumnName]];
value[seriesNumber] = parseFloat(data[i][valueColumnName]);
}
var values = [];
$.each(valueMap, function (index, value) {
values.push(value);
});
dataTable.setData(values);
}
// draw the chart and return the chart object
chart.draw(dataTable, plotSettings);
return chart;
}
export function drawChart () {
TableChartEnum.currentSettings.width = $('#resizer').width() - 20;
TableChartEnum.currentSettings.height = $('#resizer').height() - 20;
// TODO: a better way using .redraw() ?
if (TableChartEnum.currentChart !== null) {
TableChartEnum.currentChart.destroy();
}
var columnNames = [];
$('select[name="chartXAxis"] option').each(function () {
columnNames.push(escapeHtml($(this).text()));
});
try {
TableChartEnum.currentChart = PMA_queryChart(TableChartEnum.chart_data, columnNames, TableChartEnum.currentSettings);
if (TableChartEnum.currentChart !== null) {
$('#saveChart').attr('href', TableChartEnum.currentChart.toImageString());
}
} catch (err) {
PMA_ajaxShowMessage(err.message, false);
}
}
export function getSelectedSeries () {
var val = $('select[name="chartSeries"]').val() || [];
var ret = [];
$.each(val, function (i, v) {
ret.push(parseInt(v, 10));
});
return ret;
}
export function onXAxisChange () {
var $xAxisSelect = $('select[name="chartXAxis"]');
TableChartEnum.currentSettings.mainAxis = parseInt($xAxisSelect.val(), 10);
if (TableChartEnum.dateTimeCols.indexOf(TableChartEnum.currentSettings.mainAxis) !== -1) {
$('span.span_timeline').show();
} else {
$('span.span_timeline').hide();
if (TableChartEnum.currentSettings.type === 'timeline') {
$('input#radio_line').prop('checked', true);
TableChartEnum.currentSettings.type = 'line';
}
}
if (TableChartEnum.numericCols.indexOf(TableChartEnum.currentSettings.mainAxis) !== -1) {
$('span.span_scatter').show();
} else {
$('span.span_scatter').hide();
if (TableChartEnum.currentSettings.type === 'scatter') {
$('input#radio_line').prop('checked', true);
TableChartEnum.currentSettings.type = 'line';
}
}
var xaxis_title = $xAxisSelect.children('option:selected').text();
$('input[name="xaxis_label"]').val(xaxis_title);
TableChartEnum.currentSettings.xaxisLabel = xaxis_title;
}
export function onDataSeriesChange () {
var $seriesSelect = $('select[name="chartSeries"]');
TableChartEnum.currentSettings.selectedSeries = getSelectedSeries();
var yaxis_title;
if (TableChartEnum.currentSettings.selectedSeries.length === 1) {
$('span.span_pie').show();
yaxis_title = $seriesSelect.children('option:selected').text();
} else {
$('span.span_pie').hide();
if (TableChartEnum.currentSettings.type === 'pie') {
$('input#radio_line').prop('checked', true);
TableChartEnum.currentSettings.type = 'line';
}
yaxis_title = PMA_messages.strYValues;
}
$('input[name="yaxis_label"]').val(yaxis_title);
TableChartEnum.currentSettings.yaxisLabel = yaxis_title;
}

View File

@ -0,0 +1,88 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from '../../utils/JqueryExtended';
/**
* Hides/shows the "Open in ENUM/SET editor" message, depending on the data type of the column currently selected
*/
function PMA_showNoticeForEnum (selectElement) {
var enum_notice_id = selectElement.attr('id').split('_')[1];
enum_notice_id += '_' + (parseInt(selectElement.attr('id').split('_')[2], 10) + 1);
var selectedType = selectElement.val();
if (selectedType === 'ENUM' || selectedType === 'SET') {
$('p#enum_notice_' + enum_notice_id).show();
} else {
$('p#enum_notice_' + enum_notice_id).hide();
}
}
/**
* Hides/shows the default value input field, depending on the default type
* Ticks the NULL checkbox if NULL is chosen as default value.
*/
function PMA_hideShowDefaultValue ($default_type) {
if ($default_type.val() === 'USER_DEFINED') {
$default_type.siblings('.default_value').show().focus();
} else {
$default_type.siblings('.default_value').hide();
if ($default_type.val() === 'NULL') {
var $null_checkbox = $default_type.closest('tr').find('.allow_null');
$null_checkbox.prop('checked', true);
}
}
}
/**
* Hides/shows the input field for column expression based on whether
* VIRTUAL/PERSISTENT is selected
*
* @param $virtuality virtuality dropdown
*/
function PMA_hideShowExpression ($virtuality) {
if ($virtuality.val() === '') {
$virtuality.siblings('.expression').hide();
} else {
$virtuality.siblings('.expression').show();
}
}
/**
* Show notices for ENUM columns; add/hide the default value
*
*/
export function PMA_verifyColumnsProperties () {
$('select.column_type').each(function () {
PMA_showNoticeForEnum($(this));
});
$('select.default_type').each(function () {
PMA_hideShowDefaultValue($(this));
});
$('select.virtuality').each(function () {
PMA_hideShowExpression($(this));
});
}
/**
* If the chosen storage engine is FEDERATED show connection field. Hide otherwise
*
* @param $engine_selector storage engine selector
*/
export function PMA_hideShowConnection ($engine_selector) {
var $connection = $('.create_table_form input[name=connection]');
var index = $connection.parent('td').index() + 1;
var $labelTh = $connection.parents('tr').prev('tr').children('th:nth-child(' + index + ')');
if ($engine_selector.val() !== 'FEDERATED') {
$connection
.prop('disabled', true)
.parent('td').hide();
$labelTh.hide();
} else {
$connection
.prop('disabled', false)
.parent('td').show();
$labelTh.show();
}
}

View File

@ -0,0 +1,56 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { $ } from '../../utils/JqueryExtended';
export function changeValueFieldType (elem, searchIndex) {
var fieldsValue = $('select#fieldID_' + searchIndex);
if (0 === fieldsValue.size()) {
return;
}
var type = $(elem).val();
if ('IN (...)' === type ||
'NOT IN (...)' === type ||
'BETWEEN' === type ||
'NOT BETWEEN' === type
) {
$('#fieldID_' + searchIndex).attr('multiple', '');
} else {
$('#fieldID_' + searchIndex).removeAttr('multiple');
}
}
/**
* Checks if given data-type is numeric or date.
*
* @param string data_type Column data-type
*
* @return bool|string
*/
export function PMA_checkIfDataTypeNumericOrDate (data_type) {
// To test for numeric data-types.
var numeric_re = new RegExp(
'TINYINT|SMALLINT|MEDIUMINT|INT|BIGINT|DECIMAL|FLOAT|DOUBLE|REAL',
'i'
);
// To test for date data-types.
var date_re = new RegExp(
'DATETIME|DATE|TIMESTAMP|TIME|YEAR',
'i'
);
// Return matched data-type
if (numeric_re.test(data_type)) {
return numeric_re.exec(data_type)[0];
}
if (date_re.test(data_type)) {
return date_re.exec(data_type)[0];
}
return false;
}

View File

@ -0,0 +1,28 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import CommonParams from '../../variables/common_params';
/**
* Reload fields table
*/
export function reloadFieldForm () {
$.post($('#fieldsForm').attr('action'), $('#fieldsForm').serialize() + CommonParams.get('arg_separator') + 'ajax_request=true', function (form_data) {
var $temp_div = $('<div id=\'temp_div\'><div>').append(form_data.message);
$('#fieldsForm').replaceWith($temp_div.find('#fieldsForm'));
$('#addColumns').replaceWith($temp_div.find('#addColumns'));
$('#move_columns_dialog').find('ul').replaceWith($temp_div.find('#move_columns_dialog ul'));
$('#moveColumns').removeClass('move-active');
});
$('#page_content').show();
}
export function checkFirst () {
if ($('select[name=after_field] option:selected').data('pos') === 'first') {
$('input[name=field_where]').val('first');
} else {
$('input[name=field_where]').val('after');
}
}

View File

@ -0,0 +1,50 @@
/**
* Updates an element containing code.
*
* @param jQuery Object $base base element which contains the raw and the
* highlighted code.
*
* @param string htmlValue code in HTML format, displayed if code cannot be
* highlighted
*
* @param string rawValue raw code, used as a parameter for highlighter
*
* @return bool whether content was updated or not
*/
export function PMA_updateCode ($base, htmlValue, rawValue) {
var $code = $base.find('code');
if ($code.length === 0) {
return false;
}
// Determines the type of the content and appropriate CodeMirror mode.
var type = '';
var mode = '';
if ($code.hasClass('json')) {
type = 'json';
mode = 'application/json';
} else if ($code.hasClass('sql')) {
type = 'sql';
mode = 'text/x-mysql';
} else if ($code.hasClass('xml')) {
type = 'xml';
mode = 'application/xml';
} else {
return false;
}
// Element used to display unhighlighted code.
var $notHighlighted = $('<pre>' + htmlValue + '</pre>');
// Tries to highlight code using CodeMirror.
if (typeof CodeMirror !== 'undefined') {
var $highlighted = $('<div class="' + type + '-highlight cm-s-default"></div>');
CodeMirror.runMode(rawValue, mode, $highlighted[0]);
$notHighlighted.hide();
$code.html('').append($notHighlighted, $highlighted[0]);
} else {
$code.html('').append($notHighlighted);
}
return true;
}

70
js/src/functions/chart.js Normal file
View File

@ -0,0 +1,70 @@
/**
* Creates a Profiling Chart. Used in sql.js
* and in server_status_monitor.js
*/
import { $ } from '../utils/JqueryExtended';
import JQPlotChartFactory from '../classes/Chart';
import { ChartType, ColumnType, DataTable } from '../classes/Chart';
export function createProfilingChart (target, data) {
// create the chart
var factory = new JQPlotChartFactory();
console.log(factory);
var chart = factory.createChart(ChartType.PIE, target);
// create the data table and add columns
var dataTable = new DataTable();
dataTable.addColumn(ColumnType.STRING, '');
dataTable.addColumn(ColumnType.NUMBER, '');
dataTable.setData(data);
var windowWidth = $(window).width();
var location = 's';
if (windowWidth > 768) {
var location = 'se';
}
// draw the chart and return the chart object
chart.draw(dataTable, {
seriesDefaults: {
rendererOptions: {
showDataLabels: true
}
},
highlighter: {
tooltipLocation: 'se',
sizeAdjust: 0,
tooltipAxes: 'pieref',
formatString: '%s, %.9Ps'
},
legend: {
show: true,
location: location,
rendererOptions: {
numberColumns: 2
}
},
// from http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines#Color_Palette
seriesColors: [
'#fce94f',
'#fcaf3e',
'#e9b96e',
'#8ae234',
'#729fcf',
'#ad7fa8',
'#ef2929',
'#888a85',
'#c4a000',
'#ce5c00',
'#8f5902',
'#4e9a06',
'#204a87',
'#5c3566',
'#a40000',
'#babdb6',
'#2e3436'
]
});
console.log(chart);
return chart;
}

592
js/src/functions/config.js Normal file
View File

@ -0,0 +1,592 @@
import { PMA_ajaxShowMessage } from '../utils/show_ajax_messages';
import { PMA_Messages as PMA_messages } from '../variables/export_variables';
import { defaultValues, validate } from '../variables/get_config';
import { validators } from '../classes/Config';
/**
* checks whether browser supports web storage
*
* @param type the type of storage i.e. localStorage or sessionStorage
*
* @returns bool
*/
export function isStorageSupported (type, warn) {
try {
window[type].setItem('PMATest', 'test');
// Check whether key-value pair was set successfully
if (window[type].getItem('PMATest') === 'test') {
// Supported, remove test variable from storage
window[type].removeItem('PMATest');
return true;
}
} catch (error) {
// Not supported
if (warn) {
PMA_ajaxShowMessage(PMA_messages.strNoLocalStorage, false);
}
}
return false;
}
/** ******************** Common Functions for Settings page ****************** */
/**
* Checks whether field has its default value
*
* @param {Element} field
* @param {String} type
* @return boolean
*/
function checkFieldDefault (field, type) {
var $field = $(field);
var field_id = $field.attr('id');
if (typeof defaultValues[field_id] === 'undefined') {
return true;
}
var isDefault = true;
var currentValue = getFieldValue($field, type);
if (type !== 'select') {
isDefault = currentValue === defaultValues[field_id];
} else {
// compare arrays, will work for our representation of select values
if (currentValue.length !== defaultValues[field_id].length) {
isDefault = false;
} else {
for (var i = 0; i < currentValue.length; i++) {
if (currentValue[i] !== defaultValues[field_id][i]) {
isDefault = false;
break;
}
}
}
}
return isDefault;
}
/**
* Enables or disables the "restore default value" button
*
* @param {Element} field
* @param {boolean} display
*/
function setRestoreDefaultBtn (field, display) {
var $el = $(field).closest('td').find('.restore-default img');
$el[display ? 'show' : 'hide']();
}
/**
* Marks field depending on its value (system default or custom)
*
* @param {Element} field
*/
export function markField (field) {
var $field = $(field);
var type = getFieldType($field);
var isDefault = checkFieldDefault($field, type);
// checkboxes uses parent <span> for marking
var $fieldMarker = (type === 'checkbox') ? $field.parent() : $field;
setRestoreDefaultBtn($field, !isDefault);
$fieldMarker[isDefault ? 'removeClass' : 'addClass']('custom');
}
/**
* Sets field value
*
* value must be of type:
* o undefined (omitted) - restore default value (form default, not PMA default)
* o String - if field_type is 'text'
* o boolean - if field_type is 'checkbox'
* o Array of values - if field_type is 'select'
*
* @param {Element} field
* @param {String} field_type see {@link #getFieldType}
* @param {String|Boolean} value
*/
export function setFieldValue (field, field_type, value) {
var $field = $(field);
switch (field_type) {
case 'text':
case 'number':
$field.val(value);
break;
case 'checkbox':
$field.prop('checked', value);
break;
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
for (i = 0; i < imax; i++) {
options[i].selected = (value.indexOf(options[i].value) !== -1);
}
break;
}
markField($field);
}
/**
* Returns field type
*
* @param {Element} field
*
* @return {string}
*/
export function getFieldType (field) {
var $field = $(field);
var tagName = $field.prop('tagName');
if (tagName === 'INPUT') {
return $field.attr('type');
} else if (tagName === 'SELECT') {
return 'select';
} else if (tagName === 'TEXTAREA') {
return 'text';
}
return '';
}
/**
* Gets field value
*
* Will return one of:
* o String - if type is 'text'
* o boolean - if type is 'checkbox'
* o Array of values - if type is 'select'
*
* @param {Element} field
* @param {String} field_type returned by {@link #getFieldType}
* @type Boolean|String|String[]
*/
function getFieldValue (field, field_type) {
var $field = $(field);
switch (field_type) {
case 'text':
case 'number':
return $field.prop('value');
case 'checkbox':
return $field.prop('checked');
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
var items = [];
for (i = 0; i < imax; i++) {
if (options[i].selected) {
items.push(options[i].value);
}
}
return items;
}
return null;
}
/**
* Returns values for all fields in fieldsets
*/
function getAllValues () {
var $elements = $('fieldset input, fieldset select, fieldset textarea');
var values = {};
var type;
var value;
for (var i = 0; i < $elements.length; i++) {
type = getFieldType($elements[i]);
value = getFieldValue($elements[i], type);
if (typeof value !== 'undefined') {
// we only have single selects, fatten array
if (type === 'select') {
value = value[0];
}
values[$elements[i].name] = value;
}
}
return values;
}
/**
* Returns element's id prefix
* @param {Element} element
*/
function getIdPrefix (element) {
return $(element).attr('id').replace(/[^-]+$/, '');
}
/** ******************** For the {MANAGE YOUR SETTINGS PAGE} ****************** */
/** Contains functions for saving configuration to localstorage */
/**
* Saves user preferences to localStorage
*
* @param {Element} form
*/
export function savePrefsToLocalStorage (form) {
var $form = $(form);
var submit = $form.find('input[type=submit]');
submit.prop('disabled', true);
$.ajax({
url: 'prefs_manage.php',
cache: false,
type: 'POST',
data: {
ajax_request: true,
server: PMA_commonParams.get('server'),
submit_get_json: true
},
success: function (data) {
if (typeof data !== 'undefined' && data.success === true) {
window.localStorage.config = data.prefs;
window.localStorage.config_mtime = data.mtime;
window.localStorage.config_mtime_local = (new Date()).toUTCString();
updatePrefsDate();
$('div.localStorage-empty').hide();
$('div.localStorage-exists').show();
var group = $form.parent('.group');
group.css('height', group.height() + 'px');
$form.hide('fast');
$form.prev('.click-hide-message').show('fast');
} else {
PMA_ajaxShowMessage(data.error);
}
},
complete: function () {
submit.prop('disabled', false);
}
});
}
/**
* Updates preferences timestamp in Import form
*/
export function updatePrefsDate () {
var d = new Date(window.localStorage.config_mtime_local);
var msg = PMA_messages.strSavedOn.replace(
'@DATE@',
PMA_formatDateTime(d)
);
$('#opts_import_local_storage').find('div.localStorage-exists').html(msg);
}
/**
* Prepares message which informs that localStorage preferences are available and can be imported or deleted
*/
export function offerPrefsAutoimport () {
var has_config = (isStorageSupported('localStorage')) && (window.localStorage.config || false);
var $cnt = $('#prefs_autoload');
if (!$cnt.length || !has_config) {
return;
}
$cnt.find('a').on('click', function (e) {
e.preventDefault();
var $a = $(this);
if ($a.attr('href') === '#no') {
$cnt.remove();
$.post('index.php', {
server: PMA_commonParams.get('server'),
prefs_autoload: 'hide'
}, null, 'html');
return;
} else if ($a.attr('href') === '#delete') {
$cnt.remove();
localStorage.clear();
$.post('index.php', {
server: PMA_commonParams.get('server'),
prefs_autoload: 'hide'
}, null, 'html');
return;
}
$cnt.find('input[name=json]').val(window.localStorage.config);
$cnt.find('form').submit();
});
$cnt.show();
}
/** ******************** For resetting individual field to default ****************** */
/**
* Restores field's default value
*
* @param {String} field_id
*/
function restoreField (field_id) {
var $field = $('#' + field_id);
if ($field.length === 0 || defaultValues[field_id] === undefined) {
return;
}
setFieldValue($field, getFieldType($field), defaultValues[field_id]);
}
export function setupRestoreField () {
$('div.tabs_contents')
.on('mouseenter', '.restore-default, .set-value', function () {
$(this).css('opacity', 1);
})
.on('mouseleave', '.restore-default, .set-value', function () {
$(this).css('opacity', 0.25);
})
.on('click', '.restore-default, .set-value', function (e) {
e.preventDefault();
var href = $(this).attr('href');
var field_sel;
if ($(this).hasClass('restore-default')) {
field_sel = href;
console.log(field_sel);
restoreField(field_sel.substr(1));
} else {
field_sel = href.match(/^[^=]+/)[0];
var value = href.match(/\=(.+)$/)[1];
setFieldValue($(field_sel), 'text', value);
}
$(field_sel).trigger('change');
})
.find('.restore-default, .set-value')
// inline-block for IE so opacity inheritance works
.css({ display: 'inline-block', opacity: 0.25 });
}
/** ******************** For Setting up Config tabs ****************** */
/**
* Sets active tab
*
* @param {String} tab_id
*/
export function setTab (tab_id) {
$('ul.tabs').each(function () {
var $this = $(this);
if (!$this.find('li a[href="#' + tab_id + '"]').length) {
return;
}
$this.find('li').removeClass('active').find('a[href="#' + tab_id + '"]').parent().addClass('active');
$this.parent().find('div.tabs_contents fieldset').hide().filter('#' + tab_id).show();
var hashValue = 'tab_' + tab_id;
location.hash = hashValue;
$this.parent().find('input[name=tab_hash]').val(hashValue);
});
}
export function setupConfigTabs () {
var forms = $('form.config-form');
forms.each(function () {
var $this = $(this);
var $tabs = $this.find('ul.tabs');
if (!$tabs.length) {
return;
}
// add tabs events and activate one tab (the first one or indicated by location hash)
$tabs.find('li').removeClass('active');
$tabs.find('a')
.on('click', function (e) {
e.preventDefault();
setTab($(this).attr('href').substr(1));
})
.filter(':first')
.parent()
.addClass('active');
$this.find('div.tabs_contents fieldset').hide().filter(':first').show();
});
}
export function adjustPrefsNotification () {
var $prefsAutoLoad = $('#prefs_autoload');
var $tableNameControl = $('#table_name_col_no');
var $prefsAutoShowing = ($prefsAutoLoad.css('display') !== 'none');
if ($prefsAutoShowing && $tableNameControl.length) {
$tableNameControl.css('top', '55px');
}
}
/** ******************** For Setting up Validations ****************** */
/**
* Returns validation functions associated with form field
*
* @param {String} field_id form field id
* @param {boolean} onKeyUpOnly see validateField
* @type Array
* @return array of [function, parameters to be passed to function]
*/
function getFieldValidators (field_id, onKeyUpOnly) {
// look for field bound validator
var name = field_id && field_id.match(/[^-]+$/)[0];
if (typeof validators._field[name] !== 'undefined') {
return [[validators._field[name], null]];
}
// look for registered validators
var functions = [];
if (typeof validate[field_id] !== 'undefined') {
// validate[field_id]: array of [type, params, onKeyUp]
for (var i = 0, imax = validate[field_id].length; i < imax; i++) {
if (onKeyUpOnly && !validate[field_id][i][2]) {
continue;
}
functions.push([validators[validate[field_id][i][0]], validate[field_id][i][1]]);
}
}
return functions;
}
/**
* Displays errors for given form fields
*
* WARNING: created DOM elements must be identical with the ones made by
* PhpMyAdmin\Config\FormDisplayTemplate::displayInput()!
*
* @param {Object} error_list list of errors in the form {field id: error array}
*/
function displayErrors (error_list) {
var tempIsEmpty = function (item) {
return item !== '';
};
for (var field_id in error_list) {
var errors = error_list[field_id];
var $field = $('#' + field_id);
var isFieldset = $field.attr('tagName') === 'FIELDSET';
var $errorCnt;
if (isFieldset) {
$errorCnt = $field.find('dl.errors');
} else {
$errorCnt = $field.siblings('.inline_errors');
}
// remove empty errors (used to clear error list)
errors = $.grep(errors, tempIsEmpty);
// CSS error class
if (!isFieldset) {
// checkboxes uses parent <span> for marking
var $fieldMarker = ($field.attr('type') === 'checkbox') ? $field.parent() : $field;
$fieldMarker[errors.length ? 'addClass' : 'removeClass']('field-error');
}
if (errors.length) {
// if error container doesn't exist, create it
if ($errorCnt.length === 0) {
if (isFieldset) {
$errorCnt = $('<dl class="errors" />');
$field.find('table').before($errorCnt);
} else {
$errorCnt = $('<dl class="inline_errors" />');
$field.closest('td').append($errorCnt);
}
}
var html = '';
for (var i = 0, imax = errors.length; i < imax; i++) {
html += '<dd>' + errors[i] + '</dd>';
}
$errorCnt.html(html);
} else if ($errorCnt !== null) {
// remove useless error container
$errorCnt.remove();
}
}
}
/**
* Validates fieldset and puts errors in 'errors' object
*
* @param {Element} fieldset
* @param {boolean} isKeyUp
* @param {Object} errors
*/
function validate_fieldset (fieldset, isKeyUp, errors) {
var $fieldset = $(fieldset);
if ($fieldset.length && typeof validators._fieldset[$fieldset.attr('id')] !== 'undefined') {
var fieldset_errors = validators._fieldset[$fieldset.attr('id')].apply($fieldset[0], [isKeyUp]);
for (var field_id in fieldset_errors) {
if (typeof errors[field_id] === 'undefined') {
errors[field_id] = [];
}
if (typeof fieldset_errors[field_id] === 'string') {
fieldset_errors[field_id] = [fieldset_errors[field_id]];
}
$.merge(errors[field_id], fieldset_errors[field_id]);
}
}
}
/**
* Validates form field and puts errors in 'errors' object
*
* @param {Element} field
* @param {boolean} isKeyUp
* @param {Object} errors
*/
function validate_field (field, isKeyUp, errors) {
var args;
var result;
var $field = $(field);
var field_id = $field.attr('id');
errors[field_id] = [];
var functions = getFieldValidators(field_id, isKeyUp);
for (var i = 0; i < functions.length; i++) {
if (typeof functions[i][1] !== 'undefined' && functions[i][1] !== null) {
args = functions[i][1].slice(0);
} else {
args = [];
}
args.unshift(isKeyUp);
result = functions[i][0].apply($field[0], args);
if (result !== true) {
if (typeof result === 'string') {
result = [result];
}
$.merge(errors[field_id], result);
}
}
}
/**
* Validates form field and parent fieldset
*
* @param {Element} field
* @param {boolean} isKeyUp
*/
function validate_field_and_fieldset (field, isKeyUp) {
var $field = $(field);
var errors = {};
validate_field($field, isKeyUp, errors);
validate_fieldset($field.closest('fieldset.optbox'), isKeyUp, errors);
displayErrors(errors);
}
export function setupValidation () {
// register validators and mark custom values
var $elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
$elements.each(function () {
markField(this);
var $el = $(this);
$el.on('change', function () {
validate_field_and_fieldset(this, false);
markField(this);
});
var tagName = $el.attr('tagName');
// text fields can be validated after each change
if (tagName === 'INPUT' && $el.attr('type') === 'text') {
$el.on('keyup', function () {
validate_field_and_fieldset($el, true);
markField($el);
});
}
// disable textarea spellcheck
if (tagName === 'TEXTAREA') {
$el.attr('spellcheck', false);
}
});
// check whether we've refreshed a page and browser remembered modified
// form values
var $check_page_refresh = $('#check_page_refresh');
if ($check_page_refresh.length === 0 || $check_page_refresh.val() === '1') {
// run all field validators
var errors = {};
for (var i = 0; i < $elements.length; i++) {
validate_field($elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validate_fieldset(this, false, errors);
});
displayErrors(errors);
} else if ($check_page_refresh) {
$check_page_refresh.val('1');
}
}

624
js/src/functions/export.js Normal file
View File

@ -0,0 +1,624 @@
import { PMA_ajaxShowMessage } from '../utils/show_ajax_messages';
import { PMA_Messages as messages } from '../variables/export_variables';
import CommonParams from '../variables/common_params';
/**
* Functions used in the export tab
*
*/
/**
* Disables the "Dump some row(s)" sub-options
*/
export function disableDumpSomeRowsSubOptions () {
$('label[for=\'limit_to\']').fadeTo('fast', 0.4);
$('label[for=\'limit_from\']').fadeTo('fast', 0.4);
$('input[type=\'text\'][name=\'limit_to\']').prop('disabled', 'disabled');
$('input[type=\'text\'][name=\'limit_from\']').prop('disabled', 'disabled');
}
/**
* Enables the "Dump some row(s)" sub-options
*/
export function enableDumpSomeRowsSubOptions () {
$('label[for=\'limit_to\']').fadeTo('fast', 1);
$('label[for=\'limit_from\']').fadeTo('fast', 1);
$('input[type=\'text\'][name=\'limit_to\']').prop('disabled', '');
$('input[type=\'text\'][name=\'limit_from\']').prop('disabled', '');
}
/**
* Return template data as a json object
*
* @returns template data
*/
export function getTemplateData () {
var $form = $('form[name="dump"]');
var blacklist = ['token', 'server', 'db', 'table', 'single_table',
'export_type', 'export_method', 'sql_query', 'template_id'];
var obj = {};
var arr = $form.serializeArray();
$.each(arr, function () {
if ($.inArray(this.name, blacklist) < 0) {
if (obj[this.name] !== undefined) {
if (! obj[this.name].push) {
obj[this.name] = [obj[this.name]];
}
obj[this.name].push(this.value || '');
} else {
obj[this.name] = this.value || '';
}
}
});
// include unchecked checboxes (which are ignored by serializeArray()) with null
// to uncheck them when loading the template
$form.find('input[type="checkbox"]:not(:checked)').each(function () {
if (obj[this.name] === undefined) {
obj[this.name] = null;
}
});
// include empty multiselects
$form.find('select').each(function () {
if ($(this).find('option:selected').length === 0) {
obj[this.name] = [];
}
});
return obj;
}
/**
* Create a template with selected options
*
* @param name name of the template
*/
export function createTemplate (name) {
var templateData = getTemplateData();
var params = {
ajax_request : true,
server : CommonParams.get('server'),
db : CommonParams.get('db'),
table : CommonParams.get('table'),
exportType : $('input[name="export_type"]').val(),
templateAction : 'create',
templateName : name,
templateData : JSON.stringify(templateData)
};
PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
$('#templateName').val('');
$('#template').html(response.data);
$('#template').find('option').each(function () {
if ($(this).text() === name) {
$(this).prop('selected', true);
}
});
PMA_ajaxShowMessage(messages.strTemplateCreated);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Loads a template
*
* @param id ID of the template to load
*/
export function loadTemplate (id) {
var params = {
ajax_request : true,
server : CommonParams.get('server'),
db : CommonParams.get('db'),
table : CommonParams.get('table'),
exportType : $('input[name="export_type"]').val(),
templateAction : 'load',
templateId : id,
};
PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
var $form = $('form[name="dump"]');
var options = JSON.parse(response.data);
$.each(options, function (key, value) {
var $element = $form.find('[name="' + key + '"]');
if ($element.length) {
if (($element.is('input') && $element.attr('type') === 'checkbox') && value === null) {
$element.prop('checked', false);
} else {
if (($element.is('input') && $element.attr('type') === 'checkbox') ||
($element.is('input') && $element.attr('type') === 'radio') ||
($element.is('select') && $element.attr('multiple') === 'multiple')) {
if (! value.push) {
value = [value];
}
}
$element.val(value);
}
$element.trigger('change');
}
});
$('input[name="template_id"]').val(id);
PMA_ajaxShowMessage(messages.strTemplateLoaded);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Updates an existing template with current options
*
* @param id ID of the template to update
*/
export function updateTemplate (id) {
var templateData = getTemplateData();
var params = {
ajax_request : true,
server : CommonParams.get('server'),
db : CommonParams.get('db'),
table : CommonParams.get('table'),
exportType : $('input[name="export_type"]').val(),
templateAction : 'update',
templateId : id,
templateData : JSON.stringify(templateData)
};
PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
PMA_ajaxShowMessage(messages.strTemplateUpdated);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Delete a template
*
* @param id ID of the template to delete
*/
export function deleteTemplate (id) {
var params = {
ajax_request : true,
server : CommonParams.get('server'),
db : CommonParams.get('db'),
table : CommonParams.get('table'),
exportType : $('input[name="export_type"]').val(),
templateAction : 'delete',
templateId : id,
};
PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
$('#template').find('option[value="' + id + '"]').remove();
PMA_ajaxShowMessage(messages.strTemplateDeleted);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
export function setupTableStructureOrData () {
if ($('input[name=\'export_type\']').val() !== 'database') {
return;
}
var pluginName = $('#plugins').find('option:selected').val();
var formElemName = pluginName + '_structure_or_data';
var forceStructureOrData = !($('input[name=\'' + formElemName + '_default\']').length);
if (forceStructureOrData === true) {
$('input[name="structure_or_data_forced"]').val(1);
$('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]')
.prop('disabled', true);
$('.export_structure, .export_data').fadeTo('fast', 0.4);
} else {
$('input[name="structure_or_data_forced"]').val(0);
$('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]')
.prop('disabled', false);
$('.export_structure, .export_data').fadeTo('fast', 1);
var structureOrData = $('input[name="' + formElemName + '_default"]').val();
if (structureOrData === 'structure') {
$('.export_data input[type="checkbox"]')
.prop('checked', false);
} else if (structureOrData === 'data') {
$('.export_structure input[type="checkbox"]')
.prop('checked', false);
}
if (structureOrData === 'structure' || structureOrData === 'structure_and_data') {
if (!$('.export_structure input[type="checkbox"]:checked').length) {
$('input[name="table_select[]"]:checked')
.closest('tr')
.find('.export_structure input[type="checkbox"]')
.prop('checked', true);
}
}
if (structureOrData === 'data' || structureOrData === 'structure_and_data') {
if (!$('.export_data input[type="checkbox"]:checked').length) {
$('input[name="table_select[]"]:checked')
.closest('tr')
.find('.export_data input[type="checkbox"]')
.prop('checked', true);
}
}
checkSelectedTables();
checkTableSelectAll();
checkTableSelectStrutureOrData();
}
}
/**
* Toggles the hiding and showing of plugin structure-specific and data-specific
* options
*/
export function toggleStructureDataOpts () {
var pluginName = $('select#plugins').val();
var radioFormName = pluginName + '_structure_or_data';
var dataDiv = '#' + pluginName + '_data';
var structureDiv = '#' + pluginName + '_structure';
var show = $('input[type=\'radio\'][name=\'' + radioFormName + '\']:checked').val();
if (show === 'data') {
$(dataDiv).slideDown('slow');
$(structureDiv).slideUp('slow');
} else {
$(structureDiv).slideDown('slow');
if (show === 'structure') {
$(dataDiv).slideUp('slow');
} else {
$(dataDiv).slideDown('slow');
}
}
}
/**
* Toggles the disabling of the "save to file" options
*/
export function toggleSaveToFile () {
var $ulSaveAsfile = $('#ul_save_asfile');
if (!$('#radio_dump_asfile').prop('checked')) {
$ulSaveAsfile.find('> li').fadeTo('fast', 0.4);
$ulSaveAsfile.find('> li > input').prop('disabled', true);
$ulSaveAsfile.find('> li > select').prop('disabled', true);
} else {
$ulSaveAsfile.find('> li').fadeTo('fast', 1);
$ulSaveAsfile.find('> li > input').prop('disabled', false);
$ulSaveAsfile.find('> li > select').prop('disabled', false);
}
}
/**
* For SQL plugin, toggles the disabling of the "display comments" options
*/
export function toggleSqlIncludeComments () {
$('#checkbox_sql_include_comments').on('change', function () {
var $ulIncludeComments = $('#ul_include_comments');
if (!$('#checkbox_sql_include_comments').prop('checked')) {
$ulIncludeComments.find('> li').fadeTo('fast', 0.4);
$ulIncludeComments.find('> li > input').prop('disabled', true);
} else {
// If structure is not being exported, the comment options for structure should not be enabled
if ($('#radio_sql_structure_or_data_data').prop('checked')) {
$('#text_sql_header_comment').prop('disabled', false).parent('li').fadeTo('fast', 1);
} else {
$ulIncludeComments.find('> li').fadeTo('fast', 1);
$ulIncludeComments.find('> li > input').prop('disabled', false);
}
}
});
}
export function checkTableSelectAll () {
var total = $('input[name="table_select[]"]').length;
var strChecked = $('input[name="table_structure[]"]:checked').length;
var dataChecked = $('input[name="table_data[]"]:checked').length;
var strAll = $('#table_structure_all');
var dataAll = $('#table_data_all');
if (strChecked === total) {
strAll
.prop('indeterminate', false)
.prop('checked', true);
} else if (strChecked === 0) {
strAll
.prop('indeterminate', false)
.prop('checked', false);
} else {
strAll
.prop('indeterminate', true)
.prop('checked', false);
}
if (dataChecked === total) {
dataAll
.prop('indeterminate', false)
.prop('checked', true);
} else if (dataChecked === 0) {
dataAll
.prop('indeterminate', false)
.prop('checked', false);
} else {
dataAll
.prop('indeterminate', true)
.prop('checked', false);
}
}
export function checkTableSelectStrutureOrData () {
var strChecked = $('input[name="table_structure[]"]:checked').length;
var dataChecked = $('input[name="table_data[]"]:checked').length;
var autoIncrement = $('#checkbox_sql_auto_increment');
var pluginName = $('select#plugins').val();
var dataDiv = '#' + pluginName + '_data';
var structureDiv = '#' + pluginName + '_structure';
if (strChecked === 0) {
$(structureDiv).slideUp('slow');
} else {
$(structureDiv).slideDown('slow');
}
if (dataChecked === 0) {
$(dataDiv).slideUp('slow');
autoIncrement.prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$(dataDiv).slideDown('slow');
autoIncrement.prop('disabled', false).parent().fadeTo('fast', 1);
}
}
export function toggleTableSelectAllStr () {
var strAll = $('#table_structure_all').is(':checked');
if (strAll) {
$('input[name="table_structure[]"]').prop('checked', true);
} else {
$('input[name="table_structure[]"]').prop('checked', false);
}
}
export function toggleTableSelectAllData () {
var dataAll = $('#table_data_all').is(':checked');
if (dataAll) {
$('input[name="table_data[]"]').prop('checked', true);
} else {
$('input[name="table_data[]"]').prop('checked', false);
}
}
export function checkSelectedTables () {
$('.export_table_select tbody tr').each(function () {
checkTableSelected(this);
});
}
export function checkTableSelected (row) {
var $row = $(row);
var tableSelect = $row.find('input[name="table_select[]"]');
var strCheck = $row.find('input[name="table_structure[]"]');
var dataCheck = $row.find('input[name="table_data[]"]');
var data = dataCheck.is(':checked:not(:disabled)');
var structure = strCheck.is(':checked:not(:disabled)');
if (data && structure) {
tableSelect.prop({ checked: true, indeterminate: false });
$row.addClass('marked');
} else if (data || structure) {
tableSelect.prop({ checked: true, indeterminate: true });
$row.removeClass('marked');
} else {
tableSelect.prop({ checked: false, indeterminate: false });
$row.removeClass('marked');
}
}
export function toggleTableSelect (row) {
var $row = $(row);
var tableSelected = $row.find('input[name="table_select[]"]').is(':checked');
if (tableSelected) {
$row.find('input[type="checkbox"]:not(:disabled)').prop('checked', true);
$row.addClass('marked');
} else {
$row.find('input[type="checkbox"]:not(:disabled)').prop('checked', false);
$row.removeClass('marked');
}
}
export function handleAddProcCheckbox () {
if ($('#table_structure_all').is(':checked') === true
&& $('#table_data_all').is(':checked') === true
) {
$('#checkbox_sql_procedure_function').prop('checked', true);
} else {
$('#checkbox_sql_procedure_function').prop('checked', false);
}
}
/**
* Toggles display of options when quick and custom export are selected
*/
export function toggleQuickOrCustom () {
if ($('input[name=\'quick_or_custom\']').length === 0 // custom_no_form option
|| $('#radio_custom_export').prop('checked') // custom
) {
$('#databases_and_tables').show();
$('#rows').show();
$('#output').show();
$('#format_specific_opts').show();
$('#output_quick_export').hide();
var selectedPluginName = $('#plugins').find('option:selected').val();
$('#' + selectedPluginName + '_options').show();
} else { // quick
$('#databases_and_tables').hide();
$('#rows').hide();
$('#output').hide();
$('#format_specific_opts').hide();
$('#output_quick_export').show();
}
}
var time_out;
export function check_time_out (timeLimit) {
if (typeof timeLimit === 'undefined' || timeLimit === 0) {
return true;
}
// margin of one second to avoid race condition to set/access session variable
timeLimit = timeLimit + 1;
var href = 'export.php';
var params = {
'ajax_request' : true,
'check_time_out' : true
};
clearTimeout(time_out);
time_out = setTimeout(function () {
$.get(href, params, function (data) {
if (data.message === 'timeout') {
PMA_ajaxShowMessage(
'<div class="error">' +
messages.strTimeOutError +
'</div>',
false
);
}
});
}, timeLimit * 1000);
}
/**
* Handler for Database/table alias select
*
* @param event object the event object
*
* @return void
*/
export function aliasSelectHandler (event) {
var sel = event.data.sel;
var type = event.data.type;
var inputId = $(this).val();
var $label = $(this).next('label');
$('input#' + $label.attr('for')).addClass('hide');
$('input#' + inputId).removeClass('hide');
$label.attr('for', inputId);
$('#alias_modal ' + sel + '[id$=' + type + ']:visible').addClass('hide');
var $inputWrapper = $('#alias_modal ' + sel + '#' + inputId + type);
$inputWrapper.removeClass('hide');
if (type === '_cols' && $inputWrapper.length > 0) {
var outer = $inputWrapper[0].outerHTML;
// Replace opening tags
var regex = /<dummy_inp/gi;
if (outer.match(regex)) {
var newTag = outer.replace(regex, '<input');
// Replace closing tags
regex = /<\/dummy_inp/gi;
newTag = newTag.replace(regex, '</input');
// Assign replacement
$inputWrapper.replaceWith(newTag);
}
} else if (type === '_tables') {
$('.table_alias_select:visible').trigger('change');
}
$('#alias_modal').dialog('option', 'position', 'center');
}
/**
* Handler for Alias dialog box
*
* @param event object the event object
*
* @return void
*/
export function createAliasModal (event) {
event.preventDefault();
var dlgButtons = {};
dlgButtons[messages.strSaveAndClose] = function () {
$(this).dialog('close');
$('#alias_modal').parent().appendTo($('form[name="dump"]'));
};
$('#alias_modal').dialog({
width: Math.min($(window).width() - 100, 700),
maxHeight: $(window).height(),
modal: true,
dialogClass: 'alias-dialog',
buttons: dlgButtons,
create: function () {
$(this).css('maxHeight', $(window).height() - 150);
var db = CommonParams.get('db');
if (db) {
var option = $('<option></option>');
option.text(db);
option.attr('value', db);
$('#db_alias_select').append(option).val(db).trigger('change');
} else {
var params = {
ajax_request : true,
server : CommonParams.get('server'),
type: 'list-databases'
};
$.post('ajax.php', params, function (response) {
if (response.success === true) {
$.each(response.databases, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#db_alias_select').append(option);
});
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
},
close: function () {
var isEmpty = true;
$(this).find('input[type="text"]').each(function () {
// trim empty input fields on close
if ($(this).val()) {
isEmpty = false;
} else {
$(this).parents('tr').remove();
}
});
// Toggle checkbox based on aliases
$('input#btn_alias_config').prop('checked', !isEmpty);
},
position: { my: 'center top', at: 'center top', of: window }
});
}
export function aliasToggleRow (elm) {
var inputs = elm.parents('tr').find('input,button');
if (elm.val()) {
inputs.attr('disabled', false);
} else {
inputs.attr('disabled', true);
}
}
export function addAlias (type, name, field, value) {
if (value === '') {
return;
}
var row = $('#alias_data tfoot tr').clone();
row.find('th').text(type);
row.find('td:first').text(name);
row.find('input').attr('name', field);
row.find('input').val(value);
row.find('.alias_remove').on('click', function () {
$(this).parents('tr').remove();
});
var matching = $('#alias_data [name="' + $.escapeSelector(field) + '"]');
if (matching.length > 0) {
matching.parents('tr').remove();
}
$('#alias_data tbody').append(row);
}

View File

@ -0,0 +1,95 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { escapeHtml } from '../utils/Sanitise';
/**
* Returns an HTML IMG tag for a particular image from a theme,
* which may be an actual file or an icon from a sprite
*
* @access public
*
* @param {string} image The name of the file to get
*
* @param {string} alternate Used to set 'alt' and 'title' attributes of the image
*
* @param {object} attributes An associative array of other attributes
*
* @return {Object} The requested image, this object has two methods:
* .toString() - Returns the IMG tag for the requested image
* .attr(name) - Returns a particular attribute of the IMG
* tag given it's name
* .attr(name, value) - Sets a particular attribute of the IMG
* tag to the given value
*/
function PMA_getImage (image, alternate, attributes) {
// custom image object, it will eventually be returned by this functions
var retval = {
data: {
// this is private
alt: '',
title: '',
src: 'themes/dot.gif',
},
attr: function (name, value) {
if (value === undefined) {
if (this.data[name] === undefined) {
return '';
} else {
return this.data[name];
}
} else {
this.data[name] = value;
}
},
toString: function () {
var retval = '<' + 'img';
for (var i in this.data) {
retval += ' ' + i + '="' + this.data[i] + '"';
}
retval += ' /' + '>';
return retval;
}
};
// initialise missing parameters
if (attributes === undefined) {
attributes = {};
}
if (alternate === undefined) {
alternate = '';
}
// set alt
if (attributes.alt !== undefined) {
retval.attr('alt', escapeHtml(attributes.alt));
} else {
retval.attr('alt', escapeHtml(alternate));
}
// set title
if (attributes.title !== undefined) {
retval.attr('title', escapeHtml(attributes.title));
} else {
retval.attr('title', escapeHtml(alternate));
}
// set css classes
retval.attr('class', 'icon ic_' + image);
// set all other attrubutes
for (var i in attributes) {
if (i === 'src') {
// do not allow to override the 'src' attribute
continue;
}
retval.attr(i, attributes[i]);
}
return retval;
}
/**
* Module export
*/
export {
PMA_getImage
};

View File

@ -0,0 +1,65 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_Messages as messages } from '../variables/export_variables';
/**
* Functions used in the import tab
*/
/**
* Toggles the hiding and showing of each plugin's options
* according to the currently selected plugin from the dropdown list
*
* @access public
*
* @return {void}
*/
function changePluginOpts () {
$('#format_specific_opts').find('div.format_specific_options').each(function () {
$(this).hide();
});
var selectedPluginName = $('#plugins').find('option:selected').val();
$('#' + selectedPluginName + '_options').fadeIn('slow');
if (selectedPluginName === 'csv') {
$('#import_notification').text(messages.strImportCSV);
} else {
$('#import_notification').text('');
}
}
/**
* Toggles the hiding and showing of each plugin's options and sets the selected value
* in the plugin dropdown list according to the format of the selected file
*
* @access public
*
* @param {string} fname Name of the file
*
* @return {void}
*/
function matchFile (fname) {
var fnameArray = fname.toLowerCase().split('.');
var len = fnameArray.length;
if (len !== 0) {
var extension = fnameArray[len - 1];
if (extension === 'gz' || extension === 'bz2' || extension === 'zip') {
len--;
}
// Only toggle if the format of the file can be imported
if ($('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).length === 1) {
$('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).prop('selected', true);
changePluginOpts();
}
}
}
/**
* Module export
*/
export {
changePluginOpts,
matchFile
};

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,24 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used for page-related settings
* @name Page-related settings
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
/**
* Module import
*/
import { PMA_Messages as messages } from '../variables/export_variables';
/**
* @param {Element} selector jQuery element for which setting need to be show
*
* @access private
*
* @returns {void}
*/
function showSettings (selector) {
var buttons = {};
buttons[PMA_messages.strApply] = function () {
buttons[messages.strApply] = function () {
$('.config-form').submit();
};
buttons[PMA_messages.strCancel] = function () {
buttons[messages.strCancel] = function () {
$(this).dialog('close');
};
@ -22,7 +26,7 @@ function showSettings (selector) {
var $clone = $(selector + ' .page_settings').clone(true);
$(selector)
.dialog({
title: PMA_messages.strPageSettings,
title: messages.strPageSettings,
width: 700,
minHeight: 250,
modal: true,
@ -36,24 +40,28 @@ function showSettings (selector) {
});
}
/**
* @access public
*
* @return {void}
*/
function showPageSettings () {
showSettings('#page_settings_modal');
}
/**
* @access public
*
* @return {void}
*/
function showNaviSettings () {
showSettings('#pma_navigation_settings');
}
AJAX.registerTeardown('page_settings.js', function () {
$('#page_settings_icon').css('display', 'none');
$('#page_settings_icon').off('click');
$('#pma_navigation_settings_icon').off('click');
});
AJAX.registerOnload('page_settings.js', function () {
if ($('#page_settings_modal').length) {
$('#page_settings_icon').css('display', 'inline');
$('#page_settings_icon').on('click', showPageSettings);
}
$('#pma_navigation_settings_icon').on('click', showNaviSettings);
});
/**
* Module export
*/
export {
showNaviSettings,
showPageSettings
};

View File

@ -1,65 +1,39 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Functions used in the import tab
* Module import
*/
import { changePluginOpts, matchFile } from './functions/import';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
import { PMA_Messages as messages } from './variables/export_variables';
/**
* @package PhpMyAdmin
*
* Import
*/
/**
* Toggles the hiding and showing of each plugin's options
* according to the currently selected plugin from the dropdown list
*/
function changePluginOpts () {
$('#format_specific_opts').find('div.format_specific_options').each(function () {
$(this).hide();
});
var selected_plugin_name = $('#plugins').find('option:selected').val();
$('#' + selected_plugin_name + '_options').fadeIn('slow');
if (selected_plugin_name === 'csv') {
$('#import_notification').text(PMA_messages.strImportCSV);
} else {
$('#import_notification').text('');
}
}
/**
* Toggles the hiding and showing of each plugin's options and sets the selected value
* in the plugin dropdown list according to the format of the selected file
*/
function matchFile (fname) {
var fname_array = fname.toLowerCase().split('.');
var len = fname_array.length;
if (len !== 0) {
var extension = fname_array[len - 1];
if (extension === 'gz' || extension === 'bz2' || extension === 'zip') {
len--;
}
// Only toggle if the format of the file can be imported
if ($('select[name=\'format\'] option').filterByValue(fname_array[len - 1]).length === 1) {
$('select[name=\'format\'] option').filterByValue(fname_array[len - 1]).prop('selected', true);
changePluginOpts();
}
}
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('import.js', function () {
function teardownImport () {
$('#plugins').off('change');
$('#input_import_file').off('change');
$('#select_local_import_file').off('change');
$('#input_import_file').off('change').off('focus');
$('#select_local_import_file').off('focus');
$('#text_csv_enclosed').add('#text_csv_escaped').off('keyup');
});
}
AJAX.registerOnload('import.js', function () {
/**
* Binding event handlers on page load
*/
function onloadImport () {
// import_file_form validation.
$(document).on('submit', '#import_file_form', function (event) {
$(document).on('submit', '#import_file_form', function () {
var radioLocalImport = $('#radio_local_import_file');
var radioImport = $('#radio_import_file');
var fileMsg = '<div class="error"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error" /> ' + PMA_messages.strImportDialogMessage + '</div>';
var fileMsg = '<div class="error"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error" /> ' + messages.strImportDialogMessage + '</div>';
if (radioLocalImport.length !== 0) {
// remote upload.
@ -72,7 +46,7 @@ AJAX.registerOnload('import.js', function () {
if (radioLocalImport.is(':checked')) {
if ($('#select_local_import_file').length === 0) {
PMA_ajaxShowMessage('<div class="error"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error" /> ' + PMA_messages.strNoImportFile + ' </div>', false);
PMA_ajaxShowMessage('<div class="error"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error" /> ' + messages.strNoImportFile + ' </div>', false);
return false;
}
@ -152,4 +126,12 @@ AJAX.registerOnload('import.js', function () {
}
return true;
});
});
}
/**
* Module export
*/
export {
teardownImport,
onloadImport
};

86
js/src/index.js Normal file
View File

@ -0,0 +1,86 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import './variables/import_variables';
import { $ } from './utils/JqueryExtended';
import { AJAX } from './ajax';
import './variables/get_config';
import './variables/InlineScripting';
import Console from './console';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
import PMA_commonParams from './variables/common_params';
import PMA_MicroHistory from './classes/MicroHistory';
import FileHandler from './classes/FileHandler';
/**
* Page load event handler
*/
$(function () {
var menuContent = $('<div></div>')
.append($('#serverinfo').clone())
.append($('#topmenucontainer').clone())
.html();
if (history && history.pushState) {
// set initial state reload
var initState = ('state' in window.history && window.history.state !== null);
var initURL = $('#selflink').find('> a').attr('href') || location.href;
var state = {
url : initURL,
menu : menuContent
};
history.replaceState(state, null);
$(window).on('popstate', function (event) {
var initPop = (! initState && location.href === initURL);
initState = true;
// check if popstate fired on first page itself
if (initPop) {
return;
}
var state = event.originalEvent.state;
if (state && state.menu) {
AJAX.$msgbox = PMA_ajaxShowMessage();
var params = 'ajax_request=true' + PMA_commonParams.get('arg_separator') + 'ajax_page_request=true';
var url = state.url || location.href;
$.get(url, params, AJAX.responseHandler);
// TODO: Check if sometimes menu is not retrieved from server,
// Not sure but it seems menu was missing only for printview which
// been removed lately, so if it's right some dead menu checks/fallbacks
// may need to be removed from this file and Header.php
// AJAX.handleMenu.replace(event.originalEvent.state.menu);
}
});
} else {
// Fallback to microhistory mechanism
AJAX.scriptHandler
.load([{ 'name' : 'microhistory.js', 'fire' : 1 }], function () {
// The cache primer is set by the footer class
if (PMA_MicroHistory.primer.url) {
PMA_MicroHistory.menus.add(
PMA_MicroHistory.primer.menuHash,
menuContent
);
}
$(function () {
// Queue up this event twice to make sure that we get a copy
// of the page after all other onload events have been fired
if (PMA_MicroHistory.primer.url) {
PMA_MicroHistory.add(
PMA_MicroHistory.primer.url,
PMA_MicroHistory.primer.scripts,
PMA_MicroHistory.primer.menuHash
);
}
});
});
}
});
let fileHandler = new FileHandler();
fileHandler.init();
$(function () {
Console.initialize();
});

264
js/src/indexes.js Normal file
View File

@ -0,0 +1,264 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import IndexEnum from './utils/IndexEnum';
import * as Indexes from './functions/Indexes';
import { escapeHtml } from './utils/Sanitise';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage } from './utils/show_ajax_messages';
import { PMA_hideShowConnection } from './functions/Table/TableColumns';
import { PMA_previewSQL } from './functions/Sql/PreviewSql';
import PMA_commonParams from './variables/common_params';
import { AJAX } from './ajax';
import { getJSConfirmCommonParam } from './functions/Common';
import { PMA_commonActions } from './classes/CommonActions';
import { PMA_highlightSQL } from './utils/sql';
/**
* @fileoverview function used for index manipulation pages
* @name Table Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
/**
* Unbind all event handlers before tearing down a page
*/
export function teardownIndexes () {
$(document).off('click', '#save_index_frm');
$(document).off('click', '#preview_index_frm');
$(document).off('change', '#select_index_choice');
$(document).off('click', 'a.drop_primary_key_index_anchor.ajax');
$(document).off('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax');
$(document).off('click', '#index_frm input[type=submit]');
$('body').off('change', 'select[name*="field_key"]');
$(document).off('click', '.show_index_dialog');
}
/**
* @description <p>Ajax scripts for table index page</p>
*
* Actions ajaxified here:
* <ul>
* <li>Showing/hiding inputs depending on the index type chosen</li>
* <li>create/edit/drop indexes</li>
* </ul>
*/
export function onloadIndexes () {
// Re-initialize variables.
IndexEnum.primary_indexes = [];
IndexEnum.unique_indexes = [];
IndexEnum.indexes = [];
IndexEnum.fulltext_indexes = [];
IndexEnum.spatial_indexes = [];
// for table creation form
var $engine_selector = $('.create_table_form select[name=tbl_storage_engine]');
if ($engine_selector.length) {
PMA_hideShowConnection($engine_selector);
}
var $form = $('#index_frm');
if ($form.length > 0) {
Indexes.showIndexEditDialog($form);
}
$(document).on('click', '#save_index_frm', function (event) {
event.preventDefault();
var $form = $('#index_frm');
var argsep = PMA_commonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'do_save_data=1' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
$(document).on('click', '#preview_index_frm', function (event) {
event.preventDefault();
PMA_previewSQL($('#index_frm'));
});
$(document).on('change', '#select_index_choice', function (event) {
event.preventDefault();
Indexes.checkIndexType();
Indexes.checkIndexName('index_frm');
});
/**
* Ajax Event handler for 'Drop Index'
*/
$(document).on('click', 'a.drop_primary_key_index_anchor.ajax', function (event) {
event.preventDefault();
var $anchor = $(this);
/**
* @var $curr_row Object containing reference to the current field's row
*/
var $curr_row = $anchor.parents('tr');
/** @var Number of columns in the key */
var rows = $anchor.parents('td').attr('rowspan') || 1;
/** @var Rows that should be hidden */
var $rows_to_hide = $curr_row;
for (var i = 1, $last_row = $curr_row.next(); i < rows; i++, $last_row = $last_row.next()) {
$rows_to_hide = $rows_to_hide.add($last_row);
}
var question = escapeHtml(
$curr_row.children('td')
.children('.drop_primary_key_index_msg')
.val()
);
$anchor.PMA_confirm(question, $anchor.attr('href'), function (url) {
var $msg = PMA_ajaxShowMessage(PMA_messages.strDroppingPrimaryKeyIndex, false);
var params = getJSConfirmCommonParam(this, $anchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
PMA_ajaxRemoveMessage($msg);
var $table_ref = $rows_to_hide.closest('table');
if ($rows_to_hide.length === $table_ref.find('tbody > tr').length) {
// We are about to remove all rows from the table
$table_ref.hide('medium', function () {
$('div.no_indexes_defined').show('medium');
$rows_to_hide.remove();
});
$table_ref.siblings('div.notice').hide('medium');
} else {
// We are removing some of the rows only
$rows_to_hide.hide('medium', function () {
$(this).remove();
});
}
if ($('.result_query').length) {
$('.result_query').remove();
}
if (data.sql_query) {
$('<div class="result_query"></div>')
.html(data.sql_query)
.prependTo('#structure_content');
PMA_highlightSQL($('#page_content'));
}
PMA_commonActions.refreshMain(false, function () {
$('a.ajax[href^=#indexes]').trigger('click');
});
PMA_reloadNavigation();
} else {
PMA_ajaxShowMessage(PMA_messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}); // end $.PMA_confirm()
}); // end Drop Primary Key/Index
/**
*Ajax event handler for index edit
**/
$(document).on('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax', function (event) {
event.preventDefault();
var url;
var title;
if ($(this).find('a').length === 0) {
// Add index
var valid = checkFormElementInRange(
$(this).closest('form')[0],
'added_fields',
'Column count has to be larger than zero.'
);
if (! valid) {
return;
}
url = $(this).closest('form').serialize();
title = PMA_messages.strAddIndex;
} else {
// Edit index
url = $(this).find('a').attr('href');
if (url.substring(0, 16) === 'tbl_indexes.php?') {
url = url.substring(16, url.length);
}
title = PMA_messages.strEditIndex;
}
url += PMA_commonParams.get('arg_separator') + 'ajax_request=true';
Indexes.indexEditorDialog(url, title, function () {
// refresh the page using ajax
PMA_commonActions.refreshMain(false, function () {
$('a.ajax[href^=#indexes]').trigger('click');
});
});
});
/**
* Ajax event handler for advanced index creation during table creation
* and column addition.
*/
$('body').on('change', 'select[name*="field_key"]', function () {
// Index of column on Table edit and create page.
var col_index = /\d+/.exec($(this).attr('name'));
col_index = col_index[0];
// Choice of selected index.
var index_choice = /[a-z]+/.exec($(this).val());
index_choice = index_choice[0];
// Array containing corresponding indexes.
var source_array = null;
if (index_choice === 'none') {
Indexes.PMA_removeColumnFromIndex(col_index);
return false;
}
// Select a source array.
source_array = Indexes.PMA_getIndexArray(index_choice);
if (source_array === null) {
return;
}
if (source_array.length === 0) {
var index = {
'Key_name': (index_choice === 'primary' ? 'PRIMARY' : ''),
'Index_choice': index_choice.toUpperCase()
};
Indexes.PMA_showAddIndexDialog(source_array, 0, [col_index], col_index, index);
} else {
if (index_choice === 'primary') {
var array_index = 0;
var source_length = source_array[array_index].columns.length;
var target_columns = [];
for (var i = 0; i < source_length; i++) {
target_columns.push(source_array[array_index].columns[i].col_index);
}
target_columns.push(col_index);
Indexes.PMA_showAddIndexDialog(source_array, array_index, target_columns, col_index,
source_array[array_index]);
} else {
// If there are multiple columns selected for an index, show advanced dialog.
Indexes.PMA_indexTypeSelectionDialog(source_array, index_choice, col_index);
}
}
});
$(document).on('click', '.show_index_dialog', function (e) {
e.preventDefault();
// Get index details.
var previous_index = $(this).prev('select')
.attr('data-index')
.split(',');
var index_choice = previous_index[0];
var array_index = previous_index[1];
var source_array = Indexes.PMA_getIndexArray(index_choice);
var source_length = source_array[array_index].columns.length;
var target_columns = [];
for (var i = 0; i < source_length; i++) {
target_columns.push(source_array[array_index].columns[i].col_index);
}
Indexes.PMA_showAddIndexDialog(source_array, array_index, target_columns, -1, source_array[array_index]);
});
$('#index_frm').on('submit', function () {
if (typeof(this.elements['index[Key_name]'].disabled) !== 'undefined') {
this.elements['index[Key_name]'].disabled = false;
}
});
}

28
js/src/key_handler.js Normal file
View File

@ -0,0 +1,28 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { onKeyDownArrowsHandler } from './functions/KeyHandler';
function teardownKeyhandler () {
$(document).off('keydown keyup', '#table_columns');
$(document).off('keydown keyup', 'table.insertRowTable');
}
function onloadKeyhandler () {
$(document).on('keydown keyup', '#table_columns', function (event) {
onKeyDownArrowsHandler(event.originalEvent);
});
$(document).on('keydown keyup', 'table.insertRowTable', function (event) {
onKeyDownArrowsHandler(event.originalEvent);
});
}
/**
* Module export
*/
export {
teardownKeyhandler,
onloadKeyhandler
};

View File

@ -0,0 +1,41 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
import PMA_commonParams from './variables/common_params';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
import { AJAX } from './ajax';
import { removeColumnFromMultiSort } from './functions/ColumnSorting';
/**
* @fileoverview Implements the shiftkey + click remove column
* from order by clause funcationality
* @name columndelete
*
* @requires jQuery
*/
export function onloadMultiColumnSort () {
$(document).on('click', 'th.draggable.column_heading.pointer.marker a', function (event) {
var url = $(this).parent().find('input').val();
var argsep = PMA_commonParams.get('arg_separator');
if (event.ctrlKey || event.altKey) {
event.preventDefault();
let params = removeColumnFromMultiSort(url, $(this).parent());
if (params) {
AJAX.source = $(this);
PMA_ajaxShowMessage();
params += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('sql.php', params, AJAX.responseHandler);
}
} else if (event.shiftKey) {
event.preventDefault();
AJAX.source = $(this);
PMA_ajaxShowMessage();
let params = url.substring(url.indexOf('?') + 1);
params += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('sql.php', params, AJAX.responseHandler);
}
});
}
export function teardownMultiColumnSort () {
$(document).off('click', 'th.draggable.column_heading.pointer.marker a');
}

398
js/src/navigation.js Normal file
View File

@ -0,0 +1,398 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* Module import */
import * as Navigation from './functions/navigation';
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import CommonParams from './variables/common_params';
import { PMA_ajaxShowMessage, PMA_ajaxRemoveMessage, PMA_tooltip } from './utils/show_ajax_messages';
import { isStorageSupported } from './functions/config';
import { indexEditorDialog } from './functions/Indexes';
import RTE from './classes/RTE';
/**
* function used in or for navigation panel
*
* @package phpMyAdmin-Navigation
*/
/**
* Executed on page load
*/
$(function () {
if (! $('#pma_navigation').length) {
// Don't bother running any code if the navigation is not even on the page
return;
}
// Do not let the page reload on submitting the fast filter
$(document).on('submit', '.fast_filter', function (event) {
event.preventDefault();
});
// Fire up the resize handlers
new Navigation.ResizeHandler();
/**
* opens/closes (hides/shows) tree elements
* loads data via ajax
*/
$(document).on('click', '#pma_navigation_tree a.expander', function (event) {
event.preventDefault();
event.stopImmediatePropagation();
var $icon = $(this).find('img');
if ($icon.is('.ic_b_plus')) {
Navigation.expandTreeNode($(this));
} else {
Navigation.collapseTreeNode($(this));
}
});
/**
* Register event handler for click on the reload
* navigation icon at the top of the panel
*/
$(document).on('click', '#pma_navigation_reload', function (event) {
event.preventDefault();
// reload icon object
var $icon = $(this).find('img');
// source of the hidden throbber icon
var icon_throbber_src = $('#pma_navigation').find('.throbber').attr('src');
// source of the reload icon
var icon_reload_src = $icon.attr('src');
// replace the source of the reload icon with the one for throbber
$icon.attr('src', icon_throbber_src);
Navigation.PMA_reloadNavigation();
// after one second, put back the reload icon
setTimeout(function () {
$icon.attr('src', icon_reload_src);
}, 1000);
});
$(document).on('change', '#navi_db_select', function () {
if (! $(this).val()) {
CommonParams.set('db', '');
Navigation.PMA_reloadNavigation();
}
$(this).closest('form').trigger('submit');
});
/**
* Register event handler for click on the collapse all
* navigation icon at the top of the navigation tree
*/
$(document).on('click', '#pma_navigation_collapse', function (event) {
event.preventDefault();
$('#pma_navigation_tree').find('a.expander').each(function () {
var $icon = $(this).find('img');
if ($icon.is('.ic_b_minus')) {
$(this).click();
}
});
});
/**
* Register event handler to toggle
* the 'link with main panel' icon on mouseenter.
*/
$(document).on('mouseenter', '#pma_navigation_sync', function (event) {
event.preventDefault();
var synced = $('#pma_navigation_tree').hasClass('synced');
var $img = $('#pma_navigation_sync').children('img');
if (synced) {
$img.removeClass('ic_s_link').addClass('ic_s_unlink');
} else {
$img.removeClass('ic_s_unlink').addClass('ic_s_link');
}
});
/**
* Register event handler to toggle
* the 'link with main panel' icon on mouseout.
*/
$(document).on('mouseout', '#pma_navigation_sync', function (event) {
event.preventDefault();
var synced = $('#pma_navigation_tree').hasClass('synced');
var $img = $('#pma_navigation_sync').children('img');
if (synced) {
$img.removeClass('ic_s_unlink').addClass('ic_s_link');
} else {
$img.removeClass('ic_s_link').addClass('ic_s_unlink');
}
});
/**
* Register event handler to toggle
* the linking with main panel behavior
*/
$(document).on('click', '#pma_navigation_sync', function (event) {
event.preventDefault();
var synced = $('#pma_navigation_tree').hasClass('synced');
var $img = $('#pma_navigation_sync').children('img');
if (synced) {
$img
.removeClass('ic_s_unlink')
.addClass('ic_s_link')
.attr('alt', PMA_messages.linkWithMain)
.attr('title', PMA_messages.linkWithMain);
$('#pma_navigation_tree')
.removeClass('synced')
.find('li.selected')
.removeClass('selected');
} else {
$img
.removeClass('ic_s_link')
.addClass('ic_s_unlink')
.attr('alt', PMA_messages.unlinkWithMain)
.attr('title', PMA_messages.unlinkWithMain);
$('#pma_navigation_tree').addClass('synced');
Navigation.PMA_showCurrentNavigation();
}
});
/**
* Bind all "fast filter" events
*/
$(document).on('click', '#pma_navigation_tree li.fast_filter span', Navigation.PMA_fastFilter.events.clear);
$(document).on('focus', '#pma_navigation_tree li.fast_filter input.searchClause', Navigation.PMA_fastFilter.events.focus);
$(document).on('blur', '#pma_navigation_tree li.fast_filter input.searchClause', Navigation.PMA_fastFilter.events.blur);
$(document).on('keyup', '#pma_navigation_tree li.fast_filter input.searchClause', Navigation.PMA_fastFilter.events.keyup);
/**
* Ajax handler for pagination
*/
$(document).on('click', '#pma_navigation_tree div.pageselector a.ajax', function (event) {
event.preventDefault();
Navigation.PMA_navigationTreePagination($(this));
});
/**
* Node highlighting
*/
$(document).on(
'mouseover',
'#pma_navigation_tree.highlight li:not(.fast_filter)',
function () {
if ($('li:visible', this).length === 0) {
$(this).addClass('activePointer');
}
}
);
$(document).on(
'mouseout',
'#pma_navigation_tree.highlight li:not(.fast_filter)',
function () {
$(this).removeClass('activePointer');
}
);
/** Create a Routine, Trigger or Event */
$(document).on('click', 'li.new_procedure a.ajax, li.new_function a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('routine');
dialog.editorDialog(1, $(this));
});
$(document).on('click', 'li.new_trigger a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('trigger');
dialog.editorDialog(1, $(this));
});
$(document).on('click', 'li.new_event a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('event');
dialog.editorDialog(1, $(this));
});
/** Edit Routines, Triggers or Events */
$(document).on('click', 'li.procedure > a.ajax, li.function > a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('routine');
dialog.editorDialog(0, $(this));
});
$(document).on('click', 'li.trigger > a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('trigger');
dialog.editorDialog(0, $(this));
});
$(document).on('click', 'li.event > a.ajax', function (event) {
event.preventDefault();
var dialog = new RTE.object('event');
dialog.editorDialog(0, $(this));
});
/** Execute Routines */
$(document).on('click', 'li.procedure div a.ajax img,' +
' li.function div a.ajax img', function (event) {
event.preventDefault();
var dialog = new RTE.object('routine');
dialog.executeDialog($(this).parent());
});
/** Export Triggers and Events */
$(document).on('click', 'li.trigger div:eq(1) a.ajax img,' +
' li.event div:eq(1) a.ajax img', function (event) {
event.preventDefault();
var dialog = new RTE.object();
dialog.exportDialog($(this).parent());
});
/** New index */
$(document).on('click', '#pma_navigation_tree li.new_index a.ajax', function (event) {
event.preventDefault();
var url = $(this).attr('href').substr(
$(this).attr('href').indexOf('?') + 1
) + CommonParams.get('arg_separator') + 'ajax_request=true';
var title = PMA_messages.strAddIndex;
indexEditorDialog(url, title);
});
/** Edit index */
$(document).on('click', 'li.index a.ajax', function (event) {
event.preventDefault();
var url = $(this).attr('href').substr(
$(this).attr('href').indexOf('?') + 1
) + CommonParams.get('arg_separator') + 'ajax_request=true';
var title = PMA_messages.strEditIndex;
indexEditorDialog(url, title);
});
/** New view */
$(document).on('click', 'li.new_view a.ajax', function (event) {
event.preventDefault();
PMA_createViewDialog($(this));
});
/** Hide navigation tree item */
$(document).on('click', 'a.hideNavItem.ajax', function (event) {
event.preventDefault();
$.ajax({
type: 'POST',
data: {
server: CommonParams.get('server'),
},
url: $(this).attr('href') + CommonParams.get('arg_separator') + 'ajax_request=true',
success: function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Navigation.PMA_reloadNavigation();
} else {
PMA_ajaxShowMessage(data.error);
}
}
});
});
/** Display a dialog to choose hidden navigation items to show */
$(document).on('click', 'a.showUnhide.ajax', function (event) {
event.preventDefault();
var $msg = PMA_ajaxShowMessage();
$.get($(this).attr('href') + CommonParams.get('arg_separator') + 'ajax_request=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
PMA_ajaxRemoveMessage($msg);
var buttonOptions = {};
buttonOptions[PMA_messages.strClose] = function () {
$(this).dialog('close');
};
$('<div/>')
.attr('id', 'unhideNavItemDialog')
.append(data.message)
.dialog({
width: 400,
minWidth: 200,
modal: true,
buttons: buttonOptions,
title: PMA_messages.strUnhideNavItem,
close: function () {
$(this).remove();
}
});
} else {
PMA_ajaxShowMessage(data.error);
}
});
});
/** Show a hidden navigation tree item */
$(document).on('click', 'a.unhideNavItem.ajax', function (event) {
event.preventDefault();
var $tr = $(this).parents('tr');
var $msg = PMA_ajaxShowMessage();
$.ajax({
type: 'POST',
data: {
server: CommonParams.get('server'),
},
url: $(this).attr('href') + CommonParams.get('arg_separator') + 'ajax_request=true',
success: function (data) {
PMA_ajaxRemoveMessage($msg);
if (typeof data !== 'undefined' && data.success === true) {
$tr.remove();
Navigation.PMA_reloadNavigation();
} else {
PMA_ajaxShowMessage(data.error);
}
}
});
});
// Add/Remove favorite table using Ajax.
$(document).on('click', '.favorite_table_anchor', function (event) {
event.preventDefault();
var $self = $(this);
var anchor_id = $self.attr('id');
if ($self.data('favtargetn') !== null) {
if ($('a[data-favtargets="' + $self.data('favtargetn') + '"]').length > 0) {
$('a[data-favtargets="' + $self.data('favtargetn') + '"]').trigger('click');
return;
}
}
$.ajax({
url: $self.attr('href'),
cache: false,
type: 'POST',
data: {
favorite_tables: (isStorageSupported('localStorage') && typeof window.localStorage.favorite_tables !== 'undefined')
? window.localStorage.favorite_tables
: '',
server: CommonParams.get('server'),
},
success: function (data) {
if (data.changes) {
$('#pma_favorite_list').html(data.list);
$('#' + anchor_id).parent().html(data.anchor);
PMA_tooltip(
$('#' + anchor_id),
'a',
$('#' + anchor_id).attr('title')
);
// Update localStorage.
if (isStorageSupported('localStorage')) {
window.localStorage.favorite_tables = data.favorite_tables;
}
} else {
PMA_ajaxShowMessage(data.message);
}
}
});
});
// Check if session storage is supported
if (isStorageSupported('sessionStorage')) {
var storage = window.sessionStorage;
// remove tree from storage if Navi_panel config form is submitted
$(document).on('submit', 'form.config-form', function () {
storage.removeItem('navTreePaths');
});
// Initialize if no previous state is defined
if ($('#pma_navigation_tree_content').length &&
typeof storage.navTreePaths === 'undefined'
) {
Navigation.PMA_reloadNavigation();
} else if (CommonParams.get('server').toString() === storage.server.toString() &&
CommonParams.get('token').toString() === storage.token.toString()
) {
// Reload the tree to the state before page refresh
Navigation.PMA_reloadNavigation(Navigation.navFilterStateRestore, JSON.parse(storage.navTreePaths));
} else {
// If the user is different
Navigation.navTreeStateUpdate();
}
}
});

299
js/src/normalization.js Normal file
View File

@ -0,0 +1,299 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Module import
*/
import { PMA_Messages as PMA_messages } from './variables/export_variables';
import PMA_commonParams from './variables/common_params';
import { PMA_ajaxShowMessage } from './utils/show_ajax_messages';
import { PMA_sprintf } from './utils/sprintf';
import { escapeHtml } from './utils/Sanitise';
import {
goToStep2,
goToStep3,
moveRepeatingGroup,
appendHtmlColumnsList
} from './functions/Table/Normalization';
import NormalizationEnum from './utils/NormalizationEnum';
import { indexEditorDialog } from './functions/Indexes';
/**
* @fileoverview events handling from normalization page
* @name normalization
*
* @requires jQuery
*/
/**
* AJAX scripts for normalization.php
*
*/
export function teardownNormalization () {
$('#extra').off('click', '#selectNonAtomicCol');
$('#splitGo').off('click');
$('.tblFooters').off('click', '#saveSplit');
$('#extra').off('click', '#addNewPrimary');
$('.tblFooters').off('click', '#saveNewPrimary');
$('#extra').off('click', '#removeRedundant');
$('#mainContent p').off('click', '#createPrimaryKey');
$('#mainContent').off('click', '#backEditPd');
$('#mainContent').off('click', '#showPossiblePd');
$('#mainContent').off('click', '.pickPd');
}
export function onloadNormalization () {
var selectedCol;
NormalizationEnum.normalizeto = $('#mainContent').data('normalizeto');
$('#extra').on('click', '#selectNonAtomicCol', function () {
if ($(this).val() === 'no_such_col') {
goToStep2();
} else {
selectedCol = $(this).val();
}
});
$('#splitGo').on('click', function () {
if (!selectedCol || selectedCol === '') {
return false;
}
var numField = $('#numField').val();
$.get(
'normalization.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'splitColumn': true,
'numFields': numField
},
function (data) {
if (data.success === true) {
$('#newCols').html(data.message);
$('.default_value').hide();
$('.enum_notice').hide();
$('<input />')
.attr({ type: 'submit', id: 'saveSplit', value: PMA_messages.strSave })
.appendTo('.tblFooters');
var cancelSplitButton = $('<input />')
.attr({ type: 'submit', id: 'cancelSplit', value: PMA_messages.strCancel })
.on('click', function () {
$('#newCols').html('');
$(this).parent().html('');
})
.appendTo('.tblFooters');
}
}
);
return false;
});
$('.tblFooters').on('click','#saveSplit', function () {
central_column_list = [];
if ($('#newCols #field_0_1').val() === '') {
$('#newCols #field_0_1').focus();
return false;
}
var argsep = PMA_commonParams.get('arg_separator');
var datastring = $('#newCols :input').serialize();
datastring += argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last';
$.post('tbl_addfield.php', datastring, function (data) {
if (data.success) {
$.post(
'sql.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'dropped_column': selectedCol,
'purge' : 1,
'sql_query': 'ALTER TABLE `' + PMA_commonParams.get('table') + '` DROP `' + selectedCol + '`;',
'is_js_confirmed': 1
},
function (data) {
if (data.success === true) {
appendHtmlColumnsList();
$('#newCols').html('');
$('.tblFooters').html('');
} else {
PMA_ajaxShowMessage(data.error, false);
}
selectedCol = '';
}
);
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
$('#extra').on('click', '#addNewPrimary', function () {
$.get(
'normalization.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'addNewPrimary': true
},
function (data) {
if (data.success === true) {
$('#newCols').html(data.message);
$('.default_value').hide();
$('.enum_notice').hide();
$('<input />')
.attr({ type: 'submit', id: 'saveNewPrimary', value: PMA_messages.strSave })
.appendTo('.tblFooters');
$('<input />')
.attr({ type: 'submit', id: 'cancelSplit', value: PMA_messages.strCancel })
.on('click', function () {
$('#newCols').html('');
$(this).parent().html('');
})
.appendTo('.tblFooters');
} else {
PMA_ajaxShowMessage(data.error, false);
}
}
);
return false;
});
$('.tblFooters').on('click', '#saveNewPrimary', function () {
var datastring = $('#newCols :input').serialize();
var argsep = PMA_commonParams.get('arg_separator');
datastring += argsep + 'field_key[0]=primary_0' + argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last';
$.post('tbl_addfield.php', datastring, function (data) {
if (data.success === true) {
$('#mainContent h4').html(PMA_messages.strPrimaryKeyAdded);
$('#mainContent p').html(PMA_messages.strToNextStep);
$('#mainContent #extra').html('');
$('#mainContent #newCols').html('');
$('.tblFooters').html('');
setTimeout(function () {
goToStep3();
}, 2000);
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
$('#extra').on('click', '#removeRedundant', function () {
var dropQuery = 'ALTER TABLE `' + PMA_commonParams.get('table') + '` ';
$('#extra input[type=checkbox]:checked').each(function () {
dropQuery += 'DROP `' + $(this).val() + '`, ';
});
dropQuery = dropQuery.slice(0, -2);
$.post(
'sql.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'sql_query': dropQuery,
'is_js_confirmed': 1
},
function (data) {
if (data.success === true) {
goToStep2('goToFinish1NF');
} else {
PMA_ajaxShowMessage(data.error, false);
}
}
);
});
$('#extra').on('click', '#moveRepeatingGroup', function () {
var repeatingCols = '';
$('#extra input[type=checkbox]:checked').each(function () {
repeatingCols += $(this).val() + ', ';
});
if (repeatingCols !== '') {
var newColName = $('#extra input[type=checkbox]:checked:first').val();
repeatingCols = repeatingCols.slice(0, -2);
var confirmStr = PMA_sprintf(PMA_messages.strMoveRepeatingGroup, escapeHtml(repeatingCols), escapeHtml(PMA_commonParams.get('table')));
confirmStr += '<input type="text" name="repeatGroupTable" placeholder="' + PMA_messages.strNewTablePlaceholder + '"/>' +
'( ' + escapeHtml(NormalizationEnum.primary_key.toString()) + ', <input type="text" name="repeatGroupColumn" placeholder="' + PMA_messages.strNewColumnPlaceholder + '" value="' + escapeHtml(newColName) + '">)' +
'</ol>';
$('#newCols').html(confirmStr);
$('<input />')
.attr({ type: 'submit', value: PMA_messages.strCancel })
.on('click', function () {
$('#newCols').html('');
$('#extra input[type=checkbox]').prop('checked', false);
})
.appendTo('.tblFooters');
$('<input />')
.attr({ type: 'submit', value: PMA_messages.strGo })
.on('click', function () {
moveRepeatingGroup(repeatingCols);
})
.appendTo('.tblFooters');
}
});
$('#mainContent p').on('click', '#createPrimaryKey', function (event) {
event.preventDefault();
var url = { create_index: 1,
server: PMA_commonParams.get('server'),
db: PMA_commonParams.get('db'),
table: PMA_commonParams.get('table'),
added_fields: 1,
add_fields:1,
index: { Key_name:'PRIMARY' },
ajax_request: true
};
var title = PMA_messages.strAddPrimaryKey;
indexEditorDialog(url, title, function () {
// on success
$('.sqlqueryresults').remove();
$('.result_query').remove();
$('.tblFooters').html('');
goToStep2('goToStep3');
});
return false;
});
$('#mainContent').on('click', '#backEditPd', function () {
$('#mainContent').html(NormalizationEnum.backup);
});
$('#mainContent').on('click', '#showPossiblePd', function () {
if ($(this).hasClass('hideList')) {
$(this).html('+ ' + PMA_messages.strShowPossiblePd);
$(this).removeClass('hideList');
$('#newCols').slideToggle('slow');
return false;
}
if ($('#newCols').html() !== '') {
$('#showPossiblePd').html('- ' + PMA_messages.strHidePd);
$('#showPossiblePd').addClass('hideList');
$('#newCols').slideToggle('slow');
return false;
}
$('#newCols').insertAfter('#mainContent h4');
$('#newCols').html('<div class="center">' + PMA_messages.strLoading + '<br/>' + PMA_messages.strWaitForPd + '</div>');
$.post(
'normalization.php',
{
'ajax_request': true,
'db': PMA_commonParams.get('db'),
'table': PMA_commonParams.get('table'),
'findPdl': true
}, function (data) {
$('#showPossiblePd').html('- ' + PMA_messages.strHidePd);
$('#showPossiblePd').addClass('hideList');
$('#newCols').html(data.message);
});
});
$('#mainContent').on('click', '.pickPd', function () {
var strColsLeft = $(this).next('.determinants').html();
var colsLeft = strColsLeft.split(',');
var strColsRight = $(this).next().next().html();
var colsRight = strColsRight.split(',');
for (var i in colsRight) {
$('form[data-colname="' + colsRight[i].trim() + '"] input[type="checkbox"]').prop('checked', false);
for (var j in colsLeft) {
$('form[data-colname="' + colsRight[i].trim() + '"] input[value="' + colsLeft[j].trim() + '"]').prop('checked', true);
}
}
});
}

49
js/src/page_settings.js Normal file
View File

@ -0,0 +1,49 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used for page-related settings
* @name Page-related settings
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*/
/**
* Module import
*/
import {
showNaviSettings,
showPageSettings
} from './functions/page_settings';
/**
* @package PhpMyAdmin
*
* Page Settings
*/
/**
* Unbind all event handlers before tearing down a page.
*/
function teardownPageSettings () {
$('#page_settings_icon').css('display', 'none');
$('#page_settings_icon').off('click');
$('#pma_navigation_settings_icon').off('click');
}
/**
* Binding event handler on page load.
*/
function onloadPageSettings () {
if ($('#page_settings_modal').length) {
$('#page_settings_icon').css('display', 'inline');
$('#page_settings_icon').on('click', showPageSettings);
}
$('#pma_navigation_settings_icon').on('click', showNaviSettings);
}
export {
teardownPageSettings,
onloadPageSettings
};

Some files were not shown because too many files have changed in this diff Show More