Exemple #1
0
  this.helperFunction = function helperFunc(params, hash, options, env) {
    var param;
    var handlebarsOptions = {};
    merge(handlebarsOptions, options);
    merge(handlebarsOptions, env);

    handlebarsOptions.hash = {};
    for (var prop in hash) {
      param = hash[prop];

      if (isStream(param)) {
        handlebarsOptions.hash[prop] = param._label;
      } else {
        handlebarsOptions.hash[prop] = param;
      }
    }

    var args = new Array(params.length);
    for (var i = 0, l = params.length; i < l; i++) {
      param = params[i];

      if (isStream(param)) {
        args[i] = param._label;
      } else {
        args[i] = param;
      }
    }
    args.push(handlebarsOptions);

    return fn.apply(this, args);
  };
Exemple #2
0
function makeBindings(hash, options, view) {
  for (var prop in hash) {
    var value = hash[prop];

    // Classes are processed separately
    if (prop === 'class' && isStream(value)) {
      hash.classBinding = value._label;
      delete hash['class'];
      continue;
    }

    if (prop === 'classBinding') {
      continue;
    }

    if (IS_BINDING.test(prop)) {
      if (isStream(value)) {
        Ember.warn("You're attempting to render a view by passing " +
                   prop + " " +
                   "to a view helper without a quoted value, " +
                   "but this syntax is ambiguous. You should either surround " +
                   prop + "'s value in quotes or remove `Binding` " +
                   "from " + prop + ".");
      } else if (typeof value === 'string') {
        hash[prop] = view._getBindingForStream(value);
      }
    } else {
      if (isStream(value) && prop !== 'id') {
        hash[prop + 'Binding'] = view._getBindingForStream(value);
        delete hash[prop];
      }
    }
  }
}
/**
  The `{{link-to}}` helper renders a link to the supplied
  `routeName` passing an optionally supplied model to the
  route as its `model` context of the route. The block
  for `{{link-to}}` becomes the innerHTML of the rendered
  element:

  ```handlebars
  {{#link-to 'photoGallery'}}
    Great Hamster Photos
  {{/link-to}}
  ```

  You can also use an inline form of `{{link-to}}` helper by
  passing the link text as the first argument
  to the helper:

  ```handlebars
  {{link-to 'Great Hamster Photos' 'photoGallery'}}
  ```

  Both will result in:

  ```html
  <a href="/hamster-photos">
    Great Hamster Photos
  </a>
  ```

  ### Supplying a tagName
  By default `{{link-to}}` renders an `<a>` element. This can
  be overridden for a single use of `{{link-to}}` by supplying
  a `tagName` option:

  ```handlebars
  {{#link-to 'photoGallery' tagName="li"}}
    Great Hamster Photos
  {{/link-to}}
  ```

  ```html
  <li>
    Great Hamster Photos
  </li>
  ```

  To override this option for your entire application, see
  "Overriding Application-wide Defaults".

  ### Disabling the `link-to` helper
  By default `{{link-to}}` is enabled.
  any passed value to `disabled` helper property will disable the `link-to` helper.

  static use: the `disabled` option:

  ```handlebars
  {{#link-to 'photoGallery' disabled=true}}
    Great Hamster Photos
  {{/link-to}}
  ```

  dynamic use: the `disabledWhen` option:

  ```handlebars
  {{#link-to 'photoGallery' disabledWhen=controller.someProperty}}
    Great Hamster Photos
  {{/link-to}}
  ```

  any passed value to `disabled` will disable it except `undefined`.
  to ensure that only `true` disable the `link-to` helper you can
  override the global behaviour of `Ember.LinkView`.

  ```javascript
  Ember.LinkView.reopen({
    disabled: Ember.computed(function(key, value) {
      if (value !== undefined) {
        this.set('_isDisabled', value === true);
      }
      return value === true ? get(this, 'disabledClass') : false;
    })
  });
  ```

  see "Overriding Application-wide Defaults" for more.

  ### Handling `href`
  `{{link-to}}` will use your application's Router to
  fill the element's `href` property with a url that
  matches the path to the supplied `routeName` for your
  router's configured `Location` scheme, which defaults
  to Ember.HashLocation.

  ### Handling current route
  `{{link-to}}` will apply a CSS class name of 'active'
  when the application's current route matches
  the supplied routeName. For example, if the application's
  current route is 'photoGallery.recent' the following
  use of `{{link-to}}`:

  ```handlebars
  {{#link-to 'photoGallery.recent'}}
    Great Hamster Photos from the last week
  {{/link-to}}
  ```

  will result in

  ```html
  <a href="/hamster-photos/this-week" class="active">
    Great Hamster Photos
  </a>
  ```

  The CSS class name used for active classes can be customized
  for a single use of `{{link-to}}` by passing an `activeClass`
  option:

  ```handlebars
  {{#link-to 'photoGallery.recent' activeClass="current-url"}}
    Great Hamster Photos from the last week
  {{/link-to}}
  ```

  ```html
  <a href="/hamster-photos/this-week" class="current-url">
    Great Hamster Photos
  </a>
  ```

  To override this option for your entire application, see
  "Overriding Application-wide Defaults".

  ### Supplying a model
  An optional model argument can be used for routes whose
  paths contain dynamic segments. This argument will become
  the model context of the linked route:

  ```javascript
  App.Router.map(function() {
    this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
  });
  ```

  ```handlebars
  {{#link-to 'photoGallery' aPhoto}}
    {{aPhoto.title}}
  {{/link-to}}
  ```

  ```html
  <a href="/hamster-photos/42">
    Tomster
  </a>
  ```

  ### Supplying multiple models
  For deep-linking to route paths that contain multiple
  dynamic segments, multiple model arguments can be used.
  As the router transitions through the route path, each
  supplied model argument will become the context for the
  route with the dynamic segments:

  ```javascript
  App.Router.map(function() {
    this.resource("photoGallery", {path: "hamster-photos/:photo_id"}, function() {
      this.route("comment", {path: "comments/:comment_id"});
    });
  });
  ```
  This argument will become the model context of the linked route:

  ```handlebars
  {{#link-to 'photoGallery.comment' aPhoto comment}}
    {{comment.body}}
  {{/link-to}}
  ```

  ```html
  <a href="/hamster-photos/42/comment/718">
    A+++ would snuggle again.
  </a>
  ```

  ### Supplying an explicit dynamic segment value
  If you don't have a model object available to pass to `{{link-to}}`,
  an optional string or integer argument can be passed for routes whose
  paths contain dynamic segments. This argument will become the value
  of the dynamic segment:

  ```javascript
  App.Router.map(function() {
    this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
  });
  ```

  ```handlebars
  {{#link-to 'photoGallery' aPhotoId}}
    {{aPhoto.title}}
  {{/link-to}}
  ```

  ```html
  <a href="/hamster-photos/42">
    Tomster
  </a>
  ```

  When transitioning into the linked route, the `model` hook will
  be triggered with parameters including this passed identifier.

  ### Allowing Default Action

 By default the `{{link-to}}` helper prevents the default browser action
 by calling `preventDefault()` as this sort of action bubbling is normally
 handled internally and we do not want to take the browser to a new URL (for
 example).

 If you need to override this behavior specify `preventDefault=false` in
 your template:

  ```handlebars
  {{#link-to 'photoGallery' aPhotoId preventDefault=false}}
    {{aPhotoId.title}}
  {{/link-to}}
  ```

  ### Overriding attributes
  You can override any given property of the Ember.LinkView
  that is generated by the `{{link-to}}` helper by passing
  key/value pairs, like so:

  ```handlebars
  {{#link-to  aPhoto tagName='li' title='Following this link will change your life' classNames='pic sweet'}}
    Uh-mazing!
  {{/link-to}}
  ```

  See [Ember.LinkView](/api/classes/Ember.LinkView.html) for a
  complete list of overrideable properties. Be sure to also
  check out inherited properties of `LinkView`.

  ### Overriding Application-wide Defaults
  ``{{link-to}}`` creates an instance of Ember.LinkView
  for rendering. To override options for your entire
  application, reopen Ember.LinkView and supply the
  desired values:

  ``` javascript
  Ember.LinkView.reopen({
    activeClass: "is-active",
    tagName: 'li'
  })
  ```

  It is also possible to override the default event in
  this manner:

  ``` javascript
  Ember.LinkView.reopen({
    eventName: 'customEventName'
  });
  ```

  @method link-to
  @for Ember.Handlebars.helpers
  @param {String} routeName
  @param {Object} [context]*
  @param [options] {Object} Handlebars key/value pairs of options, you can override any property of Ember.LinkView
  @return {String} HTML string
  @see {Ember.LinkView}
*/
function linkToHelper(params, hash, options, env) {
  var queryParamsObject;

  Ember.assert("You must provide one or more parameters to the link-to helper.", params.length);

  var lastParam = params[params.length - 1];

  if (lastParam && lastParam.isQueryParams) {
    hash.queryParamsObject = queryParamsObject = params.pop();
  }

  if (hash.disabledWhen) {
    hash.disabled = hash.disabledWhen;
    delete hash.disabledWhen;
  }

  if (!options.template) {
    var linkTitle = params.shift();
    var parseTextAsHTML = options.morph.parseTextAsHTML;

    if (isStream(linkTitle)) {
      hash.linkTitle = { stream: linkTitle };
    }

    options.template = {
      isHTMLBars: true,
      revision: 'Ember@VERSION_STRING_PLACEHOLDER',
      render: function(view, env) {
        var value = read(linkTitle) || "";
        if (parseTextAsHTML) {
          return value;
        } else {
          return env.dom.createTextNode(value);
        }
      }
    };
  }

  for (var i = 0; i < params.length; i++) {
    if (isStream(params[i])) {
      var lazyValue = params[i];

      if (!lazyValue._isController) {
        while (ControllerMixin.detect(lazyValue.value())) {
          lazyValue = lazyValue.get('model');
        }
      }

      params[i] = lazyValue;
    }
  }

  hash.params = params;

  options.helperName = options.helperName || 'link-to';

  return env.helpers.view.helperFunction.call(this, [LinkView], hash, options, env);
}
Exemple #4
0
  this.helperFunction = function helperFunc(params, hash, options, env) {
    var param, blockResult, fnResult;
    var context = this;
    var handlebarsOptions = {
      hash: { },
      types: new Array(params.length),
      hashTypes: { }
    };

    merge(handlebarsOptions, options);
    merge(handlebarsOptions, env);

    handlebarsOptions.hash = {};

    if (options.isBlock) {
      handlebarsOptions.fn = function() {
        blockResult = options.template.render(context, env, options.morph.contextualElement);
      };
    }

    for (var prop in hash) {
      param = hash[prop];

      handlebarsOptions.hashTypes[prop] = calculateCompatType(param);

      if (isStream(param)) {
        handlebarsOptions.hash[prop] = param._label;
      } else {
        handlebarsOptions.hash[prop] = param;
      }
    }

    var args = new Array(params.length);
    for (var i = 0, l = params.length; i < l; i++) {
      param = params[i];

      handlebarsOptions.types[i] = calculateCompatType(param);

      if (isStream(param)) {
        args[i] = param._label;
      } else {
        args[i] = param;
      }
    }
    args.push(handlebarsOptions);

    fnResult = fn.apply(this, args);

    return options.isBlock ? blockResult : fnResult;
  };
