]>
git.wh0rd.org - tt-rss.git/blob - lib/dijit/_editor/_Plugin.js.uncompressed.js
1 define("dijit/_editor/_Plugin", [
2 "dojo/_base/connect", // connect.connect
3 "dojo/_base/declare", // declare
4 "dojo/_base/lang", // lang.mixin, lang.hitch
6 ], function(connect
, declare
, lang
, Button
){
9 // dijit/_editor/_Plugin
11 // Base class for a "plugin" to the editor, which is usually
12 // a single button on the Toolbar and some associated code
15 var _Plugin
= declare("dijit._editor._Plugin", null, {
17 // Base class for a "plugin" to the editor, which is usually
18 // a single button on the Toolbar and some associated code
20 constructor: function(/*Object?*/args
){
21 this.params
= args
|| {};
22 lang
.mixin(this, this.params
);
24 this._attrPairNames
= {};
27 // editor: [const] dijit.Editor
28 // Points to the parent editor
31 // iconClassPrefix: [const] String
32 // The CSS class name for the button node is formed from `iconClassPrefix` and `command`
33 iconClassPrefix
: "dijitEditorIcon",
35 // button: dijit._Widget?
36 // Pointer to `dijit.form.Button` or other widget (ex: `dijit.form.FilteringSelect`)
37 // that is added to the toolbar to control this plugin.
38 // If not specified, will be created on initialization according to `buttonClass`
42 // String like "insertUnorderedList", "outdent", "justifyCenter", etc. that represents an editor command.
43 // Passed to editor.execCommand() if `useDefaultCommand` is true.
46 // useDefaultCommand: Boolean
47 // If true, this plugin executes by calling Editor.execCommand() with the argument specified in `command`.
48 useDefaultCommand
: true,
50 // buttonClass: Widget Class
51 // Class of widget (ex: dijit.form.Button or dijit.form.FilteringSelect)
52 // that is added to the toolbar to control this plugin.
53 // This is used to instantiate the button, unless `button` itself is specified directly.
57 // Flag to indicate if this plugin has been disabled and should do nothing
58 // helps control button state, among other things. Set via the setter api.
61 getLabel: function(/*String*/key
){
63 // Returns the label to use for the button
66 return this.editor
.commands
[key
]; // String
69 _initButton: function(){
71 // Initialize the button or other widget that will control this plugin.
72 // This code only works for plugins controlling built-in commands in the editor.
74 // protected extension
75 if(this.command
.length
){
76 var label
= this.getLabel(this.command
),
78 className
= this.iconClassPrefix
+" "+this.iconClassPrefix
+ this.command
.charAt(0).toUpperCase() + this.command
.substr(1);
80 var props
= lang
.mixin({
86 dropDown
: this.dropDown
,
88 }, this.params
|| {});
89 this.button
= new this.buttonClass(props
);
92 if(this.get("disabled") && this.button
){
93 this.button
.set("disabled", this.get("disabled"));
99 // Destroy this plugin
102 while(h
= this._connects
.pop()){ h
.remove(); }
104 this.dropDown
.destroyRecursive();
108 connect: function(o
, f
, tf
){
110 // Make a connect.connect() that is automatically disconnected when this plugin is destroyed.
111 // Similar to `dijit._Widget.connect`.
114 this._connects
.push(connect
.connect(o
, f
, this, tf
));
117 updateState: function(){
119 // Change state of the plugin to respond to events in the editor.
121 // This is called on meaningful events in the editor, such as change of selection
122 // or caret position (but not simple typing of alphanumeric keys). It gives the
123 // plugin a chance to update the CSS of its button.
125 // For example, the "bold" plugin will highlight/unhighlight the bold button depending on whether the
126 // characters next to the caret are bold or not.
128 // Only makes sense when `useDefaultCommand` is true, as it calls Editor.queryCommandEnabled(`command`).
132 if(!e
|| !e
.isLoaded
|| !c
.length
){ return; }
133 var disabled
= this.get("disabled");
136 enabled
= !disabled
&& e
.queryCommandEnabled(c
);
137 if(this.enabled
!== enabled
){
138 this.enabled
= enabled
;
139 this.button
.set('disabled', !enabled
);
141 if(typeof this.button
.checked
== 'boolean'){
142 checked
= e
.queryCommandState(c
);
143 if(this.checked
!== checked
){
144 this.checked
= checked
;
145 this.button
.set('checked', e
.queryCommandState(c
));
149 console
.log(e
); // FIXME: we shouldn't have debug statements in our code. Log as an error?
154 setEditor: function(/*dijit.Editor*/ editor
){
156 // Tell the plugin which Editor it is associated with.
158 // TODO: refactor code to just pass editor to constructor.
160 // FIXME: detach from previous editor!!
161 this.editor
= editor
;
163 // FIXME: prevent creating this if we don't need to (i.e., editor can't handle our command)
166 // Processing for buttons that execute by calling editor.execCommand()
167 if(this.button
&& this.useDefaultCommand
){
168 if(this.editor
.queryCommandAvailable(this.command
)){
169 this.connect(this.button
, "onClick",
170 lang
.hitch(this.editor
, "execCommand", this.command
, this.commandArg
)
173 // hide button because editor doesn't support command (due to browser limitations)
174 this.button
.domNode
.style
.display
= "none";
178 this.connect(this.editor
, "onNormalizedDisplayChanged", "updateState");
181 setToolbar: function(/*dijit.Toolbar*/ toolbar
){
183 // Tell the plugin to add it's controller widget (often a button)
184 // to the toolbar. Does nothing if there is no controller widget.
186 // TODO: refactor code to just pass toolbar to constructor.
189 toolbar
.addChild(this.button
);
191 // console.debug("adding", this.button, "to:", toolbar);
194 set: function(/* attribute */ name
, /* anything */ value
){
196 // Set a property on a plugin
198 // The property to set.
200 // The value to set in the property.
202 // Sets named properties on a plugin which may potentially be handled by a
203 // setter in the plugin.
204 // For example, if the plugin has a properties "foo"
205 // and "bar" and a method named "_setFooAttr", calling:
206 // | plugin.set("foo", "Howdy!");
207 // would be equivalent to writing:
208 // | plugin._setFooAttr("Howdy!");
210 // | plugin.set("bar", 3);
211 // would be equivalent to writing:
214 // set() may also be called with a hash of name/value pairs, ex:
219 // This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
220 if(typeof name
=== "object"){
222 this.set(x
, name
[x
]);
226 var names
= this._getAttrNames(name
);
228 // use the explicit setter
229 var result
= this[names
.s
].apply(this, Array
.prototype.slice
.call(arguments
, 1));
231 this._set(name
, value
);
233 return result
|| this;
238 // Get a property from a plugin.
240 // The property to get.
242 // Get a named property from a plugin. The property may
243 // potentially be retrieved via a getter method. If no getter is defined, this
244 // just retrieves the object's property.
245 // For example, if the plugin has a properties "foo"
246 // and "bar" and a method named "_getFooAttr", calling:
247 // | plugin.get("foo");
248 // would be equivalent to writing:
249 // | plugin._getFooAttr();
251 // | plugin.get("bar");
252 // would be equivalent to writing:
254 var names
= this._getAttrNames(name
);
255 return this[names
.g
] ? this[names
.g
]() : this[name
];
258 _setDisabledAttr: function(disabled
){
260 // Function to set the plugin state and call updateState to make sure the
261 // button is updated appropriately.
262 this.disabled
= disabled
;
266 _getAttrNames: function(name
){
268 // Helper function for get() and set().
269 // Caches attribute name values so we don't do the string ops every time.
273 var apn
= this._attrPairNames
;
274 if(apn
[name
]){ return apn
[name
]; }
275 var uc
= name
.charAt(0).toUpperCase() + name
.substr(1);
276 return (apn
[name
] = {
282 _set: function(/*String*/ name
, /*anything*/ value
){
284 // Helper function to set new value for specified attribute
289 // Hash mapping plugin name to factory, used for registering plugins
290 _Plugin
.registry
= {};