<commit_before>var MARKDOWN_TUTORIAL = "\
# Markdown tutorial by example\
\n\n\
Read this if you need to check the Markdown syntax. \n\n\
\
> **Disable the live tutorial to go back to your article**.\n\
\
\n\n\n\
# Headers \
\n\n\
## Header's Subsection \
\n\n\
### Header's Subsection \
\n\n\
#### Header's Subsection \
\n\n\
##### Header's Subsection \
\n\n\n\
# Text Format \
\n\n\
normal, *italic*, **bold**, __bold__, _emphasis_, ~~strikethrough~~, ùníçõd&, `code`, \*escaping special chars\*, © \
\n\n\
## Bloquote \
\n\n\
> You can put some warning or important messages in bloquotes. \n\
Check that a bloquote can have multiple lines. \
\n\n\n\
# Code \
\n\n\
```\n\
print('test')\n\
```\
\n\n\
```javascript\n\
$(function(){\n\
  $('div').html('I am a div.');\n\
});\n\
```\
\n\n\n\
# Lists\
\n\n\
## Unordered list\
\n\n\
- item 1\n\
- item 2\n\
\n\
or\n\
\n\
* item 1\n\
* item 2\
\n\n\
## Ordered list\
\n\n\
1. item 1\n\
1. item 2\n\
\n\
or\n\
\n\
1. item 1\n\
2. item 2\n\
\n\
## Nesting\
\n\n\
1. item 1\n\
  1. item 1.1\n\
  2. item 1.2\n\
    - subitem 1\n\
    - subitem 2\n\
2. item 2\n\
\n\
## Task Listing\
\n\n\
- [ ] item 1\n\
- [x] item 2\n\
\n\n\
# Tables\
\n\n\
First Column Header | Second Column Header | Third Column\n\
------------------- | -------------------- | ------------\n\
Content from cell 1 | | Content from cell 3\n\
Another cell 1 | Another cell 2\n\
\n\n\
# Links\
\n\n\
* [text of the link](http://hackguides.org)\n\
* http://hackguides.org\
\n\n\n\
# Images and Files\
\n\n\
![alt text](http://tutorials.pluralsight.com/static/img/dark-logo.png 'Logo Title')\
\n\n\n\
# Horizontal rules\
\n\n\
------------------------\
\n\n\
or\
\n\n\
* * *\
\n\n\
or\
\n\n\
*****\
\n\n\
";

var editor;
var author_name;
var author_real_name;
var current_local_filename;

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

var previewUpdated = debounce(function() {
    var content_as_markdown = editor.getSession().getValue();
    var content_as_html = marked(content_as_markdown);
    var preview = $('#preview');
    preview.html(content_as_html);
    $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
}, 500);

var autosaveEnabled = true;

var loadAutoSave = function(local_filename) {
    var obj = localStorage.getItem('hack.guides');
    if (obj) {
        obj = JSON.parse(obj);
        return obj[local_filename]; // markdown content or undefined
    }
    return undefined;
}

var autoSave = debounce(function(local_filename) {
    var content_as_markdown = editor.getSession().getValue();
    var obj = localStorage.getItem('hack.guides') || '{}';
    obj = JSON.parse(obj);
    obj[local_filename] = content_as_markdown;
    localStorage.setItem('hack.guides', JSON.stringify(obj));
}, 1000);

var clearLocalSave = function(local_filename) {
    var obj = localStorage.getItem('hack.guides');
    if (obj) {
        obj = JSON.parse(obj);
        delete obj[local_filename];
        localStorage.setItem('hack.guides', JSON.stringify(obj));
    }
    return undefined;
}

function openLiveMarkdownTutorial() {
    autosaveEnabled = false;
    editor.getSession().setValue(MARKDOWN_TUTORIAL);
}

function closeLiveMarkdownTutorial() {
    editor.setValue(loadAutoSave(current_local_filename) || '');
    autosaveEnabled = true;
}

var liveTutorialEnabled = false;
function toggleLiveTutorial() {
    if (liveTutorialEnabled) {
        closeLiveMarkdownTutorial();
    } else {
        openLiveMarkdownTutorial();
    }
    liveTutorialEnabled = ! liveTutorialEnabled;
}

function initialize_editor(local_filename, content, name, real_name, img_upload_url) {
    author_name = name;
    author_real_name = real_name;
    current_local_filename = local_filename;

    editor = ace.edit("editor");
    editor.setTheme("ace/theme/github");
    editor.getSession().setMode("ace/mode/markdown");
    editor.getSession().setUseWrapMode(true);
    // editor.getSession().setNewLineMode("unix");
    editor.setShowPrintMargin(false);
    editor.setOption('maxLines', 99999);
    editor.$blockScrolling = Infinity;
    // editor.renderer.setShowGutter(false);
    // editor.renderer.setOption('showLineNumbers', false);

    marked.setOptions({
      gfm: true,
      tables: true,
      breaks: true,
      pedantic: false,
      sanitize: false,
      smartLists: true,
      smartypants: false
    });

    var placeholder = '# Start writing your tutorial here.\n\nOr load the live markdown tutorial to check the syntax.';
    editor.setValue(content || loadAutoSave(local_filename) || placeholder);
    editor.gotoLine(1);
    previewUpdated();

    editor.getSession().on('change', function(e) {
        previewUpdated();
        if (autosaveEnabled) {
            autoSave(local_filename);
        }
    });

    configure_dropzone_area(img_upload_url);

    return editor;
}

var scrollSyncEnabled = false;
var $divs = null;
var scrollSyncFunction = function(e) {
    var
      $other     = $divs.not(this).off('scroll'),
      other      = $other[0],
      percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);

    other.scrollTop = Math.round(percentage * (other.scrollHeight - other.offsetHeight));

    setTimeout(function() { $other.on('scroll', scrollSyncFunction); }, 10);

    return false;
};

function toggleScrollSync() {
    $divs = $('#editor-wrapper, #preview');
    if (scrollSyncEnabled) {
        $divs.off('scroll', scrollSyncFunction);
    } else {
        $divs.on('scroll', scrollSyncFunction);
    }
    scrollSyncEnabled = ! scrollSyncEnabled;
}

function configure_dropzone_area(img_upload_url) {
    Dropzone.autoDiscover = false;
    var dropZoneOptions = {
        url: img_upload_url,
        paramName: 'file',
        maxFilesize: 3, // MB
        uploadMultiple: false,
        disablePreview: false,
        createImageThumbnails: false,
        addRemoveLinks: false,
        previewTemplate: document.querySelector('#preview-template').innerHTML,
        clickable: '.btn-dropzone',
        accept: function(file, done) {
            if (file.name.endsWith('.exe') || file.name.endsWith('.bin') || file.name.endsWith('.bat')) {
                done("File not supported");
            }
            else {
                done();
            }
        }
    };
    var myDropzone = new Dropzone("div#droppable-area", dropZoneOptions);
    myDropzone.on('success', function(file, path) {
        // Add Markdown reference into the editor
        var fileMarkdown = '\n![description](' + path + ')\n';
        editor.insert(fileMarkdown);
    });

    myDropzone.on("complete", function(file) {
        myDropzone.removeFile(file);
    });

    return myDropzone;
}