Exemple #5
0
export function actionHelper(params, hash, options, env) {

  var target;
  if (!hash.target) {
    target = this.getStream('controller');
  } else if (isStream(hash.target)) {
    target = hash.target;
  } else {
    target = this.getStream(hash.target);
  }

  // Ember.assert("You specified a quoteless path to the {{action}} helper which did not resolve to an action name (a string). Perhaps you meant to use a quoted actionName? (e.g. {{action 'save'}}).", !params[0].isStream);
  // Ember.deprecate("You specified a quoteless path to the {{action}} helper which did not resolve to an action name (a string). Perhaps you meant to use a quoted actionName? (e.g. {{action 'save'}}).", params[0].isStream);

  var actionOptions = {
    eventName: hash.on || "click",
    parameters: params.slice(1),
    view: this,
    bubbles: hash.bubbles,
    preventDefault: hash.preventDefault,
    target: target,
    withKeyCode: hash.withKeyCode
  };

  var actionId = ActionHelper.registerAction(params[0], actionOptions, hash.allowedKeys);
  env.dom.setAttribute(options.element, 'data-ember-action', actionId);
}
Exemple #6
0
function buildDynamicKeyStream(source, keySource) {
  if (!isStream(keySource)) {
    return source.get(keySource);
  } else {
    return new DynamicKeyStream(source, keySource);
  }
}
Exemple #7
0
  var DynamicKeyStream = function DynamicKeyStream(source, keySource) {
    if (!isStream(keySource)) {
      return new KeyStream(source, keySource);
    }
    Ember.assert('DynamicKeyStream error: source must be a stream', isStream(source)); // TODO: This isn't necessary.

    // used to get the original path for debugging and legacy purposes
    var label = labelFor(source, keySource);

    this.init(label);
    this.path = label;
    this.sourceDep = this.addMutableDependency(source);
    this.keyDep = this.addMutableDependency(keySource);
    this.observedObject = null;
    this.observedKey = null;
  };
