<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.
 *
*/

/*jshint -W030 */

var FileTransferError = require('./FileTransferError'),
    ProgressEvent = require('org.apache.cordova.file.ProgressEvent'),
    FileUploadResult = require('org.apache.cordova.file.FileUploadResult'),
    FileEntry = require('org.apache.cordova.file.FileEntry');

// Some private helper functions, hidden by the module
function cordovaPathToNative(path) {
    // turn / into \\
    var cleanPath = path.replace(/\//g, '\\');
    // turn  \\ into \
    cleanPath = cleanPath.replace(/\\\\/g, '\\');
    // strip end \\ characters
    cleanPath = cleanPath.replace(/\\+$/g, '');
    return cleanPath;
}

function nativePathToCordova(path) {
    var cleanPath = path.replace(/\\/g, '/');
    return cleanPath;
}

var fileTransferOps = [];

function FileTransferOperation(state, promise) {
    this.state = state;
    this.promise = promise;
}

FileTransferOperation.PENDING = 0;
FileTransferOperation.DONE = 1;
FileTransferOperation.CANCELLED = 2;

module.exports = {

/*
exec(win, fail, 'FileTransfer', 'upload',
[filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
*/
    upload:function(successCallback, errorCallback, options) {
        var filePath = options[0];
        var server = options[1];
        var fileKey = options[2] || 'source';
        var fileName = options[3];
        var mimeType = options[4];
        var params = options[5];
        var trustAllHosts = options[6]; // todo
        var chunkedMode = options[7]; // todo
        var headers = options[8] || {};
        var uploadId = options[9];

        if (filePath === null || typeof filePath === 'undefined') {
            errorCallback && errorCallback(FileTransferError.FILE_NOT_FOUND_ERR);
            return;
        }

        if (String(filePath).substr(0, 8) == "file:///") {
            filePath = Windows.Storage.ApplicationData.current.localFolder.path + String(filePath).substr(8).split("/").join("\\");
        } else if (String(filePath).indexOf('ms-appdata:///') === 0) {
            // Handle 'ms-appdata' scheme
            filePath = filePath.toString()
                .replace('ms-appdata:///local', Windows.Storage.ApplicationData.current.localFolder.path)
                .replace('ms-appdata:///temp', Windows.Storage.ApplicationData.current.temporaryFolder.path);
        }
        // normalize path separators
        filePath = cordovaPathToNative(filePath);

        // Create internal download operation object
        fileTransferOps[uploadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);

        Windows.Storage.StorageFile.getFileFromPathAsync(filePath).then(function (storageFile) {

            if(!fileName) {
                fileName = storageFile.name;
            }
            if(!mimeType) {
                // use the actual content type of the file, probably this should be the default way.
                // other platforms probably can't look this up.
                mimeType = storageFile.contentType;
            }

            storageFile.openAsync(Windows.Storage.FileAccessMode.read).then(function (stream) {

                // check if upload isn't already cancelled
                var uploadOp = fileTransferOps[uploadId];
                if (uploadOp && uploadOp.state == FileTransferOperation.CANCELLED) {
                    // Here we should call errorCB with ABORT_ERR error
                    errorCallback && errorCallback(new FileTransferError(FileTransferError.ABORT_ERR, filePath, server));
                    return;
                }

                var blob = MSApp.createBlobFromRandomAccessStream(mimeType, stream);

                var formData = new FormData();
                formData.append(fileKey, blob, fileName);
                // add params
                for(var key in params) {
                    formData.append(key,params[key]);
                }

                var uploadOperation;
                try {
                    // Create XHR promise for uploading data to server
                    uploadOperation = WinJS.xhr({ type: "POST", url: server, data: formData, headers: headers });
                    fileTransferOps[uploadId].promise = uploadOperation;
                } catch (e) {
                    // it will fail if URL is malformed, so we handle this situation
                    errorCallback && errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR, filePath, server, null, null, e));
                    return;
                }

                uploadOperation.then(function (response) {
                    storageFile.getBasicPropertiesAsync().done(function(basicProperties) {
                        var ftResult = new FileUploadResult(basicProperties.size, response.status, response.responseText);
                        successCallback && successCallback(ftResult);
                    });
                }, function(err) {
                    if ('status' in err) {
                        errorCallback && errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR, filePath, server, err.status, err.responseText, err));
                    } else {
                        errorCallback && errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR, filePath, server, null, null, err));
                    }
                }, function(evt) {
                    // progress event handler, calls successCallback with empty ProgressEvent
                    // We can't specify ProgressEvent data here since evt not provides any helpful information
                    var progressEvent = new ProgressEvent('progress');
                    successCallback && successCallback(progressEvent, { keepCallback: true });
                });
            });
        }, function(err) {
            errorCallback && errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, server, null, null, err));
        });
    },

    download:function(successCallback, errorCallback, options) {
        var source = options[0];
        var target = cordovaPathToNative(options[1]);
        var downloadId = options[3];
        var headers = options[4] || {};

        if (target === null || typeof target === undefined) {
            errorCallback && errorCallback(FileTransferError.FILE_NOT_FOUND_ERR);
            return;
        }
        if (String(target).substr(0, 8) == "file:///") {
            target = Windows.Storage.ApplicationData.current.localFolder.path + String(target).substr(8).split("/").join("\\");
        } else if (String(target).indexOf('ms-appdata:///') === 0) {
            // Handle 'ms-appdata' scheme
            target = target.toString()
                .replace('ms-appdata:///local', Windows.Storage.ApplicationData.current.localFolder.path)
                .replace('ms-appdata:///temp', Windows.Storage.ApplicationData.current.temporaryFolder.path);
        }
        target = cordovaPathToNative(target);

        var path = target.substr(0, String(target).lastIndexOf("\\"));
        var fileName = target.substr(String(target).lastIndexOf("\\") + 1);
        if (path === null || fileName === null) {
            errorCallback && errorCallback(FileTransferError.FILE_NOT_FOUND_ERR);
            return;
        }

        var download = null;

        // Create internal download operation object
        fileTransferOps[downloadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);

        var downloadCallback = function(storageFolder) {
            storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.generateUniqueName).then(function(storageFile) {

                // check if download isn't already cancelled
                var downloadOp = fileTransferOps[downloadId];
                if (downloadOp && downloadOp.state == FileTransferOperation.CANCELLED) {
                    // Here we should call errorCB with ABORT_ERR error
                    errorCallback && errorCallback(new FileTransferError(FileTransferError.ABORT_ERR, source, target));
                    return;
                }

                // if download isn't cancelled, contunue with creating and preparing download operation
                var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
                for (var header in headers) {
                    downloader.setRequestHeader(header, headers[header]);
                }

                // create download object. This will throw an exception if URL is malformed
                try {
                    var uri = Windows.Foundation.Uri(source);
                    download = downloader.createDownload(uri, storageFile);
                } catch (e) {
                    // so we handle this and call errorCallback
                    errorCallback && errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
                    return;
                }

                var downloadOperation = download.startAsync();
                // update internal TransferOperation object with newly created promise
                fileTransferOps[downloadId].promise = downloadOperation;

                downloadOperation.then(function () {

                    // Update TransferOperation object with new state, delete promise property
                    // since it is not actual anymore
                    var currentDownloadOp = fileTransferOps[downloadId];
                    if (currentDownloadOp) {
                        currentDownloadOp.state = FileTransferOperation.DONE;
                        currentDownloadOp.promise = null;
                    }

                    var nativeURI = storageFile.path.replace(Windows.Storage.ApplicationData.current.localFolder.path, 'ms-appdata:///local')
                        .replace(Windows.Storage.ApplicationData.current.temporaryFolder.path, 'ms-appdata:///temp')
                        .replace('\\', '/');

                    successCallback && successCallback(new FileEntry(storageFile.name, storageFile.path, null, nativeURI));
                }, function(error) {

                    var result;
                    // Handle download error here. If download was cancelled,
                    // message property will be specified
                    if (error.message == 'Canceled') {
                        result = new FileTransferError(FileTransferError.ABORT_ERR, source, target, null, null, error);
                    } else {
                        // in the other way, try to get response property
                        var response = download.getResponseInformation();
                        if (!response) {
                            result = new FileTransferError(FileTransferError.CONNECTION_ERR, source, target);
                        } else if (response.statusCode == 401 || response.statusCode == 404) {
                            result = new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, response.statusCode, null, error);
                        }
                    }

                    // Update TransferOperation object with new state, delete promise property
                    // since it is not actual anymore
                    var currentDownloadOp = fileTransferOps[downloadId];
                    if (currentDownloadOp) {
                        currentDownloadOp.state = FileTransferOperation.CANCELLED;
                        currentDownloadOp.promise = null;
                    }

                    // Cleanup, remove incompleted file
                    storageFile.deleteAsync().then(function () {
                        errorCallback && errorCallback(result);
                    });

                }, function(evt) {

                    var progressEvent = new ProgressEvent('progress', {
                        loaded: evt.progress.bytesReceived,
                        total: evt.progress.totalBytesToReceive,
                        target: evt.resultFile
                    });
                    progressEvent.lengthComputable = true;

                    successCallback && successCallback(progressEvent, { keepCallback: true });
                });
            }, function(error) {
                errorCallback && errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, null, null, error));
            });
        };

        var fileNotFoundErrorCallback = function(error) {
            errorCallback && errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, null, null, error));
        };

        Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(downloadCallback, function (error) {
            // Handle non-existent directory
            if (error.number === -2147024894) {
                var parent = path.substr(0, path.lastIndexOf('\\')),
                    folderNameToCreate = path.substr(path.lastIndexOf('\\') + 1);

                Windows.Storage.StorageFolder.getFolderFromPathAsync(parent).then(function(parentFolder) {
                    parentFolder.createFolderAsync(folderNameToCreate).then(downloadCallback, fileNotFoundErrorCallback);
                }, fileNotFoundErrorCallback);
            } else {
                fileNotFoundErrorCallback();
            }
        });
    },

    abort: function (successCallback, error, options) {
        var fileTransferOpId = options[0];

        // Try to find transferOperation with id specified, and cancel its' promise
        var currentOp = fileTransferOps[fileTransferOpId];
        if (currentOp) {
            currentOp.state = FileTransferOperation.CANCELLED;
            currentOp.promise && currentOp.promise.cancel();
        }
    }

};