function save(sha, path, secondary_repo, action_url) {
    var form = document.createElement("form");
    form.action = action_url;
    form.method = "POST";

    var textarea = document.createElement("textarea");
    textarea.name = "content";
    $(textarea).val(editor.getSession().getValue());
    form.appendChild(textarea);

    var sha_elem = document.createElement("input");
    sha_elem.name = "sha";
    sha_elem.value = sha;
    form.appendChild(sha_elem.cloneNode());

    var path_elem = document.createElement("input");
    path_elem.name = "path";
    path_elem.value = path;
    form.appendChild(path_elem.cloneNode());

    var title = document.getElementById("title");
    form.appendChild(title.cloneNode());

    var orig_stack = document.getElementById("original_stack");
    form.appendChild(orig_stack.cloneNode());

    var stacks_select = document.getElementById("stacks");
    var stacks = document.createElement("input");
    stacks.name = "stacks";
    stacks.value = stacks_select.value;
    form.appendChild(stacks.cloneNode());

    if (secondary_repo) {
        var secondary_repo_elem = document.createElement("input");
        secondary_repo_elem.name = "secondary_repo";
        secondary_repo_elem.value = 1;
        form.appendChild(secondary_repo_elem.cloneNode());
    }

    // To be sent, the form needs to be attached to the main document.
    form.style.display = "none";
    document.body.appendChild(form);

    form.submit();

    // But once the form is sent, it's useless to keep it.
    document.body.removeChild(form);
}
<commit_msg>Fixed typo<commit_after>var MARKDOWN_TUTORIAL = "\
# Markdown tutorial by example\
\n\n\
Read this if you need to check the Markdown syntax. \n\n\
\
> **Disable the live tutorial to go back to your article**.\n\
\
\n\n\n\
# Headers \
\n\n\
## Header's Subsection \
\n\n\
### Header's Subsection \
\n\n\
#### Header's Subsection \
\n\n\
##### Header's Subsection \
\n\n\n\
# Text Format \
\n\n\
normal, *italic*, **bold**, __bold__, _emphasis_, ~~strikethrough~~, ùníçõd&, `code`, \*escaping special chars\*, © \
\n\n\
## Bloquote \
\n\n\
> You can put some warning or important messages in blockquotes. \n\
Check that a blockquote can have multiple lines. \
\n\n\n\
# Code \
\n\n\
```\n\
print('test')\n\
```\
\n\n\
```javascript\n\
$(function(){\n\
  $('div').html('I am a div.');\n\
});\n\
```\
\n\n\n\
# Lists\
\n\n\
## Unordered list\
\n\n\
- item 1\n\
- item 2\n\
\n\
or\n\
\n\
* item 1\n\
* item 2\
\n\n\
## Ordered list\
\n\n\
1. item 1\n\
1. item 2\n\
\n\
or\n\
\n\
1. item 1\n\
2. item 2\n\
\n\
## Nesting\
\n\n\
1. item 1\n\
  1. item 1.1\n\
  2. item 1.2\n\
    - subitem 1\n\
    - subitem 2\n\
2. item 2\n\
\n\
## Task Listing\
\n\n\
- [ ] item 1\n\
- [x] item 2\n\
\n\n\
# Tables\
\n\n\
First Column Header | Second Column Header | Third Column\n\
------------------- | -------------------- | ------------\n\
Content from cell 1 | | Content from cell 3\n\
Another cell 1 | Another cell 2\n\
\n\n\
# Links\
\n\n\
* [text of the link](http://hackguides.org)\n\
* http://hackguides.org\
\n\n\n\
# Images and Files\
\n\n\
![alt text](http://tutorials.pluralsight.com/static/img/dark-logo.png 'Logo Title')\
\n\n\n\
# Horizontal rules\
\n\n\
------------------------\
\n\n\
or\
\n\n\
* * *\
\n\n\
or\
\n\n\
*****\
\n\n\
";

var editor;
var author_name;
var author_real_name;
var current_local_filename;

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

var previewUpdated = debounce(function() {
    var content_as_markdown = editor.getSession().getValue();
    var content_as_html = marked(content_as_markdown);
    var preview = $('#preview');
    preview.html(content_as_html);
    $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
}, 500);

var autosaveEnabled = true;

var loadAutoSave = function(local_filename) {
    var obj = localStorage.getItem('hack.guides');
    if (obj) {
        obj = JSON.parse(obj);
        return obj[local_filename]; // markdown content or undefined
    }
    return undefined;
}

var autoSave = debounce(function(local_filename) {
    var content_as_markdown = editor.getSession().getValue();
    var obj = localStorage.getItem('hack.guides') || '{}';
    obj = JSON.parse(obj);
    obj[local_filename] = content_as_markdown;
    localStorage.setItem('hack.guides', JSON.stringify(obj));
}, 1000);

var clearLocalSave = function(local_filename) {
    var obj = localStorage.getItem('hack.guides');
    if (obj) {
        obj = JSON.parse(obj);
        delete obj[local_filename];
        localStorage.setItem('hack.guides', JSON.stringify(obj));
    }
    return undefined;
}

function openLiveMarkdownTutorial() {
    autosaveEnabled = false;
    editor.getSession().setValue(MARKDOWN_TUTORIAL);
}

function closeLiveMarkdownTutorial() {
    editor.setValue(loadAutoSave(current_local_filename) || '');
    autosaveEnabled = true;
}

var liveTutorialEnabled = false;
function toggleLiveTutorial() {
    if (liveTutorialEnabled) {
        closeLiveMarkdownTutorial();
    } else {
        openLiveMarkdownTutorial();
    }
    liveTutorialEnabled = ! liveTutorialEnabled;
}

function initialize_editor(local_filename, content, name, real_name, img_upload_url) {
    author_name = name;
    author_real_name = real_name;
    current_local_filename = local_filename;

    editor = ace.edit("editor");
    editor.setTheme("ace/theme/github");
    editor.getSession().setMode("ace/mode/markdown");
    editor.getSession().setUseWrapMode(true);
    // editor.getSession().setNewLineMode("unix");
    editor.setShowPrintMargin(false);
    editor.setOption('maxLines', 99999);
    editor.$blockScrolling = Infinity;
    // editor.renderer.setShowGutter(false);
    // editor.renderer.setOption('showLineNumbers', false);

    marked.setOptions({
      gfm: true,
      tables: true,
      breaks: true,
      pedantic: false,
      sanitize: false,
      smartLists: true,
      smartypants: false
    });

    var placeholder = '# Start writing your tutorial here.\n\nOr load the live markdown tutorial to check the syntax.';
    editor.setValue(content || loadAutoSave(local_filename) || placeholder);
    editor.gotoLine(1);
    previewUpdated();

    editor.getSession().on('change', function(e) {
        previewUpdated();
        if (autosaveEnabled) {
            autoSave(local_filename);
        }
    });

    configure_dropzone_area(img_upload_url);

    return editor;
}

var scrollSyncEnabled = false;
var $divs = null;
var scrollSyncFunction = function(e) {
    var
      $other     = $divs.not(this).off('scroll'),
      other      = $other[0],
      percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);

    other.scrollTop = Math.round(percentage * (other.scrollHeight - other.offsetHeight));

    setTimeout(function() { $other.on('scroll', scrollSyncFunction); }, 10);

    return false;
};

function toggleScrollSync() {
    $divs = $('#editor-wrapper, #preview');
    if (scrollSyncEnabled) {
        $divs.off('scroll', scrollSyncFunction);
    } else {
        $divs.on('scroll', scrollSyncFunction);
    }
    scrollSyncEnabled = ! scrollSyncEnabled;
}

function configure_dropzone_area(img_upload_url) {
    Dropzone.autoDiscover = false;
    var dropZoneOptions = {
        url: img_upload_url,
        paramName: 'file',
        maxFilesize: 3, // MB
        uploadMultiple: false,
        disablePreview: false,
        createImageThumbnails: false,
        addRemoveLinks: false,
        previewTemplate: document.querySelector('#preview-template').innerHTML,
        clickable: '.btn-dropzone',
        accept: function(file, done) {
            if (file.name.endsWith('.exe') || file.name.endsWith('.bin') || file.name.endsWith('.bat')) {
                done("File not supported");
            }
            else {
                done();
            }
        }
    };
    var myDropzone = new Dropzone("div#droppable-area", dropZoneOptions);
    myDropzone.on('success', function(file, path) {
        // Add Markdown reference into the editor
        var fileMarkdown = '\n![description](' + path + ')\n';
        editor.insert(fileMarkdown);
    });

    myDropzone.on("complete", function(file) {
        myDropzone.removeFile(file);
    });

    return myDropzone;
}

function save(sha, path, secondary_repo, action_url) {
    var form = document.createElement("form");
    form.action = action_url;
    form.method = "POST";

    var textarea = document.createElement("textarea");
    textarea.name = "content";
    $(textarea).val(editor.getSession().getValue());
    form.appendChild(textarea);

    var sha_elem = document.createElement("input");
    sha_elem.name = "sha";
    sha_elem.value = sha;
    form.appendChild(sha_elem.cloneNode());

    var path_elem = document.createElement("input");
    path_elem.name = "path";
    path_elem.value = path;
    form.appendChild(path_elem.cloneNode());

    var title = document.getElementById("title");
    form.appendChild(title.cloneNode());

    var orig_stack = document.getElementById("original_stack");
    form.appendChild(orig_stack.cloneNode());

    var stacks_select = document.getElementById("stacks");
    var stacks = document.createElement("input");
    stacks.name = "stacks";
    stacks.value = stacks_select.value;
    form.appendChild(stacks.cloneNode());

    if (secondary_repo) {
        var secondary_repo_elem = document.createElement("input");
        secondary_repo_elem.name = "secondary_repo";
        secondary_repo_elem.value = 1;
        form.appendChild(secondary_repo_elem.cloneNode());
    }

    // To be sent, the form needs to be attached to the main document.
    form.style.display = "none";
    document.body.appendChild(form);

    form.submit();

    // But once the form is sent, it's useless to keep it.
    document.body.removeChild(form);
}
<|endoftext|>


