├── README.md ├── config ├── defaults.js ├── demoMap.js └── templateConfig.js ├── css └── main.css ├── images ├── SelectAll.png ├── SelectNone.png ├── ajax-loader.gif ├── error.png └── error_gray.png ├── index.html ├── js ├── Operations │ └── ApplyStyle.js ├── dijit │ ├── ColorSelectorDialog.js │ ├── UniqueComboBox.js │ └── css │ │ └── ColorSelectorDialog.css ├── jsoneditor-master │ ├── .gitignore │ ├── .npmignore │ ├── CONTRIBUTING.md │ ├── HISTORY.md │ ├── LICENSE │ ├── NOTICE │ ├── README.md │ ├── bower.json │ ├── dist │ │ ├── img │ │ │ └── jsoneditor-icons.png │ │ ├── jsoneditor.css │ │ ├── jsoneditor.js │ │ ├── jsoneditor.map │ │ ├── jsoneditor.min.css │ │ └── jsoneditor.min.js │ ├── docs │ │ ├── api.md │ │ ├── shortcut_keys.md │ │ └── usage.md │ ├── examples │ │ ├── 01_basic_usage.html │ │ ├── 02_viewer.html │ │ ├── 03_switch_mode.html │ │ ├── 04_load_and_save.html │ │ ├── 05_custom_fields_editable.html │ │ └── requirejs_demo │ │ │ ├── requirejs_demo.html │ │ │ └── scripts │ │ │ ├── main.js │ │ │ └── require.js │ ├── gulpfile.js │ ├── index.js │ ├── misc │ │ ├── codeeditor.png │ │ ├── how_to_publish.md │ │ ├── jsoneditor.png │ │ └── todo.txt │ ├── package.json │ ├── src │ │ ├── css │ │ │ ├── contextmenu.css │ │ │ ├── img │ │ │ │ ├── description.txt │ │ │ │ ├── export.sh │ │ │ │ ├── jsoneditor-icons.png │ │ │ │ └── jsoneditor-icons.svg │ │ │ ├── jsoneditor.css │ │ │ ├── menu.css │ │ │ └── searchbox.css │ │ └── js │ │ │ ├── ContextMenu.js │ │ │ ├── Highlighter.js │ │ │ ├── History.js │ │ │ ├── JSONEditor.js │ │ │ ├── Node.js │ │ │ ├── SearchBox.js │ │ │ ├── ace │ │ │ ├── index.js │ │ │ └── theme-jsoneditor.js │ │ │ ├── appendNodeFactory.js │ │ │ ├── header.js │ │ │ ├── modeswitcher.js │ │ │ ├── textmode.js │ │ │ ├── treemode.js │ │ │ └── util.js │ └── test │ │ ├── couchdbeditor.html │ │ ├── largefile.json │ │ ├── test_build.html │ │ ├── test_build_min.html │ │ └── util.test.js ├── main.js ├── nls │ ├── fr │ │ └── resources.js │ └── resources.js └── template.js ├── oauth-callback.html ├── previous ├── index_OLD.html └── main_OLD.js └── resources ├── VectorBasemapStyleEditor_004 ├── VectorBasemapStyleEditor_004.html ├── VectorBasemapStyleEditor_004.mp4 ├── VectorBasemapStyleEditor_004_First_Frame.png ├── VectorBasemapStyleEditor_004_Thumbnails.png ├── VectorBasemapStyleEditor_004_config.xml ├── VectorBasemapStyleEditor_004_controller.swf ├── VectorBasemapStyleEditor_004_embed.css ├── VectorBasemapStyleEditor_004_player.html ├── scripts │ ├── config_xml.js │ └── techsmith-smart-player.min.js └── skins │ └── overlay │ ├── spritesheet.min.css │ ├── spritesheet.png │ └── techsmith-smart-player.min.css └── configurationPanel.js /README.md: -------------------------------------------------------------------------------- 1 | 2 | #### Live Demo 3 | - https://maps.esri.com/jg/VectorBasemapStyleEditor/ 4 | 5 | #### Vector Basemap Style Editor 6 | Edit the styles of Esri Vector Basemaps via ArcGIS.com items 7 | - Always make a backup copy of the ArcGIS.com item before using this app 8 | - The user experience is focused on color replacement 9 | - Edit style json directly by clicking on 'id' cell. Warning: use caution! 10 | 11 | #### Deployment 12 | - Copy your application to a web accessible location 13 | - Create a new item in your Org to your version of this application 14 | - Register the new application item and make note of the App ID 15 | - In /config/default.js change the oauthappid to the above App ID 16 | 17 | #### Version 18 | - 0.1.4 19 | - JS API 3.23 20 | 21 | 22 | #### License 23 | 24 | > Copyright 2017 Esri 25 | > 26 | > Licensed under the Apache License, Version 2.0 (the "License"); 27 | > you may not use this file except in compliance with the License. 28 | > You may obtain a copy of the License at 29 | > 30 | > http://www.apache.org/licenses/LICENSE-2.0 31 | > 32 | > Unless required by applicable law or agreed to in writing, software 33 | > distributed under the License is distributed on an "AS IS" BASIS, 34 | > WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 | > See the License for the specific language governing permissions and 36 | > limitations under the License. 37 | -------------------------------------------------------------------------------- /config/defaults.js: -------------------------------------------------------------------------------- 1 | /*global define,location */ 2 | /*jslint sloppy:true */ 3 | /* 4 | | Copyright 2014 Esri 5 | | 6 | | Licensed under the Apache License, Version 2.0 (the "License"); 7 | | you may not use this file except in compliance with the License. 8 | | You may obtain a copy of the License at 9 | | 10 | | http://www.apache.org/licenses/LICENSE-2.0 11 | | 12 | | Unless required by applicable law or agreed to in writing, software 13 | | distributed under the License is distributed on an "AS IS" BASIS, 14 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | | See the License for the specific language governing permissions and 16 | | limitations under the License. 17 | */ 18 | define({ 19 | //Default configuration settings for the application. This is where you'll define things like a bing maps key, 20 | //default web map, default app color theme and more. These values can be overwritten by template configuration settings and url parameters. 21 | "appid": "", 22 | "webmap": "589a3ac57b7844618f9a8ee94ca49d59", 23 | "oauthappid": "hrFP8yDGOiGFx4ub", 24 | //Group templates must support a group url parameter. This will contain the id of the group. 25 | "group": "", 26 | //Enter the url to the proxy if needed by the application. See the 'Using the proxy page' help topic for details 27 | //http://developers.arcgis.com/en/javascript/jshelp/ags_proxy.html 28 | "proxyurl": "https://maps.esri.com/proxy/DotNet/proxy.ashx", 29 | //Example of a template specific property. If your template had several color schemes 30 | //you could define the default here and setup configuration settings to allow users to choose a different 31 | //color theme. 32 | "theme": "blue", 33 | "bingKey": "", //Enter the url to your organizations bing maps key if you want to use bing basemaps 34 | //Defaults to arcgis.com. Set this value to your portal or organization host name. 35 | "sharinghost": "https://www.arcgis.com", 36 | "units": null, 37 | //If your applcation needs to edit feature layer fields set this value to true. When false the map will 38 | //be dreated with layers that are not set to editable which allows the FeatureLayer to load features optimally. 39 | "editable": false, 40 | "helperServices": { 41 | "geometry": { 42 | "url": null 43 | }, 44 | "printTask": { 45 | "url": null 46 | }, 47 | "elevationSync": { 48 | "url": null 49 | }, 50 | "geocode": [{ 51 | "url": null 52 | }] 53 | } 54 | }); -------------------------------------------------------------------------------- /config/demoMap.js: -------------------------------------------------------------------------------- 1 | define({ 2 | "item": { 3 | "id": "24e01ef45d40423f95300ad2abc5038a", 4 | "owner": "khutchins_jsapi", 5 | "orgId": "V6ZHFr6zdgNZuVG0", 6 | "created": 1386962036000, 7 | "modified": 1425412391000, 8 | "guid": null, 9 | "name": null, 10 | "title": "Farmers Markets", 11 | "type": "Web Map", 12 | "typeKeywords": ["ArcGIS Online", "Explorer Web Map", "Map", "Online Map", "Web Map"], 13 | "description": "A heat map showing the concentration of farmers markets across the US. ", 14 | "tags": ["map", "cities"], 15 | "snippet": "A heat map showing the concentration of farmers markets across the US.", 16 | "thumbnail": "thumbnail/ago_downloaded.png", 17 | "documentation": null, 18 | "extent": [[-123.4521, 46.9231], [-121.0021, 48.0258]], 19 | "spatialReference": null, 20 | "accessInformation": null, 21 | "licenseInfo": null, 22 | "culture": "en", 23 | "properties": null, 24 | "url": null, 25 | "access": "public", 26 | "size": 4519, 27 | "appCategories": [], 28 | "industries": [], 29 | "languages": [], 30 | "largeThumbnail": null, 31 | "banner": null, 32 | "screenshots": [], 33 | "listed": false, 34 | "commentsEnabled": true, 35 | "numComments": 0, 36 | "numRatings": 0, 37 | "avgRating": 0, 38 | "numViews": 50960 39 | }, 40 | "itemData": { 41 | "operationalLayers": [ 42 | { 43 | "id": "Farmers_Market_Locations_6307", 44 | "layerType": "ArcGISFeatureLayer", 45 | "url": "http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Farmers_Market_Locations/FeatureServer/0", 46 | "visibility": true, 47 | "opacity": 0.5346534653465347, 48 | "title": "Farmers Market Locations", 49 | "itemId": "4668eb9347f446bb87b4ca8f6da21550", 50 | "layerDefinition": { 51 | "drawingInfo": { 52 | "renderer": { 53 | "type": "simple", 54 | "symbol": { 55 | "angle": 0, 56 | "xoffset": 0, 57 | "yoffset": 12, 58 | "type": "esriPMS", 59 | "url": "http://static.arcgis.com/images/Symbols/Basic1/Orange_1_Tear_Pin2.png", 60 | "imageData": "iVBORw0KGgoAAAANSUhEUgAAAHkAAAB5CAYAAAAd+o5JAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADKGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwMTQgNzkuMTU2Nzk3LCAyMDE0LzA4LzIwLTA5OjUzOjAyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4RUU2RURGQzZDNDkxMUU0QTM3RThDNzNCRDk3QTcyQSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4RUU2RURGRDZDNDkxMUU0QTM3RThDNzNCRDk3QTcyQSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjhFRTZFREZBNkM0OTExRTRBMzdFOEM3M0JEOTdBNzJBIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjhFRTZFREZCNkM0OTExRTRBMzdFOEM3M0JEOTdBNzJBIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+gzeecQAAB41JREFUeF7tnc2R1EgUhDEBE7jtFRMwARMwARPwgPOeMAETMAETMIHr3mbzdagnNM2nbv28zO4RyogvNiLZkVr5pqpLVSXNm6enp4Odg+bBvkDzYF+gebAv0DzYF2ge7As0D/YFmgf7As2DfYHmwb5A82BfoHmwL9BM4NR///7zQXwW38QP8XSDn+K7+CI+DIexifJwgmaCbqk4H0UV9begQi6liv5JvB1O0SbKwwmaCTqkArwT1fq6CjtF/fK8G067WZSHEzQTbJECfyu+DgVI0lJsysMJmgnWSiHXd6275d6ieo/V3Tjl4QTNBEulUKtrnjOISvFLvB8+3iJRHk7QTLBECrMGVfduvVN8Hj7mbFEeTtBMMFcKsUa4FO4j8W34uLNEeThBM8EcVXgXYT4y9VlnfU9THk7QTHBLCuweo+etfB8+/lVRHk7QTHBNCus1dNFT3Oy6KQ8naCaYkkKqKUkK7zXxZbgcFOXhBM0EJIVTt0mPOopeyuQcOOXhBM0EJAXzSPfBW6lfVhyIUR5O0ExwKQVSM1kU1msGv58pDydoJhhLYdRc9F666Uv+6LYpDydoJhhLQdRcMAW0B34Ml/ksysMJmgnOUgh7bsVnXrRmysMJmgnOUgCJVly/ROedH2NqlqoWGuhnOnkxSUJ5OEEzwVkKwBlyFfHmdh79P3Xr5p5CfV6HpjycoJmgpAuv1SUKZCu1Z2vxXi39jHM583mChPJwgmaCki7c0XpmLxRMST/vuJ37ORwe83CCZoKSLrx7wLVoye+adCzH/Pmpy6Y8nKCZQBf8/iKArfxxq7JVOmb3StinOi7l4QTNBHXBFwFsoXqEtt2UY+m49f1O51zDqaehPJygmUAX3NlKrq76bJGO3bkqduptKA8naCaoC74IYC3Vits3wI+l47e15joe5eEEzQS64K7g2gZbU9I52kbbdTzKwwmaCSiAlZwGM07pHJ2DxA+UhxM0E8DFr2XxpMcawXnXchR5KUMN7NK5ur5ejiIvZaiBXTpX10DxKPIKrCPrs3SeroWUv6rIbd3fUAer4LyrqGNRHk7QTKAL7ur+Fj+LtFQ6R9eEyO86HuXhBM0EuuCuzQKznlrYIp2ja3bur5vx6lxLtsxbn6Xjd30fn6ZfKQ8naCbQBdfeLgpiDbZZLx27cyHlNH6gPJygmWAIsPZdURhraB+A6ZidmwxP38clysMJmglKuvDOVlJdauvtlI7XuRXoubehPJygmaCkC+/ssou6LWsptI7TvTXp43BozMMJmgnO0sV3h1mFXvUuj5J+tn7xOr9Gil/D4U+iPJygmeAsBeB4VLW+RxdvJNDP1IjfsUX4xWehPJygmWAshdA1+3VJFazuxydvserfRI0NXJ+hePEVQnk4QTPBWArBsTPykmrdNZAq6iui/utotZf8cXtHeThBM8GlFEYi8HvwRy9CeThBM8GlFEaiNafBSRrKwwmaCUgKZW+tGccClIcTNBOQFMqeWvPkVCvl4QTNBFNSOJ2zTPfi6jZhysMJmgmmpHCOVzw1g2aCa1JI3TNOSWpccXVqlfJwgmaCa1JIr/l9Xjf3gVMeTtBMcEsKq2vnSJJZT1ZSHk7QTHBLCqwWCl7bLdWshRHKwwmaCeZIobleN+Hg6/Cxb4rycIJmgrlSeK/hlurqLdOlKA8naCaYK4X3GgZhix66ozycoJlgiRTiIw/CFr/GgvJwgmaCpVKYjzoIW7wLhfJwgmaCpVKYjzgTNnuwNRbl4QTNBGukUB9pJuzmzNaUKA8naCZYowpVPMog7Hn35VJRHk7QTLBWCvcRXn6+6Z1hlIcTNBNskUJ2brq7RfUkm569ojycoJlgixRy99v8lrD5nWGUhxM0E2yVwr7HHwd7sUl+rSgPJ2gm2CoFfo9BWMtDdZSHEzQTdEihJ/eEtT3sTnk4QTNBlxR+agGj7UF3ysMJmgm6pPATM2GbB1tjUR5O0EzQKRXB8Qb8M6tntqZEeThBM0GnVATncmT7uzspDydoJuiWiuFYjtw0szUlysMJmgm6pYI49oRZXgRHeThBM4FDKkrnLZXt/WCUhxM0E7ik4nS15rZbpktRHk7QTOCSitNxS2V7L1iJ8nCCZgKnVKQtEySbV5luifJwgmYCp1SkLa25deKDRHk4QTOBWyrWmtZcrbh14oNEeThBM4FbKtaa1mxvxSXKwwmaCRJS0Za2ZnsrLlEeTtBMkJCKtuRZKuuIeizKwwmaCVJS8ebeN1tH1GNRHk7QTJCSijdnFizWikuUhxM0EySlIt5aoYr8sZKzKA8naCZISkW8tkJlWWm6JsrDCZoJklIha72ZClzY/9bjpSgPJ2gmSEvFpOeonv9kQFKUhxM0E6SlgtLt1KqnEreK8nCCZoJ7SEW9vJ2K3TaNRXk4QTPBPaSijp+6+DnYcVEeTtBMcA+psONnqOx//m9KlIcTNBPcSyruucu+S1ddojycoJngXlJxq8uO3xuPRXk4QTPBvaQCV5d9t666RHk4QfNgX6B5sC/QPNgXaB7sCzQP9gWaB/sCzYN9gebBvkDzYF+gebAv0DzYF2ge7ImnN/8DAsn7a/PsTiMAAAAASUVORK5CYII=", 61 | "contentType": "image/png", 62 | "width": 24, 63 | "height": 24 64 | } 65 | } 66 | } 67 | }, 68 | "popupInfo": { 69 | "title": "", 70 | "fieldInfos": [ 71 | { 72 | "fieldName": "FMID", 73 | "label": "FMID", 74 | "isEditable": true, 75 | "tooltip": "", 76 | "visible": false, 77 | "format": { 78 | "places": 0, 79 | "digitSeparator": true 80 | }, 81 | "stringFieldOption": "textbox", 82 | "isEditableOnLayer": true 83 | }, 84 | { 85 | "fieldName": "Location", 86 | "label": "Location", 87 | "isEditable": true, 88 | "tooltip": "", 89 | "visible": true, 90 | "stringFieldOption": "textbox", 91 | "isEditableOnLayer": true 92 | }, 93 | { 94 | "fieldName": "MarketName", 95 | "label": "MarketName", 96 | "isEditable": true, 97 | "tooltip": "", 98 | "visible": false, 99 | "stringFieldOption": "textbox", 100 | "isEditableOnLayer": true 101 | }, 102 | { 103 | "fieldName": "Website", 104 | "label": "Website", 105 | "isEditable": true, 106 | "tooltip": "", 107 | "visible": true, 108 | "stringFieldOption": "textbox", 109 | "isEditableOnLayer": true 110 | }, 111 | { 112 | "fieldName": "street", 113 | "label": "street", 114 | "isEditable": true, 115 | "tooltip": "", 116 | "visible": false, 117 | "stringFieldOption": "textbox", 118 | "isEditableOnLayer": true 119 | }, 120 | { 121 | "fieldName": "city", 122 | "label": "city", 123 | "isEditable": true, 124 | "tooltip": "", 125 | "visible": false, 126 | "stringFieldOption": "textbox", 127 | "isEditableOnLayer": true 128 | }, 129 | { 130 | "fieldName": "County", 131 | "label": "County", 132 | "isEditable": true, 133 | "tooltip": "", 134 | "visible": false, 135 | "stringFieldOption": "textbox", 136 | "isEditableOnLayer": true 137 | }, 138 | { 139 | "fieldName": "State", 140 | "label": "State", 141 | "isEditable": true, 142 | "tooltip": "", 143 | "visible": false, 144 | "stringFieldOption": "textbox", 145 | "isEditableOnLayer": true 146 | }, 147 | { 148 | "fieldName": "zip", 149 | "label": "zip", 150 | "isEditable": true, 151 | "tooltip": "", 152 | "visible": false, 153 | "format": { 154 | "places": 0, 155 | "digitSeparator": true 156 | }, 157 | "stringFieldOption": "textbox", 158 | "isEditableOnLayer": true 159 | }, 160 | { 161 | "fieldName": "x", 162 | "label": "x", 163 | "isEditable": true, 164 | "tooltip": "", 165 | "visible": false, 166 | "format": { 167 | "places": 2, 168 | "digitSeparator": true 169 | }, 170 | "stringFieldOption": "textbox", 171 | "isEditableOnLayer": true 172 | }, 173 | { 174 | "fieldName": "y", 175 | "label": "y", 176 | "isEditable": true, 177 | "tooltip": "", 178 | "visible": false, 179 | "format": { 180 | "places": 2, 181 | "digitSeparator": true 182 | }, 183 | "stringFieldOption": "textbox", 184 | "isEditableOnLayer": true 185 | }, 186 | { 187 | "fieldName": "FID", 188 | "label": "FID", 189 | "isEditable": false, 190 | "tooltip": "", 191 | "visible": false, 192 | "format": { 193 | "places": 0, 194 | "digitSeparator": true 195 | }, 196 | "stringFieldOption": "textbox", 197 | "isEditableOnLayer": false 198 | } 199 | ], 200 | "description": "
{MarketName}
", 201 | "showAttachments": true, 202 | "mediaInfos": [ 203 | 204 | ] 205 | } 206 | } 207 | ], 208 | "baseMap": { 209 | "baseMapLayers": [ 210 | { 211 | "id": "defaultBasemap", 212 | "layerType": "ArcGISTiledMapServiceLayer", 213 | "opacity": 1, 214 | "visibility": true, 215 | "url": "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer" 216 | } 217 | ], 218 | "title": "Topographic" 219 | }, 220 | "spatialReference": { 221 | "wkid": 102100, 222 | "latestWkid": 3857 223 | }, 224 | "version": "2.1", 225 | "bookmarks": [ 226 | { 227 | "extent": { 228 | "spatialReference": { 229 | "wkid": 102100, 230 | "latestWkid": 3857 231 | }, 232 | "xmax": -12636569.516104667, 233 | "xmin": -13378925.93481026, 234 | "ymax": 4372513.169906271, 235 | "ymin": 3882704.692654886 236 | }, 237 | "name": "Mojave Desert" 238 | }, 239 | { 240 | "extent": { 241 | "spatialReference": { 242 | "wkid": 102100, 243 | "latestWkid": 3857 244 | }, 245 | "xmax": -13498167.69893507, 246 | "xmin": -13869345.908287708, 247 | "ymax": 6166795.97187194, 248 | "ymin": 5921891.733246354 249 | }, 250 | "name": "Puget Sound" 251 | } 252 | ], 253 | "applicationProperties": { 254 | "viewing": { 255 | "routing": { 256 | "enabled": true 257 | }, 258 | "basemapGallery": { 259 | "enabled": true 260 | }, 261 | "measure": { 262 | "enabled": true 263 | }, 264 | "search": { 265 | "enabled": false, 266 | "disablePlaceFinder": true, 267 | "hintText": "Place or Address", 268 | "layers": [ 269 | 270 | ] 271 | } 272 | } 273 | } 274 | } 275 | }); -------------------------------------------------------------------------------- /config/templateConfig.js: -------------------------------------------------------------------------------- 1 | /*global define */ 2 | /*jslint sloppy:true */ 3 | /* 4 | | Copyright 2014 Esri 5 | | 6 | | Licensed under the Apache License, Version 2.0 (the "License"); 7 | | you may not use this file except in compliance with the License. 8 | | You may obtain a copy of the License at 9 | | 10 | | http://www.apache.org/licenses/LICENSE-2.0 11 | | 12 | | Unless required by applicable law or agreed to in writing, software 13 | | distributed under the License is distributed on an "AS IS" BASIS, 14 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | | See the License for the specific language governing permissions and 16 | | limitations under the License. 17 | */ 18 | define({ 19 | // When true, the template will query arcgis.com for the webmap item. 20 | "queryForWebmap": false, 21 | // When true, the template will query arcgis.com for the group's information. 22 | "queryForGroupInfo": false, 23 | // When true, the template will query arcgis.com for the items contained within the group 24 | "queryForGroupItems": false, 25 | // Use a local hosted webmap instead of a webmap on ArcGIS or portal. 26 | "useLocalWebmap": false, 27 | // Webmap file to use for the local webmap 28 | "localWebmapFile": "config/demoMap", 29 | //When true the template will query arcgis.com for default settings for helper services, units etc. If you 30 | //want to use custom settings for units or any of the helper services set queryForOrg to false then enter 31 | //default values for any items you need using the helper services and units properties. 32 | "queryForOrg": false, 33 | //If you need localization set the localize value to true to get the localized strings 34 | //from the javascript/nls/resource files. 35 | //Note that we've included a placeholder nls folder and a resource file with one error string 36 | //to show how to setup the strings file. 37 | "queryForLocale": true, 38 | // These are the options specified for querying items within the group. Modify these to get more items. You can also call the public template.queryGroupItems() method with these options as a parameter. 39 | "groupParams": { 40 | q: "group:\"${groupid}\" AND -type:\"Code Attachment\"", 41 | "sortField": "modified", 42 | "sortOrder": "desc", 43 | "num": 9, 44 | "start": 0 45 | }, 46 | //This option demonstrates how to handle additional custom url parameters. For example 47 | //if you want users to be able to specify lat/lon coordinates that define the map's center or 48 | //specify an alternate basemap via a url parameter. 49 | "urlItems": [], 50 | // Most users will not need to modify this value. For esri hosting environments only. Will automatically create a "sharinghost" and "proxyurl" for the application. Only set this is to true if the app is going to be stored on Esri's hosting servers. If you are using your own custom hosted portal, set the "sharinghost" in defaults.js instead of setting this to true. 51 | esriEnvironment: false 52 | }); -------------------------------------------------------------------------------- /images/SelectAll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/images/SelectAll.png -------------------------------------------------------------------------------- /images/SelectNone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/images/SelectNone.png -------------------------------------------------------------------------------- /images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/images/ajax-loader.gif -------------------------------------------------------------------------------- /images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/images/error.png -------------------------------------------------------------------------------- /images/error_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/images/error_gray.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Vector Basemap Style Editor 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 29 | 30 | 61 | 62 | 63 |
64 |
65 | 66 | 67 | 79 | 80 |
68 | Vector Basemap Style Editor BETA 69 | 70 | Esri Vector Basemaps 71 |  |  72 | Style Reference 73 |  |  74 | GitHub 75 |  |  76 | Show Me 77 | 78 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | 105 |
106 |
107 |
108 |
Zoom: 1
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | 117 | 118 | 119 | 120 | 121 |
122 | 123 | 124 |
125 | 126 | source-layer: 127 | 128 | 129 | 130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
Style Type
139 |
140 |
141 |
142 |
Basemap Color Palette
143 |
144 |
145 |
146 |
147 | 148 | 149 | 150 | 151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 | 164 |
165 |
166 |
167 | 168 | -------------------------------------------------------------------------------- /js/Operations/ApplyStyle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * ApplyStyle 4 | * - Apply VectorTileLayer Style 5 | * 6 | * Author: John Grayson - Applications Prototype Lab - Esri 7 | * 8 | * Created: 11/24/2015 - 0.0.1 - 9 | * Modified: 12/21/2015 - 0.0.2 - ADDED CALLBACK FUNCTION AND INPUT VALIDATION 10 | * 11 | */ 12 | define([ 13 | "dojo/_base/declare", 14 | "esri/OperationBase" 15 | ], function (declare, OperationBase) { 16 | 17 | // CLASS // 18 | var ApplyStyle = declare([OperationBase], { 19 | 20 | // CLASS NAME // 21 | declaredClass: "ApplyStyle", 22 | 23 | // LABEL // 24 | label: "Apply VectorTileLayer Style", 25 | 26 | // TYPE // 27 | type: "ApplyVectorTileLayerStyle", 28 | 29 | // VALID // 30 | validOperation: false, 31 | 32 | /** 33 | * CONSTRUCTOR 34 | */ 35 | constructor: function (options) { 36 | declare.safeMixin(this, options); 37 | // VALIDATE INPUTS // 38 | this.validOperation = ((this.layer != null) && (this.undoStyle != null) && (this.redoStyle != null)); 39 | }, 40 | 41 | /** 42 | * UNDO APPLY STYLE 43 | */ 44 | performUndo: function () { 45 | if(this.validOperation) { 46 | // SET STYLE // 47 | this.layer.setStyle(this.undoStyle); 48 | if(this.applyStyleCallback) { 49 | // CALLBACK // 50 | this.applyStyleCallback(this.undoStyle.layers) 51 | } 52 | } 53 | }, 54 | 55 | /** 56 | * REDO APPLY STYLE 57 | */ 58 | performRedo: function () { 59 | if(this.validOperation) { 60 | // SET STYLE // 61 | this.layer.setStyle(this.redoStyle); 62 | if(this.applyStyleCallback) { 63 | // CALLBACK // 64 | this.applyStyleCallback(this.redoStyle.layers) 65 | } 66 | } 67 | } 68 | 69 | }); 70 | 71 | // DEFAULT LABEL // 72 | ApplyStyle.defaultLabel = "Apply VectorTileLayer Style"; 73 | 74 | // VERSION // 75 | ApplyStyle.version = "0.0.2"; 76 | 77 | // RETURN CLASS // 78 | return ApplyStyle; 79 | }); 80 | 81 | 82 | -------------------------------------------------------------------------------- /js/dijit/UniqueComboBox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * UniqueComboBox 4 | * - COMBOBOX THAT ONLY DISPLAYS UNIQUE VALUES 5 | * 6 | * Adapted from: https://davidwalsh.name/unique-combobox 7 | * https://github.com/dojo/dijit/blob/master/form/_ComboBoxMenu.js 8 | * https://github.com/dojo/dijit/blob/master/form/_ComboBoxMenuMixin.js 9 | * 10 | * Author: John Grayson - Applications Prototype Lab - Esri 11 | * Created: 11/30/2015 - 0.0.1 - 12 | * Modified: 12/18/2015 - 0.0.2 - GET searchAttr FROM COMBOX AND PASS ON TO COMBOXMENU 13 | * 14 | * 15 | * Usage: 16 | * 17 | * var itemList = new UniqueComboBox({ 18 | * style: "width:250px;", 19 | * placeHolder: 'select item', 20 | * searchAttr: "source-layer", 21 | * intermediateChanges: true, 22 | * fetchProperties: { sort: [{ attribute: "source-layer", descending: false }] } 23 | * }, "source-layer-combo"); 24 | * itemList.startup(); 25 | * itemList.on("change", lang.hitch(this, function (evt) { 26 | * console.info(evt); 27 | * })); 28 | * 29 | */ 30 | 31 | define([ 32 | "dojo/_base/declare", 33 | "dijit/form/ComboBox", 34 | "dijit/form/_ComboBoxMenu", 35 | "dojo/_base/lang", 36 | "dojo/_base/array" 37 | ], function (declare, ComboBox, _ComboBoxMenu, lang, array) { 38 | 39 | /** 40 | * COMBOBOXMENU THAT DISPLAYS UNIQUE VALUES 41 | */ 42 | var _UniqueComboBoxMenu = declare(_ComboBoxMenu, { 43 | 44 | // CLASS NAME // 45 | declaredClass: "_UniqueComboBoxMenu", 46 | 47 | /** 48 | * 49 | * @param results 50 | * @param dataObject 51 | * @param labelFunc 52 | * @returns {*} 53 | */ 54 | createOptions: function (results, dataObject, labelFunc) { 55 | 56 | // FILTER DUPLICATE VALUES IF WE HAVE searchAttr SET // 57 | if(this.searchAttr) { 58 | 59 | // UNIQUE KEYS AND ITEMS // 60 | var uniqueKeys = {}; 61 | var uniqueItems = []; 62 | 63 | array.forEach(results, lang.hitch(this, function (result, index) { 64 | // FOR THIS DATA WE NEED TO ADDITIONALLY CHECK TO SEE // 65 | // IF THE ITEM HAS THE searchAttr PROPERTY... // 66 | if(result.hasOwnProperty(this.searchAttr)) { 67 | var label = labelFunc(result); 68 | if(typeof label != "string") { 69 | label = label.label; 70 | } 71 | if(!uniqueKeys[label]) { 72 | uniqueKeys[label] = result; 73 | uniqueItems.push(result); 74 | } 75 | } 76 | })); 77 | 78 | // RESET RESULTS // 79 | arguments[0] = uniqueItems; 80 | } 81 | 82 | return this.inherited(arguments); 83 | } 84 | 85 | }); 86 | 87 | /** 88 | * COMBOBOX THAT ONLY DISPLAYS UNIQUE VALUES IN searchAttr PROPERTY OF ITEMS 89 | */ 90 | var UniqueComboBox = declare([ComboBox], { 91 | // DROPDOWN CLASS // 92 | dropDownClass: _UniqueComboBoxMenu, 93 | /** 94 | * OVERRIDE POSTCREATE SO WE CAN SET searchAttr ON COMBOBOXMENU 95 | */ 96 | postCreate: function () { 97 | this.inherited(arguments); 98 | // THIS SHOULD FORCE THE CREATION OF DROPDOWN // 99 | this._startSearchAll(); 100 | if(this.dropDown) { 101 | // SET searchAttr ON DROPDOWN // 102 | this.dropDown.searchAttr = this.searchAttr; 103 | } 104 | } 105 | }); 106 | 107 | // VERSION // 108 | UniqueComboBox.version = "0.0.2"; 109 | 110 | // RETURN CLASS // 111 | return UniqueComboBox; 112 | }); 113 | 114 | 115 | -------------------------------------------------------------------------------- /js/dijit/css/ColorSelectorDialog.css: -------------------------------------------------------------------------------- 1 | @import url("//js.arcgis.com/3.17/dojox/widget/ColorPicker/ColorPicker.css"); 2 | 3 | .colorSelectorDlg { 4 | /*...*/ 5 | } 6 | 7 | .colorSelectorDlg-selector-container { 8 | width : 725px; 9 | height : 225px; 10 | } 11 | 12 | .colorSelectorDlg-selector-custom-container { 13 | width : 350px; 14 | } 15 | 16 | .variations-node { 17 | float : left; 18 | margin-left : 20px; 19 | } 20 | 21 | .dijitColorPalette, 22 | .dojoxColorPicker { 23 | background : none !important; 24 | border : none !important; 25 | } 26 | 27 | .dojoxColorPickerOptional input { 28 | width : 40px; 29 | } 30 | 31 | .dijitColorPalette .dijitPaletteImg { 32 | padding : 2px !important; 33 | } 34 | 35 | .dijitColorPalette .dijitPaletteImg .dijitColorPaletteSwatch, 36 | .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg .dijitColorPaletteSwatch, 37 | .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg .dijitColorPaletteSwatch, 38 | .dijitColorPalette .dijitPaletteCell.dijitPaletteCellSelected .dijitPaletteImg .dijitColorPaletteSwatch { 39 | width : 14px !important; 40 | height : 14px !important; 41 | } -------------------------------------------------------------------------------- /js/jsoneditor-master/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | build 3 | downloads 4 | node_modules 5 | *.zip 6 | npm-debug.log -------------------------------------------------------------------------------- /js/jsoneditor-master/.npmignore: -------------------------------------------------------------------------------- 1 | bower.json 2 | downloads 3 | misc 4 | node_modules 5 | test 6 | tools 7 | .idea 8 | component.json 9 | gulpfile.js 10 | .npmignore 11 | .gitignore 12 | *.zip 13 | npm-debug.log -------------------------------------------------------------------------------- /js/jsoneditor-master/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Contributions to the `jsoneditor` library are very welcome! We can't do this 4 | alone. You can contribute in different ways: spread the word, report bugs, come 5 | up with ideas and suggestions, and contribute to the code. 6 | 7 | There are a few preferences regarding code contributions: 8 | 9 | - `jsoneditor` follows the node.js code style as described 10 | [here](http://nodeguide.com/style.html). 11 | - Send pull requests to the `develop` branch, not the `master` branch. 12 | - Only commit changes done in the source files under `src`, not to the builds 13 | which are located in the root of the project (like `jsoneditor.js`, 14 | `jsoneditor.css`, etc. 15 | 16 | Thanks! 17 | 18 | -------------------------------------------------------------------------------- /js/jsoneditor-master/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /js/jsoneditor-master/NOTICE: -------------------------------------------------------------------------------- 1 | JSON Editor 2 | https://github.com/josdejong/jsoneditor 3 | 4 | Copyright (C) 2011-2015 Jos de Jong 5 | 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | -------------------------------------------------------------------------------- /js/jsoneditor-master/README.md: -------------------------------------------------------------------------------- 1 | # JSON Editor 2 | https://github.com/josdejong/jsoneditor 3 | http://jsoneditoronline.org/ 4 | 5 | Website: http://jsoneditoronline.org/ 6 | Github: https://github.com/josdejong/jsoneditor 7 | 8 | 9 | ## Description 10 | 11 | JSON Editor is a web-based tool to view, edit, and format JSON. 12 | It has various modes such as a tree editor, a code editor, and a plain text 13 | editor. 14 | 15 | The editor can be used as a component in your own web application. The library 16 | can be loaded as CommonJS module, AMD module, or as a regular javascript file. 17 | 18 | Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 9+. 19 | 20 | json editor 21 | 22 | code editor 23 | 24 | 25 | ## Features 26 | 27 | ### Tree editor 28 | - Edit, add, move, remove, and duplicate fields and values. 29 | - Change type of values. 30 | - Sort arrays and objects. 31 | - Colorized code. 32 | - Search & highlight text in the treeview. 33 | - Undo and redo all actions. 34 | 35 | ### Code editor 36 | - Format and compact JSON. 37 | - Colorized code (powered by Ace). 38 | - Inspect JSON (powered by Ace). 39 | 40 | ### Text editor 41 | - Format and compact JSON. 42 | 43 | 44 | ## Documentation 45 | 46 | - Documentation: 47 | - [API](https://github.com/josdejong/jsoneditor/tree/master/docs/api.md) 48 | - [Usage](https://github.com/josdejong/jsoneditor/tree/master/docs/usage.md) 49 | - [Shortcut keys](https://github.com/josdejong/jsoneditor/tree/master/docs/shortcut_keys.md) 50 | - [Examples](https://github.com/josdejong/jsoneditor/tree/master/examples) 51 | - [Source](https://github.com/josdejong/jsoneditor) 52 | - [History](https://github.com/josdejong/jsoneditor/blob/master/HISTORY.md) 53 | 54 | 55 | ## Install 56 | 57 | with npm: 58 | 59 | npm install jsoneditor 60 | 61 | with bower: 62 | 63 | bower install jsoneditor 64 | 65 | download: 66 | 67 | [http://jsoneditoronline.org/downloads/](http://jsoneditoronline.org/downloads/) 68 | 69 | 70 | #### More 71 | 72 | There is a directive available for using JSONEditor in Angular.js: 73 | 74 | [https://github.com/angular-tools/ng-jsoneditor](https://github.com/angular-tools/ng-jsoneditor) 75 | 76 | 77 | ## Use 78 | 79 | ```html 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 |
91 | 92 | 111 | 112 | 113 | ``` 114 | 115 | 116 | ## Build 117 | 118 | The code of the JSON Editor is located in the folder `./src`. To build 119 | jsoneditor: 120 | 121 | - Install dependencies: 122 | 123 | ``` 124 | npm install 125 | ``` 126 | 127 | - Build JSON Editor: 128 | 129 | ``` 130 | npm run build 131 | ``` 132 | 133 | This will generate the files `./jsoneditor.js`, `./jsoneditor.css`, and 134 | minified versions in the root of the project. 135 | 136 | 137 | ## Custom builds 138 | 139 | The source code of JSONEditor consists of CommonJS modules. JSONEditor can be bundled in a customized way using a module bundler like [browserify](http://browserify.org/) or [webpack](http://webpack.github.io/). First, install all dependencies of jsoneditor: 140 | 141 | npm install 142 | 143 | To create a custom bundle of the source code using browserify: 144 | 145 | browserify ./index.js -o ./jsoneditor.custom.js -s JSONEditor 146 | 147 | The Ace editor, used in mode `code`, accounts for about 75% of the total 148 | size of the library. To exclude the Ace editor from the bundle: 149 | 150 | browserify ./index.js -o ./jsoneditor.custom.js -s JSONEditor -x brace -x brace/mode/json -x brace/ext/searchbox 151 | 152 | To minify the generated bundle, use [uglifyjs](https://github.com/mishoo/UglifyJS2): 153 | 154 | uglifyjs ./jsoneditor.custom.js -o ./jsoneditor.custom.min.js -m -c 155 | -------------------------------------------------------------------------------- /js/jsoneditor-master/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsoneditor", 3 | "version": "4.2.1", 4 | "description": "A web-based tool to view, edit and format JSON", 5 | "tags": [ 6 | "json", 7 | "editor", 8 | "viewer", 9 | "formatter" 10 | ], 11 | "homepage": "http://jsoneditoronline.org/", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/josdejong/jsoneditor.git" 15 | }, 16 | "main": [ 17 | "./dist/jsoneditor.min.js", 18 | "./dist/jsoneditor.min.css" 19 | ], 20 | "bugs": "https://github.com/josdejong/jsoneditor/issues", 21 | "ignore": [ 22 | "misc", 23 | "node_modules", 24 | "test", 25 | "tools", 26 | "gulpfile.js", 27 | "npm-debug.log", 28 | ".idea", 29 | ".npmignore", 30 | ".gitignore" 31 | ], 32 | "dependencies": {} 33 | } 34 | -------------------------------------------------------------------------------- /js/jsoneditor-master/dist/img/jsoneditor-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/js/jsoneditor-master/dist/img/jsoneditor-icons.png -------------------------------------------------------------------------------- /js/jsoneditor-master/dist/jsoneditor.min.css: -------------------------------------------------------------------------------- 1 | .jsoneditor .field,.jsoneditor .readonly,.jsoneditor .value{border:1px solid transparent;min-height:16px;min-width:32px;padding:2px;margin:1px;word-wrap:break-word;float:left}.jsoneditor .field p,.jsoneditor .value p{margin:0}.jsoneditor .value{word-break:break-word}.jsoneditor .readonly{min-width:16px;color:gray}.jsoneditor .empty{border-color:#d3d3d3;border-style:dashed;border-radius:2px}.jsoneditor .field.empty{background-image:url(img/jsoneditor-icons.png);background-position:0 -144px}.jsoneditor .value.empty{background-image:url(img/jsoneditor-icons.png);background-position:-48px -144px}.jsoneditor .value.url{color:green;text-decoration:underline}.jsoneditor a.value.url:focus,.jsoneditor a.value.url:hover{color:red}.jsoneditor .separator{padding:3px 0;vertical-align:top;color:gray}.jsoneditor .field.highlight,.jsoneditor .field[contenteditable=true]:focus,.jsoneditor .field[contenteditable=true]:hover,.jsoneditor .value.highlight,.jsoneditor .value[contenteditable=true]:focus,.jsoneditor .value[contenteditable=true]:hover{background-color:#FFFFAB;border:1px solid #ff0;border-radius:2px}.jsoneditor .field.highlight-active,.jsoneditor .field.highlight-active:focus,.jsoneditor .field.highlight-active:hover,.jsoneditor .value.highlight-active,.jsoneditor .value.highlight-active:focus,.jsoneditor .value.highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}.jsoneditor div.tree button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background:url(img/jsoneditor-icons.png)}.jsoneditor div.tree button.collapsed{background-position:0 -48px}.jsoneditor div.tree button.expanded{background-position:0 -72px}.jsoneditor div.tree button.contextmenu{background-position:-48px -72px}.jsoneditor div.tree button.contextmenu.selected,.jsoneditor div.tree button.contextmenu:focus,.jsoneditor div.tree button.contextmenu:hover{background-position:-48px -48px}.jsoneditor div.tree :focus{outline:0}.jsoneditor div.tree button:focus{background-color:#f5f5f5;outline:#e5e5e5 solid 1px}.jsoneditor div.tree button.invisible{visibility:hidden;background:0 0}.jsoneditor{color:#1A1A1A;border:1px solid #97B0F8;box-sizing:border-box;width:100%;height:100%;overflow:auto;position:relative;padding:0;line-height:100%}.jsoneditor,.jsoneditor div.outer{-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.jsoneditor div.tree table.tree{border-collapse:collapse;border-spacing:0;width:100%;margin:0}.jsoneditor div.outer{width:100%;height:100%;margin:-35px 0 0;padding:35px 0 0;box-sizing:border-box;overflow:hidden}.jsoneditor div.tree{width:100%;height:100%;position:relative;overflow:auto}.jsoneditor textarea.text{width:100%;height:100%;margin:0;box-sizing:border-box;border:none;background-color:#fff;resize:none}.jsoneditor .menu,.jsoneditor textarea.text{-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.jsoneditor tr.highlight{background-color:#FFFFAB}.jsoneditor div.tree button.dragarea{background:url(img/jsoneditor-icons.png)-72px -72px;cursor:move}.jsoneditor div.tree button.dragarea:focus,.jsoneditor div.tree button.dragarea:hover{background-position:-72px -48px}.jsoneditor td,.jsoneditor th,.jsoneditor tr{padding:0;margin:0}.jsoneditor td,.jsoneditor td.tree{vertical-align:top}.jsoneditor .field,.jsoneditor .value,.jsoneditor td,.jsoneditor textarea,.jsoneditor th{font-family:droid sans mono,consolas,monospace,courier new,courier,sans-serif;font-size:10pt;color:#1A1A1A}.jsoneditor-contextmenu{position:absolute;z-index:99999}.jsoneditor-contextmenu ul{position:relative;left:0;top:0;width:124px;background:#fff;border:1px solid #d3d3d3;box-shadow:2px 2px 12px rgba(128,128,128,.3);list-style:none;margin:0;padding:0}.jsoneditor-contextmenu ul li button{padding:0;margin:0;width:124px;height:24px;border:none;cursor:pointer;color:#4d4d4d;background:0 0;line-height:26px;text-align:left}.jsoneditor-contextmenu ul li button::-moz-focus-inner{padding:0;border:0}.jsoneditor-contextmenu ul li button:focus,.jsoneditor-contextmenu ul li button:hover{color:#1a1a1a;background-color:#f5f5f5;outline:0}.jsoneditor-contextmenu ul li button.default{width:92px}.jsoneditor-contextmenu ul li button.expand{float:right;width:32px;height:24px;border-left:1px solid #e5e5e5}.jsoneditor-contextmenu div.icon{float:left;width:24px;height:24px;border:none;padding:0;margin:0;background-image:url(img/jsoneditor-icons.png)}.jsoneditor-contextmenu ul li button div.expand{float:right;width:24px;height:24px;padding:0;margin:0 4px 0 0;background:url(img/jsoneditor-icons.png)0 -72px;opacity:.4}.jsoneditor-contextmenu ul li button.expand:focus div.expand,.jsoneditor-contextmenu ul li button.expand:hover div.expand,.jsoneditor-contextmenu ul li button:focus div.expand,.jsoneditor-contextmenu ul li button:hover div.expand,.jsoneditor-contextmenu ul li.selected div.expand{opacity:1}.jsoneditor-contextmenu .separator{height:0;border-top:1px solid #e5e5e5;padding-top:5px;margin-top:5px}.jsoneditor-contextmenu button.remove>.icon{background-position:-24px -24px}.jsoneditor-contextmenu button.remove:focus>.icon,.jsoneditor-contextmenu button.remove:hover>.icon{background-position:-24px 0}.jsoneditor-contextmenu button.append>.icon{background-position:0 -24px}.jsoneditor-contextmenu button.append:focus>.icon,.jsoneditor-contextmenu button.append:hover>.icon{background-position:0 0}.jsoneditor-contextmenu button.insert>.icon{background-position:0 -24px}.jsoneditor-contextmenu button.insert:focus>.icon,.jsoneditor-contextmenu button.insert:hover>.icon{background-position:0 0}.jsoneditor-contextmenu button.duplicate>.icon{background-position:-48px -24px}.jsoneditor-contextmenu button.duplicate:focus>.icon,.jsoneditor-contextmenu button.duplicate:hover>.icon{background-position:-48px 0}.jsoneditor-contextmenu button.sort-asc>.icon{background-position:-168px -24px}.jsoneditor-contextmenu button.sort-asc:focus>.icon,.jsoneditor-contextmenu button.sort-asc:hover>.icon{background-position:-168px 0}.jsoneditor-contextmenu button.sort-desc>.icon{background-position:-192px -24px}.jsoneditor-contextmenu button.sort-desc:focus>.icon,.jsoneditor-contextmenu button.sort-desc:hover>.icon{background-position:-192px 0}.jsoneditor-contextmenu ul li .selected{background-color:#D5DDF6}.jsoneditor-contextmenu ul li{overflow:hidden}.jsoneditor-contextmenu ul li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset 0 0 10px rgba(128,128,128,.5);padding:0 10px;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out}.jsoneditor-contextmenu ul li ul li button{padding-left:24px}.jsoneditor-contextmenu ul li ul li button:focus,.jsoneditor-contextmenu ul li ul li button:hover{background-color:#f5f5f5}.jsoneditor-contextmenu button.type-string>.icon{background-position:-144px -24px}.jsoneditor-contextmenu button.type-string.selected>.icon,.jsoneditor-contextmenu button.type-string:focus>.icon,.jsoneditor-contextmenu button.type-string:hover>.icon{background-position:-144px 0}.jsoneditor-contextmenu button.type-auto>.icon{background-position:-120px -24px}.jsoneditor-contextmenu button.type-auto.selected>.icon,.jsoneditor-contextmenu button.type-auto:focus>.icon,.jsoneditor-contextmenu button.type-auto:hover>.icon{background-position:-120px 0}.jsoneditor-contextmenu button.type-object>.icon{background-position:-72px -24px}.jsoneditor-contextmenu button.type-object.selected>.icon,.jsoneditor-contextmenu button.type-object:focus>.icon,.jsoneditor-contextmenu button.type-object:hover>.icon{background-position:-72px 0}.jsoneditor-contextmenu button.type-array>.icon{background-position:-96px -24px}.jsoneditor-contextmenu button.type-array.selected>.icon,.jsoneditor-contextmenu button.type-array:focus>.icon,.jsoneditor-contextmenu button.type-array:hover>.icon{background-position:-96px 0}.jsoneditor-contextmenu button.type-modes>.icon{background-image:none;width:6px}.jsoneditor .menu{width:100%;height:35px;padding:2px;margin:0;overflow:hidden;box-sizing:border-box;color:#1A1A1A;background-color:#D5DDF6;border-bottom:1px solid #97B0F8}.jsoneditor .menu button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid #aec0f8;background:url(img/jsoneditor-icons.png)#e3eaf6;color:#4D4D4D;opacity:.8;font-family:arial,sans-serif;font-size:10pt;float:left}.jsoneditor .menu button:hover{background-color:#f0f2f5}.jsoneditor .menu button:active,.jsoneditor .menu button:focus{background-color:#fff}.jsoneditor .menu button:disabled{background-color:#e3eaf6}.jsoneditor .menu button.collapse-all{background-position:0 -96px}.jsoneditor .menu button.expand-all{background-position:0 -120px}.jsoneditor .menu button.undo{background-position:-24px -96px}.jsoneditor .menu button.undo:disabled{background-position:-24px -120px}.jsoneditor .menu button.redo{background-position:-48px -96px}.jsoneditor .menu button.redo:disabled{background-position:-48px -120px}.jsoneditor .menu button.compact{background-position:-72px -96px}.jsoneditor .menu button.format{background-position:-72px -120px}.jsoneditor .menu button.modes{background-image:none;width:auto;padding-left:6px;padding-right:6px}.jsoneditor .menu button.separator{margin-left:10px}.jsoneditor .menu a{font-family:arial,sans-serif;font-size:10pt;color:#97B0F8;vertical-align:middle}.jsoneditor .menu a:hover{color:red}.jsoneditor .menu a.poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}.jsoneditor .search .results,.jsoneditor .search input{font-family:arial,sans-serif;font-size:10pt;color:#1A1A1A;background:0 0}.jsoneditor .search{position:absolute;right:2px;top:2px}.jsoneditor .search .frame{border:1px solid #97B0F8;background-color:#fff;padding:0 2px;margin:0}.jsoneditor .search .frame table{border-collapse:collapse}.jsoneditor .search input{width:120px;border:none;outline:0;margin:1px}.jsoneditor .search .results{color:#4d4d4d;padding-right:5px;line-height:24px}.jsoneditor .search button{width:16px;height:24px;padding:0;margin:0;border:none;background:url(img/jsoneditor-icons.png);vertical-align:top}.jsoneditor .search button:hover{background-color:transparent}.jsoneditor .search button.refresh{width:18px;background-position:-99px -73px}.jsoneditor .search button.next{cursor:pointer;background-position:-124px -73px}.jsoneditor .search button.next:hover{background-position:-124px -49px}.jsoneditor .search button.previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}.jsoneditor .search button.previous:hover{background-position:-148px -49px} -------------------------------------------------------------------------------- /js/jsoneditor-master/docs/api.md: -------------------------------------------------------------------------------- 1 | # API Reference 2 | 3 | ## JSONEditor 4 | 5 | ### Constructor 6 | 7 | #### `JSONEditor(container [, options] [, json])` 8 | 9 | Constructs a new JSONEditor. 10 | 11 | *Parameters:* 12 | 13 | - `{Element} container` 14 | An HTML DIV element. The JSONEditor will be created inside this container element. 15 | - `{Object} options` 16 | Optional object with options. Available options: 17 | 18 | - `{Object} ace` 19 | Provide a custom version of the [Ace editor](http://ace.c9.io/) and use this instead of the version that comes embedded with JSONEditor. Only applicable when `mode` is `code`. 20 | - `{function} change` 21 | Set a callback method triggered when the contents of the JSONEditor change. Called without parameters. Will only be triggered on changes made by the user, not in case of programmatic changes via the functions `set` or `setText`. 22 | - `{function} editable` 23 | Set a callback method to determine whether individual nodes are editable or read-only. Only applicable when option `mode` is `tree`. The callback is invoked as `editable(node)`, where `node` is an object `{field: string, value: string, path: string[]}`. The function must either return a boolean value to set both the nodes field and value editable or read-only, or return an object `{field: boolean, value: boolean}`. 24 | - `{function} error` 25 | Set a callback method triggered when an error occurs. Invoked with the error as first argument. The callback is only invoked 26 | for errors triggered by a users action. 27 | - `{boolean} history` 28 | Enables history, adds a button Undo and Redo to the menu of the JSONEditor. True by default. Only applicable when `mode` is 'tree' or 'form'. 29 | - `{String} mode` 30 | Set the editor mode. Available values: 'tree' (default), 'view', 'form', 'code', 'text'. In 'view' mode, the data and datastructure is read-only. In 'form' mode, only the value can be changed, the datastructure is read-only. Mode 'code' requires the Ace editor to be loaded on the page. Mode 'text' shows the data as plain text. 31 | - `{String[]} modes` 32 | Create a box in the editor menu where the user can switch between the specified modes. Available values: see option `mode`. 33 | - `{String} name` 34 | Initial field name for the root node, is undefined by default. Can also be set using `JSONEditor.setName(name)`. Only applicable when `mode` is 'tree', 'view', or 'form'. 35 | - `{boolean} search` 36 | Enables a search box in the upper right corner of the JSONEditor. True by default. Only applicable when `mode` is 'tree', 'view', or 'form'. 37 | - `{Number} indentation` 38 | Number of indentation spaces. 2 by default. Only applicable when `mode` is 'code' or 'text'. 39 | - `{String} theme` 40 | Set the Ace editor theme, uses included 'ace/theme/jsoneditor' by default. Please note that only the default theme is included with jsoneditor, so if you specify another one you need to make sure it is loaded. 41 | 42 | - `{JSON} json` 43 | Initial JSON data to be loaded into the JSONEditor. Alternatively, the method `JSONEditor.set(json)` can be used to load JSON data into the editor. 44 | 45 | *Returns:* 46 | 47 | - `{JSONEditor} editor` 48 | New instance of a JSONEditor. 49 | 50 | 51 | ### Methods 52 | 53 | #### `JSONEditor.collapseAll()` 54 | 55 | Collapse all fields. Only applicable for mode 'tree', 'view', and 'form'. 56 | 57 | #### `JSONEditor.expandAll()` 58 | 59 | Expand all fields. Only applicable for mode 'tree', 'view', and 'form'. 60 | 61 | #### `JSONEditor.focus()` 62 | 63 | Set focus to the JSONEditor. 64 | 65 | #### `JSONEditor.set(json)` 66 | 67 | Set JSON data. 68 | 69 | *Parameters:* 70 | 71 | - `{JSON} json` 72 | JSON data to be displayed in the JSONEditor. 73 | 74 | #### `JSONEditor.setMode(mode)` 75 | 76 | Switch mode. Mode `code` requires the [Ace editor](http://ace.ajax.org/). 77 | 78 | *Parameters:* 79 | 80 | - `{String} mode` 81 | Available values: `tree`, 'view', `form`, `code`, `text`. 82 | 83 | #### `JSONEditor.setName(name)` 84 | 85 | Set a field name for the root node. 86 | 87 | *Parameters:* 88 | 89 | - `{String | undefined} name` 90 | Field name of the root node. If undefined, the current name will be removed. 91 | 92 | #### `JSONEditor.setText(jsonString)` 93 | 94 | Set text data in the editor. 95 | 96 | *Parameters:* 97 | 98 | - `{String} jsonString` 99 | Contents of the editor as string. 100 | 101 | #### `JSONEditor.get()` 102 | 103 | Get JSON data. 104 | 105 | *Returns:* 106 | 107 | - `{JSON} json` 108 | JSON data from the JSONEditor. 109 | 110 | #### `JSONEditor.getName()` 111 | 112 | Retrieve the current field name of the root node. 113 | 114 | *Returns:* 115 | 116 | - `{String | undefined} name` 117 | Current field name of the root node, or undefined if not set. 118 | 119 | #### `JSONEditor.getText()` 120 | 121 | Get JSON data as string. 122 | 123 | *Returns:* 124 | 125 | - `{String} jsonString` 126 | Contents of the editor as string. When the editor is in code `text` or `code`, 127 | the returned text is returned as-is. For the other modes, the returned text 128 | is a compacted string. In order to get the JSON formatted with a certain 129 | number of spaces, use `JSON.stringify(JSONEditor.get(), null, 2)`. 130 | 131 | 132 | ### Examples 133 | 134 | A tree editor: 135 | 136 | ```js 137 | var options = { 138 | "mode": "tree", 139 | "search": true 140 | }; 141 | var editor = new JSONEditor(container, options); 142 | var json = { 143 | "Array": [1, 2, 3], 144 | "Boolean": true, 145 | "Null": null, 146 | "Number": 123, 147 | "Object": {"a": "b", "c": "d"}, 148 | "String": "Hello World" 149 | }; 150 | editor.set(json); 151 | editor.expandAll(); 152 | 153 | var json = editor.get(json); 154 | ``` 155 | 156 | A text editor: 157 | 158 | ```js 159 | var options = { 160 | "mode": "text", 161 | "indentation": 2 162 | }; 163 | var editor = new JSONEditor(container, options); 164 | var json = { 165 | "Array": [1, 2, 3], 166 | "Boolean": true, 167 | "Null": null, 168 | "Number": 123, 169 | "Object": {"a": "b", "c": "d"}, 170 | "String": "Hello World" 171 | }; 172 | editor.set(json); 173 | 174 | var json = editor.get(); 175 | ``` 176 | 177 | ## JSON parsing and stringification 178 | 179 | In general to parse or stringify JSON data, the browsers built in JSON parser can be used. To create a formatted string from a JSON object, use: 180 | 181 | ```js 182 | var formattedString = JSON.stringify(json, null, 2); 183 | ``` 184 | 185 | to create a compacted string from a JSON object, use: 186 | 187 | ```js 188 | var compactString = JSON.stringify(json); 189 | ``` 190 | 191 | To parse a String to a JSON object, use: 192 | 193 | ```js 194 | var json = JSON.parse(string); 195 | ``` 196 | -------------------------------------------------------------------------------- /js/jsoneditor-master/docs/shortcut_keys.md: -------------------------------------------------------------------------------- 1 | # Shortcut keys 2 | 3 | ## Tree Editor 4 | 5 | Key | Description 6 | ----------------------- | ------------------------------------------------ 7 | Alt+Arrows | Move the caret up/down/left/right between fields 8 | Shift+Alt+Arrows | Move field up/down/left/right 9 | Ctrl+D | Duplicate field 10 | Ctrl+Del | Remove field 11 | Ctrl+Enter | Open link when on a field containing an url 12 | Ctrl+Ins | Insert a new field with type auto 13 | Ctrl+Shift+Ins | Append a new field with type auto 14 | Ctrl+E | Expand or collapse field 15 | Alt+End | Move the caret to the last field 16 | Ctrl+F | Find 17 | F3, Ctrl+G | Find next 18 | Shift+F3, Ctrl+Shift+G | Find previous 19 | Alt+Home | Move the caret to the first field 20 | Ctrl+M | Show actions menu 21 | Ctrl+Z | Undo last action 22 | Ctrl+Shift+Z | Redo 23 | 24 | 25 | ## Code Editor 26 | 27 | The code editor is powered by [Ace Editor](http://ace.c9.io/). This editor's 28 | shortcut keys are described here: 29 | 30 | https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts 31 | 32 | Additionally, there are shortcut keys to format/compact the code: 33 | 34 | Key | Description 35 | ----------------------- | ------------------------------------------------ 36 | Ctrl+\ | Format JSON data, set proper indentation 37 | Ctrl+Shift+\ | Compact JSON data, remove all whitespace 38 | -------------------------------------------------------------------------------- /js/jsoneditor-master/docs/usage.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | ### Install 4 | 5 | with npm: 6 | 7 | npm install jsoneditor 8 | 9 | with bower: 10 | 11 | bower install jsoneditor 12 | 13 | download: 14 | 15 | [http://jsoneditoronline.org/downloads/](http://jsoneditoronline.org/downloads/) 16 | 17 | The library consists of three files: one javascript file, one css file and an 18 | image. Both full and minified version are available. 19 | 20 | ## Load 21 | 22 | To implement JSONEditor in a web application, load the javascript and css file 23 | in the head of the HTML page: 24 | 25 | ```html 26 | 27 | 28 | ``` 29 | 30 | ## Use 31 | 32 | In the body, create an div element with an id and a size: 33 | 34 | ```html 35 |
36 | ``` 37 | 38 | After the page is loaded, load the editor with javascript: 39 | 40 | ```js 41 | var container = document.getElementById("jsoneditor"); 42 | var options = { 43 | mode: 'tree' 44 | }; 45 | var editor = new JSONEditor(container, options); 46 | ``` 47 | 48 | To set JSON data in the editor: 49 | 50 | ```js 51 | var json = { 52 | "Array": [1, 2, 3], 53 | "Boolean": true, 54 | "Null": null, 55 | "Number": 123, 56 | "Object": {"a": "b", "c": "d"}, 57 | "String": "Hello World" 58 | }; 59 | editor.set(json); 60 | ``` 61 | 62 | To get JSON data from the editor: 63 | 64 | ```js 65 | var json = editor.get(); 66 | ``` 67 | 68 | 69 | ## Full Example 70 | 71 | ```html 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |

83 | 84 | 85 |

86 |
87 | 88 | 112 | 113 | 114 | ``` 115 | 116 | For more examples, see the 117 | [examples section](https://github.com/josdejong/jsoneditor/tree/master/examples). 118 | -------------------------------------------------------------------------------- /js/jsoneditor-master/examples/01_basic_usage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JSONEditor | Basic usage 5 | 6 | 7 | 8 | 9 | 15 | 16 | 17 |

18 | 19 | 20 |

21 |
22 | 23 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /js/jsoneditor-master/examples/02_viewer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JSONEditor | Viewer 5 | 6 | 7 | 8 | 9 | 10 | 18 | 19 | 20 |

21 | This editor is read-only (mode='viewer'). 22 |

23 |
24 | 25 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /js/jsoneditor-master/examples/03_switch_mode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JSONEditor | Switch mode 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 | 32 |

33 | Switch editor mode using the mode box. 34 | Note that the mode can be changed programmatically as well using the method 35 | editor.setMode(mode), try it in the console of your browser. 36 |

37 | 38 |
39 | 40 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /js/jsoneditor-master/examples/04_load_and_save.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JSONEditor | Load and save 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 21 | 22 | 23 |

Load and save JSON documents

24 |

25 | This examples uses HTML5 to load/save local files. 26 | Powered by FileReader.js and 27 | FileSaver.js.
28 | Only supported on modern browsers (Chrome, FireFox, IE10+, Safari 6.1+, Opera 15+). 29 |

30 |

31 | Load a JSON document: 32 |

33 |

34 | Save a JSON document: 35 |

36 | 37 |
38 | 39 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /js/jsoneditor-master/examples/05_custom_fields_editable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JSONEditor | Basic usage 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 |

17 | In this example: 18 |

19 | 24 | 25 |
26 | 27 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /js/jsoneditor-master/examples/requirejs_demo/requirejs_demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JSONEditor | Require.js demo 5 | 11 | 12 | 13 | 14 | 15 |

16 | 17 | 18 |

19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /js/jsoneditor-master/examples/requirejs_demo/scripts/main.js: -------------------------------------------------------------------------------- 1 | var module = '../../../dist/jsoneditor'; 2 | require([module], function (JSONEditor) { 3 | // create the editor 4 | var container = document.getElementById('jsoneditor'); 5 | var editor = new JSONEditor(container); 6 | 7 | // set json 8 | document.getElementById('setJSON').onclick = function () { 9 | var json = { 10 | 'array': [1, 2, 3], 11 | 'boolean': true, 12 | 'null': null, 13 | 'number': 123, 14 | 'object': {'a': 'b', 'c': 'd'}, 15 | 'string': 'Hello World' 16 | }; 17 | editor.set(json); 18 | }; 19 | 20 | // get json 21 | document.getElementById('getJSON').onclick = function () { 22 | var json = editor.get(); 23 | alert(JSON.stringify(json, null, 2)); 24 | }; 25 | }); 26 | -------------------------------------------------------------------------------- /js/jsoneditor-master/gulpfile.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var gulp = require('gulp'); 3 | var gutil = require('gulp-util'); 4 | var concatCss = require('gulp-concat-css'); 5 | var minifyCSS = require('gulp-minify-css'); 6 | var shell = require('gulp-shell'); 7 | var mkdirp = require('mkdirp'); 8 | var webpack = require('webpack'); 9 | var uglify = require('uglify-js'); 10 | 11 | var NAME = 'jsoneditor'; 12 | var ENTRY = './src/js/JSONEditor.js'; 13 | var HEADER = './src/js/header.js'; 14 | var IMAGE = './src/css/img/jsoneditor-icons.png'; 15 | var DIST = './dist'; 16 | 17 | // generate banner with today's date and correct version 18 | function createBanner() { 19 | var today = gutil.date(new Date(), 'yyyy-mm-dd'); // today, formatted as yyyy-mm-dd 20 | var version = require('./package.json').version; // math.js version 21 | 22 | return String(fs.readFileSync(HEADER)) 23 | .replace('@@date', today) 24 | .replace('@@version', version); 25 | } 26 | 27 | var bannerPlugin = new webpack.BannerPlugin(createBanner(), { 28 | entryOnly: true, 29 | raw: true 30 | }); 31 | 32 | var webpackConfig = { 33 | entry: ENTRY, 34 | output: { 35 | library: 'JSONEditor', 36 | libraryTarget: 'umd', 37 | path: DIST, 38 | filename: NAME + '.js' 39 | }, 40 | plugins: [ bannerPlugin ], 41 | cache: true 42 | }; 43 | 44 | var uglifyConfig = { 45 | outSourceMap: NAME + '.map', 46 | output: { 47 | comments: /@license/ 48 | } 49 | }; 50 | 51 | // create a single instance of the compiler to allow caching 52 | var compiler = webpack(webpackConfig); 53 | 54 | // make dist and dist/img folders 55 | gulp.task('mkdir', function () { 56 | mkdirp.sync(DIST); 57 | mkdirp.sync(DIST + '/img'); 58 | }); 59 | 60 | // bundle javascript 61 | gulp.task('bundle', ['mkdir'], function (done) { 62 | // update the banner contents (has a date in it which should stay up to date) 63 | bannerPlugin.banner = createBanner(); 64 | 65 | compiler.run(function (err, stats) { 66 | if (err) { 67 | gutil.log(err); 68 | } 69 | 70 | gutil.log('bundled ' + NAME + '.js'); 71 | 72 | done(); 73 | }); 74 | }); 75 | 76 | // bundle css 77 | gulp.task('bundle-css', ['mkdir'], function () { 78 | gulp.src([ 79 | 'src/css/jsoneditor.css', 80 | 'src/css/contextmenu.css', 81 | 'src/css/menu.css', 82 | 'src/css/searchbox.css' 83 | ]) 84 | .pipe(concatCss(NAME + '.css')) 85 | .pipe(gulp.dest(DIST)) 86 | .pipe(concatCss(NAME + '.min.css')) 87 | .pipe(minifyCSS()) 88 | .pipe(gulp.dest(DIST)); 89 | 90 | gutil.log('bundled ' + DIST + '/' + NAME + '.css'); 91 | gutil.log('bundled ' + DIST + '/' + NAME + '.min.css'); 92 | }); 93 | 94 | // create a folder img and copy the icons 95 | gulp.task('copy-img', ['mkdir'], function () { 96 | gulp.src(IMAGE) 97 | .pipe(gulp.dest(DIST +'/img')); 98 | gutil.log('Copied images'); 99 | }); 100 | 101 | gulp.task('minify', ['bundle'], function () { 102 | var result = uglify.minify([DIST + '/' + NAME + '.js'], uglifyConfig); 103 | 104 | var fileMin = DIST + '/' + NAME + '.min.js'; 105 | var fileMap = DIST + '/' + NAME + '.map'; 106 | 107 | fs.writeFileSync(fileMin, result.code); 108 | fs.writeFileSync(fileMap, result.map); 109 | 110 | gutil.log('Minified ' + fileMin); 111 | gutil.log('Mapped ' + fileMap); 112 | 113 | }); 114 | 115 | // TODO: zip file using archiver 116 | var pkg = 'jsoneditor-' + require('./package.json').version + '.zip'; 117 | gulp.task('zip', shell.task([ 118 | 'zip ' + pkg + ' ' + 'README.md NOTICE LICENSE HISTORY.md index.html src dist docs examples -r ' 119 | ])); 120 | 121 | // The default task (called when you run `gulp`) 122 | gulp.task('default', ['bundle', 'bundle-css', 'copy-img', 'minify']); 123 | -------------------------------------------------------------------------------- /js/jsoneditor-master/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./src/js/JSONEditor'); 2 | -------------------------------------------------------------------------------- /js/jsoneditor-master/misc/codeeditor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/js/jsoneditor-master/misc/codeeditor.png -------------------------------------------------------------------------------- /js/jsoneditor-master/misc/how_to_publish.md: -------------------------------------------------------------------------------- 1 | # How to publish jsoneditor 2 | 3 | This document describes the steps required to publish a new version of jsoneditor. 4 | 5 | 6 | ## Update version number 7 | 8 | Update the version number in both package.json and bower.json. 9 | 10 | 11 | ## Update history 12 | 13 | Update the date and version number in the file HISTORY.md. Verify whether all 14 | changes in the new version are described. 15 | 16 | 17 | ## Test the library 18 | 19 | Run the unit tests and validate whether all tests pass: 20 | 21 | npm test 22 | 23 | 24 | ## Build library 25 | 26 | Build the build (jsoneditor.js, jsoneditor.css, ...) files by running: 27 | 28 | npm run build 29 | 30 | After the build is complete, verify if the files are updated and contain the 31 | correct date and version number in the header. 32 | 33 | 34 | ## Test 35 | 36 | Test whether the npm library is ok by installing it locally: 37 | 38 | cd ../tmp-folder 39 | npm install ./path/to/jsoneditor 40 | 41 | Check whether the examples in the library work ok, and whether the necessary 42 | files are included. 43 | 44 | 45 | ## Commit 46 | 47 | - Commit the final code. 48 | - Merge the develop branch into the master branch. 49 | - Push to github. 50 | 51 | If everything is well, create a tag for the new version, like: 52 | 53 | git tag v1.2.4 54 | git push --tags 55 | 56 | 57 | ## Publish 58 | 59 | Publish to npm: 60 | 61 | npm publish 62 | 63 | Publish at cdnjs: test after 30 to 60 minutes whether the new version is 64 | published at cdnjs (should auto update). 65 | 66 | 67 | ## Test published library 68 | 69 | Install the libraries locally and test whether they work correctly: 70 | 71 | cd tmp-folder 72 | npm install jsoneditor 73 | bower install jsoneditor 74 | 75 | 76 | ## Put zip file to website 77 | 78 | Create a zipped file of the library by running 79 | 80 | gulp zip 81 | 82 | Add the file to the `downloads` folder of the website. 83 | 84 | 85 | ## Update version number 86 | 87 | Switch to the develop branch, and update the version numbers in package.json and 88 | bower.json to a new snapshot version, like 89 | 90 | 1.2.5-SNAPSHOT 91 | 92 | commit and push the changes. 93 | 94 | 95 | ## Done 96 | 97 | Congrats, be proud. 98 | 99 | -------------------------------------------------------------------------------- /js/jsoneditor-master/misc/jsoneditor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/js/jsoneditor-master/misc/jsoneditor.png -------------------------------------------------------------------------------- /js/jsoneditor-master/misc/todo.txt: -------------------------------------------------------------------------------- 1 | JSON EDITOR TODO 2 | 3 | ________________________________________________________________________ 4 | 5 | VERSION 1: Basic functionality 6 | 7 | Bug: on Opera, you cannot double click to select a word in the field/value 8 | editable div 9 | 10 | Bug: get the breaking of long words working on Firefox an IE. Does not work for 11 | a word like "blablablablablablablablablablablablablablablablablablablabla", 12 | and in IE also not for urls. 13 | 14 | for highlighting and expanding: send a timestamp, and when very large, 15 | split via a timeout in different parts so, the browser stays responsive. 16 | 17 | ________________________________________________________________________ 18 | 19 | VERSION 2: Functionality 20 | 21 | store the contents in the browser. also store all revisions (used with undo/redo) 22 | 23 | add documentation/information about JSON in general 24 | 25 | write documentation about the sourcecode 26 | 27 | warning when an object has multiple fields with the same name 28 | 29 | create options: 30 | - collapsed: true/false 31 | - editableFields: true/false 32 | 33 | ________________________________________________________________________ 34 | 35 | VERSION 3: Performance 36 | 37 | performance improvements: lazy loading of the HTML elements 38 | method getValue() should retrieve the data from its in memory JSON, and not 39 | by reading the from the fields on screen. Fields on screen must directly 40 | update their value in memory when changed. 41 | Also, the in memory JSON should correspond one to one to the real JSON data... 42 | 43 | automatically update left or right panel contents on change? 44 | 45 | 46 | ________________________________________________________________________ 47 | 48 | VERSION 4: Validator 49 | 50 | Implement a JSON Schema validator 51 | http://en.wikipedia.org/wiki/Json#Schema 52 | http://tools.ietf.org/html/draft-zyp-json-schema-03 53 | 54 | the editor on the right will get an extra button on the right: for specifying 55 | validation parameters. On the left, we will get two text editors on top of each 56 | other: one with the JSON data, the other with the JSON schema. 57 | By default, the validator is not visible. There will be an option in the main 58 | menu to toggle validator. 59 | 60 | Also: create buttons to generate JSON from a schema. 61 | 62 | ________________________________________________________________________ 63 | 64 | VERSION 5 65 | 66 | support for XML? others? 67 | 68 | 69 | ________________________________________________________________________ 70 | 71 | VERSION 6 72 | 73 | store data online, with an account? 74 | payed account without ads and with some nice extra features? 75 | 76 | -------------------------------------------------------------------------------- /js/jsoneditor-master/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsoneditor", 3 | "version": "4.2.1", 4 | "main": "./index", 5 | "description": "A web-based tool to view, edit and format JSON", 6 | "tags": [ 7 | "json", 8 | "editor", 9 | "viewer", 10 | "formatter" 11 | ], 12 | "author": "Jos de Jong ", 13 | "homepage": "http://jsoneditoronline.org/", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/josdejong/jsoneditor.git" 17 | }, 18 | "bugs": "https://github.com/josdejong/jsoneditor/issues", 19 | "scripts": { 20 | "build": "gulp", 21 | "test": "mocha test" 22 | }, 23 | "dependencies": { 24 | "brace": "^0.4.1", 25 | "jsonlint": "josdejong/jsonlint#85a19d7" 26 | }, 27 | "devDependencies": { 28 | "gulp": "^3.8.11", 29 | "gulp-concat-css": "^2.0.0", 30 | "gulp-minify-css": "^0.4.5", 31 | "gulp-shell": "^0.3.0", 32 | "gulp-util": "^3.0.3", 33 | "mkdirp": "^0.5.0", 34 | "mocha": "^2.1.0", 35 | "uglify-js": "^2.4.16", 36 | "webpack": "^1.5.3" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/css/contextmenu.css: -------------------------------------------------------------------------------- 1 | 2 | /* ContextMenu - main menu */ 3 | 4 | .jsoneditor-contextmenu { 5 | position: absolute; 6 | z-index: 99999; 7 | } 8 | 9 | .jsoneditor-contextmenu ul { 10 | position: relative; 11 | left: 0; 12 | top: 0; 13 | width: 124px; 14 | 15 | background: white; 16 | border: 1px solid #d3d3d3; 17 | box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); 18 | 19 | list-style: none; 20 | margin: 0; 21 | padding: 0; 22 | } 23 | 24 | .jsoneditor-contextmenu ul li button { 25 | padding: 0; 26 | margin: 0; 27 | width: 124px; 28 | height: 24px; 29 | border: none; 30 | cursor: pointer; 31 | color: #4d4d4d; 32 | background: transparent; 33 | 34 | line-height: 26px; 35 | text-align: left; 36 | } 37 | 38 | /* Fix button padding in firefox */ 39 | .jsoneditor-contextmenu ul li button::-moz-focus-inner { 40 | padding: 0; 41 | border: 0; 42 | } 43 | 44 | .jsoneditor-contextmenu ul li button:hover, 45 | .jsoneditor-contextmenu ul li button:focus { 46 | color: #1a1a1a; 47 | background-color: #f5f5f5; 48 | outline: none; 49 | } 50 | 51 | .jsoneditor-contextmenu ul li button.default { 52 | width: 92px; 53 | } 54 | 55 | .jsoneditor-contextmenu ul li button.expand { 56 | float: right; 57 | width: 32px; 58 | height: 24px; 59 | border-left: 1px solid #e5e5e5; 60 | } 61 | 62 | .jsoneditor-contextmenu div.icon { 63 | float: left; 64 | width: 24px; 65 | height: 24px; 66 | border: none; 67 | padding: 0; 68 | margin: 0; 69 | background-image: url('img/jsoneditor-icons.png'); 70 | } 71 | 72 | .jsoneditor-contextmenu ul li button div.expand { 73 | float: right; 74 | width: 24px; 75 | height: 24px; 76 | padding: 0; 77 | margin: 0 4px 0 0; 78 | background: url('img/jsoneditor-icons.png') 0 -72px; 79 | opacity: 0.4; 80 | } 81 | 82 | .jsoneditor-contextmenu ul li button:hover div.expand, 83 | .jsoneditor-contextmenu ul li button:focus div.expand, 84 | .jsoneditor-contextmenu ul li.selected div.expand, 85 | .jsoneditor-contextmenu ul li button.expand:hover div.expand, 86 | .jsoneditor-contextmenu ul li button.expand:focus div.expand { 87 | opacity: 1; 88 | } 89 | 90 | .jsoneditor-contextmenu .separator { 91 | height: 0; 92 | border-top: 1px solid #e5e5e5; 93 | padding-top: 5px; 94 | margin-top: 5px; 95 | } 96 | 97 | .jsoneditor-contextmenu button.remove > .icon { 98 | background-position: -24px -24px; 99 | } 100 | .jsoneditor-contextmenu button.remove:hover > .icon, 101 | .jsoneditor-contextmenu button.remove:focus > .icon { 102 | background-position: -24px 0; 103 | } 104 | 105 | .jsoneditor-contextmenu button.append > .icon { 106 | background-position: 0 -24px; 107 | } 108 | .jsoneditor-contextmenu button.append:hover > .icon, 109 | .jsoneditor-contextmenu button.append:focus > .icon { 110 | background-position: 0 0; 111 | } 112 | 113 | .jsoneditor-contextmenu button.insert > .icon { 114 | background-position: 0 -24px; 115 | } 116 | .jsoneditor-contextmenu button.insert:hover > .icon, 117 | .jsoneditor-contextmenu button.insert:focus > .icon { 118 | background-position: 0 0; 119 | } 120 | 121 | .jsoneditor-contextmenu button.duplicate > .icon { 122 | background-position: -48px -24px; 123 | } 124 | .jsoneditor-contextmenu button.duplicate:hover > .icon, 125 | .jsoneditor-contextmenu button.duplicate:focus > .icon { 126 | background-position: -48px 0; 127 | } 128 | 129 | .jsoneditor-contextmenu button.sort-asc > .icon { 130 | background-position: -168px -24px; 131 | } 132 | .jsoneditor-contextmenu button.sort-asc:hover > .icon, 133 | .jsoneditor-contextmenu button.sort-asc:focus > .icon { 134 | background-position: -168px 0; 135 | } 136 | 137 | .jsoneditor-contextmenu button.sort-desc > .icon { 138 | background-position: -192px -24px; 139 | } 140 | .jsoneditor-contextmenu button.sort-desc:hover > .icon, 141 | .jsoneditor-contextmenu button.sort-desc:focus > .icon { 142 | background-position: -192px 0; 143 | } 144 | 145 | /* ContextMenu - sub menu */ 146 | 147 | .jsoneditor-contextmenu ul li .selected { 148 | background-color: #D5DDF6; 149 | } 150 | 151 | .jsoneditor-contextmenu ul li { 152 | overflow: hidden; 153 | } 154 | 155 | .jsoneditor-contextmenu ul li ul { 156 | display: none; 157 | position: relative; 158 | left: -10px; 159 | top: 0; 160 | 161 | border: none; 162 | box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5); 163 | padding: 0 10px; 164 | 165 | /* TODO: transition is not supported on IE8-9 */ 166 | -webkit-transition: all 0.3s ease-out; 167 | -moz-transition: all 0.3s ease-out; 168 | -o-transition: all 0.3s ease-out; 169 | transition: all 0.3s ease-out; 170 | } 171 | 172 | .jsoneditor-contextmenu ul li.selected ul { 173 | } 174 | 175 | .jsoneditor-contextmenu ul li ul li button { 176 | padding-left: 24px; 177 | } 178 | 179 | .jsoneditor-contextmenu ul li ul li button:hover, 180 | .jsoneditor-contextmenu ul li ul li button:focus { 181 | background-color: #f5f5f5; 182 | 183 | } 184 | 185 | .jsoneditor-contextmenu button.type-string > .icon { 186 | background-position: -144px -24px; 187 | } 188 | .jsoneditor-contextmenu button.type-string:hover > .icon, 189 | .jsoneditor-contextmenu button.type-string:focus > .icon, 190 | .jsoneditor-contextmenu button.type-string.selected > .icon{ 191 | background-position: -144px 0; 192 | } 193 | 194 | .jsoneditor-contextmenu button.type-auto > .icon { 195 | background-position: -120px -24px; 196 | } 197 | .jsoneditor-contextmenu button.type-auto:hover > .icon, 198 | .jsoneditor-contextmenu button.type-auto:focus > .icon, 199 | .jsoneditor-contextmenu button.type-auto.selected > .icon { 200 | background-position: -120px 0; 201 | } 202 | 203 | .jsoneditor-contextmenu button.type-object > .icon { 204 | background-position: -72px -24px; 205 | } 206 | .jsoneditor-contextmenu button.type-object:hover > .icon, 207 | .jsoneditor-contextmenu button.type-object:focus > .icon, 208 | .jsoneditor-contextmenu button.type-object.selected > .icon{ 209 | background-position: -72px 0; 210 | } 211 | 212 | .jsoneditor-contextmenu button.type-array > .icon { 213 | background-position: -96px -24px; 214 | } 215 | .jsoneditor-contextmenu button.type-array:hover > .icon, 216 | .jsoneditor-contextmenu button.type-array:focus > .icon, 217 | .jsoneditor-contextmenu button.type-array.selected > .icon{ 218 | background-position: -96px 0; 219 | } 220 | 221 | .jsoneditor-contextmenu button.type-modes > .icon { 222 | background-image: none; 223 | width: 6px; 224 | } 225 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/css/img/description.txt: -------------------------------------------------------------------------------- 1 | JSON Editor Online Icons 2 | 3 | size: outer: 24x24 px 4 | inner: 16x16 px 5 | 6 | blue background: RGBA 97b0f8ff 7 | gray background: RGBA d3d3d3ff 8 | 9 | red foreground: RGBA ff0000ff 10 | green foreground: RGBA 109618ff 11 | 12 | characters are based on the Arial font 13 | 14 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/css/img/export.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Export the SVG icons to PNG and GIF formats 3 | 4 | echo "Exporting the SVG icons..." 5 | 6 | outputdir=./ 7 | mogrify -format png -background transparent -path $outputdir *.svg 8 | # mogrify -format gif -background transparent -path $outputdir dots_gray.svg 9 | echo "PNG's exported to $outputdir" 10 | 11 | # mogrify -format gif -background transparent -path gif *.svg 12 | # echo "GIF's exported to /gif" 13 | # mogrify -format png -background transparent -path png *.svg 14 | # echo "PNG's exported to /png" 15 | 16 | echo "Done" 17 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/css/img/jsoneditor-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/js/jsoneditor-master/src/css/img/jsoneditor-icons.png -------------------------------------------------------------------------------- /js/jsoneditor-master/src/css/jsoneditor.css: -------------------------------------------------------------------------------- 1 | 2 | .jsoneditor .field, 3 | .jsoneditor .value, 4 | .jsoneditor .readonly { 5 | border: 1px solid transparent; 6 | min-height: 16px; 7 | min-width: 32px; 8 | padding: 2px; 9 | margin: 1px; 10 | word-wrap: break-word; 11 | float: left; 12 | } 13 | 14 | /* adjust margin of p elements inside editable divs, needed for Opera, IE */ 15 | .jsoneditor .field p, 16 | .jsoneditor .value p { 17 | margin: 0; 18 | } 19 | 20 | .jsoneditor .value { 21 | word-break: break-word; 22 | } 23 | 24 | .jsoneditor .readonly { 25 | min-width: 16px; 26 | color: gray; 27 | } 28 | 29 | .jsoneditor .empty { 30 | border-color: lightgray; 31 | border-style: dashed; 32 | border-radius: 2px; 33 | } 34 | 35 | .jsoneditor .field.empty { 36 | background-image: url('img/jsoneditor-icons.png'); 37 | background-position: 0 -144px; 38 | } 39 | 40 | .jsoneditor .value.empty { 41 | background-image: url('img/jsoneditor-icons.png'); 42 | background-position: -48px -144px; 43 | } 44 | 45 | .jsoneditor .value.url { 46 | color: green; 47 | text-decoration: underline; 48 | } 49 | 50 | .jsoneditor a.value.url:hover, 51 | .jsoneditor a.value.url:focus { 52 | color: red; 53 | } 54 | 55 | .jsoneditor .separator { 56 | padding: 3px 0; 57 | vertical-align: top; 58 | color: gray; 59 | } 60 | 61 | .jsoneditor .field[contenteditable=true]:focus, 62 | .jsoneditor .field[contenteditable=true]:hover, 63 | .jsoneditor .value[contenteditable=true]:focus, 64 | .jsoneditor .value[contenteditable=true]:hover, 65 | .jsoneditor .field.highlight, 66 | .jsoneditor .value.highlight { 67 | background-color: #FFFFAB; 68 | border: 1px solid yellow; 69 | border-radius: 2px; 70 | } 71 | 72 | .jsoneditor .field.highlight-active, 73 | .jsoneditor .field.highlight-active:focus, 74 | .jsoneditor .field.highlight-active:hover, 75 | .jsoneditor .value.highlight-active, 76 | .jsoneditor .value.highlight-active:focus, 77 | .jsoneditor .value.highlight-active:hover { 78 | background-color: #ffee00; 79 | border: 1px solid #ffc700; 80 | border-radius: 2px; 81 | } 82 | 83 | .jsoneditor div.tree button { 84 | width: 24px; 85 | height: 24px; 86 | padding: 0; 87 | margin: 0; 88 | border: none; 89 | cursor: pointer; 90 | background: transparent url('img/jsoneditor-icons.png'); 91 | } 92 | 93 | .jsoneditor div.tree button.collapsed { 94 | background-position: 0 -48px; 95 | } 96 | 97 | .jsoneditor div.tree button.expanded { 98 | background-position: 0 -72px; 99 | } 100 | 101 | .jsoneditor div.tree button.contextmenu { 102 | background-position: -48px -72px; 103 | } 104 | 105 | .jsoneditor div.tree button.contextmenu:hover, 106 | .jsoneditor div.tree button.contextmenu:focus, 107 | .jsoneditor div.tree button.contextmenu.selected { 108 | background-position: -48px -48px; 109 | } 110 | 111 | .jsoneditor div.tree *:focus { 112 | outline: none; 113 | } 114 | 115 | .jsoneditor div.tree button:focus { 116 | /* TODO: nice outline for buttons with focus 117 | outline: #97B0F8 solid 2px; 118 | box-shadow: 0 0 8px #97B0F8; 119 | */ 120 | background-color: #f5f5f5; 121 | outline: #e5e5e5 solid 1px; 122 | } 123 | 124 | .jsoneditor div.tree button.invisible { 125 | visibility: hidden; 126 | background: none; 127 | } 128 | 129 | .jsoneditor { 130 | color: #1A1A1A; 131 | border: 1px solid #97B0F8; 132 | -moz-box-sizing: border-box; 133 | -webkit-box-sizing: border-box; 134 | box-sizing: border-box; 135 | 136 | width: 100%; 137 | height: 100%; 138 | overflow: auto; 139 | position: relative; 140 | padding: 0; 141 | line-height: 100%; 142 | } 143 | 144 | 145 | .jsoneditor div.tree table.tree { 146 | border-collapse: collapse; 147 | border-spacing: 0; 148 | width: 100%; 149 | margin: 0; 150 | } 151 | 152 | .jsoneditor div.outer { 153 | width: 100%; 154 | height: 100%; 155 | margin: -35px 0 0 0; 156 | padding: 35px 0 0 0; 157 | 158 | -moz-box-sizing: border-box; 159 | -webkit-box-sizing: border-box; 160 | box-sizing: border-box; 161 | 162 | overflow: hidden; 163 | } 164 | 165 | .jsoneditor div.tree { 166 | width: 100%; 167 | height: 100%; 168 | position: relative; 169 | overflow: auto; 170 | } 171 | 172 | .jsoneditor textarea.text { 173 | width: 100%; 174 | height: 100%; 175 | margin: 0; 176 | 177 | -moz-box-sizing: border-box; 178 | -webkit-box-sizing: border-box; 179 | box-sizing: border-box; 180 | 181 | border: none; 182 | background-color: white; 183 | resize: none; 184 | } 185 | 186 | .jsoneditor tr.highlight { 187 | background-color: #FFFFAB; 188 | } 189 | 190 | .jsoneditor div.tree button.dragarea { 191 | background: url('img/jsoneditor-icons.png') -72px -72px; 192 | cursor: move; 193 | } 194 | 195 | .jsoneditor div.tree button.dragarea:hover, 196 | .jsoneditor div.tree button.dragarea:focus { 197 | background-position: -72px -48px; 198 | } 199 | 200 | .jsoneditor tr, 201 | .jsoneditor th, 202 | .jsoneditor td { 203 | padding: 0; 204 | margin: 0; 205 | } 206 | 207 | .jsoneditor td { 208 | vertical-align: top; 209 | } 210 | 211 | .jsoneditor td.tree { 212 | vertical-align: top; 213 | } 214 | 215 | .jsoneditor .field, 216 | .jsoneditor .value, 217 | .jsoneditor td, 218 | .jsoneditor th, 219 | .jsoneditor textarea { 220 | font-family: droid sans mono, consolas, monospace, courier new, courier, sans-serif; 221 | font-size: 10pt; 222 | color: #1A1A1A; 223 | } 224 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/css/menu.css: -------------------------------------------------------------------------------- 1 | 2 | .jsoneditor .menu { 3 | width: 100%; 4 | height: 35px; 5 | padding: 2px; 6 | margin: 0; 7 | overflow: hidden; 8 | -moz-box-sizing: border-box; 9 | -webkit-box-sizing: border-box; 10 | box-sizing: border-box; 11 | 12 | color: #1A1A1A; 13 | background-color: #D5DDF6; 14 | border-bottom: 1px solid #97B0F8; 15 | } 16 | 17 | .jsoneditor .menu button { 18 | width: 26px; 19 | height: 26px; 20 | margin: 2px; 21 | padding: 0; 22 | border-radius: 2px; 23 | border: 1px solid #aec0f8; 24 | background: #e3eaf6 url('img/jsoneditor-icons.png'); 25 | color: #4D4D4D; 26 | opacity: 0.8; 27 | 28 | font-family: arial, sans-serif; 29 | font-size: 10pt; 30 | 31 | float: left; 32 | } 33 | 34 | .jsoneditor .menu button:hover { 35 | background-color: #f0f2f5; 36 | } 37 | .jsoneditor .menu button:focus, 38 | .jsoneditor .menu button:active { 39 | background-color: #ffffff; 40 | } 41 | .jsoneditor .menu button:disabled { 42 | background-color: #e3eaf6; 43 | } 44 | 45 | .jsoneditor .menu button.collapse-all { 46 | background-position: 0 -96px; 47 | } 48 | .jsoneditor .menu button.expand-all { 49 | background-position: 0 -120px; 50 | } 51 | .jsoneditor .menu button.undo { 52 | background-position: -24px -96px; 53 | } 54 | .jsoneditor .menu button.undo:disabled { 55 | background-position: -24px -120px; 56 | } 57 | .jsoneditor .menu button.redo { 58 | background-position: -48px -96px; 59 | } 60 | .jsoneditor .menu button.redo:disabled { 61 | background-position: -48px -120px; 62 | } 63 | .jsoneditor .menu button.compact { 64 | background-position: -72px -96px; 65 | } 66 | .jsoneditor .menu button.format { 67 | background-position: -72px -120px; 68 | } 69 | 70 | .jsoneditor .menu button.modes { 71 | background-image: none; 72 | width: auto; 73 | padding-left: 6px; 74 | padding-right: 6px; 75 | } 76 | 77 | .jsoneditor .menu button.separator { 78 | margin-left: 10px; 79 | } 80 | 81 | .jsoneditor .menu a { 82 | font-family: arial, sans-serif; 83 | font-size: 10pt; 84 | color: #97B0F8; 85 | vertical-align: middle; 86 | } 87 | 88 | .jsoneditor .menu a:hover { 89 | color: red; 90 | } 91 | 92 | .jsoneditor .menu a.poweredBy { 93 | font-size: 8pt; 94 | position: absolute; 95 | right: 0; 96 | top: 0; 97 | padding: 10px; 98 | } 99 | 100 | /* TODO: css for button:disabled is not supported by IE8 */ 101 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/css/searchbox.css: -------------------------------------------------------------------------------- 1 | 2 | .jsoneditor .search input, 3 | .jsoneditor .search .results { 4 | font-family: arial, sans-serif; 5 | font-size: 10pt; 6 | color: #1A1A1A; 7 | background: transparent; /* For Firefox */ 8 | } 9 | 10 | .jsoneditor .search { 11 | position: absolute; 12 | right: 2px; 13 | top: 2px; 14 | } 15 | 16 | .jsoneditor .search .frame { 17 | border: 1px solid #97B0F8; 18 | background-color: white; 19 | padding: 0 2px; 20 | margin: 0; 21 | } 22 | 23 | .jsoneditor .search .frame table { 24 | border-collapse: collapse; 25 | } 26 | 27 | .jsoneditor .search input { 28 | width: 120px; 29 | border: none; 30 | outline: none; 31 | margin: 1px; 32 | } 33 | 34 | .jsoneditor .search .results { 35 | color: #4d4d4d; 36 | padding-right: 5px; 37 | line-height: 24px; 38 | } 39 | 40 | .jsoneditor .search button { 41 | width: 16px; 42 | height: 24px; 43 | padding: 0; 44 | margin: 0; 45 | border: none; 46 | background: url('img/jsoneditor-icons.png'); 47 | vertical-align: top; 48 | } 49 | 50 | .jsoneditor .search button:hover { 51 | background-color: transparent; 52 | } 53 | 54 | .jsoneditor .search button.refresh { 55 | width: 18px; 56 | background-position: -99px -73px; 57 | } 58 | 59 | .jsoneditor .search button.next { 60 | cursor: pointer; 61 | background-position: -124px -73px; 62 | } 63 | .jsoneditor .search button.next:hover { 64 | background-position: -124px -49px; 65 | } 66 | 67 | .jsoneditor .search button.previous { 68 | cursor: pointer; 69 | background-position: -148px -73px; 70 | margin-right: 2px; 71 | } 72 | .jsoneditor .search button.previous:hover { 73 | background-position: -148px -49px; 74 | } 75 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/Highlighter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The highlighter can highlight/unhighlight a node, and 3 | * animate the visibility of a context menu. 4 | * @constructor Highlighter 5 | */ 6 | function Highlighter () { 7 | this.locked = false; 8 | } 9 | 10 | /** 11 | * Hightlight given node and its childs 12 | * @param {Node} node 13 | */ 14 | Highlighter.prototype.highlight = function (node) { 15 | if (this.locked) { 16 | return; 17 | } 18 | 19 | if (this.node != node) { 20 | // unhighlight current node 21 | if (this.node) { 22 | this.node.setHighlight(false); 23 | } 24 | 25 | // highlight new node 26 | this.node = node; 27 | this.node.setHighlight(true); 28 | } 29 | 30 | // cancel any current timeout 31 | this._cancelUnhighlight(); 32 | }; 33 | 34 | /** 35 | * Unhighlight currently highlighted node. 36 | * Will be done after a delay 37 | */ 38 | Highlighter.prototype.unhighlight = function () { 39 | if (this.locked) { 40 | return; 41 | } 42 | 43 | var me = this; 44 | if (this.node) { 45 | this._cancelUnhighlight(); 46 | 47 | // do the unhighlighting after a small delay, to prevent re-highlighting 48 | // the same node when moving from the drag-icon to the contextmenu-icon 49 | // or vice versa. 50 | this.unhighlightTimer = setTimeout(function () { 51 | me.node.setHighlight(false); 52 | me.node = undefined; 53 | me.unhighlightTimer = undefined; 54 | }, 0); 55 | } 56 | }; 57 | 58 | /** 59 | * Cancel an unhighlight action (if before the timeout of the unhighlight action) 60 | * @private 61 | */ 62 | Highlighter.prototype._cancelUnhighlight = function () { 63 | if (this.unhighlightTimer) { 64 | clearTimeout(this.unhighlightTimer); 65 | this.unhighlightTimer = undefined; 66 | } 67 | }; 68 | 69 | /** 70 | * Lock highlighting or unhighlighting nodes. 71 | * methods highlight and unhighlight do not work while locked. 72 | */ 73 | Highlighter.prototype.lock = function () { 74 | this.locked = true; 75 | }; 76 | 77 | /** 78 | * Unlock highlighting or unhighlighting nodes 79 | */ 80 | Highlighter.prototype.unlock = function () { 81 | this.locked = false; 82 | }; 83 | 84 | module.exports = Highlighter; 85 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/History.js: -------------------------------------------------------------------------------- 1 | var util = require('./util'); 2 | 3 | /** 4 | * @constructor History 5 | * Store action history, enables undo and redo 6 | * @param {JSONEditor} editor 7 | */ 8 | function History (editor) { 9 | this.editor = editor; 10 | this.clear(); 11 | 12 | // map with all supported actions 13 | this.actions = { 14 | 'editField': { 15 | 'undo': function (params) { 16 | params.node.updateField(params.oldValue); 17 | }, 18 | 'redo': function (params) { 19 | params.node.updateField(params.newValue); 20 | } 21 | }, 22 | 'editValue': { 23 | 'undo': function (params) { 24 | params.node.updateValue(params.oldValue); 25 | }, 26 | 'redo': function (params) { 27 | params.node.updateValue(params.newValue); 28 | } 29 | }, 30 | 'appendNode': { 31 | 'undo': function (params) { 32 | params.parent.removeChild(params.node); 33 | }, 34 | 'redo': function (params) { 35 | params.parent.appendChild(params.node); 36 | } 37 | }, 38 | 'insertBeforeNode': { 39 | 'undo': function (params) { 40 | params.parent.removeChild(params.node); 41 | }, 42 | 'redo': function (params) { 43 | params.parent.insertBefore(params.node, params.beforeNode); 44 | } 45 | }, 46 | 'insertAfterNode': { 47 | 'undo': function (params) { 48 | params.parent.removeChild(params.node); 49 | }, 50 | 'redo': function (params) { 51 | params.parent.insertAfter(params.node, params.afterNode); 52 | } 53 | }, 54 | 'removeNode': { 55 | 'undo': function (params) { 56 | var parent = params.parent; 57 | var beforeNode = parent.childs[params.index] || parent.append; 58 | parent.insertBefore(params.node, beforeNode); 59 | }, 60 | 'redo': function (params) { 61 | params.parent.removeChild(params.node); 62 | } 63 | }, 64 | 'duplicateNode': { 65 | 'undo': function (params) { 66 | params.parent.removeChild(params.clone); 67 | }, 68 | 'redo': function (params) { 69 | params.parent.insertAfter(params.clone, params.node); 70 | } 71 | }, 72 | 'changeType': { 73 | 'undo': function (params) { 74 | params.node.changeType(params.oldType); 75 | }, 76 | 'redo': function (params) { 77 | params.node.changeType(params.newType); 78 | } 79 | }, 80 | 'moveNode': { 81 | 'undo': function (params) { 82 | params.startParent.moveTo(params.node, params.startIndex); 83 | }, 84 | 'redo': function (params) { 85 | params.endParent.moveTo(params.node, params.endIndex); 86 | } 87 | }, 88 | 'sort': { 89 | 'undo': function (params) { 90 | var node = params.node; 91 | node.hideChilds(); 92 | node.sort = params.oldSort; 93 | node.childs = params.oldChilds; 94 | node.showChilds(); 95 | }, 96 | 'redo': function (params) { 97 | var node = params.node; 98 | node.hideChilds(); 99 | node.sort = params.newSort; 100 | node.childs = params.newChilds; 101 | node.showChilds(); 102 | } 103 | } 104 | 105 | // TODO: restore the original caret position and selection with each undo 106 | // TODO: implement history for actions "expand", "collapse", "scroll", "setDocument" 107 | }; 108 | } 109 | 110 | /** 111 | * The method onChange is executed when the History is changed, and can 112 | * be overloaded. 113 | */ 114 | History.prototype.onChange = function () {}; 115 | 116 | /** 117 | * Add a new action to the history 118 | * @param {String} action The executed action. Available actions: "editField", 119 | * "editValue", "changeType", "appendNode", 120 | * "removeNode", "duplicateNode", "moveNode" 121 | * @param {Object} params Object containing parameters describing the change. 122 | * The parameters in params depend on the action (for 123 | * example for "editValue" the Node, old value, and new 124 | * value are provided). params contains all information 125 | * needed to undo or redo the action. 126 | */ 127 | History.prototype.add = function (action, params) { 128 | this.index++; 129 | this.history[this.index] = { 130 | 'action': action, 131 | 'params': params, 132 | 'timestamp': new Date() 133 | }; 134 | 135 | // remove redo actions which are invalid now 136 | if (this.index < this.history.length - 1) { 137 | this.history.splice(this.index + 1, this.history.length - this.index - 1); 138 | } 139 | 140 | // fire onchange event 141 | this.onChange(); 142 | }; 143 | 144 | /** 145 | * Clear history 146 | */ 147 | History.prototype.clear = function () { 148 | this.history = []; 149 | this.index = -1; 150 | 151 | // fire onchange event 152 | this.onChange(); 153 | }; 154 | 155 | /** 156 | * Check if there is an action available for undo 157 | * @return {Boolean} canUndo 158 | */ 159 | History.prototype.canUndo = function () { 160 | return (this.index >= 0); 161 | }; 162 | 163 | /** 164 | * Check if there is an action available for redo 165 | * @return {Boolean} canRedo 166 | */ 167 | History.prototype.canRedo = function () { 168 | return (this.index < this.history.length - 1); 169 | }; 170 | 171 | /** 172 | * Undo the last action 173 | */ 174 | History.prototype.undo = function () { 175 | if (this.canUndo()) { 176 | var obj = this.history[this.index]; 177 | if (obj) { 178 | var action = this.actions[obj.action]; 179 | if (action && action.undo) { 180 | action.undo(obj.params); 181 | if (obj.params.oldSelection) { 182 | this.editor.setSelection(obj.params.oldSelection); 183 | } 184 | } 185 | else { 186 | util.log('Error: unknown action "' + obj.action + '"'); 187 | } 188 | } 189 | this.index--; 190 | 191 | // fire onchange event 192 | this.onChange(); 193 | } 194 | }; 195 | 196 | /** 197 | * Redo the last action 198 | */ 199 | History.prototype.redo = function () { 200 | if (this.canRedo()) { 201 | this.index++; 202 | 203 | var obj = this.history[this.index]; 204 | if (obj) { 205 | var action = this.actions[obj.action]; 206 | if (action && action.redo) { 207 | action.redo(obj.params); 208 | if (obj.params.newSelection) { 209 | this.editor.setSelection(obj.params.newSelection); 210 | } 211 | } 212 | else { 213 | util.log('Error: unknown action "' + obj.action + '"'); 214 | } 215 | } 216 | 217 | // fire onchange event 218 | this.onChange(); 219 | } 220 | }; 221 | 222 | module.exports = History; 223 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/JSONEditor.js: -------------------------------------------------------------------------------- 1 | var treemode = require('./treemode'); 2 | var textmode = require('./textmode'); 3 | var util = require('./util'); 4 | 5 | /** 6 | * @constructor JSONEditor 7 | * @param {Element} container Container element 8 | * @param {Object} [options] Object with options. available options: 9 | * {String} mode Editor mode. Available values: 10 | * 'tree' (default), 'view', 11 | * 'form', 'text', and 'code'. 12 | * {function} change Callback method, triggered 13 | * on change of contents 14 | * {Boolean} search Enable search box. 15 | * True by default 16 | * Only applicable for modes 17 | * 'tree', 'view', and 'form' 18 | * {Boolean} history Enable history (undo/redo). 19 | * True by default 20 | * Only applicable for modes 21 | * 'tree', 'view', and 'form' 22 | * {String} name Field name for the root node. 23 | * Only applicable for modes 24 | * 'tree', 'view', and 'form' 25 | * {Number} indentation Number of indentation 26 | * spaces. 4 by default. 27 | * Only applicable for 28 | * modes 'text' and 'code' 29 | * @param {Object | undefined} json JSON object 30 | */ 31 | function JSONEditor (container, options, json) { 32 | if (!(this instanceof JSONEditor)) { 33 | throw new Error('JSONEditor constructor called without "new".'); 34 | } 35 | 36 | // check for unsupported browser (IE8 and older) 37 | var ieVersion = util.getInternetExplorerVersion(); 38 | if (ieVersion != -1 && ieVersion < 9) { 39 | throw new Error('Unsupported browser, IE9 or newer required. ' + 40 | 'Please install the newest version of your browser.'); 41 | } 42 | 43 | if (arguments.length) { 44 | this._create(container, options, json); 45 | } 46 | } 47 | 48 | /** 49 | * Configuration for all registered modes. Example: 50 | * { 51 | * tree: { 52 | * mixin: TreeEditor, 53 | * data: 'json' 54 | * }, 55 | * text: { 56 | * mixin: TextEditor, 57 | * data: 'text' 58 | * } 59 | * } 60 | * 61 | * @type { Object. } 62 | */ 63 | JSONEditor.modes = {}; 64 | 65 | /** 66 | * Create the JSONEditor 67 | * @param {Element} container Container element 68 | * @param {Object} [options] See description in constructor 69 | * @param {Object | undefined} json JSON object 70 | * @private 71 | */ 72 | JSONEditor.prototype._create = function (container, options, json) { 73 | this.container = container; 74 | this.options = options || {}; 75 | this.json = json || {}; 76 | 77 | var mode = this.options.mode || 'tree'; 78 | this.setMode(mode); 79 | }; 80 | 81 | /** 82 | * Detach the editor from the DOM 83 | * @private 84 | */ 85 | JSONEditor.prototype._delete = function () {}; 86 | 87 | /** 88 | * Set JSON object in editor 89 | * @param {Object | undefined} json JSON data 90 | */ 91 | JSONEditor.prototype.set = function (json) { 92 | this.json = json; 93 | }; 94 | 95 | /** 96 | * Get JSON from the editor 97 | * @returns {Object} json 98 | */ 99 | JSONEditor.prototype.get = function () { 100 | return this.json; 101 | }; 102 | 103 | /** 104 | * Set string containing JSON for the editor 105 | * @param {String | undefined} jsonText 106 | */ 107 | JSONEditor.prototype.setText = function (jsonText) { 108 | this.json = util.parse(jsonText); 109 | }; 110 | 111 | /** 112 | * Get stringified JSON contents from the editor 113 | * @returns {String} jsonText 114 | */ 115 | JSONEditor.prototype.getText = function () { 116 | return JSON.stringify(this.json); 117 | }; 118 | 119 | /** 120 | * Set a field name for the root node. 121 | * @param {String | undefined} name 122 | */ 123 | JSONEditor.prototype.setName = function (name) { 124 | if (!this.options) { 125 | this.options = {}; 126 | } 127 | this.options.name = name; 128 | }; 129 | 130 | /** 131 | * Get the field name for the root node. 132 | * @return {String | undefined} name 133 | */ 134 | JSONEditor.prototype.getName = function () { 135 | return this.options && this.options.name; 136 | }; 137 | 138 | /** 139 | * Change the mode of the editor. 140 | * JSONEditor will be extended with all methods needed for the chosen mode. 141 | * @param {String} mode Available modes: 'tree' (default), 'view', 'form', 142 | * 'text', and 'code'. 143 | */ 144 | JSONEditor.prototype.setMode = function (mode) { 145 | var container = this.container, 146 | options = util.extend({}, this.options), 147 | data, 148 | name; 149 | 150 | options.mode = mode; 151 | var config = JSONEditor.modes[mode]; 152 | if (config) { 153 | try { 154 | var asText = (config.data == 'text'); 155 | name = this.getName(); 156 | data = this[asText ? 'getText' : 'get'](); // get text or json 157 | 158 | this._delete(); 159 | util.clear(this); 160 | util.extend(this, config.mixin); 161 | this.create(container, options); 162 | 163 | this.setName(name); 164 | this[asText ? 'setText' : 'set'](data); // set text or json 165 | 166 | if (typeof config.load === 'function') { 167 | try { 168 | config.load.call(this); 169 | } 170 | catch (err) {} 171 | } 172 | } 173 | catch (err) { 174 | this._onError(err); 175 | } 176 | } 177 | else { 178 | throw new Error('Unknown mode "' + options.mode + '"'); 179 | } 180 | }; 181 | 182 | /** 183 | * Throw an error. If an error callback is configured in options.error, this 184 | * callback will be invoked. Else, a regular error is thrown. 185 | * @param {Error} err 186 | * @private 187 | */ 188 | JSONEditor.prototype._onError = function(err) { 189 | // TODO: onError is deprecated since version 2.2.0. cleanup some day 190 | if (typeof this.onError === 'function') { 191 | util.log('WARNING: JSONEditor.onError is deprecated. Use options.error instead.'); 192 | this.onError(err); 193 | } 194 | 195 | if (this.options && typeof this.options.error === 'function') { 196 | this.options.error(err); 197 | } 198 | else { 199 | throw err; 200 | } 201 | }; 202 | 203 | /** 204 | * Register a plugin with one ore multiple modes for the JSON Editor. 205 | * 206 | * A mode is described as an object with properties: 207 | * 208 | * - `mode: String` The name of the mode. 209 | * - `mixin: Object` An object containing the mixin functions which 210 | * will be added to the JSONEditor. Must contain functions 211 | * create, get, getText, set, and setText. May have 212 | * additional functions. 213 | * When the JSONEditor switches to a mixin, all mixin 214 | * functions are added to the JSONEditor, and then 215 | * the function `create(container, options)` is executed. 216 | * - `data: 'text' | 'json'` The type of data that will be used to load the mixin. 217 | * - `[load: function]` An optional function called after the mixin 218 | * has been loaded. 219 | * 220 | * @param {Object | Array} mode A mode object or an array with multiple mode objects. 221 | */ 222 | JSONEditor.registerMode = function (mode) { 223 | var i, prop; 224 | 225 | if (util.isArray(mode)) { 226 | // multiple modes 227 | for (i = 0; i < mode.length; i++) { 228 | JSONEditor.registerMode(mode[i]); 229 | } 230 | } 231 | else { 232 | // validate the new mode 233 | if (!('mode' in mode)) throw new Error('Property "mode" missing'); 234 | if (!('mixin' in mode)) throw new Error('Property "mixin" missing'); 235 | if (!('data' in mode)) throw new Error('Property "data" missing'); 236 | var name = mode.mode; 237 | if (name in JSONEditor.modes) { 238 | throw new Error('Mode "' + name + '" already registered'); 239 | } 240 | 241 | // validate the mixin 242 | if (typeof mode.mixin.create !== 'function') { 243 | throw new Error('Required function "create" missing on mixin'); 244 | } 245 | var reserved = ['setMode', 'registerMode', 'modes']; 246 | for (i = 0; i < reserved.length; i++) { 247 | prop = reserved[i]; 248 | if (prop in mode.mixin) { 249 | throw new Error('Reserved property "' + prop + '" not allowed in mixin'); 250 | } 251 | } 252 | 253 | JSONEditor.modes[name] = mode; 254 | } 255 | }; 256 | 257 | // register tree and text modes 258 | JSONEditor.registerMode(treemode); 259 | JSONEditor.registerMode(textmode); 260 | 261 | module.exports = JSONEditor; 262 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/SearchBox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @constructor SearchBox 3 | * Create a search box in given HTML container 4 | * @param {JSONEditor} editor The JSON Editor to attach to 5 | * @param {Element} container HTML container element of where to 6 | * create the search box 7 | */ 8 | function SearchBox (editor, container) { 9 | var searchBox = this; 10 | 11 | this.editor = editor; 12 | this.timeout = undefined; 13 | this.delay = 200; // ms 14 | this.lastText = undefined; 15 | 16 | this.dom = {}; 17 | this.dom.container = container; 18 | 19 | var table = document.createElement('table'); 20 | this.dom.table = table; 21 | table.className = 'search'; 22 | container.appendChild(table); 23 | var tbody = document.createElement('tbody'); 24 | this.dom.tbody = tbody; 25 | table.appendChild(tbody); 26 | var tr = document.createElement('tr'); 27 | tbody.appendChild(tr); 28 | 29 | var td = document.createElement('td'); 30 | tr.appendChild(td); 31 | var results = document.createElement('div'); 32 | this.dom.results = results; 33 | results.className = 'results'; 34 | td.appendChild(results); 35 | 36 | td = document.createElement('td'); 37 | tr.appendChild(td); 38 | var divInput = document.createElement('div'); 39 | this.dom.input = divInput; 40 | divInput.className = 'frame'; 41 | divInput.title = 'Search fields and values'; 42 | td.appendChild(divInput); 43 | 44 | // table to contain the text input and search button 45 | var tableInput = document.createElement('table'); 46 | divInput.appendChild(tableInput); 47 | var tbodySearch = document.createElement('tbody'); 48 | tableInput.appendChild(tbodySearch); 49 | tr = document.createElement('tr'); 50 | tbodySearch.appendChild(tr); 51 | 52 | var refreshSearch = document.createElement('button'); 53 | refreshSearch.className = 'refresh'; 54 | td = document.createElement('td'); 55 | td.appendChild(refreshSearch); 56 | tr.appendChild(td); 57 | 58 | var search = document.createElement('input'); 59 | this.dom.search = search; 60 | search.oninput = function (event) { 61 | searchBox._onDelayedSearch(event); 62 | }; 63 | search.onchange = function (event) { // For IE 9 64 | searchBox._onSearch(event); 65 | }; 66 | search.onkeydown = function (event) { 67 | searchBox._onKeyDown(event); 68 | }; 69 | search.onkeyup = function (event) { 70 | searchBox._onKeyUp(event); 71 | }; 72 | refreshSearch.onclick = function (event) { 73 | search.select(); 74 | }; 75 | 76 | // TODO: ESC in FF restores the last input, is a FF bug, https://bugzilla.mozilla.org/show_bug.cgi?id=598819 77 | td = document.createElement('td'); 78 | td.appendChild(search); 79 | tr.appendChild(td); 80 | 81 | var searchNext = document.createElement('button'); 82 | searchNext.title = 'Next result (Enter)'; 83 | searchNext.className = 'next'; 84 | searchNext.onclick = function () { 85 | searchBox.next(); 86 | }; 87 | td = document.createElement('td'); 88 | td.appendChild(searchNext); 89 | tr.appendChild(td); 90 | 91 | var searchPrevious = document.createElement('button'); 92 | searchPrevious.title = 'Previous result (Shift+Enter)'; 93 | searchPrevious.className = 'previous'; 94 | searchPrevious.onclick = function () { 95 | searchBox.previous(); 96 | }; 97 | td = document.createElement('td'); 98 | td.appendChild(searchPrevious); 99 | tr.appendChild(td); 100 | } 101 | 102 | /** 103 | * Go to the next search result 104 | * @param {boolean} [focus] If true, focus will be set to the next result 105 | * focus is false by default. 106 | */ 107 | SearchBox.prototype.next = function(focus) { 108 | if (this.results != undefined) { 109 | var index = (this.resultIndex != undefined) ? this.resultIndex + 1 : 0; 110 | if (index > this.results.length - 1) { 111 | index = 0; 112 | } 113 | this._setActiveResult(index, focus); 114 | } 115 | }; 116 | 117 | /** 118 | * Go to the prevous search result 119 | * @param {boolean} [focus] If true, focus will be set to the next result 120 | * focus is false by default. 121 | */ 122 | SearchBox.prototype.previous = function(focus) { 123 | if (this.results != undefined) { 124 | var max = this.results.length - 1; 125 | var index = (this.resultIndex != undefined) ? this.resultIndex - 1 : max; 126 | if (index < 0) { 127 | index = max; 128 | } 129 | this._setActiveResult(index, focus); 130 | } 131 | }; 132 | 133 | /** 134 | * Set new value for the current active result 135 | * @param {Number} index 136 | * @param {boolean} [focus] If true, focus will be set to the next result. 137 | * focus is false by default. 138 | * @private 139 | */ 140 | SearchBox.prototype._setActiveResult = function(index, focus) { 141 | // de-activate current active result 142 | if (this.activeResult) { 143 | var prevNode = this.activeResult.node; 144 | var prevElem = this.activeResult.elem; 145 | if (prevElem == 'field') { 146 | delete prevNode.searchFieldActive; 147 | } 148 | else { 149 | delete prevNode.searchValueActive; 150 | } 151 | prevNode.updateDom(); 152 | } 153 | 154 | if (!this.results || !this.results[index]) { 155 | // out of range, set to undefined 156 | this.resultIndex = undefined; 157 | this.activeResult = undefined; 158 | return; 159 | } 160 | 161 | this.resultIndex = index; 162 | 163 | // set new node active 164 | var node = this.results[this.resultIndex].node; 165 | var elem = this.results[this.resultIndex].elem; 166 | if (elem == 'field') { 167 | node.searchFieldActive = true; 168 | } 169 | else { 170 | node.searchValueActive = true; 171 | } 172 | this.activeResult = this.results[this.resultIndex]; 173 | node.updateDom(); 174 | 175 | // TODO: not so nice that the focus is only set after the animation is finished 176 | node.scrollTo(function () { 177 | if (focus) { 178 | node.focus(elem); 179 | } 180 | }); 181 | }; 182 | 183 | /** 184 | * Cancel any running onDelayedSearch. 185 | * @private 186 | */ 187 | SearchBox.prototype._clearDelay = function() { 188 | if (this.timeout != undefined) { 189 | clearTimeout(this.timeout); 190 | delete this.timeout; 191 | } 192 | }; 193 | 194 | /** 195 | * Start a timer to execute a search after a short delay. 196 | * Used for reducing the number of searches while typing. 197 | * @param {Event} event 198 | * @private 199 | */ 200 | SearchBox.prototype._onDelayedSearch = function (event) { 201 | // execute the search after a short delay (reduces the number of 202 | // search actions while typing in the search text box) 203 | this._clearDelay(); 204 | var searchBox = this; 205 | this.timeout = setTimeout(function (event) { 206 | searchBox._onSearch(event); 207 | }, 208 | this.delay); 209 | }; 210 | 211 | /** 212 | * Handle onSearch event 213 | * @param {Event} event 214 | * @param {boolean} [forceSearch] If true, search will be executed again even 215 | * when the search text is not changed. 216 | * Default is false. 217 | * @private 218 | */ 219 | SearchBox.prototype._onSearch = function (event, forceSearch) { 220 | this._clearDelay(); 221 | 222 | var value = this.dom.search.value; 223 | var text = (value.length > 0) ? value : undefined; 224 | if (text != this.lastText || forceSearch) { 225 | // only search again when changed 226 | this.lastText = text; 227 | this.results = this.editor.search(text); 228 | this._setActiveResult(undefined); 229 | 230 | // display search results 231 | if (text != undefined) { 232 | var resultCount = this.results.length; 233 | switch (resultCount) { 234 | case 0: this.dom.results.innerHTML = 'no results'; break; 235 | case 1: this.dom.results.innerHTML = '1 result'; break; 236 | default: this.dom.results.innerHTML = resultCount + ' results'; break; 237 | } 238 | } 239 | else { 240 | this.dom.results.innerHTML = ''; 241 | } 242 | } 243 | }; 244 | 245 | /** 246 | * Handle onKeyDown event in the input box 247 | * @param {Event} event 248 | * @private 249 | */ 250 | SearchBox.prototype._onKeyDown = function (event) { 251 | var keynum = event.which; 252 | if (keynum == 27) { // ESC 253 | this.dom.search.value = ''; // clear search 254 | this._onSearch(event); 255 | event.preventDefault(); 256 | event.stopPropagation(); 257 | } 258 | else if (keynum == 13) { // Enter 259 | if (event.ctrlKey) { 260 | // force to search again 261 | this._onSearch(event, true); 262 | } 263 | else if (event.shiftKey) { 264 | // move to the previous search result 265 | this.previous(); 266 | } 267 | else { 268 | // move to the next search result 269 | this.next(); 270 | } 271 | event.preventDefault(); 272 | event.stopPropagation(); 273 | } 274 | }; 275 | 276 | /** 277 | * Handle onKeyUp event in the input box 278 | * @param {Event} event 279 | * @private 280 | */ 281 | SearchBox.prototype._onKeyUp = function (event) { 282 | var keynum = event.keyCode; 283 | if (keynum != 27 && keynum != 13) { // !show and !Enter 284 | this._onDelayedSearch(event); // For IE 9 285 | } 286 | }; 287 | 288 | module.exports = SearchBox; 289 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/ace/index.js: -------------------------------------------------------------------------------- 1 | // load brace 2 | var ace = require('brace'); 3 | 4 | // load required ace modules 5 | require('brace/mode/json'); 6 | require('brace/ext/searchbox'); 7 | require('./theme-jsoneditor'); 8 | 9 | module.exports = ace; 10 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/ace/theme-jsoneditor.js: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Distributed under the BSD license: 3 | * 4 | * Copyright (c) 2010, Ajax.org B.V. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Ajax.org B.V. nor the 15 | * names of its contributors may be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY 22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | * ***** END LICENSE BLOCK ***** */ 30 | 31 | ace.define('ace/theme/jsoneditor', ['require', 'exports', 'module', 'ace/lib/dom'], function(acequire, exports, module) { 32 | 33 | exports.isDark = false; 34 | exports.cssClass = "ace-jsoneditor"; 35 | exports.cssText = ".ace-jsoneditor .ace_gutter {\ 36 | background: #ebebeb;\ 37 | color: #333\ 38 | }\ 39 | \ 40 | .ace-jsoneditor.ace_editor {\ 41 | font-family: droid sans mono, consolas, monospace, courier new, courier, sans-serif;\ 42 | line-height: 1.3;\ 43 | }\ 44 | .ace-jsoneditor .ace_print-margin {\ 45 | width: 1px;\ 46 | background: #e8e8e8\ 47 | }\ 48 | .ace-jsoneditor .ace_scroller {\ 49 | background-color: #FFFFFF\ 50 | }\ 51 | .ace-jsoneditor .ace_text-layer {\ 52 | color: gray\ 53 | }\ 54 | .ace-jsoneditor .ace_variable {\ 55 | color: #1a1a1a\ 56 | }\ 57 | .ace-jsoneditor .ace_cursor {\ 58 | border-left: 2px solid #000000\ 59 | }\ 60 | .ace-jsoneditor .ace_overwrite-cursors .ace_cursor {\ 61 | border-left: 0px;\ 62 | border-bottom: 1px solid #000000\ 63 | }\ 64 | .ace-jsoneditor .ace_marker-layer .ace_selection {\ 65 | background: #D5DDF6\ 66 | }\ 67 | .ace-jsoneditor.ace_multiselect .ace_selection.ace_start {\ 68 | box-shadow: 0 0 3px 0px #FFFFFF;\ 69 | border-radius: 2px\ 70 | }\ 71 | .ace-jsoneditor .ace_marker-layer .ace_step {\ 72 | background: rgb(255, 255, 0)\ 73 | }\ 74 | .ace-jsoneditor .ace_marker-layer .ace_bracket {\ 75 | margin: -1px 0 0 -1px;\ 76 | border: 1px solid #BFBFBF\ 77 | }\ 78 | .ace-jsoneditor .ace_marker-layer .ace_active-line {\ 79 | background: #FFFBD1\ 80 | }\ 81 | .ace-jsoneditor .ace_gutter-active-line {\ 82 | background-color : #dcdcdc\ 83 | }\ 84 | .ace-jsoneditor .ace_marker-layer .ace_selected-word {\ 85 | border: 1px solid #D5DDF6\ 86 | }\ 87 | .ace-jsoneditor .ace_invisible {\ 88 | color: #BFBFBF\ 89 | }\ 90 | .ace-jsoneditor .ace_keyword,\ 91 | .ace-jsoneditor .ace_meta,\ 92 | .ace-jsoneditor .ace_support.ace_constant.ace_property-value {\ 93 | color: #AF956F\ 94 | }\ 95 | .ace-jsoneditor .ace_keyword.ace_operator {\ 96 | color: #484848\ 97 | }\ 98 | .ace-jsoneditor .ace_keyword.ace_other.ace_unit {\ 99 | color: #96DC5F\ 100 | }\ 101 | .ace-jsoneditor .ace_constant.ace_language {\ 102 | color: darkorange\ 103 | }\ 104 | .ace-jsoneditor .ace_constant.ace_numeric {\ 105 | color: red\ 106 | }\ 107 | .ace-jsoneditor .ace_constant.ace_character.ace_entity {\ 108 | color: #BF78CC\ 109 | }\ 110 | .ace-jsoneditor .ace_invalid {\ 111 | color: #FFFFFF;\ 112 | background-color: #FF002A;\ 113 | }\ 114 | .ace-jsoneditor .ace_fold {\ 115 | background-color: #AF956F;\ 116 | border-color: #000000\ 117 | }\ 118 | .ace-jsoneditor .ace_storage,\ 119 | .ace-jsoneditor .ace_support.ace_class,\ 120 | .ace-jsoneditor .ace_support.ace_function,\ 121 | .ace-jsoneditor .ace_support.ace_other,\ 122 | .ace-jsoneditor .ace_support.ace_type {\ 123 | color: #C52727\ 124 | }\ 125 | .ace-jsoneditor .ace_string {\ 126 | color: green\ 127 | }\ 128 | .ace-jsoneditor .ace_comment {\ 129 | color: #BCC8BA\ 130 | }\ 131 | .ace-jsoneditor .ace_entity.ace_name.ace_tag,\ 132 | .ace-jsoneditor .ace_entity.ace_other.ace_attribute-name {\ 133 | color: #606060\ 134 | }\ 135 | .ace-jsoneditor .ace_markup.ace_underline {\ 136 | text-decoration: underline\ 137 | }\ 138 | .ace-jsoneditor .ace_indent-guide {\ 139 | background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y\ 140 | }"; 141 | 142 | var dom = acequire("../lib/dom"); 143 | dom.importCssString(exports.cssText, exports.cssClass); 144 | }); 145 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/appendNodeFactory.js: -------------------------------------------------------------------------------- 1 | var util = require('./util'); 2 | var ContextMenu = require('./ContextMenu'); 3 | 4 | /** 5 | * A factory function to create an AppendNode, which depends on a Node 6 | * @param {Node} Node 7 | */ 8 | function appendNodeFactory(Node) { 9 | /** 10 | * @constructor AppendNode 11 | * @extends Node 12 | * @param {TreeEditor} editor 13 | * Create a new AppendNode. This is a special node which is created at the 14 | * end of the list with childs for an object or array 15 | */ 16 | function AppendNode (editor) { 17 | /** @type {TreeEditor} */ 18 | this.editor = editor; 19 | this.dom = {}; 20 | } 21 | 22 | AppendNode.prototype = new Node(); 23 | 24 | /** 25 | * Return a table row with an append button. 26 | * @return {Element} dom TR element 27 | */ 28 | AppendNode.prototype.getDom = function () { 29 | // TODO: implement a new solution for the append node 30 | var dom = this.dom; 31 | 32 | if (dom.tr) { 33 | return dom.tr; 34 | } 35 | 36 | this._updateEditability(); 37 | 38 | // a row for the append button 39 | var trAppend = document.createElement('tr'); 40 | trAppend.node = this; 41 | dom.tr = trAppend; 42 | 43 | // TODO: consistent naming 44 | 45 | if (this.editable.field) { 46 | // a cell for the dragarea column 47 | dom.tdDrag = document.createElement('td'); 48 | 49 | // create context menu 50 | var tdMenu = document.createElement('td'); 51 | dom.tdMenu = tdMenu; 52 | var menu = document.createElement('button'); 53 | menu.className = 'contextmenu'; 54 | menu.title = 'Click to open the actions menu (Ctrl+M)'; 55 | dom.menu = menu; 56 | tdMenu.appendChild(dom.menu); 57 | } 58 | 59 | // a cell for the contents (showing text 'empty') 60 | var tdAppend = document.createElement('td'); 61 | var domText = document.createElement('div'); 62 | domText.innerHTML = '(empty)'; 63 | domText.className = 'readonly'; 64 | tdAppend.appendChild(domText); 65 | dom.td = tdAppend; 66 | dom.text = domText; 67 | 68 | this.updateDom(); 69 | 70 | return trAppend; 71 | }; 72 | 73 | /** 74 | * Update the HTML dom of the Node 75 | */ 76 | AppendNode.prototype.updateDom = function () { 77 | var dom = this.dom; 78 | var tdAppend = dom.td; 79 | if (tdAppend) { 80 | tdAppend.style.paddingLeft = (this.getLevel() * 24 + 26) + 'px'; 81 | // TODO: not so nice hard coded offset 82 | } 83 | 84 | var domText = dom.text; 85 | if (domText) { 86 | domText.innerHTML = '(empty ' + this.parent.type + ')'; 87 | } 88 | 89 | // attach or detach the contents of the append node: 90 | // hide when the parent has childs, show when the parent has no childs 91 | var trAppend = dom.tr; 92 | if (!this.isVisible()) { 93 | if (dom.tr.firstChild) { 94 | if (dom.tdDrag) { 95 | trAppend.removeChild(dom.tdDrag); 96 | } 97 | if (dom.tdMenu) { 98 | trAppend.removeChild(dom.tdMenu); 99 | } 100 | trAppend.removeChild(tdAppend); 101 | } 102 | } 103 | else { 104 | if (!dom.tr.firstChild) { 105 | if (dom.tdDrag) { 106 | trAppend.appendChild(dom.tdDrag); 107 | } 108 | if (dom.tdMenu) { 109 | trAppend.appendChild(dom.tdMenu); 110 | } 111 | trAppend.appendChild(tdAppend); 112 | } 113 | } 114 | }; 115 | 116 | /** 117 | * Check whether the AppendNode is currently visible. 118 | * the AppendNode is visible when its parent has no childs (i.e. is empty). 119 | * @return {boolean} isVisible 120 | */ 121 | AppendNode.prototype.isVisible = function () { 122 | return (this.parent.childs.length == 0); 123 | }; 124 | 125 | /** 126 | * Show a contextmenu for this node 127 | * @param {HTMLElement} anchor The element to attach the menu to. 128 | * @param {function} [onClose] Callback method called when the context menu 129 | * is being closed. 130 | */ 131 | AppendNode.prototype.showContextMenu = function (anchor, onClose) { 132 | var node = this; 133 | var titles = Node.TYPE_TITLES; 134 | var items = [ 135 | // create append button 136 | { 137 | 'text': 'Append', 138 | 'title': 'Append a new field with type \'auto\' (Ctrl+Shift+Ins)', 139 | 'submenuTitle': 'Select the type of the field to be appended', 140 | 'className': 'insert', 141 | 'click': function () { 142 | node._onAppend('', '', 'auto'); 143 | }, 144 | 'submenu': [ 145 | { 146 | 'text': 'Auto', 147 | 'className': 'type-auto', 148 | 'title': titles.auto, 149 | 'click': function () { 150 | node._onAppend('', '', 'auto'); 151 | } 152 | }, 153 | { 154 | 'text': 'Array', 155 | 'className': 'type-array', 156 | 'title': titles.array, 157 | 'click': function () { 158 | node._onAppend('', []); 159 | } 160 | }, 161 | { 162 | 'text': 'Object', 163 | 'className': 'type-object', 164 | 'title': titles.object, 165 | 'click': function () { 166 | node._onAppend('', {}); 167 | } 168 | }, 169 | { 170 | 'text': 'String', 171 | 'className': 'type-string', 172 | 'title': titles.string, 173 | 'click': function () { 174 | node._onAppend('', '', 'string'); 175 | } 176 | } 177 | ] 178 | } 179 | ]; 180 | 181 | var menu = new ContextMenu(items, {close: onClose}); 182 | menu.show(anchor); 183 | }; 184 | 185 | /** 186 | * Handle an event. The event is catched centrally by the editor 187 | * @param {Event} event 188 | */ 189 | AppendNode.prototype.onEvent = function (event) { 190 | var type = event.type; 191 | var target = event.target || event.srcElement; 192 | var dom = this.dom; 193 | 194 | // highlight the append nodes parent 195 | var menu = dom.menu; 196 | if (target == menu) { 197 | if (type == 'mouseover') { 198 | this.editor.highlighter.highlight(this.parent); 199 | } 200 | else if (type == 'mouseout') { 201 | this.editor.highlighter.unhighlight(); 202 | } 203 | } 204 | 205 | // context menu events 206 | if (type == 'click' && target == dom.menu) { 207 | var highlighter = this.editor.highlighter; 208 | highlighter.highlight(this.parent); 209 | highlighter.lock(); 210 | util.addClassName(dom.menu, 'selected'); 211 | this.showContextMenu(dom.menu, function () { 212 | util.removeClassName(dom.menu, 'selected'); 213 | highlighter.unlock(); 214 | highlighter.unhighlight(); 215 | }); 216 | } 217 | 218 | if (type == 'keydown') { 219 | this.onKeyDown(event); 220 | } 221 | }; 222 | 223 | return AppendNode; 224 | } 225 | 226 | module.exports = appendNodeFactory; 227 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/header.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jsoneditor.js 3 | * 4 | * @brief 5 | * JSONEditor is a web-based tool to view, edit, and format JSON. 6 | * It shows data a clear, editable treeview. 7 | * 8 | * Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+ 9 | * 10 | * @license 11 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 12 | * use this file except in compliance with the License. You may obtain a copy 13 | * of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software 18 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 19 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 20 | * License for the specific language governing permissions and limitations under 21 | * the License. 22 | * 23 | * Copyright (c) 2011-2015 Jos de Jong, http://jsoneditoronline.org 24 | * 25 | * @author Jos de Jong, 26 | * @version @@version 27 | * @date @@date 28 | */ -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/modeswitcher.js: -------------------------------------------------------------------------------- 1 | var ContextMenu = require('./ContextMenu'); 2 | 3 | /** 4 | * Create a select box to be used in the editor menu's, which allows to switch mode 5 | * @param {Object} editor 6 | * @param {String[]} modes Available modes: 'code', 'form', 'text', 'tree', 'view' 7 | * @param {String} current Available modes: 'code', 'form', 'text', 'tree', 'view' 8 | * @returns {HTMLElement} box 9 | */ 10 | function createModeSwitcher(editor, modes, current) { 11 | // TODO: decouple mode switcher from editor 12 | 13 | /** 14 | * Switch the mode of the editor 15 | * @param {String} mode 16 | */ 17 | function switchMode(mode) { 18 | // switch mode 19 | editor.setMode(mode); 20 | 21 | // restore focus on mode box 22 | var modeBox = editor.dom && editor.dom.modeBox; 23 | if (modeBox) { 24 | modeBox.focus(); 25 | } 26 | } 27 | 28 | // available modes 29 | var availableModes = { 30 | code: { 31 | 'text': 'Code', 32 | 'title': 'Switch to code highlighter', 33 | 'click': function () { 34 | switchMode('code') 35 | } 36 | }, 37 | form: { 38 | 'text': 'Form', 39 | 'title': 'Switch to form editor', 40 | 'click': function () { 41 | switchMode('form'); 42 | } 43 | }, 44 | text: { 45 | 'text': 'Text', 46 | 'title': 'Switch to plain text editor', 47 | 'click': function () { 48 | switchMode('text'); 49 | } 50 | }, 51 | tree: { 52 | 'text': 'Tree', 53 | 'title': 'Switch to tree editor', 54 | 'click': function () { 55 | switchMode('tree'); 56 | } 57 | }, 58 | view: { 59 | 'text': 'View', 60 | 'title': 'Switch to tree view', 61 | 'click': function () { 62 | switchMode('view'); 63 | } 64 | } 65 | }; 66 | 67 | // list the selected modes 68 | var items = []; 69 | for (var i = 0; i < modes.length; i++) { 70 | var mode = modes[i]; 71 | var item = availableModes[mode]; 72 | if (!item) { 73 | throw new Error('Unknown mode "' + mode + '"'); 74 | } 75 | 76 | item.className = 'type-modes' + ((current == mode) ? ' selected' : ''); 77 | items.push(item); 78 | } 79 | 80 | // retrieve the title of current mode 81 | var currentMode = availableModes[current]; 82 | if (!currentMode) { 83 | throw new Error('Unknown mode "' + current + '"'); 84 | } 85 | var currentTitle = currentMode.text; 86 | 87 | // create the html element 88 | var box = document.createElement('button'); 89 | box.className = 'modes separator'; 90 | box.innerHTML = currentTitle + ' ▾'; 91 | box.title = 'Switch editor mode'; 92 | box.onclick = function () { 93 | var menu = new ContextMenu(items); 94 | menu.show(box); 95 | }; 96 | 97 | return box; 98 | } 99 | 100 | exports.create = createModeSwitcher; 101 | -------------------------------------------------------------------------------- /js/jsoneditor-master/src/js/textmode.js: -------------------------------------------------------------------------------- 1 | var ace; 2 | try { 3 | ace = require('./ace'); 4 | } 5 | catch (err) { 6 | // failed to load ace, no problem, we will fall back to plain text 7 | } 8 | 9 | var modeswitcher = require('./modeswitcher'); 10 | var util = require('./util'); 11 | 12 | // create a mixin with the functions for text mode 13 | var textmode = {}; 14 | 15 | /** 16 | * Create a text editor 17 | * @param {Element} container 18 | * @param {Object} [options] Object with options. available options: 19 | * {String} mode Available values: 20 | * "text" (default) 21 | * or "code". 22 | * {Number} indentation Number of indentation 23 | * spaces. 2 by default. 24 | * {function} change Callback method 25 | * triggered on change 26 | * {Object} ace A custom instance of 27 | * Ace editor. 28 | * @private 29 | */ 30 | textmode.create = function (container, options) { 31 | // read options 32 | options = options || {}; 33 | this.options = options; 34 | 35 | // indentation 36 | if (options.indentation) { 37 | this.indentation = Number(options.indentation); 38 | } 39 | else { 40 | this.indentation = 2; // number of spaces 41 | } 42 | 43 | // grab ace from options if provided 44 | var _ace = options.ace ? options.ace : ace; 45 | 46 | // determine mode 47 | this.mode = (options.mode == 'code') ? 'code' : 'text'; 48 | if (this.mode == 'code') { 49 | // verify whether Ace editor is available and supported 50 | if (typeof _ace === 'undefined') { 51 | this.mode = 'text'; 52 | util.log('WARNING: Cannot load code editor, Ace library not loaded. ' + 53 | 'Falling back to plain text editor'); 54 | } 55 | } 56 | 57 | // determine theme 58 | this.theme = options.theme || 'ace/theme/jsoneditor'; 59 | 60 | var me = this; 61 | this.container = container; 62 | this.dom = {}; 63 | this.editor = undefined; // ace code editor 64 | this.textarea = undefined; // plain text editor (fallback when Ace is not available) 65 | 66 | this.width = container.clientWidth; 67 | this.height = container.clientHeight; 68 | 69 | this.frame = document.createElement('div'); 70 | this.frame.className = 'jsoneditor'; 71 | this.frame.onclick = function (event) { 72 | // prevent default submit action when the editor is located inside a form 73 | event.preventDefault(); 74 | }; 75 | this.frame.onkeydown = function (event) { 76 | me._onKeyDown(event); 77 | }; 78 | 79 | // create menu 80 | this.menu = document.createElement('div'); 81 | this.menu.className = 'menu'; 82 | this.frame.appendChild(this.menu); 83 | 84 | // create format button 85 | var buttonFormat = document.createElement('button'); 86 | buttonFormat.className = 'format'; 87 | buttonFormat.title = 'Format JSON data, with proper indentation and line feeds (Ctrl+\\)'; 88 | this.menu.appendChild(buttonFormat); 89 | buttonFormat.onclick = function () { 90 | try { 91 | me.format(); 92 | } 93 | catch (err) { 94 | me._onError(err); 95 | } 96 | }; 97 | 98 | // create compact button 99 | var buttonCompact = document.createElement('button'); 100 | buttonCompact.className = 'compact'; 101 | buttonCompact.title = 'Compact JSON data, remove all whitespaces (Ctrl+Shift+\\)'; 102 | this.menu.appendChild(buttonCompact); 103 | buttonCompact.onclick = function () { 104 | try { 105 | me.compact(); 106 | } 107 | catch (err) { 108 | me._onError(err); 109 | } 110 | }; 111 | 112 | // create mode box 113 | if (this.options && this.options.modes && this.options.modes.length) { 114 | var modeBox = modeswitcher.create(this, this.options.modes, this.options.mode); 115 | this.menu.appendChild(modeBox); 116 | this.dom.modeBox = modeBox; 117 | } 118 | 119 | this.content = document.createElement('div'); 120 | this.content.className = 'outer'; 121 | this.frame.appendChild(this.content); 122 | 123 | this.container.appendChild(this.frame); 124 | 125 | if (this.mode == 'code') { 126 | this.editorDom = document.createElement('div'); 127 | this.editorDom.style.height = '100%'; // TODO: move to css 128 | this.editorDom.style.width = '100%'; // TODO: move to css 129 | this.content.appendChild(this.editorDom); 130 | 131 | var editor = _ace.edit(this.editorDom); 132 | editor.setTheme(this.theme); 133 | editor.setShowPrintMargin(false); 134 | editor.setFontSize(13); 135 | editor.getSession().setMode('ace/mode/json'); 136 | editor.getSession().setTabSize(this.indentation); 137 | editor.getSession().setUseSoftTabs(true); 138 | editor.getSession().setUseWrapMode(true); 139 | this.editor = editor; 140 | 141 | var poweredBy = document.createElement('a'); 142 | poweredBy.appendChild(document.createTextNode('powered by ace')); 143 | poweredBy.href = 'http://ace.ajax.org'; 144 | poweredBy.target = '_blank'; 145 | poweredBy.className = 'poweredBy'; 146 | poweredBy.onclick = function () { 147 | // TODO: this anchor falls below the margin of the content, 148 | // therefore the normal a.href does not work. We use a click event 149 | // for now, but this should be fixed. 150 | window.open(poweredBy.href, poweredBy.target); 151 | }; 152 | this.menu.appendChild(poweredBy); 153 | 154 | if (options.change) { 155 | // register onchange event 156 | editor.on('change', function () { 157 | options.change(); 158 | }); 159 | } 160 | } 161 | else { 162 | // load a plain text textarea 163 | var textarea = document.createElement('textarea'); 164 | textarea.className = 'text'; 165 | textarea.spellcheck = false; 166 | this.content.appendChild(textarea); 167 | this.textarea = textarea; 168 | 169 | if (options.change) { 170 | // register onchange event 171 | if (this.textarea.oninput === null) { 172 | this.textarea.oninput = function () { 173 | options.change(); 174 | } 175 | } 176 | else { 177 | // oninput is undefined. For IE8- 178 | this.textarea.onchange = function () { 179 | options.change(); 180 | } 181 | } 182 | } 183 | } 184 | }; 185 | 186 | /** 187 | * Event handler for keydown. Handles shortcut keys 188 | * @param {Event} event 189 | * @private 190 | */ 191 | textmode._onKeyDown = function (event) { 192 | var keynum = event.which || event.keyCode; 193 | var handled = false; 194 | 195 | if (keynum == 220 && event.ctrlKey) { 196 | if (event.shiftKey) { // Ctrl+Shift+\ 197 | this.compact(); 198 | } 199 | else { // Ctrl+\ 200 | this.format(); 201 | } 202 | handled = true; 203 | } 204 | 205 | if (handled) { 206 | event.preventDefault(); 207 | event.stopPropagation(); 208 | } 209 | }; 210 | 211 | /** 212 | * Detach the editor from the DOM 213 | * @private 214 | */ 215 | textmode._delete = function () { 216 | if (this.frame && this.container && this.frame.parentNode == this.container) { 217 | this.container.removeChild(this.frame); 218 | } 219 | }; 220 | 221 | /** 222 | * Throw an error. If an error callback is configured in options.error, this 223 | * callback will be invoked. Else, a regular error is thrown. 224 | * @param {Error} err 225 | * @private 226 | */ 227 | textmode._onError = function(err) { 228 | // TODO: onError is deprecated since version 2.2.0. cleanup some day 229 | if (typeof this.onError === 'function') { 230 | util.log('WARNING: JSONEditor.onError is deprecated. ' + 231 | 'Use options.error instead.'); 232 | this.onError(err); 233 | } 234 | 235 | if (this.options && typeof this.options.error === 'function') { 236 | this.options.error(err); 237 | } 238 | else { 239 | throw err; 240 | } 241 | }; 242 | 243 | /** 244 | * Compact the code in the formatter 245 | */ 246 | textmode.compact = function () { 247 | var json = this.get(); 248 | var text = JSON.stringify(json); 249 | this.setText(text); 250 | }; 251 | 252 | /** 253 | * Format the code in the formatter 254 | */ 255 | textmode.format = function () { 256 | var json = this.get(); 257 | var text = JSON.stringify(json, null, this.indentation); 258 | this.setText(text); 259 | }; 260 | 261 | /** 262 | * Set focus to the formatter 263 | */ 264 | textmode.focus = function () { 265 | if (this.textarea) { 266 | this.textarea.focus(); 267 | } 268 | if (this.editor) { 269 | this.editor.focus(); 270 | } 271 | }; 272 | 273 | /** 274 | * Resize the formatter 275 | */ 276 | textmode.resize = function () { 277 | if (this.editor) { 278 | var force = false; 279 | this.editor.resize(force); 280 | } 281 | }; 282 | 283 | /** 284 | * Set json data in the formatter 285 | * @param {Object} json 286 | */ 287 | textmode.set = function(json) { 288 | this.setText(JSON.stringify(json, null, this.indentation)); 289 | }; 290 | 291 | /** 292 | * Get json data from the formatter 293 | * @return {Object} json 294 | */ 295 | textmode.get = function() { 296 | var text = this.getText(); 297 | var json; 298 | 299 | try { 300 | json = util.parse(text); // this can throw an error 301 | } 302 | catch (err) { 303 | // try to sanitize json, replace JavaScript notation with JSON notation 304 | text = util.sanitize(text); 305 | 306 | // try to parse again 307 | json = util.parse(text); // this can throw an error 308 | } 309 | 310 | return json; 311 | }; 312 | 313 | /** 314 | * Get the text contents of the editor 315 | * @return {String} jsonText 316 | */ 317 | textmode.getText = function() { 318 | if (this.textarea) { 319 | return this.textarea.value; 320 | } 321 | if (this.editor) { 322 | return this.editor.getValue(); 323 | } 324 | return ''; 325 | }; 326 | 327 | /** 328 | * Set the text contents of the editor 329 | * @param {String} jsonText 330 | */ 331 | textmode.setText = function(jsonText) { 332 | if (this.textarea) { 333 | this.textarea.value = jsonText; 334 | } 335 | if (this.editor) { 336 | this.editor.setValue(jsonText, -1); 337 | } 338 | }; 339 | 340 | // define modes 341 | module.exports = [ 342 | { 343 | mode: 'text', 344 | mixin: textmode, 345 | data: 'text', 346 | load: textmode.format 347 | }, 348 | { 349 | mode: 'code', 350 | mixin: textmode, 351 | data: 'text', 352 | load: textmode.format 353 | } 354 | ]; 355 | -------------------------------------------------------------------------------- /js/jsoneditor-master/test/couchdbeditor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CouchDB Document Editor 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 34 | 35 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 93 | 94 | 95 | 96 | 97 |

CouchDB Document Editor

80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
Document Url:
92 |
98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /js/jsoneditor-master/test/test_build.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 26 | 27 | 28 | 29 |

30 | Switch editor mode using the mode box. 31 | Note that the mode can be changed programmatically as well using the method 32 | editor.setMode(mode), try it in the console of your browser. 33 |

34 | 35 |
36 | 37 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /js/jsoneditor-master/test/test_build_min.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 26 | 27 | 28 | 29 |

30 | Switch editor mode using the mode box. 31 | Note that the mode can be changed programmatically as well using the method 32 | editor.setMode(mode), try it in the console of your browser. 33 |

34 | 35 |
36 | 37 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /js/jsoneditor-master/test/util.test.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var util = require('../src/js/util'); 3 | 4 | describe('util', function () { 5 | 6 | describe('sanitize', function () { 7 | 8 | it('should leave valid JSON as is', function () { 9 | assert.equal(util.sanitize('{"a":2}'), '{"a":2}'); 10 | }); 11 | 12 | it('should replace JavaScript with JSON', function () { 13 | assert.equal(util.sanitize('{a:2}'), '{"a":2}'); 14 | assert.equal(util.sanitize('{\'a\':2}'), '{"a":2}'); 15 | assert.equal(util.sanitize('{a:\'foo\'}'), '{"a":"foo"}'); 16 | 17 | // should leave string content untouched 18 | assert.equal(util.sanitize('"{a:b}"'), '"{a:b}"'); 19 | }); 20 | 21 | it('should add/remove escape characters', function () { 22 | assert.equal(util.sanitize('"foo\'bar"'), '"foo\'bar"'); 23 | assert.equal(util.sanitize('"foo\\"bar"'), '"foo\\"bar"'); 24 | assert.equal(util.sanitize('\'foo"bar\''), '"foo\\"bar"'); 25 | assert.equal(util.sanitize('\'foo\\\'bar\''), '"foo\'bar"'); 26 | assert.equal(util.sanitize('"foo\\\'bar"'), '"foo\'bar"'); 27 | }); 28 | 29 | it('remove comments', function () { 30 | assert.equal(util.sanitize('/* foo */ {}'), ' {}'); 31 | 32 | // should not remove comments in string 33 | assert.equal(util.sanitize('{"str":"/* foo */"}'), '{"str":"/* foo */"}'); 34 | }); 35 | 36 | it('should strip JSONP notation', function () { 37 | // matching 38 | assert.equal(util.sanitize('callback_123({});'), '{}'); 39 | assert.equal(util.sanitize('callback_123([]);'), '[]'); 40 | assert.equal(util.sanitize('callback_123(2);'), '2'); 41 | assert.equal(util.sanitize('callback_123("foo");'), '"foo"'); 42 | assert.equal(util.sanitize('callback_123(null);'), 'null'); 43 | assert.equal(util.sanitize('callback_123(true);'), 'true'); 44 | assert.equal(util.sanitize('callback_123(false);'), 'false'); 45 | assert.equal(util.sanitize('/* foo bar */ callback_123 ({})'), '{}'); 46 | assert.equal(util.sanitize('/* foo bar */ callback_123 ({})'), '{}'); 47 | assert.equal(util.sanitize('/* foo bar */\ncallback_123({})'), '{}'); 48 | assert.equal(util.sanitize('/* foo bar */ callback_123 ( {} )'), ' {} '); 49 | assert.equal(util.sanitize(' /* foo bar */ callback_123 ({}); '), '{}'); 50 | assert.equal(util.sanitize('\n/* foo\nbar */\ncallback_123 ({});\n\n'), '{}'); 51 | 52 | // non-matching 53 | assert.equal(util.sanitize('callback abc({});'), 'callback abc({});'); 54 | assert.equal(util.sanitize('callback {}'), 'callback {}'); 55 | assert.equal(util.sanitize('callback({}'), 'callback({}'); 56 | }); 57 | 58 | }); 59 | 60 | // TODO: thoroughly test all util methods 61 | }); -------------------------------------------------------------------------------- /js/nls/fr/resources.js: -------------------------------------------------------------------------------- 1 | /*global define */ 2 | /* 3 | | Copyright 2014 Esri 4 | | 5 | | Licensed under the Apache License, Version 2.0 (the "License"); 6 | | you may not use this file except in compliance with the License. 7 | | You may obtain a copy of the License at 8 | | 9 | | http://www.apache.org/licenses/LICENSE-2.0 10 | | 11 | | Unless required by applicable law or agreed to in writing, software 12 | | distributed under the License is distributed on an "AS IS" BASIS, 13 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | | See the License for the specific language governing permissions and 15 | | limitations under the License. 16 | */ 17 | define(({ 18 | map: { 19 | error: "Impossible de créer la carte" 20 | } 21 | })); -------------------------------------------------------------------------------- /js/nls/resources.js: -------------------------------------------------------------------------------- 1 | /*global define */ 2 | /* 3 | | Copyright 2014 Esri 4 | | 5 | | Licensed under the Apache License, Version 2.0 (the "License"); 6 | | you may not use this file except in compliance with the License. 7 | | You may obtain a copy of the License at 8 | | 9 | | http://www.apache.org/licenses/LICENSE-2.0 10 | | 11 | | Unless required by applicable law or agreed to in writing, software 12 | | distributed under the License is distributed on an "AS IS" BASIS, 13 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | | See the License for the specific language governing permissions and 15 | | limitations under the License. 16 | */ 17 | define({ 18 | root: ({ 19 | map: { 20 | error: "Unable to create map" 21 | } 22 | }), 23 | "fr": 1 24 | }); -------------------------------------------------------------------------------- /oauth-callback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /previous/index_OLD.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Vector Basemap Style Editor 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 38 | 39 | 69 | 70 | 71 |
72 |
73 | 74 | 75 | 87 | 88 |
76 | Vector Basemap Style Editor 77 | 78 | Esri Vector Basemaps 79 | | 80 | Style Reference 81 | | 82 | GitHub 83 | | 84 | Show Me 85 | 86 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | 99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
Zoom: 1
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | 122 | 123 | 124 | 125 | 126 |
127 | 128 | 129 |
130 | 131 | source-layer: 132 | 133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
Style Type
142 |
143 |
144 |
145 |
Basemap Color Palette
146 |
147 |
148 |
149 |
150 | 151 | 152 | 153 | 154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | 167 |
168 |
169 |
170 | 171 | -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Created by Camtasia Studio 8 9 | 10 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004.mp4 -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_First_Frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_First_Frame.png -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_Thumbnails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_Thumbnails.png -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | English 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_controller.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_controller.swf -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_embed.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | #tsc_player { 4 | z-index: 9999; 5 | } 6 | 7 | .tscplayer_inline { 8 | position:static; 9 | margin: 30px; 10 | width: 852px; 11 | height: 480px; 12 | z-index:auto; 13 | } 14 | 15 | .tscplayer_fullframe { 16 | position:absolute; 17 | top: 0px; 18 | left: 0px; 19 | margin: 0px; 20 | padding: 0px; 21 | z-index: 9999; 22 | } 23 | 24 | @media screen and (max-width: 852px) { 25 | .tscplayer_inline { 26 | width: 100%; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/VectorBasemapStyleEditor_004_player.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 24 |
25 | 26 | 27 | 74 | 75 | -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/scripts/config_xml.js: -------------------------------------------------------------------------------- 1 | var TSC = TSC || {}; 2 | 3 | TSC.embedded_config_xml = '\ 4 | \ 5 | \ 6 | \ 7 | \ 8 | \ 9 | \ 10 | English\ 11 | \ 12 | \ 13 | \ 14 | \ 15 | \ 16 | \ 17 | \ 18 | \ 19 | \ 20 | \ 21 | \ 22 | \ 23 | \ 24 | \ 25 | \ 26 | \ 27 | \ 28 | \ 29 | \ 30 | \ 31 | \ 32 | \ 33 | \ 34 | \ 35 | \ 36 | \ 37 | \ 38 | '; 39 | -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/skins/overlay/spritesheet.min.css: -------------------------------------------------------------------------------- 1 | .spritesheet{display:inline-block;overflow:hidden;background-repeat:no-repeat;background-image:url(spritesheet.png)}.sprite_repeat{background-repeat:repeat-x!important}.rewind_button_normal{width:43px;height:43px;background-position:-192px -226px}.rewind_button_over{width:43px;height:43px;background-position:-240px -226px}.rewind_button_down{width:43px;height:43px;background-position:-144px -288px}.rewind_button_disabled{width:43px;height:43px;background-position:-192px -226px}.play_button_normal{width:43px;height:43px;background-position:-144px -0px}.play_button_over{width:43px;height:43px;background-position:-144px -48px}.play_button_down{width:43px;height:43px;background-position:-96px -288px}.play_button_disabled{width:43px;height:43px;background-position:-144px -0px}.pause_button_normal{width:43px;height:43px;background-position:-96px -192px}.pause_button_over{width:43px;height:43px;background-position:-96px -240px}.pause_button_down{width:43px;height:43px;background-position:-96px -144px}.pause_button_disabled{width:43px;height:43px;background-position:-96px -192px}.previous_button_normal{width:43px;height:43px;background-position:-144px -192px}.previous_button_over{width:43px;height:43px;background-position:-144px -240px}.previous_button_down{width:43px;height:43px;background-position:-144px -144px}.previous_button_disabled{width:43px;height:43px;background-position:-144px -96px}.next_button_normal{width:43px;height:43px;background-position:-96px -48px}.next_button_over{width:43px;height:43px;background-position:-96px -96px}.next_button_down{width:43px;height:43px;background-position:-96px -0px}.next_button_disabled{width:43px;height:43px;background-position:-48px -288px}.settings_button_normal{width:43px;height:43px;background-position:-380px -0px}.settings_button_over{width:43px;height:43px;background-position:-428px -0px}.settings_button_down{width:43px;height:43px;background-position:-332px -0px}.settings_button_disabled{width:43px;height:43px;background-position:-380px -0px}.settings_off_button_normal{width:43px;height:43px;background-position:-476px -0px}.settings_off_button_over{width:43px;height:43px;background-position:-476px -0px}.settings_off_button_down{width:43px;height:43px;background-position:-476px -0px}.settings_off_button_disabled{width:43px;height:43px;background-position:-476px -0px}.closed_caption_button_normal{width:43px;height:43px;background-position:-0px -48px}.closed_caption_button_over{width:43px;height:43px;background-position:-0px -96px}.closed_caption_button_down{width:43px;height:43px;background-position:-0px -0px}.closed_caption_button_disabled{width:43px;height:43px;background-position:-0px -48px}.closed_caption_off_button_normal{width:43px;height:43px;background-position:-0px -144px}.closed_caption_off_button_over{width:43px;height:43px;background-position:-0px -144px}.closed_caption_off_button_down{width:43px;height:43px;background-position:-0px -144px}.closed_caption_off_button_disabled{width:43px;height:43px;background-position:-0px -144px}.toc_button_normal{width:43px;height:43px;background-position:-353px -48px}.toc_button_over{width:43px;height:43px;background-position:-401px -48px}.toc_button_down{width:43px;height:43px;background-position:-305px -48px}.toc_button_disabled{width:43px;height:43px;background-position:-353px -48px}.toc_off_button_normal{width:43px;height:43px;background-position:-449px -48px}.toc_off_button_over{width:43px;height:43px;background-position:-449px -48px}.toc_off_button_down{width:43px;height:43px;background-position:-449px -48px}.toc_off_button_disabled{width:43px;height:43px;background-position:-449px -48px}.fullscreen_enter_button_normal{width:43px;height:43px;background-position:-48px -48px}.fullscreen_enter_button_over{width:43px;height:43px;background-position:-48px -96px}.fullscreen_enter_button_down{width:43px;height:43px;background-position:-48px -0px}.fullscreen_enter_button_disabled{width:43px;height:43px;background-position:-48px -48px}.fullscreen_leave_button_normal{width:43px;height:43px;background-position:-48px -192px}.fullscreen_leave_button_over{width:43px;height:43px;background-position:-48px -240px}.fullscreen_leave_button_down{width:43px;height:43px;background-position:-48px -144px}.fullscreen_leave_button_disabled{width:43px;height:43px;background-position:-48px -192px}.fullframe_enter_button_normal{width:43px;height:43px;background-position:-0px -240px}.fullframe_enter_button_over{width:43px;height:43px;background-position:-0px -240px}.fullframe_enter_button_down{width:43px;height:43px;background-position:-0px -240px}.fullframe_enter_button_disabled{width:43px;height:43px;background-position:-0px -240px}.fullframe_leave_button_normal{width:43px;height:43px;background-position:-0px -288px}.fullframe_leave_button_over{width:43px;height:43px;background-position:-0px -288px}.fullframe_leave_button_down{width:43px;height:43px;background-position:-0px -288px}.fullframe_leave_button_disabled{width:43px;height:43px;background-position:-0px -288px}.play_button_overlay_normal{width:108px;height:108px;background-position:-192px -0px}.play_button_overlay_over{width:108px;height:108px;background-position:-192px -0px}.play_button_overlay_down{width:108px;height:108px;background-position:-192px -0px}.play_button_overlay_disabled{width:108px;height:108px;background-position:-192px -0px}.replay_button_overlay_normal{width:108px;height:108px;background-position:-192px -113px}.replay_button_overlay_over{width:108px;height:108px;background-position:-192px -113px}.replay_button_overlay_down{width:108px;height:108px;background-position:-192px -113px}.replay_button_overlay_disabled{width:108px;height:108px;background-position:-192px -113px}.scroll_down_arrow_normal{width:16px;height:16px;background-position:-14px -213px}.scroll_down_arrow_over{width:16px;height:16px;background-position:-192px -274px}.scroll_down_arrow_down{width:16px;height:16px;background-position:-14px -213px}.scroll_down_arrow_disabled{width:16px;height:16px;background-position:-14px -213px}.scroll_up_arrow_normal{width:16px;height:16px;background-position:-232px -313px}.scroll_up_arrow_over{width:16px;height:16px;background-position:-253px -292px}.scroll_up_arrow_down{width:16px;height:16px;background-position:-232px -292px}.scroll_up_arrow_disabled{width:16px;height:16px;background-position:-232px -313px}.scroll_thumb_bottom_normal{width:14px;height:50px;background-position:-192px -295px}.scroll_thumb_bottom_over{width:14px;height:50px;background-position:-192px -295px}.scroll_thumb_bottom_down{width:14px;height:50px;background-position:-192px -295px}.scroll_thumb_bottom_disabled{width:14px;height:50px;background-position:-192px -295px}.scroll_track_normal{width:15px;height:13px;background-position:-232px -274px}.scroll_track_over{width:16px;height:4px;background-position:-69px -336px}.scroll_track_down{width:16px;height:4px;background-position:-48px -336px}.scroll_track_disabled{width:15px;height:13px;background-position:-232px -274px}.scrubbar_scrubber_normal{width:10px;height:43px;background-position:-305px -0px}.scrubbar_scrubber_over{width:10px;height:43px;background-position:-305px -0px}.scrubbar_scrubber_down{width:10px;height:43px;background-position:-305px -0px}.scrubbar_scrubber_disabled{width:10px;height:43px;background-position:-305px -0px}.unmute_button_normal{width:43px;height:43px;background-position:-545px -48px}.unmute_button_over{width:43px;height:43px;background-position:-305px -96px}.unmute_button_down{width:43px;height:43px;background-position:-497px -48px}.unmute_button_disabled{width:43px;height:43px;background-position:-545px -48px}.volume_button_normal{width:43px;height:43px;background-position:-353px -192px}.volume_button_over{width:43px;height:43px;background-position:-353px -240px}.volume_button_down{width:43px;height:43px;background-position:-305px -144px}.volume_button_disabled{width:43px;height:43px;background-position:-353px -192px}.volume_button_low_normal{width:43px;height:43px;background-position:-401px -96px}.volume_button_low_over{width:43px;height:43px;background-position:-449px -96px}.volume_button_low_down{width:43px;height:43px;background-position:-353px -96px}.volume_button_low_disabled{width:43px;height:43px;background-position:-401px -96px}.volume_button_med_normal{width:43px;height:43px;background-position:-545px -96px}.volume_button_med_over{width:43px;height:43px;background-position:-353px -144px}.volume_button_med_down{width:43px;height:43px;background-position:-497px -96px}.volume_button_med_disabled{width:43px;height:43px;background-position:-545px -96px}.volume_button_high_normal{width:43px;height:43px;background-position:-305px -240px}.volume_button_high_over{width:43px;height:43px;background-position:-305px -288px}.volume_button_high_down{width:43px;height:43px;background-position:-305px -192px}.volume_button_high_disabled{width:43px;height:43px;background-position:-305px -240px}.volumebar_slider_normal{width:13px;height:9px;background-position:-96px -336px}.volumebar_slider_over{width:13px;height:9px;background-position:-96px -336px}.volumebar_slider_down{width:13px;height:9px;background-position:-96px -336px}.volumebar_slider_disabled{width:13px;height:9px;background-position:-96px -336px}.scrubbar_loaded_track_end{width:2px;height:43px;background-position:-288px -226px}.scrubbar_track_left{width:1px;height:43px;background-position:-295px -226px}.scrubbar_track_right{width:1px;height:43px;background-position:-320px -0px}.scrubbar_track{width:2px;height:43px;background-position:-0px -479px}.scrubbar_loaded_track{width:2px;height:43px;background-position:-0px -393px}.scrubbar_played_track{width:2px;height:43px;background-position:-0px -436px}.seperator{width:1px;height:43px;background-position:-326px -0px}.volumebar_track{width:5px;height:2px;background-position:-35px -192px}.volumebar_track_end{width:5px;height:2px;background-position:-35px -199px}.volumebar_backdrop{width:31px;height:97px;background-position:-401px -144px}.control_backdrop_left{width:2px;height:43px;background-position:-0px -192px}.control_backdrop_right{width:2px;height:43px;background-position:-7px -192px}.toc_title_backdrop{width:8px;height:18px;background-position:-0px -522px}.control_backdrop{width:2px;height:43px;background-position:-0px -350px} -------------------------------------------------------------------------------- /resources/VectorBasemapStyleEditor_004/skins/overlay/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrayson-apl/VectorBasemapStyleEditor/eb7c2e4b2dc58583e7d70b6de4fec5f9cd419653/resources/VectorBasemapStyleEditor_004/skins/overlay/spritesheet.png -------------------------------------------------------------------------------- /resources/configurationPanel.js: -------------------------------------------------------------------------------- 1 | { 2 | "configurationSettings":[ 3 | { 4 | "category":"Configure template", 5 | "fields":[ 6 | { 7 | "type":"webmap" 8 | }, 9 | { 10 | "placeHolder":"Defaults to map owner", 11 | "label":"Owner Text:", 12 | "fieldName":"owner", 13 | "type":"string", 14 | "tooltip":"Defaults to map owner" 15 | }, 16 | { 17 | "type":"string", 18 | "fieldName":"theme", 19 | "tooltip":"Color theme to use", 20 | "label":"Color Scheme:", 21 | "options":[ 22 | { 23 | "label":"Chrome", 24 | "value":"chrome" 25 | }, 26 | { 27 | "label":"Seaside", 28 | "value":"seaside" 29 | }, 30 | { 31 | "label":"Pavement", 32 | "value":"pavement" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | ], 39 | "values":{ 40 | 41 | } 42 | } --------------------------------------------------------------------------------