social_stream 0.23.2 → 0.23.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/base/app/assets/javascripts/layouts.js +0 -1
  2. data/base/app/assets/javascripts/social_stream.comments.js +10 -3
  3. data/base/app/assets/javascripts/social_stream.search.js.erb +3 -1
  4. data/base/app/assets/javascripts/social_stream.wall.js.erb +8 -1
  5. data/base/app/assets/stylesheets/{activities.css.scss → activities.css.scss.erb} +1 -1
  6. data/base/app/models/relation.rb +4 -0
  7. data/base/app/models/tie.rb +5 -0
  8. data/base/app/views/cheesecake/_index.html.erb +2 -2
  9. data/base/app/views/layouts/_search.html.erb +2 -2
  10. data/base/app/views/posts/_new_activity_fields.erb +0 -6
  11. data/base/lib/generators/social_stream/base/templates/relations.yml +4 -4
  12. data/base/lib/social_stream/base/version.rb +1 -1
  13. data/base/lib/tasks/db/populate.rake +2 -2
  14. data/base/spec/dummy/config/relations.yml +4 -4
  15. data/base/vendor/assets/javascripts/jquery.watermark.js +563 -0
  16. data/documents/app/assets/javascripts/social_stream.audio.js.erb +25 -0
  17. data/documents/app/assets/javascripts/social_stream.repository.js.erb +27 -0
  18. data/documents/app/assets/javascripts/social_stream.video.js.erb +38 -0
  19. data/documents/app/assets/stylesheets/documents.css.scss +11 -14
  20. data/documents/app/views/audios/_audio.html.erb +0 -18
  21. data/documents/app/views/audios/_audio_processed.html.erb +35 -39
  22. data/documents/app/views/common_documents/_document_info.html.erb +2 -2
  23. data/documents/app/views/common_documents/_edit_form.html.erb +1 -1
  24. data/documents/app/views/common_documents/_headers.html.erb +1 -1
  25. data/documents/app/views/common_documents/_index.html.erb +3 -0
  26. data/documents/app/views/pictures/_picture.html.erb +3 -1
  27. data/documents/app/views/videos/_video.html.erb +0 -20
  28. data/documents/app/views/videos/_video_processed.html.erb +56 -43
  29. data/documents/config/locales/en.yml +1 -1
  30. data/documents/config/locales/es.yml +1 -1
  31. data/documents/lib/social_stream/documents/version.rb +1 -1
  32. data/documents/social_stream-documents.gemspec +1 -1
  33. data/documents/vendor/assets/javascripts/jquery.jplayer.js +87 -68
  34. data/documents/vendor/assets/swf/Jplayer.swf +0 -0
  35. data/events/app/assets/javascripts/social_stream-events.js +2 -0
  36. data/events/app/assets/javascripts/social_stream.calendar.js.erb +98 -0
  37. data/events/app/assets/javascripts/social_stream.event.js +17 -0
  38. data/events/app/assets/javascripts/social_stream.events.poster.js +1 -0
  39. data/events/app/assets/javascripts/{events.js.coffee → social_stream.events.tools.js.coffee} +0 -16
  40. data/events/app/assets/stylesheets/events.css.scss +33 -0
  41. data/events/app/controllers/events_controller.rb +19 -9
  42. data/events/app/views/events/_event.html.erb +5 -0
  43. data/events/app/views/events/_sidebar_calendar.html.erb +6 -28
  44. data/events/app/views/events/index.js.erb +3 -0
  45. data/events/app/views/rooms/_form.html.erb +1 -1
  46. data/events/app/views/rooms/create.js.erb +1 -1
  47. data/events/lib/social_stream/events/version.rb +1 -1
  48. data/events/social_stream-events.gemspec +1 -1
  49. data/lib/social_stream/version.rb +1 -1
  50. data/presence/app/assets/javascripts/jquery.ui.chatbox.sstreampresence.js +1 -1
  51. data/presence/app/assets/javascripts/presence.js.erb +16 -1
  52. data/presence/app/assets/javascripts/presence_XmppClient.js.erb +10 -3
  53. data/presence/app/assets/javascripts/presence_game.js.erb +284 -49
  54. data/presence/app/assets/javascripts/presence_game_comunication.js.erb +313 -0
  55. data/presence/app/assets/javascripts/presence_game_interface.js.erb +134 -0
  56. data/presence/app/assets/javascripts/presence_game_ter.js.erb +237 -188
  57. data/presence/app/assets/javascripts/presence_persistence.js +1 -1
  58. data/presence/app/assets/javascripts/presence_uiManager.js.erb +4 -2
  59. data/presence/app/assets/javascripts/presence_utilities.js +1 -1
  60. data/presence/app/assets/javascripts/presence_videochat.js.erb +2 -3
  61. data/presence/app/assets/javascripts/presence_windowManager.js +8 -1
  62. data/presence/app/assets/stylesheets/TresEnRaya.css +57 -0
  63. data/presence/app/assets/stylesheets/chat.css.scss +22 -1
  64. data/presence/app/views/chat/_index.html.erb +15 -18
  65. data/presence/config/locales/en.yml +14 -1
  66. data/presence/config/locales/es.yml +14 -1
  67. data/presence/lib/social_stream/presence/version.rb +1 -1
  68. data/presence/lib/tasks/presence/installer.rake +2 -2
  69. data/presence/social_stream-presence.gemspec +1 -1
  70. data/presence/vendor/assets/javascripts/jquery.gamequery-0.5.1.js +1164 -0
  71. data/social_stream.gemspec +4 -4
  72. data/spec/dummy/config/relations.yml +4 -4
  73. metadata +44 -34
  74. data/base/vendor/assets/javascripts/jquery.watermarkinput.js +0 -81
  75. data/documents/app/assets/javascripts/documents.js.erb +0 -71