Exemple #8
0
export function componentHelper(params, hash, options, env) {
  Ember.assert(
    "The `component` helper expects exactly one argument, plus name/property values.",
    params.length === 1
  );

  var componentNameParam = params[0];
  var container = this.container || read(this._keywords.view).container;

  var props = {
    helperName: options.helperName || 'component'
  };
  if (options.template) {
    props.template = options.template;
  }

  var viewClass;
  if (isStream(componentNameParam)) {
    viewClass = BoundComponentView;
    props = { _boundComponentOptions: Ember.merge(hash, props) };
    props._boundComponentOptions.componentNameStream = componentNameParam;
  } else {
    viewClass = readComponentFactory(componentNameParam, container);
    if (!viewClass) {
      throw new EmberError('HTMLBars error: Could not find component named "' + componentNameParam + '".');
    }
    mergeViewBindings(this, props, hash);
  }

  appendTemplatedView(this, options.morph, viewClass, props);
}
Exemple #9
0
function appendBlockConditional(view, inverted, helperName, params, hash, options, env) {
  Ember.assert(
    "The block form of the `if` and `unless` helpers expect exactly one " +
    "argument, e.g. `{{#if newMessages}} You have new messages. {{/if}}.`",
    params.length === 1
  );

  var condition = shouldDisplay(params[0]);
  var truthyTemplate = (inverted ? options.inverse : options.template) || emptyTemplate;
  var falsyTemplate = (inverted ? options.template : options.inverse) || emptyTemplate;

  if (isStream(condition)) {
    view.appendChild(BoundIfView, {
      _morph: options.morph,
      _context: get(view, 'context'),
      conditionStream: condition,
      truthyTemplate: truthyTemplate,
      falsyTemplate: falsyTemplate,
      helperName: helperName
    });
  } else {
    var template = condition ? truthyTemplate : falsyTemplate;
    if (template) {
      return template.render(view, env, options.morph.contextualElement);
    }
  }
}
function getKey(obj, key) {
  if (isStream(obj)) {
    return obj.getKey(key);
  } else {
    return obj && obj[key];
  }
}
Exemple #11
0
/**
@module ember
@submodule ember-htmlbars
*/

