├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── README.md ├── index.js ├── lib ├── classdata.js ├── conf │ ├── aliases.json │ ├── alternates.json │ └── foundation.json └── rules │ ├── ext-array-foreach.js │ ├── ext-deps.js │ ├── no-ext-create.js │ └── no-ext-multi-def.js ├── package.json └── test ├── conf └── bootstrap.js └── lib ├── classdata.js └── rules ├── ext-array-foreach.js ├── ext-deps.js ├── no-ext-create.js └── no-ext-multi-def.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .c9/ 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.12" 4 | - "0.10" 5 | sudo: false 6 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | for (var key in grunt.file.readJSON("package.json").devDependencies) { 3 | if (key !== "grunt" && key !== "grunt-cli" && key.indexOf("grunt") === 0) { 4 | grunt.loadNpmTasks(key); 5 | } 6 | } 7 | 8 | grunt.initConfig({ 9 | mochaTest: { 10 | test: { 11 | options: { 12 | reporter: 'spec' 13 | }, 14 | src: ['test/lib/**/*.js'] 15 | } 16 | } 17 | }); 18 | 19 | grunt.registerTask('test', 'mochaTest:test'); 20 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Nat Burns 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | eslint-plugin-extjs 2 | ============ 3 | [![npm](https://img.shields.io/npm/v/eslint-plugin-extjs.svg)](https://npmjs.org/package/eslint-plugin-extjs) [![Travis](https://img.shields.io/travis/burnnat/eslint-plugin-extjs.svg)](https://travis-ci.org/burnnat/eslint-plugin-extjs) [![Gemnasium](https://img.shields.io/gemnasium/burnnat/eslint-plugin-extjs.svg)](https://gemnasium.com/burnnat/eslint-plugin-extjs) 4 | 5 | ESLint rules for projects using the ExtJS framework. These rules are targeted for use with ExtJS 4.x. Pull requests for compatibility with 5.x are welcome! 6 | 7 | ## Rule Details 8 | 9 | ### ext-array-foreach 10 | 11 | The two main array iterator functions provided by ExtJS, [`Ext.Array.forEach`][ext-array-foreach] 12 | and [`Ext.Array.each`][ext-array-each], differ in that `each` provides extra 13 | functionality for early termination and reverse iteration. The `forEach` method, 14 | however, will delegate to the browser's native [`Array.forEach`][array-foreach] 15 | implementation where available, for performance. So, in situations where the 16 | extra features of `each` are not needed, `forEach` should be preferred. As the 17 | `forEach` documentation says: 18 | 19 | > [Ext.Array.forEach] will simply delegate to the native Array.prototype.forEach 20 | > method if supported. It doesn't support stopping the iteration by returning 21 | > false in the callback function like each. However, performance could be much 22 | > better in modern browsers comparing with each. 23 | 24 | The following patterns are considered warnings: 25 | 26 | Ext.Array.each( 27 | ['a', 'b'], 28 | function() { 29 | // do something 30 | } 31 | ); 32 | 33 | Ext.Array.each( 34 | ['a', 'b'], 35 | function() { 36 | // do something 37 | }, 38 | this, 39 | false 40 | ); 41 | 42 | The following patterns are not considered warnings: 43 | 44 | Ext.Array.forEach( 45 | ['a', 'b'], 46 | function() { 47 | // do something 48 | } 49 | ); 50 | 51 | Ext.Array.each( 52 | ['a', 'b'], 53 | function(item) { 54 | if (item === 'a') { 55 | return false; 56 | } 57 | } 58 | ); 59 | 60 | Ext.Array.each( 61 | ['a', 'b'], 62 | function() { 63 | // do something 64 | }, 65 | this, 66 | true 67 | ); 68 | 69 | ### ext-deps 70 | 71 | One problem with larger ExtJS projects is keeping the [`uses`][ext-uses] and 72 | [`requires`][ext-requires] configs for a class synchronized as its body changes 73 | over time and dependencies are added and removed. This rule checks that all 74 | external references within a particular class have a corresponding entry in the 75 | `uses` or `requires` config, and that there are no extraneous dependencies 76 | listed in the class configuration that are not referenced in the class body. 77 | 78 | The following patterns are considered warnings: 79 | 80 | Ext.define('App', { 81 | requires: ['Ext.panel.Panel'] 82 | }); 83 | 84 | Ext.define('App', { 85 | constructor: function() { 86 | this.panel = new Ext.panel.Panel(); 87 | } 88 | }); 89 | 90 | The following patterns are not considered warnings: 91 | 92 | Ext.define('App', { 93 | requires: ['Ext.panel.Panel'], 94 | 95 | constructor: function() { 96 | this.panel = new Ext.panel.Panel(); 97 | } 98 | }); 99 | 100 | Ext.define('App', { 101 | extend: 'Ext.panel.Panel' 102 | }); 103 | 104 | ### no-ext-create 105 | 106 | While using [`Ext.create`][ext-create] for instantiation has some benefits 107 | during development, mainly synchronous loading of missing classes, it remains 108 | slower than the `new` operator due to its extra overhead. For projects with 109 | properly configured [`uses`][ext-uses] and [`requires`][ext-requires] blocks, 110 | the extra features of `Ext.create` are not needed, so the `new` keyword should 111 | be preferred in cases where the class name is static. This is confirmed by 112 | Sencha employees, one of whom has [said][ext-create-forum]: 113 | 114 | > 'Ext.create' is slower than 'new'. Its chief benefit is for situations where 115 | > the class name is a dynamic value and 'new' is not an option. As long as the 116 | > 'requires' declarations are correct, the overhead of 'Ext.create' is simply 117 | > not needed. 118 | 119 | The following patterns are considered warnings: 120 | 121 | var panel = Ext.create('Ext.util.Something', { 122 | someConfig: true 123 | }); 124 | 125 | The following patterns are not considered warnings: 126 | 127 | var panel = new Ext.util.Something({ 128 | someConfig: true 129 | }); 130 | 131 | var panel = Ext.create(getDynamicClassName(), { 132 | config: true 133 | }); 134 | 135 | ### no-ext-multi-def 136 | 137 | Best practices for ExtJS 4 [dictate][ext-class-system] that each class 138 | definition be placed in its own file, and that the filename should correspond to 139 | the class being defined therein. This rule checks that there is no more than one 140 | top-level class definition included per file. 141 | 142 | The following patterns are considered warnings: 143 | 144 | // all in one file 145 | Ext.define('App.First', { 146 | // ... 147 | }); 148 | Ext.define('App.Second', { 149 | // ... 150 | }); 151 | 152 | The following patterns are not considered warnings: 153 | 154 | // file a 155 | Ext.define('App', { 156 | // class definition 157 | }); 158 | 159 | // file b 160 | Ext.define('App', { 161 | dynamicDefine: function() { 162 | Ext.define('Dynamic' + Ext.id(), { 163 | // class definition 164 | }); 165 | } 166 | }); 167 | 168 | [array-foreach]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach 169 | [ext-array-foreach]: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.Array-method-forEach 170 | [ext-array-each]: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.Array-method-each 171 | [ext-class-system]: http://docs.sencha.com/extjs/4.2.1/#!/guide/class_system-section-2%29-source-files 172 | [ext-create]: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext-method-create 173 | [ext-create-forum]: http://www.sencha.com/forum/showthread.php?166536-Ext.draw-Ext.create-usage-dropped-why&p=700522&viewfull=1#post700522 174 | [ext-requires]: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.Class-cfg-requires 175 | [ext-uses]: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.Class-cfg-uses 176 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'ext-array-foreach': require('./lib/rules/ext-array-foreach'), 4 | 'ext-deps': require('./lib/rules/ext-deps'), 5 | 'no-ext-create': require('./lib/rules/no-ext-create'), 6 | 'no-ext-multi-def': require('./lib/rules/no-ext-multi-def') 7 | }, 8 | rulesConfig: { 9 | 'ext-array-foreach': 0, 10 | 'ext-deps': 0, 11 | 'no-ext-create': 0, 12 | 'no-ext-multi-def': 0 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /lib/classdata.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | 3 | var foundation = require("./conf/foundation.json"); 4 | var alternates = require("./conf/alternates.json"); 5 | var aliases = require("./conf/aliases.json"); 6 | 7 | var camel = "(?:[A-Z]+[a-z0-9]*)+"; 8 | var lower = "[a-z]+[a-z0-9]*"; 9 | 10 | var bootPrefix = "Ext\\.ClassManager\\."; 11 | var bootSuffix = "\\(([\\s\\S]*?)\\)"; 12 | 13 | var bootAliasRe = new RegExp(bootPrefix + "addNameAliasMappings" + bootSuffix); 14 | var bootAlternatesRe = new RegExp(bootPrefix + "addNameAlternateMappings" + bootSuffix); 15 | 16 | var aliasRe = /^(.*?)\.(.*)$/; 17 | var namespaceRe = new RegExp("^" + camel + "$"); 18 | var classRe = new RegExp("^" + camel + "(?:\\." + lower + ")*\\." + camel); 19 | 20 | var ClassList = function() { 21 | this.foundation = {}; 22 | this.namespaces = {}; 23 | this.alternates = {}; 24 | this.aliases = { 25 | layout: {}, 26 | proxy: {}, 27 | reader: {}, 28 | writer: {}, 29 | widget: {} 30 | }; 31 | }; 32 | 33 | ClassList.prototype.loadFoundation = function(map) { 34 | var me = this; 35 | 36 | Object.keys(map) 37 | .forEach(function(key) { 38 | me.foundation[key] = map[key]; 39 | }); 40 | }; 41 | 42 | ClassList.prototype.loadAlternates = function(map) { 43 | var me = this; 44 | 45 | Object.keys(map) 46 | .forEach(function(key) { 47 | var values = map[key]; 48 | 49 | if (values.length > 0) { 50 | values.forEach(function(alternate) { 51 | me.alternates[alternate] = key; 52 | }); 53 | } 54 | }); 55 | }; 56 | 57 | ClassList.prototype.loadAliases = function(map) { 58 | var me = this; 59 | 60 | Object.keys(map) 61 | .forEach(function(key) { 62 | var values = map[key]; 63 | 64 | if (values.length > 0) { 65 | values.forEach(function(alias) { 66 | var parts = alias.match(aliasRe); 67 | 68 | var aliases = me.aliases[parts[1]]; 69 | 70 | if (aliases) { 71 | aliases[parts[2]] = key; 72 | } 73 | }); 74 | } 75 | }); 76 | }; 77 | 78 | ClassList.prototype.loadScope = function(scope) { 79 | var me = this; 80 | 81 | scope.variables.forEach(function(variable) { 82 | var name = variable.name; 83 | 84 | if (namespaceRe.test(name)) { 85 | me.namespaces[name] = true; 86 | } 87 | }); 88 | }; 89 | 90 | ClassList.prototype.getClassName = function(member) { 91 | var cls = classRe.exec(member); 92 | 93 | if (cls) { 94 | var name = cls[0]; 95 | var namespace = name.split(".")[0]; 96 | 97 | if (this.namespaces[namespace]) { 98 | return name; 99 | } 100 | } 101 | 102 | return null; 103 | }; 104 | 105 | module.exports = { 106 | loadDefaults: function() { 107 | var classes = new ClassList(); 108 | 109 | classes.loadFoundation(foundation); 110 | classes.loadAlternates(alternates); 111 | classes.loadAliases(aliases); 112 | 113 | return classes; 114 | }, 115 | 116 | readBootstrapData: function(data, regex) { 117 | var match = data.match(regex); 118 | 119 | if (match) { 120 | return JSON.parse(match[1]); 121 | } 122 | else { 123 | return null; 124 | } 125 | }, 126 | 127 | loadBootstrap: function(path) { 128 | var classes = this.loadDefaults(); 129 | 130 | var bootstrap = fs.readFileSync(path, 'UTF-8'); 131 | 132 | classes.loadAlternates( 133 | this.readBootstrapData(bootstrap, bootAlternatesRe) 134 | ); 135 | 136 | classes.loadAliases( 137 | this.readBootstrapData(bootstrap, bootAliasRe) 138 | ); 139 | 140 | return classes; 141 | } 142 | }; -------------------------------------------------------------------------------- /lib/conf/aliases.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ext.rtl.layout.container.boxOverflow.Menu": [], 3 | "Ext.dom.AbstractElement_static": [], 4 | "Ext.draw.engine.ImageExporter": [], 5 | "Ext.layout.component.Auto": [ 6 | "layout.autocomponent" 7 | ], 8 | "Ext.grid.property.Store": [], 9 | "Ext.dom.Element_anim": [], 10 | "Ext.layout.container.Box": [ 11 | "layout.box" 12 | ], 13 | "Ext.rtl.resizer.BorderSplitterTracker": [], 14 | "Ext.direct.JsonProvider": [ 15 | "direct.jsonprovider" 16 | ], 17 | "Ext.tree.Panel": [ 18 | "widget.treepanel" 19 | ], 20 | "Ext.data.Model": [], 21 | "Ext.data.reader.Reader": [], 22 | "Ext.tab.Tab": [ 23 | "widget.tab" 24 | ], 25 | "Ext.button.Button": [ 26 | "widget.button" 27 | ], 28 | "Ext.util.Grouper": [], 29 | "Ext.util.TaskRunner": [], 30 | "Ext.direct.RemotingProvider": [ 31 | "direct.remotingprovider" 32 | ], 33 | "Ext.grid.column.Date": [ 34 | "widget.datecolumn" 35 | ], 36 | "Ext.data.NodeInterface": [], 37 | "Ext.view.NodeCache": [], 38 | "Ext.grid.plugin.RowEditing": [ 39 | "plugin.rowediting" 40 | ], 41 | "Ext.form.field.Trigger": [ 42 | "widget.trigger", 43 | "widget.triggerfield" 44 | ], 45 | "Ext.rtl.grid.plugin.HeaderResizer": [], 46 | "Ext.tip.QuickTip": [ 47 | "widget.quicktip" 48 | ], 49 | "Ext.form.action.Load": [ 50 | "formaction.load" 51 | ], 52 | "Ext.form.field.ComboBox": [ 53 | "widget.combo", 54 | "widget.combobox" 55 | ], 56 | "Ext.layout.container.Border": [ 57 | "layout.border" 58 | ], 59 | "Ext.rtl.layout.container.Column": [], 60 | "Ext.data.JsonPStore": [ 61 | "store.jsonp" 62 | ], 63 | "Ext.ux.ajax.Simlet": [ 64 | "simlet.basic" 65 | ], 66 | "Ext.layout.component.field.TextArea": [ 67 | "layout.textareafield" 68 | ], 69 | "Ext.dom.AbstractHelper": [], 70 | "Ext.layout.container.Container": [ 71 | "layout.container" 72 | ], 73 | "Ext.util.Sortable": [], 74 | "Ext.selection.Model": [], 75 | "Ext.draw.CompositeSprite": [], 76 | "Ext.fx.Queue": [], 77 | "Ext.dd.StatusProxy": [], 78 | "Ext.form.field.Checkbox": [ 79 | "widget.checkbox", 80 | "widget.checkboxfield" 81 | ], 82 | "Ext.XTemplateCompiler": [], 83 | "Ext.direct.Transaction": [ 84 | "direct.transaction" 85 | ], 86 | "Ext.util.Offset": [], 87 | "Ext.dom.Element": [], 88 | "Ext.container.Monitor": [], 89 | "Ext.view.DragZone": [], 90 | "Ext.util.KeyNav": [], 91 | "Ext.rtl.dom.Element_static": [], 92 | "Ext.form.field.File": [ 93 | "widget.filefield", 94 | "widget.fileuploadfield" 95 | ], 96 | "Ext.ux.IFrame": [ 97 | "widget.uxiframe" 98 | ], 99 | "Ext.slider.Single": [ 100 | "widget.slider", 101 | "widget.sliderfield" 102 | ], 103 | "Ext.panel.Proxy": [], 104 | "Ext.fx.target.Target": [], 105 | "Ext.ComponentManager": [], 106 | "Ext.dom.AbstractElement_traversal": [], 107 | "Ext.grid.feature.GroupingSummary": [ 108 | "feature.groupingsummary" 109 | ], 110 | "Ext.grid.property.HeaderContainer": [], 111 | "Ext.layout.component.BoundList": [ 112 | "layout.boundlist" 113 | ], 114 | "Ext.tab.Bar": [ 115 | "widget.tabbar" 116 | ], 117 | "Ext.app.Application": [], 118 | "Ext.layout.container.Accordion": [ 119 | "layout.accordion" 120 | ], 121 | "Ext.ShadowPool": [], 122 | "Ext.grid.locking.HeaderContainer": [], 123 | "Ext.resizer.ResizeTracker": [], 124 | "Ext.panel.Tool": [ 125 | "widget.tool" 126 | ], 127 | "Ext.layout.container.boxOverflow.None": [], 128 | "Ext.tree.View": [ 129 | "widget.treeview" 130 | ], 131 | "Ext.grid.CellContext": [], 132 | "Ext.ElementLoader": [], 133 | "Ext.grid.ColumnComponentLayout": [ 134 | "layout.columncomponent" 135 | ], 136 | "Ext.toolbar.Separator": [ 137 | "widget.tbseparator" 138 | ], 139 | "Ext.dd.DragZone": [], 140 | "Ext.layout.component.FieldSet": [ 141 | "layout.fieldset" 142 | ], 143 | "Ext.util.Renderable": [], 144 | "Ext.util.Bindable": [], 145 | "Ext.data.SortTypes": [], 146 | "Ext.rtl.layout.container.HBox": [], 147 | "Ext.ux.FieldReplicator": [], 148 | "Ext.util.Animate": [], 149 | "Ext.data.flash.BinaryXhr": [], 150 | "Ext.form.field.Date": [ 151 | "widget.datefield" 152 | ], 153 | "Ext.ux.dd.PanelFieldDragZone": [], 154 | "Ext.Component": [ 155 | "widget.box", 156 | "widget.component" 157 | ], 158 | "Ext.chart.axis.Axis": [], 159 | "Ext.menu.DatePicker": [ 160 | "widget.datemenu" 161 | ], 162 | "Ext.fx.target.CompositeSprite": [], 163 | "Ext.ux.GroupTabPanel": [ 164 | "widget.grouptabpanel" 165 | ], 166 | "Ext.rtl.tip.QuickTipManager": [], 167 | "Ext.ux.statusbar.ValidationStatus": [], 168 | "Ext.form.field.Picker": [ 169 | "widget.pickerfield" 170 | ], 171 | "Ext.fx.Animator": [], 172 | "Ext.ux.layout.Center": [ 173 | "layout.ux.center" 174 | ], 175 | "Ext.Ajax": [], 176 | "Ext.layout.component.Dock": [ 177 | "layout.dock" 178 | ], 179 | "Ext.util.Filter": [], 180 | "Ext.dd.DragDrop": [], 181 | "Ext.grid.Scroller": [], 182 | "Ext.view.View": [ 183 | "widget.dataview" 184 | ], 185 | "Ext.data.association.BelongsTo": [ 186 | "association.belongsto" 187 | ], 188 | "Ext.fx.target.Element": [], 189 | "Ext.draw.Surface": [], 190 | "Ext.dd.DDProxy": [], 191 | "Ext.grid.plugin.BufferedRendererTreeView": [], 192 | "Ext.data.AbstractStore": [], 193 | "Ext.grid.locking.View": [], 194 | "Ext.form.action.StandardSubmit": [ 195 | "formaction.standardsubmit" 196 | ], 197 | "Ext.diag.layout.Context": [], 198 | "Ext.dd.Registry": [], 199 | "Ext.ux.event.Player": [], 200 | "Ext.picker.Month": [ 201 | "widget.monthpicker" 202 | ], 203 | "Ext.menu.Manager": [], 204 | "Ext.container.Container": [ 205 | "widget.container" 206 | ], 207 | "Ext.rtl.form.field.Spinner": [], 208 | "Ext.util.KeyMap": [], 209 | "Ext.ux.ToolbarDroppable": [], 210 | "Ext.data.Batch": [], 211 | "Ext.resizer.Handle": [], 212 | "Ext.util.ElementContainer": [], 213 | "Ext.grid.feature.Grouping": [ 214 | "feature.grouping" 215 | ], 216 | "Ext.tab.Panel": [ 217 | "widget.tabpanel" 218 | ], 219 | "Ext.rtl.grid.CellEditor": [], 220 | "Ext.ux.TabCloseMenu": [ 221 | "plugin.tabclosemenu" 222 | ], 223 | "Ext.dom.Element_position": [], 224 | "Ext.layout.component.Body": [ 225 | "layout.body" 226 | ], 227 | "Ext.layout.Context": [], 228 | "Ext.ux.grid.filter.DateTimeFilter": [ 229 | "gridfilter.datetime" 230 | ], 231 | "Ext.layout.component.field.ComboBox": [ 232 | "layout.combobox" 233 | ], 234 | "Ext.dd.DDTarget": [], 235 | "Ext.chart.Chart": [ 236 | "widget.chart" 237 | ], 238 | "Ext.ux.grid.FiltersFeature": [ 239 | "feature.filters" 240 | ], 241 | "Ext.data.Field": [ 242 | "data.field" 243 | ], 244 | "Ext.form.field.FileButton": [ 245 | "widget.filebutton" 246 | ], 247 | "Ext.chart.series.Gauge": [ 248 | "series.gauge" 249 | ], 250 | "Ext.data.StoreManager": [], 251 | "Ext.tip.QuickTipManager": [], 252 | "Ext.data.IdGenerator": [], 253 | "Ext.grid.plugin.Editing": [ 254 | "editing.editing" 255 | ], 256 | "Ext.Queryable": [], 257 | "Ext.state.LocalStorageProvider": [ 258 | "state.localstorage" 259 | ], 260 | "Ext.grid.RowEditor": [ 261 | "widget.roweditor" 262 | ], 263 | "Ext.ux.grid.TransformGrid": [], 264 | "Ext.app.EventDomain": [], 265 | "Ext.form.action.Action": [], 266 | "Ext.ProgressBar": [ 267 | "widget.progressbar" 268 | ], 269 | "Ext.fx.Easing": [], 270 | "Ext.tree.ViewDragZone": [], 271 | "Ext.data.reader.Array": [ 272 | "reader.array" 273 | ], 274 | "Ext.picker.Date": [ 275 | "widget.datepicker" 276 | ], 277 | "Ext.ux.event.Driver": [], 278 | "Ext.ux.ajax.XmlSimlet": [ 279 | "simlet.xml" 280 | ], 281 | "Ext.rtl.grid.column.Column": [], 282 | "Ext.data.proxy.JsonP": [ 283 | "proxy.jsonp", 284 | "proxy.scripttag" 285 | ], 286 | "Ext.fx.Anim": [], 287 | "Ext.chart.series.Area": [ 288 | "series.area" 289 | ], 290 | "Ext.menu.Item": [ 291 | "widget.menuitem" 292 | ], 293 | "Ext.util.TaskManager": [], 294 | "Ext.rtl.dom.Element_position": [], 295 | "Ext.chart.Legend": [], 296 | "Ext.ux.form.MultiSelect": [ 297 | "widget.multiselect", 298 | "widget.multiselectfield" 299 | ], 300 | "Ext.grid.plugin.HeaderReorderer": [ 301 | "plugin.gridheaderreorderer" 302 | ], 303 | "Ext.rtl.view.Table": [], 304 | "Ext.layout.container.VBox": [ 305 | "layout.vbox" 306 | ], 307 | "Ext.rtl.util.Floating": [], 308 | "Ext.view.DropZone": [], 309 | "Ext.rtl.tree.Column": [], 310 | "Ext.layout.component.Button": [ 311 | "layout.button" 312 | ], 313 | "Ext.form.field.Hidden": [ 314 | "widget.hidden", 315 | "widget.hiddenfield" 316 | ], 317 | "Ext.rtl.grid.plugin.RowEditing": [], 318 | "Ext.form.FieldContainer": [ 319 | "widget.fieldcontainer" 320 | ], 321 | "Ext.ux.event.RecorderManager": [ 322 | "widget.eventrecordermanager" 323 | ], 324 | "Ext.chart.series.Cartesian": [], 325 | "Ext.data.proxy.Server": [ 326 | "proxy.server" 327 | ], 328 | "Ext.grid.column.Column": [ 329 | "widget.gridcolumn" 330 | ], 331 | "Ext.rtl.layout.component.Dock": [], 332 | "Ext.data.ResultSet": [], 333 | "Ext.data.association.HasMany": [ 334 | "association.hasmany" 335 | ], 336 | "Ext.layout.container.Fit": [ 337 | "layout.fit" 338 | ], 339 | "Ext.util.CSS": [], 340 | "Ext.rtl.AbstractComponent": [], 341 | "Ext.layout.component.field.Field": [ 342 | "layout.field" 343 | ], 344 | "Ext.data.proxy.Ajax": [ 345 | "proxy.ajax" 346 | ], 347 | "Ext.app.domain.Component": [], 348 | "Ext.rtl.EventObjectImpl": [], 349 | "Ext.form.Label": [ 350 | "widget.label" 351 | ], 352 | "Ext.data.writer.Writer": [ 353 | "writer.base" 354 | ], 355 | "Ext.view.BoundListKeyNav": [], 356 | "Ext.form.FieldSet": [ 357 | "widget.fieldset" 358 | ], 359 | "Ext.XTemplateParser": [], 360 | "Ext.form.field.VTypes": [], 361 | "Ext.fx.PropertyHandler": [], 362 | "Ext.form.CheckboxGroup": [ 363 | "widget.checkboxgroup" 364 | ], 365 | "Ext.data.JsonP": [], 366 | "Ext.draw.engine.Vml": [], 367 | "Ext.layout.container.CheckboxGroup": [ 368 | "layout.checkboxgroup" 369 | ], 370 | "Ext.app.domain.Direct": [], 371 | "Ext.panel.Header": [ 372 | "widget.header" 373 | ], 374 | "Ext.ux.TabScrollerMenu": [ 375 | "plugin.tabscrollermenu" 376 | ], 377 | "Ext.grid.plugin.CellEditing": [ 378 | "plugin.cellediting" 379 | ], 380 | "Ext.app.Controller": [], 381 | "Ext.rtl.dom.Layer": [], 382 | "Ext.form.field.Time": [ 383 | "widget.timefield" 384 | ], 385 | "Ext.fx.CubicBezier": [], 386 | "Ext.ux.LiveSearchGridPanel": [], 387 | "Ext.button.Cycle": [ 388 | "widget.cycle" 389 | ], 390 | "Ext.app.domain.Global": [], 391 | "Ext.ux.grid.filter.DateFilter": [ 392 | "gridfilter.date" 393 | ], 394 | "Ext.data.Tree": [ 395 | "data.tree" 396 | ], 397 | "Ext.ModelManager": [], 398 | "Ext.data.XmlStore": [ 399 | "store.xml" 400 | ], 401 | "Ext.grid.ViewDropZone": [], 402 | "Ext.ux.BoxReorderer": [], 403 | "Ext.rtl.slider.Multi": [], 404 | "Ext.grid.header.DropZone": [], 405 | "Ext.rtl.layout.component.field.Text": [], 406 | "Ext.util.HashMap": [], 407 | "Ext.grid.column.Template": [ 408 | "widget.templatecolumn" 409 | ], 410 | "Ext.EventObjectImpl": [], 411 | "Ext.ComponentLoader": [], 412 | "Ext.form.FieldAncestor": [], 413 | "Ext.rtl.layout.container.Border": [], 414 | "Ext.app.domain.Controller": [], 415 | "Ext.chart.axis.Gauge": [ 416 | "axis.gauge" 417 | ], 418 | "Ext.layout.container.border.Region": [], 419 | "Ext.data.validations": [], 420 | "Ext.data.Connection": [], 421 | "Ext.resizer.Splitter": [ 422 | "widget.splitter" 423 | ], 424 | "Ext.dd.DropZone": [], 425 | "Ext.direct.ExceptionEvent": [ 426 | "direct.exception" 427 | ], 428 | "Ext.form.RadioManager": [], 429 | "Ext.data.association.HasOne": [ 430 | "association.hasone" 431 | ], 432 | "Ext.draw.Text": [ 433 | "widget.text" 434 | ], 435 | "Ext.window.MessageBox": [ 436 | "widget.messagebox" 437 | ], 438 | "Ext.fx.target.CompositeElementCSS": [], 439 | "Ext.diag.layout.ContextItem": [], 440 | "Ext.ux.grid.filter.StringFilter": [ 441 | "gridfilter.string" 442 | ], 443 | "Ext.rtl.selection.CellModel": [], 444 | "Ext.rtl.layout.ContextItem": [], 445 | "Ext.chart.series.Line": [ 446 | "series.line" 447 | ], 448 | "Ext.view.Table": [ 449 | "widget.tableview" 450 | ], 451 | "Ext.data.writer.Json": [ 452 | "writer.json" 453 | ], 454 | "Ext.fx.target.CompositeElement": [], 455 | "Ext.fx.Manager": [], 456 | "Ext.chart.Label": [], 457 | "Ext.grid.View": [ 458 | "widget.gridview" 459 | ], 460 | "Ext.Action": [], 461 | "Ext.form.Basic": [], 462 | "Ext.rtl.form.field.Checkbox": [], 463 | "Ext.container.Viewport": [ 464 | "widget.viewport" 465 | ], 466 | "Ext.state.Stateful": [], 467 | "Ext.ux.grid.menu.RangeMenu": [], 468 | "Ext.grid.feature.RowBody": [ 469 | "feature.rowbody" 470 | ], 471 | "Ext.form.field.Text": [ 472 | "widget.textfield" 473 | ], 474 | "Ext.rtl.layout.component.field.Trigger": [], 475 | "Ext.data.reader.Xml": [ 476 | "reader.xml" 477 | ], 478 | "Ext.grid.feature.AbstractSummary": [ 479 | "feature.abstractsummary" 480 | ], 481 | "Ext.rtl.layout.container.boxOverflow.Scroller": [], 482 | "Ext.chart.axis.Category": [ 483 | "axis.category" 484 | ], 485 | "Ext.grid.plugin.BufferedRendererTableView": [], 486 | "Ext.layout.container.Absolute": [ 487 | "layout.absolute" 488 | ], 489 | "Ext.rtl.layout.container.Box": [], 490 | "Ext.data.reader.Json": [ 491 | "reader.json" 492 | ], 493 | "Ext.util.TextMetrics": [], 494 | "Ext.data.TreeStore": [ 495 | "store.tree" 496 | ], 497 | "Ext.view.BoundList": [ 498 | "widget.boundlist" 499 | ], 500 | "Ext.form.field.HtmlEditor": [ 501 | "widget.htmleditor" 502 | ], 503 | "Ext.layout.container.Form": [ 504 | "layout.form" 505 | ], 506 | "Ext.chart.MaskLayer": [], 507 | "Ext.util.Observable": [], 508 | "Ext.ux.DataTip": [ 509 | "plugin.datatip" 510 | ], 511 | "Ext.ux.ajax.JsonSimlet": [ 512 | "simlet.json" 513 | ], 514 | "Ext.resizer.BorderSplitterTracker": [], 515 | "Ext.util.LruCache": [], 516 | "Ext.tip.Tip": [], 517 | "Ext.dom.CompositeElement": [], 518 | "Ext.grid.column.RowNumberer": [ 519 | "widget.rownumberer" 520 | ], 521 | "Ext.grid.column.CheckColumn": [ 522 | "widget.checkcolumn" 523 | ], 524 | "Ext.rtl.resizer.SplitterTracker": [], 525 | "Ext.grid.feature.RowWrap": [ 526 | "feature.rowwrap" 527 | ], 528 | "Ext.data.proxy.Client": [], 529 | "Ext.data.Types": [], 530 | "Ext.draw.SpriteDD": [], 531 | "Ext.layout.container.boxOverflow.Menu": [], 532 | "Ext.LoadMask": [ 533 | "widget.loadmask" 534 | ], 535 | "Ext.rtl.grid.RowEditor": [], 536 | "Ext.toolbar.Paging": [ 537 | "widget.pagingtoolbar" 538 | ], 539 | "Ext.data.association.Association": [], 540 | "Ext.tree.ViewDropZone": [], 541 | "Ext.toolbar.Toolbar": [ 542 | "widget.toolbar" 543 | ], 544 | "Ext.tip.ToolTip": [ 545 | "widget.tooltip" 546 | ], 547 | "Ext.ux.DataView.DragSelector": [], 548 | "Ext.chart.Highlight": [], 549 | "Ext.state.Manager": [], 550 | "Ext.ux.grid.menu.ListMenu": [], 551 | "Ext.util.Inflector": [], 552 | "Ext.grid.Panel": [ 553 | "widget.grid", 554 | "widget.gridpanel" 555 | ], 556 | "Ext.XTemplate": [], 557 | "Ext.data.NodeStore": [ 558 | "store.node" 559 | ], 560 | "Ext.Shadow": [], 561 | "Ext.form.action.Submit": [ 562 | "formaction.submit" 563 | ], 564 | "Ext.form.Panel": [ 565 | "widget.form" 566 | ], 567 | "Ext.chart.series.Series": [], 568 | "Ext.perf.Accumulator": [], 569 | "Ext.ux.PreviewPlugin": [ 570 | "plugin.preview" 571 | ], 572 | "Ext.data.Request": [], 573 | "Ext.ux.ajax.SimXhr": [], 574 | "Ext.dd.DD": [], 575 | "Ext.dom.CompositeElementLite": [], 576 | "Ext.ux.CellDragDrop": [ 577 | "plugin.celldragdrop" 578 | ], 579 | "Ext.toolbar.Fill": [ 580 | "widget.tbfill" 581 | ], 582 | "Ext.ux.SlidingPager": [], 583 | "Ext.data.proxy.WebStorage": [], 584 | "Ext.util.Floating": [], 585 | "Ext.ux.TabReorderer": [], 586 | "Ext.form.action.DirectSubmit": [ 587 | "formaction.directsubmit" 588 | ], 589 | "Ext.ux.grid.filter.NumericFilter": [ 590 | "gridfilter.numeric" 591 | ], 592 | "Ext.util.Cookies": [], 593 | "Ext.data.UuidGenerator": [ 594 | "idgen.uuid" 595 | ], 596 | "Ext.util.Point": [], 597 | "Ext.fx.target.Component": [], 598 | "Ext.form.CheckboxManager": [], 599 | "Ext.ux.event.Recorder": [], 600 | "Ext.form.field.Field": [], 601 | "Ext.form.field.Display": [ 602 | "widget.displayfield" 603 | ], 604 | "Ext.layout.container.Anchor": [ 605 | "layout.anchor" 606 | ], 607 | "Ext.layout.component.field.Text": [ 608 | "layout.textfield" 609 | ], 610 | "Ext.data.DirectStore": [ 611 | "store.direct" 612 | ], 613 | "Ext.ux.grid.filter.BooleanFilter": [ 614 | "gridfilter.boolean" 615 | ], 616 | "Ext.dom.Layer": [], 617 | "Ext.grid.RowEditorButtons": [ 618 | "widget.roweditorbuttons" 619 | ], 620 | "Ext.data.BufferStore": [ 621 | "store.buffer" 622 | ], 623 | "Ext.ux.form.SearchField": [ 624 | "widget.searchfield" 625 | ], 626 | "Ext.ux.dd.CellFieldDropZone": [], 627 | "Ext.grid.plugin.DivRenderer": [ 628 | "plugin.divrenderer" 629 | ], 630 | "Ext.grid.ColumnLayout": [ 631 | "layout.gridcolumn" 632 | ], 633 | "Ext.dom.AbstractElement_style": [], 634 | "Ext.Template": [], 635 | "Ext.AbstractComponent": [], 636 | "Ext.chart.series.Column": [ 637 | "series.column" 638 | ], 639 | "Ext.flash.Component": [ 640 | "widget.flash" 641 | ], 642 | "Ext.form.field.Base": [ 643 | "widget.field" 644 | ], 645 | "Ext.dom.AbstractElement_insertion": [], 646 | "Ext.grid.feature.GroupStore": [], 647 | "Ext.data.SequentialIdGenerator": [ 648 | "idgen.sequential" 649 | ], 650 | "Ext.grid.header.Container": [ 651 | "widget.headercontainer" 652 | ], 653 | "Ext.container.ButtonGroup": [ 654 | "widget.buttongroup" 655 | ], 656 | "Ext.data.PageMap": [], 657 | "Ext.grid.column.Action": [ 658 | "widget.actioncolumn" 659 | ], 660 | "Ext.layout.component.field.Trigger": [ 661 | "layout.triggerfield" 662 | ], 663 | "Ext.layout.component.field.FieldContainer": [ 664 | "layout.fieldcontainer" 665 | ], 666 | "Ext.chart.Shape": [], 667 | "Ext.panel.DD": [], 668 | "Ext.container.AbstractContainer": [], 669 | "Ext.ux.grid.filter.ListFilter": [ 670 | "gridfilter.list" 671 | ], 672 | "Ext.data.ArrayStore": [ 673 | "store.array" 674 | ], 675 | "Ext.rtl.layout.container.CheckboxGroup": [], 676 | "Ext.window.Window": [ 677 | "widget.window" 678 | ], 679 | "Ext.grid.feature.Feature": [ 680 | "feature.feature" 681 | ], 682 | "Ext.picker.Color": [ 683 | "widget.colorpicker" 684 | ], 685 | "Ext.ux.GMapPanel": [ 686 | "widget.gmappanel" 687 | ], 688 | "Ext.chart.theme.Theme": [], 689 | "Ext.util.ClickRepeater": [], 690 | "Ext.form.field.Spinner": [ 691 | "widget.spinnerfield" 692 | ], 693 | "Ext.container.DockingContainer": [], 694 | "Ext.selection.DataViewModel": [], 695 | "Ext.ux.DataView.Animated": [], 696 | "Ext.rtl.selection.TreeModel": [], 697 | "Ext.dd.DragTracker": [], 698 | "Ext.data.Group": [], 699 | "Ext.dd.DragDropManager": [], 700 | "Ext.selection.CheckboxModel": [ 701 | "selection.checkboxmodel" 702 | ], 703 | "Ext.menu.KeyNav": [], 704 | "Ext.layout.container.Column": [ 705 | "layout.column" 706 | ], 707 | "Ext.draw.Matrix": [], 708 | "Ext.form.field.Number": [ 709 | "widget.numberfield" 710 | ], 711 | "Ext.rtl.util.Renderable": [], 712 | "Ext.ux.statusbar.StatusBar": [ 713 | "widget.statusbar" 714 | ], 715 | "Ext.data.proxy.Direct": [ 716 | "proxy.direct" 717 | ], 718 | "Ext.chart.Navigation": [], 719 | "Ext.slider.Tip": [ 720 | "widget.slidertip" 721 | ], 722 | "Ext.chart.theme.Base": [], 723 | "Ext.form.field.TextArea": [ 724 | "widget.textarea", 725 | "widget.textareafield" 726 | ], 727 | "Ext.rtl.layout.container.VBox": [], 728 | "Ext.util.Positionable": [], 729 | "Ext.form.field.Radio": [ 730 | "widget.radio", 731 | "widget.radiofield" 732 | ], 733 | "Ext.layout.component.ProgressBar": [ 734 | "layout.progressbar" 735 | ], 736 | "Ext.chart.series.Pie": [ 737 | "series.pie" 738 | ], 739 | "Ext.tree.plugin.TreeViewDragDrop": [ 740 | "plugin.treeviewdragdrop" 741 | ], 742 | "Ext.direct.Provider": [ 743 | "direct.provider" 744 | ], 745 | "Ext.data.TreeModel": [], 746 | "Ext.layout.Layout": [], 747 | "Ext.toolbar.TextItem": [ 748 | "widget.tbtext" 749 | ], 750 | "Ext.ux.DataView.Draggable": [], 751 | "Ext.dom.Helper": [], 752 | "Ext.rtl.button.Button": [], 753 | "Ext.util.AbstractMixedCollection": [], 754 | "Ext.data.JsonStore": [ 755 | "store.json" 756 | ], 757 | "Ext.button.Split": [ 758 | "widget.splitbutton" 759 | ], 760 | "Ext.dd.DropTarget": [], 761 | "Ext.direct.RemotingEvent": [ 762 | "direct.rpc" 763 | ], 764 | "Ext.ux.form.ItemSelector": [ 765 | "widget.itemselector", 766 | "widget.itemselectorfield" 767 | ], 768 | "Ext.draw.Sprite": [], 769 | "Ext.ux.Spotlight": [], 770 | "Ext.fx.target.Sprite": [], 771 | "Ext.data.proxy.LocalStorage": [ 772 | "proxy.localstorage" 773 | ], 774 | "Ext.layout.component.Draw": [ 775 | "layout.draw" 776 | ], 777 | "Ext.AbstractPlugin": [], 778 | "Ext.Editor": [ 779 | "widget.editor" 780 | ], 781 | "Ext.chart.Tip": [], 782 | "Ext.chart.axis.Radial": [ 783 | "axis.radial" 784 | ], 785 | "Ext.ux.ajax.DataSimlet": [], 786 | "Ext.layout.container.Table": [ 787 | "layout.table" 788 | ], 789 | "Ext.chart.axis.Abstract": [], 790 | "Ext.data.proxy.Rest": [ 791 | "proxy.rest" 792 | ], 793 | "Ext.rtl.layout.container.Absolute": [], 794 | "Ext.util.Queue": [], 795 | "Ext.state.CookieProvider": [], 796 | "Ext.Img": [ 797 | "widget.image", 798 | "widget.imagecomponent" 799 | ], 800 | "Ext.dd.DragSource": [], 801 | "Ext.grid.CellEditor": [], 802 | "Ext.layout.ClassList": [], 803 | "Ext.button.Manager": [], 804 | "Ext.rtl.form.field.File": [], 805 | "Ext.util.Sorter": [], 806 | "Ext.resizer.SplitterTracker": [], 807 | "Ext.panel.Table": [ 808 | "widget.tablepanel" 809 | ], 810 | "Ext.dom.Element_scroll": [], 811 | "Ext.draw.Color": [], 812 | "Ext.chart.series.Bar": [ 813 | "series.bar" 814 | ], 815 | "Ext.PluginManager": [], 816 | "Ext.util.ComponentDragger": [], 817 | "Ext.chart.Callout": [], 818 | "Ext.chart.series.Scatter": [ 819 | "series.scatter" 820 | ], 821 | "Ext.data.Store": [ 822 | "store.store" 823 | ], 824 | "Ext.grid.feature.Summary": [ 825 | "feature.summary" 826 | ], 827 | "Ext.util.ProtoElement": [], 828 | "Ext.layout.component.Component": [], 829 | "Ext.direct.Manager": [], 830 | "Ext.data.proxy.Proxy": [ 831 | "proxy.proxy" 832 | ], 833 | "Ext.menu.CheckItem": [ 834 | "widget.menucheckitem" 835 | ], 836 | "Ext.ux.ProgressBarPager": [], 837 | "Ext.dom.Element_fx": [], 838 | "Ext.dom.AbstractElement": [], 839 | "Ext.layout.container.Card": [ 840 | "layout.card" 841 | ], 842 | "Ext.draw.Component": [ 843 | "widget.draw" 844 | ], 845 | "Ext.toolbar.Item": [ 846 | "widget.tbitem" 847 | ], 848 | "Ext.form.RadioGroup": [ 849 | "widget.radiogroup" 850 | ], 851 | "Ext.rtl.tab.Bar": [], 852 | "Ext.rtl.form.field.Trigger": [], 853 | "Ext.slider.Thumb": [], 854 | "Ext.grid.header.DragZone": [], 855 | "Ext.rtl.resizer.ResizeTracker": [], 856 | "Ext.form.action.DirectLoad": [ 857 | "formaction.directload" 858 | ], 859 | "Ext.picker.Time": [ 860 | "widget.timepicker" 861 | ], 862 | "Ext.grid.plugin.BufferedRenderer": [ 863 | "plugin.bufferedrenderer" 864 | ], 865 | "Ext.resizer.BorderSplitter": [ 866 | "widget.bordersplitter" 867 | ], 868 | "Ext.menu.ColorPicker": [ 869 | "widget.colormenu" 870 | ], 871 | "Ext.ZIndexManager": [], 872 | "Ext.ux.ajax.SimManager": [], 873 | "Ext.menu.Menu": [ 874 | "widget.menu" 875 | ], 876 | "Ext.chart.LegendItem": [], 877 | "Ext.toolbar.Spacer": [ 878 | "widget.tbspacer" 879 | ], 880 | "Ext.rtl.dd.DD": [], 881 | "Ext.panel.Panel": [ 882 | "widget.panel" 883 | ], 884 | "Ext.util.Memento": [], 885 | "Ext.app.domain.Store": [], 886 | "Ext.data.proxy.Memory": [ 887 | "proxy.memory" 888 | ], 889 | "Ext.grid.plugin.DragDrop": [ 890 | "plugin.gridviewdragdrop" 891 | ], 892 | "Ext.chart.axis.Time": [ 893 | "axis.time" 894 | ], 895 | "Ext.ComponentQuery": [], 896 | "Ext.dom.Element_style": [], 897 | "Ext.draw.engine.SvgExporter": [], 898 | "Ext.layout.container.Auto": [ 899 | "layout.auto", 900 | "layout.autocontainer" 901 | ], 902 | "Ext.grid.locking.Lockable": [], 903 | "Ext.ux.TreePicker": [ 904 | "widget.treepicker" 905 | ], 906 | "Ext.view.AbstractView": [], 907 | "Ext.util.Region": [], 908 | "Ext.fx.target.ElementCSS": [], 909 | "Ext.draw.Draw": [], 910 | "Ext.util.Event": [], 911 | "Ext.ux.data.PagingMemoryProxy": [ 912 | "proxy.pagingmemory" 913 | ], 914 | "Ext.rtl.panel.Panel": [], 915 | "Ext.ux.grid.filter.Filter": [], 916 | "Ext.layout.component.field.HtmlEditor": [ 917 | "layout.htmleditor" 918 | ], 919 | "Ext.ux.GroupTabRenderer": [ 920 | "plugin.grouptabrenderer" 921 | ], 922 | "Ext.dom.Element_dd": [], 923 | "Ext.data.proxy.SessionStorage": [ 924 | "proxy.sessionstorage" 925 | ], 926 | "Ext.app.EventBus": [], 927 | "Ext.menu.Separator": [ 928 | "widget.menuseparator" 929 | ], 930 | "Ext.util.History": [], 931 | "Ext.direct.Event": [ 932 | "direct.event" 933 | ], 934 | "Ext.direct.RemotingMethod": [], 935 | "Ext.dd.ScrollManager": [], 936 | "Ext.chart.Mask": [], 937 | "Ext.rtl.dom.Element_anim": [], 938 | "Ext.selection.CellModel": [ 939 | "selection.cellmodel" 940 | ], 941 | "Ext.view.TableLayout": [ 942 | "layout.tableview" 943 | ], 944 | "Ext.rtl.panel.Header": [], 945 | "Ext.rtl.dom.Element_scroll": [], 946 | "Ext.state.Provider": [], 947 | "Ext.ux.DataView.LabelEditor": [], 948 | "Ext.layout.container.Editor": [ 949 | "layout.editor" 950 | ], 951 | "Ext.grid.ColumnManager": [], 952 | "Ext.data.Errors": [], 953 | "Ext.dom.AbstractQuery": [], 954 | "Ext.grid.plugin.RowExpander": [ 955 | "plugin.rowexpander" 956 | ], 957 | "Ext.selection.TreeModel": [ 958 | "selection.treemodel" 959 | ], 960 | "Ext.form.Labelable": [], 961 | "Ext.grid.column.Number": [ 962 | "widget.numbercolumn" 963 | ], 964 | "Ext.grid.property.Grid": [ 965 | "widget.propertygrid" 966 | ], 967 | "Ext.draw.engine.Svg": [], 968 | "Ext.FocusManager": [], 969 | "Ext.AbstractManager": [], 970 | "Ext.chart.series.Radar": [ 971 | "series.radar" 972 | ], 973 | "Ext.rtl.dom.Element_insertion": [], 974 | "Ext.ux.RowExpander": [], 975 | "Ext.grid.property.Property": [], 976 | "Ext.chart.TipSurface": [], 977 | "Ext.grid.column.Boolean": [ 978 | "widget.booleancolumn" 979 | ], 980 | "Ext.layout.SizeModel": [], 981 | "Ext.direct.PollingProvider": [ 982 | "direct.pollingprovider" 983 | ], 984 | "Ext.grid.plugin.HeaderResizer": [ 985 | "plugin.gridheaderresizer" 986 | ], 987 | "Ext.tree.Column": [ 988 | "widget.treecolumn" 989 | ], 990 | "Ext.data.writer.Xml": [ 991 | "writer.xml" 992 | ], 993 | "Ext.slider.Multi": [ 994 | "widget.multislider" 995 | ], 996 | "Ext.panel.AbstractPanel": [], 997 | "Ext.ux.event.Maker": [], 998 | "Ext.layout.component.field.Slider": [ 999 | "layout.sliderfield" 1000 | ], 1001 | "Ext.chart.axis.Numeric": [ 1002 | "axis.numeric" 1003 | ], 1004 | "Ext.layout.container.boxOverflow.Scroller": [], 1005 | "Ext.data.Operation": [], 1006 | "Ext.resizer.Resizer": [], 1007 | "Ext.layout.container.HBox": [ 1008 | "layout.hbox" 1009 | ], 1010 | "Ext.selection.RowModel": [ 1011 | "selection.rowmodel" 1012 | ], 1013 | "Ext.layout.ContextItem": [], 1014 | "Ext.util.MixedCollection": [], 1015 | "Ext.perf.Monitor": [] 1016 | } 1017 | -------------------------------------------------------------------------------- /lib/conf/alternates.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ext.rtl.layout.container.boxOverflow.Menu": [], 3 | "Ext.dom.AbstractElement_static": [], 4 | "Ext.draw.engine.ImageExporter": [], 5 | "Ext.layout.component.Auto": [], 6 | "Ext.grid.property.Store": [ 7 | "Ext.grid.PropertyStore" 8 | ], 9 | "Ext.dom.Element_anim": [], 10 | "Ext.layout.container.Box": [ 11 | "Ext.layout.BoxLayout" 12 | ], 13 | "Ext.rtl.resizer.BorderSplitterTracker": [], 14 | "Ext.direct.JsonProvider": [], 15 | "Ext.tree.Panel": [ 16 | "Ext.tree.TreePanel", 17 | "Ext.TreePanel" 18 | ], 19 | "Ext.data.Model": [ 20 | "Ext.data.Record" 21 | ], 22 | "Ext.data.reader.Reader": [ 23 | "Ext.data.Reader", 24 | "Ext.data.DataReader" 25 | ], 26 | "Ext.tab.Tab": [], 27 | "Ext.button.Button": [ 28 | "Ext.Button" 29 | ], 30 | "Ext.util.Grouper": [], 31 | "Ext.util.TaskRunner": [], 32 | "Ext.direct.RemotingProvider": [], 33 | "Ext.grid.column.Date": [ 34 | "Ext.grid.DateColumn" 35 | ], 36 | "Ext.data.NodeInterface": [], 37 | "Ext.view.NodeCache": [], 38 | "Ext.grid.plugin.RowEditing": [], 39 | "Ext.form.field.Trigger": [ 40 | "Ext.form.TriggerField", 41 | "Ext.form.TwinTriggerField", 42 | "Ext.form.Trigger" 43 | ], 44 | "Ext.rtl.grid.plugin.HeaderResizer": [], 45 | "Ext.tip.QuickTip": [ 46 | "Ext.QuickTip" 47 | ], 48 | "Ext.form.action.Load": [ 49 | "Ext.form.Action.Load" 50 | ], 51 | "Ext.form.field.ComboBox": [ 52 | "Ext.form.ComboBox" 53 | ], 54 | "Ext.layout.container.Border": [ 55 | "Ext.layout.BorderLayout" 56 | ], 57 | "Ext.rtl.layout.container.Column": [], 58 | "Ext.data.JsonPStore": [], 59 | "Ext.ux.ajax.Simlet": [], 60 | "Ext.layout.component.field.TextArea": [], 61 | "Ext.dom.AbstractHelper": [], 62 | "Ext.layout.container.Container": [ 63 | "Ext.layout.ContainerLayout" 64 | ], 65 | "Ext.util.Sortable": [], 66 | "Ext.selection.Model": [ 67 | "Ext.AbstractSelectionModel" 68 | ], 69 | "Ext.draw.CompositeSprite": [], 70 | "Ext.fx.Queue": [], 71 | "Ext.dd.StatusProxy": [], 72 | "Ext.form.field.Checkbox": [ 73 | "Ext.form.Checkbox" 74 | ], 75 | "Ext.XTemplateCompiler": [], 76 | "Ext.direct.Transaction": [ 77 | "Ext.Direct.Transaction" 78 | ], 79 | "Ext.util.Offset": [], 80 | "Ext.dom.Element": [ 81 | "Ext.Element", 82 | "Ext.core.Element" 83 | ], 84 | "Ext.container.Monitor": [], 85 | "Ext.view.DragZone": [], 86 | "Ext.util.KeyNav": [ 87 | "Ext.KeyNav" 88 | ], 89 | "Ext.rtl.dom.Element_static": [], 90 | "Ext.form.field.File": [ 91 | "Ext.form.FileUploadField", 92 | "Ext.ux.form.FileUploadField", 93 | "Ext.form.File" 94 | ], 95 | "Ext.ux.IFrame": [], 96 | "Ext.slider.Single": [ 97 | "Ext.Slider", 98 | "Ext.form.SliderField", 99 | "Ext.slider.SingleSlider", 100 | "Ext.slider.Slider" 101 | ], 102 | "Ext.panel.Proxy": [ 103 | "Ext.dd.PanelProxy" 104 | ], 105 | "Ext.fx.target.Target": [], 106 | "Ext.ComponentManager": [ 107 | "Ext.ComponentMgr" 108 | ], 109 | "Ext.dom.AbstractElement_traversal": [], 110 | "Ext.grid.feature.GroupingSummary": [], 111 | "Ext.grid.property.HeaderContainer": [ 112 | "Ext.grid.PropertyColumnModel" 113 | ], 114 | "Ext.layout.component.BoundList": [], 115 | "Ext.tab.Bar": [], 116 | "Ext.app.Application": [], 117 | "Ext.layout.container.Accordion": [ 118 | "Ext.layout.AccordionLayout" 119 | ], 120 | "Ext.ShadowPool": [], 121 | "Ext.grid.locking.HeaderContainer": [], 122 | "Ext.resizer.ResizeTracker": [], 123 | "Ext.panel.Tool": [], 124 | "Ext.layout.container.boxOverflow.None": [ 125 | "Ext.layout.boxOverflow.None" 126 | ], 127 | "Ext.tree.View": [], 128 | "Ext.grid.CellContext": [], 129 | "Ext.ElementLoader": [], 130 | "Ext.grid.ColumnComponentLayout": [], 131 | "Ext.toolbar.Separator": [ 132 | "Ext.Toolbar.Separator" 133 | ], 134 | "Ext.dd.DragZone": [], 135 | "Ext.layout.component.FieldSet": [], 136 | "Ext.util.Renderable": [], 137 | "Ext.util.Bindable": [], 138 | "Ext.data.SortTypes": [], 139 | "Ext.rtl.layout.container.HBox": [], 140 | "Ext.ux.FieldReplicator": [], 141 | "Ext.util.Animate": [], 142 | "Ext.data.flash.BinaryXhr": [], 143 | "Ext.form.field.Date": [ 144 | "Ext.form.DateField", 145 | "Ext.form.Date" 146 | ], 147 | "Ext.ux.dd.PanelFieldDragZone": [], 148 | "Ext.Component": [], 149 | "Ext.chart.axis.Axis": [ 150 | "Ext.chart.Axis" 151 | ], 152 | "Ext.menu.DatePicker": [], 153 | "Ext.fx.target.CompositeSprite": [], 154 | "Ext.ux.GroupTabPanel": [], 155 | "Ext.rtl.tip.QuickTipManager": [], 156 | "Ext.ux.statusbar.ValidationStatus": [], 157 | "Ext.form.field.Picker": [ 158 | "Ext.form.Picker" 159 | ], 160 | "Ext.fx.Animator": [], 161 | "Ext.ux.layout.Center": [], 162 | "Ext.Ajax": [], 163 | "Ext.layout.component.Dock": [ 164 | "Ext.layout.component.AbstractDock" 165 | ], 166 | "Ext.util.Filter": [], 167 | "Ext.dd.DragDrop": [], 168 | "Ext.grid.Scroller": [], 169 | "Ext.view.View": [ 170 | "Ext.DataView" 171 | ], 172 | "Ext.data.association.BelongsTo": [ 173 | "Ext.data.BelongsToAssociation" 174 | ], 175 | "Ext.fx.target.Element": [], 176 | "Ext.draw.Surface": [], 177 | "Ext.dd.DDProxy": [], 178 | "Ext.grid.plugin.BufferedRendererTreeView": [], 179 | "Ext.data.AbstractStore": [], 180 | "Ext.grid.locking.View": [ 181 | "Ext.grid.LockingView" 182 | ], 183 | "Ext.form.action.StandardSubmit": [], 184 | "Ext.diag.layout.Context": [], 185 | "Ext.dd.Registry": [], 186 | "Ext.ux.event.Player": [], 187 | "Ext.picker.Month": [ 188 | "Ext.MonthPicker" 189 | ], 190 | "Ext.menu.Manager": [ 191 | "Ext.menu.MenuMgr" 192 | ], 193 | "Ext.container.Container": [ 194 | "Ext.Container" 195 | ], 196 | "Ext.rtl.form.field.Spinner": [], 197 | "Ext.util.KeyMap": [ 198 | "Ext.KeyMap" 199 | ], 200 | "Ext.ux.ToolbarDroppable": [], 201 | "Ext.data.Batch": [], 202 | "Ext.resizer.Handle": [], 203 | "Ext.util.ElementContainer": [], 204 | "Ext.grid.feature.Grouping": [], 205 | "Ext.tab.Panel": [ 206 | "Ext.TabPanel" 207 | ], 208 | "Ext.rtl.grid.CellEditor": [], 209 | "Ext.ux.TabCloseMenu": [], 210 | "Ext.dom.Element_position": [], 211 | "Ext.layout.component.Body": [], 212 | "Ext.layout.Context": [], 213 | "Ext.ux.grid.filter.DateTimeFilter": [], 214 | "Ext.layout.component.field.ComboBox": [], 215 | "Ext.dd.DDTarget": [], 216 | "Ext.chart.Chart": [], 217 | "Ext.ux.grid.FiltersFeature": [], 218 | "Ext.data.Field": [], 219 | "Ext.form.field.FileButton": [], 220 | "Ext.chart.series.Gauge": [], 221 | "Ext.data.StoreManager": [ 222 | "Ext.StoreMgr", 223 | "Ext.data.StoreMgr", 224 | "Ext.StoreManager" 225 | ], 226 | "Ext.tip.QuickTipManager": [ 227 | "Ext.QuickTips" 228 | ], 229 | "Ext.data.IdGenerator": [], 230 | "Ext.grid.plugin.Editing": [], 231 | "Ext.Queryable": [], 232 | "Ext.state.LocalStorageProvider": [], 233 | "Ext.grid.RowEditor": [], 234 | "Ext.ux.grid.TransformGrid": [], 235 | "Ext.app.EventDomain": [], 236 | "Ext.form.action.Action": [ 237 | "Ext.form.Action" 238 | ], 239 | "Ext.ProgressBar": [], 240 | "Ext.fx.Easing": [], 241 | "Ext.tree.ViewDragZone": [], 242 | "Ext.data.reader.Array": [ 243 | "Ext.data.ArrayReader" 244 | ], 245 | "Ext.picker.Date": [ 246 | "Ext.DatePicker" 247 | ], 248 | "Ext.ux.event.Driver": [], 249 | "Ext.ux.ajax.XmlSimlet": [], 250 | "Ext.rtl.grid.column.Column": [], 251 | "Ext.data.proxy.JsonP": [ 252 | "Ext.data.ScriptTagProxy" 253 | ], 254 | "Ext.fx.Anim": [], 255 | "Ext.chart.series.Area": [], 256 | "Ext.menu.Item": [ 257 | "Ext.menu.TextItem" 258 | ], 259 | "Ext.util.TaskManager": [ 260 | "Ext.TaskManager" 261 | ], 262 | "Ext.rtl.dom.Element_position": [], 263 | "Ext.chart.Legend": [], 264 | "Ext.ux.form.MultiSelect": [ 265 | "Ext.ux.Multiselect" 266 | ], 267 | "Ext.grid.plugin.HeaderReorderer": [], 268 | "Ext.rtl.view.Table": [], 269 | "Ext.layout.container.VBox": [ 270 | "Ext.layout.VBoxLayout" 271 | ], 272 | "Ext.rtl.util.Floating": [], 273 | "Ext.view.DropZone": [], 274 | "Ext.rtl.tree.Column": [], 275 | "Ext.layout.component.Button": [], 276 | "Ext.form.field.Hidden": [ 277 | "Ext.form.Hidden" 278 | ], 279 | "Ext.rtl.grid.plugin.RowEditing": [], 280 | "Ext.form.FieldContainer": [], 281 | "Ext.ux.event.RecorderManager": [], 282 | "Ext.chart.series.Cartesian": [ 283 | "Ext.chart.CartesianSeries", 284 | "Ext.chart.CartesianChart" 285 | ], 286 | "Ext.data.proxy.Server": [ 287 | "Ext.data.ServerProxy" 288 | ], 289 | "Ext.grid.column.Column": [ 290 | "Ext.grid.Column" 291 | ], 292 | "Ext.rtl.layout.component.Dock": [], 293 | "Ext.data.ResultSet": [], 294 | "Ext.data.association.HasMany": [ 295 | "Ext.data.HasManyAssociation" 296 | ], 297 | "Ext.layout.container.Fit": [ 298 | "Ext.layout.FitLayout" 299 | ], 300 | "Ext.util.CSS": [], 301 | "Ext.rtl.AbstractComponent": [], 302 | "Ext.layout.component.field.Field": [], 303 | "Ext.data.proxy.Ajax": [ 304 | "Ext.data.HttpProxy", 305 | "Ext.data.AjaxProxy" 306 | ], 307 | "Ext.app.domain.Component": [], 308 | "Ext.rtl.EventObjectImpl": [], 309 | "Ext.form.Label": [], 310 | "Ext.data.writer.Writer": [ 311 | "Ext.data.DataWriter", 312 | "Ext.data.Writer" 313 | ], 314 | "Ext.view.BoundListKeyNav": [], 315 | "Ext.form.FieldSet": [], 316 | "Ext.XTemplateParser": [], 317 | "Ext.form.field.VTypes": [ 318 | "Ext.form.VTypes" 319 | ], 320 | "Ext.fx.PropertyHandler": [], 321 | "Ext.form.CheckboxGroup": [], 322 | "Ext.data.JsonP": [], 323 | "Ext.draw.engine.Vml": [], 324 | "Ext.layout.container.CheckboxGroup": [], 325 | "Ext.app.domain.Direct": [], 326 | "Ext.panel.Header": [], 327 | "Ext.ux.TabScrollerMenu": [], 328 | "Ext.grid.plugin.CellEditing": [], 329 | "Ext.app.Controller": [], 330 | "Ext.rtl.dom.Layer": [], 331 | "Ext.form.field.Time": [ 332 | "Ext.form.TimeField", 333 | "Ext.form.Time" 334 | ], 335 | "Ext.fx.CubicBezier": [], 336 | "Ext.ux.LiveSearchGridPanel": [], 337 | "Ext.button.Cycle": [ 338 | "Ext.CycleButton" 339 | ], 340 | "Ext.app.domain.Global": [], 341 | "Ext.ux.grid.filter.DateFilter": [], 342 | "Ext.data.Tree": [], 343 | "Ext.ModelManager": [ 344 | "Ext.ModelMgr" 345 | ], 346 | "Ext.data.XmlStore": [], 347 | "Ext.grid.ViewDropZone": [], 348 | "Ext.ux.BoxReorderer": [], 349 | "Ext.rtl.slider.Multi": [], 350 | "Ext.grid.header.DropZone": [], 351 | "Ext.rtl.layout.component.field.Text": [], 352 | "Ext.util.HashMap": [], 353 | "Ext.grid.column.Template": [ 354 | "Ext.grid.TemplateColumn" 355 | ], 356 | "Ext.EventObjectImpl": [], 357 | "Ext.ComponentLoader": [], 358 | "Ext.form.FieldAncestor": [], 359 | "Ext.rtl.layout.container.Border": [], 360 | "Ext.app.domain.Controller": [], 361 | "Ext.chart.axis.Gauge": [], 362 | "Ext.layout.container.border.Region": [], 363 | "Ext.data.validations": [], 364 | "Ext.data.Connection": [], 365 | "Ext.resizer.Splitter": [], 366 | "Ext.dd.DropZone": [], 367 | "Ext.direct.ExceptionEvent": [], 368 | "Ext.form.RadioManager": [], 369 | "Ext.data.association.HasOne": [ 370 | "Ext.data.HasOneAssociation" 371 | ], 372 | "Ext.draw.Text": [], 373 | "Ext.window.MessageBox": [], 374 | "Ext.fx.target.CompositeElementCSS": [], 375 | "Ext.diag.layout.ContextItem": [], 376 | "Ext.ux.grid.filter.StringFilter": [], 377 | "Ext.rtl.selection.CellModel": [], 378 | "Ext.rtl.layout.ContextItem": [], 379 | "Ext.chart.series.Line": [ 380 | "Ext.chart.LineSeries", 381 | "Ext.chart.LineChart" 382 | ], 383 | "Ext.view.Table": [], 384 | "Ext.data.writer.Json": [ 385 | "Ext.data.JsonWriter" 386 | ], 387 | "Ext.fx.target.CompositeElement": [], 388 | "Ext.fx.Manager": [], 389 | "Ext.chart.Label": [], 390 | "Ext.grid.View": [], 391 | "Ext.Action": [], 392 | "Ext.form.Basic": [ 393 | "Ext.form.BasicForm" 394 | ], 395 | "Ext.rtl.form.field.Checkbox": [], 396 | "Ext.container.Viewport": [ 397 | "Ext.Viewport" 398 | ], 399 | "Ext.state.Stateful": [], 400 | "Ext.ux.grid.menu.RangeMenu": [], 401 | "Ext.grid.feature.RowBody": [], 402 | "Ext.form.field.Text": [ 403 | "Ext.form.TextField", 404 | "Ext.form.Text" 405 | ], 406 | "Ext.rtl.layout.component.field.Trigger": [], 407 | "Ext.data.reader.Xml": [ 408 | "Ext.data.XmlReader" 409 | ], 410 | "Ext.grid.feature.AbstractSummary": [], 411 | "Ext.rtl.layout.container.boxOverflow.Scroller": [], 412 | "Ext.chart.axis.Category": [ 413 | "Ext.chart.CategoryAxis" 414 | ], 415 | "Ext.grid.plugin.BufferedRendererTableView": [], 416 | "Ext.layout.container.Absolute": [ 417 | "Ext.layout.AbsoluteLayout" 418 | ], 419 | "Ext.rtl.layout.container.Box": [], 420 | "Ext.data.reader.Json": [ 421 | "Ext.data.JsonReader" 422 | ], 423 | "Ext.util.TextMetrics": [], 424 | "Ext.data.TreeStore": [], 425 | "Ext.view.BoundList": [ 426 | "Ext.BoundList" 427 | ], 428 | "Ext.form.field.HtmlEditor": [ 429 | "Ext.form.HtmlEditor" 430 | ], 431 | "Ext.layout.container.Form": [ 432 | "Ext.layout.FormLayout" 433 | ], 434 | "Ext.chart.MaskLayer": [], 435 | "Ext.util.Observable": [], 436 | "Ext.ux.DataTip": [], 437 | "Ext.ux.ajax.JsonSimlet": [], 438 | "Ext.resizer.BorderSplitterTracker": [], 439 | "Ext.util.LruCache": [], 440 | "Ext.tip.Tip": [ 441 | "Ext.Tip" 442 | ], 443 | "Ext.dom.CompositeElement": [ 444 | "Ext.CompositeElement" 445 | ], 446 | "Ext.grid.column.RowNumberer": [ 447 | "Ext.grid.RowNumberer" 448 | ], 449 | "Ext.grid.column.CheckColumn": [ 450 | "Ext.ux.CheckColumn" 451 | ], 452 | "Ext.rtl.resizer.SplitterTracker": [], 453 | "Ext.grid.feature.RowWrap": [], 454 | "Ext.data.proxy.Client": [ 455 | "Ext.data.ClientProxy" 456 | ], 457 | "Ext.data.Types": [], 458 | "Ext.draw.SpriteDD": [], 459 | "Ext.layout.container.boxOverflow.Menu": [ 460 | "Ext.layout.boxOverflow.Menu" 461 | ], 462 | "Ext.LoadMask": [], 463 | "Ext.rtl.grid.RowEditor": [], 464 | "Ext.toolbar.Paging": [ 465 | "Ext.PagingToolbar" 466 | ], 467 | "Ext.data.association.Association": [ 468 | "Ext.data.Association" 469 | ], 470 | "Ext.tree.ViewDropZone": [], 471 | "Ext.toolbar.Toolbar": [ 472 | "Ext.Toolbar" 473 | ], 474 | "Ext.tip.ToolTip": [ 475 | "Ext.ToolTip" 476 | ], 477 | "Ext.ux.DataView.DragSelector": [], 478 | "Ext.chart.Highlight": [], 479 | "Ext.state.Manager": [], 480 | "Ext.ux.grid.menu.ListMenu": [], 481 | "Ext.util.Inflector": [], 482 | "Ext.grid.Panel": [ 483 | "Ext.list.ListView", 484 | "Ext.ListView", 485 | "Ext.grid.GridPanel" 486 | ], 487 | "Ext.XTemplate": [], 488 | "Ext.data.NodeStore": [], 489 | "Ext.Shadow": [], 490 | "Ext.form.action.Submit": [ 491 | "Ext.form.Action.Submit" 492 | ], 493 | "Ext.form.Panel": [ 494 | "Ext.FormPanel", 495 | "Ext.form.FormPanel" 496 | ], 497 | "Ext.chart.series.Series": [], 498 | "Ext.perf.Accumulator": [], 499 | "Ext.ux.PreviewPlugin": [], 500 | "Ext.data.Request": [], 501 | "Ext.ux.ajax.SimXhr": [], 502 | "Ext.dd.DD": [], 503 | "Ext.dom.CompositeElementLite": [ 504 | "Ext.CompositeElementLite" 505 | ], 506 | "Ext.ux.CellDragDrop": [], 507 | "Ext.toolbar.Fill": [ 508 | "Ext.Toolbar.Fill" 509 | ], 510 | "Ext.ux.SlidingPager": [], 511 | "Ext.data.proxy.WebStorage": [ 512 | "Ext.data.WebStorageProxy" 513 | ], 514 | "Ext.util.Floating": [], 515 | "Ext.ux.TabReorderer": [], 516 | "Ext.form.action.DirectSubmit": [ 517 | "Ext.form.Action.DirectSubmit" 518 | ], 519 | "Ext.ux.grid.filter.NumericFilter": [], 520 | "Ext.util.Cookies": [], 521 | "Ext.data.UuidGenerator": [], 522 | "Ext.util.Point": [], 523 | "Ext.fx.target.Component": [], 524 | "Ext.form.CheckboxManager": [], 525 | "Ext.ux.event.Recorder": [], 526 | "Ext.form.field.Field": [], 527 | "Ext.form.field.Display": [ 528 | "Ext.form.DisplayField", 529 | "Ext.form.Display" 530 | ], 531 | "Ext.layout.container.Anchor": [ 532 | "Ext.layout.AnchorLayout" 533 | ], 534 | "Ext.layout.component.field.Text": [], 535 | "Ext.data.DirectStore": [], 536 | "Ext.ux.grid.filter.BooleanFilter": [], 537 | "Ext.dom.Layer": [ 538 | "Ext.Layer" 539 | ], 540 | "Ext.grid.RowEditorButtons": [], 541 | "Ext.data.BufferStore": [], 542 | "Ext.ux.form.SearchField": [], 543 | "Ext.ux.dd.CellFieldDropZone": [], 544 | "Ext.grid.plugin.DivRenderer": [], 545 | "Ext.grid.ColumnLayout": [], 546 | "Ext.dom.AbstractElement_style": [], 547 | "Ext.Template": [], 548 | "Ext.AbstractComponent": [], 549 | "Ext.chart.series.Column": [ 550 | "Ext.chart.ColumnSeries", 551 | "Ext.chart.ColumnChart", 552 | "Ext.chart.StackedColumnChart" 553 | ], 554 | "Ext.flash.Component": [ 555 | "Ext.FlashComponent" 556 | ], 557 | "Ext.form.field.Base": [ 558 | "Ext.form.Field", 559 | "Ext.form.BaseField" 560 | ], 561 | "Ext.dom.AbstractElement_insertion": [], 562 | "Ext.grid.feature.GroupStore": [], 563 | "Ext.data.SequentialIdGenerator": [], 564 | "Ext.grid.header.Container": [], 565 | "Ext.container.ButtonGroup": [ 566 | "Ext.ButtonGroup" 567 | ], 568 | "Ext.data.PageMap": [], 569 | "Ext.grid.column.Action": [ 570 | "Ext.grid.ActionColumn" 571 | ], 572 | "Ext.layout.component.field.Trigger": [], 573 | "Ext.layout.component.field.FieldContainer": [], 574 | "Ext.chart.Shape": [], 575 | "Ext.panel.DD": [], 576 | "Ext.container.AbstractContainer": [], 577 | "Ext.ux.grid.filter.ListFilter": [], 578 | "Ext.data.ArrayStore": [], 579 | "Ext.rtl.layout.container.CheckboxGroup": [], 580 | "Ext.window.Window": [ 581 | "Ext.Window" 582 | ], 583 | "Ext.grid.feature.Feature": [], 584 | "Ext.picker.Color": [ 585 | "Ext.ColorPalette" 586 | ], 587 | "Ext.ux.GMapPanel": [], 588 | "Ext.chart.theme.Theme": [], 589 | "Ext.util.ClickRepeater": [], 590 | "Ext.form.field.Spinner": [ 591 | "Ext.form.Spinner" 592 | ], 593 | "Ext.container.DockingContainer": [], 594 | "Ext.selection.DataViewModel": [], 595 | "Ext.ux.DataView.Animated": [], 596 | "Ext.rtl.selection.TreeModel": [], 597 | "Ext.dd.DragTracker": [], 598 | "Ext.data.Group": [], 599 | "Ext.dd.DragDropManager": [ 600 | "Ext.dd.DragDropMgr", 601 | "Ext.dd.DDM" 602 | ], 603 | "Ext.selection.CheckboxModel": [], 604 | "Ext.menu.KeyNav": [], 605 | "Ext.layout.container.Column": [ 606 | "Ext.layout.ColumnLayout" 607 | ], 608 | "Ext.draw.Matrix": [], 609 | "Ext.form.field.Number": [ 610 | "Ext.form.NumberField", 611 | "Ext.form.Number" 612 | ], 613 | "Ext.rtl.util.Renderable": [], 614 | "Ext.ux.statusbar.StatusBar": [ 615 | "Ext.ux.StatusBar" 616 | ], 617 | "Ext.data.proxy.Direct": [ 618 | "Ext.data.DirectProxy" 619 | ], 620 | "Ext.chart.Navigation": [], 621 | "Ext.slider.Tip": [], 622 | "Ext.chart.theme.Base": [], 623 | "Ext.form.field.TextArea": [ 624 | "Ext.form.TextArea" 625 | ], 626 | "Ext.rtl.layout.container.VBox": [], 627 | "Ext.util.Positionable": [], 628 | "Ext.form.field.Radio": [ 629 | "Ext.form.Radio" 630 | ], 631 | "Ext.layout.component.ProgressBar": [], 632 | "Ext.chart.series.Pie": [ 633 | "Ext.chart.PieSeries", 634 | "Ext.chart.PieChart" 635 | ], 636 | "Ext.tree.plugin.TreeViewDragDrop": [], 637 | "Ext.direct.Provider": [], 638 | "Ext.data.TreeModel": [], 639 | "Ext.layout.Layout": [], 640 | "Ext.toolbar.TextItem": [ 641 | "Ext.Toolbar.TextItem" 642 | ], 643 | "Ext.ux.DataView.Draggable": [], 644 | "Ext.dom.Helper": [], 645 | "Ext.rtl.button.Button": [], 646 | "Ext.util.AbstractMixedCollection": [], 647 | "Ext.data.JsonStore": [], 648 | "Ext.button.Split": [ 649 | "Ext.SplitButton" 650 | ], 651 | "Ext.dd.DropTarget": [], 652 | "Ext.direct.RemotingEvent": [], 653 | "Ext.ux.form.ItemSelector": [ 654 | "Ext.ux.ItemSelector" 655 | ], 656 | "Ext.draw.Sprite": [], 657 | "Ext.ux.Spotlight": [], 658 | "Ext.fx.target.Sprite": [], 659 | "Ext.data.proxy.LocalStorage": [ 660 | "Ext.data.LocalStorageProxy" 661 | ], 662 | "Ext.layout.component.Draw": [], 663 | "Ext.AbstractPlugin": [], 664 | "Ext.Editor": [], 665 | "Ext.chart.Tip": [], 666 | "Ext.chart.axis.Radial": [], 667 | "Ext.ux.ajax.DataSimlet": [], 668 | "Ext.layout.container.Table": [ 669 | "Ext.layout.TableLayout" 670 | ], 671 | "Ext.chart.axis.Abstract": [], 672 | "Ext.data.proxy.Rest": [ 673 | "Ext.data.RestProxy" 674 | ], 675 | "Ext.rtl.layout.container.Absolute": [], 676 | "Ext.util.Queue": [], 677 | "Ext.state.CookieProvider": [], 678 | "Ext.Img": [], 679 | "Ext.dd.DragSource": [], 680 | "Ext.grid.CellEditor": [], 681 | "Ext.layout.ClassList": [], 682 | "Ext.button.Manager": [ 683 | "Ext.ButtonToggleManager" 684 | ], 685 | "Ext.rtl.form.field.File": [], 686 | "Ext.util.Sorter": [], 687 | "Ext.resizer.SplitterTracker": [], 688 | "Ext.panel.Table": [], 689 | "Ext.dom.Element_scroll": [], 690 | "Ext.draw.Color": [], 691 | "Ext.chart.series.Bar": [ 692 | "Ext.chart.BarSeries", 693 | "Ext.chart.BarChart", 694 | "Ext.chart.StackedBarChart" 695 | ], 696 | "Ext.PluginManager": [ 697 | "Ext.PluginMgr" 698 | ], 699 | "Ext.util.ComponentDragger": [], 700 | "Ext.chart.Callout": [], 701 | "Ext.chart.series.Scatter": [], 702 | "Ext.data.Store": [], 703 | "Ext.grid.feature.Summary": [], 704 | "Ext.util.ProtoElement": [], 705 | "Ext.layout.component.Component": [], 706 | "Ext.direct.Manager": [], 707 | "Ext.data.proxy.Proxy": [ 708 | "Ext.data.DataProxy", 709 | "Ext.data.Proxy" 710 | ], 711 | "Ext.menu.CheckItem": [], 712 | "Ext.ux.ProgressBarPager": [], 713 | "Ext.dom.Element_fx": [], 714 | "Ext.dom.AbstractElement": [], 715 | "Ext.layout.container.Card": [ 716 | "Ext.layout.CardLayout" 717 | ], 718 | "Ext.draw.Component": [], 719 | "Ext.toolbar.Item": [ 720 | "Ext.Toolbar.Item" 721 | ], 722 | "Ext.form.RadioGroup": [], 723 | "Ext.rtl.tab.Bar": [], 724 | "Ext.rtl.form.field.Trigger": [], 725 | "Ext.slider.Thumb": [], 726 | "Ext.grid.header.DragZone": [], 727 | "Ext.rtl.resizer.ResizeTracker": [], 728 | "Ext.form.action.DirectLoad": [ 729 | "Ext.form.Action.DirectLoad" 730 | ], 731 | "Ext.picker.Time": [], 732 | "Ext.grid.plugin.BufferedRenderer": [], 733 | "Ext.resizer.BorderSplitter": [], 734 | "Ext.menu.ColorPicker": [], 735 | "Ext.ZIndexManager": [ 736 | "Ext.WindowGroup" 737 | ], 738 | "Ext.ux.ajax.SimManager": [], 739 | "Ext.menu.Menu": [], 740 | "Ext.chart.LegendItem": [], 741 | "Ext.toolbar.Spacer": [ 742 | "Ext.Toolbar.Spacer" 743 | ], 744 | "Ext.rtl.dd.DD": [], 745 | "Ext.panel.Panel": [ 746 | "Ext.Panel" 747 | ], 748 | "Ext.util.Memento": [], 749 | "Ext.app.domain.Store": [], 750 | "Ext.data.proxy.Memory": [ 751 | "Ext.data.MemoryProxy" 752 | ], 753 | "Ext.grid.plugin.DragDrop": [], 754 | "Ext.chart.axis.Time": [ 755 | "Ext.chart.TimeAxis" 756 | ], 757 | "Ext.ComponentQuery": [], 758 | "Ext.dom.Element_style": [], 759 | "Ext.draw.engine.SvgExporter": [], 760 | "Ext.layout.container.Auto": [], 761 | "Ext.grid.locking.Lockable": [ 762 | "Ext.grid.Lockable" 763 | ], 764 | "Ext.ux.TreePicker": [], 765 | "Ext.view.AbstractView": [], 766 | "Ext.util.Region": [], 767 | "Ext.fx.target.ElementCSS": [], 768 | "Ext.draw.Draw": [], 769 | "Ext.util.Event": [], 770 | "Ext.ux.data.PagingMemoryProxy": [ 771 | "Ext.data.PagingMemoryProxy" 772 | ], 773 | "Ext.rtl.panel.Panel": [], 774 | "Ext.ux.grid.filter.Filter": [], 775 | "Ext.layout.component.field.HtmlEditor": [], 776 | "Ext.ux.GroupTabRenderer": [], 777 | "Ext.dom.Element_dd": [], 778 | "Ext.data.proxy.SessionStorage": [ 779 | "Ext.data.SessionStorageProxy" 780 | ], 781 | "Ext.app.EventBus": [], 782 | "Ext.menu.Separator": [], 783 | "Ext.util.History": [ 784 | "Ext.History" 785 | ], 786 | "Ext.direct.Event": [], 787 | "Ext.direct.RemotingMethod": [], 788 | "Ext.dd.ScrollManager": [], 789 | "Ext.chart.Mask": [], 790 | "Ext.rtl.dom.Element_anim": [], 791 | "Ext.selection.CellModel": [], 792 | "Ext.view.TableLayout": [], 793 | "Ext.rtl.panel.Header": [], 794 | "Ext.rtl.dom.Element_scroll": [], 795 | "Ext.state.Provider": [], 796 | "Ext.ux.DataView.LabelEditor": [], 797 | "Ext.layout.container.Editor": [], 798 | "Ext.grid.ColumnManager": [ 799 | "Ext.grid.ColumnModel" 800 | ], 801 | "Ext.data.Errors": [], 802 | "Ext.dom.AbstractQuery": [], 803 | "Ext.grid.plugin.RowExpander": [], 804 | "Ext.selection.TreeModel": [], 805 | "Ext.form.Labelable": [], 806 | "Ext.grid.column.Number": [ 807 | "Ext.grid.NumberColumn" 808 | ], 809 | "Ext.grid.property.Grid": [ 810 | "Ext.grid.PropertyGrid" 811 | ], 812 | "Ext.draw.engine.Svg": [], 813 | "Ext.FocusManager": [ 814 | "Ext.FocusMgr" 815 | ], 816 | "Ext.AbstractManager": [], 817 | "Ext.chart.series.Radar": [], 818 | "Ext.rtl.dom.Element_insertion": [], 819 | "Ext.ux.RowExpander": [], 820 | "Ext.grid.property.Property": [ 821 | "Ext.PropGridProperty" 822 | ], 823 | "Ext.chart.TipSurface": [], 824 | "Ext.grid.column.Boolean": [ 825 | "Ext.grid.BooleanColumn" 826 | ], 827 | "Ext.layout.SizeModel": [], 828 | "Ext.direct.PollingProvider": [], 829 | "Ext.grid.plugin.HeaderResizer": [], 830 | "Ext.tree.Column": [], 831 | "Ext.data.writer.Xml": [ 832 | "Ext.data.XmlWriter" 833 | ], 834 | "Ext.slider.Multi": [ 835 | "Ext.slider.MultiSlider" 836 | ], 837 | "Ext.panel.AbstractPanel": [], 838 | "Ext.ux.event.Maker": [], 839 | "Ext.layout.component.field.Slider": [], 840 | "Ext.chart.axis.Numeric": [ 841 | "Ext.chart.NumericAxis" 842 | ], 843 | "Ext.layout.container.boxOverflow.Scroller": [ 844 | "Ext.layout.boxOverflow.Scroller" 845 | ], 846 | "Ext.data.Operation": [], 847 | "Ext.resizer.Resizer": [ 848 | "Ext.Resizable" 849 | ], 850 | "Ext.layout.container.HBox": [ 851 | "Ext.layout.HBoxLayout" 852 | ], 853 | "Ext.selection.RowModel": [], 854 | "Ext.layout.ContextItem": [], 855 | "Ext.util.MixedCollection": [], 856 | "Ext.perf.Monitor": [ 857 | "Ext.Perf" 858 | ] 859 | } 860 | -------------------------------------------------------------------------------- /lib/conf/foundation.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ext.Array": true, 3 | "Ext.Base": true, 4 | "Ext.Class": true, 5 | "Ext.ClassManager": true, 6 | "Ext.Date": true, 7 | "Ext.Error": true, 8 | "Ext.Function": true, 9 | "Ext.Loader": true, 10 | "Ext.Number": true, 11 | "Ext.Object": true, 12 | "Ext.String": true, 13 | "Ext.Version": true 14 | } 15 | -------------------------------------------------------------------------------- /lib/rules/ext-array-foreach.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to flag use of Ext.Array.each() when Ext.Array.forEach() 3 | * would be better. 4 | * 5 | * @author Nat Burns 6 | */ 7 | 8 | //------------------------------------------------------------------------------ 9 | // Rule Definition 10 | //------------------------------------------------------------------------------ 11 | 12 | module.exports = function(context) { 13 | 14 | "use strict"; 15 | 16 | var findFunctionAncestor = function(ancestors) { 17 | var ancestor; 18 | 19 | while (ancestors.length > 0) { 20 | ancestor = ancestors.pop(); 21 | 22 | if (ancestor.type === "FunctionExpression") { 23 | return ancestor; 24 | } 25 | } 26 | 27 | return null; 28 | }; 29 | 30 | var calls = []; 31 | 32 | return { 33 | "ReturnStatement": function(node) { 34 | if (calls.length === 0 || !node.argument) { 35 | return; 36 | } 37 | 38 | var parent = calls[calls.length - 1]; 39 | 40 | if (!parent.isExtArray) { 41 | return; 42 | } 43 | 44 | var fn = findFunctionAncestor(context.getAncestors()); 45 | 46 | if (parent.fn === fn) { 47 | parent.usesExtraFeature = true; 48 | } 49 | }, 50 | 51 | "CallExpression": function(node) { 52 | var info = { 53 | node: node 54 | }; 55 | 56 | var callee = node.callee; 57 | var args = node.arguments; 58 | 59 | if (callee.type === "MemberExpression") { 60 | var obj = callee.object; 61 | var name = callee.property.name; 62 | 63 | if ( 64 | (name === "each" || name === "forEach") 65 | && obj.type === "MemberExpression" 66 | && obj.object.name === "Ext" 67 | && obj.property.name === "Array" 68 | ) { 69 | var fn = args[1]; 70 | 71 | if (fn) { 72 | info.isExtArray = true; 73 | info.fn = fn; 74 | info.name = name; 75 | info.usesExtraFeature = false; 76 | 77 | if (name === "each") { 78 | var reverse = args[3]; 79 | 80 | if ( 81 | reverse && 82 | ( 83 | reverse.type !== "Literal" || 84 | reverse.value !== false 85 | ) 86 | ) { 87 | info.usesExtraFeature = true; 88 | } 89 | } 90 | } 91 | } 92 | } 93 | 94 | calls.push(info); 95 | }, 96 | 97 | "CallExpression:exit": function() { 98 | var call = calls.pop(); 99 | 100 | if ( 101 | call.isExtArray 102 | && call.name === "each" 103 | && !call.usesExtraFeature 104 | ) { 105 | context.report( 106 | call.node, 107 | "Use Ext.Array.forEach() rather than Ext.Array.each()." 108 | ); 109 | } 110 | } 111 | }; 112 | 113 | }; -------------------------------------------------------------------------------- /lib/rules/ext-deps.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to flag missing and unused dependencies in ExtJS classes. 3 | * @author Nat Burns 4 | */ 5 | 6 | var classdata = require("../classdata"); 7 | 8 | //------------------------------------------------------------------------------ 9 | // Rule Definition 10 | //------------------------------------------------------------------------------ 11 | 12 | module.exports = function(context) { 13 | 14 | "use strict"; 15 | 16 | var classes = classdata.loadDefaults(); 17 | var calls = []; 18 | 19 | var getPropertyKey = function(property) { 20 | var key = property.key; 21 | 22 | if (key.type === "Identifier") { 23 | return key.name; 24 | } 25 | else if (key.type === "Literal") { 26 | return "" + key.value; 27 | } 28 | 29 | return null; 30 | }; 31 | 32 | var addDependency = function(typeName) { 33 | calls[calls.length - 1].dependencies[classes.alternates[typeName] || typeName] = true; 34 | }; 35 | 36 | var addReference = function(typeName) { 37 | calls[calls.length - 1].references[classes.alternates[typeName] || typeName] = true; 38 | }; 39 | 40 | var handleTypes = function(node, key, callback, options) { 41 | if (options.string && node.type === "Literal" && typeof node.value === "string") { 42 | callback(node.value); 43 | } 44 | else if (options.array && node.type === "ArrayExpression") { 45 | node.elements.forEach(function(element) { 46 | handleTypes(element, key, callback, options); 47 | }); 48 | } 49 | else if (options.objectkey && node.type === "ObjectExpression") { 50 | node.properties.forEach(function(prop) { 51 | var subkey = getPropertyKey(prop); 52 | 53 | if (subkey === options.objectkey) { 54 | handleTypes(prop.value, key, callback, options); 55 | } 56 | }); 57 | } 58 | else if (options.strict) { 59 | context.report( 60 | node, 61 | "Unexpected {{node}} encountered in {{key}} config.", 62 | { 63 | node: node.type, 64 | key: key 65 | } 66 | ); 67 | } 68 | }; 69 | 70 | var parseReference = function(node) { 71 | if (node.type === "Identifier") { 72 | return node.name; 73 | } 74 | else if (node.type === "MemberExpression") { 75 | var obj = parseReference(node.object); 76 | var prop = parseReference(node.property); 77 | 78 | if (obj && prop) { 79 | return obj + "." + prop; 80 | } 81 | } 82 | 83 | return null; 84 | }; 85 | 86 | 87 | return { 88 | 89 | "Program": function() { 90 | classes.loadScope(context.getScope()); 91 | }, 92 | 93 | "MemberExpression": function(node) { 94 | if (calls.length < 1) { 95 | // Don't include top-level references without a wrapping class. 96 | return; 97 | } 98 | 99 | var ancestors = context.getAncestors(); 100 | var parent = ancestors[ancestors.length - 1]; 101 | 102 | if (parent.type !== "MemberExpression") { 103 | var member = parseReference(node); 104 | 105 | if (member) { 106 | var cls = classes.getClassName(member); 107 | 108 | if (cls) { 109 | addReference(cls); 110 | } 111 | } 112 | } 113 | }, 114 | 115 | "Property": function(node) { 116 | var key = getPropertyKey(node); 117 | 118 | switch (key) { 119 | case "xtype": 120 | case "items": 121 | key = "widget"; 122 | break; 123 | 124 | case "defaultReaderType": 125 | key = "reader"; 126 | break; 127 | 128 | case "defaultWriterType": 129 | key = "writer"; 130 | break; 131 | } 132 | 133 | var aliases = classes.aliases[key]; 134 | 135 | if (aliases) { 136 | var addAliasReference = function(type) { 137 | var cls = aliases[type]; 138 | 139 | if (cls) { 140 | addReference(cls); 141 | } 142 | }; 143 | 144 | handleTypes( 145 | node.value, 146 | key, 147 | addAliasReference, 148 | key === "widget" 149 | ? { 150 | string: true, 151 | array: true, 152 | objectkey: "xtype" 153 | } 154 | : { 155 | string: true, 156 | objectkey: "type" 157 | } 158 | ); 159 | } 160 | }, 161 | 162 | "CallExpression": function(node) { 163 | var info = { 164 | node: node, 165 | references: {} 166 | }; 167 | 168 | calls.push(info); 169 | 170 | var callee = node.callee; 171 | var method = callee.property 172 | ? callee.property.name 173 | : null; 174 | 175 | var args = node.arguments; 176 | var arg; 177 | 178 | if (callee.type === "MemberExpression" && callee.object.name === "Ext") { 179 | if (method === "create" && args.length > 0) { 180 | arg = node.arguments[0]; 181 | 182 | if (arg.type === "Literal" && typeof arg.value === "string") { 183 | addReference(arg.value); 184 | } 185 | } 186 | else if (method === "define" && args.length > 1) { 187 | arg = node.arguments[0]; 188 | 189 | if (arg.type === "Literal" && typeof arg.value === "string") { 190 | info.name = arg.value; 191 | } 192 | 193 | arg = node.arguments[1]; 194 | 195 | if (arg.type === "ObjectExpression") { 196 | info.dependencies = {}; 197 | 198 | arg.properties.forEach(function(prop) { 199 | var key = getPropertyKey(prop); 200 | 201 | var handler; 202 | var options; 203 | 204 | if (key === "requires" || key === "uses") { 205 | handler = addDependency; 206 | 207 | options = { 208 | string: true, 209 | array: true 210 | }; 211 | } 212 | else if (key === "extend") { 213 | handler = function(type) { 214 | addDependency(type); 215 | addReference(type); 216 | }; 217 | 218 | options = { string: true }; 219 | } 220 | 221 | if (handler) { 222 | options.strict = true; 223 | handleTypes(prop.value, key, handler, options); 224 | } 225 | }); 226 | } 227 | } 228 | } 229 | }, 230 | 231 | "CallExpression:exit": function() { 232 | var call = calls.pop(); 233 | 234 | var deps = call.dependencies; 235 | var refs = call.references; 236 | 237 | if (deps) { 238 | Object.keys(refs).forEach(function(name) { 239 | if (refs[name] && !deps[name] && !classes.foundation[name]) { 240 | context.report( 241 | call.node, 242 | "Class {{name}} is referenced by {{parent}} but not listed as a dependency.", 243 | { 244 | name: name, 245 | parent: call.name 246 | } 247 | ); 248 | } 249 | }); 250 | 251 | Object.keys(deps).forEach(function(name) { 252 | if (deps[name] && !refs[name]) { 253 | context.report( 254 | call.node, 255 | "The dependency {{name}} is never used by the parent class {{parent}}.", 256 | { 257 | name: name, 258 | parent: call.name 259 | } 260 | ); 261 | } 262 | }); 263 | } 264 | else if (calls.length > 0) { 265 | var parent = calls[calls.length - 1].references; 266 | 267 | Object.keys(refs).forEach(function(name) { 268 | parent[name] = parent[name] || refs[name]; 269 | }); 270 | } 271 | } 272 | }; 273 | 274 | }; -------------------------------------------------------------------------------- /lib/rules/no-ext-create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to flag use of Ext.create() 3 | * @author Nat Burns 4 | */ 5 | 6 | //------------------------------------------------------------------------------ 7 | // Rule Definition 8 | //------------------------------------------------------------------------------ 9 | 10 | module.exports = function(context) { 11 | 12 | "use strict"; 13 | 14 | return { 15 | "CallExpression": function(node) { 16 | var callee = node.callee; 17 | var arg = node.arguments[0]; 18 | 19 | if ( 20 | callee.type === "MemberExpression" 21 | && callee.object.name === "Ext" 22 | && callee.property.name === "create" 23 | && arg 24 | && arg.type === "Literal" 25 | && typeof arg.value === "string" 26 | ) { 27 | context.report( 28 | node, 29 | "Use new {{name}}() rather than Ext.create('{{name}}').", 30 | { 31 | name: arg.value 32 | } 33 | ) 34 | } 35 | } 36 | }; 37 | 38 | }; -------------------------------------------------------------------------------- /lib/rules/no-ext-multi-def.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to flag multiple Ext.define() calls in a single file 3 | * @author Nat Burns 4 | */ 5 | 6 | //------------------------------------------------------------------------------ 7 | // Rule Definition 8 | //------------------------------------------------------------------------------ 9 | 10 | module.exports = function(context) { 11 | 12 | "use strict"; 13 | 14 | var count = 0; 15 | 16 | return { 17 | "CallExpression": function(node) { 18 | var callee = node.callee; 19 | var arg = node.arguments[0]; 20 | 21 | if ( 22 | callee.type === "MemberExpression" 23 | && callee.object.name === "Ext" 24 | && callee.property.name === "define" 25 | && arg 26 | && arg.type === "Literal" 27 | && typeof arg.value === "string" 28 | ) { 29 | count++; 30 | 31 | if (count > 1) { 32 | context.report( 33 | node, 34 | "Only one class definition is allowed per file." 35 | ); 36 | } 37 | } 38 | } 39 | }; 40 | 41 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-extjs", 3 | "version": "0.0.3", 4 | "description": "ESLint rules for projects using the ExtJS framework.", 5 | "homepage": "https://github.com/burnnat/eslint-plugin-extjs", 6 | "author": { 7 | "name": "Nat Burns", 8 | "email": "nbaccount@burnskids.com" 9 | }, 10 | "licenses": [ 11 | { 12 | "type": "MIT", 13 | "url": "https://github.com/burnnat/eslint-plugin-extjs/blob/master/LICENSE" 14 | } 15 | ], 16 | "main": "index.js", 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/burnnat/eslint-plugin-extjs.git" 20 | }, 21 | "bugs": { 22 | "url": "https://github.com/burnnat/eslint-plugin-extjs/issues" 23 | }, 24 | "engines": { 25 | "node": ">=0.8.0" 26 | }, 27 | "dependencies": {}, 28 | "peerDependencies": { 29 | "eslint": ">=0.8.0" 30 | }, 31 | "devDependencies": { 32 | "grunt": "~0.4.5", 33 | "grunt-cli": "~0.1.13", 34 | "grunt-mocha-test": "~0.12.7", 35 | "eslint": "latest", 36 | "eslint-tester": "latest" 37 | }, 38 | "scripts": { 39 | "test": "node ./node_modules/grunt-cli/bin/grunt test" 40 | }, 41 | "keywords": [ 42 | "eslint", 43 | "eslintplugin", 44 | "extjs" 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /test/conf/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is generated by Sencha Cmd and should NOT be edited. It is 3 | * provided to support globbing requires, custom xtypes, and other 4 | * metadata-driven class system features 5 | */ 6 | Ext.Loader.addClassPathMappings({ 7 | "Ext": "ext/src", 8 | "App": "app" 9 | }); 10 | Ext.ClassManager.addNameAlternateMappings({ 11 | "App.Original": [ 12 | "App.Orig" 13 | ], 14 | "App.doodad.Manager": [ 15 | "App.DoodadManager", 16 | "App.DoodadMgr" 17 | ] 18 | }); 19 | Ext.ClassManager.addNameAliasMappings({ 20 | "App.Widget": [ 21 | "widget.appwidget" 22 | ], 23 | "App.Proxy": [ 24 | "proxy.appproxy", 25 | "proxy.app" 26 | ] 27 | }); 28 | Ext.Loader.loadScript("app/overrides/Something.js"); -------------------------------------------------------------------------------- /test/lib/classdata.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | var path = require("path"); 3 | var classdata = require("../../lib/classdata"); 4 | 5 | describe("classdata", function() { 6 | it("should load bootstrap files", function() { 7 | var classes = classdata.loadBootstrap( 8 | path.join(__dirname, "../conf/bootstrap.js") 9 | ); 10 | 11 | assert.equal(classes.alternates["App.Orig"], "App.Original"); 12 | assert.equal(classes.alternates["App.DoodadMgr"], "App.doodad.Manager"); 13 | assert.equal(classes.alternates["App.DoodadManager"], "App.doodad.Manager"); 14 | 15 | assert.equal(classes.aliases.widget.appwidget, "App.Widget"); 16 | assert.equal(classes.aliases.proxy.appproxy, "App.Proxy"); 17 | assert.equal(classes.aliases.proxy.app, "App.Proxy"); 18 | }); 19 | }); -------------------------------------------------------------------------------- /test/lib/rules/ext-array-foreach.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Tests for ext-array-foreach rule. 3 | * @author Nat Burns 4 | */ 5 | 6 | //------------------------------------------------------------------------------ 7 | // Requirements 8 | //------------------------------------------------------------------------------ 9 | 10 | var rule = require("../../../lib/rules/ext-array-foreach"); 11 | var RuleTester = require("eslint").RuleTester; 12 | var tester = new RuleTester(); 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | tester.run("ext-array-foreach", rule, { 19 | valid: [ 20 | "Ext.Array.forEach(['a'], function() {});", 21 | "Ext.Array.each(['a'], function(item) { if (item === 'a') { return false; } });", 22 | "Ext.Array.each(['a'], function() {}, this, true);" 23 | ], 24 | invalid: [ 25 | { 26 | code: "Ext.Array.each(['a'], function() {});", 27 | errors: [ 28 | { 29 | message: "Use Ext.Array.forEach() rather than Ext.Array.each().", 30 | type: "CallExpression" 31 | } 32 | ] 33 | }, 34 | { 35 | code: "Ext.Array.each(['a'], function() {}, this, false);", 36 | errors: [ 37 | { 38 | message: "Use Ext.Array.forEach() rather than Ext.Array.each().", 39 | type: "CallExpression" 40 | } 41 | ] 42 | } 43 | ] 44 | }); -------------------------------------------------------------------------------- /test/lib/rules/ext-deps.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Tests for ext-deps rule. 3 | * @author Nat Burns 4 | */ 5 | 6 | //------------------------------------------------------------------------------ 7 | // Requirements 8 | //------------------------------------------------------------------------------ 9 | 10 | var rule = require("../../../lib/rules/ext-deps"); 11 | var RuleTester = require("eslint").RuleTester; 12 | var tester = new RuleTester(); 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | tester.run("ext-deps", rule, { 19 | valid: [ 20 | { 21 | code: "Ext.require('App.Class');", 22 | global: { 23 | Ext: true, 24 | App: true 25 | } 26 | }, 27 | { 28 | code: "Ext.util.History.back();", 29 | global: { 30 | Ext: true, 31 | App: true 32 | } 33 | }, 34 | { 35 | code: "Ext.define('App.Class', { requires: ['Ext.panel.Panel'], constructor: function() { this.panel = new Ext.panel.Panel(); } });", 36 | global: { 37 | Ext: true, 38 | App: true 39 | } 40 | }, 41 | { 42 | code: "Ext.define('App.Class', { requires: ['Ext.Ajax'], constructor: function() { this.timeout = Ext.Ajax.defaultTimeout; } });", 43 | global: { 44 | Ext: true, 45 | App: true 46 | } 47 | }, 48 | { 49 | code: "Ext.define('App.Class', { requires: ['Ext.container.Viewport'], constructor: function() { this.viewport = new Ext.Viewport(); } });", 50 | global: { 51 | Ext: true, 52 | App: true 53 | } 54 | }, 55 | { 56 | code: "Ext.define('App.Class', { requires: ['Ext.Viewport'], constructor: function() { this.viewport = new Ext.container.Viewport(); } });", 57 | global: { 58 | Ext: true, 59 | App: true 60 | } 61 | }, 62 | { 63 | code: "Ext.define('App.Class', { uses: ['App.Panel'], constructor: function() { this.panel = Ext.create('App.Panel'); } });", 64 | global: { 65 | Ext: true, 66 | App: true 67 | } 68 | }, 69 | { 70 | code: "Ext.define('App.Class', { uses: ['Ext.state.Manager', 'Ext.state.CookieProvider'], init: function() { Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); } });", 71 | global: { 72 | Ext: true, 73 | App: true 74 | } 75 | }, 76 | { 77 | code: "Ext.define('App.Class', { extend: 'App.Parent' });", 78 | global: { 79 | Ext: true, 80 | App: true 81 | } 82 | }, 83 | { 84 | code: "Ext.define('App.Class', { extend: 'Ext.data.proxy.Ajax', requires: ['Ext.data.reader.Array', 'Ext.data.writer.Xml'], defaultReaderType: 'array', defaultWriterType: 'xml' });", 85 | global: { 86 | Ext: true, 87 | App: true 88 | } 89 | }, 90 | { 91 | code: "Ext.define('App.Class', { extend: 'App.Parent', constructor: function() { App.Parent.register(this); } });", 92 | global: { 93 | Ext: true, 94 | App: true 95 | } 96 | }, 97 | { 98 | code: "Ext.define('App.Class', { constructor: function() { this.names = Ext.Array.from(Ext.ClassManager.getName(this.self)); } });", 99 | global: { 100 | Ext: true, 101 | App: true 102 | } 103 | } 104 | ], 105 | invalid: [ 106 | { 107 | code: "Ext.define('App.Class', { requires: ['Ext.panel.Panel'] });", 108 | global: { 109 | Ext: true, 110 | App: true 111 | }, 112 | errors: [ 113 | { 114 | message: "The dependency Ext.panel.Panel is never used by the parent class App.Class.", 115 | type: "CallExpression" 116 | } 117 | ] 118 | }, 119 | { 120 | code: "Ext.define('App.Class', { uses: ['Ext.panel.Panel'] });", 121 | global: { 122 | Ext: true, 123 | App: true 124 | }, 125 | errors: [ 126 | { 127 | message: "The dependency Ext.panel.Panel is never used by the parent class App.Class.", 128 | type: "CallExpression" 129 | } 130 | ] 131 | }, 132 | { 133 | code: "Ext.define('App.Class', { constructor: function() { this.panel = new Ext.panel.Panel(); } });", 134 | global: { 135 | Ext: true, 136 | App: true 137 | }, 138 | errors: [ 139 | { 140 | message: "Class Ext.panel.Panel is referenced by App.Class but not listed as a dependency.", 141 | type: "CallExpression" 142 | } 143 | ] 144 | }, 145 | { 146 | code: "Ext.define('App.Class', { constructor: function() { this.panel = Ext.create('Ext.panel.Panel'); } });", 147 | global: { 148 | Ext: true, 149 | App: true 150 | }, 151 | errors: [ 152 | { 153 | message: "Class Ext.panel.Panel is referenced by App.Class but not listed as a dependency.", 154 | type: "CallExpression" 155 | } 156 | ] 157 | }, 158 | { 159 | code: "Ext.define('App.Class', { constructor: function() { Ext.tip.QuickTipManager.init(); } });", 160 | global: { 161 | Ext: true, 162 | App: true 163 | }, 164 | errors: [ 165 | { 166 | message: "Class Ext.tip.QuickTipManager is referenced by App.Class but not listed as a dependency.", 167 | type: "CallExpression" 168 | } 169 | ] 170 | }, 171 | { 172 | code: "Ext.define('App.Class', { layout: 'fit' });", 173 | global: { 174 | Ext: true, 175 | App: true 176 | }, 177 | errors: [ 178 | { 179 | message: "Class Ext.layout.container.Fit is referenced by App.Class but not listed as a dependency.", 180 | type: "CallExpression" 181 | } 182 | ] 183 | }, 184 | { 185 | code: "Ext.define('App.Class', { proxy: { type: 'ajax', reader: 'json', writer: 'xml' } });", 186 | global: { 187 | Ext: true, 188 | App: true 189 | }, 190 | errors: [ 191 | { 192 | message: "Class Ext.data.proxy.Ajax is referenced by App.Class but not listed as a dependency.", 193 | type: "CallExpression" 194 | }, 195 | { 196 | message: "Class Ext.data.reader.Json is referenced by App.Class but not listed as a dependency.", 197 | type: "CallExpression" 198 | }, 199 | { 200 | message: "Class Ext.data.writer.Xml is referenced by App.Class but not listed as a dependency.", 201 | type: "CallExpression" 202 | } 203 | ] 204 | }, 205 | { 206 | code: "Ext.define('App.Class', { constructor: function() { Ext.apply(this, { items: [{ xtype: 'button', text: 'Label' }, 'grid'] }); } });", 207 | global: { 208 | Ext: true, 209 | App: true 210 | }, 211 | errors: [ 212 | { 213 | message: "Class Ext.button.Button is referenced by App.Class but not listed as a dependency.", 214 | type: "CallExpression" 215 | }, 216 | { 217 | message: "Class Ext.grid.Panel is referenced by App.Class but not listed as a dependency.", 218 | type: "CallExpression" 219 | } 220 | ] 221 | } 222 | ] 223 | }); -------------------------------------------------------------------------------- /test/lib/rules/no-ext-create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Tests for no-ext-create rule. 3 | * @author Nat Burns 4 | */ 5 | 6 | //------------------------------------------------------------------------------ 7 | // Requirements 8 | //------------------------------------------------------------------------------ 9 | 10 | var rule = require("../../../lib/rules/no-ext-create"); 11 | var RuleTester = require("eslint").RuleTester; 12 | var tester = new RuleTester(); 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | tester.run("no-ext-create", rule, { 19 | valid: [ 20 | "var panel = new Ext.util.Something({ create: true });", 21 | "var panel = Ext.create(getDynamicClassName(), { config: true });" 22 | ], 23 | invalid: [ 24 | { 25 | code: "var panel = Ext.create('Ext.util.Something', { config: true });", 26 | errors: [ 27 | { 28 | message: "Use new Ext.util.Something() rather than Ext.create('Ext.util.Something').", 29 | type: "CallExpression" 30 | } 31 | ] 32 | } 33 | ] 34 | }); -------------------------------------------------------------------------------- /test/lib/rules/no-ext-multi-def.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Tests for no-ext-multi-def rule. 3 | * @author Nat Burns 4 | */ 5 | 6 | //------------------------------------------------------------------------------ 7 | // Requirements 8 | //------------------------------------------------------------------------------ 9 | 10 | var rule = require("../../../lib/rules/no-ext-multi-def"); 11 | var RuleTester = require("eslint").RuleTester; 12 | var tester = new RuleTester(); 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | tester.run("no-ext-multi-def", rule, { 19 | valid: [ 20 | "Ext.define('App.Single', {});", 21 | "Ext.define('App.Single', { constructor: function() { Ext.define('Dynamic' + Ext.id(), {}); } });" 22 | ], 23 | invalid: [ 24 | { 25 | code: "Ext.define('App.First', {}); Ext.define('App.Second', {});", 26 | errors: [ 27 | { 28 | message: "Only one class definition is allowed per file.", 29 | type: "CallExpression" 30 | } 31 | ] 32 | }, 33 | { 34 | code: "Ext.define('App.First', {}); Ext.define('App.Second', {}); Ext.define('App.Third', {});", 35 | errors: [ 36 | { 37 | message: "Only one class definition is allowed per file.", 38 | type: "CallExpression" 39 | }, 40 | { 41 | message: "Only one class definition is allowed per file.", 42 | type: "CallExpression" 43 | } 44 | ] 45 | } 46 | ] 47 | }); --------------------------------------------------------------------------------