<commit_before>define([
  'react',
  'react-modal',
  './SFUCopyrightComplianceNotice'
  ], function (React, ReactModal, SFUCopyrightComplianceNotice) {

    var SFUCopyrightComplianceModalDialog = React.createClass({

      propTypes: {
        modalIsOpen: React.PropTypes.bool
      },

      getInitialState() {
        return {
          modalIsOpen: this.props.modalIsOpen
        }
      },

      componentWillReceiveProps: function(nextProps) {
        this.setState({
          modalIsOpen: nextProps.modalIsOpen
        });
      },

      openModal(e) {
        e.preventDefault();
        this.setState({modalIsOpen: true});
      },

      closeModal(e) {
        if (e) {
          e.preventDefault();
        }
        this.setState({
          modalIsOpen: false
        });
      },

      publishCourse(e) {
        if (e) {
          e.preventDefault();
        }
        this.setState({
          modalIsOpen: false
        }, () => {
          document.getElementById(this.props.formId).submit();
        });
      },

      render() {
        return(
          <ReactModal
            isOpen={this.state.modalIsOpen}
            className='ReactModal__Content--canvas'
            overlayClassName='ReactModal__Overlay--canvas'
          >

Copyright Compliance Notice

                  <button className="Button Button--icon-action" type="button" onClick={this.closeModal}>

                    Close
                  </button>

                <SFUCopyrightComplianceNotice />

                  <button type="button" className="btn btn-default" onClick={this.closeModal}>Cancel</button>
                  <button type="button" className="btn btn-primary" onClick={this.publishCourse}>Publish</button>

          </ReactModal>
        )
      }
    });

  return SFUCopyrightComplianceModalDialog;
});
<commit_msg>Convert SFUCopyrightComplianceNoticeModalDialog to a class<commit_after>import React from 'react'
import ReactModal from 'react-modal'
import SFUCopyrightComplianceNotice from './SFUCopyrightComplianceNotice'

class SFUCopyrightComplianceModalDialog extends React.Component {

  constructor (props) {
    super(props)
    this.state = {
      modalIsOpen: this.props.modalIsOpen
    }
    this.openModal = this.openModal.bind(this)
    this.closeModal = this.closeModal.bind(this)
    this.publishCourse = this.publishCourse.bind(this)
  }

  componentWillReceiveProps (nextProps) {
    this.setState({
      modalIsOpen: nextProps.modalIsOpen
    });
  }

  openModal (e) {
    e.preventDefault();
    this.setState({modalIsOpen: true});
  }

  closeModal (e) {
    if (e) {
      e.preventDefault();
    }
    this.setState({
      modalIsOpen: false
    });
  }

  publishCourse (e) {
    if (e) {
      e.preventDefault();
    }
    this.setState({
      modalIsOpen: false
    }, () => {
      document.getElementById(this.props.formId).submit();
    });
  }

  render () {
    return (
      <ReactModal
        contentLabel="Copyright Compliance Notice"
        isOpen={this.state.modalIsOpen}
        className="ReactModal__Content--canvas"
        overlayClassName="ReactModal__Overlay--canvas"
      >

Copyright Compliance Notice

              <button className="Button Button--icon-action" type="button" onClick={this.closeModal}>

                Close
              </button>

            <SFUCopyrightComplianceNotice />

              <button type="button" className="btn btn-default" onClick={this.closeModal}>Cancel</button>
              <button type="button" className="btn btn-primary" onClick={this.publishCourse}>Publish</button>

      </ReactModal>
    )
  }
}

SFUCopyrightComplianceModalDialog.propTypes = {
  modalIsOpen: React.PropTypes.bool.isRequired,
  formId: React.PropTypes.string.isRequired
}

export default SFUCopyrightComplianceModalDialog
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
$(function() {

  BrowseTopViewModel=function(groupIds){
    this.groupIds=groupIds;

    displayGroupDetail=function(groupId){
      $.log("groupId:"+groupId);
      $.ajax("restServices/archivaServices/browseService/browseGroupId/"+encodeURIComponent(groupId), {
          type: "GET",
          dataType: 'json',
          success: function(data) {
            var browseGroupIdEntryies = $.isArray(data.browseGroupIdResult.browseGroupIdEntries) ?
                $.map(data.browseGroupIdResult.browseGroupIdEntries,function(item){
                  return new BrowseGroupIdEntry(item.name, item.project);
                }): [data.browseGroupIdResult.browseGroupIdEntries];
            $("#main-content #browse_result").html($("#browse-groups-div-tmpl" ).tmpl());
            var browseGroupsViewModel = new BrowseGroupsViewModel(browseGroupIdEntryies);

            ko.applyBindings(browseGroupsViewModel,$("#main-content #browse-groups-div" ).get(0));
          }
      });
    }
  }

  BrowseGroupsViewModel=function(browseGroupIdEntryies){
    this.browseGroupIdEntryies=browseGroupIdEntryies;
  }

  displayBrowse=function(){
    var mainContent = $("#main-content");
    mainContent.html($("#browse-tmpl" ).tmpl());
    mainContent.find("#browse_result").html(mediumSpinnerImg());
    $.ajax("restServices/archivaServices/browseService/rootGroups", {
        type: "GET",
        dataType: 'json',
        success: function(data) {
          var groupdIds =
              $.isArray(data.groupIdList.groupIds)? $.map(data.groupIdList.groupIds,function(item){
                return item;
              }): [data.groupIdList.groupIds];
          $.log("size:"+groupdIds.length);
          var browseTopViewModel = new BrowseTopViewModel(groupdIds);

          ko.applyBindings(browseTopViewModel,mainContent.find("#browse_result" ).get(0));
        }
    });
  }

  displaySearch=function(){
    $("#main-content" ).html("coming soon :-)");
  }

  BrowseGroupIdEntry=function(name,project){
    this.name=name;
    this.project=project;
  }
});<commit_msg>jquery optimisation<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
$(function() {

  BrowseTopViewModel=function(groupIds){
    this.groupIds=groupIds;
    var mainContent = $("#main-content");
    mainContent.find("#browse_result").html(mediumSpinnerImg());
    displayGroupDetail=function(groupId){
      $.log("groupId:"+groupId);
      $.ajax("restServices/archivaServices/browseService/browseGroupId/"+encodeURIComponent(groupId), {
          type: "GET",
          dataType: 'json',
          success: function(data) {
            var browseGroupIdEntryies = $.isArray(data.browseGroupIdResult.browseGroupIdEntries) ?
                $.map(data.browseGroupIdResult.browseGroupIdEntries,function(item){
                  return new BrowseGroupIdEntry(item.name, item.project);
                }): [data.browseGroupIdResult.browseGroupIdEntries];
            mainContent.find("#browse_result").html($("#browse-groups-div-tmpl" ).tmpl());
            var browseGroupsViewModel = new BrowseGroupsViewModel(browseGroupIdEntryies);

            ko.applyBindings(browseGroupsViewModel,mainContent.find("#browse-groups-div" ).get(0));
          }
      });
    }
  }

  BrowseGroupsViewModel=function(browseGroupIdEntryies){
    this.browseGroupIdEntryies=browseGroupIdEntryies;
  }

  displayBrowse=function(){
    var mainContent = $("#main-content");
    mainContent.html($("#browse-tmpl" ).tmpl());
    mainContent.find("#browse_result").html(mediumSpinnerImg());
    $.ajax("restServices/archivaServices/browseService/rootGroups", {
        type: "GET",
        dataType: 'json',
        success: function(data) {
          var groupdIds =
              $.isArray(data.groupIdList.groupIds)? $.map(data.groupIdList.groupIds,function(item){
                return item;
              }): [data.groupIdList.groupIds];
          $.log("size:"+groupdIds.length);
          var browseTopViewModel = new BrowseTopViewModel(groupdIds);

          ko.applyBindings(browseTopViewModel,mainContent.find("#browse_result" ).get(0));
        }
    });
  }

  displaySearch=function(){
    $("#main-content" ).html("coming soon :-)");
  }

  BrowseGroupIdEntry=function(name,project){
    this.name=name;
    this.project=project;
  }
});<|endoftext|>


<commit_before>dojo.provide("encuestame.org.core.comments.Comment");

dojo.require("dijit._Templated");
dojo.require("dijit._Widget");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");
dojo.require('encuestame.org.core.commons');
dojo.require('encuestame.org.core.shared.utils.AccountPicture');

dojo.declare(
        "encuestame.org.core.comments.Comment",
        [dijit._Widget, dijit._Templated],{

          templatePath: dojo.moduleUrl("encuestame.org.core.comments", "templates/comment.html"),

          widgetsInTemplate: true,

          data : null,

          /**
           *
           */
          postCreate : function() {
        	  if (this.data) {
        		  try {
        			  this._fillComment();
        		  } catch (err) {
        			  console.error("error on fill comment", err);
        		  } finally {
        			 //something could be happend.
        		  }
        	  }
          },

          /*
           *
           */
          _fillComment : function() {
        	  //set user link
        	  if (this._commented_by) {
        		  var a = dojo.create("a");
        		  var commentedBy = (this.data.commented_by == null ? this.data.commented_username : this.data.commented_by);
        		  a.innerHTML = commentedBy;
        		  a.href = encuestame.utilities.usernameLink(this.data.commented_username);
        		  a.target = "_blank";
        		  this._commented_by.appendChild(a);
        	  }
        	  //set content.
        	  /*
        	   * in the future the content could be formated by HTML.
        	   */
        	  if (this._comment_content) {
        		  var p = dojo.create("p");
        		  p.innerHTML = this.data.comment;
        		  this._comment_content.appendChild(p);
        	  }
        	  //set date
        	  if(this._comment_content_date){
        		  var date = dojo.create("a");
        		  date.innerHTML = ENME.fromNow(this.data.created_at, "YYYY-MM-DD");
        		  date.href = "#"; //TODO: future inprovments
        		  this._comment_content_date.appendChild(date);
        	  }
          }
    });<commit_msg>Removed blank target<commit_after>dojo.provide("encuestame.org.core.comments.Comment");

