<commit_before>'use strict';

/**
 * Module dependencies.
 */
var path = require('path'),
  mongoose = require('mongoose'),
  Poll = mongoose.model('Poll'),
  Opt = mongoose.model('Opt'),
  Vote = mongoose.model('Vote'),
  Voteopt = mongoose.model('Voteopt'),
  Polltag = mongoose.model('Polltag'),
  Pollreport = mongoose.model('Pollreport'),
  Polluser = mongoose.model('Polluser'),
  Report = mongoose.model('Report'),
  Bookmark = mongoose.model('Bookmark'),
  Like = mongoose.model('Like'),
  errorHandler = require(path.resolve(
    './modules/core/server/controllers/errors.server.controller'
  )),
  _ = require('lodash');
/**
 * Create a Poll
 */
exports.create = function(req, res) {
  var poll = new Poll(req.body);
  poll.user = req.user;

  var tags = req.body.tags || [];
  var opts = req.body.opts || [];
  var promises = [];

  poll.save()
    .then(_poll => {
      poll = _poll;
      // Tạo report cho poll
      var report = new Pollreport({ poll: poll._id });
      return report.save();
    }, handleError)
    .then(_report => {
      // Lưu tag vào db
      tags.forEach(tag => {
        var polltag = new Polltag({ tag: tag, poll: poll._id });
        promises.push(polltag.save());
      });
      return Promise.all(promises);
    }, handleError)
    .then(() => {
      // Lưu options vào db
      promises = [];
      opts.forEach(opt => {
        var _opt = new Opt(opt);
        _opt.user = req.user;
        _opt.poll = poll._id;
        promises.push(_opt.save());
      });
      return Promise.all(promises);
    }, handleError)
    .then(() => {
      // Tạo biến follow mới
      promises = [];
      var _polluser = new Polluser({ poll: poll._id, user: req.user._id });
      return _polluser.save();
    }, handleError)
    .then(_polluser => {
      res.jsonp(poll);
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Show the current Poll
 */
exports.read = function(req, res) {
  // convert mongoose document to JSON
  var poll = req.poll ? req.poll.toJSON() : {};

  // Add a custom field to the Article, for determining if the current User is the "owner".
  // NOTE: This field is NOT persisted to the database, since it doesn't exist in the Article model.
  poll.isCurrentUserOwner =
    req.user &&
    poll.user &&
    poll.user._id.toString() === req.user._id.toString();
  poll.canEdit =
    req.user &&
    req.user.roles &&
    req.user.roles.length &&
    req.user.roles.indexOf('admin') > -1;

  res.jsonp(poll);
};

/**
 * Update a Poll
 */
exports.update = function(req, res) {
  var poll = req.poll;
  poll = _.extend(poll, req.body);
  var tags = req.body.tags || [];
  var opts = req.body.opts || [];
  var promises = [];
  poll.save()
    .then(_poll => {
      poll = _poll;
      return Polltag.remove({ poll: _poll._id });
    }, handleError)
    .then(() => {
      tags.forEach(tag => {
        var polltag = new Polltag({ tag: tag, poll: poll._id });
        promises.push(polltag.save());
      });
      return Promise.all(promises);
    }, handleError)
    .then(() => {
      promises = [];
      opts.forEach(opt => {
        if (opt._id) {
          promises.push(
            Opt.update(
              {
                _id: opt._id
              },
              {
                $set: {
                  title: opt.title,
                  color: opt.color,
                  body: opt.body
                }
              }
            ).exec()
          );
        } else {
          var _opt = new Opt(opt);
          _opt.user = req.user;
          _opt.poll = poll;
          promises.push(_opt.save());
        }
      });
      return Promise.all(promises);
    }, handleError)
    .then(_opts => {
      promises = [];
      res.jsonp(poll);
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Delete an Poll
 */
exports.delete = function(req, res) {
  var poll = req.poll;
  poll.remove()
    .then(() => {
      return Opt.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      var promises = [];
      Vote.find({ poll: poll._id }).exec((err, votes) => {
        votes.forEach(vote => {
          promises.push(Voteopt.remove({ vote: vote._id }));
        });
      });
      return Promise.all(promises);
    }, handleError)
    .then(() => {
      return Vote.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Pollreport.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Polltag.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Report.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Bookmark.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Like.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      res.jsonp(poll);
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * List of Polls
 */
exports.list = function(req, res) {
  Poll.find()
    .sort('-created')
    .populate('category', 'name icon')
    .populate('user', 'displayName profileImageURL')
    .exec(function(err, polls) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(polls);
      }
    });
};

/**
 * List of Offset
 */
exports.findPolls = function(req, res) {
  var page = req.params.page || 0;
  Poll.find({ isPublic: true })
    .sort('-created')
    .populate('category', 'name icon')
    .populate('user', 'displayName profileImageURL')
    .skip(10 * page)
    .limit(10)
    .exec(function(err, polls) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(polls);
      }
    });
};

/**
 * List of Hot
 */
exports.findHotPolls = function(req, res) {
  var page = req.params.page || 0;
  Poll.find({ isPublic: true })
    .sort('-likeCnt')
    .populate('category', 'name icon')
    .populate('user', 'displayName profileImageURL')
    .skip(10 * page)
    .limit(10)
    .exec(function(err, polls) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(polls);
      }
    });
};

/**
 * List of Opts in poll
 */
exports.findOpts = function(req, res) {
  Poll.findOpts(req.poll._id)
    .populate('user', 'displayName')
    .exec(function(err, opts) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(opts);
      }
    });
};

/**
 * List of Cmts in poll
 */
exports.findCmts = function(req, res) {
  var page = req.params.page || 0;
  Poll.findCmts(req.poll._id)
    .sort('-created')
    .populate('user', 'displayName profileImageURL')
    .skip(10 * page)
    .limit(10)
    .exec(function(err, cmts) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(cmts);
      }
    });
};

/**
 * List of Tags in poll
 */
exports.findTags = function(req, res) {
  Poll.findTags(req.poll._id).populate('tag').exec(function(err, polltags) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(polltags);
    }
  });
};

/**
 * List of Votes in poll
 */
exports.findVotes = function(req, res) {
  Poll.findVotes(req.poll._id).exec(function(err, votes) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(votes);
    }
  });
};

/**
 * Vote in poll of user
 */
exports.findOwnerVote = function(req, res) {
  var condition = {};
  condition.poll = req.poll._id;
  if (req.user) {
    condition.user = req.user._id;
    condition.guest = false;
  } else {
    condition.ip =
      req.headers['X-Forwarded-For'] ||
      req.headers['x-forwarded-for'] ||
      req.client.remoteAddress;
    condition.guest = true;
  }
  Poll.findOwnerVote(condition).exec(function(err, vote) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(vote);
    }
  });
};

/**
 * Get all info of vote in poll
 */
