function Article()

in public/src/js/models/collections/article.js [93:212]


        function Article(opts, withCapiData) {
            var self = this;

            opts = opts || {};

            this.dropTarget = true;
            this.id = ko.observable(opts.id);

            this.group = opts.group;

            this.front = opts.group ? opts.group.front : null;

            this.props = asObservableProps(capiProps);
            this.props.webPublicationDate.extend({ notify: 'always' });

            this.fields = asObservableProps(capiFields);

            this.meta = asObservableProps(_.pluck(metaFields, 'key'));

            populateObservables(this.meta, opts.meta);

            this.metaDefaults = {};

            this.collectionMetaDefaults = deepGet(opts, '.group.parent.itemDefaults');

            this.uneditable = opts.uneditable;

            this.state = asObservableProps([
                'enableContentOverrides',
                'underDrag',
                'underControlDrag',
                'isOpen',
                'isLiveBlog',
                'isLoaded',
                'isEmpty',
                'visited',
                'tone',
                'primaryTag',
                'sectionName',
                'hasMainVideo',
                'imageCutoutSrcFromCapi',
                'ophanUrl',
                'sparkUrl',
                'premium']);

            this.state.enableContentOverrides(this.meta.snapType() !== 'latest');
            this.state.visited(opts.visited);

            this.frontPublicationDate = opts.frontPublicationDate;
            this.publishedBy = opts.publishedBy;
            this.frontPublicationTime = ko.observable();
            this.scheduledPublicationTime = ko.observable();

            this.editors = ko.observableArray();

            this.editorsDisplay = ko.observableArray();

            this.headline = ko.pureComputed(function () {
                var meta = this.meta, fields = this.fields;
                if (this.state.enableContentOverrides()) {
                    return meta.headline() || fields.headline() || (meta.snapType() ? 'No headline!' : 'Loading...');
                } else {
                    return '{ ' + meta.customKicker() + ' }';
                }
            }, this);

            this.headlineLength = ko.pureComputed(function() {
                return (this.meta.headline() || this.fields.headline() || '').length;
            }, this);

            this.headlineLengthAlert = ko.pureComputed(function() {
                return (this.meta.headline() || this.fields.headline() || '').length > vars.CONST.restrictedHeadlineLength;
            }, this);


            this.webPublicationTime = ko.pureComputed(function(){
                return humanTime(this.props.webPublicationDate());
            }, this);

            this.viewUrl = ko.pureComputed(function() {
                var url;
                if (this.fields.isLive() === 'false') {
                    url = vars.CONST.previewBase + '/' + urlAbsPath(this.props.webUrl());
                } else {
                    url = this.meta.href() || this.props.webUrl();

                    if (url && !/^https?:\/\//.test(url)) {
                        url = 'http://' + vars.CONST.mainDomain + url;
                    }
                }

                return url;
            }, this);

            // Populate supporting
            if (this.group && this.group.parentType !== 'Article') {
                this.meta.supporting = new Group({
                    parent: self,
                    parentType: 'Article',
                    omitItem: self.save.bind(self),
                    front: self.front
                });

                this.meta.supporting.items(_.map((opts.meta || {}).supporting, function (item) {
                    return new Article(_.extend(item, {
                        group: self.meta.supporting
                    }));
                }));

                contentApi.decorateItems(this.meta.supporting.items());
            }

            if (withCapiData) {
                this.addCapiData(opts);
            } else {
                this.updateEditorsDisplay();
            }

            this.thumbImage = ko.pureComputed(images.thumbnail, this);
        }