dojo.require("dijit._Templated");
dojo.require("dijit._Widget");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");
dojo.require('encuestame.org.core.commons');
dojo.require('encuestame.org.core.shared.utils.AccountPicture');

dojo.declare(
        "encuestame.org.core.comments.Comment",
        [dijit._Widget, dijit._Templated],{

          templatePath: dojo.moduleUrl("encuestame.org.core.comments", "templates/comment.html"),

          widgetsInTemplate: true,

          data : null,

          /**
           *
           */
          postCreate : function() {
        	  if (this.data) {
        		  try {
        			  this._fillComment();
        		  } catch (err) {
        			  console.error("error on fill comment", err);
        		  } finally {
        			 //something could be happend.
        		  }
        	  }
          },

          /*
           *
           */
          _fillComment : function() {
        	  //set user link
        	  if (this._commented_by) {
        		  var a = dojo.create("a");
        		  var commentedBy = (this.data.commented_by == null ? this.data.commented_username : this.data.commented_by);
        		  a.innerHTML = commentedBy;
        		  a.href = encuestame.utilities.usernameLink(this.data.commented_username);
        		  //a.target = "_blank";
        		  this._commented_by.appendChild(a);
        	  }
        	  //set content.
        	  /*
        	   * in the future the content could be formated by HTML.
        	   */
        	  if (this._comment_content) {
        		  var p = dojo.create("p");
        		  p.innerHTML = this.data.comment;
        		  this._comment_content.appendChild(p);
        	  }
        	  //set date
        	  if(this._comment_content_date){
        		  var date = dojo.create("a");
        		  date.innerHTML = ENME.fromNow(this.data.created_at, "YYYY-MM-DD");
        		  date.href = "#"; //TODO: future inprovments
        		  this._comment_content_date.appendChild(date);
        	  }
          }
    });<|endoftext|>


<commit_before>/**
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/

CKEDITOR.editorConfig = function( config )
{
  // Define changes to default configuration here. For example:
  // config.language = 'fr';
  // config.uiColor = '#AADC6E';

  //config.contentsCss = webContext + '/util/styleSheets/silverpeas-main.css';
  config.baseHref = webContext + '/wysiwyg/jsp/';
  config.filebrowserImageBrowseUrl = config.baseHref+'uploadFile.jsp';
  config.filebrowserFlashBrowseUrl = config.baseHref+'uploadFile.jsp';
  config.filebrowserBrowseUrl = config.baseHref+'uploadFile.jsp';
  config.imageUploadUrl = 'activated';
  config.extraPlugins = 'userzoom,identitycard,allmedias,autolink,video,html5audio,imageresizerowandcolumn,variables,listblock,floatpanel,richcombo,mediaofcontribution,imagebank,filebank';
  config.allowedContent = true;
  config.toolbarCanCollapse = true;
  config.disableNativeSpellChecker = false;
  //config.forcePasteAsPlainText = true;

  config.stylesSet = [
    {name: 'Titre 1', element: 'h2', attributes : { 'style' : 'border-left: 3px solid #2a2a2a; color: #2a2a2a; font-size: 16px; padding: 0 6px' }},
    {name: 'Titre 2', element: 'h3', attributes : { 'style' : 'border-left: 3px solid #7eb73b; color: #7eb73b; font-size: 14px; padding: 0 6px' }},
    {name: 'Focus', element:'strong', attributes : { 'style' : 'background-color: #2a2a2a; color: #FFF' }},
    {name: 'Paragraphe important', element:'p', attributes : { 'style' : 'background-color: #F5F5F5; border-radius: 0 10px 0 10px; padding: 9.5px; border: 1px solid #ebebeb; font-size: 110%' }}
  ];

  config.toolbar_infoLetter = [
    { name: 'document',    items : [ 'Source','-','NewPage','DocProps','Preview','Print','-','Templates' ] },
    { name: 'clipboard',   items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
    { name: 'editing',     items : [ 'Find','Replace','-','SelectAll' ] },
    '/',
    { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] },
    { name: 'paragraph',   items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock' ] },
    { name: 'links',       items : [ 'Link','Unlink','Anchor' ] },
    { name: 'insert',      items : [ 'Image','mediaofcontribution','imagebank','Video','Html5audio','Iframe','filebank','Table','HorizontalRule','Smiley','SpecialChar','PageBreak', 'variables' ] },
    '/',
    { name: 'styles',      items : [ 'Styles','Format','Font','FontSize' ] },
    { name: 'colors',      items : [ 'TextColor','BGColor' ] },
    { name: 'tools',       items : [ 'Maximize', 'ShowBlocks','-','About' ] }
  ];

  config.toolbar_infoLetter_ddwe = [
    { name: 'paragraph',   items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock' ] },
    { name: 'links',       items : [ 'Link','Unlink'] },
    { name: 'insert',      items : [ 'Image','mediaofcontribution','imagebank','variables' ] },
    '/',
    { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','-','RemoveFormat' ] },
    { name: 'styles',      items : [ 'Styles','Format','Font','FontSize' ] },
    { name: 'colors',      items : [ 'TextColor','BGColor','Smiley' ] }
  ];
};<commit_msg>Feature #12713: removing image insertion from ckeditor displayed into DDWE editor.<commit_after>/**
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/

CKEDITOR.editorConfig = function( config )
{
  // Define changes to default configuration here. For example:
  // config.language = 'fr';
  // config.uiColor = '#AADC6E';

  //config.contentsCss = webContext + '/util/styleSheets/silverpeas-main.css';
  config.baseHref = webContext + '/wysiwyg/jsp/';
  config.filebrowserImageBrowseUrl = config.baseHref+'uploadFile.jsp';
  config.filebrowserFlashBrowseUrl = config.baseHref+'uploadFile.jsp';
  config.filebrowserBrowseUrl = config.baseHref+'uploadFile.jsp';
  config.imageUploadUrl = 'activated';
  config.extraPlugins = 'userzoom,identitycard,allmedias,autolink,video,html5audio,imageresizerowandcolumn,variables,listblock,floatpanel,richcombo,mediaofcontribution,imagebank,filebank';
  config.allowedContent = true;
  config.toolbarCanCollapse = true;
  config.disableNativeSpellChecker = false;
  //config.forcePasteAsPlainText = true;

  config.stylesSet = [
    {name: 'Titre 1', element: 'h2', attributes : { 'style' : 'border-left: 3px solid #2a2a2a; color: #2a2a2a; font-size: 16px; padding: 0 6px' }},
    {name: 'Titre 2', element: 'h3', attributes : { 'style' : 'border-left: 3px solid #7eb73b; color: #7eb73b; font-size: 14px; padding: 0 6px' }},
    {name: 'Focus', element:'strong', attributes : { 'style' : 'background-color: #2a2a2a; color: #FFF' }},
    {name: 'Paragraphe important', element:'p', attributes : { 'style' : 'background-color: #F5F5F5; border-radius: 0 10px 0 10px; padding: 9.5px; border: 1px solid #ebebeb; font-size: 110%' }}
  ];

  config.toolbar_infoLetter = [
    { name: 'document',    items : [ 'Source','-','NewPage','DocProps','Preview','Print','-','Templates' ] },
    { name: 'clipboard',   items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
    { name: 'editing',     items : [ 'Find','Replace','-','SelectAll' ] },
    '/',
    { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] },
    { name: 'paragraph',   items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock' ] },
    { name: 'links',       items : [ 'Link','Unlink','Anchor' ] },
    { name: 'insert',      items : [ 'Image','mediaofcontribution','imagebank','Video','Html5audio','Iframe','filebank','Table','HorizontalRule','Smiley','SpecialChar','PageBreak', 'variables' ] },
    '/',
    { name: 'styles',      items : [ 'Styles','Format','Font','FontSize' ] },
    { name: 'colors',      items : [ 'TextColor','BGColor' ] },
    { name: 'tools',       items : [ 'Maximize', 'ShowBlocks','-','About' ] }
  ];

  config.toolbar_infoLetter_ddwe = [
    { name: 'paragraph',   items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock' ] },
    { name: 'links',       items : [ 'Link','Unlink'] },
    { name: 'insert',      items : [ 'variables' ] },
    '/',
    { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','-','RemoveFormat' ] },
    { name: 'styles',      items : [ 'Styles','Format','Font','FontSize' ] },
    { name: 'colors',      items : [ 'TextColor','BGColor','Smiley' ] }
  ];
};<|endoftext|>


<commit_before>var CreateScratch = require('./imports/create_scratch_view');
var ImportService = require('./imports/service_import/import_service_view');
var ImportTwitter = require('./imports/twitter_import/import_twitter_view');
var ImportDataView = require('./imports/import_data_view');
var ImportArcGISView = require('./imports/import_arcgis_view');

/**
 * Attributes:
 *
 *  className: import pane class view
 *  fallbackClassName: ...
 *  name: local name
 *  title: text for tab link
 *  options:
 *    - service:
 *    - fileExtensions:
 *    - showAvailableFormats:
 *    - acceptSync:
 *    - fileAttrs:
 *
 */

