Google closure library goog.forwardDeclare namespace javascript - javascript

I have some problem, and I sure community can help me )))
For Example: I have the next javascript files
file1.js
goog.provide('namespace.ModuleName');
goog.require('namespace.ModuleName.Item')
/**
* #param {Object} args
*#constructor
*/
namespace.ModuleName = function(args) {
....
..Initialization..
...
var item = [];
item.push(new namespace.ModuleName.Item(args)) // THIS ERROR
}
/**
* #private
*/
namespace.ModuleName.prototype.MyMethod = function() {
...
...
...
}
The next part. I want create new file
file2.js
goog.provide('namespace.ModuleName.Item')
/**
* #param {Object} args
*#constructor
*/
namespace.ModuleName.Item = function(args) {
}
I have some problem because "namespace.ModuleName.Item" Doesn't know about namespace.ModuleName. I can fix it. I need write goog.require('namespace.ModuleName') below goog.provide('namespace.ModuleName.Item').
But I have again some problem. Google Closure compiler writes "Require LOOP" . I can delete line where "goog.require('namespace.ModuleName.Item')". But these solution is not correct
What's the correct way to name modules
I ask this question on google forum. Guys told me "use goog.forwardDeclare"
https://groups.google.com/forum/#!topic/closure-library-discuss/PptH2fzcs_M
I tried write goog.forwardDeclare('namespace.ModuleName') above\below goog.provide('namespace.ModuleName.Item'). But it it's not worked for me. Can you help me ? Please. Or maybe write some examples. How use goog.forwardDeclare.

Related

Javascript Dot-Syntax function disappears in listen callback

