From 1325935d1396fd9a37b378d5216b9980e2acf83a Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Thu, 30 Aug 2012 07:37:08 -0700 Subject: [PATCH] First pass at YUIDoc conversion Upgraded docs for ember-metal and added a custom theme with a few tweaks. --- .gitignore | 3 +- Gemfile | 1 - Gemfile.lock | 9 -- Rakefile | 76 +-------- docs/package.json | 7 + docs/yuidoc.json | 20 +++ packages/ember-metal/lib/accessors.js | 138 ++++++++-------- packages/ember-metal/lib/array.js | 11 +- packages/ember-metal/lib/binding.js | 104 +++++++----- packages/ember-metal/lib/computed.js | 94 +++++------ packages/ember-metal/lib/core.js | 108 +++++++------ packages/ember-metal/lib/events.js | 122 ++++++++++++--- packages/ember-metal/lib/main.js | 7 + packages/ember-metal/lib/map.js | 108 ++++++++++++- packages/ember-metal/lib/mixin.js | 91 ++++++++--- packages/ember-metal/lib/observer.js | 59 +++++-- packages/ember-metal/lib/platform.js | 34 ++-- packages/ember-metal/lib/properties.js | 36 +++-- packages/ember-metal/lib/run_loop.js | 148 ++++++++++-------- packages/ember-metal/lib/utils.js | 84 +++++----- packages/ember-metal/lib/watching.js | 60 +++---- .../ember-metal/tests/performance_test.js | 2 +- packages/ember/lib/main.js | 6 + 23 files changed, 796 insertions(+), 532 deletions(-) create mode 100644 docs/package.json create mode 100644 docs/yuidoc.json diff --git a/.gitignore b/.gitignore index 32d64a70301..85f6a23c01f 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,8 @@ assets/bpm_styles.css bin/ coverage dist -docs +docs/build +docs/node_modules lib/*/tests/all.js lib/*/tests/qunit* lib/bundler/man diff --git a/Gemfile b/Gemfile index 910af5e9549..13e81ffd727 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,5 @@ gem "uglifier", :git => "https://github.com/lautis/uglifier.git" group :development do gem "rack" gem "github_downloads", :git => "https://github.com/pangratz/github_downloads.git" - gem "ember-docs", :git => "https://github.com/emberjs/docs-generator.git" gem "kicker" end diff --git a/Gemfile.lock b/Gemfile.lock index 6fdc64dd869..0fc28dac86b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,3 @@ -GIT - remote: https://github.com/emberjs/docs-generator.git - revision: cfbc2a3aabc08de305224b290ad8f37f3ef5f847 - specs: - ember-docs (0.1) - rack - thor - GIT remote: https://github.com/lautis/uglifier.git revision: 45133bfdadc8f5056cb93423d2eedad3aed936bf @@ -80,7 +72,6 @@ PLATFORMS DEPENDENCIES colored - ember-docs! github_downloads! kicker rack diff --git a/Rakefile b/Rakefile index 634d27d5efe..d4c8b669d33 100644 --- a/Rakefile +++ b/Rakefile @@ -26,43 +26,6 @@ def upload_file(uploader, filename, description, file) end end -def docs_upload_task(name) - instance_eval <<-end_eval - namespace :upload do - file "tmp/#{name}" do - mkdir_p "tmp" - - Dir.chdir("tmp") do - sh "git clone git@heroku.com:#{name}.git" - end - end - - task :pull => "tmp/#{name}" do - Dir.chdir("tmp/#{name}") do - sh "git pull origin master" - end - end - - task :clean => :pull do - rm_rf "tmp/#{name}/html" - end - - file "tmp/#{name}/html" => ['docs:build', :clean] do - cp_r "docs", "tmp/#{name}/html" - end - - task :run => "tmp/#{name}/html" do - Dir.chdir "tmp/#{name}" do - sh "git add -A html && git commit -m 'Upload generated API docs' && git push origin master" - end - end - end - - desc "Upload docs to #{name}" - task :upload => 'upload:run' - end_eval -end - desc "Strip trailing whitespace for JavaScript files in packages" task :strip_whitespace do @@ -99,31 +62,6 @@ task :upload_latest => [:clean, :dist] do upload_file(uploader, 'ember-latest.js', "Ember.js Master", "dist/ember.js") end -namespace :docs do - def doc_args - "#{Dir.glob("packages/ember-*").join(' ')} -E #{Dir.glob("packages/ember-*/tests").join(' ')} -t docs.emberjs.com" - end - - desc "Preview Ember Docs (does not auto update)" - task :preview do - require "ember_docs/cli" - EmberDocs::CLI.start("preview #{doc_args}".split(' ')) - end - - desc "Build Ember Docs" - task :build do - require "ember_docs/cli" - EmberDocs::CLI.start("generate #{doc_args} -o docs".split(' ')) - end - - docs_upload_task("ember-edge-docs") - - desc "Remove Ember Docs" - task :clean do - rm_r "docs" - end -end - desc "Run tests with phantomjs" task :test, [:suite] => :dist do |t, args| require "colored" @@ -519,21 +457,11 @@ namespace :release do task :deploy => [:update] end - namespace :docs do - docs_upload_task("ember-docs") - - desc "Prepare docs for release" - task :prepare => [] - - desc "Deploy docs" - task :deploy => [:upload] - end - desc "Prepare Ember for new release" - task :prepare => [:clean, 'framework:prepare', 'starter_kit:prepare', 'examples:prepare', 'website:prepare', 'docs:prepare'] + task :prepare => [:clean, 'framework:prepare', 'starter_kit:prepare', 'examples:prepare', 'website:prepare'] desc "Deploy a new Ember release" - task :deploy => ['framework:deploy', 'starter_kit:deploy', 'examples:deploy', 'website:deploy', 'docs:deploy'] + task :deploy => ['framework:deploy', 'starter_kit:deploy', 'examples:deploy', 'website:deploy'] end diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000000..2196f4f90ca --- /dev/null +++ b/docs/package.json @@ -0,0 +1,7 @@ +{ + "name": "ember-docs", + "version": "0.0.1", + "dependencies": { + "yuidoc": "git://github.com/wagenet/yuidoc.git" + } +} diff --git a/docs/yuidoc.json b/docs/yuidoc.json new file mode 100644 index 00000000000..c9857f160f0 --- /dev/null +++ b/docs/yuidoc.json @@ -0,0 +1,20 @@ +{ + "name": "The Ember API", + "description": "The Ember API: a framework for building ambitious web applications", + "version": "1.0 pre", + "url": "http://emberjs.com/", + "options": { + "paths": [ + "../packages/ember/lib", + "../packages/ember-debug/lib", + "../packages/ember-metal/lib", + "../packages/ember-runtime/lib", + "../packages/ember-states/lib", + "../packages/ember-views/lib", + "../packages/ember-handlebars/lib", + "../packages/ember-routing/lib", + "../packages/ember-application/lib" + ], + "outdir": "./build" + } +} diff --git a/packages/ember-metal/lib/accessors.js b/packages/ember-metal/lib/accessors.js index 3a090efee36..d84cb40564f 100644 --- a/packages/ember-metal/lib/accessors.js +++ b/packages/ember-metal/lib/accessors.js @@ -8,11 +8,14 @@ require('ember-metal/core'); require('ember-metal/platform'); require('ember-metal/utils'); +/** +@module ember-metal +*/ + var META_KEY = Ember.META_KEY, get, set; var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER; -/** @private */ var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/; var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.\*]/; var HAS_THIS = /^this[\.\*]/; @@ -25,7 +28,30 @@ var FIRST_KEY = /^([^\.\*]+)/; // Otherwise simulate accessors by looking up the property directly on the // object. -/** @private */ +/** + Gets the value of a property on an object. If the property is computed, + the function will be invoked. If the property is not defined but the + object implements the unknownProperty() method then that will be invoked. + + If you plan to run on IE8 and older browsers then you should use this + method anytime you want to retrieve a property on an object that you don't + know for sure is private. (My convention only properties beginning with + an underscore '_' are considered private.) + + On all newer browsers, you only need to use this method to retrieve + properties if the property might not be defined on the object and you want + to respect the unknownProperty() handler. Otherwise you can ignore this + method. + + Note that if the obj itself is null, this method will simply return + undefined. + + @method get + @for Ember + @param {Object} obj The object to retrieve from. + @param {String} keyName The property key to retrieve + @return {Object} the property value or null. +*/ get = function get(obj, keyName) { // Helpers that operate with 'this' within an #each if (keyName === '') { @@ -62,7 +88,29 @@ get = function get(obj, keyName) { } }; -/** @private */ +/** + Sets the value of a property on an object, respecting computed properties + and notifying observers and other listeners of the change. If the + property is not defined but the object implements the unknownProperty() + method then that will be invoked as well. + + If you plan to run on IE8 and older browsers then you should use this + method anytime you want to set a property on an object that you don't + know for sure is private. (My convention only properties beginning with + an underscore '_' are considered private.) + + On all newer browsers, you only need to use this method to set + properties if the property might not be defined on the object and you want + to respect the unknownProperty() handler. Otherwise you can ignore this + method. + + @method set + @for Ember + @param {Object} obj The object to modify. + @param {String} keyName The property key to set + @param {Object} value The value to set + @return {Object} the passed value. +*/ set = function set(obj, keyName, value, tolerant) { if (typeof obj === 'string') { Ember.assert("Path '" + obj + "' must be global if no obj is given.", IS_GLOBAL.test(obj)); @@ -118,13 +166,11 @@ set = function set(obj, keyName, value, tolerant) { return value; }; -/** @private */ function firstKey(path) { return path.match(FIRST_KEY)[0]; } // assumes path is already normalized -/** @private */ function normalizeTuple(target, path) { var hasThis = HAS_THIS.test(path), isGlobal = !hasThis && IS_GLOBAL_PATH.test(path), @@ -145,7 +191,6 @@ function normalizeTuple(target, path) { return [ target, path ]; } -/** @private */ function getPath(root, path) { var hasThis, parts, tuple, idx, len; @@ -173,7 +218,6 @@ function getPath(root, path) { return root; } -/** @private */ function setPath(root, path, value, tolerant) { var keyName; @@ -209,13 +253,11 @@ function setPath(root, path, value, tolerant) { paths (i.e. a path beginning with a captial letter not defined on the target) and * separators. - @param {Object} target - The current target. May be null. - - @param {String} path - A path on the target or a global property path. - - @returns {Array} a temporary array with the normalized target/path pair. + @method normalizeTuple + @for Ember + @param {Object} target The current target. May be null. + @param {String} path A path on the target or a global property path. + @return {Array} a temporary array with the normalized target/path pair. */ Ember.normalizeTuple = function(target, path) { return normalizeTuple(target, path); @@ -229,66 +271,9 @@ Ember.getWithDefault = function(root, key, defaultValue) { }; -/** - @function - - Gets the value of a property on an object. If the property is computed, - the function will be invoked. If the property is not defined but the - object implements the unknownProperty() method then that will be invoked. - - If you plan to run on IE8 and older browsers then you should use this - method anytime you want to retrieve a property on an object that you don't - know for sure is private. (My convention only properties beginning with - an underscore '_' are considered private.) - - On all newer browsers, you only need to use this method to retrieve - properties if the property might not be defined on the object and you want - to respect the unknownProperty() handler. Otherwise you can ignore this - method. - - Note that if the obj itself is null, this method will simply return - undefined. - - @param {Object} obj - The object to retrieve from. - - @param {String} keyName - The property key to retrieve - - @returns {Object} the property value or null. -*/ Ember.get = get; Ember.getPath = Ember.deprecateFunc('getPath is deprecated since get now supports paths', Ember.get); -/** - @function - - Sets the value of a property on an object, respecting computed properties - and notifying observers and other listeners of the change. If the - property is not defined but the object implements the unknownProperty() - method then that will be invoked as well. - - If you plan to run on IE8 and older browsers then you should use this - method anytime you want to set a property on an object that you don't - know for sure is private. (My convention only properties beginning with - an underscore '_' are considered private.) - - On all newer browsers, you only need to use this method to set - properties if the property might not be defined on the object and you want - to respect the unknownProperty() handler. Otherwise you can ignore this - method. - - @param {Object} obj - The object to modify. - - @param {String} keyName - The property key to set - - @param {Object} value - The value to set - - @returns {Object} the passed value. -*/ Ember.set = set; Ember.setPath = Ember.deprecateFunc('setPath is deprecated since set now supports paths', Ember.set); @@ -298,6 +283,12 @@ Ember.setPath = Ember.deprecateFunc('setPath is deprecated since set now support This is primarily used when syncing bindings, which may try to update after an object has been destroyed. + + @method trySet + @for Ember + @param {Object} obj The object to modify. + @param {String} keyName The property key to set + @param {Object} value The value to set */ Ember.trySet = function(root, path, value) { return set(root, path, value, true); @@ -308,8 +299,11 @@ Ember.trySetPath = Ember.deprecateFunc('trySetPath has been renamed to trySet', Returns true if the provided path is global (e.g., "MyApp.fooController.bar") instead of local ("foo.bar.baz"). + @method isGlobalPath + @for Ember + @private @param {String} path - @returns Boolean + @return Boolean */ Ember.isGlobalPath = function(path) { return IS_GLOBAL.test(path); diff --git a/packages/ember-metal/lib/array.js b/packages/ember-metal/lib/array.js index 9e05d2febcc..24b5727680b 100644 --- a/packages/ember-metal/lib/array.js +++ b/packages/ember-metal/lib/array.js @@ -1,19 +1,21 @@ /*jshint newcap:false*/ +/** +@module ember-metal +*/ + // NOTE: There is a bug in jshint that doesn't recognize `Object()` without `new` // as being ok unless both `newcap:false` and not `use strict`. // https://github.com/jshint/jshint/issues/392 // Testing this is not ideal, but we want to use native functions // if available, but not to use versions created by libraries like Prototype -/** @private */ var isNativeFunc = function(func) { // This should probably work in all browsers likely to have ES5 array methods return func && Function.prototype.toString.call(func).indexOf('[native code]') > -1; }; // From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map -/** @private */ var arrayMap = isNativeFunc(Array.prototype.map) ? Array.prototype.map : function(fun /*, thisp */) { //"use strict"; @@ -39,7 +41,6 @@ var arrayMap = isNativeFunc(Array.prototype.map) ? Array.prototype.map : functio }; // From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach -/** @private */ var arrayForEach = isNativeFunc(Array.prototype.forEach) ? Array.prototype.forEach : function(fun /*, thisp */) { //"use strict"; @@ -61,7 +62,6 @@ var arrayForEach = isNativeFunc(Array.prototype.forEach) ? Array.prototype.forEa } }; -/** @private */ var arrayIndexOf = isNativeFunc(Array.prototype.indexOf) ? Array.prototype.indexOf : function (obj, fromIndex) { if (fromIndex === null || fromIndex === undefined) { fromIndex = 0; } else if (fromIndex < 0) { fromIndex = Math.max(0, this.length + fromIndex); } @@ -105,17 +105,14 @@ var utils = Ember.EnumerableUtils = { if (Ember.SHIM_ES5) { if (!Array.prototype.map) { - /** @private */ Array.prototype.map = arrayMap; } if (!Array.prototype.forEach) { - /** @private */ Array.prototype.forEach = arrayForEach; } if (!Array.prototype.indexOf) { - /** @private */ Array.prototype.indexOf = arrayIndexOf; } } diff --git a/packages/ember-metal/lib/binding.js b/packages/ember-metal/lib/binding.js index 53124deaa81..45d183d52eb 100644 --- a/packages/ember-metal/lib/binding.js +++ b/packages/ember-metal/lib/binding.js @@ -11,17 +11,21 @@ require('ember-metal/observer'); // addObserver, removeObserver require('ember-metal/run_loop'); // Ember.run.schedule require('ember-metal/map'); +/** +@module ember-metal +*/ + // .......................................................... // CONSTANTS // /** - @static - Debug parameter you can turn on. This will log all bindings that fire to the console. This should be disabled in production code. Note that you can also enable this from the console or temporarily. + @property LOG_BINDINGS + @for Ember @type Boolean @default false */ @@ -33,7 +37,6 @@ var get = Ember.get, isGlobalPath = Ember.isGlobalPath; -/** @private */ function getWithGlobals(obj, path) { return get(isGlobalPath(path) ? window : obj, path); } @@ -42,7 +45,6 @@ function getWithGlobals(obj, path) { // BINDING // -/** @private */ var Binding = function(toPath, fromPath) { this._direction = 'fwd'; this._from = fromPath; @@ -50,10 +52,17 @@ var Binding = function(toPath, fromPath) { this._directionMap = Ember.Map.create(); }; -Binding.prototype = /** @scope Ember.Binding.prototype */ { +/** +@class Binding +@namespace Ember +*/ + +Binding.prototype = { /** This copies the Binding so it can be connected to another object. - @returns {Ember.Binding} + + @method copy + @return {Ember.Binding} */ copy: function () { var copy = new Binding(this._to, this._from); @@ -74,8 +83,9 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ { you pass when you connect() the binding. It follows the same rules as `get()` - see that method for more information. + @method from @param {String} propertyPath the property path to connect to - @returns {Ember.Binding} receiver + @return {Ember.Binding} receiver */ from: function(path) { this._from = path; @@ -91,8 +101,9 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ { you pass when you connect() the binding. It follows the same rules as `get()` - see that method for more information. + @method to @param {String|Tuple} propertyPath A property path or tuple - @returns {Ember.Binding} this + @return {Ember.Binding} this */ to: function(path) { this._to = path; @@ -105,14 +116,14 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ { means that if you change the "to" side directly, the "from" side may have a different value. - @returns {Ember.Binding} receiver + @method oneWay + @return {Ember.Binding} receiver */ oneWay: function() { this._oneWay = true; return this; }, - /** @private */ toString: function() { var oneWay = this._oneWay ? '[oneWay]' : ''; return "Ember.Binding<" + guidFor(this) + ">(" + this._from + " -> " + this._to + ")" + oneWay; @@ -127,8 +138,9 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ { changes. This method will raise an exception if you have not set the from/to properties yet. + @method connect @param {Object} obj The root object for this binding. - @returns {Ember.Binding} this + @return {Ember.Binding} this */ connect: function(obj) { Ember.assert('Must pass a valid object to Ember.Binding.connect()', !!obj); @@ -151,10 +163,9 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ { Disconnects the binding instance. Changes will no longer be relayed. You will not usually need to call this method. - @param {Object} obj - The root object you passed when connecting the binding. - - @returns {Ember.Binding} this + @method disconnect + @param {Object} obj The root object you passed when connecting the binding. + @return {Ember.Binding} this */ disconnect: function(obj) { Ember.assert('Must pass a valid object to Ember.Binding.disconnect()', !!obj); @@ -176,17 +187,16 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ { // PRIVATE // - /** @private - called when the from side changes */ + /* called when the from side changes */ fromDidChange: function(target) { this._scheduleSync(target, 'fwd'); }, - /** @private - called when the to side changes */ + /* called when the to side changes */ toDidChange: function(target) { this._scheduleSync(target, 'back'); }, - /** @private */ _scheduleSync: function(obj, dir) { var directionMap = this._directionMap; var existingDir = directionMap.get(obj); @@ -204,7 +214,6 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ { } }, - /** @private */ _sync: function(obj) { var log = Ember.LOG_BINDINGS; @@ -247,7 +256,6 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ { }; -/** @private */ function mixinProperties(to, from) { for (var key in from) { if (from.hasOwnProperty(key)) { @@ -256,11 +264,13 @@ function mixinProperties(to, from) { } } -mixinProperties(Binding, -/** @scope Ember.Binding */ { +mixinProperties(Binding, { /** - @see Ember.Binding.prototype.from + See {{#crossLink "Ember.Binding/from"}}{{/crossLink}} + + @method from + @static */ from: function() { var C = this, binding = new C(); @@ -268,7 +278,10 @@ mixinProperties(Binding, }, /** - @see Ember.Binding.prototype.to + See {{#crossLink "Ember.Binding/to"}}{{/crossLink}} + + @method to + @static */ to: function() { var C = this, binding = new C(); @@ -277,16 +290,17 @@ mixinProperties(Binding, /** Creates a new Binding instance and makes it apply in a single direction. - A one-way binding will relay changes on the "from" side object (supplies + A one-way binding will relay changes on the "from" side object (supplied as the `from` argument) the "to" side, but not the other way around. This means that if you change the "to" side directly, the "from" side may have a different value. + See {{#crossLink "Binding/oneWay"}}{{/crossLink}} + + @method oneWay @param {String} from from path. @param {Boolean} [flag] (Optional) passing nothing here will make the binding oneWay. You can - instead pass false to disable oneWay, making the binding two way again. - - @see Ember.Binding.prototype.oneWay + instead pass false to disable oneWay, making the binding two way again. */ oneWay: function(from, flag) { var C = this, binding = new C(null, from); @@ -296,8 +310,6 @@ mixinProperties(Binding, }); /** - @class - An Ember.Binding connects the properties of two objects so that whenever the value of one property changes, the other property will be changed also. @@ -395,30 +407,46 @@ mixinProperties(Binding, create bindings for you. You should always use the highest-level APIs available, even if you understand how it works underneath. + @class Binding + @namespace Ember @since Ember 0.9 */ Ember.Binding = Binding; + /** Global helper method to create a new binding. Just pass the root object along with a to and from path to create and connect the binding. - @param {Object} obj - The root object of the transform. + @method bind + @for Ember + @param {Object} obj The root object of the transform. - @param {String} to - The path to the 'to' side of the binding. Must be relative to obj. + @param {String} to The path to the 'to' side of the binding. + Must be relative to obj. - @param {String} from - The path to the 'from' side of the binding. Must be relative to obj or - a global path. + @param {String} from The path to the 'from' side of the binding. + Must be relative to obj or a global path. - @returns {Ember.Binding} binding instance + @return {Ember.Binding} binding instance */ Ember.bind = function(obj, to, from) { return new Ember.Binding(to, from).connect(obj); }; +/** + @method oneWay + @for Ember + @param {Object} obj The root object of the transform. + + @param {String} to The path to the 'to' side of the binding. + Must be relative to obj. + + @param {String} from The path to the 'from' side of the binding. + Must be relative to obj or a global path. + + @return {Ember.Binding} binding instance +*/ Ember.oneWay = function(obj, to, from) { return new Ember.Binding(to, from).oneWay().connect(obj); }; diff --git a/packages/ember-metal/lib/computed.js b/packages/ember-metal/lib/computed.js index a44498f3fde..faffecf5bb0 100644 --- a/packages/ember-metal/lib/computed.js +++ b/packages/ember-metal/lib/computed.js @@ -10,6 +10,9 @@ require('ember-metal/utils'); require('ember-metal/properties'); require('ember-metal/watching'); +/** +@module ember-metal +*/ Ember.warn("Computed properties will soon be cacheable by default. To enable this in your app, set `ENV.CP_DEFAULT_CACHEABLE = true`.", Ember.CP_DEFAULT_CACHEABLE); @@ -36,9 +39,7 @@ var get = Ember.get, // __emberproto__: SRC_OBJ // } -/** - @private - +/* This function returns a map of unique dependencies for a given object and key. */ @@ -57,11 +58,7 @@ function keysForDep(obj, depsMeta, depKey) { return keys; } -/** - @private - - return obj[META_KEY].deps - */ +/* return obj[META_KEY].deps */ function metaForDeps(obj, meta) { var deps = meta.deps; // If the current object has no dependencies... @@ -78,7 +75,6 @@ function metaForDeps(obj, meta) { return deps; } -/** @private */ function addDependentKeys(desc, obj, keyName, meta) { // the descriptor has a list of dependent keys, so // add all of its dependent keys. @@ -98,7 +94,6 @@ function addDependentKeys(desc, obj, keyName, meta) { } } -/** @private */ function removeDependentKeys(desc, obj, keyName, meta) { // the descriptor has a list of dependent keys, so // add all of its dependent keys. @@ -122,23 +117,21 @@ function removeDependentKeys(desc, obj, keyName, meta) { // COMPUTED PROPERTY // -/** @private */ +/** + @class ComputedProperty + @namespace Ember + @extends Ember.Descriptor + @constructor +*/ function ComputedProperty(func, opts) { this.func = func; this._cacheable = (opts && opts.cacheable !== undefined) ? opts.cacheable : Ember.CP_DEFAULT_CACHEABLE; this._dependentKeys = opts && opts.dependentKeys; } -/** - @constructor -*/ Ember.ComputedProperty = ComputedProperty; ComputedProperty.prototype = new Ember.Descriptor(); -/** - @extends Ember.ComputedProperty - @private -*/ var ComputedPropertyPrototype = ComputedProperty.prototype; /** @@ -158,11 +151,9 @@ var ComputedPropertyPrototype = ComputedProperty.prototype; Properties are cacheable by default. - @memberOf Ember.ComputedProperty.prototype - @name cacheable - @function + @method cacheable @param {Boolean} aFlag optional set to false to disable caching - @returns {Ember.ComputedProperty} receiver + @chainable */ ComputedPropertyPrototype.cacheable = function(aFlag) { this._cacheable = aFlag !== false; @@ -179,10 +170,8 @@ ComputedPropertyPrototype.cacheable = function(aFlag) { }.property().volatile() }); - @memberOf Ember.ComputedProperty.prototype - @name volatile - @function - @returns {Ember.ComputedProperty} receiver + @method volatile + @chainable */ ComputedPropertyPrototype.volatile = function() { return this.cacheable(false); @@ -201,11 +190,9 @@ ComputedPropertyPrototype.volatile = function() { }).property('firstName', 'lastName') }); - @memberOf Ember.ComputedProperty.prototype - @name property - @function - @param {String} path... zero or more property paths - @returns {Ember.ComputedProperty} receiver + @method property + @param {String} path* zero or more property paths + @chainable */ ComputedPropertyPrototype.property = function() { var args = []; @@ -234,11 +221,9 @@ ComputedPropertyPrototype.property = function() { exposes a public API for retrieving these values from classes, via the `metaForProperty()` function. - @memberOf Ember.ComputedProperty.prototype - @name meta - @function + @method meta @param {Hash} meta - @returns {Ember.ComputedProperty} property descriptor instance + @chainable */ ComputedPropertyPrototype.meta = function(meta) { @@ -250,7 +235,7 @@ ComputedPropertyPrototype.meta = function(meta) { } }; -/** @private - impl descriptor API */ +/* impl descriptor API */ ComputedPropertyPrototype.willWatch = function(obj, keyName) { // watch already creates meta for this instance var meta = obj[META_KEY]; @@ -269,7 +254,7 @@ ComputedPropertyPrototype.didUnwatch = function(obj, keyName) { } }; -/** @private - impl descriptor API */ +/* impl descriptor API */ ComputedPropertyPrototype.didChange = function(obj, keyName) { // _suspended is set via a CP.set to ensure we don't clear // the cached value set by the setter @@ -284,7 +269,7 @@ ComputedPropertyPrototype.didChange = function(obj, keyName) { } }; -/** @private - impl descriptor API */ +/* impl descriptor API */ ComputedPropertyPrototype.get = function(obj, keyName) { var ret, cache, meta; if (this._cacheable) { @@ -301,7 +286,7 @@ ComputedPropertyPrototype.get = function(obj, keyName) { return ret; }; -/** @private - impl descriptor API */ +/* impl descriptor API */ ComputedPropertyPrototype.set = function(obj, keyName, value) { var cacheable = this._cacheable, meta = metaFor(obj, cacheable), @@ -339,7 +324,7 @@ ComputedPropertyPrototype.set = function(obj, keyName, value) { return ret; }; -/** @private - called when property is defined */ +/* called when property is defined */ ComputedPropertyPrototype.setup = function(obj, keyName) { var meta = obj[META_KEY]; if (meta && meta.watching[keyName]) { @@ -347,7 +332,7 @@ ComputedPropertyPrototype.setup = function(obj, keyName) { } }; -/** @private - called before property is overridden */ +/* called before property is overridden */ ComputedPropertyPrototype.teardown = function(obj, keyName) { var meta = metaFor(obj); @@ -360,6 +345,7 @@ ComputedPropertyPrototype.teardown = function(obj, keyName) { return null; // no value to restore }; + /** This helper returns a new property descriptor that wraps the passed computed property function. You can use this helper to define properties @@ -370,10 +356,10 @@ ComputedPropertyPrototype.teardown = function(obj, keyName) { undefined you should set the value first. In either case return the current value of the property. - @param {Function} func - The computed property function. - - @returns {Ember.ComputedProperty} property descriptor instance + @method computed + @for Ember + @param {Function} func The computed property function. + @return {Ember.ComputedProperty} property descriptor instance */ Ember.computed = function(func) { var args; @@ -398,10 +384,11 @@ Ember.computed = function(func) { property that is generated lazily, without accidentally causing it to be created. + @method cacheFor + @for Ember @param {Object} obj the object whose property you want to check @param {String} key the name of the property whose cached value you want to return - */ Ember.cacheFor = function cacheFor(obj, key) { var cache = metaFor(obj, false).cache; @@ -411,12 +398,22 @@ Ember.cacheFor = function cacheFor(obj, key) { } }; +/** + @method computed.not + @for Ember + @param {String} dependentKey +*/ Ember.computed.not = function(dependentKey) { return Ember.computed(dependentKey, function(key) { return !get(this, dependentKey); }).cacheable(); }; +/** + @method computed.empty + @for Ember + @param {String} dependentKey +*/ Ember.computed.empty = function(dependentKey) { return Ember.computed(dependentKey, function(key) { var val = get(this, dependentKey); @@ -424,6 +421,11 @@ Ember.computed.empty = function(dependentKey) { }).cacheable(); }; +/** + @method computed.bool + @for Ember + @param {String} dependentKey +*/ Ember.computed.bool = function(dependentKey) { return Ember.computed(dependentKey, function(key) { return !!get(this, dependentKey); diff --git a/packages/ember-metal/lib/core.js b/packages/ember-metal/lib/core.js index ad31d85375e..9cece1e42cb 100644 --- a/packages/ember-metal/lib/core.js +++ b/packages/ember-metal/lib/core.js @@ -5,17 +5,12 @@ // ========================================================================== /*globals Em:true ENV */ -if ('undefined' === typeof Ember) { - // Create core object. Make it act like an instance of Ember.Namespace so that - // objects assigned to it are given a sane string representation. - Ember = {}; -} - /** - @namespace - @name Ember - @version 1.0.pre +@module ember +@submodule ember-metal +*/ +/** All Ember methods and functions are defined inside of this namespace. You generally should not add new properties to this namespace as it may be overwritten by future versions of Ember. @@ -30,8 +25,18 @@ if ('undefined' === typeof Ember) { The core Runtime framework is based on the jQuery API with a number of performance optimizations. + + @class Ember + @static + @version 1.0.pre */ +if ('undefined' === typeof Ember) { + // Create core object. Make it act like an instance of Ember.Namespace so that + // objects assigned to it are given a sane string representation. + Ember = {}; +} + // aliases needed to keep minifiers from removing the global context if ('undefined' !== typeof window) { window.Em = window.Ember = Em = Ember; @@ -45,21 +50,20 @@ Ember.toString = function() { return "Ember"; }; /** - @static + @property VERSION @type String @default '1.0.pre' - @constant + @final */ Ember.VERSION = '1.0.pre'; /** - @static - @type Hash - @constant - Standard environmental variables. You can define these in a global `ENV` variable before loading Ember to control various configuration settings. + + @property ENV + @type Hash */ Ember.ENV = Ember.ENV || ('undefined' === typeof ENV ? {} : ENV); @@ -70,11 +74,6 @@ Ember.config = Ember.config || {}; // /** - @static - @type Boolean - @default true - @constant - Determines whether Ember should enhances some built-in object prototypes to provide a more friendly API. If enabled, a few methods will be added to Function, String, and Array. Object.prototype will not be @@ -83,50 +82,46 @@ Ember.config = Ember.config || {}; In general we recommend leaving this option set to true since it rarely conflicts with other code. If you need to turn it off however, you can define an ENV.EXTEND_PROTOTYPES config to disable it. + + @property EXTEND_PROTOTYPES + @type Boolean + @default true */ Ember.EXTEND_PROTOTYPES = (Ember.ENV.EXTEND_PROTOTYPES !== false); /** - @static + Determines whether Ember logs a full stack trace during deprecation warnings + + @property LOG_STACKTRACE_ON_DEPRECATION @type Boolean @default true - @constant - - Determines whether Ember logs a full stack trace during deprecation warnings */ Ember.LOG_STACKTRACE_ON_DEPRECATION = (Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !== false); /** - @static + Determines whether Ember should add ECMAScript 5 shims to older browsers. + + @property SHIM_ES5 @type Boolean @default Ember.EXTEND_PROTOTYPES - @constant - - Determines whether Ember should add ECMAScript 5 shims to older browsers. */ Ember.SHIM_ES5 = (Ember.ENV.SHIM_ES5 === false) ? false : Ember.EXTEND_PROTOTYPES; /** - @static - @type Boolean - @default true - @constant - Determines whether computed properties are cacheable by default. This option will be removed for the 1.1 release. When caching is enabled by default, you can use `volatile()` to disable caching on individual computed properties. -*/ -Ember.CP_DEFAULT_CACHEABLE = (Ember.ENV.CP_DEFAULT_CACHEABLE !== false); -/** - @static + @property CP_DEFAULT_CACHEABLE @type Boolean @default true - @constant +*/ +Ember.CP_DEFAULT_CACHEABLE = (Ember.ENV.CP_DEFAULT_CACHEABLE !== false); +/** Determines whether views render their templates using themselves as the context, or whether it is inherited from the parent. This option will be removed in the 1.1 release. @@ -153,23 +148,22 @@ Ember.CP_DEFAULT_CACHEABLE = (Ember.ENV.CP_DEFAULT_CACHEABLE !== false); {{view.otherViewProperty}} {{/view}} {{/each}} + + @property VIEW_PRESERVES_CONTEXT + @type Boolean + @default true */ Ember.VIEW_PRESERVES_CONTEXT = (Ember.ENV.VIEW_PRESERVES_CONTEXT !== false); /** Empty function. Useful for some operations. - @returns {Object} + @method K @private + @return {Object} */ Ember.K = function() { return this; }; -/** - @namespace - @name window - @description The global window object -*/ - // Stub out the methods defined by the ember-debug package in case it's not loaded @@ -186,7 +180,6 @@ if ('undefined' === typeof ember_assert) { window.ember_assert = Ember.K; } if ('undefined' === typeof ember_warn) { window.ember_warn = Ember.K; } if ('undefined' === typeof ember_deprecate) { window.ember_deprecate = Ember.K; } if ('undefined' === typeof ember_deprecateFunc) { - /** @private */ window.ember_deprecateFunc = function(_, func) { return func; }; } @@ -196,10 +189,11 @@ if ('undefined' === typeof ember_deprecateFunc) { // /** - @class - Inside Ember-Metal, simply uses the window.console object. Override this to provide more robust logging functionality. + + @class Logger + @namespace Ember */ Ember.Logger = window.console || { log: Ember.K, warn: Ember.K, error: Ember.K, info: Ember.K, debug: Ember.K }; @@ -208,8 +202,26 @@ Ember.Logger = window.console || { log: Ember.K, warn: Ember.K, error: Ember.K, // ERROR HANDLING // +/** + A function may be assigned to `Ember.onerror` to be called when Ember internals encounter an error. + This is useful for specialized error handling and reporting code. + + @event onerror + @for Ember + @param {Exception} error the error object +*/ Ember.onerror = null; +/** + @private + + Wrap code block in a try/catch if {{#crossLink "Ember/onerror"}}{{/crossLink}} is set. + + @method handleErrors + @for Ember + @param {Function} func + @param [context] +*/ Ember.handleErrors = function(func, context) { // Unfortunately in some browsers we lose the backtrace if we rethrow the existing error, // so in the event that we don't have an `onerror` handler we don't wrap in a try/catch diff --git a/packages/ember-metal/lib/events.js b/packages/ember-metal/lib/events.js index d548486044e..e7efa389e9b 100644 --- a/packages/ember-metal/lib/events.js +++ b/packages/ember-metal/lib/events.js @@ -8,13 +8,17 @@ require('ember-metal/core'); require('ember-metal/platform'); require('ember-metal/utils'); +/** +@module ember-metal +*/ + var o_create = Ember.create, meta = Ember.meta, metaPath = Ember.metaPath, guidFor = Ember.guidFor, a_slice = [].slice; -/** +/* The event system uses a series of nested hashes to store listeners on an object. When a listener is registered, or when an event arrives, these hashes are consulted to determine which target and action pair to invoke. @@ -39,14 +43,12 @@ var o_create = Ember.create, // Gets the set of all actions, keyed on the guid of each action's // method property. -/** @private */ function actionSetFor(obj, eventName, target, writable) { return metaPath(obj, ['listeners', eventName, guidFor(target)], writable); } // Gets the set of all targets, keyed on the guid of each action's // target property. -/** @private */ function targetSetFor(obj, eventName) { var listenerSet = meta(obj, false).listeners; if (!listenerSet) { return false; } @@ -58,7 +60,6 @@ function targetSetFor(obj, eventName) { // meta system. var SKIP_PROPERTIES = { __ember_source__: true }; -/** @private */ function iterateSet(obj, eventName, callback, params) { var targetSet = targetSetFor(obj, eventName); if (!targetSet) { return false; } @@ -84,7 +85,6 @@ function iterateSet(obj, eventName, callback, params) { return false; } -/** @private */ function invokeAction(action, params, sender) { var method = action.method, target = action.target; // If there is no target, the target is the object @@ -99,9 +99,14 @@ function invokeAction(action, params, sender) { } /** - The sendEvent arguments > 2 are passed to an event listener. - - @memberOf Ember + Add an event listener + + @method addListener + @for Ember + @param obj + @param {String} eventName + @param {Object|Function} targetOrMethod A target object or a function + @param {Function|String} method A function or the name of a function to be called on `target` */ function addListener(obj, eventName, target, method) { Ember.assert("You must pass at least an object and event name to Ember.addListener", !!obj && !!eventName); @@ -123,7 +128,18 @@ function addListener(obj, eventName, target, method) { } } -/** @memberOf Ember */ +/** + Remove an event listener + + Arguments should match those passed to {{#crossLink "Ember/addListener"}}{{/crossLink}} + + @method removeListener + @for Ember + @param obj + @param {String} eventName + @param {Object|Function} targetOrMethod A target object or a function + @param {Function|String} method A function or the name of a function to be called on `target` +*/ function removeListener(obj, eventName, target, method) { Ember.assert("You must pass at least an object and event name to Ember.removeListener", !!obj && !!eventName); @@ -144,13 +160,24 @@ function removeListener(obj, eventName, target, method) { } } -// Suspend listener during callback. -// -// This should only be used by the target of the event listener -// when it is taking an action that would cause the event, e.g. -// an object might suspend its property change listener while it is -// setting that property. -/** @private */ +/** + @private + + Suspend listener during callback. + + This should only be used by the target of the event listener + when it is taking an action that would cause the event, e.g. + an object might suspend its property change listener while it is + setting that property. + + @method suspendListener + @for Ember + @param obj + @param {String} eventName + @param {Object|Function} targetOrMethod A target object or a function + @param {Function|String} method A function or the name of a function to be called on `target` + @param {Function} callback +*/ function suspendListener(obj, eventName, target, method, callback) { if (!method && 'function' === typeof target) { method = target; @@ -169,6 +196,24 @@ function suspendListener(obj, eventName, target, method, callback) { } } +/** + @private + + Suspend listener during callback. + + This should only be used by the target of the event listener + when it is taking an action that would cause the event, e.g. + an object might suspend its property change listener while it is + setting that property. + + @method suspendListener + @for Ember + @param obj + @param {Array} eventName Array of event names + @param {Object|Function} targetOrMethod A target object or a function + @param {Function|String} method A function or the name of a function to be called on `target` + @param {Function} callback +*/ function suspendListeners(obj, eventNames, target, method, callback) { if (!method && 'function' === typeof target) { method = target; @@ -200,8 +245,15 @@ function suspendListeners(obj, eventNames, target, method, callback) { } } -// returns a list of currently watched events -/** @memberOf Ember */ +/** + @private + + Return a list of currently watched events + + @method watchedEvents + @for Ember + @param obj +*/ function watchedEvents(obj) { var listeners = meta(obj, false).listeners, ret = []; @@ -215,7 +267,14 @@ function watchedEvents(obj) { return ret; } -/** @memberOf Ember */ +/** + @method sendEvent + @for Ember + @param obj + @param {String} eventName + @param {Array} params + @return true +*/ function sendEvent(obj, eventName, params) { // first give object a chance to handle it if (obj !== Ember && 'function' === typeof obj.sendEvent) { @@ -226,7 +285,14 @@ function sendEvent(obj, eventName, params) { return true; } -/** @memberOf Ember */ +/** + @private + @method deferEvent + @for Ember + @param obj + @param {String} eventName + @param {Array} params +*/ function deferEvent(obj, eventName, params) { var actions = []; iterateSet(obj, eventName, function (action) { @@ -246,7 +312,13 @@ function deferEvent(obj, eventName, params) { }; } -/** @memberOf Ember */ +/** + @private + @method hasListeners + @for Ember + @param obj + @param {String} eventName +*/ function hasListeners(obj, eventName) { if (iterateSet(obj, eventName, function() { return true; })) { return true; @@ -259,7 +331,13 @@ function hasListeners(obj, eventName) { return false; } -/** @memberOf Ember */ +/** + @private + @method listenersFor + @for Ember + @param obj + @param {String} eventName +*/ function listenersFor(obj, eventName) { var ret = []; iterateSet(obj, eventName, function (action) { diff --git a/packages/ember-metal/lib/main.js b/packages/ember-metal/lib/main.js index 2a31220acb3..f5eae0a1eba 100644 --- a/packages/ember-metal/lib/main.js +++ b/packages/ember-metal/lib/main.js @@ -4,6 +4,13 @@ // License: Licensed under MIT license (see license.js) // ========================================================================== +/** +Ember Metal + +@module ember +@submodule ember-metal +*/ + require('ember-metal/core'); require('ember-metal/map'); require('ember-metal/platform'); diff --git a/packages/ember-metal/lib/map.js b/packages/ember-metal/lib/map.js index cd1b3d2449d..a4de199b106 100644 --- a/packages/ember-metal/lib/map.js +++ b/packages/ember-metal/lib/map.js @@ -1,4 +1,8 @@ /** +@module ember-metal +*/ + +/* JavaScript (before ES6) does not have a Map implementation. Objects, which are often used as dictionaries, may only have Strings as keys. @@ -22,7 +26,6 @@ require('ember-metal/array'); require('ember-metal/utils'); require('ember-metal/core'); -/** @private */ var guidFor = Ember.guidFor, indexOf = Ember.ArrayPolyfills.indexOf; @@ -46,23 +49,43 @@ var copyMap = function(original, newObject) { return newObject; }; -// This class is used internally by Ember.js and Ember Data. -// Please do not use it at this time. We plan to clean it up -// and add many tests soon. +/** + This class is used internally by Ember.js and Ember Data. + Please do not use it at this time. We plan to clean it up + and add many tests soon. + + @class OrderedSet + @namespace Ember + @constructor + @private +*/ var OrderedSet = Ember.OrderedSet = function() { this.clear(); }; +/** + @method create + @static + @return {Ember.OrderedSet} +*/ OrderedSet.create = function() { return new OrderedSet(); }; + OrderedSet.prototype = { + /** + @method clear + */ clear: function() { this.presenceSet = {}; this.list = []; }, + /** + @method add + @param obj + */ add: function(obj) { var guid = guidFor(obj), presenceSet = this.presenceSet, @@ -74,6 +97,10 @@ OrderedSet.prototype = { list.push(obj); }, + /** + @method remove + @param obj + */ remove: function(obj) { var guid = guidFor(obj), presenceSet = this.presenceSet, @@ -87,10 +114,19 @@ OrderedSet.prototype = { } }, + /** + @method isEmpty + @return {Boolean} + */ isEmpty: function() { return this.list.length === 0; }, + /** + @method has + @param obj + @return {Boolean} + */ has: function(obj) { var guid = guidFor(obj), presenceSet = this.presenceSet; @@ -98,6 +134,11 @@ OrderedSet.prototype = { return guid in presenceSet; }, + /** + @method forEach + @param {Function} function + @param target + */ forEach: function(fn, self) { // allow mutation during iteration var list = this.list.slice(); @@ -107,10 +148,18 @@ OrderedSet.prototype = { } }, + /** + @method toArray + @return {Array} + */ toArray: function() { return this.list.slice(); }, + /** + @method copy + @return {Ember.OrderedSet} + */ copy: function() { var set = new OrderedSet(); @@ -136,14 +185,21 @@ OrderedSet.prototype = { add the key to the `keys` OrderedSet, and create or replace an entry in `values`. When an entry is deleted, we delete its entry in `keys` and `values`. -*/ -/** @private */ + @class Map + @namespace Ember + @private + @constructor +*/ var Map = Ember.Map = function() { this.keys = Ember.OrderedSet.create(); this.values = {}; }; +/** + @method create + @static +*/ Map.create = function() { return new Map(); }; @@ -152,6 +208,7 @@ Map.prototype = { /** Retrieve the value associated with a given key. + @method get @param {anything} key @return {anything} the value associated with the key, or undefined */ @@ -166,6 +223,7 @@ Map.prototype = { Adds a value to the map. If a value for the given key has already been provided, the new value will replace the old value. + @method set @param {anything} key @param {anything} value */ @@ -181,8 +239,9 @@ Map.prototype = { /** Removes a value from the map for an associated key. + @method remove @param {anything} key - @returns {Boolean} true if an item was removed, false otherwise + @return {Boolean} true if an item was removed, false otherwise */ remove: function(key) { // don't use ES6 "delete" because it will be annoying @@ -205,8 +264,9 @@ Map.prototype = { /** Check whether a key is present. + @method has @param {anything} key - @returns {Boolean} true if the item was present, false otherwise + @return {Boolean} true if the item was present, false otherwise */ has: function(key) { var values = this.values, @@ -221,6 +281,7 @@ Map.prototype = { The keys are guaranteed to be iterated over in insertion order. + @method forEach @param {Function} callback @param {anything} self if passed, the `this` value inside the callback. By default, `this` is the map. @@ -235,16 +296,36 @@ Map.prototype = { }); }, + /** + @method copy + @return {Ember.Map} + */ copy: function() { return copyMap(this, new Map()); } }; +/** + @class MapWithDefault + @namespace Ember + @extends Ember.Map + @private + @constructor + @param [options] + @param {anything} [options.defaultValue] +*/ var MapWithDefault = Ember.MapWithDefault = function(options) { Map.call(this); this.defaultValue = options.defaultValue; }; +/** + @method create + @static + @param [options] + @param {anything} [options.defaultValue] + @return {Ember.MapWithDefault|Ember.Map} If options are passed, returns Ember.MapWithDefault otherwise returns Ember.Map +*/ MapWithDefault.create = function(options) { if (options) { return new MapWithDefault(options); @@ -255,6 +336,13 @@ MapWithDefault.create = function(options) { MapWithDefault.prototype = Ember.create(Map.prototype); +/** + Retrieve the value associated with a given key. + + @method get + @param {anything} key + @return {anything} the value associated with the key, or the default value +*/ MapWithDefault.prototype.get = function(key) { var hasValue = this.has(key); @@ -267,6 +355,10 @@ MapWithDefault.prototype.get = function(key) { } }; +/** + @method copy + @return {Ember.MapWithDefault} +*/ MapWithDefault.prototype.copy = function() { return copyMap(this, new MapWithDefault({ defaultValue: this.defaultValue diff --git a/packages/ember-metal/lib/mixin.js b/packages/ember-metal/lib/mixin.js index 7f717d31df6..10b5183a49e 100644 --- a/packages/ember-metal/lib/mixin.js +++ b/packages/ember-metal/lib/mixin.js @@ -13,6 +13,10 @@ require('ember-metal/utils'); require('ember-metal/array'); require('ember-metal/binding'); +/** +@module ember-metal +*/ + var Mixin, REQUIRED, Alias, classToString, superClassString, a_map = Ember.ArrayPolyfills.map, @@ -25,7 +29,6 @@ var Mixin, REQUIRED, Alias, defineProperty = Ember.defineProperty, guidFor = Ember.guidFor; -/** @private */ function mixinsMeta(obj) { var m = Ember.meta(obj, true), ret = m.mixins; if (!ret) { @@ -37,7 +40,6 @@ function mixinsMeta(obj) { return ret; } -/** @private */ function initMixin(mixin, args) { if (args && args.length > 0) { mixin.mixins = a_map.call(args, function(x) { @@ -54,18 +56,15 @@ function initMixin(mixin, args) { return mixin; } -/** @private */ function isMethod(obj) { return 'function' === typeof obj && obj.isMethod !== false && obj !== Boolean && obj !== Object && obj !== Number && obj !== Array && obj !== Date && obj !== String; } -/** @private */ function mergeMixins(mixins, m, descs, values, base) { var len = mixins.length, idx, mixin, guid, props, value, key, ovalue, concats; - /** @private */ function removeKeys(keyName) { delete descs[keyName]; delete values[keyName]; @@ -133,7 +132,6 @@ function mergeMixins(mixins, m, descs, values, base) { } } -/** @private */ function writableReq(obj) { var m = Ember.meta(obj), req = m.required; if (!req || req.__emberproto__ !== obj) { @@ -145,7 +143,6 @@ function writableReq(obj) { var IS_BINDING = Ember.IS_BINDING = /^.+Binding$/; -/** @private */ function detectBinding(obj, key, value, m) { if (IS_BINDING.test(key)) { var bindings = m.bindings; @@ -159,7 +156,6 @@ function detectBinding(obj, key, value, m) { } } -/** @private */ function connectBindings(obj, m) { // TODO Mixin.apply(instance) should disconnect binding if exists var bindings = m.bindings, key, binding, to; @@ -188,7 +184,6 @@ function finishPartial(obj, m) { return obj; } -/** @private */ function applyMixin(obj, mixins, partial) { var descs = {}, values = {}, m = Ember.meta(obj), req = m.required, key, value, desc, prevValue, paths, len, idx; @@ -293,6 +288,13 @@ function applyMixin(obj, mixins, partial) { return obj; } +/** + @method mixin + @for Ember + @param obj + @param mixins* + @return obj +*/ Ember.mixin = function(obj) { var args = a_slice.call(arguments, 1); applyMixin(obj, args, false); @@ -300,8 +302,6 @@ Ember.mixin = function(obj) { }; /** - @class - The `Ember.Mixin` class allows you to create mixins, whose properties can be added to other classes. For instance, @@ -324,13 +324,14 @@ Ember.mixin = function(obj) { Note that Mixins are created with `Ember.Mixin.create`, not `Ember.Mixin.extend`. + + @class Mixin + @namespace Ember */ Ember.Mixin = function() { return initMixin(this, arguments); }; -/** @private */ Mixin = Ember.Mixin; -/** @private */ Mixin._apply = applyMixin; Mixin.applyPartial = function(obj) { @@ -340,6 +341,11 @@ Mixin.applyPartial = function(obj) { Mixin.finishPartial = finishPartial; +/** + @method create + @static + @param arguments* +*/ Mixin.create = function() { classToString.processed = false; var M = this; @@ -348,6 +354,10 @@ Mixin.create = function() { var MixinPrototype = Mixin.prototype; +/** + @method reopen + @param arguments* +*/ MixinPrototype.reopen = function() { var mixin, tmp; @@ -378,6 +388,11 @@ MixinPrototype.reopen = function() { return this; }; +/** + @method apply + @param obj + @return applied object +*/ MixinPrototype.apply = function(obj) { return applyMixin(obj, [this], false); }; @@ -386,7 +401,6 @@ MixinPrototype.applyPartial = function(obj) { return applyMixin(obj, [this], true); }; -/** @private */ function _detect(curMixin, targetMixin, seen) { var guid = guidFor(curMixin); @@ -401,6 +415,11 @@ function _detect(curMixin, targetMixin, seen) { return false; } +/** + @method detect + @param obj + @return {Boolean} +*/ MixinPrototype.detect = function(obj) { if (!obj) { return false; } if (obj instanceof Mixin) { return _detect(obj, this, {}); } @@ -417,7 +436,6 @@ MixinPrototype.without = function() { return ret; }; -/** @private */ function _keys(ret, mixin, seen) { if (seen[guidFor(mixin)]) { return; } seen[guidFor(mixin)] = true; @@ -441,12 +459,11 @@ MixinPrototype.keys = function() { return ret; }; -/** @private - make Mixin's have nice displayNames */ +/* make Mixins have nice displayNames */ var NAME_KEY = Ember.GUID_KEY+'_name'; var get = Ember.get; -/** @private */ function processNames(paths, root, seen) { var idx = paths.length; for(var key in root) { @@ -465,7 +482,6 @@ function processNames(paths, root, seen) { paths.length = idx; // cut out last item } -/** @private */ function findNamespaces() { var Namespace = Ember.Namespace, obj, isNamespace; @@ -494,9 +510,13 @@ function findNamespaces() { } } +/** + @private + @method identifyNamespaces + @for Ember +*/ Ember.identifyNamespaces = findNamespaces; -/** @private */ superClassString = function(mixin) { var superclass = mixin.superclass; if (superclass) { @@ -507,7 +527,6 @@ superClassString = function(mixin) { } }; -/** @private */ classToString = function() { var Namespace = Ember.Namespace, namespace; @@ -562,11 +581,16 @@ Mixin.mixins = function(obj) { REQUIRED = new Ember.Descriptor(); REQUIRED.toString = function() { return '(Required Property)'; }; +/** + Denotes a required property for a mixin + + @method required + @for Ember +*/ Ember.required = function() { return REQUIRED; }; -/** @private */ Alias = function(methodName) { this.methodName = methodName; }; @@ -587,8 +611,10 @@ Alias.prototype = new Ember.Descriptor(); paintSample.get('colour'); //=> 'red' paintSample.moniker(); //=> 'Zed' + @method alias + @for Ember @param {String} methodName name of the method or property to alias - @returns {Ember.Descriptor} + @return {Ember.Descriptor} */ Ember.alias = function(methodName) { return new Alias(methodName); @@ -598,6 +624,13 @@ Ember.alias = function(methodName) { // OBSERVER HELPER // +/** + @method observer + @for Ember + @param {Function} func + @param {String} propertyNames* + @return func +*/ Ember.observer = function(func) { var paths = a_slice.call(arguments, 1); func.__ember_observes__ = paths; @@ -606,6 +639,13 @@ Ember.observer = function(func) { // If observers ever become asynchronous, Ember.immediateObserver // must remain synchronous. +/** + @method immediateObserver + @for Ember + @param {Function} func + @param {String} propertyNames* + @return func +*/ Ember.immediateObserver = function() { for (var i=0, l=arguments.length; i true + @method makeArray + @for Ember @param {Object} obj the object - @returns {Array} + @return {Array} */ Ember.makeArray = function(obj) { if (obj === null || obj === undefined) { return []; } @@ -371,8 +384,8 @@ function canInvoke(obj, methodName) { /** Checks to see if the `methodName` exists on the `obj`. - @function - + @method canInvoke + @for Ember @param {Object} obj The object to check for the method @param {String} methodName The method name to check for */ @@ -382,13 +395,12 @@ Ember.canInvoke = canInvoke; Checks to see if the `methodName` exists on the `obj`, and if it does, invokes it with the arguments passed. - @function - + @method tryInvoke + @for Ember @param {Object} obj The object to check for the method @param {String} methodName The method name to check for - @param {Array} args The arguments to pass to the method - - @returns {*} whatever the invoked function returns if it can be invoked + @param {Array} [args] The arguments to pass to the method + @return {anything} the return value of the invoked method or undefined if it cannot be invoked */ Ember.tryInvoke = function(obj, methodName, args) { if (canInvoke(obj, methodName)) { diff --git a/packages/ember-metal/lib/watching.js b/packages/ember-metal/lib/watching.js index db53dd75d49..0796d59ee65 100644 --- a/packages/ember-metal/lib/watching.js +++ b/packages/ember-metal/lib/watching.js @@ -12,6 +12,10 @@ require('ember-metal/properties'); require('ember-metal/observer'); require('ember-metal/array'); +/** +@module ember-metal +*/ + var guidFor = Ember.guidFor, // utils.js metaFor = Ember.meta, // utils.js get = Ember.get, // accessors.js @@ -29,13 +33,11 @@ var guidFor = Ember.guidFor, // utils.js var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER, o_defineProperty = Ember.platform.defineProperty; -/** @private */ function firstKey(path) { return path.match(FIRST_KEY)[0]; } // returns true if the passed path is just a keyName -/** @private */ function isKeyName(path) { return path==='*' || !IS_PATH.test(path); } @@ -46,7 +48,6 @@ function isKeyName(path) { var DEP_SKIP = { __emberproto__: true }; // skip some keys and toString -/** @private */ function iterDeps(method, obj, depKey, seen, meta) { var guid = guidFor(obj); @@ -70,7 +71,6 @@ function iterDeps(method, obj, depKey, seen, meta) { var WILL_SEEN, DID_SEEN; // called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...) -/** @private */ function dependentKeysWillChange(obj, depKey, meta) { if (obj.isDestroying) { return; } @@ -81,7 +81,6 @@ function dependentKeysWillChange(obj, depKey, meta) { } // called whenever a property has just changed to update dependent keys -/** @private */ function dependentKeysDidChange(obj, depKey, meta) { if (obj.isDestroying) { return; } @@ -95,7 +94,6 @@ function dependentKeysDidChange(obj, depKey, meta) { // CHAIN // -/** @private */ function addChainWatcher(obj, keyName, node) { if (!obj || ('object' !== typeof obj)) return; // nothing to do var m = metaFor(obj); @@ -109,7 +107,6 @@ function addChainWatcher(obj, keyName, node) { Ember.watch(obj, keyName); } -/** @private */ function removeChainWatcher(obj, keyName, node) { if (!obj || 'object' !== typeof obj) { return; } // nothing to do var m = metaFor(obj, false), @@ -124,7 +121,6 @@ var pendingQueue = []; // attempts to add the pendingQueue chains again. If some of them end up // back in the queue and reschedule is true, schedules a timeout to try // again. -/** @private */ function flushPendingChains() { if (pendingQueue.length === 0) { return; } // nothing to do @@ -136,7 +132,6 @@ function flushPendingChains() { Ember.warn('Watching an undefined global, Ember expects watched globals to be setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0); } -/** @private */ function isProto(pvalue) { return metaFor(pvalue, false).proto === pvalue; } @@ -144,7 +139,6 @@ function isProto(pvalue) { // A ChainNode watches a single key on an object. If you provide a starting // value for the key then the node won't actually watch it. For a root node // pass null for parent and key and object for value. -/** @private */ var ChainNode = function(parent, key, value, separator) { var obj; this._parent = parent; @@ -372,7 +366,6 @@ ChainNodePrototype.didChange = function(suppressEvent) { // get the chains for the current object. If the current object has // chains inherited from the proto they will be cloned and reconfigured for // the current object. -/** @private */ function chainsFor(obj) { var m = metaFor(obj), ret = m.chains; if (!ret) { @@ -383,7 +376,6 @@ function chainsFor(obj) { return ret; } -/** @private */ function notifyChains(obj, m, keyName, methodName, arg) { var nodes = m.chainWatchers; @@ -402,12 +394,10 @@ Ember.overrideChains = function(obj, keyName, m) { notifyChains(obj, m, keyName, 'didChange', true); }; -/** @private */ function chainsWillChange(obj, keyName, m) { notifyChains(obj, m, keyName, 'willChange'); } -/** @private */ function chainsDidChange(obj, keyName, m) { notifyChains(obj, m, keyName, 'didChange'); } @@ -424,6 +414,11 @@ function chainsDidChange(obj, keyName, m) { primitive used by observers and dependent keys; usually you will never call this method directly but instead use higher level methods like Ember.addObserver(). + + @method watch + @for Ember + @param obj + @param {String} keyName */ Ember.watch = function(obj, keyName) { // can't watch length on Array - it is special... @@ -473,7 +468,6 @@ Ember.isWatching = function isWatching(obj, key) { Ember.watch.flushPending = flushPendingChains; -/** @private */ Ember.unwatch = function(obj, keyName) { // can't watch length on Array - it is special... if (keyName === 'length' && Ember.typeOf(obj) === 'array') { return this; } @@ -517,6 +511,10 @@ Ember.unwatch = function(obj, keyName) { Call on an object when you first beget it from another object. This will setup any chained watchers on the object instance as needed. This method is safe to call multiple times. + + @method rewatch + @for Ember + @param obj */ Ember.rewatch = function(obj) { var m = metaFor(obj, false), chains = m.chains; @@ -557,15 +555,11 @@ Ember.finishChains = function(obj) { manually along with `Ember.propertyDidChange()` which you should call just after the property value changes. - @memberOf Ember - - @param {Object} obj - The object with the property that will change - - @param {String} keyName - The property key (or path) that will change. - - @returns {void} + @method propertyWillChange + @for Ember + @param {Object} obj The object with the property that will change + @param {String} keyName The property key (or path) that will change. + @return {void} */ function propertyWillChange(obj, keyName, value) { var m = metaFor(obj, false), @@ -592,15 +586,11 @@ Ember.propertyWillChange = propertyWillChange; manually along with `Ember.propertyWilLChange()` which you should call just before the property value changes. - @memberOf Ember - - @param {Object} obj - The object with the property that will change - - @param {String} keyName - The property key (or path) that will change. - - @returns {void} + @method propertyDidChange + @for Ember + @param {Object} obj The object with the property that will change + @param {String} keyName The property key (or path) that will change. + @return {void} */ function propertyDidChange(obj, keyName) { var m = metaFor(obj, false), @@ -627,8 +617,10 @@ var NODE_STACK = []; Tears down the meta on an object so that it can be garbage collected. Multiple calls will have no effect. + @method destroy + @for Ember @param {Object} obj the object to destroy - @returns {void} + @return {void} */ Ember.destroy = function (obj) { var meta = obj[META_KEY], node, nodes, key, nodeObject; diff --git a/packages/ember-metal/tests/performance_test.js b/packages/ember-metal/tests/performance_test.js index 108d6d48615..639483a6737 100644 --- a/packages/ember-metal/tests/performance_test.js +++ b/packages/ember-metal/tests/performance_test.js @@ -1,4 +1,4 @@ -/** +/* This test file is designed to capture performance regressions related to deferred computation. Things like run loops, computed properties, and bindings should run the minimum amount of times to achieve best performance, so any diff --git a/packages/ember/lib/main.js b/packages/ember/lib/main.js index c4796a2e186..2fc4b92e08b 100644 --- a/packages/ember/lib/main.js +++ b/packages/ember/lib/main.js @@ -7,3 +7,9 @@ require('ember-metal'); require('ember-views'); require('ember-handlebars'); + +/** +Ember + +@module ember +*/