module.exports = {
  File: {
    className: ImportDataView,
    name: 'file',
    title: 'Data file',
    options: {
      type: 'url',
      fileEnabled: true,
      acceptSync: true
    }
  },
  GDrive:   {
    className: ImportService,
    name: 'gdrive',
    title: 'Google Drive',
    options: {
      service: 'gdrive',
      fileExtensions: ['Google SpreadSheet', 'CSV'],
      showAvailableFormats: false,
      acceptSync: true,
      fileAttrs: {
        ext: true,
        title: 'filename',
        description: {
          content: [{
            name: 'size',
            format: 'size',
            key: true
          }]
        }
      }
    }
  },
  Dropbox: {
    className: ImportService,
    name: 'dropbox',
    title: 'Dropbox',
    options: {
      service: 'dropbox',
      fileExtensions: ['CSV', 'XLS', 'KML', 'GPX'],
      showAvailableFormats: true,
      acceptSync: true,
      fileAttrs: {
        ext: true,
        title: 'filename',
        description: {
          content: [
            {
              name: 'id',
              format: ''
            },
            {
              name: 'size',
              format: 'size',
              key: true
            }
          ],
          separator: '-'
        }
      }
    }
  },
  Twitter: {
    className: ImportTwitter,
    fallback: 'new_common/views/create/listing/import_twitter_fallback',
    name: 'twitter',
    title: 'Twitter'
  },
  Mailchimp: {
    className: ImportService,
    fallback: 'new_common/views/create/listing/import_mailchimp_fallback',
    name: 'mailchimp',
    title: 'MailChimp',
    options: {
      service: 'mailchimp',
      fileExtensions: [],
      acceptSync: true,
      showAvailableFormats: false,
      fileAttrs: {
        ext: true,
        title: 'filename',
        description: {
          content: [{
            name: 'member_count',
            format: 'number',
            key: true
          }],
          itemName: 'member',
          separator: ''
        }
      }
    }
  },
  Arcgis: {
    className: ImportArcGISView,
    fallback: 'new_common/views/create/listing/import_arcgis_fallback',
    name: 'arcgis',
    title: 'ArcGIS online'
  },
  Salesforce: {
    className: ImportDataView,
    fallback: 'new_common/views/create/listing/import_salesforce_fallback',
    name: 'salesforce',
    title: 'SalesForce',
    options: {
      type: 'service',
      service_name: 'salesforce',
      acceptSync: true,
      formTemplate: 'new_common/views/create/listing/import_types/data_form_salesforce',
      headerTemplate: 'new_common/views/create/listing/import_types/data_header_salesforce'
    }
  }
};
<commit_msg>#2849 js bugfix<commit_after>var ImportService = require('./imports/service_import/import_service_view');
var ImportTwitter = require('./imports/twitter_import/import_twitter_view');
var ImportDataView = require('./imports/import_data_view');
var ImportArcGISView = require('./imports/import_arcgis_view');

/**
 * Attributes:
 *
 *  className: import pane class view
 *  fallbackClassName: ...
 *  name: local name
 *  title: text for tab link
 *  options:
 *    - service:
 *    - fileExtensions:
 *    - showAvailableFormats:
 *    - acceptSync:
 *    - fileAttrs:
 *
 */

module.exports = {
  File: {
    className: ImportDataView,
    name: 'file',
    title: 'Data file',
    options: {
      type: 'url',
      fileEnabled: true,
      acceptSync: true
    }
  },
  GDrive:   {
    className: ImportService,
    name: 'gdrive',
    title: 'Google Drive',
    options: {
      service: 'gdrive',
      fileExtensions: ['Google SpreadSheet', 'CSV'],
      showAvailableFormats: false,
      acceptSync: true,
      fileAttrs: {
        ext: true,
        title: 'filename',
        description: {
          content: [{
            name: 'size',
            format: 'size',
            key: true
          }]
        }
      }
    }
  },
  Dropbox: {
    className: ImportService,
    name: 'dropbox',
    title: 'Dropbox',
    options: {
      service: 'dropbox',
      fileExtensions: ['CSV', 'XLS', 'KML', 'GPX'],
      showAvailableFormats: true,
      acceptSync: true,
      fileAttrs: {
        ext: true,
        title: 'filename',
        description: {
          content: [
            {
              name: 'id',
              format: ''
            },
            {
              name: 'size',
              format: 'size',
              key: true
            }
          ],
          separator: '-'
        }
      }
    }
  },
  Twitter: {
    className: ImportTwitter,
    fallback: 'new_common/views/create/listing/import_twitter_fallback',
    name: 'twitter',
    title: 'Twitter'
  },
  Mailchimp: {
    className: ImportService,
    fallback: 'new_common/views/create/listing/import_mailchimp_fallback',
    name: 'mailchimp',
    title: 'MailChimp',
    options: {
      service: 'mailchimp',
      fileExtensions: [],
      acceptSync: true,
      showAvailableFormats: false,
      fileAttrs: {
        ext: true,
        title: 'filename',
        description: {
          content: [{
            name: 'member_count',
            format: 'number',
            key: true
          }],
          itemName: 'member',
          separator: ''
        }
      }
    }
  },
  Arcgis: {
    className: ImportArcGISView,
    fallback: 'new_common/views/create/listing/import_arcgis_fallback',
    name: 'arcgis',
    title: 'ArcGIS online'
  },
  Salesforce: {
    className: ImportDataView,
    fallback: 'new_common/views/create/listing/import_salesforce_fallback',
    name: 'salesforce',
    title: 'SalesForce',
    options: {
      type: 'service',
      service_name: 'salesforce',
      acceptSync: true,
      formTemplate: 'new_common/views/create/listing/import_types/data_form_salesforce',
      headerTemplate: 'new_common/views/create/listing/import_types/data_header_salesforce'
    }
  }
};
<|endoftext|>


<commit_before>(function($){

	$.fn.mediaPlayer = function(options) {
		var defaults = {
				type			:"audio",
				source			:""
			},
			opts = $.extend({}, defaults, options),
			dimensionsString = "",
			thisMedia = this;

		if (opts.type == "audio") {
			opts.height = x_audioBarH;
			if (opts.width == undefined) {
				opts.width = thisMedia.width();
			}
		}
		if (opts.height != undefined) {
			dimensionsString = ' width="' + opts.width + '" height="' + opts.height + '"';
		}

		if (thisMedia.children().length > 0) {
			thisMedia.find("div").detach();
		}

		var fileInfo = opts.source.split(".");
		fileInfo.splice(1, 1, fileInfo[1].slice(0, -1));

		var setUpMedia = function() {
			opts.source = eval(opts.source);
			thisMedia.append('<' + opts.type + ' preload="metadata"' + dimensionsString + '><source type="' + opts.type + "/" + fileInfo[1] + '" src="' + opts.source + '" /></' + opts.type + '>');

			thisMedia.find(opts.type).mediaelementplayer({
				startVolume:		x_volume,
				alwaysShowControls:	true,
				pauseOtherPlayers:	true,
				enableAutosize:		true,
				playpauseText:		x_mediaText[1].label,
				muteText:			x_mediaText[2].label,
				fullscreenText:		x_mediaText[3].label,
				stopText:			x_mediaText[0].label,
				tracksText:			x_mediaText[4].label,
				success:	function (mediaElement, domObject) {
					if (opts.autoNavigate == "true" && x_currentPage + 1 != x_pages.length) { // go to next page when media played to end
						mediaElement.addEventListener("ended", function() {
							$x_nextBtn.trigger("click");
						}, false);
					}

					mediaElement.addEventListener("volumechange", function(e) { // update volume on all media players on page
						if (e.volume != undefined) {
							x_volume = e.volume;
						} else {
							x_volume = e.target.player.getVolume();
						}
						$("audio,video").each(function() {
							if (this != domObject) {
								var $this = $(this);
								if ($this.is(":visible")) { // html5
									if ($this[0].volume != x_volume) {
										$this[0].volume = x_volume;
									}
								} else { // flash
									if ($this[0].player.media.volume != x_volume) {
										$this[0].player.media.setVolume(x_volume);
									}
								}
							}
						});
					});

					if (opts.autoPlay == "true") { // autoplay media (won't work on iOS on 1st load)
						mediaElement.play();
					}

					if (opts.startEndFrame != undefined) { // start / end playing video at specified frame
						var startFrame	= opts.startEndFrame[0];
						var endFrame	= opts.startEndFrame[1];
						if (startFrame != 0) {
							mediaElement.addEventListener("canplay", function() {
								mediaElement.setCurrentTime(startFrame);
							});
						}
						if (endFrame != 0) {
							mediaElement.addEventListener("timeupdate", function(e) {
								if (mediaElement.currentTime > endFrame) {
									mediaElement.pause();
								}
							}, false);
						}
					}

					if (opts.pageName) {
						eval(opts.pageName).mediaFunct(mediaElement); // send mediaElement back to page so you can set up events for media
					}
				}
			});
		};

		var fileExists = function(url, resultCallback) {
			$.ajax({
				url: url,
				type: 'HEAD',
				success: function() {
					resultCallback(true);
				}, error: function() {
					resultCallback(false);
				}
			});
		};

		if (fileInfo['1'] !== 'mp4') {
			var url = eval(fileInfo[0] + ".mp4'");

			fileExists(url, function(exists) {
				if (exists) {
					opts.source = fileInfo[0] + ".mp4'";
				}

				setUpMedia();
			});
		}

	};
})(jQuery);<commit_msg>Fix source mimetype when changing the video url to mp4 version.<commit_after>(function($){

	$.fn.mediaPlayer = function(options) {
		var defaults = {
				type			:"audio",
				source			:""
			},
			opts = $.extend({}, defaults, options),
			dimensionsString = "",
			mimeType = '',
			thisMedia = this;

		if (opts.type == "audio") {
			opts.height = x_audioBarH;
			if (opts.width == undefined) {
				opts.width = thisMedia.width();
			}
		}
		if (opts.height != undefined) {
			dimensionsString = ' width="' + opts.width + '" height="' + opts.height + '"';
		}

		if (thisMedia.children().length > 0) {
			thisMedia.find("div").detach();
		}

		var fileInfo = opts.source.split(".");
		fileInfo.splice(1, 1, fileInfo[1].slice(0, -1));
		mimeType = opts.type + "/" + fileInfo[1];

		var setUpMedia = function() {
			opts.source = eval(opts.source);
			thisMedia.append('<' + opts.type + ' preload="metadata"' + dimensionsString + '><source type="' + mimeType + '" src="' + opts.source + '" /></' + opts.type + '>');

			thisMedia.find(opts.type).mediaelementplayer({
				startVolume:		x_volume,
				alwaysShowControls:	true,
				pauseOtherPlayers:	true,
				enableAutosize:		true,
				playpauseText:		x_mediaText[1].label,
				muteText:			x_mediaText[2].label,
				fullscreenText:		x_mediaText[3].label,
				stopText:			x_mediaText[0].label,
				tracksText:			x_mediaText[4].label,
				success:	function (mediaElement, domObject) {
					if (opts.autoNavigate == "true" && x_currentPage + 1 != x_pages.length) { // go to next page when media played to end
						mediaElement.addEventListener("ended", function() {
							$x_nextBtn.trigger("click");
						}, false);
					}

					mediaElement.addEventListener("volumechange", function(e) { // update volume on all media players on page
						if (e.volume != undefined) {
							x_volume = e.volume;
						} else {
							x_volume = e.target.player.getVolume();
						}
						$("audio,video").each(function() {
							if (this != domObject) {
								var $this = $(this);
								if ($this.is(":visible")) { // html5
									if ($this[0].volume != x_volume) {
										$this[0].volume = x_volume;
									}
								} else { // flash
									if ($this[0].player.media.volume != x_volume) {
										$this[0].player.media.setVolume(x_volume);
									}
								}
							}
						});
					});

					if (opts.autoPlay == "true") { // autoplay media (won't work on iOS on 1st load)
						mediaElement.play();
					}

					if (opts.startEndFrame != undefined) { // start / end playing video at specified frame
						var startFrame	= opts.startEndFrame[0];
						var endFrame	= opts.startEndFrame[1];
						if (startFrame != 0) {
							mediaElement.addEventListener("canplay", function() {
								mediaElement.setCurrentTime(startFrame);
							});
						}
						if (endFrame != 0) {
							mediaElement.addEventListener("timeupdate", function(e) {
								if (mediaElement.currentTime > endFrame) {
									mediaElement.pause();
								}
							}, false);
						}
					}

					if (opts.pageName) {
						eval(opts.pageName).mediaFunct(mediaElement); // send mediaElement back to page so you can set up events for media
					}
				}
			});
		};

		var fileExists = function(url, resultCallback) {
			$.ajax({
				url: url,
				type: 'HEAD',
				success: function() {
					resultCallback(true);
				}, error: function() {
					resultCallback(false);
				}
			});
		};

		if (fileInfo['1'] !== 'mp4') {
			var url = eval(fileInfo[0] + ".mp4'");

			fileExists(url, function(exists) {
				if (exists) {
					opts.source = fileInfo[0] + ".mp4'";
					mimeType = 'video/mp4';
				}

				setUpMedia();
			});
		}

	};
})(jQuery);<|endoftext|>