exports.findVoteopts = function(req, res) {
  var rs = {}, ids;
  Poll.findVotes(req.poll._id).exec(function(err, _votes) {
    if (err) {
      handleError(err);
    } else {
      rs.votes = _votes;
      rs.voteopts = [];
      ids = _.pluck(_votes, '_id');
      Voteopt.find({ vote: { $in: ids } }).exec(function(err, opts) {
        if (err) {
          handleError(err);
        } else {
          rs.voteopts = opts;
          res.jsonp(rs);
        }
      });
    }
  });

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Get Like of user on this poll
 */
exports.findPollLike = function(req, res) {
  var condition = { poll: req.poll._id, user: req.user._id };
  Like.findOne(condition).exec(function(err, like) {
    if (err) {
      handleError(err);
    } else {
      res.jsonp(like);
    }
  });

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Find pollusers
 */
exports.findPolluser = function(req, res) {
  Polluser.findOne({
    poll: req.poll._id,
    user: req.user._id
  }).exec((err, _polluser) => {
    if (err) {
      handleError(err);
    } else {
      res.jsonp(_polluser);
    }
  });
  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Find report
 */
exports.findReport = function(req, res) {
  Report.findOne({
    poll: req.poll._id,
    user: req.user._id
  }).exec((err, _report) => {
    if (err) {
      handleError(err);
    } else {
      var result = (_report) ? true : false;
      res.jsonp(result);
    }
  });
  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Find report
 */
exports.findBookmark = function(req, res) {
  Bookmark.findOne({
    poll: req.poll._id,
    user: req.user._id
  }).exec((err, _bookmark) => {
    if (err) {
      handleError(err);
    } else {
      var result = (_bookmark) ? true : false;
      res.jsonp(result);
    }
  });
  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};
/**
 * Poll middleware
 */
exports.pollByID = function(req, res, next, id) {
  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).send({
      message: 'Poll is invalid'
    });
  }

/**
 * Find report
 */
exports.findPollreport = function(req, res) {
  Pollreport.findOne({ poll: req.poll._id }).exec((err, _report) => {
    if (err) {
      handleError(err);
    } else {
      res.jsonp(_report);
    }
  });
  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

  Poll.findById(id)
    .populate('category', 'name icon')
    .populate('user', 'displayName profileImageURL')
    .exec(function(err, poll) {
      if (err) {
        return next(err);
      } else if (!poll) {
        return res.status(404).send({
          message: 'No Poll with that identifier has been found'
        });
      }
      req.poll = poll;
      next();
    });
};
<commit_msg>Commited from lenh at Thu, Jul 06, 2017  9:43:27 AM<commit_after>'use strict';

/**
 * Module dependencies.
 */
var path = require('path'),
  mongoose = require('mongoose'),
  Poll = mongoose.model('Poll'),
  Opt = mongoose.model('Opt'),
  Vote = mongoose.model('Vote'),
  Voteopt = mongoose.model('Voteopt'),
  Polltag = mongoose.model('Polltag'),
  Pollreport = mongoose.model('Pollreport'),
  Polluser = mongoose.model('Polluser'),
  Report = mongoose.model('Report'),
  Bookmark = mongoose.model('Bookmark'),
  Like = mongoose.model('Like'),
  errorHandler = require(path.resolve(
    './modules/core/server/controllers/errors.server.controller'
  )),
  _ = require('lodash');
/**
 * Create a Poll
 */
exports.create = function(req, res) {
  var poll = new Poll(req.body);
  poll.user = req.user;

  var tags = req.body.tags || [];
  var opts = req.body.opts || [];
  var promises = [];

  poll
    .save()
    .then(_poll => {
      poll = _poll;
      // Tạo report cho poll
      var report = new Pollreport({ poll: poll._id });
      return report.save();
    }, handleError)
    .then(_report => {
      // Lưu tag vào db
      tags.forEach(tag => {
        var polltag = new Polltag({ tag: tag, poll: poll._id });
        promises.push(polltag.save());
      });
      return Promise.all(promises);
    }, handleError)
    .then(() => {
      // Lưu options vào db
      promises = [];
      opts.forEach(opt => {
        var _opt = new Opt(opt);
        _opt.user = req.user;
        _opt.poll = poll._id;
        promises.push(_opt.save());
      });
      return Promise.all(promises);
    }, handleError)
    .then(() => {
      // Tạo biến follow mới
      promises = [];
      var _polluser = new Polluser({ poll: poll._id, user: req.user._id });
      return _polluser.save();
    }, handleError)
    .then(_polluser => {
      res.jsonp(poll);
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Show the current Poll
 */
exports.read = function(req, res) {
  // convert mongoose document to JSON
  var poll = req.poll ? req.poll.toJSON() : {};

  // Add a custom field to the Article, for determining if the current User is the "owner".
  // NOTE: This field is NOT persisted to the database, since it doesn't exist in the Article model.
  poll.isCurrentUserOwner =
    req.user &&
    poll.user &&
    poll.user._id.toString() === req.user._id.toString();
  poll.canEdit =
    req.user &&
    req.user.roles &&
    req.user.roles.length &&
    req.user.roles.indexOf('admin') > -1;

  res.jsonp(poll);
};

/**
 * Update a Poll
 */
exports.update = function(req, res) {
  var poll = req.poll;
  poll = _.extend(poll, req.body);
  var tags = req.body.tags || [];
  var opts = req.body.opts || [];
  var promises = [];
  poll
    .save()
    .then(_poll => {
      poll = _poll;
      return Polltag.remove({ poll: _poll._id });
    }, handleError)
    .then(() => {
      tags.forEach(tag => {
        var polltag = new Polltag({ tag: tag, poll: poll._id });
        promises.push(polltag.save());
      });
      return Promise.all(promises);
    }, handleError)
    .then(() => {
      promises = [];
      opts.forEach(opt => {
        if (opt._id) {
          promises.push(
            Opt.update(
              {
                _id: opt._id
              },
              {
                $set: {
                  title: opt.title,
                  color: opt.color,
                  body: opt.body
                }
              }
            ).exec()
          );
        } else {
          var _opt = new Opt(opt);
          _opt.user = req.user;
          _opt.poll = poll;
          promises.push(_opt.save());
        }
      });
      return Promise.all(promises);
    }, handleError)
    .then(_opts => {
      promises = [];
      res.jsonp(poll);
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Delete an Poll
 */
exports.delete = function(req, res) {
  var poll = req.poll;
  poll
    .remove()
    .then(() => {
      return Opt.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      var promises = [];
      Vote.find({ poll: poll._id }).exec((err, votes) => {
        votes.forEach(vote => {
          promises.push(Voteopt.remove({ vote: vote._id }));
        });
      });
      return Promise.all(promises);
    }, handleError)
    .then(() => {
      return Vote.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Pollreport.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Polltag.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Report.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Bookmark.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      return Like.remove({ poll: poll._id });
    }, handleError)
    .then(() => {
      res.jsonp(poll);
    }, handleError);

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * List of Polls
 */
exports.list = function(req, res) {
  Poll.find()
    .sort('-created')
    .populate('category', 'name icon')
    .populate('user', 'displayName profileImageURL')
    .exec(function(err, polls) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(polls);
      }
    });
};

/**
 * List of Offset
 */
exports.findPolls = function(req, res) {
  var page = req.params.page || 0;
  Poll.find({ isPublic: true })
    .sort('-created')
    .populate('category', 'name icon')
    .populate('user', 'displayName profileImageURL')
    .skip(10 * page)
    .limit(10)
    .exec(function(err, polls) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(polls);
      }
    });
};

/**
 * List of Hot
 */
exports.findHotPolls = function(req, res) {
  var page = req.params.page || 0;
  Poll.find({ isPublic: true })
    .sort('-likeCnt')
    .populate('category', 'name icon')
    .populate('user', 'displayName profileImageURL')
    .skip(10 * page)
    .limit(10)
    .exec(function(err, polls) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(polls);
      }
    });
};

/**
 * List of Opts in poll
 */
exports.findOpts = function(req, res) {
  Poll.findOpts(req.poll._id)
    .populate('user', 'displayName')
    .exec(function(err, opts) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(opts);
      }
    });
};

/**
 * List of Cmts in poll
 */
exports.findCmts = function(req, res) {
  var page = req.params.page || 0;
  Poll.findCmts(req.poll._id)
    .sort('-created')
    .populate('user', 'displayName profileImageURL')
    .skip(10 * page)
    .limit(10)
    .exec(function(err, cmts) {
      if (err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      } else {
        res.jsonp(cmts);
      }
    });
};

/**
 * List of Tags in poll
 */
exports.findTags = function(req, res) {
  Poll.findTags(req.poll._id).populate('tag').exec(function(err, polltags) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(polltags);
    }
  });
};

/**
 * List of Votes in poll
 */
exports.findVotes = function(req, res) {
  Poll.findVotes(req.poll._id).exec(function(err, votes) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(votes);
    }
  });
};

/**
 * Vote in poll of user
 */
exports.findOwnerVote = function(req, res) {
  var condition = {};
  condition.poll = req.poll._id;
  if (req.user) {
    condition.user = req.user._id;
    condition.guest = false;
  } else {
    condition.ip =
      req.headers['X-Forwarded-For'] ||
      req.headers['x-forwarded-for'] ||
      req.client.remoteAddress;
    condition.guest = true;
  }
  Poll.findOwnerVote(condition).exec(function(err, vote) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(vote);
    }
  });
};

/**
 * Get all info of vote in poll
 */
exports.findVoteopts = function(req, res) {
  var rs = {}, ids;
  Poll.findVotes(req.poll._id).exec(function(err, _votes) {
    if (err) {
      handleError(err);
    } else {
      rs.votes = _votes;
      rs.voteopts = [];
      ids = _.pluck(_votes, '_id');
      Voteopt.find({ vote: { $in: ids } }).exec(function(err, opts) {
        if (err) {
          handleError(err);
        } else {
          rs.voteopts = opts;
          res.jsonp(rs);
        }
      });
    }
  });

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Get Like of user on this poll
 */
exports.findPollLike = function(req, res) {
  var condition = { poll: req.poll._id, user: req.user._id };
  Like.findOne(condition).exec(function(err, like) {
    if (err) {
      handleError(err);
    } else {
      res.jsonp(like);
    }
  });

  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Find pollusers
 */
exports.findPolluser = function(req, res) {
  Polluser.findOne({
    poll: req.poll._id,
    user: req.user._id
  }).exec((err, _polluser) => {
    if (err) {
      handleError(err);
    } else {
      res.jsonp(_polluser);
    }
  });
  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Find report
 */
exports.findReport = function(req, res) {
  Report.findOne({
    poll: req.poll._id,
    user: req.user._id
  }).exec((err, _report) => {
    if (err) {
      handleError(err);
    } else {
      var result = _report ? true : false;
      res.jsonp(result);
    }
  });
  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};

/**
 * Find report
 */
exports.findBookmark = function(req, res) {
  Bookmark.findOne({
    poll: req.poll._id,
    user: req.user._id
  }).exec((err, _bookmark) => {
    if (err) {
      handleError(err);
    } else {
      var result = _bookmark ? true : false;
      res.jsonp(result);
    }
  });
  function handleError(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  }
};
/**
 * Poll middleware
 */
exports.pollByID = function(req, res, next, id) {
  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).send({
      message: 'Poll is invalid'
    });
  }

  /**
 * Find report
 */
  exports.findPollreport = function(req, res) {
    Pollreport.findOne({ poll: req.poll._id }).exec((err, _report) => {
      if (err) {
        handleError(err);
      } else {
        res.jsonp(_report);
      }
    });
    function handleError(err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    }
  };

  Poll.findById(id)
    .populate('category', 'name icon')
    .populate('user', 'displayName profileImageURL')
    .exec(function(err, poll) {
      if (err) {
        return next(err);
      } else if (!poll) {
        return res.status(404).send({
          message: 'No Poll with that identifier has been found'
        });
      }
      req.poll = poll;
      next();
    });
};
<|endoftext|>


<commit_before>/**
 * @file ColorPicker component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import sum from 'lodash/sum';
import classNames from 'classnames';

import Dom from '../_vendors/Dom';
import Event from '../_vendors/Event';
import Valid from '../_vendors/Valid';
import Color from '../_vendors/Color';
import ComponentUtil from '../_vendors/ComponentUtil';

class ColorPicker extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        const hsb = Color.rgb2hsb(Color.hex2rgb(props.value));
        this.state = {
            value: props.value,
            s: hsb ? hsb[1] : 0,
            b: hsb ? hsb[2] : 0,
            x: hsb ? `${hsb[1] * 100}%` : 0,
            y: hsb ? `${(1 - hsb[2]) * 100}%` : 0
        };

        this.activated = false;

    }

    mouseDownHandler = e => {
        this.activated = true;
        this.handleChange(e.pageX, e.pageY);
    };

    mouseMoveHandler = e => {
        if (this.activated) {
            this.handleChange(e.pageX, e.pageY);
        }
    };

    mouseUpHandler = () => {
        this.activated = false;
    };

    /**
     * handle mouse event to calc new value
     * @param mouseX
     * @param mouseY
     */
    handleChange = (mouseX, mouseY) => {

        const {hue} = this.props,
            width = this.colorPickerAreaEl.offsetWidth,
            height = this.colorPickerAreaEl.offsetHeight,
            {left, top} = Dom.getOffset(this.colorPickerAreaEl),

            x = Valid.range(mouseX - left, 0, width),
            y = Valid.range(mouseY - top, 0, height),

            s = x / width,
            b = 1 - y / height,

            value = Color.rgb2hex(Color.hsb2rgb([hue, s, b]));

        this.setState({
            value,
            s,
            b,
            x,
            y
        }, () => {
            const {onChange} = this.props;
            onChange && onChange(value);
        });

    };

    componentDidMount() {

        this.colorPickerAreaEl = this.refs.colorPickerArea;

        Event.addEvent(document, 'mousemove', this.mouseMoveHandler);
        Event.addEvent(document, 'mouseup', this.mouseUpHandler);

    }

    componentWillUnmount() {
        Event.removeEvent(document, 'mousemove', this.mouseMoveHandler);
        Event.removeEvent(document, 'mouseup', this.mouseUpHandler);
    }

    static getDerivedStateFromProps(props, state) {

        const value = ComponentUtil.getDerivedState(props, state, 'value');

        if (value === state.value) {
            return null;
        }

        const hsb = Color.rgb2hsb(Color.hex2rgb(value));
        return {
            prevProps: props,
            value,
            s: hsb ? hsb[1] : 0,
            b: hsb ? hsb[2] : 0,
            x: hsb ? `${hsb[1] * 100}%` : 0,
            y: hsb ? `${(1 - hsb[2]) * 100}%` : 0
        };

    }

    // handleHueChange = hue => {
    //
    //     const {hsb} = this.state;
    //     hsb[0] = hue;
    //
    //     const value = Color.hsb2rgb(hsb);
    //
    //     this.setState({
    //         value,
    //         hsb
    //     }, () => {
    //         const {onChange} = this.props;
    //         onChange && onChange(value);
    //     });
    //
    // };

    render() {

        const {className, style, hue} = this.props,
            {value, x, y} = this.state,

            pickerClassName = classNames('color-picker', {
                [className]: className
            }),

            areaColor = Color.hue2rgb(hue),
            areaStyle = {
                background: areaColor ? `rgb(${areaColor.join(', ')})` : null
            },

            cursorClassName = classNames('color-picker-cursor', {
                light: sum(Color.hex2rgb(value)) / 3 < 128
            }),
            cursorStyle = {
                left: x,
                top: y
            };

        return (

        );

    }
}