<commit_before>define([
  'angular',
  'jquery',
  'lodash',
],
function (angular, $, _) {
  'use strict';

  angular
    .module('grafana.directives')
    .directive('panelMenu', function($compile, linkSrv) {
      var linkTemplate =
          '' +
            '{{panel.title | interpolateTemplateVars:this}}' +
            '' +
            ' {{panelMeta.timeInfo}}' +
          '';

      function createMenuTemplate($scope) {
        var template = '
';

        if ($scope.dashboardMeta.canEdit) {
          template += '
';
          template += '
';
          template += '';
          template += '';
          template += '';
          template += '

';
          template += '
';
        }

        template += '
';
        template += '';

        _.each($scope.panelMeta.menu, function(item) {
          // skip edit actions if not editor
          if (item.role === 'Editor' && !$scope.dashboardMeta.canEdit) {
            return;
          }

          template += '';
          template += item.text + '';
        });

        template += '
';
        template += '
';
        template += '
';
        return template;
      }

      function getExtendedMenu($scope) {
        var menu = angular.copy($scope.panelMeta.extendedMenu);

        if ($scope.panel.links) {
          _.each($scope.panel.links, function(link) {
            var info = linkSrv.getPanelLinkAnchorInfo(link);
            menu.push({text: info.title, href: info.href, target: info.target });
          });
        }

        return menu;
      }

      return {
        restrict: 'A',
        link: function($scope, elem) {
          var $link = $(linkTemplate);
          var $panelContainer = elem.parents(".panel-container");
          var menuScope = null;
          var timeout = null;
          var $menu = null;

          elem.append($link);

          $scope.$watchCollection('panel.links', function(newValue) {
            var showIcon = (newValue ? newValue.length > 0 : false) && $scope.panel.title !== '';
            $link.toggleClass('has-panel-links', showIcon);
          });

          function dismiss(time, force) {
            clearTimeout(timeout);
            timeout = null;

            if (time) {
              timeout = setTimeout(dismiss, time);
              return;
            }

            // if hovering or draging pospone close
            if (force !== true) {
              if ($menu.is(':hover') || $scope.dashboard.$$panelDragging) {
                dismiss(2200);
                return;
              }
            }

            if (menuScope) {
              $menu.unbind();
              $menu.remove();
              menuScope.$destroy();
              menuScope = null;
              $menu = null;
              $panelContainer.removeClass('panel-highlight');
            }
          }

          var showMenu = function(e) {
            // if menu item is clicked and menu was just removed from dom ignore this event
            if (!$.contains(document, e.target)) {
              return;
            }

            if ($menu) {
              dismiss();
              return;
            }

            var menuTemplate = createMenuTemplate($scope);
            $menu = $(menuTemplate);
            $menu.mouseleave(function() {
              dismiss(1000);
            });

            menuScope = $scope.$new();
            menuScope.extendedMenu = getExtendedMenu($scope);
            menuScope.dismiss = function() {
              dismiss(null, true);
            };

            $(".panel-container").removeClass('panel-highlight');
            $panelContainer.toggleClass('panel-highlight');

            $('.panel-menu').remove();

            elem.append($menu);

            $scope.$apply(function() {
              $compile($menu.contents())(menuScope);

              var menuWidth =  $menu[0].offsetWidth;
              var menuHeight =  $menu[0].offsetHeight;

              var windowWidth = $(window).width();
              var panelLeftPos = $(elem).offset().left;
              var panelWidth = $(elem).width();

              var menuLeftPos = (panelWidth / 2) - (menuWidth/2);
              var stickingOut = panelLeftPos + menuLeftPos + menuWidth - windowWidth;
              if (stickingOut > 0) {
                menuLeftPos -= stickingOut + 10;
              }
              if (panelLeftPos + menuLeftPos < 0) {
                menuLeftPos = 0;
              }
              if ($scope.fullscreen) {
                menuHeight = -(menuHeight/2);
              }

              $menu.css({'left': menuLeftPos, top: -menuHeight});
            });

            dismiss(2200);
          };

          elem.click(showMenu);
          $compile(elem.contents())($scope);
        }
      };
    });
});
<commit_msg>fix(templating): another fix for panel links and repeat panels, #2410<commit_after>define([
  'angular',
  'jquery',
  'lodash',
],
function (angular, $, _) {
  'use strict';

  angular
    .module('grafana.directives')
    .directive('panelMenu', function($compile, linkSrv) {
      var linkTemplate =
          '' +
            '{{panel.title | interpolateTemplateVars:this}}' +
            '' +
            ' {{panelMeta.timeInfo}}' +
          '';

      function createMenuTemplate($scope) {
        var template = '
';

        if ($scope.dashboardMeta.canEdit) {
          template += '
';
          template += '
';
          template += '';
          template += '';
          template += '';
          template += '

';
          template += '
';
        }

        template += '
';
        template += '';

        _.each($scope.panelMeta.menu, function(item) {
          // skip edit actions if not editor
          if (item.role === 'Editor' && !$scope.dashboardMeta.canEdit) {
            return;
          }

          template += '';
          template += item.text + '';
        });

        template += '
';
        template += '
';
        template += '
';
        return template;
      }

      function getExtendedMenu($scope) {
        var menu = angular.copy($scope.panelMeta.extendedMenu);

        if ($scope.panel.links) {
          _.each($scope.panel.links, function(link) {
            var info = linkSrv.getPanelLinkAnchorInfo(link, $scope.panel.scopedVars);
            menu.push({text: info.title, href: info.href, target: info.target });
          });
        }

        return menu;
      }

      return {
        restrict: 'A',
        link: function($scope, elem) {
          var $link = $(linkTemplate);
          var $panelContainer = elem.parents(".panel-container");
          var menuScope = null;
          var timeout = null;
          var $menu = null;

          elem.append($link);

          $scope.$watchCollection('panel.links', function(newValue) {
            var showIcon = (newValue ? newValue.length > 0 : false) && $scope.panel.title !== '';
            $link.toggleClass('has-panel-links', showIcon);
          });

          function dismiss(time, force) {
            clearTimeout(timeout);
            timeout = null;

            if (time) {
              timeout = setTimeout(dismiss, time);
              return;
            }

            // if hovering or draging pospone close
            if (force !== true) {
              if ($menu.is(':hover') || $scope.dashboard.$$panelDragging) {
                dismiss(2200);
                return;
              }
            }

            if (menuScope) {
              $menu.unbind();
              $menu.remove();
              menuScope.$destroy();
              menuScope = null;
              $menu = null;
              $panelContainer.removeClass('panel-highlight');
            }
          }

          var showMenu = function(e) {
            // if menu item is clicked and menu was just removed from dom ignore this event
            if (!$.contains(document, e.target)) {
              return;
            }

            if ($menu) {
              dismiss();
              return;
            }

            var menuTemplate = createMenuTemplate($scope);
            $menu = $(menuTemplate);
            $menu.mouseleave(function() {
              dismiss(1000);
            });

            menuScope = $scope.$new();
            menuScope.extendedMenu = getExtendedMenu($scope);
            menuScope.dismiss = function() {
              dismiss(null, true);
            };

            $(".panel-container").removeClass('panel-highlight');
            $panelContainer.toggleClass('panel-highlight');

            $('.panel-menu').remove();

            elem.append($menu);

            $scope.$apply(function() {
              $compile($menu.contents())(menuScope);

              var menuWidth =  $menu[0].offsetWidth;
              var menuHeight =  $menu[0].offsetHeight;

              var windowWidth = $(window).width();
              var panelLeftPos = $(elem).offset().left;
              var panelWidth = $(elem).width();

              var menuLeftPos = (panelWidth / 2) - (menuWidth/2);
              var stickingOut = panelLeftPos + menuLeftPos + menuWidth - windowWidth;
              if (stickingOut > 0) {
                menuLeftPos -= stickingOut + 10;
              }
              if (panelLeftPos + menuLeftPos < 0) {
                menuLeftPos = 0;
              }
              if ($scope.fullscreen) {
                menuHeight = -(menuHeight/2);
              }

              $menu.css({'left': menuLeftPos, top: -menuHeight});
            });

            dismiss(2200);
          };

          elem.click(showMenu);
          $compile(elem.contents())($scope);
        }
      };
    });
});
<|endoftext|>


<commit_before>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