<commit_before>/*---------------------------------------------------------------
  :: sails-rest
  -> adapter
---------------------------------------------------------------*/

var Errors = require('waterline-errors').adapter,
  restify = require('restify'),
  url = require('url'),
  _ = require('lodash'),
  _i = require('underscore.inflections'),
  _s = require('underscore.string');

module.exports = (function() {
  "use strict";

  // Rest Custom Error Object
  function RestError(message, meta) {
    this.name = "RestError";
    this.message = message || "REST Error Message";
    this.meta = meta || {};
  }
  RestError.prototype = new Error();
  RestError.prototype.constructor = RestError;

  var connections = {};

  // Private functions
  /**
   * Format result object according to schema
   * @param {Object} result
   * @param {String} collectionName - collection the result object belongs to
   * @param {Object} config - connection configuration
   * @param {Object} definition - collection definition
   * @returns {Object}
   */
  function formatResult(result, collectionName, config, definition) {
    if (_.isFunction(config.beforeFormatResult)) {
      result = config.beforeFormatResult(result, collectionName, config, definition);
    }

    _.each(definition, function(def, key) {
      if (def.type.match(/date/i)) {
        result[key] = new Date(result[key] ? result[key] : null);
      }
    });

    if (_.isFunction(config.afterFormatResult)) {
      result = config.afterFormatResult(result, collectionName, config, definition);
    }

    return result;
  }

  /**
   * Format results according to schema
   * @param {Array} results - objects (model instances)
   * @param {String} collectionName - collection the result object belongs to
   * @param {Object} config - connection configuration
   * @param {Object} definition - collection definition
   * @returns {Array}
   */
  function formatResults(results, collectionName, config, definition) {
    if (_.isFunction(config.beforeFormatResults)) {
      results = config.beforeFormatResults(results, collectionName, config, definition);
    }

    results.forEach(function(result) {
      formatResult(result, collectionName, config, definition);
    });

    if (_.isFunction(config.afterFormatResults)) {
      results = config.afterFormatResults(results, collectionName, config, definition);
    }

    return results;
  }

  /**
   * Ensure results are contained in an array. Resolves variants in API responses such as `results` or `objects` instead of `[.....]`
   * @param {Object|Array} data - response data to format as results array
   * @param {String} collectionName - collection the result object belongs to
   * @param {Object} config - connection configuration
   * @param {Object} definition - collection definition
   * @returns {Object|Array}
   */
  function getResultsAsCollection(data, collectionName, config, definition) {
    var d = (data.objects || data.results || data),
      a = _.isArray(d) ? d : [d];

    return formatResults(a, collectionName, config, definition);
  }

  /**
   * Generate a pathname to use for a request
   * @param {Object} config - connection configuration
   * @param {String} method - request method
   * @param {Object} values - data being send (if any)
   * @param {Object} options - options passed from the calling method
   * @returns {Object}
   */
  function getPathname(config, method, values, options){
    return config.pathname + '/' + config.resource + (config.action ? '/' + config.action : '');
  }

  /**
   * Generate the query string for GET requests
   * @param {Object} config - connection configuration
   * @param {String} collectionName - collection the result object belongs to
   * @param {String} methodName - name of CRUD method being used
   * @param {Object} options - options passed from the calling method
   * @returns {Object}
   */
  function getQuery(config, collectionName, methodName, options){

    if (_.isFunction(config.query)) {
      return config.query(config, collectionName, methodName, options);
    }
    else {

      var query = config.query;

      _.extend(query, (options.where || {}));
      ['skip', 'limit', 'offset'].forEach(function(key){
        if(options[key] !== undefined){
          query[key] = options[key];
        }
      });

      return query;

    }

  }

  /**
   * Makes a REST request via restify
   * @param {String} identity - type of connection interface
   * @param {String} collectionName - collection the result object belongs to
   * @param {String} methodName - name of CRUD method being used
   * @param {Function} callback - callback from method
   * @param {Object} options - options from method
   * @param {Object|Array} [values] - values from method
   * @returns {*}
   */
  function makeRequest(identity, collectionName, methodName, callback, options, values) {
    var r = null,
      opt = null,
      cache = connections[identity].cache,
      config = _.cloneDeep(connections[identity].config),
      connection = connections[identity].connection,
      definition = connections[identity].definition,
      restMethod = config.methods[methodName],
      pathname;

    // Validate passed HTTP method
    if (!_.isFunction(connection[restMethod])) {
      callback(new Error('Invalid REST method: ' + restMethod));
      return;
    }

    // Override config settings from options if available
    if (options && _.isPlainObject(options)) {
      _.each(config, function(val, key) {
        if (_.has(options, key)) {
          config[key] = options[key];
        }
      });
    }

    // if resource name not set in config,
    // try to get it from pluralized form of collectionName
    if (!config.resource) {
      config.resource = config.pluralize === true ? _i.pluralize(collectionName) : collectionName;
    }

    pathname = config.getPathname(config, restMethod, values, options);

    if (options && options.where) {
      if (options.where.id) {
        // Add id to pathname if provided
        pathname += '/' + options.where.id;
        delete options.where.id;
      } else if (methodName === 'destroy' || methodName === 'update') {
        // Find all and make new request for each.
        makeRequest(identity, collectionName, 'find', function(err, results) {
          if (err) return callback(err);

          _.each(results, function(result, i) {
            var cb = ((i + 1) === results.length) ? callback : _.noop,
              options = {
                where: {
                  id: result.id
                }
              };

            makeRequest(identity, collectionName, methodName, cb, options, values);
          });
        }, options);

        return;
      }

      // Add where statement as query parameters if requesting via GET
      if (restMethod === 'get') {
        config.query = getQuery(config, collectionName, methodName, options);
      }
      // Set opt if additional where statements are available
      else if (_.size(options.where)) {
        opt = options.where;
      } else {
        delete options.where;
      }
    }

    if (!opt && values) {
      opt = values;

      if (options) {
        opt = _.extend(options, opt);
      }
    }

    // Add pathname to connection
    config.pathname = pathname;

    // Let user customize config before request is run
    if (_.isFunction(config.beforeRequest)) {
      config = config.beforeRequest(config);
    }

    // Format URI
    var uri = url.format(config);

    // Retrieve data from the cache
    if (methodName === 'find') {
      r = cache && cache.engine.get(uri);
    }

    if (r) {
      callback(null, r);
    } else if (_.isFunction(connection[restMethod])) {
      var path = uri.replace(connection.url.href, '/');

      var cb = function(err, req, res, data) {
        var restError,
            // check if response code is in 4xx or 5xx range
            responseErrorCode = res && /^(4|5)\d+$/.test(res.statusCode.toString());

        if (err && ( res === undefined || res === null || responseErrorCode ) ) {
          restError = new RestError(err.message, {originalError: err, data: data});
          callback(restError);
        } else {
          if (methodName === 'find') {
            r = getResultsAsCollection(data, collectionName, config, definition);
            if (cache) {
              cache.engine.set(uri, r);
            }
          } else {
            r = formatResult(data, collectionName, config, definition);
            if (cache) {
              cache.engine.del(uri);
            }
          }
          callback(null, r);
        }
      };

      // Make request via restify
      if (opt) {
        connection[restMethod](path, opt, cb);
      } else {
        connection[restMethod](path, cb);
      }
    }
  }

  // Adapter
  var adapter = {

    syncable: false,

    defaults: {
      type: 'json',
      protocol: 'http',
      hostname: 'localhost',
      port: 80,
      rejectUnauthorized: true,
      pathname: '',
      resource: null,
      action: null,
      query: {},
      pluralize: true,
      methods: {
        create: 'post',
        find: 'get',
        update: 'put',
        destroy: 'del'
      },
      getPathname: getPathname,
      beforeFormatResult: null,
      afterFormatResult: null,
      beforeFormatResults: null,
      afterFormatResults: null,
      beforeRequest: null
    },

    registerConnection: function(connection, collections, cb) {
      if (!connection.identity) return cb(Errors.IdentityMissing);
      if (connections[connection.identity]) return cb(Errors.IdentityDuplicate);

      var config, clientMethod, instance;

      config = this.defaults ? _.extend({}, this.defaults, connection) : connection;
      config.methods = this.defaults ? _.extend({}, this.defaults.methods, connection.methods) : connection.methods;
      clientMethod = _s.join('', 'create', _s.capitalize(config.type), 'Client');

      if (!_.isFunction(restify[clientMethod])) {
        throw new Error('Invalid type provided: ' + config.type);
      }

      instance = {
        config: config,
        connection: restify[clientMethod]({
          url: url.format({
            protocol: config.protocol,
            hostname: config.hostname,
            host: config.host,
            port: config.port
          }),
          headers: config.headers,
          rejectUnauthorized: config.rejectUnauthorized
        })
      };

      if (config.basicAuth) {
        instance.connection.basicAuth(config.basicAuth.username, config.basicAuth.password);
      }

      if (config.cache) {
        instance.cache = config.cache;
      }

      connections[connection.identity] = instance;

      cb();
    },

    create: function(connection, collectionName, values, cb) {
      makeRequest(connection, collectionName, 'create', cb, null, values);
    },

    find: function(connection, collectionName, options, cb) {
      makeRequest(connection, collectionName, 'find', cb, options);
    },

    update: function(connection, collectionName, options, values, cb) {
      makeRequest(connection, collectionName, 'update', cb, options, values);
    },

    destroy: function(connection, collectionName, options, cb) {
      makeRequest(connection, collectionName, 'destroy', cb, options);
    },

    drop: function(connection, collectionName, relations, cb) {
      cb();
    },

    define: function(connection, collectionName, definition, cb) {
      connections[connection].definition = definition;
      cb();
    },

    describe: function(connection, collectionName, cb) {
      cb(null, connections[connection].definition);
    }
  };

  return adapter;
}());
<commit_msg>Add a data transformation step<commit_after>/*---------------------------------------------------------------
  :: sails-rest
  -> adapter
---------------------------------------------------------------*/