ColorPicker.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * hue value (deg)
     */
    hue: PropTypes.number,

    /**
     * rgb hex value
     */
    value: PropTypes.string

};

ColorPicker.defaultProps = {
    hue: 0,
    value: 'ff0000'
};

export default ColorPicker;
<commit_msg>update ColorPicker<commit_after>/**
 * @file ColorPicker component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component, createRef} from 'react';
import PropTypes from 'prop-types';
import sum from 'lodash/sum';
import classNames from 'classnames';

import Dom from '../_vendors/Dom';
import Event from '../_vendors/Event';
import Valid from '../_vendors/Valid';
import Color from '../_vendors/Color';
import ComponentUtil from '../_vendors/ComponentUtil';

class ColorPicker extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.activated = false;
        this.colorPickerArea = createRef();
        this.colorPickerAreaEl = null;

        const hsb = Color.rgb2hsb(Color.hex2rgb(props.value));
        this.state = {
            value: props.value,
            s: hsb ? hsb[1] : 0,
            b: hsb ? hsb[2] : 0,
            x: hsb ? `${hsb[1] * 100}%` : 0,
            y: hsb ? `${(1 - hsb[2]) * 100}%` : 0
        };

    }

    handleMouseDown = e => {
        this.activated = true;
        this.handleChange(e.pageX, e.pageY);
    };

    handleMouseMove = e => {
        if (this.activated) {
            this.handleChange(e.pageX, e.pageY);
        }
    };

    handleMouseUp = () => {
        this.activated = false;
    };

    /**
     * handle mouse event to calc new value
     * @param mouseX
     * @param mouseY
     */
    handleChange = (mouseX, mouseY) => {

        const {hue} = this.props,
            width = this.colorPickerAreaEl.offsetWidth,
            height = this.colorPickerAreaEl.offsetHeight,
            {left, top} = Dom.getOffset(this.colorPickerAreaEl),

            x = Valid.range(mouseX - left, 0, width),
            y = Valid.range(mouseY - top, 0, height),

            s = x / width,
            b = 1 - y / height,

            value = Color.rgb2hex(Color.hsb2rgb([hue, s, b]));

        this.setState({
            value,
            s,
            b,
            x,
            y
        }, () => {
            const {onChange} = this.props;
            onChange && onChange(value);
        });

    };

    componentDidMount() {

        this.colorPickerAreaEl = this.colorPickerArea && this.colorPickerArea.current;

        Event.addEvent(document, 'mousemove', this.handleMouseMove);
        Event.addEvent(document, 'mouseup', this.handleMouseUp);

    }

    componentWillUnmount() {
        Event.removeEvent(document, 'mousemove', this.handleMouseMove);
        Event.removeEvent(document, 'mouseup', this.handleMouseUp);
    }

    static getDerivedStateFromProps(props, state) {

        const value = ComponentUtil.getDerivedState(props, state, 'value');

        if (value === state.value) {
            return null;
        }

        const hsb = Color.rgb2hsb(Color.hex2rgb(value));
        return {
            prevProps: props,
            value,
            s: hsb ? hsb[1] : 0,
            b: hsb ? hsb[2] : 0,
            x: hsb ? `${hsb[1] * 100}%` : 0,
            y: hsb ? `${(1 - hsb[2]) * 100}%` : 0
        };

    }

    // handleHueChange = hue => {
    //
    //     const {hsb} = this.state;
    //     hsb[0] = hue;
    //
    //     const value = Color.hsb2rgb(hsb);
    //
    //     this.setState({
    //         value,
    //         hsb
    //     }, () => {
    //         const {onChange} = this.props;
    //         onChange && onChange(value);
    //     });
    //
    // };

    render() {

        const {className, style, hue} = this.props,
            {value, x, y} = this.state,
            areaColor = Color.hue2rgb(hue);

        return (

                <div ref={this.colorPickerArea}
                     className="color-picker-area"
                     style={{
                         background: areaColor ? `rgb(${areaColor.join(', ')})` : null
                     }}
                     onMouseDown={this.handleMouseDown}>

                    <div className={classNames('color-picker-cursor', {
                        light: sum(Color.hex2rgb(value)) / 3 < 128
                    })}
                         style={{
                             left: x,
                             top: y
                         }}>

        );

    }
}

ColorPicker.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * hue value (deg)
     */
    hue: PropTypes.number,

    /**
     * rgb hex value
     */
    value: PropTypes.string,

    onChange: PropTypes, func

};

ColorPicker.defaultProps = {
    hue: 0,
    value: 'ff0000'
};

export default ColorPicker;
<|endoftext|>


<commit_before>define(function(require) {
  'use strict';

  var module = require('../module');

  module.factory('MenuConfig', MenuConfig);

  //---

  MenuConfig.$inject = ['$rootScope', '$location'];

  function MenuConfig($scope, $location) {

    var menuItemFn,
        addMenuItemFn,
        selectMenuItemFn,
        checkLocationFn,
        menuItemSelected = null,
        locationsMap = {},
        menuItems = {
          left: [],
          right: []
        };

    //--- @begin: internal functions
    menuItemFn = function(label, location, css) {
      return {
        label: label,
        location: '/'+location,
        url: '#'+location,
        css: (css || '') // 'active'
      };
    };

    addMenuItemFn = function(label, location, position) {
      position = position || 'left';
      var menuItem = menuItemFn(label, location);
      locationsMap[menuItem.location] = menuItem;

      switch(position){
        case 'left':
          menuItems.left.push(menuItem);
          break;
        case 'right':
          menuItems.right.push(menuItem);
          break;
      }

    };

    selectMenuItemFn = function(item) {
      if(item !== menuItemSelected) {
        if(menuItemSelected !== null) menuItemSelected.css = '';
        item.css = 'active';
        menuItemSelected = item;
      }
    };

    checkLocationFn = function() {
      var path, splitArr, location;

      path = $location.path();
      splitArr = path.split('/');
      if(splitArr.length > 2) {
        path = '/'+splitArr[1];
        splitArr = null;
      }

      location = locationsMap[path];
      if(location) {
        selectMenuItemFn(location);
      } else {
        if(menuItemSelected !== null) {
          menuItemSelected.css = '';
          menuItemSelected = null;
        }
      }
    };
    //--- @end: internal functions

    //--- @begin: $scope config
    $scope.menuItems = menuItems;

    $scope.location = $location;
    $scope.$watch("location.path()", checkLocationFn, true);
    //--- @end: $scope config

    //--- @begin: public functions
    return {
      addMenuItem: addMenuItemFn
    };
    //--- @end: public functions

  }

});
<commit_msg>fend/navbar code style update #32<commit_after>define(function(require) {
  'use strict';

  var module = require('../module');

  module.factory('MenuConfig', MenuConfig);

  //---

  MenuConfig.$inject = ['$rootScope', '$location'];

  function MenuConfig($scope, $location) {

    var menuItemSelected = null,
        locationsMap = {},
        menuItems = {
          left: [],
          right: []
        };

    var service = {
      addMenuItem: addMenuItemFn
    };

    //--- @begin: $scope config
    $scope.menuItems = menuItems;

    $scope.location = $location;
    $scope.$watch("location.path()", checkLocationFn, true);
    //--- @end: $scope config

    return service;

    //---

    //--- @begin: internal functions
    function menuItemFn(label, location, css) {
      return {
        label: label,
        location: '/'+location,
        url: '#'+location,
        css: (css || '') // 'active'
      };
    }

    function addMenuItemFn(label, location, position) {
      position = position || 'left';
      var menuItem = menuItemFn(label, location);
      locationsMap[menuItem.location] = menuItem;

      switch(position){
        case 'left':
          menuItems.left.push(menuItem);
          break;
        case 'right':
          menuItems.right.push(menuItem);
          break;
      }
    }

    function selectMenuItemFn(item) {
      if(item !== menuItemSelected) {
        if(menuItemSelected !== null) menuItemSelected.css = '';
        item.css = 'active';
        menuItemSelected = item;
      }
    }

    function checkLocationFn() {
      var path, splitArr, location;

      path = $location.path();
      splitArr = path.split('/');
      if(splitArr.length > 2) {
        path = '/'+splitArr[1];
        splitArr = null;
      }

      location = locationsMap[path];
      if(location) {
        selectMenuItemFn(location);
      } else {
        if(menuItemSelected !== null) {
          menuItemSelected.css = '';
          menuItemSelected = null;
        }
      }
    }
    //--- @end: internal functions

  }

});
<|endoftext|>