//import Helper from "ember-htmlbars/system/helper";

/**
  A helper function used by `registerBoundHelper`. Takes the
  provided Handlebars helper function fn and returns it in wrapped
  bound helper form.

  The main use case for using this outside of `registerBoundHelper`
  is for registering helpers on the container:

  ```js
  var boundHelperFn = Ember.Handlebars.makeBoundHelper(function(word) {
    return word.toUpperCase();
  });

  container.register('helper:my-bound-helper', boundHelperFn);
  ```

  In the above example, if the helper function hadn't been wrapped in
  `makeBoundHelper`, the registered helper would be unbound.

  @method makeBoundHelper
  @for Ember.Handlebars
  @param {Function} function
  @param {String} dependentKeys*
  @since 1.2.0
  @deprecated
*/
export default function makeBoundHelper(fn, ...dependentKeys) {
  return {
    _dependentKeys: dependentKeys,

    isHandlebarsCompat: true,
    isHTMLBars: true,

    helperFunction(params, hash, templates) {
      Ember.assert("registerBoundHelper-generated helpers do not support use with Handlebars blocks.", !templates.template.yield);

      var args = readArray(params);
      var properties = new Array(params.length);

      for (var i = 0, l = params.length; i < l; i++) {
        var param = params[i];

        if (isStream(param)) {
          properties[i] = param.label;
        } else {
          properties[i] = param;
        }
      }

      args.push({ hash: readHash(hash) , templates, data: { properties } });
      return fn.apply(undefined, args);
    }
  };
}
Exemple #12
0
/*
 Given a path name, returns whether or not a component with that
 name was found in the container.
*/
export default function isComponent(env, scope, path) {
  let owner = env.owner;
  if (!owner) { return false; }
  if (typeof path === 'string') {
    if (CONTAINS_DOT_CACHE.get(path)) {
      let stream = env.hooks.get(env, scope, path);
      if (isStream(stream)) {
        let cell = stream.value();
        if (isComponentCell(cell)) {
          return true;
        }
      }
    }
    if (!CONTAINS_DASH_CACHE.get(path)) { return false; }

    if (hasComponentOrTemplate(owner, path)) {
      return true; // global component found
    } else {
      if (isEnabled('ember-htmlbars-local-lookup')) {
        let moduleName = env.meta && env.meta.moduleName;

        if (!moduleName) {
          // Without a source moduleName, we can not perform local lookups.
          return false;
        }

        let options = { source: `template:${moduleName}` };

        return hasComponentOrTemplate(owner, path, options);
      } else {
        return false;
      }
    }
  }
}
Stream.wrap = function(value, Kind, param) {
  if (isStream(value)) {
    return value;
  } else {
    return new Kind(value, param);
  }
};
Exemple #14
0
function mutParam(read, stream, internal) {
  if (internal) {
    if (!isStream(stream)) {
      let literal = stream;
      stream = new LiteralStream(literal);
    }
  } else {
    assert('You can only pass a path to mut', isStream(stream));
  }

  if (stream[MUTABLE_REFERENCE]) {
    return stream;
  }

  return new MutStream(stream);
}
Exemple #15
0
/**
  @module ember-metal
*/