var Errors = require('waterline-errors').adapter,
  restify = require('restify'),
  url = require('url'),
  _ = require('lodash'),
  _i = require('underscore.inflections'),
  _s = require('underscore.string');

module.exports = (function() {
  "use strict";

  // Rest Custom Error Object
  function RestError(message, meta) {
    this.name = "RestError";
    this.message = message || "REST Error Message";
    this.meta = meta || {};
  }
  RestError.prototype = new Error();
  RestError.prototype.constructor = RestError;

  var connections = {};

  // Private functions
  /**
   * Format result object according to schema
   * @param {Object} result
   * @param {String} collectionName - collection the result object belongs to
   * @param {Object} config - connection configuration
   * @param {Object} definition - collection definition
   * @returns {Object}
   */
  function formatResult(result, collectionName, config, definition) {
    if (_.isFunction(config.beforeFormatResult)) {
      result = config.beforeFormatResult(result, collectionName, config, definition);
    }

    _.each(definition, function(def, key) {
      if (def.type.match(/date/i)) {
        result[key] = new Date(result[key] ? result[key] : null);
      }
    });

    if (_.isFunction(config.afterFormatResult)) {
      result = config.afterFormatResult(result, collectionName, config, definition);
    }

    return result;
  }

  /**
   * Format results according to schema
   * @param {Array} results - objects (model instances)
   * @param {String} collectionName - collection the result object belongs to
   * @param {Object} config - connection configuration
   * @param {Object} definition - collection definition
   * @returns {Array}
   */
  function formatResults(results, collectionName, config, definition) {
    if (_.isFunction(config.beforeFormatResults)) {
      results = config.beforeFormatResults(results, collectionName, config, definition);
    }

    results.forEach(function(result) {
      formatResult(result, collectionName, config, definition);
    });

    if (_.isFunction(config.afterFormatResults)) {
      results = config.afterFormatResults(results, collectionName, config, definition);
    }

    return results;
  }

  /**
   * Ensure results are contained in an array. Resolves variants in API responses such as `results` or `objects` instead of `[.....]`
   * @param {Object|Array} data - response data to format as results array
   * @param {String} collectionName - collection the result object belongs to
   * @param {Object} config - connection configuration
   * @param {Object} definition - collection definition
   * @returns {Object|Array}
   */
  function getResultsAsCollection(data, collectionName, config, definition) {
    var d = (data.objects || data.results || data),
      a = _.isArray(d) ? d : [d];

    return formatResults(a, collectionName, config, definition);
  }

  /**
   * Generate a pathname to use for a request
   * @param {Object} config - connection configuration
   * @param {String} method - request method
   * @param {Object} values - data being send (if any)
   * @param {Object} options - options passed from the calling method
   * @returns {Object}
   */
  function getPathname(config, method, values, options){
    return config.pathname + '/' + config.resource + (config.action ? '/' + config.action : '');
  }

  /**
   * Generate the query string for GET requests
   * @param {Object} config - connection configuration
   * @param {String} collectionName - collection the result object belongs to
   * @param {String} methodName - name of CRUD method being used
   * @param {Object} options - options passed from the calling method
   * @returns {Object}
   */
  function getQuery(config, collectionName, methodName, options){

    if (_.isFunction(config.query)) {
      return config.query(config, collectionName, methodName, options);
    }
    else {

      var query = config.query;

      _.extend(query, (options.where || {}));
      ['skip', 'limit', 'offset'].forEach(function(key){
        if(options[key] !== undefined){
          query[key] = options[key];
        }
      });

      return query;

    }

  }

  /**
   * Makes a REST request via restify
   * @param {String} identity - type of connection interface
   * @param {String} collectionName - collection the result object belongs to
   * @param {String} methodName - name of CRUD method being used
   * @param {Function} callback - callback from method
   * @param {Object} options - options from method
   * @param {Object|Array} [values] - values from method
   * @returns {*}
   */
  function makeRequest(identity, collectionName, methodName, callback, options, values) {
    var r = null,
      opt = null,
      cache = connections[identity].cache,
      config = _.cloneDeep(connections[identity].config),
      connection = connections[identity].connection,
      definition = connections[identity].definition,
      restMethod = config.methods[methodName],
      pathname;

    // Validate passed HTTP method
    if (!_.isFunction(connection[restMethod])) {
      callback(new Error('Invalid REST method: ' + restMethod));
      return;
    }

    // Override config settings from options if available
    if (options && _.isPlainObject(options)) {
      _.each(config, function(val, key) {
        if (_.has(options, key)) {
          config[key] = options[key];
        }
      });
    }

    // if resource name not set in config,
    // try to get it from pluralized form of collectionName
    if (!config.resource) {
      config.resource = config.pluralize === true ? _i.pluralize(collectionName) : collectionName;
    }

    pathname = config.getPathname(config, restMethod, values, options);

    if (options && options.where) {
      if (options.where.id) {
        // Add id to pathname if provided
        pathname += '/' + options.where.id;
        delete options.where.id;
      } else if (methodName === 'destroy' || methodName === 'update') {
        // Find all and make new request for each.
        makeRequest(identity, collectionName, 'find', function(err, results) {
          if (err) return callback(err);

          _.each(results, function(result, i) {
            var cb = ((i + 1) === results.length) ? callback : _.noop,
              options = {
                where: {
                  id: result.id
                }
              };

            makeRequest(identity, collectionName, methodName, cb, options, values);
          });
        }, options);

        return;
      }

      // Add where statement as query parameters if requesting via GET
      if (restMethod === 'get') {
        config.query = getQuery(config, collectionName, methodName, options);
      }
      // Set opt if additional where statements are available
      else if (_.size(options.where)) {
        opt = options.where;
      } else {
        delete options.where;
      }
    }

    if (!opt && values) {
      opt = values;

      if (options) {
        opt = _.extend(options, opt);
      }
    }

    // Add pathname to connection
    config.pathname = pathname;

    // Let user customize config before request is run
    if (_.isFunction(config.beforeRequest)) {
      config = config.beforeRequest(config);
    }

    // Format URI
    var uri = url.format(config);

    // Retrieve data from the cache
    if (methodName === 'find') {
      r = cache && cache.engine.get(uri);
    }

    if (r) {
      callback(null, r);
    } else if (_.isFunction(connection[restMethod])) {
      var path = uri.replace(connection.url.href, '/');

      var cb = function(err, req, res, data) {
        var restError,
            // check if response code is in 4xx or 5xx range
            responseErrorCode = res && /^(4|5)\d+$/.test(res.statusCode.toString());

        if (err && ( res === undefined || res === null || responseErrorCode ) ) {
          restError = new RestError(err.message, {originalError: err, data: data});
          callback(restError);
        } else {
          if (methodName === 'find') {
            r = getResultsAsCollection(data, collectionName, config, definition);
            if (cache) {
              cache.engine.set(uri, r);
            }
          } else {
            r = formatResult(data, collectionName, config, definition);
            if (cache) {
              cache.engine.del(uri);
            }
          }
          callback(null, r);
        }
      };

      // Make request via restify
      if (opt) {
        if (_.isFunction(config.transformData)) {
          opt = config.transformData(opt, config, methodName);
        }
        connection[restMethod](path, opt, cb);
      } else {
        connection[restMethod](path, cb);
      }
    }
  }

  // Adapter
  var adapter = {

    syncable: false,

    defaults: {
      type: 'json',
      protocol: 'http',
      hostname: 'localhost',
      port: 80,
      rejectUnauthorized: true,
      pathname: '',
      resource: null,
      action: null,
      query: {},
      pluralize: true,
      methods: {
        create: 'post',
        find: 'get',
        update: 'put',
        destroy: 'del'
      },
      getPathname: getPathname,
      beforeFormatResult: null,
      afterFormatResult: null,
      beforeFormatResults: null,
      afterFormatResults: null,
      beforeRequest: null
    },

    registerConnection: function(connection, collections, cb) {
      if (!connection.identity) return cb(Errors.IdentityMissing);
      if (connections[connection.identity]) return cb(Errors.IdentityDuplicate);

      var config, clientMethod, instance;

      config = this.defaults ? _.extend({}, this.defaults, connection) : connection;
      config.methods = this.defaults ? _.extend({}, this.defaults.methods, connection.methods) : connection.methods;
      clientMethod = _s.join('', 'create', _s.capitalize(config.type), 'Client');

      if (!_.isFunction(restify[clientMethod])) {
        throw new Error('Invalid type provided: ' + config.type);
      }

      instance = {
        config: config,
        connection: restify[clientMethod]({
          url: url.format({
            protocol: config.protocol,
            hostname: config.hostname,
            host: config.host,
            port: config.port
          }),
          headers: config.headers,
          rejectUnauthorized: config.rejectUnauthorized
        })
      };

      if (config.basicAuth) {
        instance.connection.basicAuth(config.basicAuth.username, config.basicAuth.password);
      }

      if (config.cache) {
        instance.cache = config.cache;
      }

      connections[connection.identity] = instance;

      cb();
    },

    create: function(connection, collectionName, values, cb) {
      makeRequest(connection, collectionName, 'create', cb, null, values);
    },

    find: function(connection, collectionName, options, cb) {
      makeRequest(connection, collectionName, 'find', cb, options);
    },

    update: function(connection, collectionName, options, values, cb) {
      makeRequest(connection, collectionName, 'update', cb, options, values);
    },

    destroy: function(connection, collectionName, options, cb) {
      makeRequest(connection, collectionName, 'destroy', cb, options);
    },

    drop: function(connection, collectionName, relations, cb) {
      cb();
    },

    define: function(connection, collectionName, definition, cb) {
      connections[connection].definition = definition;
      cb();
    },

    describe: function(connection, collectionName, cb) {
      cb(null, connections[connection].definition);
    }
  };

  return adapter;
}());
<|endoftext|>