<commit_before>goog.provide('gmf.mobileMeasurelengthDirective');

goog.require('gmf');
goog.require('ngeo.DecorateInteraction');
/** @suppress {extraRequire} */
goog.require('ngeo.filters');
goog.require('ngeo.interaction.MeasureLengthMobile');
goog.require('ngeo.interaction.MobileDraw');
goog.require('ol.style.Fill');
goog.require('ol.style.RegularShape');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');

gmf.module.value('gmfMobileMeasureLengthTemplateUrl',
  /**
     * @param {angular.JQLite} element Element.
     * @param {angular.Attributes} attrs Attributes.
     * @return {string} The template url.
     */
  (element, attrs) => {
    const templateUrl = attrs['gmfMobileMeasureLengthTemplateurl'];
    return templateUrl !== undefined ? templateUrl :
      `${gmf.baseTemplateUrl}/mobilemeasurelength.html`;
  });

/**
 * Provide a directive to do a length measure on the mobile devices.
 *
 * Example:
 *
 *      <div gmf-mobile-measurelength
 *        gmf-mobile-measurelength-active="ctrl.measureLengthActive"
 *        gmf-mobile-measurelength-map="::ctrl.map">
 *      </div>
 *
 * @htmlAttribute {boolean} gmf-mobile-measurelength-active Used to active
 * or deactivate the component.
 * @htmlAttribute {number=} gmf-mobile-measurelength-precision the number of significant digits to display.
 * @htmlAttribute {ol.Map} gmf-mobile-measurelength-map The map.
 * @htmlAttribute {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction=}
 *     gmf-mobile-measurelength-sketchstyle A style for the measure length.
 * @param {string|function(!angular.JQLite=, !angular.Attributes=)}
 *     gmfMobileMeasureLengthTemplateUrl Template URL for the directive.
 * @return {angular.Directive} The Directive Definition Object.
 * @ngInject
 * @ngdoc directive
 * @ngname gmfMobileMeasureLength
 */
gmf.mobileMeasureLengthDirective =
    function(gmfMobileMeasureLengthTemplateUrl) {
      return {
        restrict: 'A',
        scope: {
          'active': '=gmfMobileMeasurelengthActive',
          'precision': '<?gmfMobileMeasurelengthPrecision',
          'map': '=gmfMobileMeasurelengthMap',
          'sketchStyle': '=?gmfMobileMeasurelengthSketchstyle'
        },
        controller: 'GmfMobileMeasureLengthController as ctrl',
        bindToController: true,
        templateUrl: gmfMobileMeasureLengthTemplateUrl,
        /**
         * @param {angular.Scope} scope Scope.
         * @param {angular.JQLite} element Element.
         * @param {angular.Attributes} attrs Attributes.
         * @param {gmf.MobileMeasureLengthController} controller Controller.
         */
        link(scope, element, attrs, controller) {
          controller.init();
        }
      };
    };

gmf.module.directive('gmfMobileMeasurelength',
  gmf.mobileMeasureLengthDirective);

/**
 * @param {!angular.Scope} $scope Angular scope.
 * @param {ngeo.DecorateInteraction} ngeoDecorateInteraction Decorate
 *     interaction service.
 * @param {angular.$filter} $filter Angular filter
 * @constructor
 * @private
 * @struct
 * @ngInject
 * @ngdoc controller
 * @ngname GmfMobileMeasureLengthController
 */
gmf.MobileMeasureLengthController = function($scope, ngeoDecorateInteraction, $filter) {

  /**
   * @type {ol.Map}
   * @export
   */
  this.map;

  /**
   * @type {boolean}
   * @export
   */
  this.active;

  $scope.$watch(() => this.active, (newVal) => {
    this.measure.setActive(newVal);
  });

  /**
   * @type {number|undefined}
   * @export
   */
  this.precision;

  /**
   * @type {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction}
   * @export
   */
  this.sketchStyle;

  if (this.sketchStyle === undefined) {
    this.sketchStyle = new ol.style.Style({
      fill: new ol.style.Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      }),
      stroke: new ol.style.Stroke({
        color: 'rgba(0, 0, 0, 0.5)',
        lineDash: [10, 10],
        width: 2
      }),
      image: new ol.style.RegularShape({
        stroke: new ol.style.Stroke({
          color: 'rgba(0, 0, 0, 0.7)',
          width: 2
        }),
        points: 4,
        radius: 8,
        radius2: 0,
        angle: 0
      })
    });
  }

  /**
   * @type {ngeo.interaction.MeasureLengthMobile}
   * @export
   */
  this.measure = new ngeo.interaction.MeasureLengthMobile($filter('ngeoUnitPrefix'), {
    precision: this.precision,
    sketchStyle: this.sketchStyle
  });

  this.measure.setActive(this.active);
  ngeoDecorateInteraction(this.measure);

  /**
   * @type {ngeo.interaction.MobileDraw}
   * @export
   */
  this.drawInteraction = /** @type {ngeo.interaction.MobileDraw} */ (
    this.measure.getDrawInteraction());

  const drawInteraction = this.drawInteraction;
  ngeoDecorateInteraction(drawInteraction);

  Object.defineProperty(this, 'hasPoints', {
    get() {
      return this.drawInteraction.getFeature() !== null;
    }
  });

  /**
   * @type {boolean}
   * @export
   */
  this.dirty = false;

  ol.events.listen(
    drawInteraction,
    ol.Object.getChangeEventType(
      ngeo.interaction.MobileDrawProperty.DIRTY),
    function() {
      this.dirty = drawInteraction.getDirty();

      // this is where the angular scope is forced to be applied. We
      // only need to do this when dirty, as going to "no being dirty"
      // is made by a click on a button where Angular is within scope
      if (this.dirty) {
        $scope.$apply();
      }
    },
    this
  );

  /**
   * @type {boolean}
   * @export
   */
  this.drawing = false;

  ol.events.listen(
    drawInteraction,
    ol.Object.getChangeEventType(
      ngeo.interaction.MobileDrawProperty.DRAWING),
    function() {
      this.drawing = drawInteraction.getDrawing();
    },
    this
  );

  /**
   * @type {boolean}
   * @export
   */
  this.valid = false;

  ol.events.listen(
    drawInteraction,
    ol.Object.getChangeEventType(
      ngeo.interaction.MobileDrawProperty.VALID),
    function() {
      this.valid = drawInteraction.getValid();
    },
    this
  );
};

/**
 * Initialise the controller.
 */
gmf.MobileMeasureLengthController.prototype.init = function() {
  this.map.addInteraction(this.measure);
};

/**
 * Add current sketch point to line measure
 * @export
 */
gmf.MobileMeasureLengthController.prototype.addPoint = function() {
  this.drawInteraction.addToDrawing();
};

/**
 * Clear the sketch feature
 * @export
 */
gmf.MobileMeasureLengthController.prototype.clear = function() {
  this.drawInteraction.clearDrawing();
};

/**
 * Finish line measure
 * @export
 */
gmf.MobileMeasureLengthController.prototype.finish = function() {
  this.drawInteraction.finishDrawing();
};

/**
 * Deactivate the directive.
 * @export
 */
gmf.MobileMeasureLengthController.prototype.deactivate = function() {
  this.active = false;
};

gmf.module.controller('GmfMobileMeasureLengthController',
  gmf.MobileMeasureLengthController);
<commit_msg>Move initialization into the appropriate function<commit_after>goog.provide('gmf.mobileMeasurelengthDirective');

goog.require('gmf');
goog.require('ngeo.DecorateInteraction');
/** @suppress {extraRequire} */
goog.require('ngeo.filters');
goog.require('ngeo.interaction.MeasureLengthMobile');
goog.require('ngeo.interaction.MobileDraw');
goog.require('ol.style.Fill');
goog.require('ol.style.RegularShape');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');

gmf.module.value('gmfMobileMeasureLengthTemplateUrl',
  /**
     * @param {angular.JQLite} element Element.
     * @param {angular.Attributes} attrs Attributes.
     * @return {string} The template url.
     */
  (element, attrs) => {
    const templateUrl = attrs['gmfMobileMeasureLengthTemplateurl'];
    return templateUrl !== undefined ? templateUrl :
      `${gmf.baseTemplateUrl}/mobilemeasurelength.html`;
  });

/**
 * Provide a directive to do a length measure on the mobile devices.
 *
 * Example:
 *
 *      <div gmf-mobile-measurelength
 *        gmf-mobile-measurelength-active="ctrl.measureLengthActive"
 *        gmf-mobile-measurelength-map="::ctrl.map">
 *      </div>
 *
 * @htmlAttribute {boolean} gmf-mobile-measurelength-active Used to active
 * or deactivate the component.
 * @htmlAttribute {number=} gmf-mobile-measurelength-precision the number of significant digits to display.
 * @htmlAttribute {ol.Map} gmf-mobile-measurelength-map The map.
 * @htmlAttribute {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction=}
 *     gmf-mobile-measurelength-sketchstyle A style for the measure length.
 * @param {string|function(!angular.JQLite=, !angular.Attributes=)}
 *     gmfMobileMeasureLengthTemplateUrl Template URL for the directive.
 * @return {angular.Directive} The Directive Definition Object.
 * @ngInject
 * @ngdoc directive
 * @ngname gmfMobileMeasureLength
 */
gmf.mobileMeasureLengthDirective =
    function(gmfMobileMeasureLengthTemplateUrl) {
      return {
        restrict: 'A',
        scope: {
          'active': '=gmfMobileMeasurelengthActive',
          'precision': '<?gmfMobileMeasurelengthPrecision',
          'map': '=gmfMobileMeasurelengthMap',
          'sketchStyle': '=?gmfMobileMeasurelengthSketchstyle'
        },
        controller: 'GmfMobileMeasureLengthController as ctrl',
        bindToController: true,
        templateUrl: gmfMobileMeasureLengthTemplateUrl,
        /**
         * @param {angular.Scope} scope Scope.
         * @param {angular.JQLite} element Element.
         * @param {angular.Attributes} attrs Attributes.
         * @param {gmf.MobileMeasureLengthController} controller Controller.
         */
        link(scope, element, attrs, controller) {
          controller.init();
        }
      };
    };