/**
  @private
  @class Dependency
  @namespace Ember.streams
  @constructor
*/
function Dependency(depender, dependee) {
  Ember.assert("Dependency error: Depender must be a stream", isStream(depender));

  this.next = null;
  this.prev = null;
  this.depender = depender;
  this.dependee = dependee;
  this.unsubscription = null;
}
Exemple #16
0
QUnit.test('returns a stream if a stream is in the array', function(assert) {
  let stream = new Stream(function() {
    return 'bar';
  });
  let result = concat(['foo', stream, 'baz'], ' ');

  assert.ok(isStream(result), 'a stream is returned');
  assert.equal(read(result), 'foo bar baz');
});
Exemple #17
0
function calculateCompatType(item) {
  if (isStream(item)) {
    return 'ID';
  } else {
    var itemType = typeof item;

    return itemType.toUpperCase();
  }
}
Exemple #18
0
  setSource: function(nextSource) {
    Ember.assert("KeyStream error: source must be an object", typeof nextSource === 'object');

    var prevSource = this.source;

    if (nextSource !== prevSource) {
      if (isStream(prevSource)) {
        prevSource.unsubscribe(this._didChange, this);
      }

      if (isStream(nextSource)) {
        nextSource.subscribe(this._didChange, this);
      }

      this.source = nextSource;
      this.notify();
    }
  },