<commit_before>/**
 * GT core JavaScript file. Allows accessing applications' APIs, DOM elements,
 * templated elements and PageTools' JavaScript functions using simple syntax.
 *
 * GT is developed by Greg Bowler / PHP.Gt team.
 * Documentation: http://php.gt/Docs/ClientSide/GtJs.html
 *
 * Provided as standard:
 * GT.api("Name") - manipulate the application's API.
 * GT.dom("selector") - obtain a reference to GTDOM element, with helpers.
 * GT.template("Name") - obtain a cloned GTDOM element, taken from the template.
 * GT.tool("Name") - obtain an object wrapper to the JavaScript extensions of
 * certain PHP.Gt PageTools.
 *
 * Note that the global GT object acts as a shorthand too:
 * GT(callback) - execute the callback function on the DOM ready event.
 * GT("selector") - shorthand to selecting a GTDOM element.
 *
 * Gt.js provides helper functions on the DOM elements by wrapping all elements
 * within the GT.DOM namespace.
 * Compatible with Google Chrom[e|ium] 10+, Mozilla Firefox 8+, Opera 11+,
 * Internet Explorer 8+.
 */
;(function() {
/**
 * This function represents the function that is attached to the window as
 * window.GT, and also acts as a shorthand function for many of the features
 * of this library.
 *
 * Pass a string, and it will be treated as a CSS selector, returning a
 * GT.domElCollection containing all matching GT.domElement objects. The context
 * of the selection can be passed into the second argument as any representation
 * of DOM Elements, native or GT.
 *
 * Pass a function, and the function will be added to the loadQueue and invoked
 * on the browser's DOM Ready event. A second argument can be passed in as a
 * string or regular expression to match on the current window.location.href.
 * If there is no match, the function will be ignored.
 */
var _GT = function() {
	if(GT.typeOf(arguments[0]) === "function") {
		console.log("Function added.");
		return;
	}
	if(GT.typeOf(arguments[0]) === "string") {
		console.log("CSS selector");
		return;
	}
	if(GT.instanceOf(arguments[0], GT.baseType("NodeList"))
	|| GT.instanceOf(arguments[0], GT.baseType("Node")) ){
		console.log("Returning a GT.dom.element");
		return;
	}

	throw new GT.error("Invalid GT parameters.", arguments);
},

_domFunctions = {
	"create": function(el, attrArray, value) {
		return "CREATED ELEMENT";
	},
},
_domElementFunctions = {
	"addClass": function(className) {
	},
	"removeClass": function(className) {
	},
	"toggleClass": function(className) {
	},
	"hasClass": function(className) {
	},

	"appendChild": function(child) {
	},
	"appendChildAfter": function(child) {
	},
	"appendChildBefore": function(child) {
	},

	"getAttribute": function(name) {
	},
	"setAttribute": function(name, value) {
	},
	"hasAttribute": function(name) {
	}
},
/**
 * Element map functions listed here are mapped directly to functions in the
 * _domElementFunctions object of the same name. Each element within the
 * collection is iterated over. The returned result is the combination of all
 * elements within the collection. For example, .hasClass will return true if
 * any of the elements have the specified class name.
 */
_domElementCollectionFunctions = {
	"mappedFunctions": [
		"addClass",
		"removeClass",
		"toggleClass",
		"hasClass",
	]
},

/**
 * Internal function.
 * Once PHP.Gt has processed any template elements, they will be placed in a
 * special hidden DIV in the document.body, retrieved by this function.
 * In projects that do not use PHP.Gt, the templating functionality can still
 * be used because of this function.
 *
 * Called internally, it adds all template elements within the special PHP.Gt
 * DIV to the internal template object, then removes any existing elements
 * with a data-template attribute, storing them in the internal object.
 *
 * The template list object is exposed by the GT.template function.
 */
_templateScrape = function() {

},

/**
 * Internal function.
 * Creates a listener on the DOM ready event and invokes the load queue when it
 * fires. Compatible with old IE browsers too.
 */
_attachLoadQueue = function() {

},

/**
 * Internal function.
 * Called when the DOM ready event fires. Executes all callbacks in the load
 * queue.
 */
_invokeLoadQueue = function() {

},

/**
 * Creates an exception object with an optional object to report to the console.
 *
 * @param {string} message The message to be logged.
 * @param {object} [obj] The associated object, or array of objects.
 * @return {object} The exception object, to be thrown.
 */
error = function(message, obj) {
	var that = this;
	this.name = "GtErrorException";
	this.message = this.name + ": " + message;
	this.arguments = Array.prototype.pop.apply(arguments);
	this.toString = function() {
		return that.message;
	}
},

/**
 * Returns a string representation of the type of the passed in object.
 */
typeOf = function(obj) {
	return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
},
/**
 * Checks the prototype tree of the passed in object. The test subject could be
 * a string representation of the type to check for.
 */
instanceOf = function(obj, test) {
	var ref = obj,
		test = test.toLowerCase(),
		newRef,
		count = 0;

	// Check parameters are correctly typed.
	if(GT.typeOf(test) !== "string") {
		throw new GT.error(
			"GT.instanceOf method parameters incorrect types.",
			arguments
		);
	}

	// Because of certain popular browsers not supporting W3C DOM2 standard,
	// HTMLElement and Node tests have to be handled differently.
	if(test === "node") {
		return !!(
			typeof obj == "object"
			&& "nodeType" in obj
			&& obj.nodeType >= 1
			&& obj.nodeType <= 12
			&& obj.cloneNode
		);
	}
	if(test === "htmlelement") {
		return !!(
			typeof obj == "object"
			&& "nodeType" in obj
			&& obj.nodeType === 1
			&& obj.cloneNode
		);
	}

	// Recursive loop on reference.constructor, checking the type.
	while(ref && count < 100) {
		newRef = new Object(ref.constructor);
		if(newRef === ref) {
			break;
		}
		ref = newRef;

		if(GT.typeOf(ref) === test) {
			return true;
		}
		count++;
	}

	return false;
},

/**
 * Merges all properties from obj1, obj2, obj3, obj4, ... and returns
 * the new object.
 * @param {object} target The object who's properties to extend.
 * @param {object} obj1 First object to take the properties from.
 * @param {object} [obj2] Second object to take the properties from.
 * @param {object} [objN] Any number of objects to take the properties from.
 * @return {object} The merged object.
 */
merge = function(target, obj1, obj2, objN) {
	var argLen = arguments.length,
		i = 1,
		prop;
	for(; i < argLen; i++) {
		for(prop in arguments[i]) {
			if(arguments[i].hasOwnProperty(prop)) {
				target[prop] = arguments[i][prop];
			}
		}
	}

	return target;
},

/**
 * Initializes a nested namespace within the GT global for use in modular
 * scripts.
 *
 * @return {Object} The created namespace object.
 */
namespace = function() {

},

/**
 * Adds a callback to the load queue to be invoked on the DOM ready event.
 * If a page is given, callbacks will only be added to the queue if the current
 * window.location.href matches the given string or regular expression.
 *
 * @param {function} callback The callback to invoke on DOM ready.
 * @param {string|RegExp} [page] The match to make in order to add the callback.
 */
ready = function(callback, page) {

},

/**
 * Used to perform asynchronous HTTP requests. Automatically parses the response
 * by converting to JSON wherever possible. For connection pooling, the GT.http
 * object is instantiated with `new`.
 *
 */
http = function() {
	/**
	 * @param {string} uri The HTTP URI to connect to with or without query
	 * string parameters. For HTTP GET and DELETE methods, the data parameter
	 * will be converted to a query string as these methods do not allow data
	 * in the body.
	 * @param {string} [method] Defaults to GET, can be either GET, POST, PUT
	 * or DELETE.
	 * @param {object|string} [data] The key-value-pair object to place in the
	 * request body. Optionally, a querystring style string can be used. When
	 * data is passed in on GET or DELETE methods, the keys are moved to the
	 * querystring, as they do not allow data in the request body. If there is
	 * already a querystring, an exception is thrown.
	 * @param {function} [callback] The callback to invoke when the HTTP request
	 * gets a response. The callback is passed two parameters: `responseData`,
	 * either a string containing the response or an object when JSON was
	 * returned, and `xhr`, a reference to the XMLHttpRequest object used.
	 */
	var execute = function(uri, method, data, callback) {
	};

	return {
		"execute": execute
	}
},

/**
 * Used as a shorthand function to interact with PHP.Gt's public HTTP APIs.
 */
api = function() {

},

/**
 * Wraps CSS selectors to GT.dom.elementCollection objects.
 * @param {string} selector The CSS selector to search the DOM for.
 * Alternatively, a reference to a native HTML element, array of native HTML
 * elements, or a DOM Node List can be passed as the first argument, which will
 * be converted into a GT.dom.elementCollection.
 * @param {GT.dom.element} [context] The context to execute the CSS selector in.
 * This defaults to window.document.
 */
dom = function(selector, context) {
	return "SELECTED ELEMT";
},

/**
 * Obtains a cloned reference to a template element.
 */
template = function(name) {

},

tool = function() {

};

// Attach the GT object to the window, exposing the namespace as a global.
window.GT = _GT;
// Build the GT object to expose public methods.
GT.error = error;
GT.typeOf = typeOf;
GT.instanceOf = instanceOf;
GT.dom = dom;
GT.merge = merge;

// Extend GT.dom capabilities.
GT.merge(GT.dom, _domFunctions);
return;

})();<commit_msg>Major update to client side code, not backwards compatible! Main improvements are with DOM handling and IE8 compatibility.<commit_after>/**
 * GT core JavaScript file. Allows accessing applications' APIs, DOM elements,
 * templated elements and PageTools' JavaScript functions using simple syntax.
 *
 * GT is developed by Greg Bowler / PHP.Gt team.
 * Documentation: http://php.gt/Docs/ClientSide/GtJs.html
 *
 * Provided as standard:
 * GT.api("Name") - manipulate the application's API.
 * GT.dom("selector") - obtain a reference to GTDOM element, with helpers.
 * GT.template("Name") - obtain a cloned GTDOM element, taken from the template.
 * GT.tool("Name") - obtain an object wrapper to the JavaScript extensions of
 * certain PHP.Gt PageTools.
 *
 * Note that the global GT object acts as a shorthand too:
 * GT(callback) - execute the callback function on the DOM ready event.
 * GT("selector") - shorthand to selecting a GTDOM element.
 *
 * Gt.js provides helper functions on the DOM elements by wrapping all elements
 * within the GT.DOM namespace.
 * Compatible with Google Chrom[e|ium] 10+, Mozilla Firefox 8+, Opera 11+,
 * Internet Explorer 8+, Safari 5+.
 */