gmf.module.directive('gmfMobileMeasurelength',
  gmf.mobileMeasureLengthDirective);

/**
 * @param {!angular.Scope} $scope Angular scope.
 * @param {ngeo.DecorateInteraction} ngeoDecorateInteraction Decorate
 *     interaction service.
 * @param {angular.$filter} $filter Angular filter
 * @constructor
 * @private
 * @struct
 * @ngInject
 * @ngdoc controller
 * @ngname GmfMobileMeasureLengthController
 */
gmf.MobileMeasureLengthController = function($scope, ngeoDecorateInteraction, $filter) {

  /**
   * @type {angular.Scope}
   * @private
   */
  this.scope_ = $scope;

  /**
   * @type {ngeo.DecorateInteraction}
   * @private
   */
  this.ngeoDecorateInteraction_ = ngeoDecorateInteraction;

  /**
   * @type {angular.$filter}
   * @private
   */
  this.filter_ = $filter;

  /**
   * @type {ol.Map}
   * @export
   */
  this.map;

  /**
   * @type {boolean}
   * @export
   */
  this.active;

  this.scope_.$watch(() => this.active, (newVal) => {
    this.measure.setActive(newVal);
  });

  /**
   * @type {number|undefined}
   * @export
   */
  this.precision;

  /**
   * @type {ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction}
   * @export
   */
  this.sketchStyle = new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 255, 255, 0.2)'
    }),
    stroke: new ol.style.Stroke({
      color: 'rgba(0, 0, 0, 0.5)',
      lineDash: [10, 10],
      width: 2
    }),
    image: new ol.style.RegularShape({
      stroke: new ol.style.Stroke({
        color: 'rgba(0, 0, 0, 0.7)',
        width: 2
      }),
      points: 4,
      radius: 8,
      radius2: 0,
      angle: 0
    })
  });

  /**
   * @type {ngeo.interaction.MeasureLengthMobile}
   * @export
   */
  this.measure;

  /**
   * @type {ngeo.interaction.MobileDraw}
   * @export
   */
  this.drawInteraction;

  /**
   * @type {boolean}
   * @export
   */
  this.dirty = false;

  /**
   * @type {boolean}
   * @export
   */
  this.drawing = false;

  /**
   * @type {boolean}
   * @export
   */
  this.valid = false;
};

/**
 * Initialise the controller.
 */
gmf.MobileMeasureLengthController.prototype.init = function() {

  this.measure = new ngeo.interaction.MeasureLengthMobile(this.filter_('ngeoUnitPrefix'), {
    precision: this.precision,
    sketchStyle: this.sketchStyle
  });

  this.measure.setActive(this.active);
  this.ngeoDecorateInteraction_(this.measure);

  this.drawInteraction = /** @type {ngeo.interaction.MobileDraw} */ (
    this.measure.getDrawInteraction());

  const drawInteraction = this.drawInteraction;
  this.ngeoDecorateInteraction_(drawInteraction);

  Object.defineProperty(this, 'hasPoints', {
    get() {
      return this.drawInteraction.getFeature() !== null;
    }
  });

  ol.events.listen(
    drawInteraction,
    ol.Object.getChangeEventType(
      ngeo.interaction.MobileDrawProperty.DIRTY),
    function() {
      this.dirty = drawInteraction.getDirty();

      // this is where the angular scope is forced to be applied. We
      // only need to do this when dirty, as going to "no being dirty"
      // is made by a click on a button where Angular is within scope
      if (this.dirty) {
        this.scope_.$apply();
      }
    },
    this
  );

  ol.events.listen(
    drawInteraction,
    ol.Object.getChangeEventType(
      ngeo.interaction.MobileDrawProperty.DRAWING),
    function() {
      this.drawing = drawInteraction.getDrawing();
    },
    this
  );

  ol.events.listen(
    drawInteraction,
    ol.Object.getChangeEventType(
      ngeo.interaction.MobileDrawProperty.VALID),
    function() {
      this.valid = drawInteraction.getValid();
    },
    this
  );

  this.map.addInteraction(this.measure);
};

/**
 * Add current sketch point to line measure
 * @export
 */
gmf.MobileMeasureLengthController.prototype.addPoint = function() {
  this.drawInteraction.addToDrawing();
};

/**
 * Clear the sketch feature
 * @export
 */
gmf.MobileMeasureLengthController.prototype.clear = function() {
  this.drawInteraction.clearDrawing();
};

/**
 * Finish line measure
 * @export
 */
gmf.MobileMeasureLengthController.prototype.finish = function() {
  this.drawInteraction.finishDrawing();
};

/**
 * Deactivate the directive.
 * @export
 */
gmf.MobileMeasureLengthController.prototype.deactivate = function() {
  this.active = false;
};

gmf.module.controller('GmfMobileMeasureLengthController',
  gmf.MobileMeasureLengthController);
<|endoftext|>