define([
    './3rdparty/stats/stats.min',
    './gameclock',
    './logger',
    './misc',
  ], function(
    StatsJS,
    GameClock,
    Logger,
    Misc) {

  var $ = function(id) {
    return document.getElementById(id);
  };

  var stats = {
    begin: function() { },
    end: function() { },
  };

  var statusNode;
  var logger = new Logger.NullLogger();

  // options:
  //   showFPS: true adds a fps display
  //   debug: un-hides the debug html elements
  //   numConsoleLines: number of lines to show for the debug console.
  //
  // You can add text to the debug console with
  // `GameSupport.log(msg)` or `GameSupport.error(msg)`
  // which are no-ops if `debug` is false.
  //
  // Similarly you can display status with
  // `GameSupport.setStatus("foo\nbar");`
  var init = function(server, options) {
    var showConnected = function() {
      $('hft-disconnected').style.display = "none";
    }

    var showDisconnected = function() {
      $('hft-disconnected').style.display = "block";
    }

    server.addEventListener('connect', showConnected);
    server.addEventListener('disconnect', showDisconnected);

    if (options.showFPS) {
      stats = new Stats();
      stats.setMode(0); // 0: fps, 1: ms

      // Align top-left
      var s = stats.domElement.style;
      s.position = 'absolute';
      s.right = '0px';
      s.top = '0px';

      document.body.appendChild(stats.domElement);
    }

    if (options.debug) {
      statusNode = document.createTextNode("");
      $("hft-status").appendChild(statusNode);
      var debugCSS = Misc.findCSSStyleRule("#hft-debug");
      debugCSS.style.display = "block";

      logger = new Logger.HTMLLogger($("hft-console"), options.numConsoleLines);
    }
  };

  // globals that are checked/effected
  //
  //   elapsedTime: time elapsed in seconds since last frame
  //   frameCount:  count of frames
  //   haveServer:  if false will pause when it doens't have the focus.
  //   pauseOnBlur: if true will pause when it doesn't have the focus.
  //   step:        if true will step one tick for each mouse click
  //
  var run = function(globals, fn) {
    var clock = new GameClock();

    var requestId;
    var loop = function() {
      stats.begin();

      globals.elapsedTime = clock.getElapsedTime();
      ++globals.frameCount;

      var result = fn();

      stats.end();

      requestId = result ? undefined : requestAnimationFrame(loop);
    };

    var start = function() {
      if (requestId === undefined) {
        loop();
      }
    };

    var stop = function() {
      if (requestId !== undefined) {
        cancelAnimationFrame(requestId);
        requestId = undefined;
      }
    };

    // The only reason this is here is because when you
    // open devtools in Chrome the game blurs. As the
    // devtools is expanded and contracted, if the game
    // is not running it won't respond to being resized.
    var updateOnce = function() {
      if (requestId === undefined) {
        start();
        stop();
      }
    };

    // This is here because running a game at 60fps
    // in my MacBook Pro switches the discrete GPU
    // and uses a ton of CPU as well, eating up my
    // battery. So, if I'm running locally I make
    // the game pause on blur which means effectively
    // it will stop anytime I switch back to my editor.
    if (!globals.haveServer || globals.pauseOnBlur) {
      window.addEventListener('blur', stop, false);
      window.addEventListener('focus', start, false);
      window.addEventListener('resize', updateOnce, false);
    }

    if (globals.step) {
      updateOnce();
      window.addEventListener('click', updateOnce, false);
    } else {
      start();
    }
  };

  var setStatus = function(str) {
    if (statusNode) {
      statusNode.nodeValue = str;
    }
  };

  var log = function(str) {
    logger.log(str);
  };

  var error = function(str) {
    logger.error(str);
  };

  return {
    init: init,
    run: run,
    log: log,
    error: error,
    setStatus: setStatus,
  };
});

<commit_msg>update gamesupport to not disconnect if haveServer is false<commit_after>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

define([
    './3rdparty/stats/stats.min',
    './gameclock',
    './logger',
    './misc',
  ], function(
    StatsJS,
    GameClock,
    Logger,
    Misc) {

  var $ = function(id) {
    return document.getElementById(id);
  };

  var stats = {
    begin: function() { },
    end: function() { },
  };

  var statusNode;
  var logger = new Logger.NullLogger();

  // options:
  //   showFPS: true adds a fps display
  //   debug: un-hides the debug html elements
  //   numConsoleLines: number of lines to show for the debug console.
  //
  // You can add text to the debug console with
  // `GameSupport.log(msg)` or `GameSupport.error(msg)`
  // which are no-ops if `debug` is false.
  //
  // Similarly you can display status with
  // `GameSupport.setStatus("foo\nbar");`
  var init = function(server, options) {
    var showConnected = function() {
      $('hft-disconnected').style.display = "none";
    }

    var showDisconnected = function() {
      $('hft-disconnected').style.display = "block";
    }

    if (options.haveServer !== false) {
      server.addEventListener('connect', showConnected);
      server.addEventListener('disconnect', showDisconnected);
    }

    if (options.showFPS) {
      stats = new Stats();
      stats.setMode(0); // 0: fps, 1: ms

      // Align top-left
      var s = stats.domElement.style;
      s.position = 'absolute';
      s.right = '0px';
      s.top = '0px';

      document.body.appendChild(stats.domElement);
    }

    if (options.debug) {
      statusNode = document.createTextNode("");
      $("hft-status").appendChild(statusNode);
      var debugCSS = Misc.findCSSStyleRule("#hft-debug");
      debugCSS.style.display = "block";

      logger = new Logger.HTMLLogger($("hft-console"), options.numConsoleLines);
    }
  };

  // globals that are checked/effected
  //
  //   elapsedTime: time elapsed in seconds since last frame
  //   frameCount:  count of frames
  //   haveServer:  if false will pause when it doens't have the focus.
  //   pauseOnBlur: if true will pause when it doesn't have the focus.
  //   step:        if true will step one tick for each mouse click
  //
  var run = function(globals, fn) {
    var clock = new GameClock();

    var requestId;
    var loop = function() {
      stats.begin();

      globals.elapsedTime = clock.getElapsedTime();
      ++globals.frameCount;

      var result = fn();

      stats.end();

      requestId = result ? undefined : requestAnimationFrame(loop);
    };

    var start = function() {
      if (requestId === undefined) {
        loop();
      }
    };

    var stop = function() {
      if (requestId !== undefined) {
        cancelAnimationFrame(requestId);
        requestId = undefined;
      }
    };

    // The only reason this is here is because when you
    // open devtools in Chrome the game blurs. As the
    // devtools is expanded and contracted, if the game
    // is not running it won't respond to being resized.
    var updateOnce = function() {
      if (requestId === undefined) {
        start();
        stop();
      }
    };

    // This is here because running a game at 60fps
    // in my MacBook Pro switches the discrete GPU
    // and uses a ton of CPU as well, eating up my
    // battery. So, if I'm running locally I make
    // the game pause on blur which means effectively
    // it will stop anytime I switch back to my editor.
    if (!globals.haveServer || globals.pauseOnBlur) {
      window.addEventListener('blur', stop, false);
      window.addEventListener('focus', start, false);
      window.addEventListener('resize', updateOnce, false);
    }

    if (globals.step) {
      updateOnce();
      window.addEventListener('click', updateOnce, false);
    } else {
      start();
    }
  };

  var setStatus = function(str) {
    if (statusNode) {
      statusNode.nodeValue = str;
    }
  };

  var log = function(str) {
    logger.log(str);
  };

  var error = function(str) {
    logger.error(str);
  };

  return {
    init: init,
    run: run,
    log: log,
    error: error,
    setStatus: setStatus,
  };
});

<|endoftext|>