I'm trying to update Annotorious (https://annotorious.github.io/#) to the latest version of Closure / Javascript.
When I compile it with "SIMPLE" optimizations, dot-syntax functions seem to disappear when goog.events.listen callbacks are invoked. Here's an example:
Here's the "main":
goog.provide('annotorious.Annotorious');
...
/**
* The main entrypoint to the application. The Annotorious class is instantiated exactly once,
* and added to the global window object as 'window.anno'. It exposes the external JavaScript API
* and internally manages the 'modules'. (Each module is responsible for one particular media
* type - image, OpenLayers, etc.)
* #constructor
*/
annotorious.Annotorious = function() {
/** #private **/
this._isInitialized = false;
/** #private **/
this._modules = [ new annotorious.mediatypes.image.ImageModule() ];
...
In another file (they're all compiled together), we have this:
goog.provide('annotorious.Annotation');
goog.require('annotorious.shape');
/**
* A 'domain class' implementation of the external annotation interface.
* #param {string} src the source URL of the annotated object
* #param {string} text the annotation text
* #param {annotorious.shape.Shape} shape the annotated fragment shape
* #constructor
*/
annotorious.Annotation = function(src, text, shape) {
this.src = src;
this.text = text;
this.shapes = [ shape ];
this['context'] = document.URL; // Prevents dead code removal
}
So we start up the code, and at some point we end in the editor for the annotation, listening for a "Save" button:
goog.provide('annotorious.Editor');
....
/**
* Annotation edit form.
* #param {Object} annotator reference to the annotator
* #constructor
*/
annotorious.Editor = function(annotator) {
this.element = goog.soy.renderAsElement(annotorious.templates.editform);
....
/** #private **/
//this._btnSave = goog.dom.query('.annotorious-editor-button-save', this.element)[0];
this._btnSave = this.element.querySelector('.annotorious-editor-button-save');
...
goog.events.listen(this._btnSave, goog.events.EventType.CLICK, function(event) {
event.preventDefault();
var annotation = self.getAnnotation();
annotator.addAnnotation(annotation);
annotator.stopSelection();
if (self._original_annotation)
annotator.fireEvent(annotorious.events.EventType.ANNOTATION_UPDATED, annotation, annotator.getItem());
else
annotator.fireEvent(annotorious.events.EventType.ANNOTATION_CREATED, annotation, annotator.getItem());
self.close();
});
If I put a breakpoint at "goog.events.listen(this._btnSave...", and type "annotorious.Annotation", I get what I expect:
In fact, it has all kinds of methods:
Then I let the code go, and break in the listener (event.preventDefault();, etc, above):
Now, all the dot-syntax methods are gone.
This of course causes crashes later on.
All of these files are compiled together.
This happens for all callbacks - 'load' events, other ux callbacks, etc.
This must have worked in prior versions of Closure / JS.
What could be causing this?
Thanks!
Ok, I was able to resolve the problem by adding "--assume_function_wrapper" to the closure compiler command line.
Previously, I was compiling the package using Plovr. However, since Plovr hasn't been updated in a long time, I switched to using the closure compiler natively.
Apparently either Plovr provided '--assume_function_wrapper' internally or the version of the compiler Plovr used didn't break the functions as described.
As #john suggests above I'll bet '--assume_function_wrapper' keeps goog.provide from "destroying" namespaces by re-declaring them.

typedef of this variable doesn't produce warning

I want to produce a warning for a number if a string is assigned to it. So, I thought typedef of Closure might do this for me. I tried the following -
var Widget = function()
{
/** #typedef {number} */
this.size = null;
};
new Widget().size = "kaboom!"
When I compile it using http://closure-compiler.appspot.com/home it doesn't throw a warning or error. What am I doing wrong? And/or what other tool should I be using?
Turn the optimization up to Advanced in the closure compiler service to catch these warnings. You still won't see any for your example (well, you will see some, but not what you are expecting), because typedefs are used to define custom types. Also, you need to annotate your constructor. Run the following example in advanced mode and you will see your warnings. Instead of making a typedef for a simple thing like number, I would just use #type, but this example is to show you the proper use of typedef.
/** #typedef {number} */
var customType;
/** #constructor */
var Widget = function()
{
/** #type {customType} */
this.size = null;
};
new Widget().size = "kaboom!"

Organizing and Documenting Multi-File JavaScript Projects

I'm beginning a fairly large JavaScript project. The project will have everything exist within one or more namespaces, so only a sparse number of things will exist in the global scope (at the moment, there is only one thing).
In order to keep things organized, I would like to keep each class in its own file (much like you would other many other languages) instead of in "modules".
I built a little compilation script (with NodeJS) which will compile all of the files in to a single JavaScript file at the end of the day.
I thought I had a good method, but I'm trying to get JSDoc(3) to cooperate with me and not having a lot of luck, so I'm wondering if I'm maybe tackling this in the wrong way, or if there is some trick with JSDoc I'm missing.
In the source, each namespace is a folder and each class is a file of the same name.
Each class file looks something like this:
var BaseNS = BaseNS || {};
BaseNS.SubNS = BaseNS.SubNS || {};
BaseNS.SubNS.MyClass = (function() {
function MyClass() {
}
Object.defineProperties(MyClass.prototype, {
'someProp', {
getter: function() { return this._someProp = this._someProp || 0; },
setter: function(val) { this._someProp = val; }
}
// ... more
});
MyClass.prototype.someMethod = function() {};
// ... more
return MyClass;
}}());
When compiled together, my compilation script handles dependencies to get the classes in the correct order and also removed duplicate namespace declaration lines.
I think this method is relatively clean and straight-forward. The catch is, I can't figure out how to write the JSDoc documentation in a way which gives me things as I think they should be.
I would like to go with a "class-like" method for things. This is actually for an application which is largely removed from the DOM. Also, I'd like the entire project to be vanilla, modern JavaScript (i.e., no RequireJS, etc.)
Any ideas how to get this documented, or a better way to arrange things?
Thanks.
After playing around with various things for about four hours yesterday, I think I've figured out the optimal format, which combines nice efficent form while allowing for minimal comments to get things to parse properly.
"use strict";
/** #namespace */
var NS = NS || {};
/** #namespace */
NS.Sub = NS.Sub || {};
/**
* #class
*/
NS.Sub.SomeClass = (function(NS) {
/**
* #constructor
* #lends NS.Sub.SomeClass
*/
var SomeClass = function() {
/** #method */
this.someFunc = function(cookie) {
};
Object.defineProperties(this, /** #lends NS.Sub.SomeClass */ {
/**
* #type {number}
* #instance
*/
somePublicProp: {
getter: function() { return this._somePublicProp || 24; },
setter: function(val) { this._somePublicProp = val; }
}
});
};
return SomeClass;
})(NS);
If anyone has any recommendations on how to make this better, I'd love to hear them. In particular, I can't figure out a way to get rid of the need for var SomeClass; ... return SomeClass. I'd like to just return it directly (preferably without any name), but then JSDoc loses track of my method, which means more comments, which isn't cool.

requirejs exports doesn't work in firefox 15

I use a external library that uses requirejs I don't know
how its work but FileError is in the global scope in other browser
or in FF8 but in FF 14/15 says FileError not defined.
define(function (require, exports, module) {
"use strict";
var Async = require("utils/Async");
var NativeFileSystem = {
/**
* LOT OF CODE HERE
* ...
* ...
* ...
*/
/** class: FileError
*
* Implementation of HTML file API error code return class. Note that we don't
* actually define the error codes here--we rely on the browser's built-in FileError
* class's constants. In other words, external clients of this API should always
* use FileError.<constant-name>, not NativeFileSystem.FileError.<constant-name>.
*
* #constructor
* #param {number} code The error code to return with this FileError. Must be
* one of the codes defined in the FileError class.
*/
NativeFileSystem.FileError = function (code) {
this.code = code || 0;
};
/**
*THIS FIX THE PROBLEM BUT IT A HACK
*window.FileError = NativeFileSystem.FileError;
*/
// Define public API
exports.NativeFileSystem = NativeFileSystem;
});
Of course if I add window.FileError = NativeFileSystem.FileError; after the
function definition its work fine. But I don't want hack the library
The full source of the file is here
Brackets relies on the FileError class only for the error code constants.
The FileAPI is still a draft spec http://www.w3.org/TR/FileAPI/ and it appears they have changed FileError to DOMError in the time since we originally wrote NativeFileSystem. We could remove this dependency and define our own equivalent FileError constants to remove the dependency. We were attempting to model our API after the FileAPI, but it's been a moving target.

Using JSDoc with namespaces and a variant form of function definition

I've been trying to use JsDoc for documenting my javascript but I keep coming across this hurdle. It keeps saying "nothing to document, exiting"
Here is the peice of code I'm trying to document:
/**
* Container for all editing methods
* #namespace
*/
var FREdit = {
/**
* Toggle value for editing
* #type Number
*/
isToggleOn:0,
/**
* Initialize editing
*/
init: function(){
this.initPopups();
},
/**
* Function to enable editing
*/
enable: function(){
this.enableTitles();
this.isToggleOn = 1;
}
};
Above I'm using namespace. Even if I use a variant form of function definition in JavaScript, JSDoc doesn't seem to recognise it. Eg:
/**
* Just any function
*/
var any_function = function(){
};
Any idea how to get around this? Thanks!
Judging from your question I'm guessing you're using JSDoc.
The original JSDoc has been unsupported for a while now.
I suggest you use jsdoc-toolkit as it has much better support.
According to their documentation you can document the class pattern.
Take a look at their examples and you should be good to go!
Cheers!

Categories