require("cordova/exec/proxy").add("FileTransfer",module.exports);
<commit_msg>CB-8093 Fixes incorrect FileTransferError returned in case of download failure<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.
 *
*/

/*jshint -W030 */

var FileTransferError = require('./FileTransferError'),
    ProgressEvent = require('org.apache.cordova.file.ProgressEvent'),
    FileUploadResult = require('org.apache.cordova.file.FileUploadResult'),
    FileEntry = require('org.apache.cordova.file.FileEntry');

// Some private helper functions, hidden by the module
function cordovaPathToNative(path) {
    // turn / into \\
    var cleanPath = path.replace(/\//g, '\\');
    // turn  \\ into \
    cleanPath = cleanPath.replace(/\\\\/g, '\\');
    // strip end \\ characters
    cleanPath = cleanPath.replace(/\\+$/g, '');
    return cleanPath;
}

function nativePathToCordova(path) {
    var cleanPath = path.replace(/\\/g, '/');
    return cleanPath;
}

var fileTransferOps = [];

function FileTransferOperation(state, promise) {
    this.state = state;
    this.promise = promise;
}

FileTransferOperation.PENDING = 0;
FileTransferOperation.DONE = 1;
FileTransferOperation.CANCELLED = 2;

module.exports = {

/*
exec(win, fail, 'FileTransfer', 'upload',
[filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
*/
    upload:function(successCallback, errorCallback, options) {
        var filePath = options[0];
        var server = options[1];
        var fileKey = options[2] || 'source';
        var fileName = options[3];
        var mimeType = options[4];
        var params = options[5];
        var trustAllHosts = options[6]; // todo
        var chunkedMode = options[7]; // todo
        var headers = options[8] || {};
        var uploadId = options[9];

        if (filePath === null || typeof filePath === 'undefined') {
            errorCallback && errorCallback(FileTransferError.FILE_NOT_FOUND_ERR);
            return;
        }

        if (String(filePath).substr(0, 8) == "file:///") {
            filePath = Windows.Storage.ApplicationData.current.localFolder.path + String(filePath).substr(8).split("/").join("\\");
        } else if (String(filePath).indexOf('ms-appdata:///') === 0) {
            // Handle 'ms-appdata' scheme
            filePath = filePath.toString()
                .replace('ms-appdata:///local', Windows.Storage.ApplicationData.current.localFolder.path)
                .replace('ms-appdata:///temp', Windows.Storage.ApplicationData.current.temporaryFolder.path);
        }
        // normalize path separators
        filePath = cordovaPathToNative(filePath);

        // Create internal download operation object
        fileTransferOps[uploadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);

        Windows.Storage.StorageFile.getFileFromPathAsync(filePath).then(function (storageFile) {

            if(!fileName) {
                fileName = storageFile.name;
            }
            if(!mimeType) {
                // use the actual content type of the file, probably this should be the default way.
                // other platforms probably can't look this up.
                mimeType = storageFile.contentType;
            }

            storageFile.openAsync(Windows.Storage.FileAccessMode.read).then(function (stream) {

                // check if upload isn't already cancelled
                var uploadOp = fileTransferOps[uploadId];
                if (uploadOp && uploadOp.state == FileTransferOperation.CANCELLED) {
                    // Here we should call errorCB with ABORT_ERR error
                    errorCallback && errorCallback(new FileTransferError(FileTransferError.ABORT_ERR, filePath, server));
                    return;
                }

                var blob = MSApp.createBlobFromRandomAccessStream(mimeType, stream);

                var formData = new FormData();
                formData.append(fileKey, blob, fileName);
                // add params
                for(var key in params) {
                    formData.append(key,params[key]);
                }

                var uploadOperation;
                try {
                    // Create XHR promise for uploading data to server
                    uploadOperation = WinJS.xhr({ type: "POST", url: server, data: formData, headers: headers });
                    fileTransferOps[uploadId].promise = uploadOperation;
                } catch (e) {
                    // it will fail if URL is malformed, so we handle this situation
                    errorCallback && errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR, filePath, server, null, null, e));
                    return;
                }

                uploadOperation.then(function (response) {
                    storageFile.getBasicPropertiesAsync().done(function(basicProperties) {
                        var ftResult = new FileUploadResult(basicProperties.size, response.status, response.responseText);
                        successCallback && successCallback(ftResult);
                    });
                }, function(err) {
                    if ('status' in err) {
                        errorCallback && errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR, filePath, server, err.status, err.responseText, err));
                    } else {
                        errorCallback && errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR, filePath, server, null, null, err));
                    }
                }, function(evt) {
                    // progress event handler, calls successCallback with empty ProgressEvent
                    // We can't specify ProgressEvent data here since evt not provides any helpful information
                    var progressEvent = new ProgressEvent('progress');
                    successCallback && successCallback(progressEvent, { keepCallback: true });
                });
            });
        }, function(err) {
            errorCallback && errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, server, null, null, err));
        });
    },

    download:function(successCallback, errorCallback, options) {
        var source = options[0];
        var target = cordovaPathToNative(options[1]);
        var downloadId = options[3];
        var headers = options[4] || {};

        if (target === null || typeof target === undefined) {
            errorCallback && errorCallback(FileTransferError.FILE_NOT_FOUND_ERR);
            return;
        }
        if (String(target).substr(0, 8) == "file:///") {
            target = Windows.Storage.ApplicationData.current.localFolder.path + String(target).substr(8).split("/").join("\\");
        } else if (String(target).indexOf('ms-appdata:///') === 0) {
            // Handle 'ms-appdata' scheme
            target = target.toString()
                .replace('ms-appdata:///local', Windows.Storage.ApplicationData.current.localFolder.path)
                .replace('ms-appdata:///temp', Windows.Storage.ApplicationData.current.temporaryFolder.path);
        }
        target = cordovaPathToNative(target);

        var path = target.substr(0, String(target).lastIndexOf("\\"));
        var fileName = target.substr(String(target).lastIndexOf("\\") + 1);
        if (path === null || fileName === null) {
            errorCallback && errorCallback(FileTransferError.FILE_NOT_FOUND_ERR);
            return;
        }

        var download = null;

        // Create internal download operation object
        fileTransferOps[downloadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);

        var downloadCallback = function(storageFolder) {
            storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.generateUniqueName).then(function(storageFile) {

                // check if download isn't already cancelled
                var downloadOp = fileTransferOps[downloadId];
                if (downloadOp && downloadOp.state == FileTransferOperation.CANCELLED) {
                    // Here we should call errorCB with ABORT_ERR error
                    errorCallback && errorCallback(new FileTransferError(FileTransferError.ABORT_ERR, source, target));
                    return;
                }

                // if download isn't cancelled, contunue with creating and preparing download operation
                var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
                for (var header in headers) {
                    downloader.setRequestHeader(header, headers[header]);
                }

                // create download object. This will throw an exception if URL is malformed
                try {
                    var uri = Windows.Foundation.Uri(source);
                    download = downloader.createDownload(uri, storageFile);
                } catch (e) {
                    // so we handle this and call errorCallback
                    errorCallback && errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
                    return;
                }

                var downloadOperation = download.startAsync();
                // update internal TransferOperation object with newly created promise
                fileTransferOps[downloadId].promise = downloadOperation;

                downloadOperation.then(function () {

                    // Update TransferOperation object with new state, delete promise property
                    // since it is not actual anymore
                    var currentDownloadOp = fileTransferOps[downloadId];
                    if (currentDownloadOp) {
                        currentDownloadOp.state = FileTransferOperation.DONE;
                        currentDownloadOp.promise = null;
                    }

                    var nativeURI = storageFile.path.replace(Windows.Storage.ApplicationData.current.localFolder.path, 'ms-appdata:///local')
                        .replace(Windows.Storage.ApplicationData.current.temporaryFolder.path, 'ms-appdata:///temp')
                        .replace('\\', '/');

                    successCallback && successCallback(new FileEntry(storageFile.name, storageFile.path, null, nativeURI));
                }, function(error) {

                    var getTransferError = new WinJS.Promise(function (resolve) {
                        // Handle download error here. If download was cancelled,
                        // message property will be specified
                        if (error.message === 'Canceled') {
                            resolve(new FileTransferError(FileTransferError.ABORT_ERR, source, target, null, null, error));
                        } else {
                            // in the other way, try to get response property
                            var response = download.getResponseInformation();
                            if (!response) {
                                resolve(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target));
                            } else {
                                var reader = new Windows.Storage.Streams.DataReader(download.getResultStreamAt(0));
                                reader.loadAsync(download.progress.bytesReceived).then(function (bytesLoaded) {
                                    var payload = reader.readString(bytesLoaded);
                                    resolve(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, response.statusCode, payload, error));
                                });
                            }
                        }
                    });
                    getTransferError.then(function (fileTransferError) {

                        // Update TransferOperation object with new state, delete promise property
                        // since it is not actual anymore
                        var currentDownloadOp = fileTransferOps[downloadId];
                        if (currentDownloadOp) {
                            currentDownloadOp.state = FileTransferOperation.CANCELLED;
                            currentDownloadOp.promise = null;
                        }

                        // Cleanup, remove incompleted file
                        storageFile.deleteAsync().then(function() {
                            errorCallback && errorCallback(fileTransferError);
                        });
                    });

                }, function(evt) {

                    var progressEvent = new ProgressEvent('progress', {
                        loaded: evt.progress.bytesReceived,
                        total: evt.progress.totalBytesToReceive,
                        target: evt.resultFile
                    });
                    progressEvent.lengthComputable = true;

                    successCallback && successCallback(progressEvent, { keepCallback: true });
                });
            }, function(error) {
                errorCallback && errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, null, null, error));
            });
        };

        var fileNotFoundErrorCallback = function(error) {
            errorCallback && errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, null, null, error));
        };

        Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(downloadCallback, function (error) {
            // Handle non-existent directory
            if (error.number === -2147024894) {
                var parent = path.substr(0, path.lastIndexOf('\\')),
                    folderNameToCreate = path.substr(path.lastIndexOf('\\') + 1);

                Windows.Storage.StorageFolder.getFolderFromPathAsync(parent).then(function(parentFolder) {
                    parentFolder.createFolderAsync(folderNameToCreate).then(downloadCallback, fileNotFoundErrorCallback);
                }, fileNotFoundErrorCallback);
            } else {
                fileNotFoundErrorCallback();
            }
        });
    },

    abort: function (successCallback, error, options) {
        var fileTransferOpId = options[0];

        // Try to find transferOperation with id specified, and cancel its' promise
        var currentOp = fileTransferOps[fileTransferOpId];
        if (currentOp) {
            currentOp.state = FileTransferOperation.CANCELLED;
            currentOp.promise && currentOp.promise.cancel();
        }
    }

};