<commit_before>
var MapObject =  {
    map: null,
    home_marker:null,
    markerClusterer: null,
    markers_array: [],
    infoWindow: new google.maps.InfoWindow(),
    geocoder: new google.maps.Geocoder(),//地址解析对象
    map_share_html:null,	//新增一个marker的初始化html
    visibleInfoWindow: null,
    map_options: {
        id: 'mapCanvas',
        type: "ROADMAP",        // HYBRID, ROADMAP, SATELLITE, TERRAIN
        center_latitude : 34.524661, //默认将中心定于中国
        center_longitude : 103.886719,
        zoom : 4,
        auto_adjust : false,    //adjust the map to the markers if set to true
        auto_zoom: true,        //zoom given by auto-adjust
        bounds: []              //adjust map to these limits. Should be [{"lat": , "lng": }]
    },
    temp_marker:null,
    temp_infowindow: new google.maps.InfoWindow(),
    markers : new Map(),
    info_windows: new Map(), //窗体对象map
    info_windows_html: new Map(),		//窗体的html map
    bounds_object: null,				//contains current bounds from markers, polylines etc...
    polygons: [], 						  //contains raw data, array of arrays (first element could be a hash containing options)
    polylines: [], 						  //contains raw data, array of arrays (first element could be a hash containing options)
    circles: [],
    //初始化map
    initialize: function (id) {
        var myOptions = {
            zoom: this.map_options.zoom,
            draggableCursor: "default",
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            center: new google.maps.LatLng(this.map_options.center_latitude, this.map_options.center_longitude)
        };
        this.map = new google.maps.Map(
            document.getElementById(this.map_options.id),
            myOptions);
        //        this.initControl() ;

        //        this.infoWindow = new google.maps.InfoWindow();
        this.init_marker_from_data("my_home",id);
    //        this.init_marker_from_data("firend_postition");
    //	this.init_marker_from_data("schedule");

    },

    //控件初始化
    initControl: function () {

    },

    //添加marker 监听
    add_marker_listen:function (){
        google.maps.event.addListenerOnce(MapObject.map, 'click', function(event) {
            //alert(2)
            MapObject.add_marker(MapObject.map,event.latLng);
        });
         google.maps.event.addListener(MapObject.map, 'mousemove', function(event) {
           MapObject.map.setOptions({ draggableCursor: 'crosshair' });
      });
               google.maps.event.addListener(MapObject.map, 'rightclick', function(event) {
           clear_marker_listen();
      });
    },

    //删除marker 监听
    clear_marker_listen: function (){
        google.maps.event.clearListeners(MapObject.map, 'click');
    },

    //添加一个marker
    add_marker:function (map,initialLocation){
        //alert(1)
        this.temp_marker = new google.maps.Marker({
            map:map,
            draggable:true,
            animation: google.maps.Animation.DROP,
            position: initialLocation
        });

        MapObject.geocoder.geocode({
            latLng: initialLocation
        }, function(responses){
            MapObject.new_marker_Function(responses)
        });
        google.maps.event.clearListeners(MapObject.map, 'mousemove')
         MapObject.map.setOptions({ draggableCursor: 'default' });

    },
    //new marker请求地址解析的回调函数
    new_marker_Function:function (responses) {
        string = MapObject.split_responses_address(responses);

        postition_html = "

当前位置："+string +"
"
        MapObject.temp_infowindow.setContent(postition_html + MapObject.map_share_html+"
")
        MapObject.temp_infowindow.open(MapObject.map,MapObject.temp_marker);
         google.maps.event.addListener(MapObject.temp_infowindow, 'domready', function(){
        $("#place_full_address").attr("value",string);
        $("#place_place_latitude").attr("value",MapObject.temp_marker.getPosition().lat());
        $("#place_place_longitude").attr("value",MapObject.temp_marker.getPosition().lng());
         })

        google.maps.event.addListenerOnce(MapObject.temp_infowindow, 'closeclick', function(){
            MapObject.temp_marker.setMap(null)
        });
        google.maps.event.addListener(MapObject.temp_marker, 'dragend', function(){
            MapObject.geocoder.geocode({
                latLng: MapObject.temp_marker.getPosition()
            }, function(responses){
                string = MapObject.split_responses_address(responses);
                //alert(string)
                $("#postition_text").html("当前位置："+string );
                $("#place_full_address").attr("value",string)
                $("#place_place_latitude").attr("value",MapObject.temp_marker.getPosition().lat())
                $("#place_place_longitude").attr("value",MapObject.temp_marker.getPosition().lng())
            });
        });

    },

    split_responses_address:function(responses){
        if (responses && responses.length > 0) {
            //MapObject.updateMarkerAddress(marker_id,responses);
            string = '';
            for(i = responses[0].address_components.length-1;i>=0;i--){
                string += (responses[0].address_components[i].long_name+ "|")
            }
            return string;
        }else{
            return //"找不到该地址"
        }
    },

    //跳动动画效果
    toggleBounce: function (marker) {

        if (marker.getAnimation() != null) {
            marker.setAnimation(null);
        } else {
            marker.setAnimation(google.maps.Animation.BOUNCE);
        }
    },

    //定位
    set_current_position: function (){
        // Try W3C Geolocation (Preferred)
        if(navigator.geolocation) {
            browserSupportFlag = true;
            navigator.geolocation.getCurrentPosition(function(position) {
                initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
                map.setCenter(initialLocation);
                add_marker(initialLocation)
            }, function() {
                handleNoGeolocation(browserSupportFlag);
            },{
                enableHighAccuracy:true,
                maximumAge:30000,
                timeout:3000
            });
        // Try Google Gears Geolocation
        } else if (google.gears) {
            browserSupportFlag = true;
            var geo = google.gears.factory.create('beta.geolocation');
            geo.getCurrentPosition(function(position) {
                initialLocation = new google.maps.LatLng(position.latitude,position.longitude);
                map.setCenter(initialLocation);
                add_marker(initialLocation)
            }, function() {
                handleNoGeoLocation(browserSupportFlag);
            });
        // Browser do not support Geolocation
        } else {
            browserSupportFlag = false;
            handleNoGeolocation(browserSupportFlag);
        }
    },

    handleNoGeolocation: function (errorFlag) {
        if (errorFlag == true) {
            alert("定位服务失败，我们将您定位在中国，请您手动选择您的位置");
            initialLocation = newyork;
        } else {
            alert("您拒绝定位服务，我们将您定位在中国，请您手动选择您的位置");
            initialLocation = siberia;
        }
        map.setCenter(initialLocation);
        map.setZoom(4);
    },

    //提交marker信息到后台
    submit_marker: function(type){
        var markerLatLng = MapObject.temp_marker.getPosition()
        alert(type)
        MapObject.geocoder.geocode({
            latLng: markerLatLng
        },
        function(responses) {
            if (responses && responses.length > 0) {
                string = '';
                for(i = responses[0].address_components.length-1;i>=0;i--){
                    string += (responses[0].address_components[i].long_name+ "|")
                }
                if(type == 'notes'){
                    $.ajax({
                        type: "POST",
                        url: "/notes",
                        data: "marker[geocode_position]="+ string +"&note[body]="+ $("#note_body").val()+ "&ajax=true"+ "&marker[marker_latitude]=" +markerLatLng.lat()+ "&marker[marker_longitude]=" +markerLatLng.lng(),
                        success: function(message){
                        }
                    });
                }

                if(type == 'place'){
//                    $.ajax({
//                        type: "POST",
//                        url: "/places",
//                        data: "marker[geocode_position]="+ $("#place_full_address") .attr("value")+
//                               "&marker[marker_latitude]=" + $("#place_place_latitude").attr("value")+
//                               "&marker[marker_longitude]=" + $("#place_place_longitude").attr("value")+
//                                "&place[place_name]="+ $("#place_place_name").val()+
//                                "&place[full_address]="+ $("#place_full_address").val()+
//                                "&place[place_description]="+ $("#place_place_description").val()+"&ajax=true",
//                        success: function(message){
//                        }
//                    });

                    $("#place_full_address").attr("value",string)
		    $("#place_place_latitude").attr("value",markerLatLng.lat())
		    $("#place_place_longitude").attr("value",markerLatLng.lng())

                }
            }
        }
        );

    },

    //实例化一个窗体对象，实例化所需的html 从 map 中获取
    new_info_window:function(marker_id){
        //alert(marker_id);
        //alert(MapObject.markers.get(marker_id))
        infowindow = null;
        //alert(MapObject.info_windows.get(marker_id))
        if (!MapObject.info_windows.get(marker_id)){
            infowindow = new google.maps.InfoWindow({
                content: MapObject.info_windows_html.get(marker_id),
                disableAutoPan:false
            });
            MapObject.info_windows.put(marker_id,infowindow)
            //alert(MapObject.markers.get(marker_id))
            infowindow.open(MapObject.map,MapObject.markers.get(marker_id))
            google.maps.event.addListener(infowindow, 'closeclick', function(){
                //alert(marker_id)
                //alert(MapObject.info_windows.get(marker_id));
                MapObject.info_windows.remove(marker_id);
            });
        }
        return infowindow;

    },

    //实例化一个窗体对象，实例化所需的html直接传入
    new_info_window_html:function(html){
        infowindow = new google.maps.InfoWindow({
            content: html,
            disableAutoPan:false
        });
        return infowindow;

    },

    //从后台获取数据后初始化marker
    init_marker_from_data:function(type,people_id){
        id_string = ''
        if(people_id !=null && people_id != ''){
            id_string +=("&people_id="+people_id)
        }
        $.ajax({
            type: "GET",
            url: "/markers?type="+type+id_string,
            success: function(){
            }
        });
    },

    marker_del:function(marker_id){
        //alert(MapObject.markers.get(marker_id))
        var bln=confirm("真的要删除该标记")
        if (bln==true)
        {
            $.ajax({
                type: "DELETE",
                data: "id="+marker_id,
                url: "/markers/"+marker_id,
                success: function(message){
                    if(message.success){
                        MapObject.infoWindow.close();
                        MapObject.markerClusterer.removeMarker(MapObject.markers.get(marker_id));
                    }else{
                        alert("网络延迟，请重试")
                    }

                }
            });

        }

    },
    marker_move: function(marker_id){
        //alert(marker_id)
        marker = MapObject.markers.get(marker_id);
        //alert(marker);
        marker.setDraggable(true);
        marker.setAnimation(google.maps.Animation.BOUNCE);
        google.maps.event.addListenerOnce(marker, 'dragend', function(){
            marker.setDraggable(false);
            markerLatLng = marker.getPosition();
            //alert(markerLatLng);
            MapObject.infoWindow.close();
            google.maps.event.clearListeners(marker, 'click')
            MapObject.geocodePosition(marker_id,markerLatLng)
        });
    } ,

    updata_data_marker: function(data,id){
        $.ajax({
            type: "PUT",
            data: data,
            url: "/markers/"+id,
            success: function(message){

            }
        });
    },

    //反向地址解析方法
    geocodePosition:function (marker_id,markerLatLng) {
        MapObject.geocoder.geocode({
            latLng: markerLatLng
        }, function(responses) {
            if (responses && responses.length > 0) {

                //MapObject.updateMarkerAddress(marker_id,responses);
                string = '';
                for(i = responses[0].address_components.length-1;i>=0;i--){
                    string += (responses[0].address_components[i].long_name+ "|")
                }
                //alert("1 "+ string)
                data = "marker[id]="+marker_id+ "&marker[geocode_position]="+ string +"&marker[marker_latitude]=" +markerLatLng.lat()+ "&marker[marker_longitude]=" +markerLatLng.lng(),

                MapObject.updata_data_marker(data,marker_id)
            } else {
                alert("none")
            }
        });
    },

    //地址解析方法
    re_geocodePosition:function (address,icon,info_htm,is_home) {
        MapObject.geocoder.geocode({
            address: address
        }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                //alert(results[0].geometry.location)
                MapObject.geocodePosition_marker(results[0].geometry.location,icon,info_htm,is_home)
            } else {
                alert("找不到这个地方");
            }
        });
    },

    geocodePosition_marker:function(latLng,icon,info_htm,is_home){
        marker = new google.maps.Marker({
            map: MapObject.map,
            draggable: false,
            animation: google.maps.Animation.DROP,
            icon: icon,
            position: latLng
        });
        //alert(info_htm)
        if (info_htm!= null){
            var fn = MapObject.markerClickFunction(info_htm, marker);
            google.maps.event.addListener(marker, 'click', fn);
        }
        if(is_home){
            MapObject.home_marker = marker;

            return;
        }else{
            MapObject.markerClusterer.addMarker(marker,true);
        }

    //alert(results[0].geometry.location)
    },

    //根据google返回的数据更新info_window
    updateMarkerAddress:function(marker_id,responses){
        marker_address = $("#stream_item_"+marker_id+" .marker_address")
        for(i = responses[0].address_components.length-1;i>=0;i--){
            string = responses[0].address_components[i].long_name
            //alert(string)
            $(""+ string +"").appendTo(marker_address)
        }
    },

    markerClickFunction:function(html, marker) {
        return function(e) {
            e.cancelBubble = true;
            e.returnValue = false;
            if (e.stopPropagation) {
                e.stopPropagation();
                e.preventDefault();
            }
            //alert(marker)
            MapObject.infoWindow.setContent(html);
            //MapObject.infoWindow.setPosition(latlng);
            MapObject.infoWindow.open(MapObject.map,marker);
        };
    }

}