;(function() {
/**
 * This function represents the function that is attached to the window as
 * window.GT, and also acts as a shorthand function for many of the features
 * of this library.
 *
 * Pass a string, and it will be treated as a CSS selector, returning a
 * GT.domElCollection containing all matching GT.domElement objects. The context
 * of the selection can be passed into the second argument as any representation
 * of DOM Elements, native or GT.
 *
 * Pass a function, and the function will be added to the loadQueue and invoked
 * on the browser's DOM Ready event. A second argument can be passed in as a
 * string or regular expression to match on the current window.location.href.
 * If there is no match, the function will be ignored.
 */
var _GT = function() {
	if(GT.typeOf(arguments[0]) === "function") {
		console.log("Function added.");
		return;
	}
	if(GT.typeOf(arguments[0]) === "string") {
		console.log("CSS selector");
		return;
	}
	if(GT.instanceOf(arguments[0], GT.baseType("NodeList"))
	|| GT.instanceOf(arguments[0], GT.baseType("Node")) ){
		console.log("Returning a GT.dom.element");
		return;
	}

	throw new GT.error("Invalid GT parameters.", arguments);
},

/**
 * As browser support for HTMLElement and Node varies across the mainstream
 * browsers, DomElement wraps all DOM interaction and provides a normalised
 * API across all browsers.
 *
 * DomElement is exposed on GT.dom.element and can be constructed as
 * new GT.dom.element, and is returned by using any of the DOM manipulation
 * functions within GT.
 */
DomElement = function(el, attrObj, value) {
	var that = this,
		dummy = document.createElement("_"),
		_node = null,
		prop,
		propsToWrap = [
			"childNodes",
			"children",
			"firstChild",
			"lastChild",
		];

	if(GT.instanceOf(el, "Node")) {
		_node = el;
	}
	else if(GT.typeOf(el) === "string") {
		_node = document.createElement(el);
	}
	else if(GT.typeOf(el) === "domelement") {
		_node = el._node;
	}
	else {
		throw new GT.error(
			"DomElement constructor passed invalid element parameter", el);
	}

	if(GT.typeOf(attrObj) === "object") {
		for(prop in attrObj) {
			if(!attrObj.hasOwnProperty(prop)) {
				continue;
			}
			_node.setAttribute(prop, attrObj[prop]);
		}
	}
	else if(GT.typeOf(attrObj) === "string") {
		// This allows a new element to be created by ignoring the attrArray
		// parameter: GT.dom.create("p", "This is a test");
		value = attrObj;
	}

	if(value) {
		_node.textContent = value;
	}

`
	// Copy all properties from the native node to the DomElement, but skip
	// any that need references to DomElement objects themselves.
	for(prop in _node) {
		try {
			//if(!Object.prototype.hasOwnProperty.call(_node, prop)) {
			//	continue;
			//}
			if(propsToWrap.indexOf(prop) >= 0) {
				// TODO: Wrap property.
			}
			else {
				this[prop] = _node[prop];
			}
		}
		catch(e) {
			this[prop] = 0;
		}
	}
	this._node = _node;

	// Attach all property listeners.
	_node.constructor.prototype.watch = _domElementPropWatch;
	_node.watch("textContent", function(v1, v2, v3, v4) {
		console.log("WIN!!!", v1, v2, v3, v4);
	});

	return _node;
},

DomElementCollection = function(elArray) {
	this.value = "I AM AN ELEMENT COLLECTION!";
},

/**
 * Object.watch is a non-standard function in the Gecko rendering engine, added
 * to the current browser's native DOM Element in this shim.
 * Watches for a property to be assigned a value and runs a function when
 * that occurs.
 * @param {string} prop The property name to watch upon.
 * @param {function} callback The function to call when the property changes.
 */
_domElementPropWatch = function(prop, callback) {
	var oldval = this[prop],
		newval = oldval,
		getter = function() {
			return newval;
		},
		setter = function(val) {
			oldval = newval;
			return newval = callback.call(this, prop, oldval, val);
		};
	if (delete this[prop]) { // can't watch constants
		// ES5-compliant browsers:
		if(Object.defineProperty) {
			Object.defineProperty(this, prop, {
				get: getter,
				set: setter
			});
		}
		// Legacy browsers:
		else if(Object.prototype.__defineGetter__
		&& Object.prototype.__defineSetter__) {
			Object.prototype.__defineGetter__.call(this, prop, getter);
			Object.prototype.__defineSetter__.call(this, prop, setter);
		}
	}
};

_domFunctions = {
	"create": function(el, attrArray, value) {
		return "CREATED ELEMENT";
	},
},
_domElementFunctions = {
	"addClass": function(className) {
	},
	"removeClass": function(className) {
	},
	"toggleClass": function(className) {
	},
	"hasClass": function(className) {
	},

	"appendChild": function(child) {
	},
	"appendChildAfter": function(child) {
	},
	"appendChildBefore": function(child) {
	},

	"getAttribute": function(name) {
	},
	"setAttribute": function(name, value) {
	},
	"hasAttribute": function(name) {
	},
},
/**
 * Element map functions listed here are mapped directly to functions in the
 * _domElementFunctions object of the same name. Each element within the
 * collection is iterated over. The returned result is the combination of all
 * elements within the collection. For example, .hasClass will return true if
 * any of the elements have the specified class name.
 */
_domElementCollectionFunctions = {
	"fnMapAll": [
		"addClass",
		"removeClass",
		"toggleClass",
		"hasClass",
	],
	"fnMapFirst": [
		"appendChild",
		"appendChildAfter",
		"appendChildBefore",
		"getAttribute",
		"setAttribute",
		"hasAttribute",
	],
},

/**
 * To allow certain JavaScript features to be usable across all mainstream
 * browsers, shims are functions that are attached to particular objects'
 * prototypes. Each key in the _shims object represents the object to
 * extend, and the properties within each object's keys are the named functions
 * to assign. This is done in the _addShims function.
 */
_shims = {
	"Object": {
	},
	"Array": {
		/**
		 * Returns the first index at which a given element can be found in
		 * the array, or -1 if it is not present.
		 */
		"indexOf": function (searchElement /*, fromIndex */ ) {
	        "use strict";
	        if (this == null) {
	            throw new TypeError();
	        }
	        var t = Object(this);
	        var len = t.length >>> 0;
	        if (len === 0) {
	            return -1;
	        }
	        var n = 0;
	        if (arguments.length > 1) {
	            n = Number(arguments[1]);
	            if (n != n) { // shortcut for verifying if it's NaN
	                n = 0;
	            } else if (n != 0 && n != Infinity && n != -Infinity) {
	                n = (n > 0 || -1) * Math.floor(Math.abs(n));
	            }
	        }
	        if (n >= len) {
	            return -1;
	        }
	        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
	        for (; k < len; k++) {
	            if (k in t && t[k] === searchElement) {
	                return k;
	            }
	        }
	        return -1;
	    }
	},
},

/**
 * Called internally, attaches JavaScript versions of native functionality to
 * older / non-supportive browsers, or attaches special helper functions to all
 * browsers.
 *
 * Iterates over all functions in the _shims object, checks if the function
 * already exists and if not, attaches it to the relevant prototype.
 */
_addShims = function() {
	var obj, 	// Name of the object to extend.
		def,	// Name of the function definition to add.
		proto;	// Reference to the object prototype's function.
	for(obj in _shims) {
		if(!_shims.hasOwnProperty(obj)) {
			continue;
		}

		for(def in _shims[obj]) {
			if(!_shims[obj].hasOwnProperty(def)) {
				continue;
			}

			proto = window[obj].prototype[def];
			if(proto) {
				continue;
			}

			/**
			 * TODO: Try to get IE to play ball one last time, then if not we'll
			 * just have to get EVERYTHING in a method... not as sexy but owell.
			 */

			try {
				Object.defineProperty(
					window[obj].prototype,
					def,
					{
						"enumerable": false,
						"configurable": true,
						"writable": false,
						"value": _shims[obj][def],
					}
				);
			}
			catch(e) {
				// For non ES5-compliant browsers.
				window[obj].prototype[def] = _shims[obj][def];
			}
		}
	}
},

/**
 * Internal function.
 * Once PHP.Gt has processed any template elements, they will be placed in a
 * special hidden DIV in the document.body, retrieved by this function.
 * In projects that do not use PHP.Gt, the templating functionality can still
 * be used because of this function.
 *
 * Called internally, it adds all template elements within the special PHP.Gt
 * DIV to the internal template object, then removes any existing elements
 * with a data-template attribute, storing them in the internal object.
 *
 * The template list object is exposed by the GT.template function.
 */
_templateScrape = function() {

},

/**
 * Internal function.
 * Creates a listener on the DOM ready event and invokes the load queue when it
 * fires. Compatible with old IE browsers too.
 */
_attachLoadQueue = function() {

},

/**
 * Internal function.
 * Called when the DOM ready event fires. Executes all callbacks in the load
 * queue.
 */
_invokeLoadQueue = function() {

},

/**
 * Creates an exception object with an optional object to report to the console.
 *
 * @param {string} message The message to be logged.
 * @param {object} [obj] The associated object, or array of objects.
 * @return {object} The exception object, to be thrown.
 */
error = function(message, obj) {
	var that = this;
	this.name = "GtErrorException";
	this.message = this.name + ": " + message;
	this.arguments = Array.prototype.pop.apply(arguments);
	this.toString = function() {
		return that.message;
	}
},

/**
 * Returns a string representation of the type of the passed in object.
 */
typeOf = function(obj) {
	return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
},
/**
 * Checks the prototype tree of the passed in object. The test subject could be
 * a string representation of the type to check for.
 */
instanceOf = function(obj, test) {
	var ref = obj,
		test = test.toLowerCase(),
		newRef,
		count = 0;

	// Check parameters are correctly typed.
	if(GT.typeOf(test) !== "string") {
		throw new GT.error(
			"GT.instanceOf method parameters incorrect types.",
			arguments
		);
	}

	// Because of certain popular browsers not supporting W3C DOM2 standard,
	// HTMLElement and Node tests have to be handled differently.
	if(test === "node") {
		return !!(
			typeof obj == "object"
			&& "nodeType" in obj
			&& obj.nodeType >= 1
			&& obj.nodeType <= 12
			&& obj.cloneNode
		);
	}
	if(test === "htmlelement") {
		return !!(
			typeof obj == "object"
			&& "nodeType" in obj
			&& obj.nodeType === 1
			&& obj.cloneNode
		);
	}

	// Recursive loop on reference.constructor, checking the type.
	while(ref && count < 100) {
		newRef = new Object(ref.constructor);
		if(newRef === ref) {
			break;
		}
		ref = newRef;

		if(GT.typeOf(ref) === test) {
			return true;
		}
		count++;
	}

	return false;
},

/**
 * Merges all properties from obj1, obj2, obj3, obj4, ... and returns
 * the new object.
 * @param {object} target The object who's properties to extend.
 * @param {object} obj1 First object to take the properties from.
 * @param {object} [obj2] Second object to take the properties from.
 * @param {object} [objN] Any number of objects to take the properties from.
 * @return {object} The merged object.
 */
merge = function(target, obj1, obj2, objN) {
	var argLen = arguments.length,
		i = 1,
		prop;
	for(; i < argLen; i++) {
		for(prop in arguments[i]) {
			if(arguments[i].hasOwnProperty(prop)) {
				target[prop] = arguments[i][prop];
			}
		}
	}

	return target;
},

/**
 * Initializes a nested namespace within the GT global for use in modular
 * scripts.
 *
 * @return {Object} The created namespace object.
 */
namespace = function() {

},

/**
 * Adds a callback to the load queue to be invoked on the DOM ready event.
 * If a page is given, callbacks will only be added to the queue if the current
 * window.location.href matches the given string or regular expression.
 *
 * @param {function} callback The callback to invoke on DOM ready.
 * @param {string|RegExp} [page] The match to make in order to add the callback.
 */
ready = function(callback, page) {

},

/**
 * Used to perform asynchronous HTTP requests. Automatically parses the response
 * by converting to JSON wherever possible. For connection pooling, the GT.http
 * object is instantiated with `new`.
 *
 */
http = function() {
	/**
	 * @param {string} uri The HTTP URI to connect to with or without query
	 * string parameters. For HTTP GET and DELETE methods, the data parameter
	 * will be converted to a query string as these methods do not allow data
	 * in the body.
	 * @param {string} [method] Defaults to GET, can be either GET, POST, PUT
	 * or DELETE.
	 * @param {object|string} [data] The key-value-pair object to place in the
	 * request body. Optionally, a querystring style string can be used. When
	 * data is passed in on GET or DELETE methods, the keys are moved to the
	 * querystring, as they do not allow data in the request body. If there is
	 * already a querystring, an exception is thrown.
	 * @param {function} [callback] The callback to invoke when the HTTP request
	 * gets a response. The callback is passed two parameters: `responseData`,
	 * either a string containing the response or an object when JSON was
	 * returned, and `xhr`, a reference to the XMLHttpRequest object used.
	 */
	var execute = function(uri, method, data, callback) {
	};

	return {
		"execute": execute
	}
},

/**
 * Used as a shorthand function to interact with PHP.Gt's public HTTP APIs.
 */
api = function() {

},

/**
 * Wraps CSS selectors to GT.dom.elementCollection objects.
 * @param {string} selector The CSS selector to search the DOM for.
 * Alternatively, a reference to a native HTML element, array of native HTML
 * elements, or a DOM Node List can be passed as the first argument, which will
 * be converted into a GT.dom.elementCollection.
 * @param {GT.dom.element} [context] The context to execute the CSS selector in.
 * This defaults to window.document.
 */
dom = function(selector, context) {
	return "SELECTED ELEMT";
},

/**
 * Obtains a cloned reference to a template element.
 */
template = function(name) {

},

tool = function() {

};

// Attach the GT object to the window, exposing the namespace as a global.
window.GT = _GT;

// Extend any objects required for full functionality.
_addShims();

// Build the GT object to expose public methods.
GT.error = error;
GT.typeOf = typeOf;
GT.instanceOf = instanceOf;

GT.dom = dom;
GT.dom.element = DomElement;
GT.dom.elementCollection = DomElementCollection;

GT.merge = merge;

// Extend GT.dom capabilities.
GT.merge(GT.dom, _domFunctions);
return;

})();<|endoftext|>