How to call an EventType on a goog.ui.tree.Basenode? - events

I am constructing a tree using the Google Closure Library. Now I want the nodes to expand on a single mouseclick, but I seem not to get it working.
I've tried calling goog.ui.component.EventType.SELECT, but it won't work.
At my tree-component class I've added the following event:
goog.events.listen(item, [goog.ui.Component.EventType.SELECT, goog.ui.tree.BaseNode.EventType.EXPAND], this.dispatchEvent, false, this);
And at my class calling the function i've added:
goog.events.listen(this._tree, [goog.ui.Component.EventType.SELECT, goog.ui.tree.BaseNode.EventType.EXPAND], this.treeClick, false, this)
Any suggestions on how I could expand my node with a single click?

I see that BaseNode is screwing up any click events:
/**
* Handles a click event.
* #param {!goog.events.BrowserEvent} e The browser event.
* #protected
* #suppress {underscore}
*/
goog.ui.tree.BaseNode.prototype.onClick_ = goog.events.Event.preventDefault;
When adding this code to the goog/demos/tree/demo.html:
goog.ui.tree.BaseNode.prototype.onClick_ = function (e) {
var qq = this.expanded_?this.collapse():this.expand();
};
The tree control expands and collapses on one click.
Tried to extend goog.ui.tree.TreeControl and override createNode to return a custom goog.ui.tree.TreeNode that overrides onClick but could not do it without getting errors. In theory you could create your custom TreeControl that expands and collapses on one click.
If you want to support non collapsable content and other features I guess you have to trigger some sort of event instead of just extend or callapse the TreeNode.
[update]
After some fiddling I got it working by subclassing TreeControl and TreeNode added the following code to goog/demos/tree/demo.html
/**
* This creates a myTreeControl object. A tree control provides a way to
* view a hierarchical set of data.
* #param {string} html The HTML content of the node label.
* #param {Object=} opt_config The configuration for the tree. See
* goog.ui.tree.TreeControl.defaultConfig. If not specified, a default config
* will be used.
* #param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
* #constructor
* #extends {goog.ui.tree.BaseNode}
*/
var myTreeControl = function (html, opt_config, opt_domHelper) {
goog.ui.tree.TreeControl.call(this, html, opt_config, opt_domHelper);
};
goog.inherits(myTreeControl, goog.ui.tree.TreeControl);
/**
* Creates a new myTreeNode using the same config as the root.
* myTreeNode responds on single clicks
* #param {string} html The html content of the node label.
* #return {goog.ui.tree.TreeNode} The new item.
* #override
*/
myTreeControl.prototype.createNode = function (html) {
return new myTreeNode(html || '', this.getConfig(),
this.getDomHelper());
};
/**
* A single node in the myTreeControl.
* #param {string} html The html content of the node label.
* #param {Object=} opt_config The configuration for the tree. See
* goog.ui.tree.TreeControl.defaultConfig. If not specified, a default config
* will be used.
* #param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
* #constructor
* #extends {goog.ui.tree.BaseNode}
*/
var myTreeNode = function (html, opt_config, opt_domHelper) {
goog.ui.tree.TreeNode.call(this,html, opt_config, opt_domHelper)
}
goog.inherits(myTreeNode, goog.ui.tree.TreeNode);
/**
* Handles a click event.
* #param {!goog.events.BrowserEvent} e The browser event.
* #override
*/
myTreeNode.prototype.onClick_ = function (e) {
goog.base(this, "onClick_", e);
this.onDoubleClick_(e);
};
Changed the creation of the tree variable:
tree = new myTreeControl('root', treeConfig);
Works on single clicks and have not noticed any other things breaking. I've added the annotations so it'll compile easier. You might put the declarations in a separate file with a goog.provide.
Too bad the handleMouseEvent_ of TreeControl is private or you'll just override that one but you can't without changing either TreeControl source or getting compile errors/warnings. Ach wel, jammer.

Related

Getting the currently selected element in CKEditor 5