function obj2str(o){
    var r = [];
    if(typeof o == "string" || o == null) {
        return o;
    }
    if(typeof o == "object"){
        if(!o.sort){
            r[0]="{"
            for(var i in o){
                r[r.length]=i;
                r[r.length]=":";
                r[r.length]=obj2str(o[i]);
                r[r.length]=",";
            }
            r[r.length-1]="}"
        }else{
            r[0]="["
            for(var i =0;i<o.length;i++){
                r[r.length]=obj2str(o[i]);
                r[r.length]=",";
            }
            r[r.length-1]="]"
        }
        return r.join("");
    }
    return o.toString();
}

<commit_msg>some change<commit_after>
var MapObject =  {
    map: null,
    home_marker:null,
    markerClusterer: null,
    markers_array: [],
    infoWindow: new google.maps.InfoWindow(),
    geocoder: new google.maps.Geocoder(),//地址解析对象
    map_share_html:null,	//新增一个marker的初始化html
    visibleInfoWindow: null,
    map_options: {
        id: 'mapCanvas',
        type: "ROADMAP",        // HYBRID, ROADMAP, SATELLITE, TERRAIN
        center_latitude : 34.524661, //默认将中心定于中国
        center_longitude : 103.886719,
        zoom : 4,
        auto_adjust : false,    //adjust the map to the markers if set to true
        auto_zoom: true,        //zoom given by auto-adjust
        bounds: []              //adjust map to these limits. Should be [{"lat": , "lng": }]
    },
    temp_marker:null,
    temp_infowindow: new google.maps.InfoWindow(),
    markers : new Map(),
    info_windows: new Map(), //窗体对象map
    info_windows_html: new Map(),		//窗体的html map
    bounds_object: null,				//contains current bounds from markers, polylines etc...
    polygons: [], 						  //contains raw data, array of arrays (first element could be a hash containing options)
    polylines: [], 						  //contains raw data, array of arrays (first element could be a hash containing options)
    circles: [],
    //初始化map
    initialize: function (id) {
        var myOptions = {
            zoom: this.map_options.zoom,
            draggableCursor: "default",
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            center: new google.maps.LatLng(this.map_options.center_latitude, this.map_options.center_longitude)
        };
        this.map = new google.maps.Map(
            document.getElementById(this.map_options.id),
            myOptions);
        //        this.initControl() ;

        //        this.infoWindow = new google.maps.InfoWindow();
        this.init_marker_from_data("my_home",id);
    //        this.init_marker_from_data("firend_postition");
    //	this.init_marker_from_data("schedule");

    },

    //控件初始化
    initControl: function () {

    },

    //添加marker 监听
    add_marker_listen:function (){
        google.maps.event.addListenerOnce(MapObject.map, 'click', function(event) {
            //alert(2)
            MapObject.add_marker(MapObject.map,event.latLng);
        });
         google.maps.event.addListener(MapObject.map, 'mousemove', function(event) {
           MapObject.map.setOptions({ draggableCursor: 'crosshair' });
      });
               google.maps.event.addListener(MapObject.map, 'rightclick', function(event) {
           clear_marker_listen();
      });
    },

    //删除marker 监听
    clear_marker_listen: function (){
        google.maps.event.clearListeners(MapObject.map, 'click');
    },

    //添加一个marker
    add_marker:function (map,initialLocation){
        //alert(1)
        this.temp_marker = new google.maps.Marker({
            map:map,
            draggable:true,
            animation: google.maps.Animation.DROP,
            position: initialLocation
        });

        MapObject.geocoder.geocode({
            latLng: initialLocation
        }, function(responses){
            MapObject.new_marker_Function(responses)
        });
        google.maps.event.clearListeners(MapObject.map, 'mousemove')
         MapObject.map.setOptions({ draggableCursor: 'default' });

    },
    //new marker请求地址解析的回调函数
    new_marker_Function:function (responses) {
        string = MapObject.split_responses_address(responses);

        postition_html = "

当前位置："+string +"
"
        MapObject.temp_infowindow.setContent(postition_html + MapObject.map_share_html+"
")
        MapObject.temp_infowindow.open(MapObject.map,MapObject.temp_marker);
         google.maps.event.addListener(MapObject.temp_infowindow, 'domready', function(){
        $("#place_full_address").attr("value",string);
        $("#place_place_latitude").attr("value",MapObject.temp_marker.getPosition().lat());
        $("#place_place_longitude").attr("value",MapObject.temp_marker.getPosition().lng());
         })

        google.maps.event.addListenerOnce(MapObject.temp_infowindow, 'closeclick', function(){
            MapObject.temp_marker.setMap(null)
        });
        google.maps.event.addListener(MapObject.temp_marker, 'dragend', function(){
            MapObject.geocoder.geocode({
                latLng: MapObject.temp_marker.getPosition()
            }, function(responses){
                string = MapObject.split_responses_address(responses);
                //alert(string)
                $("#postition_text").html("当前位置："+string );
                $("#place_full_address").attr("value",string)
                $("#place_place_latitude").attr("value",MapObject.temp_marker.getPosition().lat())
                $("#place_place_longitude").attr("value",MapObject.temp_marker.getPosition().lng())
            });
        });

    },

    split_responses_address:function(responses){
        if (responses && responses.length > 0) {
            //MapObject.updateMarkerAddress(marker_id,responses);
            string = '';
            for(i = responses[0].address_components.length-1;i>=0;i--){
                string += (responses[0].address_components[i].long_name+ "|")
            }
            return string;
        }else{
            return //"找不到该地址"
        }
    },

    //跳动动画效果
    toggleBounce: function (marker) {

        if (marker.getAnimation() != null) {
            marker.setAnimation(null);
        } else {
            marker.setAnimation(google.maps.Animation.BOUNCE);
        }
    },

    //定位
    set_current_position: function (){
        // Try W3C Geolocation (Preferred)
        if(navigator.geolocation) {
            browserSupportFlag = true;
            navigator.geolocation.getCurrentPosition(function(position) {
                initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
                map.setCenter(initialLocation);
                add_marker(initialLocation)
            }, function() {
                handleNoGeolocation(browserSupportFlag);
            },{
                enableHighAccuracy:true,
                maximumAge:30000,
                timeout:3000
            });
        // Try Google Gears Geolocation
        } else if (google.gears) {
            browserSupportFlag = true;
            var geo = google.gears.factory.create('beta.geolocation');
            geo.getCurrentPosition(function(position) {
                initialLocation = new google.maps.LatLng(position.latitude,position.longitude);
                map.setCenter(initialLocation);
                add_marker(initialLocation)
            }, function() {
                handleNoGeoLocation(browserSupportFlag);
            });
        // Browser do not support Geolocation
        } else {
            browserSupportFlag = false;
            handleNoGeolocation(browserSupportFlag);
        }
    },

    handleNoGeolocation: function (errorFlag) {
        if (errorFlag == true) {
            alert("定位服务失败，我们将您定位在中国，请您手动选择您的位置");
            initialLocation = newyork;
        } else {
            alert("您拒绝定位服务，我们将您定位在中国，请您手动选择您的位置");
            initialLocation = siberia;
        }
        map.setCenter(initialLocation);
        map.setZoom(4);
    },

    //提交marker信息到后台
    submit_marker: function(type){
        var markerLatLng = MapObject.temp_marker.getPosition()
        alert(type)
        MapObject.geocoder.geocode({
            latLng: markerLatLng
        },
        function(responses) {
            if (responses && responses.length > 0) {
                string = '';
                for(i = responses[0].address_components.length-1;i>=0;i--){
                    string += (responses[0].address_components[i].long_name+ "|")
                }
                if(type == 'notes'){
                    $.ajax({
                        type: "POST",
                        url: "/notes",
                        data: "marker[geocode_position]="+ string +"&note[body]="+ $("#note_body").val()+ "&ajax=true"+ "&marker[marker_latitude]=" +markerLatLng.lat()+ "&marker[marker_longitude]=" +markerLatLng.lng(),
                        success: function(message){
                        }
                    });
                }

                if(type == 'place'){
//                    $.ajax({
//                        type: "POST",
//                        url: "/places",
//                        data: "marker[geocode_position]="+ $("#place_full_address") .attr("value")+
//                               "&marker[marker_latitude]=" + $("#place_place_latitude").attr("value")+
//                               "&marker[marker_longitude]=" + $("#place_place_longitude").attr("value")+
//                                "&place[place_name]="+ $("#place_place_name").val()+
//                                "&place[full_address]="+ $("#place_full_address").val()+
//                                "&place[place_description]="+ $("#place_place_description").val()+"&ajax=true",
//                        success: function(message){
//                        }
//                    });

                    $("#place_full_address").attr("value",string)
		    $("#place_place_latitude").attr("value",markerLatLng.lat())
		    $("#place_place_longitude").attr("value",markerLatLng.lng())

                }
            }
        }
        );

    },

    //实例化一个窗体对象，实例化所需的html 从 map 中获取
    new_info_window:function(marker_id){
        //alert(marker_id);
        //alert(MapObject.markers.get(marker_id))
        infowindow = null;
        //alert(MapObject.info_windows.get(marker_id))
        if (!MapObject.info_windows.get(marker_id)){
            infowindow = new google.maps.InfoWindow({
                content: MapObject.info_windows_html.get(marker_id),
                disableAutoPan:false
            });
            MapObject.info_windows.put(marker_id,infowindow)
            //alert(MapObject.markers.get(marker_id))
            infowindow.open(MapObject.map,MapObject.markers.get(marker_id))
            google.maps.event.addListener(infowindow, 'closeclick', function(){
                //alert(marker_id)
                //alert(MapObject.info_windows.get(marker_id));
                MapObject.info_windows.remove(marker_id);
            });
        }
        return infowindow;

    },

    //实例化一个窗体对象，实例化所需的html直接传入
    new_info_window_html:function(html){
        infowindow = new google.maps.InfoWindow({
            content: html,
            disableAutoPan:false
        });
        return infowindow;

    },

    //从后台获取数据后初始化marker
    init_marker_from_data:function(type,people_id){
        id_string = ''
        if(people_id !=null && people_id != ''){
            id_string +=("&people_id="+people_id)
        }
        $.ajax({
            type: "GET",
            url: "/markers?type="+type+id_string,
            success: function(){
            }
        });
    },

    marker_del:function(marker_id){
        //alert(MapObject.markers.get(marker_id))
        var bln=confirm("真的要删除该标记")
        if (bln==true)
        {
            $.ajax({
                type: "DELETE",
                data: "id="+marker_id,
                url: "/markers/"+marker_id,
                success: function(message){
                    if(message.success){
                        MapObject.infoWindow.close();
                        MapObject.markerClusterer.removeMarker(MapObject.markers.get(marker_id));
                    }else{
                        alert("网络延迟，请重试")
                    }

                }
            });

        }

    },
    marker_move: function(marker_id){
        //alert(marker_id)
        marker = MapObject.markers.get(marker_id);
        //alert(marker);
        marker.setDraggable(true);
        marker.setAnimation(google.maps.Animation.BOUNCE);
        google.maps.event.addListenerOnce(marker, 'dragend', function(){
            marker.setDraggable(false);
            markerLatLng = marker.getPosition();
            //alert(markerLatLng);
            MapObject.infoWindow.close();
            google.maps.event.clearListeners(marker, 'click')
            MapObject.geocodePosition(marker_id,markerLatLng)
        });
    } ,

    updata_data_marker: function(data,id){
        $.ajax({
            type: "PUT",
            data: data,
            url: "/markers/"+id,
            success: function(message){

            }
        });
    },

    //反向地址解析方法
    geocodePosition:function (marker_id,markerLatLng) {
        MapObject.geocoder.geocode({
            latLng: markerLatLng
        }, function(responses) {
            if (responses && responses.length > 0) {

                //MapObject.updateMarkerAddress(marker_id,responses);
                string = '';
                for(i = responses[0].address_components.length-1;i>=0;i--){
                    string += (responses[0].address_components[i].long_name+ "|")
                }
                //alert("1 "+ string)
                data = "marker[id]="+marker_id+ "&marker[geocode_position]="+ string +"&marker[marker_latitude]=" +markerLatLng.lat()+ "&marker[marker_longitude]=" +markerLatLng.lng(),

                MapObject.updata_data_marker(data,marker_id)
            } else {
                alert("none")
            }
        });
    },

    //地址解析方法
    re_geocodePosition:function (address,icon,info_htm,is_home) {
        MapObject.geocoder.geocode({
            address: address
        }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                //alert(results[0].geometry.location)
                MapObject.geocodePosition_marker(results[0].geometry.location,icon,info_htm,is_home)
            } else {
               // alert("找不到这个地方");
            }
        });
    },

    geocodePosition_marker:function(latLng,icon,info_htm,is_home){
        marker = new google.maps.Marker({
            map: MapObject.map,
            draggable: false,
            animation: google.maps.Animation.DROP,
            icon: icon,
            position: latLng
        });
        //alert(info_htm)
        if (info_htm!= null){
            var fn = MapObject.markerClickFunction(info_htm, marker);
            google.maps.event.addListener(marker, 'click', fn);
        }
        if(is_home){
            MapObject.home_marker = marker;

            return;
        }else{
            MapObject.markerClusterer.addMarker(marker,true);
        }

    //alert(results[0].geometry.location)
    },

    //根据google返回的数据更新info_window
    updateMarkerAddress:function(marker_id,responses){
        marker_address = $("#stream_item_"+marker_id+" .marker_address")
        for(i = responses[0].address_components.length-1;i>=0;i--){
            string = responses[0].address_components[i].long_name
            //alert(string)
            $(""+ string +"").appendTo(marker_address)
        }
    },

    markerClickFunction:function(html, marker) {
        return function(e) {
            e.cancelBubble = true;
            e.returnValue = false;
            if (e.stopPropagation) {
                e.stopPropagation();
                e.preventDefault();
            }
            //alert(marker)
            MapObject.infoWindow.setContent(html);
            //MapObject.infoWindow.setPosition(latlng);
            MapObject.infoWindow.open(MapObject.map,marker);
        };
    }

}