function mergeGenericViewBindings(view, props, hash) {
  for (var key in hash) {
    if (key === 'id' ||
        key === 'tag' ||
        key === 'class' ||
        key === 'classBinding' ||
        key === 'classNameBindings' ||
        key === 'attributeBindings') {
      continue;
    }

    var value = hash[key];

    if (IS_BINDING.test(key)) {
      if (typeof value === 'string') {
        Ember.deprecate(
          "You're attempting to render a view by passing " + key + " " +
          "to a view helper, but this syntax is deprecated. You should use `" +
          key.slice(0, -7) + "=someValue` instead."
        );

        props[key] = view._getBindingForStream(value);
      } else if (isStream(value)) {
        Ember.deprecate(
          "You're attempting to render a view by passing " + key + " " +
          "to a view helper without a quoted value, but this syntax is " +
          "ambiguous. You should either surround " + key + "'s value in " +
          "quotes or remove `Binding` from " + key + "."
        );

        props[key] = view._getBindingForStream(value);
      } else {
        props[key] = value;
      }
    } else {
      if (isStream(value)) {
        props[key + 'Binding'] = view._getBindingForStream(value);
      } else {
        props[key] = value;
      }
    }
  }
}
Exemple #20
0
  const buildStream = function buildStream(params) {
    const [objRef, pathRef] = params;

    Ember.assert('The first argument to {{get}} must be a stream', isStream(objRef));
    Ember.assert('{{get}} requires at least two arguments', params.length > 1);

    const stream = new DynamicKeyStream(objRef, pathRef);

    return stream;
  };