<commit_before>define([
    'views/list',
    'views/graph-manager/graph-base',
    'models/graph',
    'knockout'
], function(ListView, GraphBase, GraphModel , ko) {
    var BranchList = ListView.extend({
        /**
        * A backbone view to manage a list of graph nodes
        * @augments ListView
        * @constructor
        * @name NodeList
        */
        initialize: function(options) {
            ListView.prototype.initialize.apply(this, arguments);

            this.loading = options.loading || ko.observable(false);
            this.graphModel = options.graphModel;
            this.selectedNode = this.graphModel.get('selectedNode');
            this.items = options.branches;
            this.items().forEach(function (branch) {
                branch.graphModel = new GraphModel({
                    data: branch.graph
                })
            });
            this.selectedBranch = ko.observable(null);
            this.viewMetadata = ko.observable(false);

            this.selectedNode.subscribe(function(node){
                if(node){
                    _.each(this.items(), function(branch){
                        branch.filtered(true);
                        var found = _.find(branch.graph.domain_connections, function(domain_connection){
                            return _.find(domain_connection.ontology_classes, function(ontology_class){
                                return ontology_class.id === node.ontologyclass_id();
                            }, this)
                        }, this);
                        if(found){
                            branch.filtered(false);
                        }
                    }, this);
                }
            }, this);
        },

        selectItem: function(item, evt){
            ListView.prototype.selectItem.apply(this, arguments);

            if(item.selected()){
                this.selectedBranch(item);
                this.graph = new GraphBase({
                    el: $('#branch-preview'),
                    graphModel: item.graphModel
                });
                this.viewMetadata(true);
            }else{
                this.selectedBranch(null);
                this.viewMetadata(false);
            }
        },

        appendBranch: function(item, evt){
            var self = this;
            if(this.selectedNode()){
                this.loading(true);
                var ontology_connection = _.find(item.graph.domain_connections, function(domain_connection){
                    return _.find(domain_connection.ontology_classes, function(ontology_class){
                        return ontology_class.id === this.selectedNode().ontologyclass_id();
                    }, this)
                }, this);
                if(ontology_connection){
                    this.graphModel.appendBranch(this.selectedNode().nodeid, ontology_connection.ontology_property.id, item.graphid, function(response){
                        self.loading(false);
                    }, this)
                }else{
                    this.loading(true);
                    // need to alert the user!, although this shoudn't happen
                }
            }
            this.closeForm();
        },

        closeForm: function(){
            this.clearSelection();
            this.selectedBranch(null);
            this.viewMetadata(false);
        },

    });
    return BranchList;
});
<commit_msg>adding view documentation<commit_after>define([
    'views/list',
    'views/graph-manager/graph-base',
    'models/graph',
    'knockout'
], function(ListView, GraphBase, GraphModel , ko) {
    var BranchList = ListView.extend({
        /**
        * A backbone view to manage a list of branch graphs
        * @augments ListView
        * @constructor
        * @name BranchList
        */
        initialize: function(options) {
            ListView.prototype.initialize.apply(this, arguments);

            this.loading = options.loading || ko.observable(false);
            this.graphModel = options.graphModel;
            this.selectedNode = this.graphModel.get('selectedNode');
            this.items = options.branches;
            this.items().forEach(function (branch) {
                branch.graphModel = new GraphModel({
                    data: branch.graph
                })
            });
            this.selectedBranch = ko.observable(null);
            this.viewMetadata = ko.observable(false);

            this.selectedNode.subscribe(function(node){
                if(node){
                    _.each(this.items(), function(branch){
                        branch.filtered(true);
                        var found = _.find(branch.graph.domain_connections, function(domain_connection){
                            return _.find(domain_connection.ontology_classes, function(ontology_class){
                                return ontology_class.id === node.ontologyclass_id();
                            }, this)
                        }, this);
                        if(found){
                            branch.filtered(false);
                        }
                    }, this);
                }
            }, this);
        },

        /**
        * Sets the selected branch from the users selection
        * @augments ListView#selectItem
        * @memberof ListView.prototype
        * @param {branch object} item - the branch object the user selected
        * @param {click event object} evt
        */
        selectItem: function(item, evt){
            ListView.prototype.selectItem.apply(this, arguments);

            if(item.selected()){
                this.selectedBranch(item);
                this.graph = new GraphBase({
                    el: $('#branch-preview'),
                    graphModel: item.graphModel
                });
                this.viewMetadata(true);
            }else{
                this.selectedBranch(null);
                this.viewMetadata(false);
            }
        },

        /**
        * Appends the currently selected branch onto the currently selected node in the graph
        * @memberof ListView.prototype
        * @param {branch object} item - the branch object the user selected
        * @param {click event object} evt
        */
        appendBranch: function(item, evt){
            var self = this;
            if(this.selectedNode()){
                this.loading(true);
                var ontology_connection = _.find(item.graph.domain_connections, function(domain_connection){
                    return _.find(domain_connection.ontology_classes, function(ontology_class){
                        return ontology_class.id === this.selectedNode().ontologyclass_id();
                    }, this)
                }, this);
                if(ontology_connection){
                    this.graphModel.appendBranch(this.selectedNode().nodeid, ontology_connection.ontology_property.id, item.graphid, function(response){
                        self.loading(false);
                    }, this)
                }else{
                    this.loading(true);
                    // need to alert the user!, although this shoudn't happen
                }
            }
            this.closeForm();
        },

        /**
        * Closes the form and deselects the currently selected branch
        * @memberof ListView.prototype
        */
        closeForm: function(){
            this.clearSelection();
            this.selectedBranch(null);
            this.viewMetadata(false);
        },

    });
    return BranchList;
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 */

import type {DialogOptions} from '../NativeModules/specs/NativeDialogManagerAndroid';

import Platform from '../Utilities/Platform';
import RCTAlertManager from './RCTAlertManager';

export type AlertType =
  | 'default'
  | 'plain-text'
  | 'secure-text'
  | 'login-password';
export type AlertButtonStyle = 'default' | 'cancel' | 'destructive';
export type Buttons = Array<{
  text?: string,
  onPress?: ?Function,
  isPreferred?: boolean,
  style?: AlertButtonStyle,
  ...
}>;

type Options = {
  cancelable?: ?boolean,
  userInterfaceStyle?: 'unspecified' | 'light' | 'dark',
  onDismiss?: ?() => void,
  ...
};

/**
 * Launches an alert dialog with the specified title and message.
 *
 * See https://reactnative.dev/docs/alert
 */
class Alert {
  static alert(
    title: ?string,
    message?: ?string,
    buttons?: Buttons,
    options?: Options,
  ): void {
    if (Platform.OS === 'ios') {
      Alert.prompt(
        title,
        message,
        buttons,
        'default',
        undefined,
        undefined,
        options,
      );
    } else if (Platform.OS === 'android') {
      const NativeDialogManagerAndroid =
        require('../NativeModules/specs/NativeDialogManagerAndroid').default;
      if (!NativeDialogManagerAndroid) {
        return;
      }
      const constants = NativeDialogManagerAndroid.getConstants();

      const config: DialogOptions = {
        title: title || '',
        message: message || '',
        cancelable: false,
      };

      if (options && options.cancelable) {
        config.cancelable = options.cancelable;
      }
      // At most three buttons (neutral, negative, positive). Ignore rest.
      // The text 'OK' should be probably localized. iOS Alert does that in native.
      const defaultPositiveText = 'OK';
      const validButtons: Buttons = buttons
        ? buttons.slice(0, 3)
        : [{text: defaultPositiveText}];
      const buttonPositive = validButtons.pop();
      const buttonNegative = validButtons.pop();
      const buttonNeutral = validButtons.pop();

      if (buttonNeutral) {
        config.buttonNeutral = buttonNeutral.text || '';
      }
      if (buttonNegative) {
        config.buttonNegative = buttonNegative.text || '';
      }
      if (buttonPositive) {
        config.buttonPositive = buttonPositive.text || defaultPositiveText;
      }

      /* $FlowFixMe[missing-local-annot] The type annotation(s) required by
       * Flow's LTI update could not be added via codemod */
      const onAction = (action, buttonKey) => {
        if (action === constants.buttonClicked) {
          if (buttonKey === constants.buttonNeutral) {
            buttonNeutral.onPress && buttonNeutral.onPress();
          } else if (buttonKey === constants.buttonNegative) {
            buttonNegative.onPress && buttonNegative.onPress();
          } else if (buttonKey === constants.buttonPositive) {
            buttonPositive.onPress && buttonPositive.onPress();
          }
        } else if (action === constants.dismissed) {
          options && options.onDismiss && options.onDismiss();
        }
      };
      const onError = (errorMessage: string) => console.warn(errorMessage);
      NativeDialogManagerAndroid.showAlert(config, onError, onAction);
    }
  }

  static prompt(
    title: ?string,
    message?: ?string,
    callbackOrButtons?: ?(((text: string) => void) | Buttons),
    type?: ?AlertType = 'plain-text',
    defaultValue?: string,
    keyboardType?: string,
    options?: Options,
  ): void {
    if (Platform.OS === 'ios') {
      let callbacks = [];
      const buttons = [];
      let cancelButtonKey;
      let destructiveButtonKey;
      let preferredButtonKey;
      if (typeof callbackOrButtons === 'function') {
        callbacks = [callbackOrButtons];
      } else if (Array.isArray(callbackOrButtons)) {
        callbackOrButtons.forEach((btn, index) => {
          callbacks[index] = btn.onPress;
          if (btn.style === 'cancel') {
            cancelButtonKey = String(index);
          } else if (btn.style === 'destructive') {
            destructiveButtonKey = String(index);
          } else if (btn.isPreferred) {
            preferredButtonKey = String(index);
          }
          if (btn.text || index < (callbackOrButtons || []).length - 1) {
            const btnDef: {[number]: string} = {};
            btnDef[index] = btn.text || '';
            buttons.push(btnDef);
          }
        });
      }

      RCTAlertManager.alertWithArgs(
        {
          title: title || '',
          message: message || undefined,
          buttons,
          type: type || undefined,
          defaultValue,
          cancelButtonKey,
          destructiveButtonKey,
          preferredButtonKey,
          keyboardType,
          userInterfaceStyle: options?.userInterfaceStyle || undefined,
        },
        (id, value) => {
          const cb = callbacks[id];
          cb && cb(value);
        },
      );
    }
  }
}

module.exports = Alert;
<commit_msg>Allow preferred Alert button regardless of the style (#34253)<commit_after>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 */

import type {DialogOptions} from '../NativeModules/specs/NativeDialogManagerAndroid';

import Platform from '../Utilities/Platform';
import RCTAlertManager from './RCTAlertManager';

export type AlertType =
  | 'default'
  | 'plain-text'
  | 'secure-text'
  | 'login-password';
export type AlertButtonStyle = 'default' | 'cancel' | 'destructive';
export type Buttons = Array<{
  text?: string,
  onPress?: ?Function,
  isPreferred?: boolean,
  style?: AlertButtonStyle,
  ...
}>;

type Options = {
  cancelable?: ?boolean,
  userInterfaceStyle?: 'unspecified' | 'light' | 'dark',
  onDismiss?: ?() => void,
  ...
};

/**
 * Launches an alert dialog with the specified title and message.
 *
 * See https://reactnative.dev/docs/alert
 */
class Alert {
  static alert(
    title: ?string,
    message?: ?string,
    buttons?: Buttons,
    options?: Options,
  ): void {
    if (Platform.OS === 'ios') {
      Alert.prompt(
        title,
        message,
        buttons,
        'default',
        undefined,
        undefined,
        options,
      );
    } else if (Platform.OS === 'android') {
      const NativeDialogManagerAndroid =
        require('../NativeModules/specs/NativeDialogManagerAndroid').default;
      if (!NativeDialogManagerAndroid) {
        return;
      }
      const constants = NativeDialogManagerAndroid.getConstants();

      const config: DialogOptions = {
        title: title || '',
        message: message || '',
        cancelable: false,
      };

      if (options && options.cancelable) {
        config.cancelable = options.cancelable;
      }
      // At most three buttons (neutral, negative, positive). Ignore rest.
      // The text 'OK' should be probably localized. iOS Alert does that in native.
      const defaultPositiveText = 'OK';
      const validButtons: Buttons = buttons
        ? buttons.slice(0, 3)
        : [{text: defaultPositiveText}];
      const buttonPositive = validButtons.pop();
      const buttonNegative = validButtons.pop();
      const buttonNeutral = validButtons.pop();

      if (buttonNeutral) {
        config.buttonNeutral = buttonNeutral.text || '';
      }
      if (buttonNegative) {
        config.buttonNegative = buttonNegative.text || '';
      }
      if (buttonPositive) {
        config.buttonPositive = buttonPositive.text || defaultPositiveText;
      }

      /* $FlowFixMe[missing-local-annot] The type annotation(s) required by
       * Flow's LTI update could not be added via codemod */
      const onAction = (action, buttonKey) => {
        if (action === constants.buttonClicked) {
          if (buttonKey === constants.buttonNeutral) {
            buttonNeutral.onPress && buttonNeutral.onPress();
          } else if (buttonKey === constants.buttonNegative) {
            buttonNegative.onPress && buttonNegative.onPress();
          } else if (buttonKey === constants.buttonPositive) {
            buttonPositive.onPress && buttonPositive.onPress();
          }
        } else if (action === constants.dismissed) {
          options && options.onDismiss && options.onDismiss();
        }
      };
      const onError = (errorMessage: string) => console.warn(errorMessage);
      NativeDialogManagerAndroid.showAlert(config, onError, onAction);
    }
  }

  static prompt(
    title: ?string,
    message?: ?string,
    callbackOrButtons?: ?(((text: string) => void) | Buttons),
    type?: ?AlertType = 'plain-text',
    defaultValue?: string,
    keyboardType?: string,
    options?: Options,
  ): void {
    if (Platform.OS === 'ios') {
      let callbacks = [];
      const buttons = [];
      let cancelButtonKey;
      let destructiveButtonKey;
      let preferredButtonKey;
      if (typeof callbackOrButtons === 'function') {
        callbacks = [callbackOrButtons];
      } else if (Array.isArray(callbackOrButtons)) {
        callbackOrButtons.forEach((btn, index) => {
          callbacks[index] = btn.onPress;
          if (btn.style === 'cancel') {
            cancelButtonKey = String(index);
          } else if (btn.style === 'destructive') {
            destructiveButtonKey = String(index);
          }
          if (btn.isPreferred) {
            preferredButtonKey = String(index);
          }
          if (btn.text || index < (callbackOrButtons || []).length - 1) {
            const btnDef: {[number]: string} = {};
            btnDef[index] = btn.text || '';
            buttons.push(btnDef);
          }
        });
      }

      RCTAlertManager.alertWithArgs(
        {
          title: title || '',
          message: message || undefined,
          buttons,
          type: type || undefined,
          defaultValue,
          cancelButtonKey,
          destructiveButtonKey,
          preferredButtonKey,
          keyboardType,
          userInterfaceStyle: options?.userInterfaceStyle || undefined,
        },
        (id, value) => {
          const cb = callbacks[id];
          cb && cb(value);
        },
      );
    }
  }
}

module.exports = Alert;
<|endoftext|>


<commit_before>var Kc = Kc || {};
Kc.Global = Kc.Global || {};
(function (namespace, $) {
    // set all modals to static behavior (clicking out does not close)
    $.fn.modal.Constructor.DEFAULTS.backdrop = "static";

    $(document).on("ready", function(){
        // date conversion for date fields to full leading 0 - for days and months and to full year dates
        $(document).on("blur", ".uif-dateControl", function(){
            var dateFormat = $.datepicker._defaults.dateFormat;
            var date = $(this).val();
            if (!date) {
                return;
            }

            date = date.replace(/-/g, "/");

            if (date && (date.match(/\//g) || []).length === 2) {

                // find the expected position and value of year in the string based on date format
                var year;
                if (dateFormat.indexOf("y") === 0) {
                    year = date.substr(0, date.indexOf("/"));
                }
                else {
                    year = date.substr(date.lastIndexOf("/") + 1, date.length - 1);
                }

                // when year is length of 2 append the first 2 numbers of the current full year (ie 14 -> 2014)
                if (year.length === 2) {
                    var currentDate = new Date();
                    year = currentDate.getFullYear().toString().substr(0,2) + year;
                }

                var dateObj = new Date(date);
                if (isNaN(dateObj.valueOf())) {
                    // not valid abandon conversion
                    return;
                }

                dateObj.setFullYear(year);

                var formattedDate = $.datepicker.formatDate(dateFormat, dateObj);
                $(this).val(formattedDate);
            }
        });
    });

    namespace.attachRedirectHandler = function() {
        $(window).unbind("message.redirect");
        $(window).on("message.redirect", function (event) {
            if (event.originalEvent.data && event.originalEvent.data.indexOf("redirect:") === 0) {
                var location = event.originalEvent.data.substr(9);
                window.location.replace(location);
                return false;
            }
        });
    }
})(Kc.Global, jQuery);

KradResponse.prototype.updateComponentHandler = function (content, dataAttr) {
    var id = dataAttr.id;

    var $componentInDom = jQuery("#" + id);

    hideTooltips($componentInDom);

    var component = jQuery("#" + id + "_update", content);

    // remove any already existing matching dialogs from the view
    jQuery('.modal', component).each(function () {
            var existingComponent = jQuery('#' + this.id, jQuery("[data-role='View']"));
            var isPlaceHolder = existingComponent.hasClass(kradVariables.CLASSES.PLACEHOLDER);
            var displayedModal = isDisplayedModal(existingComponent);

            // do not remove placeholders or displayedModals
            if (!isPlaceHolder && !displayedModal) {
                existingComponent.remove();
            }
        }
    );

    jQuery("." + kradVariables.CLASSES.PLACEHOLDER, component).each(function () {
        var existingComponent = jQuery('#' + this.id, jQuery("[data-role='View']"));

        if (existingComponent.length && existingComponent.is(".modal") && isDisplayedModal(existingComponent)) {
            jQuery(this).remove();
        }
        else {
            existingComponent.remove();
        }
    });

    // is the new component now required
    var nowRequired = jQuery(".required", component).size() > 0;

    // get the old label
    var oldLabel = jQuery("#" + id + "_label");

    // if found then remove any required indicators and then add/readd back
    if (oldLabel) {
        oldLabel.find("span." + kradVariables.REQUIRED_MESSAGE_CLASS).remove();
        if (nowRequired) {
            oldLabel.append("*");
        }
    }

    // special label handling, if any
    var theLabel = jQuery("[data-label_for='" + id + "']", component);
    if (jQuery(".displayWith-" + id).length && theLabel.length) {
        theLabel.addClass("displayWith-" + id);
        jQuery("span.displayWith-" + id).replaceWith(theLabel);

        component.remove("[data-label_for='" + id + "']");
    }

    // remove old stuff
    if (jQuery("#" + id + "_errors").length) {
        jQuery("#" + id + "_errors").remove();
    }

    jQuery("input[data-for='" + id + "']").each(function () {
        jQuery(this).remove();
    });

    // replace component
    if ($componentInDom.length) {
        var wasPlaceholder = $componentInDom.hasClass(kradVariables.CLASSES.PLACEHOLDER);

        var componentContent = component.html();

        // for modal content update, we just want to replace the contents within the component
        var displayedModal = isDisplayedModal($componentInDom);
        if (displayedModal) {
            var innerComponentContent = jQuery(componentContent).html();
            $componentInDom.html(innerComponentContent);
            var relatedContent = jQuery(componentContent).filter("input[data-for='" + id + "']");
            $componentInDom.append(relatedContent);
        }
        else {
            $componentInDom.replaceWith(componentContent);
        }

        // Removes traces of dialog if one was destroyed by the refresh
        ensureDialogBackdropRemoved();

        // move all dialogs to dialog section
        jQuery('.modal').appendTo('#Uif-Dialogs');

        $componentInDom = jQuery("#" + id);

        if ($componentInDom.parent().is("td")) {
            $componentInDom.parent().show();
        }

        var displayWithLabel = jQuery(".displayWith-" + id);
        displayWithLabel.show();
        if (displayWithLabel.parent().is("td") || displayWithLabel.parent().is("th")) {
            displayWithLabel.parent().show();
        }

        // assume this content is open if being refreshed
        var open = $componentInDom.attr("data-open");
        if (open !== undefined && open === "false") {
            $componentInDom.attr("data-open", "true");
            $componentInDom.show();
        }

        // runs scripts on the span or div with id
        runHiddenScripts(id);
        runHiddenScripts("Uif-Dialogs");

        if (displayedModal) {
            writeMessagesForChildGroups(id);
            writeMessagesForGroup(id, getValidationData($componentInDom, true), true);
        }

        // Only for table layout collections. Keeps collection on same page.
        var currentPage = retrieveFromSession(id + ":currentPageRichTable");
        if (currentPage != null) {
            openDataTablePage(id, currentPage);
        }

        $componentInDom.unblock({onUnblock: function () {
            var isDialog = $componentInDom.hasClass(kradVariables.CLASSES.MODAL);

            // if this is the first time the content is being shown, and it is not a dialog, add highlighting
            if (wasPlaceholder && !isDialog) {
                $componentInDom.addClass(kradVariables.PROGRESSIVE_DISCLOSURE_HIGHLIGHT_CLASS);
                $componentInDom.animate({backgroundColor: "transparent"}, 6000);
            }
        }
        });

        $componentInDom.trigger(kradVariables.EVENTS.ADJUST_STICKY);
        $componentInDom.trigger(kradVariables.EVENTS.UPDATE_CONTENT);

        // Perform focus and jumpTo based on the data attributes
        performFocusAndJumpTo(true, $componentInDom.data(kradVariables.FOCUS_ID), $componentInDom.data(kradVariables.JUMP_TO_ID), $componentInDom.data(kradVariables.JUMP_TO_NAME));
    }
}

// finds the page content in the returned content and updates the page, then processes breadcrumbs and hidden
// scripts. While processing, the page contents are hidden
KradResponse.prototype.updatePageHandler = function (content, dataAttr) {
    var pageUpdate = jQuery("#page_update", content);
    var page = jQuery("[data-role='Page']", pageUpdate);
    var viewContent = jQuery("#" + kradVariables.VIEW_CONTENT_WRAPPER);

    // remove any already existing matching dialogs from the view
    jQuery('.modal', page).each(function () {
            var existingComponent = jQuery('#' + this.id, jQuery("[data-role='View']"));
            existingComponent.remove();
    });

    jQuery("." + kradVariables.CLASSES.PLACEHOLDER, page).each(function () {
        var existingComponent = jQuery('#' + this.id, jQuery("[data-role='View']"));

        if (existingComponent.length && existingComponent.is(".modal") && isDisplayedModal(existingComponent)) {
            jQuery(this).remove();
        }
        else {
            existingComponent.remove();
        }
    });

    page.hide();

    // give a selector that will avoid the temporary iframe used to hold ajax responses by the jquery form plugin
    var pageInLayout = "#" + kradVariables.VIEW_CONTENT_WRAPPER + " [data-role='Page']:first";
    hideTooltips(pageInLayout);

    var $pageInLayout = jQuery(pageInLayout);

    // update page contents from response
    viewContent.find("[data-for='" + $pageInLayout.attr("id") + "']").remove();
    $pageInLayout.replaceWith(pageUpdate.find(">*"));
    $pageInLayout = jQuery(pageInLayout);

    // Removes traces of dialog if one was destroyed by the refresh
    ensureDialogBackdropRemoved();

    // move all dialogs to dialog section
    jQuery('.modal').appendTo('#Uif-Dialogs');

    // remove detached dialogs
    jQuery("[data-detached='true']").remove();

    pageValidatorReady = false;
    runHiddenScripts(kradVariables.VIEW_CONTENT_WRAPPER, false, true);
    runHiddenScripts("Uif-Dialogs");

    markActiveMenuLink();

    viewContent.trigger(kradVariables.EVENTS.ADJUST_PAGE_MARGIN);
    $pageInLayout.trigger(kradVariables.EVENTS.UPDATE_CONTENT);

    $pageInLayout.show();

    $pageInLayout.trigger(kradVariables.EVENTS.ADJUST_STICKY);
    $pageInLayout.trigger(kradVariables.EVENTS.PAGE_UPDATE_COMPLETE);

    // Perform focus and jumpTo based on the data attributes
    performFocusAndJumpTo(true, page.data(kradVariables.FOCUS_ID), page.data(kradVariables.JUMP_TO_ID), page.data(kradVariables.JUMP_TO_NAME));
}<commit_msg>[KRACOEUS-8416] Fix for fields that could potentially hidden by dialog hiding when validated on blur<commit_after>var Kc = Kc || {};
Kc.Global = Kc.Global || {};
(function (namespace, $) {
    // set all modals to static behavior (clicking out does not close)
    $.fn.modal.Constructor.DEFAULTS.backdrop = "static";

    $(document).on("ready", function(){
        // date conversion for date fields to full leading 0 - for days and months and to full year dates
        $(document).on("blur", ".uif-dateControl", function(){
            var dateFormat = $.datepicker._defaults.dateFormat;
            var date = $(this).val();
            if (!date) {
                return;
            }

            date = date.replace(/-/g, "/");

            if (date && (date.match(/\//g) || []).length === 2) {

                // find the expected position and value of year in the string based on date format
                var year;
                if (dateFormat.indexOf("y") === 0) {
                    year = date.substr(0, date.indexOf("/"));
                }
                else {
                    year = date.substr(date.lastIndexOf("/") + 1, date.length - 1);
                }

                // when year is length of 2 append the first 2 numbers of the current full year (ie 14 -> 2014)
                if (year.length === 2) {
                    var currentDate = new Date();
                    year = currentDate.getFullYear().toString().substr(0,2) + year;
                }

                var dateObj = new Date(date);
                if (isNaN(dateObj.valueOf())) {
                    // not valid abandon conversion
                    return;
                }

                dateObj.setFullYear(year);

                var formattedDate = $.datepicker.formatDate(dateFormat, dateObj);
                $(this).val(formattedDate);
            }
        });
    });

    namespace.attachRedirectHandler = function() {
        $(window).unbind("message.redirect");
        $(window).on("message.redirect", function (event) {
            if (event.originalEvent.data && event.originalEvent.data.indexOf("redirect:") === 0) {
                var location = event.originalEvent.data.substr(9);
                window.location.replace(location);
                return false;
            }
        });
    }
})(Kc.Global, jQuery);

KradResponse.prototype.updateComponentHandler = function (content, dataAttr) {
    var id = dataAttr.id;

    var $componentInDom = jQuery("#" + id);

    hideTooltips($componentInDom);

    var component = jQuery("#" + id + "_update", content);

    // remove any already existing matching dialogs from the view
    jQuery('.modal', component).each(function () {
            var existingComponent = jQuery('#' + this.id, jQuery("[data-role='View']"));
            var isPlaceHolder = existingComponent.hasClass(kradVariables.CLASSES.PLACEHOLDER);
            var displayedModal = isDisplayedModal(existingComponent);

            // do not remove placeholders or displayedModals
            if (!isPlaceHolder && !displayedModal) {
                existingComponent.remove();
            }
        }
    );

    jQuery("." + kradVariables.CLASSES.PLACEHOLDER, component).each(function () {
        var existingComponent = jQuery('#' + this.id, jQuery("[data-role='View']"));

        if (existingComponent.length && existingComponent.is(".modal") && isDisplayedModal(existingComponent)) {
            jQuery(this).remove();
        }
        else {
            existingComponent.remove();
        }
    });

    // is the new component now required
    var nowRequired = jQuery(".required", component).size() > 0;

    // get the old label
    var oldLabel = jQuery("#" + id + "_label");

    // if found then remove any required indicators and then add/readd back
    if (oldLabel) {
        oldLabel.find("span." + kradVariables.REQUIRED_MESSAGE_CLASS).remove();
        if (nowRequired) {
            oldLabel.append("*");
        }
    }

    // special label handling, if any
    var theLabel = jQuery("[data-label_for='" + id + "']", component);
    if (jQuery(".displayWith-" + id).length && theLabel.length) {
        theLabel.addClass("displayWith-" + id);
        jQuery("span.displayWith-" + id).replaceWith(theLabel);

        component.remove("[data-label_for='" + id + "']");
    }

    // remove old stuff
    if (jQuery("#" + id + "_errors").length) {
        jQuery("#" + id + "_errors").remove();
    }

    jQuery("input[data-for='" + id + "']").each(function () {
        jQuery(this).remove();
    });

    // replace component
    if ($componentInDom.length) {
        var wasPlaceholder = $componentInDom.hasClass(kradVariables.CLASSES.PLACEHOLDER);

        var componentContent = component.html();

        // for modal content update, we just want to replace the contents within the component
        var displayedModal = isDisplayedModal($componentInDom);
        if (displayedModal) {
            var innerComponentContent = jQuery(componentContent).html();
            $componentInDom.html(innerComponentContent);
            var relatedContent = jQuery(componentContent).filter("input[data-for='" + id + "']");
            $componentInDom.append(relatedContent);
        }
        else {
            $componentInDom.replaceWith(componentContent);
        }

        // Removes traces of dialog if one was destroyed by the refresh
        ensureDialogBackdropRemoved();

        // move all dialogs to dialog section
        jQuery('.modal').appendTo('#Uif-Dialogs');

        $componentInDom = jQuery("#" + id);

        if ($componentInDom.parent().is("td")) {
            $componentInDom.parent().show();
        }

        var displayWithLabel = jQuery(".displayWith-" + id);
        displayWithLabel.show();
        if (displayWithLabel.parent().is("td") || displayWithLabel.parent().is("th")) {
            displayWithLabel.parent().show();
        }

        // assume this content is open if being refreshed
        var open = $componentInDom.attr("data-open");
        if (open !== undefined && open === "false") {
            $componentInDom.attr("data-open", "true");
            $componentInDom.show();
        }

        // runs scripts on the span or div with id
        runHiddenScripts(id);
        runHiddenScripts("Uif-Dialogs");

        if (displayedModal) {
            writeMessagesForChildGroups(id);
            writeMessagesForGroup(id, getValidationData($componentInDom, true), true);
        }

        // Only for table layout collections. Keeps collection on same page.
        var currentPage = retrieveFromSession(id + ":currentPageRichTable");
        if (currentPage != null) {
            openDataTablePage(id, currentPage);
        }

        $componentInDom.unblock({onUnblock: function () {
            var isDialog = $componentInDom.hasClass(kradVariables.CLASSES.MODAL);

            // if this is the first time the content is being shown, and it is not a dialog, add highlighting
            if (wasPlaceholder && !isDialog) {
                $componentInDom.addClass(kradVariables.PROGRESSIVE_DISCLOSURE_HIGHLIGHT_CLASS);
                $componentInDom.animate({backgroundColor: "transparent"}, 6000);
            }
        }
        });

        $componentInDom.trigger(kradVariables.EVENTS.ADJUST_STICKY);
        $componentInDom.trigger(kradVariables.EVENTS.UPDATE_CONTENT);

        // Perform focus and jumpTo based on the data attributes
        performFocusAndJumpTo(true, $componentInDom.data(kradVariables.FOCUS_ID), $componentInDom.data(kradVariables.JUMP_TO_ID), $componentInDom.data(kradVariables.JUMP_TO_NAME));
    }
}

// finds the page content in the returned content and updates the page, then processes breadcrumbs and hidden
// scripts. While processing, the page contents are hidden
KradResponse.prototype.updatePageHandler = function (content, dataAttr) {
    var pageUpdate = jQuery("#page_update", content);
    var page = jQuery("[data-role='Page']", pageUpdate);
    var viewContent = jQuery("#" + kradVariables.VIEW_CONTENT_WRAPPER);

    // remove any already existing matching dialogs from the view
    jQuery('.modal', page).each(function () {
            var existingComponent = jQuery('#' + this.id, jQuery("[data-role='View']"));
            existingComponent.remove();
    });

    jQuery("." + kradVariables.CLASSES.PLACEHOLDER, page).each(function () {
        var existingComponent = jQuery('#' + this.id, jQuery("[data-role='View']"));

        if (existingComponent.length && existingComponent.is(".modal") && isDisplayedModal(existingComponent)) {
            jQuery(this).remove();
        }
        else {
            existingComponent.remove();
        }
    });

    page.hide();

    // give a selector that will avoid the temporary iframe used to hold ajax responses by the jquery form plugin
    var pageInLayout = "#" + kradVariables.VIEW_CONTENT_WRAPPER + " [data-role='Page']:first";
    hideTooltips(pageInLayout);

    var $pageInLayout = jQuery(pageInLayout);

    // update page contents from response
    viewContent.find("[data-for='" + $pageInLayout.attr("id") + "']").remove();
    $pageInLayout.replaceWith(pageUpdate.find(">*"));
    $pageInLayout = jQuery(pageInLayout);

    // Removes traces of dialog if one was destroyed by the refresh
    ensureDialogBackdropRemoved();

    // move all dialogs to dialog section
    jQuery('.modal').appendTo('#Uif-Dialogs');

    // remove detached dialogs
    jQuery("[data-detached='true']").remove();

    pageValidatorReady = false;
    runHiddenScripts(kradVariables.VIEW_CONTENT_WRAPPER, false, true);
    runHiddenScripts("Uif-Dialogs");

    markActiveMenuLink();

    viewContent.trigger(kradVariables.EVENTS.ADJUST_PAGE_MARGIN);
    $pageInLayout.trigger(kradVariables.EVENTS.UPDATE_CONTENT);

    $pageInLayout.show();

    $pageInLayout.trigger(kradVariables.EVENTS.ADJUST_STICKY);
    $pageInLayout.trigger(kradVariables.EVENTS.PAGE_UPDATE_COMPLETE);

    // Perform focus and jumpTo based on the data attributes
    performFocusAndJumpTo(true, page.data(kradVariables.FOCUS_ID), page.data(kradVariables.JUMP_TO_ID), page.data(kradVariables.JUMP_TO_NAME));
}

/**
 * Validate that a specific field's control defined by the selector/jQuery array passed in.  Also calls dependsOnCheck
 * to validate any dependant fields.
 *
 * @param fieldControl selector/jQuery array that represents the control to validate
 */
function validateFieldValue(fieldControl) {
    // skip validation for add line fields unless there is a value. The add button will handle validation
    if (jQuery(fieldControl).attr('id').match(new RegExp(kradVariables.ID_SUFFIX.ADD_LINE_INPUT_FIELD))
            && !jQuery(fieldControl).val()) {
        return true;
    }

    //remove the ignore class if any due to a bug in the validate
    //plugin for direct validation on certain types
    if (jQuery(fieldControl).attr('id').match(/ID_SUFFIXADD_LINE_INPUT_FIELD/)) {
        jQuery(fieldControl).removeClass("ignoreValid");
        return true;
    }

    var hadIgnore = false;
    if (jQuery(fieldControl).hasClass("ignoreValid")) {
        jQuery(fieldControl).removeClass("ignoreValid");
        hadIgnore = true;
    }
    clientErrorExistsCheck = true;

    // skip fields in hidden dialogs
    if (jQuery(fieldControl).is(kradVariables.DIALOG_SELECTOR + ":hidden [data-role='Control']")) {
        return true;
    }

    //the validation call
    var valid = jQuery(fieldControl).valid();
    dependsOnCheck(fieldControl, new Array());
    clientErrorExistsCheck = false;
    if (hadIgnore) {
        jQuery(fieldControl).addClass("ignoreValid");
    }

    return valid;
}
<|endoftext|>