I am creating a CKEditor 5 plugin for adding an id attribute to arbitary elements. I have taken a lot of inspiration from the TextAlternative plugin for Images (if you're not familiar with how it works I'd sugguest taking a look.
I am recieving the following error: Cannot read property 'is' of null.
As part of my UI class, I have the following:
if ( !this._isInBalloon ) {
this._balloon.add( {
view: this._form,
position: getBalloonPositionData( editor )
} );
}
With getBalloonPositionData being:
/**
* Returns the positioning options that control the geometry of the
* {#link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect
* to the selected element in the editor content.
*
* #param {module:core/editor/editor~Editor} editor The editor instance.
* #returns {module:utils/dom/position~Options}
*/
export function getBalloonPositionData( editor ) {
const editingView = editor.editing.view;
const defaultPositions = BalloonPanelView.defaultPositions;
const t = editor.model.document.selection.getSelectedElement(); // ISSUE STARTS HERE
return {
target: editingView.domConverter.viewToDom( t ),
positions: [
defaultPositions.northArrowSouth,
defaultPositions.northArrowSouthWest,
defaultPositions.northArrowSouthEast,
defaultPositions.southArrowNorth,
defaultPositions.southArrowNorthWest,
defaultPositions.southArrowNorthEast
]
};
}
The line:
const t = editor.model.document.selection.getSelectedElement(); is where the issue starts. This method of getting the selected element was taken from elsewhere and I've seen it used in many other plugins.
I have tested with different "elements" selected and it always gets assigned null.
The full code is available # https://github.com/rhysstubbs/ckeditor5-build-classic on the branch feature/add-id-attributes-to-elements.
Any help would be great, TIA.

VSCode - Reference a type of a module from JS

Using Visual Studio Code for JS programming I can access some features from typescript; since the editor will parse all .d.ts files around, it'll help me with variable types. For example it does recognize the following:
any.js
/**
* #param {string} s
* #return {Promise<Person>}
*/
function foo(s){ ... }
foo('Jhon').then((p) => p.name )
index.d.ts
interface Person {
name: string
surname: string
}
Now, I want to access types (interfaces, classes... whatever) declared in node.d.ts declaration file; for example it declares the module stream which declares the Readable interface.
I'm looking for something like this:
const stream = require('stream')
/**
* #param {stream.Readable} stream
*/
function goo(stream) { ... }
But that does not work.I've tried with:
{internal.Readable}
{stream.Readable}
{Node.stream.Readable}
{Node.Readable}
{Node.internal.Readable}
As of VS Code 1.18, this is a limitation when using require with JSDoc types. I've opened this issue to track this specifically
Some possible workarounds:
Use import:
import * as stream from 'stream'
/**
* #param {stream.Readable} stream
*/
function goo(stream) { ... }
or import Readable explicitly:
const stream = require('stream')
const {Readable} = require('stream')
/**
* #param {Readable} stream
*/
function goo(stream) { ... }
https://github.com/Microsoft/TypeScript/issues/14377 also tracks allowing you to specify module imports in jsdocs directly.

What is the difference between Rx.Observable subscribe and forEach

After creating an Observable like so
var source = Rx.Observable.create(function(observer) {...});
What is the difference between subscribe
source.subscribe(function(x) {});
and forEach
source.forEach(function(x) {});
In the ES7 spec, which RxJS 5.0 follows (but RxJS 4.0 does not), the two are NOT the same.
subscribe
public subscribe(observerOrNext: Observer | Function, error: Function, complete: Function): Subscription
Observable.subscribe is where you will do most of your true Observable handling. It returns a subscription token, which you can use to cancel your subscription. This is important when you do not know the duration of the events/sequence you have subscribed to, or if you may need to stop listening before a known duration.
forEach
public forEach(next: Function, PromiseCtor?: PromiseConstructor): Promise
Observable.forEach returns a promise that will either resolve or reject when the Observable completes or errors. It is intended to clarify situations where you are processing an observable sequence of bounded/finite duration in a more 'synchronous' manner, such as collating all the incoming values and then presenting once, by handling the promise.
Effectively, you can act on each value, as well as error and completion events either way. So the most significant functional difference is the inability to cancel a promise.
I just review the latest code available, technically the code of foreach is actually calling subscribe in RxScala, RxJS, and RxJava. It doesn't seems a big different. They now have a return type allowing user to have an way for stopping a subscription or similar.
When I work on the RxJava earlier version, the subscribe has a subscription return, and forEach is just a void. Which you may see some different answer due to the changes.
/**
* Subscribes to the [[Observable]] and receives notifications for each element.
*
* Alias to `subscribe(T => Unit)`.
*
* $noDefaultScheduler
*
* #param onNext function to execute for each item.
* #throws java.lang.IllegalArgumentException if `onNext` is null
* #throws rx.exceptions.OnErrorNotImplementedException if the [[Observable]] tries to call `onError`
* #since 0.19
* #see ReactiveX operators documentation: Subscribe
*/
def foreach(onNext: T => Unit): Unit = {
asJavaObservable.subscribe(onNext)
}
def subscribe(onNext: T => Unit): Subscription = {
asJavaObservable.subscribe(scalaFunction1ProducingUnitToAction1(onNext))
}
/**
* Subscribes an o to the observable sequence.
* #param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
* #param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
* #param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
* #returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
*/
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
return this._subscribe(typeof oOrOnNext === 'object' ?
oOrOnNext :
observerCreate(oOrOnNext, onError, onCompleted));
};
/**
* Subscribes to the {#link Observable} and receives notifications for each element.
* <p>
* Alias to {#link #subscribe(Action1)}
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{#code forEach} does not operate by default on a particular {#link Scheduler}.</dd>
* </dl>
*
* #param onNext
* {#link Action1} to execute for each item.
* #throws IllegalArgumentException
* if {#code onNext} is null
* #throws OnErrorNotImplementedException
* if the Observable calls {#code onError}
* #see ReactiveX operators documentation: Subscribe
*/
public final void forEach(final Action1<? super T> onNext) {
subscribe(onNext);
}
public final Disposable forEach(Consumer<? super T> onNext) {
return subscribe(onNext);
}