function obj2str(o){
    var r = [];
    if(typeof o == "string" || o == null) {
        return o;
    }
    if(typeof o == "object"){
        if(!o.sort){
            r[0]="{"
            for(var i in o){
                r[r.length]=i;
                r[r.length]=":";
                r[r.length]=obj2str(o[i]);
                r[r.length]=",";
            }
            r[r.length-1]="}"
        }else{
            r[0]="["
            for(var i =0;i<o.length;i++){
                r[r.length]=obj2str(o[i]);
                r[r.length]=",";
            }
            r[r.length-1]="]"
        }
        return r.join("");
    }
    return o.toString();
}

<|endoftext|>


<commit_before>Navigation = (function() {

  function Navigation(args) {
    try {
      // Get the dropdown
      this.el = document.querySelector('[data-js="navigation"]');

      // Get child elements
      this.childs = this.el.querySelectorAll('ul > li');

      // Content
      this.contentArea = document.querySelector('[data-js="content"]');

      // Active category
      this.category_active = '';

      // Active element
      this.element_active = null;

      // Location object
      var _location = window.location,
          parameter_category = null;

      if (typeof _location.hash !== 'undefined') {
        parameter_category = _location.hash.split('#');
        parameter_category = parameter_category[1];
      }

      if (parameter_category != null) {

        // Save the active element
        this.element_active = document.querySelector('[data-js="navigation"] [data-category="'+parameter_category+'"]');

        // Add active attribute
        this.element_active.setAttribute('data-css', 'active');

        // Find elements to hide
        var elements = this.contentArea.querySelectorAll('[data-js="element"]:not([data-category="'+parameter_category+'"]');

        // Filter elements if the category is not blog (parent of all elements)
        if (parameter_category != "blog") {
          // Iterate over all elements and hide them
          for (var j = 0; j < elements.length; j++) {
            elements[j].setAttribute('data-css', 'hide');
          }
        }
      }

      // Iterate over all childs
      for (var i = 0; i < this.childs.length; i++) {

        // Listen to the click event
        this.childs[i].addEventListener('click', function(e) {
          // The clicked element
          var child = e.target;

          // Initial value for the active element
          this.element_active = this.element_active == null ? child : this.element_active;

          // Find the current category
          var category = child.getAttribute('data-category');

          // All elements
          var elements_all = this.contentArea.querySelectorAll('[data-js="element"]');

          // The currently selected category is not the same as the last active category
          // Turn the filter on
          if (category !== this.category_active && category !== null) {

            // Save the active category
            this.category_active = category;

            // Change the hash to the current category
            _location.hash = '#' + category;

            // Remove active attribute
            this.element_active.removeAttribute('data-css');

            // There are no elements
            if (elements_all.length == 0) {

            // There are elements
            } else {
              // Prevent default action
              e.preventDefault();

              // Iterate over all elements and show them
              for (var j = 0; j < elements_all.length; j++) {
                elements_all[j].removeAttribute('data-css');
              }

              // Save the active element
              this.element_active = child;

              // Add active attribute
              this.element_active.setAttribute('data-css', 'active');

              // Find elements to hide
              var elements = this.contentArea.querySelectorAll('[data-js="element"]:not([data-category="'+category+'"]');

              // Filter elements if the category is not blog (parent of all elements)
              if (category != "blog") {
                // Iterate over all elements and hide them
                for (var j = 0; j < elements.length; j++) {
                  elements[j].setAttribute('data-css', 'hide');
                }
              } else {
                // Reset hash for home
                _location.hash = '';
              }

            } // There are elements

          // Turn the filter off
          } else {
            // Prevent default action
            e.preventDefault();

            // Iterate over all elements and show them
            if (category != "blog") {
              for (var j = 0; j < elements_all.length; j++) {
                elements_all[j].removeAttribute('data-css');
              }

              // Save the active category
              this.category_active = null;

              // Change the hash to the current category
              _location.hash = '';

              // Remove active attribute
              this.element_active.removeAttribute('data-css');
            }

          }

        }.bind(this), false);
      }

    } catch(e) {}
  };

  return Navigation;
})();<commit_msg>Fixed #7: There was a ")" missing in the querySelectorAll-statement and Safari is the only browser which does not execute this error. Chrome / FireFox does D:.<commit_after>Navigation = (function() {

  function Navigation(args) {
    try {
      // Get the dropdown
      this.el = document.querySelector('[data-js="navigation"]');

      // Get child elements
      this.childs = this.el.querySelectorAll('ul > li');

      // Content
      this.contentArea = document.querySelector('[data-js="content"]');

      // Active category
      this.category_active = '';

      // Active element
      this.element_active = null;

      // Location object
      var _location = window.location,
          parameter_category = null;

      if (typeof _location.hash !== 'undefined') {
        parameter_category = _location.hash.split('#');
        parameter_category = parameter_category[1];
      }

      if (parameter_category != null) {

        // Save the active element
        this.element_active = document.querySelector('[data-js="navigation"] [data-category="'+parameter_category+'"]');

        // Add active attribute
        this.element_active.setAttribute('data-css', 'active');

        // Find elements to hide
        var elements = this.contentArea.querySelectorAll('[data-js="element"]:not([data-category="'+parameter_category+'"])');

        // Filter elements if the category is not blog (parent of all elements)
        if (parameter_category != "blog") {
          // Iterate over all elements and hide them
          for (var j = 0; j < elements.length; j++) {
            elements[j].setAttribute('data-css', 'hide');
          }
        }
      }

      // Iterate over all childs
      for (var i = 0; i < this.childs.length; i++) {

        // Listen to the click event
        this.childs[i].addEventListener('click', function(e) {
          // The clicked element
          var child = e.target;

          // Initial value for the active element
          this.element_active = this.element_active == null ? child : this.element_active;

          // Find the current category
          var category = child.getAttribute('data-category');

          // All elements
          var elements_all = this.contentArea.querySelectorAll('[data-js="element"]');

          // The currently selected category is not the same as the last active category
          // Turn the filter on
          if (category !== this.category_active && category !== null) {

            // Save the active category
            this.category_active = category;

            // Change the hash to the current category
            _location.hash = '#' + category;

            // Remove active attribute
            this.element_active.removeAttribute('data-css');

            // There are no elements
            if (elements_all.length == 0) {

            // There are elements
            } else {
              // Prevent default action
              e.preventDefault();

              // Iterate over all elements and show them
              for (var j = 0; j < elements_all.length; j++) {
                elements_all[j].removeAttribute('data-css');
              }

              // Save the active element
              this.element_active = child;

              // Add active attribute
              this.element_active.setAttribute('data-css', 'active');

              // Find elements to hide
              var elements = this.contentArea.querySelectorAll('[data-js="element"]:not([data-category="'+category+'"])');

              // Filter elements if the category is not blog (parent of all elements)
              if (category != "blog") {
                // Iterate over all elements and hide them
                for (var j = 0; j < elements.length; j++) {
                  elements[j].setAttribute('data-css', 'hide');
                }
              } else {
                // Reset hash for home
                _location.hash = '';
              }

            } // There are elements

          // Turn the filter off
          } else {
            // Prevent default action
            e.preventDefault();

            // Iterate over all elements and show them
            if (category != "blog") {
              for (var j = 0; j < elements_all.length; j++) {
                elements_all[j].removeAttribute('data-css');
              }

              // Save the active category
              this.category_active = null;

              // Change the hash to the current category
              _location.hash = '';

              // Remove active attribute
              this.element_active.removeAttribute('data-css');
            }

          }

        }.bind(this), false);
      }

    } catch(e) {}
  };

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