Exemple #21
0
function mutParam(read, stream, internal) {
  if (internal) {
    if (!isStream(stream)) {
      let literal = stream;
      stream = new Stream(function() { return literal; }, `(literal ${literal})`);
      stream.setValue = function(newValue) {
        literal = newValue;
        stream.notify();
      };
    }
  } else {
    Ember.assert("You can only pass a path to mut", isStream(stream));
  }

  if (stream[MUTABLE_REFERENCE]) {
    return stream;
  }

  return new MutStream(stream);
}
Exemple #22
0
export function partialHelper(params, hash, options, env) {
  options.helperName = options.helperName || 'partial';

  var name = params[0];

  if (isStream(name)) {
    options.template = createPartialTemplate(name);
    bind.call(this, name, hash, options, env, true, exists);
  } else {
    return renderPartial(name, this, env, options.morph.contextualElement);
  }
}
function ShouldDisplayStream(predicate) {
  Ember.assert('ShouldDisplayStream error: predicate must be a stream', isStream(predicate));

  var isTruthy = predicate.get('isTruthy');

  this.init();
  this.predicate = predicate;
  this.isTruthy = isTruthy;
  this.lengthDep = null;

  this.addDependency(predicate);
  this.addDependency(isTruthy);
}
Exemple #24
0
export default function inline(env, morph, view, path, params, hash) {
  var helper = lookupHelper(path, view, env);

  Ember.assert("A helper named '"+path+"' could not be found", helper);

  var result = helper.helperFunction.call(undefined, params, hash, { morph: morph }, env);

  if (isStream(result)) {
    appendSimpleBoundView(view, morph, result);
  } else {
    morph.setContent(result);
  }
}
Exemple #25
0
function KeyStream(source, key) {
  Ember.assert("KeyStream error: key must be a non-empty string", typeof key === 'string' && key.length > 0);
  Ember.assert("KeyStream error: key must not have a '.'", key.indexOf('.') === -1);

  this.init();
  this.source = source;
  this.obj = undefined;
  this.key = key;

  if (isStream(source)) {
    source.subscribe(this._didChange, this);
  }
}
Exemple #26
0
// Binds a property into the DOM. This will create a hook in DOM that the
// KVO system will look for and update if the property changes.
function bind(property, hash, options, env, preserveContext, shouldDisplay, valueNormalizer, childProperties, _viewClass) {
  var valueStream = isStream(property) ? property : this.getStream(property);
  var lazyValue;

  if (childProperties) {
    lazyValue = new SimpleStream(valueStream);

    var subscriber = function(childStream) {
      childStream.value();
      lazyValue.notify();
    };

    for (var i = 0; i < childProperties.length; i++) {
      var childStream = valueStream.get(childProperties[i]);
      childStream.value();
      childStream.subscribe(subscriber);
    }
  } else {
    lazyValue = valueStream;
  }

  // Set up observers for observable objects
  var viewClass = _viewClass || BoundView;
  var viewOptions = {
    _morph: options.morph,
    preserveContext: preserveContext,
    shouldDisplayFunc: shouldDisplay,
    valueNormalizerFunc: valueNormalizer,
    displayTemplate: options.template,
    inverseTemplate: options.inverse,
    lazyValue: lazyValue,
    previousContext: get(this, 'context'),
    templateHash: hash,
    helperName: options.helperName
  };

  if (options.keywords) {
    viewOptions._keywords = options.keywords;
  }

  // Create the view that will wrap the output of this template/property
  // and add it to the nearest view's childViews array.
  // See the documentation of Ember._BoundView for more.
  var bindView = this.createChildView(viewClass, viewOptions);

  this.appendChild(bindView);

  lazyValue.subscribe(this._wrapAsScheduled(function() {
    run.scheduleOnce('render', bindView, 'rerenderIfNeeded');
  }));
}
Exemple #27
0
/**
  @private

  Use the `unboundIf` helper to create a conditional that evaluates once.

  ```handlebars
  {{#unboundIf "content.shouldDisplayTitle"}}
    {{content.title}}
  {{/unboundIf}}
  ```

  @method unboundIf
  @for Ember.Handlebars.helpers
  @param {String} property Property to bind
  @param {Function} fn Context to provide for rendering
  @return {String} HTML string
  @since 1.4.0
*/
function unboundIfHelper(params, hash, options, env) {
  var template = options.template;
  var value = params[0];

  if (isStream(params[0])) {
    value = params[0].value();
  }

  if (!shouldDisplayIfHelperContent(value)) {
    template = options.inverse;
  }

  return template.render(this, env, options.morph.contextualElement);
}
Exemple #28
0
function KeyStream(source, key) {
  Ember.assert("KeyStream error: source must be a stream", isStream(source)); // TODO: This isn't necessary.
  Ember.assert("KeyStream error: key must be a non-empty string", typeof key === 'string' && key.length > 0);
  Ember.assert("KeyStream error: key must not have a '.'", key.indexOf('.') === -1);

  // used to get the original path for debugging and legacy purposes
  var label = labelFor(source, key);

  this.init(label);
  this.path = label;
  this.sourceDep = this.addMutableDependency(source);
  this.observedObject = null;
  this.key = key;
}
Exemple #29
0
export default function attribute(env, morph, element, attrName, attrValue) {
  if (boundAttributesEnabled) {
    var attrNode = new AttrNode(attrName, attrValue);
    attrNode._morph = morph;
    env.data.view.appendChild(attrNode);
  } else {
    if (isStream(attrValue)) {
      throw new EmberError('Bound attributes are not yet supported in Ember.js');
    } else {
      var sanitizedValue = sanitizeAttributeValue(element, attrName, attrValue);
      env.dom.setProperty(element, attrName, sanitizedValue);
    }
  }
}
export default function shouldDisplay(predicate) {
  if (isStream(predicate)) {
    return new ShouldDisplayStream(predicate);
  }

  var truthy = predicate && get(predicate, 'isTruthy');
  if (typeof truthy === 'boolean') { return truthy; }

  if (isArray(predicate)) {
    return get(predicate, 'length') !== 0;
  } else {
    return !!predicate;
  }
}