Create java-like document for function in IOS (Xcode)

I'm beginner with IOS developing and I'm using Xcode. In java (android), I can create document for a function like below:
/**
* Get the index object in list of object and try to catch
* {#link IndexOutOfBoundsException}
*
* #param list
* of object: {#link List}
* #param index
* of ojbect: {#link Integer}
* #return Object or null if {#link IndexOutOfBoundsException} occurs
*/
public static <T> T getIndexObject(List<T> list, int index) {
T object = null;
try {
object = list.get(index);
} catch (IndexOutOfBoundsException e) {
return null;
}
return object;
}
When I create document as above (in Java), every time when I hover the mouse over the function (used in every where), I will see the document of that function. How's about IOS in Xcode? I know Doxygen, but It only generate HTML files (that not what I want). I want document like default document of every function that provided by Apple (when Ctrl + click on a function of IOS SDK)? Can I do it? And how? Thanks!!
Use AppleDoc. They have an article on their site that explains how to integrate with Xcode: http://gentlebytes.com/appledoc-docs-examples-xcode/, basically, you use:
appledoc
--project-name appledoc
--project-company "Gentle Bytes"
--company-id com.gentlebytes
--output ~/help
--logformat xcode
.
to generate the documents. You can also do the normal HTML in addition. It's free and looks a lot like Apple's documentation.

Does Closure Library have an equivalent to jQuery.live?

In jQuery I can use live() to add event listeners, even for elements that don't exist yet:
jQuery('a[href*="/item/"]', pageContent).live('click', preLoadAjaxPage);
Does Closure Library have an equivalent?
goog.events.EventType doesn't have any "DOM change" event, so I can not do goog.events.listen(goog.dom.getDocument(), goog.events.EventType.DOM_CHANGE, addEventListenersAgain) or similar.
I followed #Felix Kling's suggestion and registered the event handler at root:
goog.events.listen(document.body, goog.events.EventType.CLICK,
/**
* #param {goog.events.BrowserEvent} event
*/
function(event) {
var realEvent = event.event_;
var el = /** #type {HTMLAnchorElement} */ (event).target;
if (el.tagName.toLowerCase() == 'a' && (href matches pattern)) {
// ...
}
});

Resources