require("cordova/exec/proxy").add("FileTransfer",module.exports);
<|endoftext|>


<commit_before>// Resizable textareas based on http://www.impressivewebs.com/textarea-auto-resize/
/*global document:false, $:false */
$(function() {
  var txt = $('textarea');
  var content = null;

  resetResizeTextarea = function () {
    if (!$("body").hasClass("text-resized")) {
      $('textarea').each(function() {
        // default/initial heights for all textareas so
        // that resizing doesn't get shorter than this
        var textarea = $(this);
        textarea.css('height', "auto");
        textarea.css('min-height', "");
        textarea.removeAttr('min-height');
        textarea.css('min-height', textarea.attr("rows")+"em");
        textarea.attr("data-height", parseInt(textarea.css('min-height')));
      });
      $("body").addClass("text-resized");
    }
  }

  resizeTextarea = function (textInput) {
    var hiddenDiv = $('body > .hiddendiv');
    content = textInput.val();

    content = content.replace(/\n/g, '
');
    hiddenDiv.width($(".step-article.step-current").width());
    hiddenDiv.html(content + '
');
    var hiddenHeight = hiddenDiv.height()*1.06;

    if (hiddenHeight >= textInput.attr("data-height")) {
      // resize when there's more text than the text container
      textInput.height(hiddenHeight+1);
    } else if (content == "") {
      // resize when no text
      textInput.height(textInput.attr("data-height"));
    }
  }

  resetResizeTextarea()
  $('body').append("

");

  txt.each(function() {
    resizeTextarea($(this));
  });

  txt.on('keyup', function (e) {
    if (e.keyCode != 9) {
      resizeTextarea($(this));
    }
  });

  txt.on('mouseup', function () {
    // resize the text container with the textarea resize handle
    var textarea = $(this);
    textarea.css("height", textarea.height());
    textarea.attr("data-height", textarea.height())
  });
});
<commit_msg>Fix XSS vulnerability on the text resizer<commit_after>// Resizable textareas based on http://www.impressivewebs.com/textarea-auto-resize/
/*global document:false, $:false */
$(function() {
  var txt = $('textarea');
  var content = null;

  resetResizeTextarea = function () {
    if (!$("body").hasClass("text-resized")) {
      $('textarea').each(function() {
        // default/initial heights for all textareas so
        // that resizing doesn't get shorter than this
        var textarea = $(this);
        textarea.css('height', "auto");
        textarea.css('min-height', "");
        textarea.removeAttr('min-height');
        textarea.css('min-height', textarea.attr("rows")+"em");
        textarea.attr("data-height", parseInt(textarea.css('min-height')));
      });
      $("body").addClass("text-resized");
    }
  }

  resizeTextarea = function (textInput) {
    var hiddenDiv = $('body > .hiddendiv');
    content = textInput.val();

    hiddenDiv.width($(".step-article.step-current").width());

    // content = content.replace(/\n/g, "
");
    var content_split = content.split("\n");
    var tagsToReplace = {
      '&': '&',
      '<': '<',
      '>': '>'
    };
    for (n=0; n<content_split.length; n++) {
      content_split[n] = content_split[n].replace(/[&<>]/g, function(tag) {
        return tagsToReplace[tag] || tag;
      })
    }
    var content_join = content_split.join("
");
    hiddenDiv.html(content_join + "
");
    var hiddenHeight = hiddenDiv.height()*1.06;

    if (hiddenHeight >= textInput.attr("data-height")) {
      // resize when there's more text than the text container
      textInput.height(hiddenHeight+1);
    } else if (content == "") {
      // resize when no text
      textInput.height(textInput.attr("data-height"));
    }
  }

  resetResizeTextarea()
  $('body').append("

");

  txt.each(function() {
    resizeTextarea($(this));
  });

  txt.on('keyup', function (e) {
    if (e.keyCode != 9) {
      resizeTextarea($(this));
    }
  });

  txt.on('mouseup', function () {
    // resize the text container with the textarea resize handle
    var textarea = $(this);
    textarea.css("height", textarea.height());
    textarea.attr("data-height", textarea.height())
  });
});
<|endoftext|>


<commit_before>"use strict";

define(['logManager',
    'js/Constants',
    'js/Utils/GMEConcepts',
    'js/NodePropertyNames'], function (logManager,
                             CONSTANTS,
                             GMEConcepts,
                             nodePropertyNames) {

    var PartBrowserControl,
        WIDGET_NAME = 'PartBrowser',
        DEFAULT_DECORATOR = "ModelDecorator";

    PartBrowserControl = function (myClient, myPartBrowserView) {
        this._client = myClient;
        this._partBrowserView = myPartBrowserView;

        //the ID of the node whose valid children types should be displayed
        this._containerNodeId = null;

        //the ID of the valid children types of the container node
        this._validChildrenTypeIDs = [];

        //decorators can use it to ask for notifications about their registered sub IDs
        this._componentIDPartIDMap = {};

        this._initDragDropFeatures();

        this._logger = logManager.create("PartBrowserControl");
        this._logger.debug("Created");
    };

    PartBrowserControl.prototype.selectedObjectChanged = function (nodeId) {
        this._logger.debug("SELECTEDOBJECT_CHANGED nodeId '" + nodeId + "'");

        //remove current territory patterns
        if (this._containerNodeId) {
            this._client.removeUI(this._territoryId);
            this._partBrowserView.clear();
        }

        this._containerNodeId = nodeId;
        this._validChildrenTypeIDs = [];

        if (this._containerNodeId) {
            //put new node's info into territory rules
            this._selfPatterns = {};
            this._selfPatterns[nodeId] = { "children": 1 };

            this._territoryId = this._client.addUI(this, true);
            //update the territory
            this._logger.debug('UPDATING TERRITORY: selectedObjectChanged' + JSON.stringify(this._selfPatterns));
            this._client.updateTerritory(this._territoryId, this._selfPatterns);
        }
    };

    PartBrowserControl.prototype._getObjectDescriptor = function (nodeId) {
        var nodeObj = this._client.getNode(nodeId),
            objDescriptor;

        if (nodeObj) {
            objDescriptor = {};

            objDescriptor.id = nodeObj.getId();
            objDescriptor.decorator = nodeObj.getRegistry(nodePropertyNames.Registry.decorator) || DEFAULT_DECORATOR;
            objDescriptor.name = nodeObj.getAttribute(nodePropertyNames.Attributes.name);
        }

        return objDescriptor;
    };

    PartBrowserControl.prototype.onOneEvent = function (events) {
        var i = events ? events.length : 0,
            e;

        this._logger.debug("onOneEvent '" + i + "' items, events: " + JSON.stringify(events));

        while (i--) {
            e = events[i];
            switch (e.etype) {
                case CONSTANTS.TERRITORY_EVENT_LOAD:
                    this._onLoad(e.eid);
                    break;
                case CONSTANTS.TERRITORY_EVENT_UPDATE:
                    this._onUpdate(e.eid);
                    break;
                case CONSTANTS.TERRITORY_EVENT_UNLOAD:
                    this._onUnload(e.eid);
                    break;
            }
        }

        this._updateValidChildrenTypeDecorators();

        this._logger.debug("onOneEvent '" + events.length + "' items - DONE");
    };

    // PUBLIC METHODS
    PartBrowserControl.prototype._onLoad = function (gmeID) {
        if (this._containerNodeId === gmeID) {
            this._processContainerNode(gmeID);
        }
    };

    PartBrowserControl.prototype._onUpdate = function (gmeID) {
        if (this._containerNodeId === gmeID) {
            this._processContainerNode(gmeID)
        }
    };

    PartBrowserControl.prototype._onUnload = function (gmeID) {
        if (this._containerNodeId === gmeID) {
            this._logger.warning('Container node got unloaded...');
            this._client.removeUI(this._territoryId);
            this._partBrowserView.clear();
        }
    };

    PartBrowserControl.prototype._processContainerNode = function (gmeID) {
        var node = this._client.getNode(gmeID),
            validChildrenTypes = [],
            oValidChildrenTypes = this._validChildrenTypeIDs.slice(0),
            len,
            diff,
            id,
            territoryChanged = false;

        if (node) {
            //get possible targets from MetaDescriptor
            validChildrenTypes = this._client.getValidChildrenTypes(gmeID);

            //the deleted ones
            diff = _.difference(oValidChildrenTypes, validChildrenTypes);
            len = diff.length;
            while (len--) {
                id = diff[len];
                this._removePart(id);

                //remove it from the territory
                //only if not itself, then we need to keep it in the territory
                if (id !== gmeID) {
                    delete this._selfPatterns[id];
                    territoryChanged = true;
                }
            }

            //check the added ones
            diff = _.difference(validChildrenTypes, oValidChildrenTypes);
            len = diff.length;
            while (len--) {
                id = diff[len];
                if (this._validChildrenTypeIDs.indexOf(id) === -1) {
                    this._validChildrenTypeIDs.push(id);

                    //add to the territory
                    //only if not self, because it's already in the territory
                    if (id !== gmeID) {
                        this._selfPatterns[id] = { "children": 0 };
                        territoryChanged = true;
                    }
                }
            }

            //update the territory
            if (territoryChanged) {
                this._doUpdateTerritory(true);
            }
        }
    };

    PartBrowserControl.prototype._doUpdateTerritory = function (async) {
        var territoryId = this._territoryId,
            patterns = this._selfPatterns,
            client = this._client,
            logger = this._logger;

        if (async === true) {
            setTimeout(function () {
                logger.debug('Updating territory with rules: ' + JSON.stringify(patterns));
                client.updateTerritory(territoryId, patterns);
            }, 10);
        } else {
            logger.debug('Updating territory with rules: ' + JSON.stringify(patterns));
            client.updateTerritory(territoryId, patterns);
        }
    };

    PartBrowserControl.prototype._getItemDecorator = function (decorator) {
        var result;

        result = this._client.decoratorManager.getDecoratorForWidget(decorator, WIDGET_NAME);
        if (!result) {
            result = this._client.decoratorManager.getDecoratorForWidget(DEFAULT_DECORATOR, WIDGET_NAME);
        }

        return result;
    };

    PartBrowserControl.prototype._getPartDescriptor = function (id) {
        var desc = this._getObjectDescriptor(id);

        desc.decoratorClass = this._getItemDecorator(desc.decorator);
        desc.control = this;
        desc.metaInfo = {};
        desc.metaInfo[CONSTANTS.GME_ID] = id;

        return desc;
    };

    PartBrowserControl.prototype.registerComponentIDForPartID = function (componentID, partId) {
        this._componentIDPartIDMap[componentID] = this._componentIDPartIDMap[componentID] || [];
        if (this._componentIDPartIDMap[componentID].indexOf(partId) === -1) {
            this._componentIDPartIDMap[componentID].push(partId);
        }
    };

    PartBrowserControl.prototype.unregisterComponentIDFromPartID = function (componentID, partId) {
        var idx;

        if (this._componentIDPartIDMap && this._componentIDPartIDMap[componentID]) {
           idx = this._componentIDPartIDMap[componentID].indexOf(partId);
            if (idx !== -1) {
                this._componentIDPartIDMap[componentID].splice(idx, 1);
            }
        }
    };

    PartBrowserControl.prototype._initDragDropFeatures = function () {
        var dragEffects = this._partBrowserView.DRAG_EFFECTS;

        this._partBrowserView.getDragEffects = function (/*el*/) {
            return [dragEffects.DRAG_CREATE_INSTANCE];
        };

        this._partBrowserView.getDragItems = function (el) {
            return [el.attr('id')];
        };
    };

    PartBrowserControl.prototype._removePart = function (id) {
        var idx;

        //remove from the UI
        this._partBrowserView.removePart(id);

        //fix accounting
        idx = this._validChildrenTypeIDs.indexOf(id);
        this._validChildrenTypeIDs.splice(idx, 1);
    };

    PartBrowserControl.prototype._updateValidChildrenTypeDecorators = function () {
        var len = this._validChildrenTypeIDs.length,
            decorators = [],
            self = this;

        while (len--) {
            decorators.push(this._getObjectDescriptor(this._validChildrenTypeIDs[len]).decorator);
        }

        if (decorators.length > 0) {
            this._client.decoratorManager.download(decorators, WIDGET_NAME, function () {
                self._refreshPartList();
            });
        }
    };

    PartBrowserControl.prototype._refreshPartList = function () {
        var childrenTypeToDisplay = [],
            i,
            id,
            names = [],
            mapNameID = {},
            objDesc,
            childrenWithName,
            decoratorInstance,
            j,
            getDecoratorTerritoryQueries,
            territoryChanged = false,
            _selfPatterns = this._selfPatterns;

        getDecoratorTerritoryQueries = function (decorator) {
            var query,
                entry;

            if (decorator) {
                query = decorator.getTerritoryQuery();

                if (query) {
                    for (entry in query) {
                        if (query.hasOwnProperty(entry)) {
                            _selfPatterns[entry] = query[entry];
                            territoryChanged = true;
                        }
                    }
                }
            }
        };

        this._logger.debug('_refreshPartList this._validChildrenTypeIDs: ' + this._validChildrenTypeIDs);

        //clear view
        this._partBrowserView.clear();

        //filter out the types that doesn't need to be displayed for whatever reason:
        // - don't display validConnectionTypes
        i = this._validChildrenTypeIDs.length;
        while (i--) {
            id = this._validChildrenTypeIDs[i];
            if (GMEConcepts.isConnectionType(id) === false) {
                childrenTypeToDisplay.push(id);

                objDesc = this._getObjectDescriptor(id);
                if (names.indexOf(objDesc.name) === -1) {
                    names.push(objDesc.name);
                    mapNameID[objDesc.name] = [id];
                } else {
                    mapNameID[objDesc.name].push(id);
                }
            }
        }

        this._logger.debug('_refreshPartList childrenTypeToDisplay: ' + childrenTypeToDisplay);

        //sort the parts by name
        names.sort();
        names.reverse();

        //display the parts in the order of their names
        i = names.length;
        while (i--) {
            childrenWithName = mapNameID[names[i]];
            childrenWithName.sort();
            childrenWithName.reverse();
            this._logger.debug(names[i] + ':  ' + childrenWithName);

            j = childrenWithName.length;
            while (j--) {
                id = childrenWithName[j];
                decoratorInstance = this._partBrowserView.addPart(id, this._getPartDescriptor(id));
                getDecoratorTerritoryQueries(decoratorInstance);
            }
        }

        //update child creation possibility
        i = this._validChildrenTypeIDs.length;
        while (i--) {
            id = this._validChildrenTypeIDs[i];
            this._partBrowserView.setEnabled(id, GMEConcepts.canCreateChild(this._containerNodeId, id));
        }

        if (territoryChanged) {
            this._doUpdateTerritory(true);
        }
    };

    return PartBrowserControl;
});<commit_msg>disable parts if the opened container is PROJECT_BASE<commit_after>"use strict";

define(['logManager',
    'js/Constants',
    'js/Utils/GMEConcepts',
    'js/NodePropertyNames'], function (logManager,
                             CONSTANTS,
                             GMEConcepts,
                             nodePropertyNames) {

    var PartBrowserControl,
        WIDGET_NAME = 'PartBrowser',
        DEFAULT_DECORATOR = "ModelDecorator";

    PartBrowserControl = function (myClient, myPartBrowserView) {
        this._client = myClient;
        this._partBrowserView = myPartBrowserView;

        //the ID of the node whose valid children types should be displayed
        this._containerNodeId = null;

        //the ID of the valid children types of the container node
        this._validChildrenTypeIDs = [];

        //decorators can use it to ask for notifications about their registered sub IDs
        this._componentIDPartIDMap = {};

        this._initDragDropFeatures();

        this._logger = logManager.create("PartBrowserControl");
        this._logger.debug("Created");
    };

    PartBrowserControl.prototype.selectedObjectChanged = function (nodeId) {
        this._logger.debug("SELECTEDOBJECT_CHANGED nodeId '" + nodeId + "'");

        //remove current territory patterns
        if (this._containerNodeId) {
            this._client.removeUI(this._territoryId);
            this._partBrowserView.clear();
        }

        this._containerNodeId = nodeId;
        this._validChildrenTypeIDs = [];

        if (this._containerNodeId) {
            //put new node's info into territory rules
            this._selfPatterns = {};
            this._selfPatterns[nodeId] = { "children": 1 };

            this._territoryId = this._client.addUI(this, true);
            //update the territory
            this._logger.debug('UPDATING TERRITORY: selectedObjectChanged' + JSON.stringify(this._selfPatterns));
            this._client.updateTerritory(this._territoryId, this._selfPatterns);
        }
    };

    PartBrowserControl.prototype._getObjectDescriptor = function (nodeId) {
        var nodeObj = this._client.getNode(nodeId),
            objDescriptor;

        if (nodeObj) {
            objDescriptor = {};

            objDescriptor.id = nodeObj.getId();
            objDescriptor.decorator = nodeObj.getRegistry(nodePropertyNames.Registry.decorator) || DEFAULT_DECORATOR;
            objDescriptor.name = nodeObj.getAttribute(nodePropertyNames.Attributes.name);
        }

        return objDescriptor;
    };

    PartBrowserControl.prototype.onOneEvent = function (events) {
        var i = events ? events.length : 0,
            e;

        this._logger.debug("onOneEvent '" + i + "' items, events: " + JSON.stringify(events));

        while (i--) {
            e = events[i];
            switch (e.etype) {
                case CONSTANTS.TERRITORY_EVENT_LOAD:
                    this._onLoad(e.eid);
                    break;
                case CONSTANTS.TERRITORY_EVENT_UPDATE:
                    this._onUpdate(e.eid);
                    break;
                case CONSTANTS.TERRITORY_EVENT_UNLOAD:
                    this._onUnload(e.eid);
                    break;
            }
        }

        this._updateValidChildrenTypeDecorators();

        this._logger.debug("onOneEvent '" + events.length + "' items - DONE");
    };

    // PUBLIC METHODS
    PartBrowserControl.prototype._onLoad = function (gmeID) {
        if (this._containerNodeId === gmeID) {
            this._processContainerNode(gmeID);
        }
    };

    PartBrowserControl.prototype._onUpdate = function (gmeID) {
        if (this._containerNodeId === gmeID) {
            this._processContainerNode(gmeID)
        }
    };

    PartBrowserControl.prototype._onUnload = function (gmeID) {
        if (this._containerNodeId === gmeID) {
            this._logger.warning('Container node got unloaded...');
            this._client.removeUI(this._territoryId);
            this._partBrowserView.clear();
        }
    };

    PartBrowserControl.prototype._processContainerNode = function (gmeID) {
        var node = this._client.getNode(gmeID),
            validChildrenTypes = [],
            oValidChildrenTypes = this._validChildrenTypeIDs.slice(0),
            len,
            diff,
            id,
            territoryChanged = false;

        if (node) {
            //get possible targets from MetaDescriptor
            validChildrenTypes = this._client.getValidChildrenTypes(gmeID);

            //the deleted ones
            diff = _.difference(oValidChildrenTypes, validChildrenTypes);
            len = diff.length;
            while (len--) {
                id = diff[len];
                this._removePart(id);

                //remove it from the territory
                //only if not itself, then we need to keep it in the territory
                if (id !== gmeID) {
                    delete this._selfPatterns[id];
                    territoryChanged = true;
                }
            }

            //check the added ones
            diff = _.difference(validChildrenTypes, oValidChildrenTypes);
            len = diff.length;
            while (len--) {
                id = diff[len];
                if (this._validChildrenTypeIDs.indexOf(id) === -1) {
                    this._validChildrenTypeIDs.push(id);

                    //add to the territory
                    //only if not self, because it's already in the territory
                    if (id !== gmeID) {
                        this._selfPatterns[id] = { "children": 0 };
                        territoryChanged = true;
                    }
                }
            }

            //update the territory
            if (territoryChanged) {
                this._doUpdateTerritory(true);
            }
        }
    };

    PartBrowserControl.prototype._doUpdateTerritory = function (async) {
        var territoryId = this._territoryId,
            patterns = this._selfPatterns,
            client = this._client,
            logger = this._logger;

        if (async === true) {
            setTimeout(function () {
                logger.debug('Updating territory with rules: ' + JSON.stringify(patterns));
                client.updateTerritory(territoryId, patterns);
            }, 10);
        } else {
            logger.debug('Updating territory with rules: ' + JSON.stringify(patterns));
            client.updateTerritory(territoryId, patterns);
        }
    };

    PartBrowserControl.prototype._getItemDecorator = function (decorator) {
        var result;

        result = this._client.decoratorManager.getDecoratorForWidget(decorator, WIDGET_NAME);
        if (!result) {
            result = this._client.decoratorManager.getDecoratorForWidget(DEFAULT_DECORATOR, WIDGET_NAME);
        }

        return result;
    };

    PartBrowserControl.prototype._getPartDescriptor = function (id) {
        var desc = this._getObjectDescriptor(id);

        desc.decoratorClass = this._getItemDecorator(desc.decorator);
        desc.control = this;
        desc.metaInfo = {};
        desc.metaInfo[CONSTANTS.GME_ID] = id;

        return desc;
    };

    PartBrowserControl.prototype.registerComponentIDForPartID = function (componentID, partId) {
        this._componentIDPartIDMap[componentID] = this._componentIDPartIDMap[componentID] || [];
        if (this._componentIDPartIDMap[componentID].indexOf(partId) === -1) {
            this._componentIDPartIDMap[componentID].push(partId);
        }
    };

    PartBrowserControl.prototype.unregisterComponentIDFromPartID = function (componentID, partId) {
        var idx;

        if (this._componentIDPartIDMap && this._componentIDPartIDMap[componentID]) {
           idx = this._componentIDPartIDMap[componentID].indexOf(partId);
            if (idx !== -1) {
                this._componentIDPartIDMap[componentID].splice(idx, 1);
            }
        }
    };

    PartBrowserControl.prototype._initDragDropFeatures = function () {
        var dragEffects = this._partBrowserView.DRAG_EFFECTS;

        this._partBrowserView.getDragEffects = function (/*el*/) {
            return [dragEffects.DRAG_CREATE_INSTANCE];
        };

        this._partBrowserView.getDragItems = function (el) {
            return [el.attr('id')];
        };
    };

    PartBrowserControl.prototype._removePart = function (id) {
        var idx;

        //remove from the UI
        this._partBrowserView.removePart(id);

        //fix accounting
        idx = this._validChildrenTypeIDs.indexOf(id);
        this._validChildrenTypeIDs.splice(idx, 1);
    };

    PartBrowserControl.prototype._updateValidChildrenTypeDecorators = function () {
        var len = this._validChildrenTypeIDs.length,
            decorators = [],
            self = this;

        while (len--) {
            decorators.push(this._getObjectDescriptor(this._validChildrenTypeIDs[len]).decorator);
        }

        if (decorators.length > 0) {
            this._client.decoratorManager.download(decorators, WIDGET_NAME, function () {
                self._refreshPartList();
            });
        }
    };

    PartBrowserControl.prototype._refreshPartList = function () {
        var childrenTypeToDisplay = [],
            i,
            id,
            names = [],
            mapNameID = {},
            objDesc,
            childrenWithName,
            decoratorInstance,
            j,
            getDecoratorTerritoryQueries,
            territoryChanged = false,
            _selfPatterns = this._selfPatterns,
            partEnabled;

        getDecoratorTerritoryQueries = function (decorator) {
            var query,
                entry;

            if (decorator) {
                query = decorator.getTerritoryQuery();

                if (query) {
                    for (entry in query) {
                        if (query.hasOwnProperty(entry)) {
                            _selfPatterns[entry] = query[entry];
                            territoryChanged = true;
                        }
                    }
                }
            }
        };

        this._logger.debug('_refreshPartList this._validChildrenTypeIDs: ' + this._validChildrenTypeIDs);

        //clear view
        this._partBrowserView.clear();

        //filter out the types that doesn't need to be displayed for whatever reason:
        // - don't display validConnectionTypes
        i = this._validChildrenTypeIDs.length;
        while (i--) {
            id = this._validChildrenTypeIDs[i];
            if (GMEConcepts.isConnectionType(id) === false) {
                childrenTypeToDisplay.push(id);

                objDesc = this._getObjectDescriptor(id);
                if (names.indexOf(objDesc.name) === -1) {
                    names.push(objDesc.name);
                    mapNameID[objDesc.name] = [id];
                } else {
                    mapNameID[objDesc.name].push(id);
                }
            }
        }

        this._logger.debug('_refreshPartList childrenTypeToDisplay: ' + childrenTypeToDisplay);

        //sort the parts by name
        names.sort();
        names.reverse();

        //display the parts in the order of their names
        i = names.length;
        while (i--) {
            childrenWithName = mapNameID[names[i]];
            childrenWithName.sort();
            childrenWithName.reverse();
            this._logger.debug(names[i] + ':  ' + childrenWithName);

            j = childrenWithName.length;
            while (j--) {
                id = childrenWithName[j];
                decoratorInstance = this._partBrowserView.addPart(id, this._getPartDescriptor(id));
                getDecoratorTerritoryQueries(decoratorInstance);
            }
        }

        //update child creation possibility
        i = this._validChildrenTypeIDs.length;
        while (i--) {
            id = this._validChildrenTypeIDs[i];
            partEnabled = GMEConcepts.canCreateChild(this._containerNodeId, id) &&
                        !GMEConcepts.isProjectPROJECTBASE(this._containerNodeId);
            this._partBrowserView.setEnabled(id, partEnabled);
        }

        if (territoryChanged) {
            this._doUpdateTerritory(true);
        }
    };

    return PartBrowserControl;
});<|endoftext|>


<commit_before>'use strict';

var fs = require('fs'),
    webdriver = require('selenium-webdriver'),
    until = require('selenium-webdriver').until,
    chrome = require('selenium-webdriver/chrome'),
    path = require('chromedriver').path,
    _ = require('lodash'),
    basePageObject = {},
    defaultTimeout = 60000,
    config,
    routes,
    world,
    screenshotPath = 'screenshots';

var co = require('bluebird').coroutine;

var service = new chrome.ServiceBuilder(path).build();
chrome.setDefaultService(service);

var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).
//withCapabilities(webdriver.Capabilities.firefox()).
build();

if (!fs.existsSync(screenshotPath)) {
    fs.mkdirSync(screenshotPath);
}

/************************************* world constructor ******************************/

var World = function World() {
    world = this;
};

/************************ module exports ***************************/

module.exports.World = World;
module.exports.getDriver = () => driver;
module.exports.getCurrentWorld = () => world;
module.exports.setConfig = (myConfig) => config = myConfig;
module.exports.setRoutes = (myRoutes) => routes = myRoutes;
module.exports.setPageConfig = (pageConfig) => basePageObject = _.defaultsDeep(basePageObject, pageConfig);

/***************************** extend until ******************************/

_.extend(until, {
    pageMatches: (page) => {
        var route = getRoute(page);
        if (!route) {
            throw new Error('Route is not defined for "' + page + '" page');
        }
        return new until.Condition('for page to match ' + page, co(function* () {
            var page = yield getPageObject();
            return page.route.path === route.path;
        }));
    },
    configuredInPage: (id) => new until.Condition('for "' + id + '" to be configured in page ', co(function* () {
        var page = yield getPageObject();
        return page.config.hasOwnProperty(_.camelCase(id));
    })),
    foundInPage: (selector) => new until.Condition('for $(' + selector + ') to be found in page ', function () {
        return !!driver.findElement(webdriver.By.css(selector));
    }),
    titleIs: (expectedTitle) => new until.Condition('for ' + expectedTitle + ' to match page title ', co(function* () {
        var title = yield driver.getTitle();
        return title === expectedTitle;
    }))
});

/************************ co functions ***************************/

var whenVisible = co(function* (el) {
    yield driver.wait(until.elementIsEnabled(el), defaultTimeout);
    yield driver.wait(until.elementIsVisible(el), defaultTimeout);
    return Promise.resolve(el);
});

var whenMatches = co(function* (el, text) {
    yield driver.wait(until.elementTextIs(el, text), defaultTimeout);
    return Promise.resolve(el);
});

var whenTitleIs = co(function* (title, timeout) {
    yield driver.wait(until.titleIs(title), timeout || defaultTimeout);
    return Promise.resolve();
});

var whenPageIs = co(function* (page, timeout) {
    yield driver.wait(until.pageMatches(page), timeout || defaultTimeout);
    return Promise.resolve();
});

/* Find the id in the config and use the selector to find the element in the dom */
var find = co(function* (id) {
    yield driver.wait(until.configuredInPage(id), defaultTimeout);
    var selector = world.currentPage.config[_.camelCase(id)];
    yield driver.wait(until.foundInPage(selector), defaultTimeout);
    return driver.findElement(webdriver.By.css(selector));
});

/************************ World prototype **************************/

World.prototype.webdriver = webdriver;
World.prototype.driver = driver;
World.prototype.find = find;

World.prototype.whenPageIs = whenPageIs;
World.prototype.whenTitleIs = whenTitleIs;

World.prototype.click = (id) => find(id)
    .then(el => whenVisible(el))
    .then(el => el.click());

World.prototype.sendKeys = (id, text) => find(id)
    .then(el => whenVisible(el))
    .then(el => el.sendKeys(text));

World.prototype.getText = (id) => find(id)
    .then(el => whenVisible(el))
    .then(el => el.getText());

World.prototype.getVal = (id) => find(id)
    .then(el => whenVisible(el))
    .then(el => el.getAttribute('value'));

World.prototype.whenTextMatches = (id, text) => find(id)
    .then(el => whenVisible(el))
    .then(el => whenMatches(el, text))
    .then(el => Promise.resolve());

World.prototype.setSize = (width, height) => Promise.resolve(driver.manage().window().setSize(width, height));

/************************** stuff *****************************/

function matchedRoute(val) {
    var matched;
    routes.some(function (route) {
        if (!route.path) {
            return matched;
        }
        var parts = route.path.split('/').map(function (part, index) {
            if (part[0] === ':') {
                return val.split('/')[index];
            } else {
                return part;
            }
        });
        if (val === parts.join('/')) {
            matched = route;
        }
        return matched;
    });
    return matched;
}

var getRoute = function (val, prop) {
    prop = prop || 'component';
    val = (prop === 'component') ? _.camelCase(val) : val;
    var route = _(routes).find(function (route) {
        return route[prop] === val;
    });
    if (route) {
        return route;
    } else if (prop === 'path') {
        return matchedRoute(val);
    }
};

World.prototype.visit = function (page, params) {
    var route = getRoute(page);
    var path = config.host + route.path;
    if (params) {
        var p = params ? params.split(',') : [];
        var parts = route.path.split('/').map(function (part) {
            if (part[0] === ':') {
                return _.kebabCase(p.shift());
            } else {
                return part;
            }
        });
        path = config.host + parts.join('/');
    }
    return driver.get(path);

};

var getPageObject = () => new Promise(function (resolve, reject) {
    world.driver.getCurrentUrl().then(function (url) {
        var route = getRoute(url.substr(config.host.length), 'path');
        if (route) {
            var pageObject = buildPageObject.call(world, route.pageObject);
            if (pageObject) {
                pageObject.route = route;
                world.currentPage = pageObject;
                return resolve(pageObject);
            }

        }
        reject(new Error('Failed to build page object for ' + url));
    });
});

function buildPageObject(pageConfig) {
    pageConfig = _.defaultsDeep(basePageObject, pageConfig);
    var pageObject = {
        world: world,
        config: pageConfig
    };
    _.each(pageConfig, function (val, prop) {
        if (_.isFunction(val)) {
            pageObject[prop] = val.bind(pageObject);
        }
    });
    return pageObject;
}
<commit_msg>Expose whenVisible<commit_after>'use strict';

var fs = require('fs'),
    webdriver = require('selenium-webdriver'),
    until = require('selenium-webdriver').until,
    chrome = require('selenium-webdriver/chrome'),
    path = require('chromedriver').path,
    _ = require('lodash'),
    basePageObject = {},
    defaultTimeout = 60000,
    config,
    routes,
    world,
    screenshotPath = 'screenshots';

var co = require('bluebird').coroutine;

var service = new chrome.ServiceBuilder(path).build();
chrome.setDefaultService(service);

var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).
//withCapabilities(webdriver.Capabilities.firefox()).
build();

if (!fs.existsSync(screenshotPath)) {
    fs.mkdirSync(screenshotPath);
}

/************************************* world constructor ******************************/

var World = function World() {
    world = this;
};

/************************ module exports ***************************/

module.exports.World = World;
module.exports.getDriver = () => driver;
module.exports.getCurrentWorld = () => world;
module.exports.setConfig = (myConfig) => config = myConfig;
module.exports.setRoutes = (myRoutes) => routes = myRoutes;
module.exports.setPageConfig = (pageConfig) => basePageObject = _.defaultsDeep(basePageObject, pageConfig);

/***************************** extend until ******************************/

_.extend(until, {
    pageMatches: (page) => {
        var route = getRoute(page);
        if (!route) {
            throw new Error('Route is not defined for "' + page + '" page');
        }
        return new until.Condition('for page to match ' + page, co(function* () {
            var page = yield getPageObject();
            return page.route.path === route.path;
        }));
    },
    configuredInPage: (id) => new until.Condition('for "' + id + '" to be configured in page ', co(function* () {
        var page = yield getPageObject();
        return page.config.hasOwnProperty(_.camelCase(id));
    })),
    foundInPage: (selector) => new until.Condition('for $(' + selector + ') to be found in page ', function () {
        return !!driver.findElement(webdriver.By.css(selector));
    }),
    titleIs: (expectedTitle) => new until.Condition('for ' + expectedTitle + ' to match page title ', co(function* () {
        var title = yield driver.getTitle();
        return title === expectedTitle;
    }))
});

/************************ co functions ***************************/

var whenVisible = co(function* (el) {
    yield driver.wait(until.elementIsEnabled(el), defaultTimeout);
    yield driver.wait(until.elementIsVisible(el), defaultTimeout);
    return Promise.resolve(el);
});

var whenMatches = co(function* (el, text) {
    yield driver.wait(until.elementTextIs(el, text), defaultTimeout);
    return Promise.resolve(el);
});

var whenTitleIs = co(function* (title, timeout) {
    yield driver.wait(until.titleIs(title), timeout || defaultTimeout);
    return Promise.resolve();
});

var whenPageIs = co(function* (page, timeout) {
    yield driver.wait(until.pageMatches(page), timeout || defaultTimeout);
    return Promise.resolve();
});

/* Find the id in the config and use the selector to find the element in the dom */
var find = co(function* (id) {
    yield driver.wait(until.configuredInPage(id), defaultTimeout);
    var selector = world.currentPage.config[_.camelCase(id)];
    yield driver.wait(until.foundInPage(selector), defaultTimeout);
    return driver.findElement(webdriver.By.css(selector));
});

/************************ World prototype **************************/

World.prototype.webdriver = webdriver;
World.prototype.driver = driver;
World.prototype.find = find;

World.prototype.whenPageIs = whenPageIs;
World.prototype.whenTitleIs = whenTitleIs;

World.prototype.click = (id) => find(id)
    .then(el => whenVisible(el))
    .then(el => el.click());

World.prototype.sendKeys = (id, text) => find(id)
    .then(el => whenVisible(el))
    .then(el => el.sendKeys(text));

World.prototype.getText = (id) => find(id)
    .then(el => whenVisible(el))
    .then(el => el.getText());

World.prototype.getVal = (id) => find(id)
    .then(el => whenVisible(el))
    .then(el => el.getAttribute('value'));

World.prototype.whenVisible = (id) => find(id)
    .then(el => whenVisible(el))
    .then(el => Promise.resolve());

World.prototype.whenTextMatches = (id, text) => find(id)
    .then(el => whenVisible(el))
    .then(el => whenMatches(el, text))
    .then(el => Promise.resolve());

World.prototype.setSize = (width, height) => Promise.resolve(driver.manage().window().setSize(width, height));

/************************** stuff *****************************/

function matchedRoute(val) {
    var matched;
    routes.some(function (route) {
        if (!route.path) {
            return matched;
        }
        var parts = route.path.split('/').map(function (part, index) {
            if (part[0] === ':') {
                return val.split('/')[index];
            } else {
                return part;
            }
        });
        if (val === parts.join('/')) {
            matched = route;
        }
        return matched;
    });
    return matched;
}

var getRoute = function (val, prop) {
    prop = prop || 'component';
    val = (prop === 'component') ? _.camelCase(val) : val;
    var route = _(routes).find(function (route) {
        return route[prop] === val;
    });
    if (route) {
        return route;
    } else if (prop === 'path') {
        return matchedRoute(val);
    }
};

World.prototype.visit = function (page, params) {
    var route = getRoute(page);
    var path = config.host + route.path;
    if (params) {
        var p = params ? params.split(',') : [];
        var parts = route.path.split('/').map(function (part) {
            if (part[0] === ':') {
                return _.kebabCase(p.shift());
            } else {
                return part;
            }
        });
        path = config.host + parts.join('/');
    }
    return driver.get(path);

};

var getPageObject = () => new Promise(function (resolve, reject) {
    world.driver.getCurrentUrl().then(function (url) {
        var route = getRoute(url.substr(config.host.length), 'path');
        if (route) {
            var pageObject = buildPageObject.call(world, route.pageObject);
            if (pageObject) {
                pageObject.route = route;
                world.currentPage = pageObject;
                return resolve(pageObject);
            }

        }
        reject(new Error('Failed to build page object for ' + url));
    });
});

function buildPageObject(pageConfig) {
    pageConfig = _.defaultsDeep(basePageObject, pageConfig);
    var pageObject = {
        world: world,
        config: pageConfig
    };
    _.each(pageConfig, function (val, prop) {
        if (_.isFunction(val)) {
            pageObject[prop] = val.bind(pageObject);
        }
    });
    return pageObject;
}
<|endoftext|>


<commit_before>var React = require('react-native');
var Slider = require('react-native-slider');
var Progress = require('react-native-progress');

var {
  View,
  Text,
  PanResponder,
  Dimensions
} = React;

class ThumbRoll extends React.Component {
  constructor(props) {
    super(props)
    var {height, width} = Dimensions.get('window');
    this.width = width;
    this.circleSize = 300;
    this.padding = 40;
    this._panResponder = {};
    this.circleCenter = {};

    this.state = {
      value: 0,
    };
  }

  componentWillMount() {
    this._panResponder = PanResponder.create({
      // Ask to be the responder:
      onStartShouldSetPanResponder: (evt, gestureState) => true,
      onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,

      onPanResponderGrant: (evt, gestureState) => {
        this.refs.circle.measure( (fx, fy, width, height, px, py) => {
          this.circleCenter.y = py + this.circleSize / 2 + this.padding;
          this.circleCenter.x = width / 2;
          console.log(this.circleCenter);
          var xPos = gestureState.x0 - this.circleCenter.x;
          var yPos = this.circleCenter.y - gestureState.y0;
          var theta = Math.atan2(xPos, yPos);
          var percent = theta / (2 * Math.PI);
          if(xPos < 0) {
            percent = 1 + percent;
          }
          if(this.state.fullLoop) {
            percent = 1;
          }
          this.setState({
            value: percent
          });
        });
        this.setState({
          fullLoop: false
        })
      },
      onPanResponderMove: (evt, gestureState) => {
        // The most recent move distance is gestureState.move{X,Y}

        // The accumulated gesture distance since becoming responder is
        // gestureState.d{x,y}
        var xPos = gestureState.moveX - this.circleCenter.x;
        var yPos = this.circleCenter.y - gestureState.moveY;
        var theta = Math.atan2(xPos, yPos);
        var percent = theta / (2 * Math.PI);
        if(xPos < 0) {
          percent = 1 + percent;
        }
        if(percent > 0.99) {
          this.setState({
            fullLoop: true
          });
        }
        if(percent < 0.99 && percent > 0.2) {
          this.setState({
            fullLoop: false
          });
        }
        if(this.state.fullLoop) {
          percent = 1;
        }
        this.setState({
          value: percent
        });
        this.props.onUpdate(Math.floor(percent * 100));
      },
      onPanResponderRelease: (evt, gestureState) => {
        // The user has released all touches while this view is the
        // responder. This typically means a gesture has succeeded
      },
      onPanResponderTerminate: (evt, gestureState) => {
        // Another component has become the responder, so this gesture
        // should be cancelled
      },
      onShouldBlockNativeResponder: (evt, gestureState) => {
        // Returns whether this component should block native components from becoming the JS
        // responder. Returns true by default. Is currently only supported on android.
        return true;
      },
    });
  }

  render() {
    return (
      <View ref='circle' style={{alignItems: 'center', padding:this.padding}} {...this._panResponder.panHandlers}>
        <Progress.Circle size={this.circleSize} progress={this.state.value} showsText={true} thickness={15}/>
      </View>
    )
  }
}

module.exports = ThumbRoll;

<commit_msg>Fix bug that caused teacher error on thumbroll click but not drag<commit_after>var React = require('react-native');
var Slider = require('react-native-slider');
var Progress = require('react-native-progress');

var {
  View,
  Text,
  PanResponder,
  Dimensions
} = React;

class ThumbRoll extends React.Component {
  constructor(props) {
    super(props)
    var {height, width} = Dimensions.get('window');
    this.width = width;
    this.circleSize = 300;
    this.padding = 40;
    this._panResponder = {};
    this.circleCenter = {};

    this.state = {
      value: 0,
    };
  }

  componentWillMount() {
    this._panResponder = PanResponder.create({
      // Ask to be the responder:
      onStartShouldSetPanResponder: (evt, gestureState) => true,
      onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,

      onPanResponderGrant: (evt, gestureState) => {
        this.refs.circle.measure( (fx, fy, width, height, px, py) => {
          this.circleCenter.y = py + this.circleSize / 2 + this.padding;
          this.circleCenter.x = width / 2;
          console.log(this.circleCenter);
          var xPos = gestureState.x0 - this.circleCenter.x;
          var yPos = this.circleCenter.y - gestureState.y0;
          var theta = Math.atan2(xPos, yPos);
          var percent = theta / (2 * Math.PI);
          if(xPos < 0) {
            percent = 1 + percent;
          }
          if(this.state.fullLoop) {
            percent = 1;
          }
          this.setState({
            value: percent
          });
          this.props.onUpdate(Math.floor(percent * 100));
        });
        this.setState({
          fullLoop: false
        })
      },
      onPanResponderMove: (evt, gestureState) => {
        // The most recent move distance is gestureState.move{X,Y}

        // The accumulated gesture distance since becoming responder is
        // gestureState.d{x,y}
        var xPos = gestureState.moveX - this.circleCenter.x;
        var yPos = this.circleCenter.y - gestureState.moveY;
        var theta = Math.atan2(xPos, yPos);
        var percent = theta / (2 * Math.PI);
        if(xPos < 0) {
          percent = 1 + percent;
        }
        if(percent > 0.99) {
          this.setState({
            fullLoop: true
          });
        }
        if(percent < 0.99 && percent > 0.2) {
          this.setState({
            fullLoop: false
          });
        }
        if(this.state.fullLoop) {
          percent = 1;
        }
        this.setState({
          value: percent
        });
        this.props.onUpdate(Math.floor(percent * 100));
      },
      onPanResponderRelease: (evt, gestureState) => {
        // The user has released all touches while this view is the
        // responder. This typically means a gesture has succeeded
      },
      onPanResponderTerminate: (evt, gestureState) => {
        // Another component has become the responder, so this gesture
        // should be cancelled
      },
      onShouldBlockNativeResponder: (evt, gestureState) => {
        // Returns whether this component should block native components from becoming the JS
        // responder. Returns true by default. Is currently only supported on android.
        return true;
      },
    });
  }

  render() {
    return (
      <View ref='circle' style={{alignItems: 'center', padding:this.padding}} {...this._panResponder.panHandlers}>
        <Progress.Circle size={this.circleSize} progress={this.state.value} showsText={true} thickness={15}/>
      </View>
    )
  }
}

module.exports = ThumbRoll;

<|endoftext|>


<commit_before>'use strict';

/**
 * Wordpress MVC gulp development file.
 * Enables predefined (standarized) tasks, such use minify or sass compilation.
 *
 * @link http://gulpjs.com/
 * @author Alejandro Mostajo <info@10quality.com>
 * @copyright 10 Quality
 * @license MIT
 * @version 1.0.0
 */

/**
 * Dependencies.
 * @since 1.0.0
 */
var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var minify = require('gulp-minify');
var cleanCSS = require('gulp-clean-css');
var zip = require('gulp-zip');
var del = require('del');

/**
 * Export module.
 * @since 1.0.0
 * @param array config Configuration file.
 */
module.exports = function(config)
{
    // Prepare options
    if (!config) config = {};
    if (!config.name) config.name = 'app';
    if (!config.version) config.version = '1.0.0';
    if (!config.prestep) config.prestep = ['sass'];

    // Set GULP tasks
    // SASS
    gulp.task('sass', function () {
        return gulp.src('./assets/raw/sass/*.scss')
            .pipe(sass().on('error', sass.logError))
            .pipe(gulp.dest('./assets/raw/css'));
    });
    // Styles
    gulp.task('styles', config.prestep, function () {
        return gulp.src('./assets/raw/css/*.css')
            .pipe(concat('app.css'))
            .pipe(gulp.dest('./assets/css'));
    });
    // Scripts
    gulp.task('scripts', function() {
        return gulp.src('./assets/raw/js/*.js')
            .pipe(concat('app.js'))
            .pipe(gulp.dest('./assets/js'));
    });
    // JS minify
    gulp.task('jsmin', ['scripts'], function() {
        return gulp.src('./assets/js/*.js')
            .pipe(minify({
                ext:{
                    min:'.js'
                }
            }))
            .pipe(gulp.dest('./builds/'+config.name+'/assets/js'));
    });
    // CSS minify
    gulp.task('cssmin', ['sass', 'styles'], function() {
        return gulp.src('./assets/css/*.css')
            .pipe(cleanCSS({compatibility: 'ie8'}))
            .pipe(gulp.dest('./builds/'+config.name+'/assets/css'));
    });
    // Build files
    gulp.task('build-files', ['scripts', 'styles'], function() {
        return gulp.src([
                '{app,assets,vendor}/**/*',
                './LICENSE',
                './*.{php,css,jpg,txt}'
            ])
            .pipe(gulp.dest('./builds/'+config.name));
    });
    // Build clean pre zip
    gulp.task('build-prezip', ['build-files'], function() {
        return del([
            './builds/'+config.name+'/assets/{raw,css,js}/**/*',
            './builds/'+config.name+'/vendor/10quality/{ayuco,wpmvc-commands}/**/*',
            './builds/'+config.name+'/assets/{raw,css,js}',
            './builds/'+config.name+'/vendor/10quality/{ayuco,wpmvc-commands}',
        ]);
    });
    // Build zip
    gulp.task('build-zip', ['build-prezip', 'jsmin', 'cssmin'], function() {
        return gulp.src('./builds/'+config.name+'/**/*')
            .pipe(zip(config.name+'-'+config.version+'.zip'))
            .pipe(gulp.dest('./builds'));
    });
    // Build clean
    gulp.task('build-clean', ['build-zip'], function() {
        return del([
            './builds/'+config.name+'/**/*',
            './builds/'+config.name,
        ]);
    });
    // DEV
    gulp.task('dev', [
        'sass',
        'styles',
        'scripts',
    ]);
    // BUILD
    gulp.task('build', [
        'sass',
        'styles',
        'scripts',
        'jsmin',
        'cssmin',
        'build-files',
        'build-prezip',
        'build-zip',
        'build-clean',
    ]);
}<commit_msg>Php parser exclusion.<commit_after>'use strict';

/**
 * Wordpress MVC gulp development file.
 * Enables predefined (standarized) tasks, such use minify or sass compilation.
 *
 * @link http://gulpjs.com/
 * @author Alejandro Mostajo <info@10quality.com>
 * @copyright 10 Quality
 * @license MIT
 * @version 1.0.0
 */

/**
 * Dependencies.
 * @since 1.0.0
 */
var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var minify = require('gulp-minify');
var cleanCSS = require('gulp-clean-css');
var zip = require('gulp-zip');
var del = require('del');

/**
 * Export module.
 * @since 1.0.0
 * @param array config Configuration file.
 */
module.exports = function(config)
{
    // Prepare options
    if (!config) config = {};
    if (!config.name) config.name = 'app';
    if (!config.version) config.version = '1.0.0';
    if (!config.prestep) config.prestep = ['sass'];

    // Set GULP tasks
    // SASS
    gulp.task('sass', function () {
        return gulp.src('./assets/raw/sass/*.scss')
            .pipe(sass().on('error', sass.logError))
            .pipe(gulp.dest('./assets/raw/css'));
    });
    // Styles
    gulp.task('styles', config.prestep, function () {
        return gulp.src('./assets/raw/css/*.css')
            .pipe(concat('app.css'))
            .pipe(gulp.dest('./assets/css'));
    });
    // Scripts
    gulp.task('scripts', function() {
        return gulp.src('./assets/raw/js/*.js')
            .pipe(concat('app.js'))
            .pipe(gulp.dest('./assets/js'));
    });
    // JS minify
    gulp.task('jsmin', ['scripts'], function() {
        return gulp.src('./assets/js/*.js')
            .pipe(minify({
                ext:{
                    min:'.js'
                }
            }))
            .pipe(gulp.dest('./builds/'+config.name+'/assets/js'));
    });
    // CSS minify
    gulp.task('cssmin', ['sass', 'styles'], function() {
        return gulp.src('./assets/css/*.css')
            .pipe(cleanCSS({compatibility: 'ie8'}))
            .pipe(gulp.dest('./builds/'+config.name+'/assets/css'));
    });
    // Build files
    gulp.task('build-files', ['scripts', 'styles'], function() {
        return gulp.src([
                '{app,assets,vendor}/**/*',
                './LICENSE',
                './*.{php,css,jpg,txt}'
            ])
            .pipe(gulp.dest('./builds/'+config.name));
    });
    // Build clean pre zip
    gulp.task('build-prezip', ['build-files'], function() {
        return del([
            './builds/'+config.name+'/assets/{raw,css,js}/**/*',
            './builds/'+config.name+'/vendor/10quality/{ayuco,wpmvc-commands,nikic}/**/*',
            './builds/'+config.name+'/assets/{raw,css,js}',
            './builds/'+config.name+'/vendor/10quality/{ayuco,wpmvc-commands,nikic}',
        ]);
    });
    // Build zip
    gulp.task('build-zip', ['build-prezip', 'jsmin', 'cssmin'], function() {
        return gulp.src('./builds/'+config.name+'/**/*')
            .pipe(zip(config.name+'-'+config.version+'.zip'))
            .pipe(gulp.dest('./builds'));
    });
    // Build clean
    gulp.task('build-clean', ['build-zip'], function() {
        return del([
            './builds/'+config.name+'/**/*',
            './builds/'+config.name,
        ]);
    });
    // DEV
    gulp.task('dev', [
        'sass',
        'styles',
        'scripts',
    ]);
    // BUILD
    gulp.task('build', [
        'sass',
        'styles',
        'scripts',
        'jsmin',
        'cssmin',
        'build-files',
        'build-prezip',
        'build-zip',
        'build-clean',
    ]);
}<|endoftext|>


<commit_before>(function ($) {
  var _enableChangeNoteHighlighting = function() {
    var form = $(this);
    var changeNoteLabels = form.find("label[for=edition_change_note]");
    var changeNoteTextareas = form.find("textarea#edition_change_note");
    var changeNoteElements = changeNoteLabels.add(changeNoteTextareas);

    if ((changeNoteLabels.length > 0) && (changeNoteTextareas.length > 0)) {
      var buttonValue = form.find("input[type=submit]")[0].value;
      var publishButtonLink = $("").text(buttonValue).addClass("button").attr("href", "#edition_publishing");

      publishButtonLink.click(function() {
        publishButtonLink.hide();
        $(changeNoteElements).wrap($("
"));
        form.show();
      });

      form.hide();
      form.before(publishButtonLink);

      form.find('input[type=checkbox][name="edition[minor_change]"]').click(function(event) {
        changeNoteElements.attr('disabled', $(this).prop('checked') ? 'disabled' : null);
      });
    };

  }

  $.fn.extend({
    enableChangeNoteHighlighting: _enableChangeNoteHighlighting
  });
})(jQuery);

jQuery(function($) {
  $("#edition_publishing").enableChangeNoteHighlighting();
});

(function($) {
  var hidePersonOverride = function() {
    if ($('input#person_override_active').prop('checked')) {
      $('.edition_person_override').show();
      $('.role_appointment').hide();
      $("#edition_role_appointment_id").val('');
    } else {
      $('.role_appointment').show();
      $('.edition_person_override').hide();
      $('#edition_person_override').val('');
    }
  }

  $('input#person_override_active').change(hidePersonOverride)
  hidePersonOverride();
})(jQuery);

(function($) {
  var hideScheduledPublication = function() {
    if ($('input#scheduled_publication_active').prop('checked')) {
      $('.scheduled_publication').show();
    } else {
      $('.scheduled_publication').hide();
    }
  }

  $('input#scheduled_publication_active').change(hideScheduledPublication)
  hideScheduledPublication();
})(jQuery);

(function($) {
  var $label = $('.check-date-valid'),
      $message = $('.date-warning-info').hide();
  if ($label.length > 0){
    var id = $($('.check-date-valid')[0]).attr('for'),
        $year = $('#' + id + '_1i'),
        $month = $('#' + id + '_2i'),
        $day = $('#' + id + '_3i');
    function checkDateValidity(){
      var year = $year[0].value,
          month = (parseInt($month[0].value) - 1),
          day = $day[0].value,
          dateSet = new Date(year, month, day),
          today = new Date();
      if (today < dateSet){
        $message.addClass('warning');
        $message.show();
      } else {
        $message.removeClass('warning');
        $message.hide();
      }
    }
    $year.bind('blur', checkDateValidity);
    $month.bind('blur', checkDateValidity);
    $day.bind('blur', checkDateValidity);
    checkDateValidity();
  }
})(jQuery);

(function($) {
  var publicationTypeChooser = $('.js-access-limited-by-default-checkbox');
  if (publicationTypeChooser.length > 0) {
    var accessLimitedByDefaultIds = publicationTypeChooser.data('access-limited-by-default-type-ids');
    var accessLimitedByDefault = function() {
      var chosenId = parseInt(publicationTypeChooser.val(), 10);
      if (accessLimitedByDefaultIds.indexOf(chosenId) >= 0) {
        $("input[name$='[access_limited]'][type=checkbox]").attr('checked', 'checked');
      }
    }

    if (accessLimitedByDefaultIds.length > 0) {
      publicationTypeChooser.change(accessLimitedByDefault)
      accessLimitedByDefault();
    }
  }
})(jQuery);

(function($){
  var $input = $('#edition_title'),
      $message = $('.title-length-info').hide(),
      $count = $message.find('.count');

  if($input.length > 0){
    $input.addClass('title-length-input');
    function checkLength(){
      var length = $input.val().split('').length;

      $count.text('Current length: '+length);
      if(length > 149){
        $input.removeClass('warning');
        $message.removeClass('warning');
        $input.addClass('error');
        $message.addClass('error');
        $message.show();
      }
      else if(length > 65){
        $input.removeClass('error');
        $message.removeClass('error');
        $input.addClass('warning');
        $message.addClass('warning');
        $message.show();
      }
      else {
        $input.removeClass('error');
        $message.removeClass('error');
        $input.removeClass('warning');
        $message.removeClass('warning');
      }
    }
    $input.bind('keyup', checkLength);
    checkLength();
  }
}(jQuery));
<commit_msg>Use jQuery inArray over indexOf for IE support<commit_after>(function ($) {
  var _enableChangeNoteHighlighting = function() {
    var form = $(this);
    var changeNoteLabels = form.find("label[for=edition_change_note]");
    var changeNoteTextareas = form.find("textarea#edition_change_note");
    var changeNoteElements = changeNoteLabels.add(changeNoteTextareas);

    if ((changeNoteLabels.length > 0) && (changeNoteTextareas.length > 0)) {
      var buttonValue = form.find("input[type=submit]")[0].value;
      var publishButtonLink = $("").text(buttonValue).addClass("button").attr("href", "#edition_publishing");

      publishButtonLink.click(function() {
        publishButtonLink.hide();
        $(changeNoteElements).wrap($("
"));
        form.show();
      });

      form.hide();
      form.before(publishButtonLink);

      form.find('input[type=checkbox][name="edition[minor_change]"]').click(function(event) {
        changeNoteElements.attr('disabled', $(this).prop('checked') ? 'disabled' : null);
      });
    };

  }

  $.fn.extend({
    enableChangeNoteHighlighting: _enableChangeNoteHighlighting
  });
})(jQuery);

jQuery(function($) {
  $("#edition_publishing").enableChangeNoteHighlighting();
});

(function($) {
  var hidePersonOverride = function() {
    if ($('input#person_override_active').prop('checked')) {
      $('.edition_person_override').show();
      $('.role_appointment').hide();
      $("#edition_role_appointment_id").val('');
    } else {
      $('.role_appointment').show();
      $('.edition_person_override').hide();
      $('#edition_person_override').val('');
    }
  }

  $('input#person_override_active').change(hidePersonOverride)
  hidePersonOverride();
})(jQuery);

(function($) {
  var hideScheduledPublication = function() {
    if ($('input#scheduled_publication_active').prop('checked')) {
      $('.scheduled_publication').show();
    } else {
      $('.scheduled_publication').hide();
    }
  }

  $('input#scheduled_publication_active').change(hideScheduledPublication)
  hideScheduledPublication();
})(jQuery);

(function($) {
  var $label = $('.check-date-valid'),
      $message = $('.date-warning-info').hide();
  if ($label.length > 0){
    var id = $($('.check-date-valid')[0]).attr('for'),
        $year = $('#' + id + '_1i'),
        $month = $('#' + id + '_2i'),
        $day = $('#' + id + '_3i');
    function checkDateValidity(){
      var year = $year[0].value,
          month = (parseInt($month[0].value) - 1),
          day = $day[0].value,
          dateSet = new Date(year, month, day),
          today = new Date();
      if (today < dateSet){
        $message.addClass('warning');
        $message.show();
      } else {
        $message.removeClass('warning');
        $message.hide();
      }
    }
    $year.bind('blur', checkDateValidity);
    $month.bind('blur', checkDateValidity);
    $day.bind('blur', checkDateValidity);
    checkDateValidity();
  }
})(jQuery);

(function($) {
  var publicationTypeChooser = $('.js-access-limited-by-default-checkbox');
  if (publicationTypeChooser.length > 0) {
    var accessLimitedByDefaultIds = publicationTypeChooser.data('access-limited-by-default-type-ids');
    var accessLimitedByDefault = function() {
      var chosenId = parseInt(publicationTypeChooser.val(), 10);
      if ($.inArray(chosenId, accessLimitedByDefaultIds) >= 0) {
        $("input[name$='[access_limited]'][type=checkbox]").attr('checked', 'checked');
      }
    }

    if (accessLimitedByDefaultIds.length > 0) {
      publicationTypeChooser.change(accessLimitedByDefault)
      accessLimitedByDefault();
    }
  }
})(jQuery);

(function($){
  var $input = $('#edition_title'),
      $message = $('.title-length-info').hide(),
      $count = $message.find('.count');

  if($input.length > 0){
    $input.addClass('title-length-input');
    function checkLength(){
      var length = $input.val().split('').length;

      $count.text('Current length: '+length);
      if(length > 149){
        $input.removeClass('warning');
        $message.removeClass('warning');
        $input.addClass('error');
        $message.addClass('error');
        $message.show();
      }
      else if(length > 65){
        $input.removeClass('error');
        $message.removeClass('error');
        $input.addClass('warning');
        $message.addClass('warning');
        $message.show();
      }
      else {
        $input.removeClass('error');
        $message.removeClass('error');
        $input.removeClass('warning');
        $message.removeClass('warning');
      }
    }
    $input.bind('keyup', checkLength);
    checkLength();
  }
}(jQuery));
<|endoftext|>