@@ -1,6 +1,5 @@
1
1
  //= require hoverIntent
2
2
  //= require superfish
3
- //= require jquery.watermarkinput
4
3
  //
5
4
  $(function() {
6
5
  jQuery('ul.sf-menu').superfish({
@@ -1,3 +1,5 @@
1
+ //= require jquery.watermark
2
+ //
1
3
  //= require social_stream.timeline
2
4
  //= require social_stream.objects
3
5
 
@@ -15,7 +17,7 @@ SocialStream.Comments = (function(SS, $, undefined){
15
17
  $(".actor_name_new_comment").hide();
16
18
  $(".actor_logo_new_comment").hide();
17
19
 
18
- $(".input_new_comments").Watermark(I18n.t('comment.input'),"#666");
20
+ $(".input_new_comments").watermark(I18n.t('comment.input'),"#666");
19
21
 
20
22
  $(".input_new_comments")
21
23
  .change(function(){autoSize(this);})
@@ -40,8 +42,13 @@ SocialStream.Comments = (function(SS, $, undefined){
40
42
  //javascript for tocomment option
41
43
  $(".to_comment").click(function(){
42
44
  $(this).parents(".activity_content").find(".activity_new_comment").show();
43
- $(this).parents(".activity_content").find(".input_new_comments").click();
44
- $(this).parents(".activity_content").find(".input_new_comments").focus();
45
+ $(this)
46
+ .closest(".activity_content")
47
+ .find(".input_new_comments")
48
+ .click()
49
+ .focus()
50
+ .val("");
51
+
45
52
  return false;
46
53
  });
47
54
  }
@@ -1,3 +1,5 @@
1
+ //= require jquery.watermark
2
+
1
3
  SocialStream.Search = (function(SS, $, undefined){
2
4
  function init(){
3
5
  $.preloadImages ("<%= asset_path "mini-loading.gif" %>");
@@ -17,7 +19,7 @@ SocialStream.Search = (function(SS, $, undefined){
17
19
  return true;
18
20
  });
19
21
 
20
- $("#global_search_input").Watermark(I18n.t('search.write'));
22
+ $("#global_search_input").watermark(I18n.t('search.write'));
21
23
  }
22
24
 
23
25
  return {
@@ -1,5 +1,7 @@
1
- //= require social_stream.timeline
1
+ //= require jquery.watermark
2
2
  //
3
+ //= require social_stream.timeline
4
+
3
5
  SocialStream.Wall = (function(SS, $, undefined){
4
6
  var initCallbacks = [];
5
7
 
@@ -23,6 +25,10 @@ SocialStream.Wall = (function(SS, $, undefined){
23
25
  });
24
26
  }
25
27
 
28
+ var initPostWatermark = function(){
29
+ $("#input_activities").watermark(I18n.t('post.input'), "#666");
30
+ }
31
+
26
32
  var initFormSelector = function(){
27
33
  $('.activity_form_selector').click(function(){
28
34
  $('.activity_form_selector').removeClass('selected');
@@ -129,6 +135,7 @@ SocialStream.Wall = (function(SS, $, undefined){
129
135
 
130
136
  addInitCallback(initFirstForm);
131
137
  addInitCallback(initFormButton);
138
+ addInitCallback(initPostWatermark );
132
139
  addInitCallback(initFormSelector);
133
140
  addInitCallback(initSecuritySelect);
134
141
  addInitCallback(activateAntiRebounds);
@@ -8,7 +8,7 @@
8
8
 
9
9
  /* Fixes to tipsy, the plugin for tooltips */
10
10
 
11
- .tipsy{ background-image: url(../assets/tipsy.gif); }
11
+ .tipsy{ background-image: url(<%= asset_path "tipsy.gif" %>); }
12
12
  .tipsy-inner { background-color: $secondary-color; color: $sentence-color; }
13
13
 
14
14
  /****************** WALL - ACTIVITIES *********************/
@@ -63,6 +63,10 @@ class Relation < ActiveRecord::Base
63
63
  where(:sender_type => st, :receiver_type => rt)
64
64
  }
65
65
 
66
+ scope :positive, lambda {
67
+ where(:type => positive_names)
68
+ }
69
+
66
70
  before_create :initialize_sender_type
67
71
 
68
72
  class << self
@@ -48,6 +48,11 @@ class Tie < ActiveRecord::Base
48
48
  end
49
49
  }
50
50
 
51
+ scope :positive, lambda {
52
+ joins(:relation).
53
+ merge(Relation.positive)
54
+ }
55
+
51
56
  scope :with_permissions, lambda { |action, object|
52
57
  joins(:relation => :permissions).
53
58
  where('permissions.action' => action).
@@ -48,7 +48,7 @@
48
48
  $("#center_body").css("width","782px");
49
49
  $("#center_body").css("max-width","782px");
50
50
  $("#content").css("width","782px");
51
- $("#contacts_filter_input").Watermark("<%= escape_javascript(I18n.t('search.name')) %>");
51
+ $("#contacts_filter_input").watermark("<%= escape_javascript(I18n.t('search.name')) %>");
52
52
  //When clicking an unselected actor
53
53
  var unselected_actor_click = function(){
54
54
  var clone = $(this).clone();
@@ -138,4 +138,4 @@
138
138
  });
139
139
  });
140
140
  <%= render :partial => 'cheesecake' %>
141
- <% end %>
141
+ <% end %>
@@ -27,7 +27,7 @@ $(document).ready(function() {
27
27
  $("#header_search_display").hide();
28
28
  });
29
29
 
30
- $("#header_search_input").Watermark("<%= escape_javascript(I18n.t('search.name')) %>");
30
+ $("#header_search_input").watermark("<%= escape_javascript(I18n.t('search.name')) %>");
31
31
 
32
32
  $("#header_search_input").keyup(function() {
33
33
  var searchstring = $(this).val();
@@ -59,4 +59,4 @@ $(document).ready(function() {
59
59
  return false;
60
60
  });
61
61
  })
62
- <% end %>
62
+ <% end %>
@@ -1,7 +1 @@
1
1
  <%= f.text_field :text, :id => "input_activities", :size => 85 %>
2
-
3
- <%= javascript_tag do %>
4
- $(function() {
5
- $("#input_activities").Watermark("<%= I18n.t('post.input') %>","#666");
6
- });
7
- <% end %>
@@ -1,11 +1,11 @@
1
1
  # Default relations for Social Stream
2
2
  #
3
- # Define the default relations and permissions supported by your application
4
- # Though subjects can customize their own relations, these are the defaults
5
- # to start up
3
+ # Define the default relations and permissions offered by your application
4
+ # Though subjects (user, groups, etc.) can customize their own relations,
5
+ # these are the defaults to start up with
6
6
  #
7
7
  # Detailed information on permissions is available at:
8
- # http://rdoc.info/gems/social_stream/Permission
8
+ # http://rdoc.info/gems/social_stream-base/Permission
9
9
  #
10
10
  user:
11
11
  friend:
@@ -1,5 +1,5 @@
1
1
  module SocialStream
2
2
  module Base
3
- VERSION = "0.17.1".freeze
3
+ VERSION = "0.17.2".freeze
4
4
  end
5
5
  end
@@ -162,7 +162,7 @@ namespace :db do
162
162
  puts 'Post population'
163
163
  posts_start = Time.now
164
164
 
165
- SocialStream::Populate.power_law(Tie.all) do |t|
165
+ SocialStream::Populate.power_law(Tie.positive.all) do |t|
166
166
  updated = Time.at(rand(Time.now.to_i))
167
167
 
168
168
  author = t.sender
@@ -170,7 +170,7 @@ namespace :db do
170
170
  user_author = ( t.sender.subject_type == "User" ? t.sender : t.sender.user_author )
171
171
 
172
172
  p = Post.create :text =>
173
- "This post sActorhould be for #{ t.relation.name } of #{ t.sender.name }.\n#{ Forgery::LoremIpsum.paragraph(:random => true) }",
173
+ "This post should be for #{ t.relation.name } of #{ t.sender.name }.\n#{ Forgery::LoremIpsum.paragraph(:random => true) }",
174
174
  :created_at => Time.at(rand(updated.to_i)),
175
175
  :updated_at => updated,
176
176
  :author_id => author.id,
@@ -1,11 +1,11 @@
1
1
  # Default relations for Social Stream
2
2
  #
3
- # Define the default relations and permissions supported by your application
4
- # Though subjects can customize their own relations, these are the defaults
5
- # to start up
3
+ # Define the default relations and permissions offered by your application
4
+ # Though subjects (user, groups, etc.) can customize their own relations,
5
+ # these are the defaults to start up with
6
6
  #
7
7
  # Detailed information on permissions is available at:
8
- # http://rdoc.info/gems/social_stream/Permission
8
+ # http://rdoc.info/gems/social_stream-base/Permission
9
9
  #
10
10
  user:
11
11
  friend:
@@ -0,0 +1,563 @@
1
+ /*
2
+ Watermark plugin for jQuery
3
+ Version: 3.1.3
4
+ http://jquery-watermark.googlecode.com/
5
+
6
+ Copyright (c) 2009-2011 Todd Northrop
7
+ http://www.speednet.biz/
8
+
9
+ March 22, 2011
10
+
11
+ Requires: jQuery 1.2.3+
12
+
13
+ Dual licensed under the MIT or GPL Version 2 licenses.
14
+ See mit-license.txt and gpl2-license.txt in the project root for details.
15
+ ------------------------------------------------------*/
16
+
17
+ (function ($, window, undefined) {
18
+
19
+ var
20
+ // String constants for data names
21
+ dataFlag = "watermark",
22
+ dataClass = "watermarkClass",
23
+ dataFocus = "watermarkFocus",
24
+ dataFormSubmit = "watermarkSubmit",
25
+ dataMaxLen = "watermarkMaxLength",
26
+ dataPassword = "watermarkPassword",
27
+ dataText = "watermarkText",
28
+
29
+ // Copy of native jQuery regex use to strip return characters from element value
30
+ rreturn = /\r/g,
31
+
32
+ // Includes only elements with watermark defined
33
+ selWatermarkDefined = "input:data(" + dataFlag + "),textarea:data(" + dataFlag + ")",
34
+
35
+ // Includes only elements capable of having watermark
36
+ selWatermarkAble = "input:text,input:password,input[type=search],input:not([type]),textarea",
37
+
38
+ // triggerFns:
39
+ // Array of function names to look for in the global namespace.
40
+ // Any such functions found will be hijacked to trigger a call to
41
+ // hideAll() any time they are called. The default value is the
42
+ // ASP.NET function that validates the controls on the page
43
+ // prior to a postback.
44
+ //
45
+ // Am I missing other important trigger function(s) to look for?
46
+ // Please leave me feedback:
47
+ // http://code.google.com/p/jquery-watermark/issues/list
48
+ triggerFns = [
49
+ "Page_ClientValidate"
50
+ ],
51
+
52
+ // Holds a value of true if a watermark was displayed since the last
53
+ // hideAll() was executed. Avoids repeatedly calling hideAll().
54
+ pageDirty = false,
55
+
56
+ // Detects if the browser can handle native placeholders
57
+ hasNativePlaceholder = ("placeholder" in document.createElement("input"));
58
+
59
+ // Best practice: this plugin adds only one method to the jQuery object.
60
+ // Also ensures that the watermark code is only added once.
61
+ $.watermark = $.watermark || {
62
+
63
+ // Current version number of the plugin
64
+ version: "3.1.3",
65
+
66
+ runOnce: true,
67
+
68
+ // Default options used when watermarks are instantiated.
69
+ // Can be changed to affect the default behavior for all
70
+ // new or updated watermarks.
71
+ options: {
72
+
73
+ // Default class name for all watermarks
74
+ className: "watermark",
75
+
76
+ // If true, plugin will detect and use native browser support for
77
+ // watermarks, if available. (e.g., WebKit's placeholder attribute.)
78
+ useNative: true,
79
+
80
+ // If true, all watermarks will be hidden during the window's
81
+ // beforeunload event. This is done mainly because WebKit
82
+ // browsers remember the watermark text during navigation
83
+ // and try to restore the watermark text after the user clicks
84
+ // the Back button. We can avoid this by hiding the text before
85
+ // the browser has a chance to save it. The regular unload event
86
+ // was tried, but it seems the browser saves the text before
87
+ // that event kicks off, because it didn't work.
88
+ hideBeforeUnload: true
89
+ },
90
+
91
+ // Hide one or more watermarks by specifying any selector type
92
+ // i.e., DOM element, string selector, jQuery matched set, etc.
93
+ hide: function (selector) {
94
+ $(selector).filter(selWatermarkDefined).each(
95
+ function () {
96
+ $.watermark._hide($(this));
97
+ }
98
+ );
99
+ },
100
+
101
+ // Internal use only.
102
+ _hide: function ($input, focus) {
103
+ var elem = $input[0],
104
+ inputVal = (elem.value || "").replace(rreturn, ""),
105
+ inputWm = $input.data(dataText) || "",
106
+ maxLen = $input.data(dataMaxLen) || 0,
107
+ className = $input.data(dataClass);
108
+
109
+ if ((inputWm.length) && (inputVal == inputWm)) {
110
+ elem.value = "";
111
+
112
+ // Password type?
113
+ if ($input.data(dataPassword)) {
114
+
115
+ if (($input.attr("type") || "") === "text") {
116
+ var $pwd = $input.data(dataPassword) || [],
117
+ $wrap = $input.parent() || [];
118
+
119
+ if (($pwd.length) && ($wrap.length)) {
120
+ $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data
121
+ $wrap[0].appendChild($pwd[0]);
122
+ $input = $pwd;
123
+ }
124
+ }
125
+ }
126
+
127
+ if (maxLen) {
128
+ $input.attr("maxLength", maxLen);
129
+ $input.removeData(dataMaxLen);
130
+ }
131
+
132
+ if (focus) {
133
+ $input.attr("autocomplete", "off"); // Avoid NS_ERROR_XPC_JS_THREW_STRING error in Firefox
134
+
135
+ window.setTimeout(
136
+ function () {
137
+ $input.select(); // Fix missing cursor in IE
138
+ }
139
+ , 1);
140
+ }
141
+ }
142
+
143
+ className && $input.removeClass(className);
144
+ },
145
+
146
+ // Display one or more watermarks by specifying any selector type
147
+ // i.e., DOM element, string selector, jQuery matched set, etc.
148
+ // If conditions are not right for displaying a watermark, ensures that watermark is not shown.
149
+ show: function (selector) {
150
+ $(selector).filter(selWatermarkDefined).each(
151
+ function () {
152
+ $.watermark._show($(this));
153
+ }
154
+ );
155
+ },
156
+
157
+ // Internal use only.
158
+ _show: function ($input) {
159
+ var elem = $input[0],
160
+ val = (elem.value || "").replace(rreturn, ""),
161
+ text = $input.data(dataText) || "",
162
+ type = $input.attr("type") || "",
163
+ className = $input.data(dataClass);
164
+
165
+ if (((val.length == 0) || (val == text)) && (!$input.data(dataFocus))) {
166
+ pageDirty = true;
167
+
168
+ // Password type?
169
+ if ($input.data(dataPassword)) {
170
+
171
+ if (type === "password") {
172
+ var $pwd = $input.data(dataPassword) || [],
173
+ $wrap = $input.parent() || [];
174
+
175
+ if (($pwd.length) && ($wrap.length)) {
176
+ $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data
177
+ $wrap[0].appendChild($pwd[0]);
178
+ $input = $pwd;
179
+ $input.attr("maxLength", text.length);
180
+ elem = $input[0];
181
+ }
182
+ }
183
+ }
184
+
185
+ // Ensure maxLength big enough to hold watermark (input of type="text" or type="search" only)
186
+ if ((type === "text") || (type === "search")) {
187
+ var maxLen = $input.attr("maxLength") || 0;
188
+
189
+ if ((maxLen > 0) && (text.length > maxLen)) {
190
+ $input.data(dataMaxLen, maxLen);
191
+ $input.attr("maxLength", text.length);
192
+ }
193
+ }
194
+
195
+ className && $input.addClass(className);
196
+ elem.value = text;
197
+ }
198
+ else {
199
+ $.watermark._hide($input);
200
+ }
201
+ },
202
+
203
+ // Hides all watermarks on the current page.
204
+ hideAll: function () {
205
+ if (pageDirty) {
206
+ $.watermark.hide(selWatermarkAble);
207
+ pageDirty = false;
208
+ }
209
+ },
210
+
211
+ // Displays all watermarks on the current page.
212
+ showAll: function () {
213
+ $.watermark.show(selWatermarkAble);
214
+ }
215
+ };
216
+
217
+ $.fn.watermark = $.fn.watermark || function (text, options) {
218
+ /// <summary>
219
+ /// Set watermark text and class name on all input elements of type="text/password/search" and
220
+ /// textareas within the matched set. If className is not specified in options, the default is
221
+ /// "watermark". Within the matched set, only input elements with type="text/password/search"
222
+ /// and textareas are affected; all other elements are ignored.
223
+ /// </summary>
224
+ /// <returns type="jQuery">
225
+ /// Returns the original jQuery matched set (not just the input and texarea elements).
226
+ /// </returns>
227
+ /// <param name="text" type="String">
228
+ /// Text to display as a watermark when the input or textarea element has an empty value and does not
229
+ /// have focus. The first time watermark() is called on an element, if this argument is empty (or not
230
+ /// a String type), then the watermark will have the net effect of only changing the class name when
231
+ /// the input or textarea element's value is empty and it does not have focus.
232
+ /// </param>
233
+ /// <param name="options" type="Object" optional="true">
234
+ /// Provides the ability to override the default watermark options ($.watermark.options). For backward
235
+ /// compatibility, if a string value is supplied, it is used as the class name that overrides the class
236
+ /// name in $.watermark.options.className. Properties include:
237
+ /// className: When the watermark is visible, the element will be styled using this class name.
238
+ /// useNative (Boolean or Function): Specifies if native browser support for watermarks will supersede
239
+ /// plugin functionality. If useNative is a function, the return value from the function will
240
+ /// determine if native support is used. The function is passed one argument -- a jQuery object
241
+ /// containing the element being tested as the only element in its matched set -- and the DOM
242
+ /// element being tested is the object on which the function is invoked (the value of "this").
243
+ /// </param>
244
+ /// <remarks>
245
+ /// The effect of changing the text and class name on an input element is called a watermark because
246
+ /// typically light gray text is used to provide a hint as to what type of input is required. However,
247
+ /// the appearance of the watermark can be something completely different: simply change the CSS style
248
+ /// pertaining to the supplied class name.
249
+ ///
250
+ /// The first time watermark() is called on an element, the watermark text and class name are initialized,
251
+ /// and the focus and blur events are hooked in order to control the display of the watermark. Also, as
252
+ /// of version 3.0, drag and drop events are hooked to guard against dropped text being appended to the
253
+ /// watermark. If native watermark support is provided by the browser, it is detected and used, unless
254
+ /// the useNative option is set to false.
255
+ ///
256
+ /// Subsequently, watermark() can be called again on an element in order to change the watermark text
257
+ /// and/or class name, and it can also be called without any arguments in order to refresh the display.
258
+ ///
259
+ /// For example, after changing the value of the input or textarea element programmatically, watermark()
260
+ /// should be called without any arguments to refresh the display, because the change event is only
261
+ /// triggered by user actions, not by programmatic changes to an input or textarea element's value.
262
+ ///
263
+ /// The one exception to programmatic updates is for password input elements: you are strongly cautioned
264
+ /// against changing the value of a password input element programmatically (after the page loads).
265
+ /// The reason is that some fairly hairy code is required behind the scenes to make the watermarks bypass
266
+ /// IE security and switch back and forth between clear text (for watermarks) and obscured text (for
267
+ /// passwords). It is *possible* to make programmatic changes, but it must be done in a certain way, and
268
+ /// overall it is not recommended.
269
+ /// </remarks>
270
+
271
+ if (!this.length) {
272
+ return this;
273
+ }
274
+
275
+ var hasClass = false,
276
+ hasText = (typeof(text) === "string");
277
+
278
+ if (hasText) {
279
+ text = text.replace(rreturn, "");
280
+ }
281
+
282
+ if (typeof(options) === "object") {
283
+ hasClass = (typeof(options.className) === "string");
284
+ options = $.extend({}, $.watermark.options, options);
285
+ }
286
+ else if (typeof(options) === "string") {
287
+ hasClass = true;
288
+ options = $.extend({}, $.watermark.options, {className: options});
289
+ }
290
+ else {
291
+ options = $.watermark.options;
292
+ }
293
+
294
+ if (typeof(options.useNative) !== "function") {
295
+ options.useNative = options.useNative? function () { return true; } : function () { return false; };
296
+ }
297
+
298
+ return this.each(
299
+ function () {
300
+ var $input = $(this);
301
+
302
+ if (!$input.is(selWatermarkAble)) {
303
+ return;
304
+ }
305
+
306
+ // Watermark already initialized?
307
+ if ($input.data(dataFlag)) {
308
+
309
+ // If re-defining text or class, first remove existing watermark, then make changes
310
+ if (hasText || hasClass) {
311
+ $.watermark._hide($input);
312
+
313
+ if (hasText) {
314
+ $input.data(dataText, text);
315
+ }
316
+
317
+ if (hasClass) {
318
+ $input.data(dataClass, options.className);
319
+ }
320
+ }
321
+ }
322
+ else {
323
+
324
+ // Detect and use native browser support, if enabled in options
325
+ if (
326
+ (hasNativePlaceholder)
327
+ && (options.useNative.call(this, $input))
328
+ && (($input.attr("tagName") || "") !== "TEXTAREA")
329
+ ) {
330
+ // className is not set because current placeholder standard doesn't
331
+ // have a separate class name property for placeholders (watermarks).
332
+ if (hasText) {
333
+ $input.attr("placeholder", text);
334
+ }
335
+
336
+ // Only set data flag for non-native watermarks
337
+ // [purposely commented-out] -> $input.data(dataFlag, 1);
338
+ return;
339
+ }
340
+
341
+ $input.data(dataText, hasText? text : "");
342
+ $input.data(dataClass, options.className);
343
+ $input.data(dataFlag, 1); // Flag indicates watermark was initialized
344
+
345
+ // Special processing for password type
346
+ if (($input.attr("type") || "") === "password") {
347
+ var $wrap = $input.wrap("<span>").parent(),
348
+ $wm = $($wrap.html().replace(/type=["']?password["']?/i, 'type="text"'));
349
+
350
+ $wm.data(dataText, $input.data(dataText));
351
+ $wm.data(dataClass, $input.data(dataClass));
352
+ $wm.data(dataFlag, 1);
353
+ $wm.attr("maxLength", text.length);
354
+
355
+ $wm.focus(
356
+ function () {
357
+ $.watermark._hide($wm, true);
358
+ }
359
+ ).bind("dragenter",
360
+ function () {
361
+ $.watermark._hide($wm);
362
+ }
363
+ ).bind("dragend",
364
+ function () {
365
+ window.setTimeout(function () { $wm.blur(); }, 1);
366
+ }
367
+ );
368
+ $input.blur(
369
+ function () {
370
+ $.watermark._show($input);
371
+ }
372
+ ).bind("dragleave",
373
+ function () {
374
+ $.watermark._show($input);
375
+ }
376
+ );
377
+
378
+ $wm.data(dataPassword, $input);
379
+ $input.data(dataPassword, $wm);
380
+ }
381
+ else {
382
+
383
+ $input.focus(
384
+ function () {
385
+ $input.data(dataFocus, 1);
386
+ $.watermark._hide($input, true);
387
+ }
388
+ ).blur(
389
+ function () {
390
+ $input.data(dataFocus, 0);
391
+ $.watermark._show($input);
392
+ }
393
+ ).bind("dragenter",
394
+ function () {
395
+ $.watermark._hide($input);
396
+ }
397
+ ).bind("dragleave",
398
+ function () {
399
+ $.watermark._show($input);
400
+ }
401
+ ).bind("dragend",
402
+ function () {
403
+ window.setTimeout(function () { $.watermark._show($input); }, 1);
404
+ }
405
+ ).bind("drop",
406
+ // Firefox makes this lovely function necessary because the dropped text
407
+ // is merged with the watermark before the drop event is called.
408
+ function (evt) {
409
+ var elem = $input[0],
410
+ dropText = evt.originalEvent.dataTransfer.getData("Text");
411
+
412
+ if ((elem.value || "").replace(rreturn, "").replace(dropText, "") === $input.data(dataText)) {
413
+ elem.value = dropText;
414
+ }
415
+
416
+ $input.focus();
417
+ }
418
+ );
419
+ }
420
+
421
+ // In order to reliably clear all watermarks before form submission,
422
+ // we need to replace the form's submit function with our own
423
+ // function. Otherwise watermarks won't be cleared when the form
424
+ // is submitted programmatically.
425
+ if (this.form) {
426
+ var form = this.form,
427
+ $form = $(form);
428
+
429
+ if (!$form.data(dataFormSubmit)) {
430
+ $form.submit($.watermark.hideAll);
431
+
432
+ // form.submit exists for all browsers except Google Chrome
433
+ // (see "else" below for explanation)
434
+ if (form.submit) {
435
+ $form.data(dataFormSubmit, form.submit);
436
+
437
+ form.submit = (function (f, $f) {
438
+ return function () {
439
+ var nativeSubmit = $f.data(dataFormSubmit);
440
+
441
+ $.watermark.hideAll();
442
+
443
+ if (nativeSubmit.apply) {
444
+ nativeSubmit.apply(f, Array.prototype.slice.call(arguments));
445
+ }
446
+ else {
447
+ nativeSubmit();
448
+ }
449
+ };
450
+ })(form, $form);
451
+ }
452
+ else {
453
+ $form.data(dataFormSubmit, 1);
454
+
455
+ // This strangeness is due to the fact that Google Chrome's
456
+ // form.submit function is not visible to JavaScript (identifies
457
+ // as "undefined"). I had to invent a solution here because hours
458
+ // of Googling (ironically) for an answer did not turn up anything
459
+ // useful. Within my own form.submit function I delete the form's
460
+ // submit function, and then call the non-existent function --
461
+ // which, in the world of Google Chrome, still exists.
462
+ form.submit = (function (f) {
463
+ return function () {
464
+ $.watermark.hideAll();
465
+ delete f.submit;
466
+ f.submit();
467
+ };
468
+ })(form);
469
+ }
470
+ }
471
+ }
472
+ }
473
+
474
+ $.watermark._show($input);
475
+ }
476
+ );
477
+ };
478
+
479
+ // The code included within the following if structure is guaranteed to only run once,
480
+ // even if the watermark script file is included multiple times in the page.
481
+ if ($.watermark.runOnce) {
482
+ $.watermark.runOnce = false;
483
+
484
+ $.extend($.expr[":"], {
485
+
486
+ // Extends jQuery with a custom selector - ":data(...)"
487
+ // :data(<name>) Includes elements that have a specific name defined in the jQuery data
488
+ // collection. (Only the existence of the name is checked; the value is ignored.)
489
+ // A more sophisticated version of the :data() custom selector originally part of this plugin
490
+ // was removed for compatibility with jQuery UI. The original code can be found in the SVN
491
+ // source listing in the file, "jquery.data.js".
492
+ data: function( elem, i, match ) {
493
+ return !!$.data( elem, match[ 3 ] );
494
+ }
495
+ });
496
+
497
+ // Overloads the jQuery .val() function to return the underlying input value on
498
+ // watermarked input elements. When .val() is being used to set values, this
499
+ // function ensures watermarks are properly set/removed after the values are set.
500
+ // Uses self-executing function to override the default jQuery function.
501
+ (function (valOld) {
502
+
503
+ $.fn.val = function () {
504
+
505
+ // Best practice: return immediately if empty matched set
506
+ if ( !this.length ) {
507
+ return arguments.length? this : undefined;
508
+ }
509
+
510
+ // If no args, then we're getting the value of the first element;
511
+ // otherwise we're setting values for all elements in matched set
512
+ if ( !arguments.length ) {
513
+
514
+ // If element is watermarked, get the underlying value;
515
+ // otherwise use native jQuery .val()
516
+ if ( this.data(dataFlag) ) {
517
+ var v = (this[0].value || "").replace(rreturn, "");
518
+ return (v === (this.data(dataText) || ""))? "" : v;
519
+ }
520
+ else {
521
+ return valOld.apply( this, arguments );
522
+ }
523
+ }
524
+ else {
525
+ valOld.apply( this, arguments );
526
+ $.watermark.show(this);
527
+ return this;
528
+ }
529
+ };
530
+
531
+ })($.fn.val);
532
+
533
+ // Hijack any functions found in the triggerFns list
534
+ if (triggerFns.length) {
535
+
536
+ // Wait until DOM is ready before searching
537
+ $(function () {
538
+ var i, name, fn;
539
+
540
+ for (i=triggerFns.length-1; i>=0; i--) {
541
+ name = triggerFns[i];
542
+ fn = window[name];
543
+
544
+ if (typeof(fn) === "function") {
545
+ window[name] = (function (origFn) {
546
+ return function () {
547
+ $.watermark.hideAll();
548
+ return origFn.apply(null, Array.prototype.slice.call(arguments));
549
+ };
550
+ })(fn);
551
+ }
552
+ }
553
+ });
554
+ }
555
+
556
+ $(window).bind("beforeunload", function () {
557
+ if ($.watermark.options.hideBeforeUnload) {
558
+ $.watermark.hideAll();
559
+ }
560
+ });
561
+ }
562
+
563
+ })(jQuery, window);