Commit b2a0c4315645ed2b64ce8118b3fa9671da33ca8c

Authored by Rodrigo Souto
2 parents c5b9f977 07f9167d

Merge branch 'master' into pluginize-solr

Conflicts:
	app/models/article.rb
	app/views/layouts/application-ng.rhtml
	lib/noosfero/plugin.rb
	script/noosfero-plugins
Showing 400 changed files with 32421 additions and 4330 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 400 files displayed.

AUTHORS
... ... @@ -148,6 +148,7 @@ Rodrigo Souto <rodrigo@colivre.coop.br>
148 148 Ronny Kursawe <kursawe.ronny@googlemail.com>
149 149 Samuel R. C. Vale <srcvale@holoscopio.com>
150 150 Valessio Brito <valessio@gmail.com>
  151 +Visita <visita@debian.(none)>
151 152 Yann Lugrin <yann.lugrin@liquid-concept.ch>
152 153  
153 154 Ideas, specifications and incentive
... ...
Gemfile
1   -source :rubygems
  1 +source "https://rubygems.org"
2 2  
3 3 gem 'exception_notification', '1.0.20090728'
4 4 gem 'system_timer'
... ...
Gemfile.lock
1 1 GEM
2   - remote: http://rubygems.org/
  2 + remote: https://rubygems.org/
3 3 specs:
4 4 builder (3.1.4)
5 5 capybara (1.1.1)
... ...
RELEASING
... ... @@ -31,6 +31,7 @@ To prepare a release of noosfero, you must follow the steps below:
31 31 sha1 of the package (with sha1sum and paste the SHA1 hash as comment in the
32 32 attachment form)
33 33 * Download the attached and verify the MD5 hash
  34 +* Push the new version tag (with git push --tags)
34 35 * Update an eventual demonstration version that you run.
35 36 * Write an announcement e-mail to the relevant mailing lists pointing to the
36 37 release notes, and maybe to the demonstration version.
... ...
app/controllers/admin/environment_design_controller.rb
... ... @@ -4,6 +4,7 @@ class EnvironmentDesignController &lt; BoxOrganizerController
4 4  
5 5 def available_blocks
6 6 @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
  7 + @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment)
7 8 end
8 9  
9 10 end
... ...
app/controllers/admin/users_controller.rb
  1 +require 'csv'
  2 +
1 3 class UsersController < AdminController
2 4  
3 5 protect 'manage_environment_users', :environment
... ... @@ -15,8 +17,16 @@ class UsersController &lt; AdminController
15 17 :disposition => "attachment; filename=users.xml"
16 18 end
17 19 format.csv do
18   - @users = User.find(:all, :conditions => {:environment_id => environment.id}, :include => [:person])
19   - render :template => "users/index_csv.rhtml", :content_type => 'text/csv', :layout => false
  20 + # using a direct connection with the dbms to optimize
  21 + command = User.send(:sanitize_sql, ["SELECT profiles.name, users.email FROM profiles
  22 + INNER JOIN users ON profiles.user_id=users.id
  23 + WHERE profiles.environment_id = ?", environment.id])
  24 + users = User.connection.execute(command)
  25 + csv_content = "name;email\n"
  26 + users.each { |u|
  27 + CSV.generate_row([u['name'], u['email']], 2, csv_content, fs=';')
  28 + }
  29 + render :text => csv_content, :content_type => 'text/csv', :layout => false
20 30 end
21 31 end
22 32 end
... ...
app/controllers/box_organizer_controller.rb
... ... @@ -68,8 +68,8 @@ class BoxOrganizerController &lt; ApplicationController
68 68 raise ArgumentError.new("Type %s is not allowed. Go away." % type)
69 69 end
70 70 else
71   - @center_block_types = Box.acceptable_center_blocks & available_blocks
72   - @side_block_types = Box.acceptable_side_blocks & available_blocks
  71 + @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1)
  72 + @side_block_types = (Box.acceptable_side_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => [2,3])
73 73 @boxes = boxes_holder.boxes
74 74 render :action => 'add_block', :layout => false
75 75 end
... ...
app/controllers/my_profile/profile_design_controller.rb
... ... @@ -7,17 +7,25 @@ class ProfileDesignController &lt; BoxOrganizerController
7 7 def available_blocks
8 8 blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock, SlideshowBlock, ProfileSearchBlock, HighlightsBlock ]
9 9  
  10 + blocks += plugins.dispatch(:extra_blocks)
  11 +
10 12 # blocks exclusive for organizations
11 13 if profile.has_members?
12 14 blocks << MembersBlock
13 15 end
14 16  
15   - # blocks exclusive to person
  17 + # blocks exclusive to people
16 18 if profile.person?
17 19 blocks << FriendsBlock
18 20 blocks << FavoriteEnterprisesBlock
19 21 blocks << CommunitiesBlock
20 22 blocks << EnterprisesBlock
  23 + blocks += plugins.dispatch(:extra_blocks, :type => Person)
  24 + end
  25 +
  26 + # blocks exclusive to communities
  27 + if profile.community?
  28 + blocks += plugins.dispatch(:extra_blocks, :type => Community)
21 29 end
22 30  
23 31 # blocks exclusive for enterprises
... ... @@ -26,6 +34,7 @@ class ProfileDesignController &lt; BoxOrganizerController
26 34 blocks << HighlightsBlock
27 35 blocks << FeaturedProductsBlock
28 36 blocks << FansBlock
  37 + blocks += plugins.dispatch(:extra_blocks, :type => Enterprise)
29 38 end
30 39  
31 40 # product block exclusive for enterprises in environments that permits it
... ... @@ -33,7 +42,7 @@ class ProfileDesignController &lt; BoxOrganizerController
33 42 blocks << ProductsBlock
34 43 end
35 44  
36   - # block exclusive to profile has blog
  45 + # block exclusive to profiles that have blog
37 46 if profile.has_blog?
38 47 blocks << BlogArchivesBlock
39 48 end
... ...
app/controllers/my_profile/profile_members_controller.rb
... ... @@ -32,7 +32,6 @@ class ProfileMembersController &lt; MyProfileController
32 32  
33 33 def last_admin
34 34 @roles = [Profile::Roles.admin(environment.id)]
35   - @pre_population = [].to_json
36 35 end
37 36  
38 37 def add_role
... ...
app/helpers/application_helper.rb
... ... @@ -30,6 +30,12 @@ module ApplicationHelper
30 30  
31 31 include AccountHelper
32 32  
  33 + include BlogHelper
  34 +
  35 + include ContentViewerHelper
  36 +
  37 + include LayoutHelper
  38 +
33 39 def locale
34 40 (@page && !@page.language.blank?) ? @page.language : FastGettext.locale
35 41 end
... ... @@ -352,10 +358,6 @@ module ApplicationHelper
352 358 end
353 359 end
354 360  
355   - def theme_stylesheet_path
356   - theme_path + '/style.css'
357   - end
358   -
359 361 def current_theme
360 362 @current_theme ||=
361 363 begin
... ... @@ -493,23 +495,24 @@ module ApplicationHelper
493 495  
494 496 def profile_cat_icons( profile )
495 497 if profile.class == Enterprise
496   - icons =
497   - profile.product_categories.map{ |c| c.size > 1 ? c[1] : nil }.
498   - compact.uniq.map{ |c|
499   - cat_name = c.gsub( /[-_\s,.;'"]+/, '_' )
500   - cat_icon = "/images/icons-cat/#{cat_name}.png"
501   - if ! File.exists? RAILS_ROOT.to_s() + '/public/' + cat_icon
502   - cat_icon = '/images/icons-cat/undefined.png'
503   - end
504   - content_tag 'span',
505   - content_tag( 'span', c ),
506   - :title => c,
507   - :class => 'product-cat-icon cat_icon_' + cat_name,
508   - :style => "background-image:url(#{cat_icon})"
509   - }.join "\n"
510   - content_tag 'div',
511   - content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,
512   - :class => 'product-category-icons'
  498 + icons = profile.product_categories.map{ |c| c.size > 1 ? c[1] : nil }.
  499 + compact.uniq.map do |c|
  500 + cat_name = c.gsub( /[-_\s,.;'"]+/, '_' )
  501 + cat_icon = "/images/icons-cat/#{cat_name}.png"
  502 + if ! File.exists? RAILS_ROOT.to_s() + '/public/' + cat_icon
  503 + cat_icon = '/images/icons-cat/undefined.png'
  504 + end
  505 + content_tag('span',
  506 + content_tag( 'span', c ),
  507 + :title => c,
  508 + :class => 'product-cat-icon cat_icon_' + cat_name,
  509 + :style => "background-image:url(#{cat_icon})"
  510 + )
  511 + end.join("\n").html_safe
  512 + content_tag('div',
  513 + content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,
  514 + :class => 'product-category-icons'
  515 + )
513 516 else
514 517 ''
515 518 end
... ... @@ -633,10 +636,10 @@ module ApplicationHelper
633 636 # FIXME
634 637 ([toplevel] + toplevel.children_for_menu).each do |cat|
635 638 if cat.top_level?
636   - result << '<div class="categorie_box">'
  639 + result << '<div class="categorie_box">'.html_safe
637 640 result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' )
638 641 result << content_tag('h5', toplevel.name)
639   - result << '<div style="display:none"><ul class="categories">'
  642 + result << '<div style="display:none"><ul class="categories">'.html_safe
640 643 else
641 644 checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}"
642 645 result << content_tag('li', labelled_check_box(
... ... @@ -647,7 +650,7 @@ module ApplicationHelper
647 650 :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n"
648 651 end
649 652 end
650   - result << '</ul></div></div>'
  653 + result << '</ul></div></div>'.html_safe
651 654 end
652 655  
653 656 content_tag('div', result)
... ... @@ -787,10 +790,10 @@ module ApplicationHelper
787 790 :class => 'lineitem' + (line_item+=1).to_s() ) +"\n"
788 791 if line_item == line_size
789 792 line_item = 0
790   - html += "<br />\n"
  793 + html += "<br />\n".html_safe
791 794 end
792 795 }
793   - html += "<br />\n" if line_size == 0 || ( values.size % line_size ) > 0
  796 + html += "<br />\n".html_safe if line_size == 0 || ( values.size % line_size ) > 0
794 797 column = object.class.columns_hash[method.to_s]
795 798 text =
796 799 ( column ?
... ... @@ -873,14 +876,6 @@ module ApplicationHelper
873 876 content_tag('div', labelled_check_box(_('Public'), 'profile_data[fields_privacy]['+name+']', 'public', profile.public_fields.include?(name)), :class => 'field-privacy-selector')
874 877 end
875 878  
876   - def template_stylesheet_path
877   - if profile.nil?
878   - "/designs/templates/#{environment.layout_template}/stylesheets/style.css"
879   - else
880   - "/designs/templates/#{profile.layout_template}/stylesheets/style.css"
881   - end
882   - end
883   -
884 879 def login_url
885 880 options = Noosfero.url_options.merge({ :controller => 'account', :action => 'login' })
886 881 url_for(options)
... ... @@ -919,18 +914,6 @@ module ApplicationHelper
919 914 end
920 915 end
921 916  
922   - def icon_theme_stylesheet_path
923   - icon_themes = []
924   - theme_icon_themes = theme_option(:icon_theme) || []
925   - for icon_theme in theme_icon_themes do
926   - theme_path = "/designs/icons/#{icon_theme}/style.css"
927   - if File.exists?(File.join(RAILS_ROOT, 'public', theme_path))
928   - icon_themes << theme_path
929   - end
930   - end
931   - icon_themes
932   - end
933   -
934 917 def page_title
935 918 (@page ? @page.title + ' - ' : '') +
936 919 (profile ? profile.short_name + ' - ' : '') +
... ... @@ -942,42 +925,13 @@ module ApplicationHelper
942 925 (@category ? " - #{@category.full_name}" : '')
943 926 end
944 927  
945   - def noosfero_javascript
946   - render :file => 'layouts/_javascript'
947   - end
948   -
949   - def noosfero_stylesheets
950   - [
951   - 'application',
952   - 'search',
953   - 'thickbox',
954   - 'lightbox',
955   - 'colorpicker',
956   - 'colorbox',
957   - pngfix_stylesheet_path,
958   - ] +
959   - tokeninput_stylesheets
960   - end
961   -
962 928 # DEPRECATED. Do not use this·
963 929 def import_controller_stylesheets(options = {})
964 930 stylesheet_import( "controller_"+ @controller.controller_name(), options )
965 931 end
966 932  
967   - def pngfix_stylesheet_path
968   - 'iepngfix/iepngfix.css'
969   - end
970   -
971   - def tokeninput_stylesheets
972   - ['token-input', 'token-input-facebook', 'token-input-mac', 'token-input-facet']
973   - end
974   -
975   - def noosfero_layout_features
976   - render :file => 'shared/noosfero_layout_features'
977   - end
978   -
979 933 def link_to_email(email)
980   - javascript_tag('var array = ' + email.split('@').to_json + '; document.write("<a href=\'mailto:" + array.join("@") + "\'>" + array.join("@") + "</a>")')
  934 + javascript_tag('var array = ' + email.split('@').to_json + '; document.write("<a href=\'mailto:" + array.join("@") + "\'>" + array.join("@") + "</a>")'.html_safe)
981 935 end
982 936  
983 937 def stylesheet(*args)
... ... @@ -987,13 +941,43 @@ module ApplicationHelper
987 941 def article_to_html(article, options = {})
988 942 options.merge!(:page => params[:npage])
989 943 content = article.to_html(options)
990   - content = content.kind_of?(Proc) ? self.instance_eval(&content) : content
  944 + content = content.kind_of?(Proc) ? self.instance_eval(&content).html_safe : content.html_safe
991 945 @plugins && @plugins.each do |plugin|
992 946 content = plugin.parse_content(content)
993 947 end
994 948 content
995 949 end
996 950  
  951 + # Please, use link_to by default!
  952 + # This method was created to work around to inexplicable
  953 + # chain of problems when display_short_format was called
  954 + # from Article model for an ArticleBlock.
  955 + def reference_to_article(text, article, anchor=nil)
  956 + if article.profile.domains.empty?
  957 + href = "/#{article.url[:profile]}/"
  958 + else
  959 + href = "http://#{article.profile.domains.first.name}/"
  960 + end
  961 + href += article.url[:page].join('/')
  962 + href += '#' + anchor if anchor
  963 + content_tag('a', text, :href => href)
  964 + end
  965 +
  966 + def display_short_format(article, options={})
  967 + options[:comments_link] ||= true
  968 + options[:read_more_link] ||= true
  969 + html = content_tag('div',
  970 + article.lead +
  971 + content_tag('div',
  972 + (options[:comments_link] ? link_to_comments(article) : '') +
  973 + (options[:read_more_link] ? reference_to_article( _('Read more'), article) : ''),
  974 + :class => 'read-more'
  975 + ),
  976 + :class => 'short-post'
  977 + )
  978 + html
  979 + end
  980 +
997 981 def colorpicker_field(object_name, method, options = {})
998 982 text_field(object_name, method, options.merge(:class => 'colorpicker_field'))
999 983 end
... ... @@ -1003,7 +987,7 @@ module ApplicationHelper
1003 987 end
1004 988  
1005 989 def ui_icon(icon_class, extra_class = '')
1006   - "<span class='ui-icon #{icon_class} #{extra_class}' style='float:left; margin-right:7px;'></span>"
  990 + "<span class='ui-icon #{icon_class} #{extra_class}' style='float:left; margin-right:7px;'></span>".html_safe
1007 991 end
1008 992  
1009 993 def ui_button(label, url, html_options = {})
... ... @@ -1018,10 +1002,6 @@ module ApplicationHelper
1018 1002 theme_option(:jquery_theme) || 'smoothness_mod'
1019 1003 end
1020 1004  
1021   - def jquery_ui_theme_stylesheet_path
1022   - 'jquery.ui/' + jquery_theme + '/jquery-ui-1.8.2.custom'
1023   - end
1024   -
1025 1005 def ui_error(message)
1026 1006 content_tag('div', ui_icon('ui-icon-alert') + message, :class => 'alert fg-state-error ui-state-error')
1027 1007 end
... ... @@ -1035,13 +1015,13 @@ module ApplicationHelper
1035 1015 end
1036 1016  
1037 1017 def collapsed_item_icon
1038   - "<span class='ui-icon ui-icon-circlesmall-plus' style='float:left;'></span>"
  1018 + "<span class='ui-icon ui-icon-circlesmall-plus' style='float:left;'></span>".html_safe
1039 1019 end
1040 1020 def expanded_item_icon
1041   - "<span class='ui-icon ui-icon-circlesmall-minus' style='float:left;'></span>"
  1021 + "<span class='ui-icon ui-icon-circlesmall-minus' style='float:left;'></span>".html_safe
1042 1022 end
1043 1023 def leaf_item_icon
1044   - "<span class='ui-icon ui-icon-arrow-1-e' style='float:left;'></span>"
  1024 + "<span class='ui-icon ui-icon-arrow-1-e' style='float:left;'></span>".html_safe
1045 1025 end
1046 1026  
1047 1027 def display_category_menu(block, categories, root = true)
... ... @@ -1300,9 +1280,7 @@ module ApplicationHelper
1300 1280 titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
1301 1281 contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
1302 1282  
1303   - content_tag :div, :class => 'ui-tabs' do
1304   - content_tag(:ul, titles) + contents
1305   - end
  1283 + content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs')
1306 1284 end
1307 1285  
1308 1286 def jquery_token_input_messages_json(hintText = _('Type in an keyword'), noResultsText = _('No results'), searchingText = _('Searching...'))
... ... @@ -1331,11 +1309,12 @@ module ApplicationHelper
1331 1309 end
1332 1310  
1333 1311 def template_options(klass, field_name)
1334   - return '' if klass.templates.count == 0
1335   - return hidden_field_tag("#{field_name}[template_id]", klass.templates.first.id) if klass.templates.count == 1
  1312 + templates = klass.templates(environment)
  1313 + return '' if templates.count == 0
  1314 + return hidden_field_tag("#{field_name}[template_id]", templates.first.id) if templates.count == 1
1336 1315  
1337 1316 counter = 0
1338   - radios = klass.templates.map do |template|
  1317 + radios = templates.map do |template|
1339 1318 counter += 1
1340 1319 content_tag('li', labelled_radio_button(link_to(template.name, template.url, :target => '_blank'), "#{field_name}[template_id]", template.id, counter==1))
1341 1320 end.join("\n")
... ... @@ -1423,4 +1402,14 @@ module ApplicationHelper
1423 1402 @no_design_blocks = true
1424 1403 end
1425 1404  
  1405 + def default_folder_for_image_upload(profile)
  1406 + default_folder = profile.folders.find_by_type('Gallery')
  1407 + default_folder = profile.folders.find_by_type('Folder') if default_folder.nil?
  1408 + default_folder
  1409 + end
  1410 +
  1411 + def content_id_to_str(content)
  1412 + content.nil? ? '' : content.id.to_s
  1413 + end
  1414 +
1426 1415 end
... ...
app/helpers/block_helper.rb
... ... @@ -3,7 +3,7 @@ module BlockHelper
3 3 def block_title(title)
4 4 tag_class = 'block-title'
5 5 tag_class += ' empty' if title.empty?
6   - content_tag 'h3', content_tag('span', title), :class => tag_class
  6 + content_tag 'h3', content_tag('span', h(title)), :class => tag_class
7 7 end
8 8  
9 9 end
... ...
app/helpers/blog_helper.rb
... ... @@ -18,8 +18,9 @@ module BlogHelper
18 18 pagination = will_paginate(articles, {
19 19 :param_name => 'npage',
20 20 :previous_label => _('&laquo; Newer posts'),
21   - :next_label => _('Older posts &raquo;')
22   - })
  21 + :next_label => _('Older posts &raquo;'),
  22 + :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"}
  23 + }) if articles.present?
23 24 content = []
24 25 artic_len = articles.length
25 26 articles.each_with_index{ |art,i|
... ... @@ -46,18 +47,6 @@ module BlogHelper
46 47 article_title(article, :no_comments => no_comments) + html
47 48 end
48 49  
49   - def display_short_format(article)
50   - html = content_tag('div',
51   - article.lead +
52   - content_tag('div',
53   - link_to_comments(article) +
54   - link_to( _('Read more'), article.url),
55   - :class => 'read-more'),
56   - :class => 'short-post'
57   - )
58   - html
59   - end
60   -
61 50 def display_full_format(article)
62 51 html = article_to_html(article)
63 52 html = content_tag('p', html) if ! html.include?('</p>')
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -36,7 +36,7 @@ module ContentViewerHelper
36 36  
37 37 def link_to_comments(article, args = {})
38 38 return '' unless article.accept_comments?
39   - link_to(number_of_comments(article), article.url.merge(:anchor => 'comments_list') )
  39 + reference_to_article number_of_comments(article), article, 'comments_list'
40 40 end
41 41  
42 42 def article_translations(article)
... ... @@ -45,7 +45,7 @@ module ContentViewerHelper
45 45 { article.environment.locales[translation.language] => { :href => url_for(translation.url) } }
46 46 end
47 47 content_tag(:div, link_to(_('Translations'), '#',
48   - :onclick => "toggleSubmenu(this, '#{_('Translations')}', #{links.to_json}); return false",
  48 + :onmouseover => "toggleSubmenu(this, '#{_('Translations')}', #{links.to_json}); return false",
49 49 :class => 'article-translations-menu simplemenu-trigger up'),
50 50 :class => 'article-translations')
51 51 end
... ...
app/helpers/dates_helper.rb
... ... @@ -23,11 +23,13 @@ module DatesHelper
23 23 end
24 24  
25 25 # formats a date for displaying.
26   - def show_date(date, use_numbers = false)
  26 + def show_date(date, use_numbers = false, year=true)
27 27 if date && use_numbers
28   - _('%{month}/%{day}/%{year}') % { :day => date.day, :month => date.month, :year => date.year }
  28 + date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}')
  29 + date_format % { :day => date.day, :month => date.month, :year => date.year }
29 30 elsif date
30   - _('%{month} %{day}, %{year}') % { :day => date.day, :month => month_name(date.month), :year => date.year }
  31 + date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}')
  32 + date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year }
31 33 else
32 34 ''
33 35 end
... ... @@ -46,7 +48,27 @@ module DatesHelper
46 48 if (date1 == date2) || (date2.nil?)
47 49 show_date(date1, use_numbers)
48 50 else
49   - _('from %{date1} to %{date2}') % {:date1 => show_date(date1, use_numbers), :date2 => show_date(date2, use_numbers)}
  51 + if date1.year == date2.year
  52 + if date1.month == date2.month
  53 + _('from %{month} %{day1} to %{day2}, %{year}') % {
  54 + :day1 => date1.day,
  55 + :day2 => date2.day,
  56 + :month => use_numbers ? date1.month : month_name(date1.month),
  57 + :year => date1.year
  58 + }
  59 + else
  60 + _('from %{date1} to %{date2}, %{year}') % {
  61 + :date1 => show_date(date1, use_numbers, false),
  62 + :date2 => show_date(date2, use_numbers, false),
  63 + :year => date1.year
  64 + }
  65 + end
  66 + else
  67 + _('from %{date1} to %{date2}') % {
  68 + :date1 => show_date(date1, use_numbers),
  69 + :date2 => show_date(date2, use_numbers)
  70 + }
  71 + end
50 72 end
51 73 end
52 74  
... ...
app/helpers/forms_helper.rb
... ... @@ -142,38 +142,6 @@ module FormsHelper
142 142 content_tag('table',rows.join("\n"))
143 143 end
144 144  
145   - def select_folder(label_text, field_id, collection, default_value=nil, html_options = {}, js_options = {})
146   - root = profile ? profile.identifier : _("root")
147   - labelled_form_field(
148   - label_text,
149   - select_tag(
150   - field_id,
151   - options_for_select(
152   - [[root, '']] +
153   - collection.collect {|f| [ root + '/' + f.full_name, f.id ] },
154   - default_value
155   - ),
156   - html_options.merge(js_options)
157   - )
158   - )
159   - end
160   -
161   - def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {})
162   - result = labelled_form_field(
163   - label_text,
164   - select_tag(
165   - field_id,
166   - options_for_select(
167   - [[profile.identifier, '']] +
168   - profile.folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] },
169   - default_value
170   - ),
171   - html_options.merge(js_options)
172   - )
173   - )
174   - return result
175   - end
176   -
177 145 def date_field(name, value, format = '%Y-%m-%d', datepicker_options = {}, html_options = {})
178 146 datepicker_options[:disabled] ||= false
179 147 datepicker_options[:alt_field] ||= ''
... ... @@ -295,23 +263,28 @@ module FormsHelper
295 263 field_id,
296 264 options_for_select(
297 265 [[root, '']] +
298   - collection.collect {|f| [ root + '/' + f.full_name, f.id ] },
299   - default_value
  266 + collection.collect {|f| [ root + '/' + f.full_name, f.id.to_s ] },
  267 + default_value.to_s
300 268 ),
301 269 html_options.merge(js_options)
302 270 )
303 271 )
304 272 end
305 273  
306   - def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {})
  274 + def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {}, find_options = {})
  275 + if find_options.empty?
  276 + folders = profile.folders
  277 + else
  278 + folders = profile.folders.where(find_options)
  279 + end
307 280 result = labelled_form_field(
308 281 label_text,
309 282 select_tag(
310 283 field_id,
311 284 options_for_select(
312 285 [[profile.identifier, '']] +
313   - profile.folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] },
314   - default_value
  286 + folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id.to_s ] },
  287 + default_value.to_s
315 288 ),
316 289 html_options.merge(js_options)
317 290 )
... ...
app/helpers/layout_helper.rb 0 → 100644
... ... @@ -0,0 +1,88 @@
  1 +module LayoutHelper
  2 +
  3 + def body_classes
  4 + # Identify the current controller and action for the CSS:
  5 + " controller-#{@controller.controller_name}" +
  6 + " action-#{@controller.controller_name}-#{@controller.action_name}" +
  7 + " template-#{profile.nil? ? "default" : profile.layout_template}" +
  8 + (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "")
  9 + end
  10 +
  11 + def noosfero_javascript
  12 + plugins_javascripts = @plugins.map { |plugin| plugin.js_files.map { |js| plugin.class.public_path(js) } }.flatten
  13 +
  14 + output = ''
  15 + output += render :file => 'layouts/_javascript'
  16 + output += javascript_tag 'render_all_jquery_ui_widgets()'
  17 + unless plugins_javascripts.empty?
  18 + output += javascript_include_tag plugins_javascripts, :cache => "cache/plugins-#{Digest::MD5.hexdigest plugins_javascripts.to_s}"
  19 + end
  20 + output
  21 + end
  22 +
  23 + def noosfero_stylesheets
  24 + standard_stylesheets = [
  25 + 'application',
  26 + 'search',
  27 + 'thickbox',
  28 + 'lightbox',
  29 + 'colorpicker',
  30 + 'colorbox',
  31 + pngfix_stylesheet_path,
  32 + ] + tokeninput_stylesheets
  33 + plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') }
  34 +
  35 + output = ''
  36 + output += stylesheet_link_tag standard_stylesheets, :cache => 'cache'
  37 + output += stylesheet_link_tag template_stylesheet_path
  38 + output += stylesheet_link_tag icon_theme_stylesheet_path
  39 + output += stylesheet_link_tag jquery_ui_theme_stylesheet_path
  40 + unless plugins_stylesheets.empty?
  41 + output += stylesheet_link_tag plugins_stylesheets, :cache => "cache/plugins-#{Digest::MD5.hexdigest plugins_stylesheets.to_s}"
  42 + end
  43 + output += stylesheet_link_tag theme_stylesheet_path
  44 + output
  45 + end
  46 +
  47 + def pngfix_stylesheet_path
  48 + 'iepngfix/iepngfix.css'
  49 + end
  50 +
  51 + def tokeninput_stylesheets
  52 + ['token-input', 'token-input-facebook', 'token-input-mac', 'token-input-facet']
  53 + end
  54 +
  55 + def noosfero_layout_features
  56 + render :file => 'shared/noosfero_layout_features'
  57 + end
  58 +
  59 + def template_stylesheet_path
  60 + if profile.nil?
  61 + "/designs/templates/#{environment.layout_template}/stylesheets/style.css"
  62 + else
  63 + "/designs/templates/#{profile.layout_template}/stylesheets/style.css"
  64 + end
  65 + end
  66 +
  67 + def icon_theme_stylesheet_path
  68 + icon_themes = []
  69 + theme_icon_themes = theme_option(:icon_theme) || []
  70 + for icon_theme in theme_icon_themes do
  71 + theme_path = "/designs/icons/#{icon_theme}/style.css"
  72 + if File.exists?(File.join(RAILS_ROOT, 'public', theme_path))
  73 + icon_themes << theme_path
  74 + end
  75 + end
  76 + icon_themes
  77 + end
  78 +
  79 + def jquery_ui_theme_stylesheet_path
  80 + 'jquery.ui/' + jquery_theme + '/jquery-ui-1.8.2.custom'
  81 + end
  82 +
  83 + def theme_stylesheet_path
  84 + theme_path + '/style.css'
  85 + end
  86 +
  87 +end
  88 +
... ...
app/helpers/profile_editor_helper.rb
... ... @@ -136,7 +136,7 @@ module ProfileEditorHelper
136 136 concat(
137 137 content_tag(
138 138 'div',
139   - capture(&block) + '<br style="clear:left;"/>&nbsp;',
  139 + capture(&block) + content_tag('br', '', :style => 'clear: left'),
140 140 :class => 'control-panel')
141 141 )
142 142 end
... ...
app/helpers/tags_helper.rb
... ... @@ -68,7 +68,7 @@ module TagsHelper
68 68 :title => n_( 'one item', '%d items', count ) % count
69 69 end
70 70  
71   - end.join("\n")
  71 + end.join("\n").html_safe
72 72 end
73 73  
74 74 end
... ...
app/models/article.rb
... ... @@ -22,6 +22,15 @@ class Article &lt; ActiveRecord::Base
22 22 'full'
23 23 end
24 24  
  25 + #FIXME This is necessary because html is being generated on the model...
  26 + include ActionView::Helpers::TagHelper
  27 +
  28 + # use for internationalizable human type names in search facets
  29 + # reimplement on subclasses
  30 + def self.type_name
  31 + _('Content')
  32 + end
  33 +
25 34 track_actions :create_article, :after_create, :keep_params => [:name, :url, :lead, :first_image], :if => Proc.new { |a| a.is_trackable? && !a.image? }
26 35  
27 36 # xss_terminate plugin can't sanitize array fields
... ... @@ -240,8 +249,13 @@ class Article &lt; ActiveRecord::Base
240 249 # The implementation in this class just provides the +body+ attribute as the
241 250 # HTML. Other article types can override this method to provide customized
242 251 # views of themselves.
  252 + # (To override short format representation, override the lead method)
243 253 def to_html(options = {})
244   - body || ''
  254 + if options[:format] == 'short'
  255 + display_short_format(self)
  256 + else
  257 + body || ''
  258 + end
245 259 end
246 260  
247 261 include ApplicationHelper
... ...
app/models/article_block.rb
... ... @@ -12,7 +12,11 @@ class ArticleBlock &lt; Block
12 12 block = self
13 13 lambda do
14 14 block_title(block.title) +
15   - (block.article ? article_to_html(block.article, :gallery_view => false) : _('Article not selected yet.'))
  15 + (block.article ? article_to_html(block.article,
  16 + :gallery_view => false,
  17 + :inside_block => block, # For Blogs and folders
  18 + :format => block.visualization_format # For Articles and contents
  19 + ).html_safe : _('Article not selected yet.'))
16 20 end
17 21 end
18 22  
... ... @@ -49,4 +53,14 @@ class ArticleBlock &lt; Block
49 53 self.box.owner.kind_of?(Environment) ? self.box.owner.portal_community.articles : self.box.owner.articles
50 54 end
51 55  
  56 + def posts_per_page
  57 + self.settings[:posts_per_page] or 1
  58 + end
  59 +
  60 + def posts_per_page= value
  61 + value = value.to_i
  62 + self.settings[:posts_per_page] = value if value > 0
  63 + end
  64 +
  65 + settings_items :visualization_format, :type => :string, :default => 'short'
52 66 end
... ...
app/models/blog.rb
... ... @@ -24,8 +24,9 @@ class Blog &lt; Folder
24 24 # FIXME isn't this too much including just to be able to generate some HTML?
25 25 include ActionView::Helpers::TagHelper
26 26 def to_html(options = {})
  27 + me = self
27 28 lambda do
28   - render :file => 'content_viewer/blog_page'
  29 + render :file => 'content_viewer/blog_page', :locals => { :blog=>me, :inside_block=>options[:inside_block] }
29 30 end
30 31 end
31 32  
... ...
app/models/event.rb
... ... @@ -104,18 +104,30 @@ class Event &lt; Article
104 104 }
105 105 }
106 106  
  107 + # TODO: some good soul, please clean this ugly hack:
107 108 if self.body
108 109 html.div('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', :class => 'event-description')
109 110 end
110 111 }
111 112  
112 113 if self.body
113   - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body)
  114 + if options[:format] == 'short'
  115 + result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', display_short_format(self))
  116 + else
  117 + result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body)
  118 + end
114 119 end
115 120  
116 121 result
117 122 end
118 123  
  124 + def lead
  125 + content_tag('div',
  126 + show_period(start_date, end_date),
  127 + :class => 'event-dates'
  128 + ) + super
  129 + end
  130 +
119 131 def event?
120 132 true
121 133 end
... ...
app/models/feed_reader_block.rb
... ... @@ -47,11 +47,11 @@ class FeedReaderBlock &lt; Block
47 47  
48 48 def formatted_feed_content
49 49 if error_message.blank?
50   - "<ul>\n" +
51   - self.feed_items[0..(limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n") +
52   - "</ul>"
  50 + "<ul>\n".html_safe +
  51 + self.feed_items[0..(limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n").html_safe +
  52 + "</ul>".html_safe
53 53 else
54   - '<p>' + error_message + '</p>'
  54 + "<p>#{error_message}</p>".html_safe
55 55 end
56 56 end
57 57  
... ...
app/models/link_list_block.rb
... ... @@ -80,7 +80,7 @@ class LinkListBlock &lt; Block
80 80  
81 81 def icons_options
82 82 ICONS.map do |i|
83   - "<span title=\"#{i[1]}\" class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>"
  83 + "<span title=\"#{i[1]}\" class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>".html_safe
84 84 end
85 85 end
86 86  
... ...
app/models/organization_mailing.rb
... ... @@ -5,7 +5,7 @@ class OrganizationMailing &lt; Mailing
5 5 end
6 6  
7 7 def recipients(offset=0, limit=100)
8   - source.members.all(:order => self.id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :conditions => { "m.person_id" => nil })
  8 + source.members.all(:order => :id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :conditions => { "m.person_id" => nil })
9 9 end
10 10  
11 11 def each_recipient
... ...
app/models/profile.rb
... ... @@ -78,7 +78,7 @@ class Profile &lt; ActiveRecord::Base
78 78 #FIXME: these will work only if the subclass is already loaded
79 79 named_scope :enterprises, lambda { {:conditions => (Enterprise.send(:subclasses).map(&:name) << 'Enterprise').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
80 80 named_scope :communities, lambda { {:conditions => (Community.send(:subclasses).map(&:name) << 'Community').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
81   - named_scope :templates, :conditions => {:is_template => true}
  81 + named_scope :templates, lambda { |environment| { :conditions => {:is_template => true, :environment_id => environment.id} } }
82 82  
83 83 def members
84 84 scopes = plugins.dispatch_scopes(:organization_members, self)
... ...
app/models/profile_list_block.rb
... ... @@ -49,13 +49,12 @@ class ProfileListBlock &lt; Block
49 49 send(:profile_image_link, item, :minor )
50 50 }.join("\n ")
51 51 if list.empty?
52   - list = '<div class="common-profile-list-block-none">'+ _('None') +'</div>'
  52 + list = content_tag 'div', _('None'), :class => 'common-profile-list-block-none'
53 53 else
54 54 list = content_tag 'ul', nl +' '+ list + nl
55 55 end
56 56 block_title(title) + nl +
57   - '<div class="common-profile-list-block">' +
58   - nl + list + nl + '<br style="clear:both" /></div>'
  57 + content_tag('div', nl + list + nl + content_tag('br', '', :style => 'clear:both'))
59 58 end
60 59 end
61 60  
... ...
app/models/tags_block.rb
... ... @@ -35,9 +35,9 @@ class TagsBlock &lt; Block
35 35 tagname_option = is_env ? :tag : :id
36 36  
37 37 block_title(title) +
38   - "\n<div class='tag_cloud'>\n"+
  38 + "\n<div class='tag_cloud'>\n".html_safe+
39 39 tag_cloud( tags, tagname_option, url, :max_size => 16, :min_size => 9 ) +
40   - "\n</div><!-- end class='tag_cloud' -->\n";
  40 + "\n</div><!-- end class='tag_cloud' -->\n".html_safe
41 41 end
42 42  
43 43 def footer
... ...
app/models/uploaded_file.rb
... ... @@ -113,7 +113,7 @@ class UploadedFile &lt; Article
113 113  
114 114 content_tag(
115 115 'div',
116   - link_to_previous + content_tag('span', _('image %d of %d'), :class => 'total-of-images') % [current_index + 1, total_of_images] + link_to_next,
  116 + link_to_previous + (content_tag('span', _('image %d of %d'), :class => 'total-of-images') % [current_index + 1, total_of_images]).html_safe + link_to_next,
117 117 :class => 'gallery-navigation'
118 118 )
119 119 end.to_s +
... ...
app/views/box_organizer/_article_block.rhtml
1   -<div class='article-block-edition'>
  1 +<div class="article-block-edition">
2 2 <% if @block.box.owner.kind_of?(Environment) and @block.box.owner.portal_community.nil? %>
3   - <p id='no_portal_community'>
  3 + <p id="no_portal_community">
4 4 <%= _("You don't have an community defined as the portal community. Define it before use this block properly.") %>
5 5 </p>
6 6 <% else %>
7   - <% articles = @block.available_articles.select {|article| !article.folder? } %>
8   - <%= select_tag('block[article_id]', options_for_select_with_title(articles.map {|item| [item.path, item.id]}, @block.article ? @block.article.id : nil)) %>
  7 + <%
  8 + articles = @block.available_articles.select {|a| !a.folder? || a.blog? }
  9 + first_text = articles[articles.find_index{|a| a.kind_of? TextArticle}||-1]
  10 + selected = @block.article || first_text
  11 + %>
  12 + <%= select_tag(
  13 + 'block[article_id]',
  14 + options_for_select_with_title(articles.map {|item| [item.path, item.id]}, selected.id),
  15 + :onchange => 'this.changedTo(this.value)'
  16 + )%>
  17 + <div id="block_blog_options" style="display:none">
  18 + <%= labelled_form_field(
  19 + _('Number of posts:'),
  20 + text_field_tag('block[posts_per_page]', @block.posts_per_page)
  21 + )%>
  22 + </div>
  23 + <%= labelled_form_field(
  24 + _('How to display this content:'),
  25 + select_tag(
  26 + 'block[visualization_format]',
  27 + options_for_select([[_('Lead'), 'short'], [_('Full post'), 'full']], @block.visualization_format)
  28 + )
  29 + )%>
  30 + <% blogs = @block.available_articles.select{|a|a.blog?} %>
  31 + <script>
  32 + var select = jQuery("#block_article_id")[0];
  33 + select.blogs = <%= blogs.map{|b| b.id.to_s }.to_json %>;
  34 + select.changedTo = function(articleId) {
  35 + var blogSelected = this.blogs.indexOf(articleId) != -1;
  36 + jQuery("#block_blog_options").toggle(blogSelected);
  37 + }
  38 + select.changedTo('<%= selected.id %>');
  39 + </script>
9 40 <% end %>
10 41 </div>
... ...
app/views/box_organizer/_highlights_block.rhtml
... ... @@ -5,7 +5,7 @@
5 5 <% for image in @block.images do %>
6 6 <tr>
7 7 <td>
8   - <%= select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i), :style => "width: 100px" %></p>
  8 + <%= select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i).html_safe, :style => "width: 100px" %></p>
9 9 </td>
10 10 <td><%= text_field_tag 'block[images][][address]', image[:address], :class => 'highlight-address', :size => 10 %></td>
11 11 <td><%= text_field_tag 'block[images][][position]', image[:position], :class => 'highlight-position', :size => 3 %></td>
... ... @@ -17,7 +17,7 @@
17 17  
18 18 <%= link_to_function(_('New highlight'), nil, :class => 'button icon-add with-text') do |page|
19 19 page.insert_html :bottom, 'highlights', content_tag('tr',
20   - content_tag('td', select_tag('block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name), :style => "width: 100px")) +
  20 + content_tag('td', select_tag('block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name).html_safe, :style => "width: 100px")) +
21 21 content_tag('td', text_field_tag('block[images][][address]', nil, :class => 'highlight-address', :size => 10)) +
22 22 content_tag('td', text_field_tag('block[images][][position]', nil, :class => 'highlight-position', :size => 3)) +
23 23 content_tag('td', text_field_tag('block[images][][title]', nil, :class => 'highlight-position', :size => 10))
... ...
app/views/cms/_text_editor_sidebar.rhtml
... ... @@ -9,7 +9,12 @@
9 9 <div id='media-upload-form'>
10 10 <% form_tag({ :action => 'media_upload' }, :multipart => true) do %>
11 11 <div class='formfield'>
12   - <%= select_profile_folder(_('Choose folder to upload files:'), :parent_id, profile) %>
  12 + <% default_folder = content_id_to_str default_folder_for_image_upload(profile) %>
  13 + <%= select_profile_folder(
  14 + _('Choose folder to upload files:'),
  15 + :parent_id, profile, default_folder, {}, {},
  16 + 'type="Folder" or type="Gallery"'
  17 + ) %>
13 18 </div>
14 19 <p><%= file_field_tag('file1') %></p>
15 20 <p><%= file_field_tag('file2') %></p>
... ...
app/views/content_viewer/blog_page.rhtml
1   -<% add_rss_feed_to_head(@page.name, @page.feed.url) if @page.blog? && @page.feed %>
  1 +<% add_rss_feed_to_head(blog.name, blog.feed.url) if blog.blog? && blog.feed %>
2 2  
3   -<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if @page.blog? && @page.external_feed && @page.external_feed.enabled && @page.external_feed.fetched_at.nil? %>
  3 +<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if blog.blog? && blog.external_feed && blog.external_feed.enabled && blog.external_feed.fetched_at.nil? %>
4 4  
5 5 <div>
6 6 <div class='blog-description'>
7   - <%= @page.body %>
  7 + <%= blog.body %>
8 8 </div>
9 9 </div>
10 10 <hr class="pre-posts"/>
11 11 <div class="blog-posts">
12   - <%= (@page.empty? ? content_tag('em', _('(no posts)')) : list_posts(@posts, @page.visualization_format)) %>
  12 + <%=
  13 + posts = @posts
  14 + format = blog.visualization_format
  15 + if inside_block
  16 + posts = blog.posts.paginate(:page=>1, :per_page=>inside_block.posts_per_page)
  17 + format = inside_block.visualization_format
  18 + end
  19 + (blog.empty? ? content_tag('em', _('(no posts)')) : list_posts(posts, format))
  20 + %>
13 21 </div>
... ...
app/views/content_viewer/view_page.rhtml
... ... @@ -90,7 +90,7 @@
90 90 <% end %>
91 91  
92 92 <% if @page.accept_comments? && @comments_count > 1 %>
93   - <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form') %>
  93 + <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button') %>
94 94 <% end %>
95 95  
96 96 <ul class="article-comments-list">
... ...
app/views/favorite_enterprises/index.rhtml
... ... @@ -5,7 +5,7 @@
5 5 <ul class="profile-list">
6 6 <% @favorite_enterprises.each do |enterprise| %>
7 7 <li>
8   - <%= link_to_profile profile_image(enterprise) + '<br/>' + enterprise.name,
  8 + <%= link_to_profile profile_image(enterprise) + '<br/>'.html_safe + enterprise.name,
9 9 enterprise.identifier, :class => 'profile-link' %>
10 10 <%# profile_image_link enterprise, :portrait, 'div' %>
11 11 <div class="controll">
... ...
app/views/layouts/_user.html.erb 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +<div id="user">
  2 + <span class='logged-in' style='display: none;'>
  3 + <%= usermenu_logged_in %>
  4 + </span>
  5 + <span class='not-logged-in' style='display: none'>
  6 +
  7 + <%= _("<span class='login'>%s</span>") % thickbox_inline_popup_link('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, 'inlineLoginBox', :id => 'link_login') %>
  8 + <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_eval(&content) }.join("") %>
  9 +
  10 + <div id='inlineLoginBox' style='display: none;'>
  11 + <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>
  12 + </div>
  13 +
  14 + <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>
  15 + <%= _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to('<strong>' + _('Sign up') + '</strong>', :controller => 'account', :action => 'signup')%>
  16 + <% end %>
  17 +
  18 + </span>
  19 + <form action="/search" id="top-search" class="search_form clean" method="get">
  20 + <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" />
  21 + <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div>
  22 + <%= javascript_tag 'jQuery("#user form input").hint();' %>
  23 + </form>
  24 +</div><!-- end id="user" -->
... ...
app/views/layouts/application-ng.rhtml
... ... @@ -8,38 +8,19 @@
8 8 <meta name="description" content="<%= @environment.name %>" />
9 9 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" />
10 10 <%= noosfero_javascript %>
11   - <%= stylesheet_link_tag noosfero_stylesheets, :cache => 'cache' %>
12   - <%= stylesheet_link_tag template_stylesheet_path %>
13   - <%= stylesheet_link_tag icon_theme_stylesheet_path %>
14   - <%= stylesheet_link_tag jquery_ui_theme_stylesheet_path %>
15   - <%
16   - plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') }
17   - %>
18   - <%= stylesheet_link_tag(plugins_stylesheets, :cache => 'cache/plugins-' + Digest::MD5.hexdigest(plugins_stylesheets.to_s)) unless plugins_stylesheets.empty? %>
19   - <%= stylesheet_link_tag theme_stylesheet_path %>
  11 + <%= noosfero_stylesheets %>
20 12  
21 13 <%# Add custom tags/styles/etc via content_for %>
22 14 <%= yield :head %>
23   - <%= javascript_tag('render_all_jquery_ui_widgets()') %>
24   - <%
25   - plugins_javascripts = @plugins.map { |plugin| plugin.js_files.map { |js| plugin.class.public_path(js) } }.flatten
26   - %>
27   - <%= javascript_include_tag(plugins_javascripts, :cache => 'cache/plugins-' + Digest::MD5.hexdigest(plugins_javascripts.to_s)) unless plugins_javascripts.empty? %>
28 15 <%=
29 16 @plugins.dispatch(:head_ending).collect do |content|
30 17 content.respond_to?(:call) ? content.call : content
31 18 end.join("\n")
32 19 %>
33 20 </head>
34   - <body class="<%=
35   - # Identify the current controller and action for the CSS:
36   - " controller-"+ @controller.controller_name() +
37   - " action-"+ @controller.controller_name() +"-"+ @controller.action_name() +
38   - " template-"+ ( profile.nil? ? "default" : profile.layout_template ) +
39   - (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "")
40   - %>" >
41   -
  21 + <body class="<%= body_classes %>">
42 22 <a href="#content" id="link-go-content"><span><%= _("Go to the content") %></span></a>
  23 +
43 24 <%=
44 25 @plugins.dispatch(:body_beginning).collect do |content|
45 26 content.respond_to?(:call) ? content.call : content
... ... @@ -51,31 +32,7 @@
51 32 <%= theme_header %>
52 33 </div>
53 34 <div id="wrap-2">
54   - <div id="user">
55   - <span class='logged-in' style='display: none;'>
56   - <%= usermenu_logged_in %>
57   - </span>
58   - <span class='not-logged-in' style='display: none'>
59   -
60   - <%= _("<span class='login'>%s</span>") % thickbox_inline_popup_link('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, 'inlineLoginBox', :id => 'link_login') %>
61   - <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_eval(&content) }.join("") %>
62   -
63   - <div id='inlineLoginBox' style='display: none;'>
64   - <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>
65   - </div>
66   -
67   - <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>
68   - <%= _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to('<strong>' + _('Sign up') + '</strong>', :controller => 'account', :action => 'signup')%>
69   - <% end %>
70   -
71   - </span>
72   - <form id="top-search" action="/search" class="search_form clean" method="get">
73   - <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" />
74   - <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div>
75   - <%= javascript_tag 'jQuery("#user form input").hint();' %>
76   - </form>
77   - </div><!-- end id="user" -->
78   -
  35 + <%= render :partial => 'layouts/user' %>
79 36 <h1 id="site-title">
80 37 <%= theme_site_title %>
81 38 </h1>
... ...
app/views/profile/_profile_wall.rhtml
1 1 <h3><%= _("%s's wall") % @profile.name %></h3>
2 2 <div id='leave_scrap'>
3 3 <%= flash[:error] %>
4   - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''" do %>
  4 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''", :complete => "jQuery('#leave_scrap_form').removeClass('loading').find('*').attr('disabled', false)", :loading => "jQuery('#leave_scrap_form').addClass('loading').find('*').attr('disabled', true)", :html => {:id => 'leave_scrap_form' } do %>
5 5 <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %>
6 6 <%= submit_button :new, _('Share') %>
7 7 <% end %>
... ...
app/views/profile_members/_manage_roles.html.erb
... ... @@ -13,11 +13,11 @@
13 13  
14 14 <% @roles.each do |role| %>
15 15 <% search_url = url_for(:action => 'search_user', :profile => profile.identifier, :role => role.id) %>
16   - <% @pre_population ||= profile.members_by_role_to_json(role) %>
  16 + <% pre_population = params[:action] == 'last_admin' ? [].to_json : profile.members_by_role_to_json(role) %>
17 17 <script type="text/javascript">
18 18 jQuery(<%= ('#search_' + role.key).to_json %>)
19 19 .tokenInput("<%= search_url %>", {
20   - prePopulate: <%= @pre_population %>,
  20 + prePopulate: <%= pre_population %>,
21 21 hintText: <%= _('Type in a search term for users').to_json %>,
22 22 noResultsText: <%= _('No results').to_json %>,
23 23 searchingText: <%= _('Searching...').to_json %>,
... ...
app/views/templates/index.html.erb
... ... @@ -2,9 +2,9 @@
2 2  
3 3 <%= _('Manage the templates used on creation of profiles') %>
4 4  
5   -<% list_of_templates = [[_('Person') , Person.templates , 'person' ],
6   - [_('Community') , Community.templates , 'community' ],
7   - [_('Enterprise'), Enterprise.templates, 'enterprise']] %>
  5 +<% list_of_templates = [[_('Person') , Person.templates(environment) , 'person' ],
  6 + [_('Community') , Community.templates(environment) , 'community' ],
  7 + [_('Enterprise'), Enterprise.templates(environment), 'enterprise']] %>
8 8  
9 9 <% list_of_templates.each do |title, templates, kind|%>
10 10 <div class='template-kind'>
... ...
app/views/themes/index.rhtml
... ... @@ -11,17 +11,17 @@
11 11 base_content = image_tag(
12 12 "/designs/templates/#{template.id}/thumbnail.png",
13 13 :alt => _('The "%s" template')) +
14   - '<div class="opt-info">' +
  14 + '<div class="opt-info">'.html_safe +
15 15 content_tag('strong', template.id, :class => 'name') +
16   - ' <br/> '
  16 + ' <br/> '.html_safe
17 17  
18 18 if @current_template == template.id # selected
19 19 content_tag( 'div',
20   - base_content + content_tag('big', _('(current)') ) +'</div>',
  20 + base_content + content_tag('big', _('(current)') ) +'</div>'.html_safe,
21 21 :class => 'template-opt list-opt selected')
22 22 else # Not selected
23 23 link_to(
24   - base_content +'</div>',
  24 + base_content +'</div>'.html_safe,
25 25 { :action => 'set_layout_template', :id => template.id },
26 26 :class => 'template-opt list-opt')
27 27 end
... ... @@ -48,17 +48,17 @@
48 48 base_content = image_tag(
49 49 "/designs/themes/#{theme.id}/preview.png",
50 50 :alt => (_('The "%s" theme.') % theme.name)) +
51   - '<div class="opt-info">' +
  51 + '<div class="opt-info">'.html_safe +
52 52 content_tag('strong', theme.name, :class => 'name') +
53   - ' <br/> '
  53 + ' <br/> '.html_safe
54 54  
55 55 if theme.id == @current_theme # selected
56 56 content_tag( 'div',
57   - base_content + content_tag('big', _('(current)') ) +'</div>',
  57 + base_content + content_tag('big', _('(current)') ) +'</div>'.html_safe,
58 58 :class => 'theme-opt list-opt selected')
59 59 else # Not selected
60 60 link_to(
61   - base_content + '</div>',
  61 + base_content + '</div>'.html_safe,
62 62 { :action => 'set', :id => theme.id },
63 63 :class => 'theme-opt list-opt')
64 64 end
... ...
app/views/users/_user_csv.rhtml
... ... @@ -1 +0,0 @@
1   -<%= user_csv.name %>;<%= user_csv.email %>
app/views/users/index_csv.rhtml
... ... @@ -1,2 +0,0 @@
1   -<%= _('name') %>;<%= _('email') %>
2   -<%= render :partial => 'user_csv', :collection => @users %>
config/cucumber.yml
1   -default: --color --format progress --strict --tags ~@selenium --tags ~@selenium-fixme --tags ~@fixme --exclude features/support/selenium.rb -r features/support -r features/step_definitions
2   -selenium: --strict --tags @selenium -r features/support -r features/step_definitions
  1 +<% base_requires = '-r features/support -r features/step_definitions' %>
  2 +<% default_options = "--color --format progress --strict --tags ~@selenium --tags ~@selenium-fixme --tags ~@fixme --exclude features/support/selenium.rb #{base_requires}" %>
  3 +<% selenium_options = "--strict --tags @selenium #{base_requires}" %>
  4 +
  5 +default: <%= default_options %>
  6 +selenium: <%= selenium_options %>
  7 +
  8 +<% enabled_plugins = Dir.glob(File.join('config', 'plugins', '*')).map{|path| plugin = File.basename(path); plugin if File.exist?(File.join('features', 'plugins', plugin)) }.compact %>
  9 +
  10 +<% enabled_plugins.each do |plugin| %>
  11 +<% plugin_features_path = File.join('features', 'plugins', plugin) %>
  12 +<% plugin_base_requires = '' %>
  13 +<% plugin_base_requires += " -r features/plugins/#{plugin}/support" if File.exist?(File.join(plugin_features_path, 'support')) %>
  14 +<% plugin_base_requires += " -r features/plugins/#{plugin}/step_definitions" if File.exist?(File.join(plugin_features_path, 'step_definitions')) %>
  15 +<%= "#{plugin}: #{default_options} #{plugin_base_requires}" %>
  16 +<%= "#{plugin}_selenium: #{selenium_options} #{plugin_base_requires}" %>
  17 +<% end %>
... ...
debian/changelog
  1 +noosfero (0.41.2) unstable; urgency=low
  2 +
  3 + * Bugfixes release
  4 +
  5 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Wed, 17 Apr 2013 16:22:53 -0300
  6 +
1 7 noosfero (0.41.1) unstable; urgency=low
2 8  
3 9 * Bugfixes release
... ...
features/plugins/README 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +This directory must contain symbolink links to the Noosfero plugins features
  2 +files folder.
... ...
features/step_definitions/mezuro_steps.rb
... ... @@ -1,14 +0,0 @@
1   -Then /^I directly delete content with name "([^\"]*)" for testing purposes$/ do |content_name|
2   - Article.find_by_name(content_name).destroy
3   -end
4   -
5   -Then /^I should be at the url "([^\"]*)"$/ do |url|
6   - if response.class.to_s == 'Webrat::SeleniumResponse'
7   - URI.parse(response.selenium.get_location).path.should == url
8   - else
9   - URI.parse(current_url).path.should == url
10   - end
11   -end
12   -
13   -Then /^I don't fill anything$/ do
14   -end
features/step_definitions/noosfero_steps.rb
... ... @@ -761,3 +761,9 @@ Given /^there are no pending jobs$/ do
761 761 Delayed::Worker.new.work_off
762 762 end
763 763 end
  764 +
  765 +When /^I confirm the "(.*)" dialog$/ do |confirmation|
  766 + a = page.driver.browser.switch_to.alert
  767 + assert_equal confirmation, a.text
  768 + a.accept
  769 +end
... ...
lib/noosfero.rb
... ... @@ -3,7 +3,7 @@ require &#39;fast_gettext&#39;
3 3  
4 4 module Noosfero
5 5 PROJECT = 'noosfero'
6   - VERSION = '0.41.1'
  6 + VERSION = '0.41.2'
7 7  
8 8 def self.pattern_for_controllers_in_directory(dir)
9 9 disjunction = controllers_in_directory(dir).join('|')
... ...
lib/noosfero/plugin.rb
... ... @@ -97,6 +97,35 @@ class Noosfero::Plugin
97 97 ERB.new(File.read("#{views_path}/#{file_path}")).result(binding)
98 98 end
99 99  
  100 + def extra_blocks(params = {})
  101 + return [] if self.class.extra_blocks.nil?
  102 + blocks = self.class.extra_blocks.map do |block, options|
  103 + type = options[:type]
  104 + type = type.is_a?(Array) ? type : [type].compact
  105 + type = type.map do |x|
  106 + x.is_a?(String) ? x.capitalize.constantize : x
  107 + end
  108 + raise "This is not a valid type" if !type.empty? && ![Person, Community, Enterprise, Environment].detect{|m| type.include?(m)}
  109 +
  110 + position = options[:position]
  111 + position = position.is_a?(Array) ? position : [position].compact
  112 + position = position.map{|p| p.to_i}
  113 + raise "This is not a valid position" if !position.empty? && ![1,2,3].detect{|m| position.include?(m)}
  114 +
  115 + if !type.empty? && (params[:type] != :all)
  116 + block = type.include?(params[:type]) ? block : nil
  117 + end
  118 +
  119 + if !position.empty? && !params[:position].nil?
  120 + block = position.detect{ |p| [params[:position]].flatten.include?(p)} ? block : nil
  121 + end
  122 +
  123 + block
  124 + end
  125 + blocks.compact!
  126 + blocks || []
  127 + end
  128 +
100 129 # Here the developer may specify the events to which the plugins can
101 130 # register and must return true or false. The default value must be false.
102 131  
... ... @@ -358,6 +387,60 @@ class Noosfero::Plugin
358 387 def find_by_contents(asset, scope, query, paginate_options={}, options={})
359 388 end
360 389  
  390 + # -> Adds additional blocks to profiles and environments.
  391 + # Your plugin must implements a class method called 'extra_blocks'
  392 + # that returns a hash with the following syntax.
  393 + # {
  394 + # 'block_name' =>
  395 + # {
  396 + # :type => 'for which holder the block will be available',
  397 + # :position => 'where the block could be displayed'
  398 + # }
  399 + # }
  400 + #
  401 + # Where:
  402 + #
  403 + # - block_name: Name of the new block added to the blocks list
  404 + # - type: Might have some of the values
  405 + # - 'environment' or Environment: If the block is available only for Environment models
  406 + # - 'community' or Community: If the block is available only for Community models
  407 + # - 'enterprise' or Enterprise: If the block is available only for Enterprise models
  408 + # - 'person' or Person: If the block is available only for Person models
  409 + # - nil: If no type parameter is passed the block will be available for all types
  410 + # - position: Is the layout position of the block. It should be:
  411 + # - '1' or 1: Area 1 of layout
  412 + # - '2' or 2: Area 2 of layout
  413 + # - '3' or 3: Area 3 of layout
  414 + # - nil: If no position parameter is passed the block will be available for all positions
  415 + #
  416 + # OBS: Area 1 is where stay the main content of layout. Areas 2 and 3 are the sides of layout.
  417 + #
  418 + # examples:
  419 + #
  420 + # def self.extra_blocks(params)
  421 + # {
  422 + # #Display 'CustomBlock1' only for 'Person' on position '1'
  423 + # CustomBlock1 => {:type => 'person', :position => '1' },
  424 + #
  425 + # #Display 'CustomBlock2' only for 'Community' on position '2'
  426 + # CustomBlock2 => {:type => Community, :position => '2' },
  427 + #
  428 + # #Display 'CustomBlock3' only for 'Enterprise' on position '3'
  429 + # CustomBlock3 => {:type => 'enterprise', :position => 3 },
  430 + #
  431 + # #Display 'CustomBlock2' for 'Environment' and 'Person' on positions '1' and '3'
  432 + # CustomBlock4 => {:type => ['environment', Person], :position => ['1','3'] },
  433 + #
  434 + # #Display 'CustomBlock5' for all types and all positions
  435 + # CustomBlock5 => {},
  436 + # }
  437 + # end
  438 + #
  439 + # OBS: The default value is a empty hash.
  440 + def self.extra_blocks
  441 + {}
  442 + end
  443 +
361 444 def method_missing(method, *args, &block)
362 445 # This is a generic hotspot for all controllers on Noosfero.
363 446 # If any plugin wants to define filters to run on any controller, the name of
... ...
lib/tasks/plugins_tests.rake
... ... @@ -17,6 +17,14 @@ def plugin_name(plugin)
17 17 "#{plugin} plugin"
18 18 end
19 19  
  20 +def plugin_enabled?(plugin)
  21 + File.exist?(File.join('config', 'plugins', plugin))
  22 +end
  23 +
  24 +def plugin_disabled_warning(plugin)
  25 + puts "E: you should enable #{plugin} plugin before running it's tests!"
  26 +end
  27 +
20 28 def run_tests(name, files_glob)
21 29 files = Dir.glob(files_glob)
22 30 if files.empty?
... ... @@ -38,21 +46,33 @@ end
38 46 def plugin_test_task(name, plugin, files_glob)
39 47 desc "Run #{name} tests for #{plugin_name(plugin)}"
40 48 task name => 'db:test:plugins:prepare' do |t|
41   - run_tests t.name, files_glob
  49 + if plugin_enabled?(plugin)
  50 + run_tests t.name, files_glob
  51 + else
  52 + plugin_disabled_warning(plugin)
  53 + end
42 54 end
43 55 end
44 56  
45 57 def plugin_cucumber_task(name, plugin, files_glob)
46 58 desc "Run #{name} tests for #{plugin_name(plugin)}"
47 59 task name => 'db:test:plugins:prepare' do |t|
48   - run_cucumber t.name, :default, files_glob
  60 + if plugin_enabled?(plugin)
  61 + run_cucumber t.name, plugin, files_glob
  62 + else
  63 + plugin_disabled_warning(plugin)
  64 + end
49 65 end
50 66 end
51 67  
52 68 def plugin_selenium_task(name, plugin, files_glob)
53 69 desc "Run #{name} tests for #{plugin_name(plugin)}"
54 70 task name => 'db:test:plugins:prepare' do |t|
55   - run_cucumber t.name, :selenium, files_glob
  71 + if plugin_enabled?(plugin)
  72 + run_cucumber t.name, "#{plugin}_selenium", files_glob
  73 + else
  74 + plugin_disabled_warning(plugin)
  75 + end
56 76 end
57 77 end
58 78  
... ... @@ -81,8 +101,8 @@ namespace :test do
81 101 plugin_test_task :units, plugin, "plugins/#{plugin}/test/unit/**/*.rb"
82 102 plugin_test_task :functionals, plugin, "plugins/#{plugin}/test/functional/**/*.rb"
83 103 plugin_test_task :integration, plugin, "plugins/#{plugin}/test/integration/**/*.rb"
84   - plugin_cucumber_task :cucumber, plugin, "plugins/#{plugin}/test/features/**/*.feature"
85   - plugin_selenium_task :selenium, plugin, "plugins/#{plugin}/test/features/**/*.feature"
  104 + plugin_cucumber_task :cucumber, plugin, "plugins/#{plugin}/features/**/*.feature"
  105 + plugin_selenium_task :selenium, plugin, "plugins/#{plugin}/features/**/*.feature"
86 106 end
87 107  
88 108 test_sequence_task(plugin, plugin, "#{plugin}:units", "#{plugin}:functionals", "#{plugin}:integration", "#{plugin}:cucumber", "#{plugin}:selenium")
... ...
plugins/bsc/features/bsc.feature 0 → 100644
... ... @@ -0,0 +1,164 @@
  1 +Feature: bsc
  2 +
  3 + Background:
  4 + Given "Bsc" plugin is enabled
  5 +
  6 + Scenario: display link to bsc creation on admin panel when bsc plugin active
  7 + Given I am logged in as admin
  8 + When I am on the environment control panel
  9 + Then I should see "Create Bsc"
  10 + When "Bsc" plugin is disabled
  11 + And I am on the environment control panel
  12 + Then I should not see "Create Bsc"
  13 +
  14 + Scenario: be able to create a bsc
  15 + Given I am logged in as admin
  16 + And I am on the environment control panel
  17 + And I follow "Create Bsc"
  18 + And I fill in the following:
  19 + | Business name | Sample Bsc |
  20 + | Company name | Sample Bsc |
  21 + | profile_data_identifier | sample-identifier |
  22 + | Cnpj | 07.970.746/0001-77 |
  23 + When I press "Save"
  24 + Then there should be a profile named "Sample Bsc"
  25 +
  26 + Scenario: display a button on bsc control panel to manage associated enterprises
  27 + Given the folllowing "bsc" from "bsc_plugin"
  28 + | business_name | identifier | company_name | cnpj |
  29 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
  30 + And I am logged in as admin
  31 + When I am on Bsc Test's control panel
  32 + Then I should see "Manage associated enterprises"
  33 +
  34 + Scenario: display a button on bsc control panel to transfer ownership
  35 + Given the folllowing "bsc" from "bsc_plugin"
  36 + | business_name | identifier | company_name | cnpj |
  37 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
  38 + And I am logged in as admin
  39 + When I am on Bsc Test's control panel
  40 + Then I should see "Transfer ownership"
  41 +
  42 + Scenario: create a new enterprise already associated with a bsc
  43 + Given the following user
  44 + | login | name |
  45 + | pedro-silva | Pedro Silva |
  46 + And the folllowing "bsc" from "bsc_plugin"
  47 + | business_name | identifier | company_name | cnpj | owner |
  48 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 | pedro-silva |
  49 + And organization_approval_method is "none" on environment
  50 + And I am logged in as "pedro-silva"
  51 + And I am on Bsc Test's control panel
  52 + And I follow "Manage associated enterprises"
  53 + And I follow "Add new enterprise"
  54 + And I fill in the following:
  55 + | Name | Associated Enterprise |
  56 + | Address | associated-enterprise |
  57 + When I press "Save"
  58 + Then "Associated Enterprise" should be associated with "Bsc Test"
  59 +
  60 + Scenario: do not display "add new product" button
  61 + Given the following user
  62 + | login | name |
  63 + | pedro-silva | Pedro Silva |
  64 + And the folllowing "bsc" from "bsc_plugin"
  65 + | business_name | identifier | company_name | cnpj | owner |
  66 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 | pedro-silva |
  67 + And feature "disable_products_for_enterprises" is disabled on environment
  68 + And I am logged in as "pedro-silva"
  69 + And I am on Bsc Test's control panel
  70 + When I follow "Manage Products and Services"
  71 + Then I should not see "New product or service"
  72 +
  73 + Scenario: display bsc's enterprises' products name on the bsc catalog
  74 + Given the following user
  75 + | login | name |
  76 + | pedro-silva | Pedro Silva |
  77 + And the folllowing "bsc" from "bsc_plugin"
  78 + | business_name | identifier | company_name | cnpj | owner |
  79 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 | pedro-silva |
  80 + And the following enterprise
  81 + | identifier | name |
  82 + | sample-enterprise | Sample Enterprise |
  83 + And the following product_category
  84 + | name |
  85 + | bike |
  86 + And the following products
  87 + | owner | category | name |
  88 + | sample-enterprise | bike | Master Bike |
  89 + And "Sample Enterprise" is associated with "Bsc Test"
  90 + And I am logged in as "pedro-silva"
  91 + When I go to Bsc Test's products page
  92 + Then I should see "Master Bike"
  93 + And I should see "Sample Enterprise"
  94 +
  95 + Scenario: display enterprise name linked only if person is member of any Bsc
  96 + Given the folllowing "bsc" from "bsc_plugin"
  97 + | business_name | identifier | company_name | cnpj |
  98 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
  99 + | Another Bsc | another-bsc | Another Bsc Test Ltda | 07.970.746/0001-77 |
  100 + And the following enterprise
  101 + | identifier | name |
  102 + | sample-enterprise | Sample Enterprise |
  103 + And the following product_category
  104 + | name |
  105 + | bike |
  106 + And the following products
  107 + | owner | category | name |
  108 + | sample-enterprise | bike | Master Bike |
  109 + And "Sample Enterprise" is associated with "Bsc Test"
  110 + And the folllowing "bsc" from "bsc_plugin"
  111 + | business_name | identifier | company_name | cnpj |
  112 + And the following user
  113 + | login | name |
  114 + | pedro | Pedro Souto |
  115 + | maria | Maria Souto |
  116 + And pedro is member of another-bsc
  117 + And I am logged in as "pedro"
  118 + When I go to Bsc Test's products page
  119 + Then I should see "Sample Enterprise"
  120 + And I should see "Sample Enterprise" within "a.bsc-catalog-enterprise-link"
  121 + But I am logged in as "maria"
  122 + When I go to Bsc Test's products page
  123 + Then I should see "Sample Enterprise"
  124 + #TODO -> test that it's not a link
  125 +
  126 + Scenario: allow only environment administrators to delete bsc profile
  127 + Given the folllowing "bsc" from "bsc_plugin"
  128 + | business_name | identifier | company_name | cnpj |
  129 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
  130 + And the following user
  131 + | login | name |
  132 + | pedro | Pedro Souto |
  133 + And "Pedro Souto" is admin of "Bsc Test"
  134 + And I am logged in as "pedro"
  135 + And I am on Bsc Test's control panel
  136 + And I follow "Bsc info and settings"
  137 + When I follow "Delete profile"
  138 + Then I should see "Access denied"
  139 + And "Bsc Test" profile should exist
  140 + But I am logged in as admin
  141 + And I am on Bsc Test's control panel
  142 + And I follow "Bsc info and settings"
  143 + When I follow "Delete profile"
  144 + Then I should see "Deleting profile Bsc Test"
  145 + And I follow "Yes, I am sure"
  146 + Then "Bsc Test" profile should not exist
  147 +
  148 + # Like we can believe that selenium is going to work...
  149 + @selenium
  150 + Scenario: list already associated enterprises on manage associated enterprises
  151 + Given the folllowing "bsc" from "bsc_plugin"
  152 + | business_name | identifier | company_name | cnpj |
  153 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
  154 + And the following enterprises
  155 + | identifier | name |
  156 + | enterprise-1 | Enterprise 1 |
  157 + | enterprise-2 | Enterprise 2 |
  158 + And "Enterprise 1" is associated with "Bsc Test"
  159 + And "Enterprise 2" is associated with "Bsc Test"
  160 + And I am logged in as admin
  161 + And I am on Bsc Test's control panel
  162 + When I follow "Manage associated enterprises"
  163 + Then I should see "Enterprise 1"
  164 + And I should see "Enterprise 2"
... ...
plugins/bsc/features/contract.feature 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +Feature: Bsc contract
  2 +As a Bsc admin
  3 +I would like to register a contract
  4 +In order to make negotiations
  5 +
  6 + Background:
  7 + Given "Bsc" plugin is enabled
  8 + And the folllowing "bsc" from "bsc_plugin"
  9 + | business_name | identifier | company_name | cnpj |
  10 + | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
  11 + And I am logged in as admin
  12 +
  13 + Scenario: be able see the manage contracts button only if the profile is a Bsc
  14 + Given the following community
  15 + | name | identifier |
  16 + | Sample Community | sample-community |
  17 + When I am on Sample Community's control panel
  18 + Then I should not see "Manage contracts"
  19 + But I am on Bsc Test's control panel
  20 + Then I should see "Manage contracts"
  21 +
... ...
plugins/bsc/test/features/bsc.feature
... ... @@ -1,164 +0,0 @@
1   -Feature: bsc
2   -
3   - Background:
4   - Given "Bsc" plugin is enabled
5   -
6   - Scenario: display link to bsc creation on admin panel when bsc plugin active
7   - Given I am logged in as admin
8   - When I am on the environment control panel
9   - Then I should see "Create Bsc"
10   - When "Bsc" plugin is disabled
11   - And I am on the environment control panel
12   - Then I should not see "Create Bsc"
13   -
14   - Scenario: be able to create a bsc
15   - Given I am logged in as admin
16   - And I am on the environment control panel
17   - And I follow "Create Bsc"
18   - And I fill in the following:
19   - | Business name | Sample Bsc |
20   - | Company name | Sample Bsc |
21   - | profile_data_identifier | sample-identifier |
22   - | Cnpj | 07.970.746/0001-77 |
23   - When I press "Save"
24   - Then there should be a profile named "Sample Bsc"
25   -
26   - Scenario: display a button on bsc control panel to manage associated enterprises
27   - Given the folllowing "bsc" from "bsc_plugin"
28   - | business_name | identifier | company_name | cnpj |
29   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
30   - And I am logged in as admin
31   - When I am on Bsc Test's control panel
32   - Then I should see "Manage associated enterprises"
33   -
34   - Scenario: display a button on bsc control panel to transfer ownership
35   - Given the folllowing "bsc" from "bsc_plugin"
36   - | business_name | identifier | company_name | cnpj |
37   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
38   - And I am logged in as admin
39   - When I am on Bsc Test's control panel
40   - Then I should see "Transfer ownership"
41   -
42   - Scenario: create a new enterprise already associated with a bsc
43   - Given the following user
44   - | login | name |
45   - | pedro-silva | Pedro Silva |
46   - And the folllowing "bsc" from "bsc_plugin"
47   - | business_name | identifier | company_name | cnpj | owner |
48   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 | pedro-silva |
49   - And organization_approval_method is "none" on environment
50   - And I am logged in as "pedro-silva"
51   - And I am on Bsc Test's control panel
52   - And I follow "Manage associated enterprises"
53   - And I follow "Add new enterprise"
54   - And I fill in the following:
55   - | Name | Associated Enterprise |
56   - | Address | associated-enterprise |
57   - When I press "Save"
58   - Then "Associated Enterprise" should be associated with "Bsc Test"
59   -
60   - Scenario: do not display "add new product" button
61   - Given the following user
62   - | login | name |
63   - | pedro-silva | Pedro Silva |
64   - And the folllowing "bsc" from "bsc_plugin"
65   - | business_name | identifier | company_name | cnpj | owner |
66   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 | pedro-silva |
67   - And feature "disable_products_for_enterprises" is disabled on environment
68   - And I am logged in as "pedro-silva"
69   - And I am on Bsc Test's control panel
70   - When I follow "Manage Products and Services"
71   - Then I should not see "New product or service"
72   -
73   - Scenario: display bsc's enterprises' products name on the bsc catalog
74   - Given the following user
75   - | login | name |
76   - | pedro-silva | Pedro Silva |
77   - And the folllowing "bsc" from "bsc_plugin"
78   - | business_name | identifier | company_name | cnpj | owner |
79   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 | pedro-silva |
80   - And the following enterprise
81   - | identifier | name |
82   - | sample-enterprise | Sample Enterprise |
83   - And the following product_category
84   - | name |
85   - | bike |
86   - And the following products
87   - | owner | category | name |
88   - | sample-enterprise | bike | Master Bike |
89   - And "Sample Enterprise" is associated with "Bsc Test"
90   - And I am logged in as "pedro-silva"
91   - When I go to Bsc Test's products page
92   - Then I should see "Master Bike"
93   - And I should see "Sample Enterprise"
94   -
95   - Scenario: display enterprise name linked only if person is member of any Bsc
96   - Given the folllowing "bsc" from "bsc_plugin"
97   - | business_name | identifier | company_name | cnpj |
98   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
99   - | Another Bsc | another-bsc | Another Bsc Test Ltda | 07.970.746/0001-77 |
100   - And the following enterprise
101   - | identifier | name |
102   - | sample-enterprise | Sample Enterprise |
103   - And the following product_category
104   - | name |
105   - | bike |
106   - And the following products
107   - | owner | category | name |
108   - | sample-enterprise | bike | Master Bike |
109   - And "Sample Enterprise" is associated with "Bsc Test"
110   - And the folllowing "bsc" from "bsc_plugin"
111   - | business_name | identifier | company_name | cnpj |
112   - And the following user
113   - | login | name |
114   - | pedro | Pedro Souto |
115   - | maria | Maria Souto |
116   - And pedro is member of another-bsc
117   - And I am logged in as "pedro"
118   - When I go to Bsc Test's products page
119   - Then I should see "Sample Enterprise"
120   - And I should see "Sample Enterprise" within "a.bsc-catalog-enterprise-link"
121   - But I am logged in as "maria"
122   - When I go to Bsc Test's products page
123   - Then I should see "Sample Enterprise"
124   - #TODO -> test that it's not a link
125   -
126   - Scenario: allow only environment administrators to delete bsc profile
127   - Given the folllowing "bsc" from "bsc_plugin"
128   - | business_name | identifier | company_name | cnpj |
129   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
130   - And the following user
131   - | login | name |
132   - | pedro | Pedro Souto |
133   - And "Pedro Souto" is admin of "Bsc Test"
134   - And I am logged in as "pedro"
135   - And I am on Bsc Test's control panel
136   - And I follow "Bsc info and settings"
137   - When I follow "Delete profile"
138   - Then I should see "Access denied"
139   - And "Bsc Test" profile should exist
140   - But I am logged in as admin
141   - And I am on Bsc Test's control panel
142   - And I follow "Bsc info and settings"
143   - When I follow "Delete profile"
144   - Then I should see "Deleting profile Bsc Test"
145   - And I follow "Yes, I am sure"
146   - Then "Bsc Test" profile should not exist
147   -
148   - # Like we can believe that selenium is going to work...
149   - @selenium
150   - Scenario: list already associated enterprises on manage associated enterprises
151   - Given the folllowing "bsc" from "bsc_plugin"
152   - | business_name | identifier | company_name | cnpj |
153   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
154   - And the following enterprises
155   - | identifier | name |
156   - | enterprise-1 | Enterprise 1 |
157   - | enterprise-2 | Enterprise 2 |
158   - And "Enterprise 1" is associated with "Bsc Test"
159   - And "Enterprise 2" is associated with "Bsc Test"
160   - And I am logged in as admin
161   - And I am on Bsc Test's control panel
162   - When I follow "Manage associated enterprises"
163   - Then I should see "Enterprise 1"
164   - And I should see "Enterprise 2"
plugins/bsc/test/features/contract.feature
... ... @@ -1,21 +0,0 @@
1   -Feature: Bsc contract
2   -As a Bsc admin
3   -I would like to register a contract
4   -In order to make negotiations
5   -
6   - Background:
7   - Given "Bsc" plugin is enabled
8   - And the folllowing "bsc" from "bsc_plugin"
9   - | business_name | identifier | company_name | cnpj |
10   - | Bsc Test | bsc-test | Bsc Test Ltda | 94.132.024/0001-48 |
11   - And I am logged in as admin
12   -
13   - Scenario: be able see the manage contracts button only if the profile is a Bsc
14   - Given the following community
15   - | name | identifier |
16   - | Sample Community | sample-community |
17   - When I am on Sample Community's control panel
18   - Then I should not see "Manage contracts"
19   - But I am on Bsc Test's control panel
20   - Then I should see "Manage contracts"
21   -
plugins/display_content/README 0 → 100644
... ... @@ -0,0 +1,70 @@
  1 +README - DisplayContent (DisplayContent Plugin)
  2 +================================
  3 +
  4 +DisplayContent is a plugin to allow the user adds a block where you could choose any of your content for display it.
  5 +
  6 +The DisplayContent block will be available for all layout columns of communities, peole, enterprises and environments.
  7 +
  8 +All the articles choosen are displayed as a list with a link for the title and the lead content.
  9 +
  10 +If a Blog or a Folder is choosen the block will display all articles inside the blog or the folder.
  11 +
  12 +Galleries are not displayed in this block.
  13 +
  14 +INSTALL
  15 +=======
  16 +
  17 +Enable Plugin
  18 +-------------
  19 +
  20 +Also, you need to enable DisplayContent Plugin at you Noosfero:
  21 +
  22 +cd <your_noosfero_dir>
  23 +./script/noosfero-plugins enable display_content
  24 +
  25 +Active Plugin
  26 +-------------
  27 +
  28 +As a Noosfero administrator user, go to administrator panel:
  29 +
  30 +- Click on "Enable/disable plugins" option
  31 +- Click on "Display Content Plugin" check-box
  32 +
  33 +DEVELOPMENT
  34 +===========
  35 +
  36 +Noosfero uses jQuery 1.5.1 and the jsTree doesn't works fine with this jQuery version.
  37 +Until Noosfero upgrade its JQuery version to a newer one is necessary to load jQuery 1.8.3 inside plugin and apply some changes in jsTree to avoid jQuery conflit.
  38 +
  39 +Get the Display Content (Noosfero with Display Content Plugin) development repository:
  40 +
  41 +$ git clone https://gitorious.org/+noosfero/noosfero/display_content
  42 +
  43 +Running DisplayContent tests
  44 +--------------------
  45 +
  46 +$ rake test:noosfero_plugins:display_content
  47 +
  48 +
  49 +Get Involved
  50 +============
  51 +
  52 +If you found any bug and/or want to collaborate, please send an e-mail to leandronunes@gmail.com
  53 +
  54 +LICENSE
  55 +=======
  56 +
  57 +Copyright (c) The Author developers.
  58 +
  59 +See Noosfero license.
  60 +
  61 +
  62 +AUTHORS
  63 +=======
  64 +
  65 + Leandro Nunes dos Santos (leandronunes at gmail.com)
  66 +
  67 +ACKNOWLEDGMENTS
  68 +===============
  69 +
  70 +The author have been supported by Serpro
... ...
plugins/display_content/controllers/display_content_plugin_admin_controller.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +require File.dirname(__FILE__) + '/display_content_plugin_module'
  2 +
  3 +class DisplayContentPluginAdminController < AdminController
  4 +
  5 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  6 +
  7 + include DisplayContentPluginController
  8 +
  9 +end
... ...
plugins/display_content/controllers/display_content_plugin_module.rb 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +module DisplayContentPluginController
  2 +
  3 + def index
  4 + block = boxes_holder.blocks.find(params[:block_id])
  5 +
  6 + articles = block.articles_of_parent(params[:id])
  7 + data = []
  8 + data = data + get_node(block, articles)
  9 + render :json => data
  10 + end
  11 +
  12 + protected
  13 +
  14 + def get_node(block, articles)
  15 + nodes = []
  16 + articles.map do |article|
  17 + node = {}
  18 + node[:data] = article.title
  19 + node[:attr] = { 'node_id' => article.id, 'parent_id' => article.parent_id}
  20 + if block.nodes.include?(article.id)
  21 + node[:attr].merge!('class' => 'jstree-checked')
  22 + elsif block.parent_nodes.include?(article.id)
  23 + node[:children] = get_node(block, article.children)
  24 + node[:attr].merge!('class' => 'jstree-undetermined')
  25 + end
  26 + node[:state] = 'closed' if Article.exists?(:parent_id => article.id)
  27 + nodes.push(node)
  28 + end
  29 + nodes
  30 + end
  31 +
  32 +end
... ...
plugins/display_content/controllers/display_content_plugin_myprofile_controller.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +require File.dirname(__FILE__) + '/display_content_plugin_module'
  2 +
  3 +class DisplayContentPluginMyprofileController < MyProfileController
  4 +
  5 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  6 +
  7 + include DisplayContentPluginController
  8 +
  9 +end
... ...
plugins/display_content/lib/display_content_block.rb 0 → 100644
... ... @@ -0,0 +1,86 @@
  1 +class DisplayContentBlock < Block
  2 +
  3 + settings_items :nodes, :type => Array, :default => []
  4 + settings_items :parent_nodes, :type => Array, :default => []
  5 + settings_items :chosen_attributes, :type => Array, :default => ['title']
  6 +
  7 + def self.description
  8 + _('Display your contents')
  9 + end
  10 +
  11 + def help
  12 + _('This block displays articles chosen by you. You can edit the block to select which of your articles is going to be displayed in the block.')
  13 + end
  14 +
  15 + def checked_nodes= params
  16 + return self.nodes if self.holder.nil?
  17 + articles = []
  18 + parent_articles = []
  19 + self.holder.articles.find(params.keys).map do |article|
  20 + if article.folder?
  21 + articles = articles + article.children
  22 + parent_articles << article.id
  23 + else
  24 + articles<< article
  25 + end
  26 + parent_articles = parent_articles + get_parent(article) unless parent_articles.include?(article.parent_id)
  27 + end
  28 + self.parent_nodes = parent_articles
  29 + self.nodes = articles.map{|a| a.id if a.is_a?(TextArticle) }.compact
  30 + end
  31 +
  32 + VALID_CONTENT = ['RawHTMLArticle', 'TextArticle', 'TextileArticle', 'TinyMceArticle', 'Folder', 'Blog', 'Forum']
  33 +
  34 + def articles_of_parent(parent = nil)
  35 + return [] if self.holder.nil?
  36 + holder.articles.find(:all, :conditions => {:type => VALID_CONTENT, :parent_id => (parent.nil? ? nil : parent)})
  37 + end
  38 +
  39 + include ActionController::UrlWriter
  40 + def content(args={})
  41 + docs = owner.articles.find(:all, :conditions => {:id => self.nodes})
  42 + block_title(title) +
  43 + content_tag('ul', docs.map {|item|
  44 + content_tag('li',
  45 + (display_attribute?('title') ? content_tag('div', link_to(h(item.title), item.url), :class => 'title') : '') +
  46 + (display_attribute?('abstract') ? content_tag('div', item.abstract ,:class => 'lead') : '') +
  47 + (display_attribute?('body') ? content_tag('div', item.body ,:class => 'body') : '')
  48 + )
  49 + }.join("\n"))
  50 +
  51 + end
  52 +
  53 + def url_params
  54 + params = {:block_id => self.id}
  55 + if self.owner.is_a?(Profile)
  56 + params.merge!(:controller => "display_content_plugin_myprofile")
  57 + params.merge!(:profile => self.holder.identifier)
  58 + else
  59 + params.merge!( :controller => "display_content_plugin_admin")
  60 + end
  61 + params
  62 + end
  63 +
  64 + def display_attribute?(attr)
  65 + chosen_attributes.include?(attr)
  66 + end
  67 +
  68 + protected
  69 +
  70 + def holder
  71 + return nil if self.box.nil? || self.box.owner.nil?
  72 + if self.box.owner.kind_of?(Environment)
  73 + return nil if self.box.owner.portal_community.nil?
  74 + self.box.owner.portal_community
  75 + else
  76 + self.box.owner
  77 + end
  78 + end
  79 +
  80 + def get_parent(article)
  81 + return [] if article.parent_id.nil?
  82 + parents = [article.parent.id] + get_parent(article.parent)
  83 + return parents
  84 + end
  85 +
  86 +end
... ...
plugins/display_content/lib/display_content_plugin.rb 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +require_dependency File.dirname(__FILE__) + '/display_content_block'
  2 +
  3 +class DisplayContentPlugin < Noosfero::Plugin
  4 +
  5 + def self.plugin_name
  6 + "Display Content Plugin"
  7 + end
  8 +
  9 + def self.plugin_description
  10 + _("A plugin that adds a block where you could choose any of your content and display it.")
  11 + end
  12 +
  13 + def self.extra_blocks
  14 + {
  15 + DisplayContentBlock => {}
  16 + }
  17 + end
  18 +
  19 + def self.has_admin_url?
  20 + false
  21 + end
  22 +
  23 + #FIXME make this test
  24 + def stylesheet?
  25 + true
  26 + end
  27 +
  28 + def js_files
  29 + ['/javascripts/jstree/_lib/jquery-1.8.3.js', '/javascripts/jstree/jquery.jstree.js']
  30 + end
  31 +
  32 +end
... ...
plugins/display_content/public/javascripts/jstree 0 → 120000
... ... @@ -0,0 +1 @@
  1 +jstree-v.pre1.0/
0 2 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/README.txt 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +jsTree pre1.0
  2 +http://jstree.com/
  3 +
  4 +Copyright (c) 2011 Ivan Bozhanov (vakata.com)
  5 +
  6 +Dual licensed under the MIT and GPL licenses:
  7 + http://www.opensource.org/licenses/mit-license.php
  8 + http://www.gnu.org/licenses/gpl.html
  9 +
  10 +This is the latest stable version before switching from GoogleCode to GitHub.
0 11 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/_dump.sql 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +CREATE TABLE IF NOT EXISTS `tree` (
  2 + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  3 + `parent_id` bigint(20) unsigned NOT NULL,
  4 + `position` bigint(20) unsigned NOT NULL,
  5 + `left` bigint(20) unsigned NOT NULL,
  6 + `right` bigint(20) unsigned NOT NULL,
  7 + `level` bigint(20) unsigned NOT NULL,
  8 + `title` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
  9 + `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  10 + PRIMARY KEY (`id`)
  11 +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=13 ;
  12 +
  13 +INSERT INTO `tree` (`id`, `parent_id`, `position`, `left`, `right`, `level`, `title`, `type`) VALUES
  14 +(1, 0, 2, 1, 14, 0, 'ROOT', ''),
  15 +(2, 1, 0, 2, 11, 1, 'C:', 'drive'),
  16 +(3, 2, 0, 3, 6, 2, '_demo', 'folder'),
  17 +(4, 3, 0, 4, 5, 3, 'index.html', 'default'),
  18 +(5, 2, 1, 7, 10, 2, '_docs', 'folder'),
  19 +(6, 1, 1, 12, 13, 1, 'D:', 'drive'),
  20 +(12, 5, 0, 8, 9, 3, 'zmei.html', 'default');
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/_inc/__mysql_errors.log 0 → 100644
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/_inc/class._database.php 0 → 100644
... ... @@ -0,0 +1,146 @@
  1 +<?php
  2 +class _database {
  3 + private $link = false;
  4 + private $result = false;
  5 + private $row = false;
  6 +
  7 + public $settings = array(
  8 + "servername"=> "localhost",
  9 + "serverport"=> "3306",
  10 + "username" => false,
  11 + "password" => false,
  12 + "database" => false,
  13 + "persist" => false,
  14 + "dieonerror"=> false,
  15 + "showerror" => false,
  16 + "error_file"=> true
  17 + );
  18 +
  19 + function __construct() {
  20 + global $db_config;
  21 + $this->settings = array_merge($this->settings, $db_config);
  22 + if($this->settings["error_file"] === true) $this->settings["error_file"] = dirname(__FILE__)."/__mysql_errors.log";
  23 + }
  24 +
  25 + function connect() {
  26 + if (!$this->link) {
  27 + $this->link = ($this->settings["persist"]) ?
  28 + mysql_pconnect(
  29 + $this->settings["servername"].":".$this->settings["serverport"],
  30 + $this->settings["username"],
  31 + $this->settings["password"]
  32 + ) :
  33 + mysql_connect(
  34 + $this->settings["servername"].":".$this->settings["serverport"],
  35 + $this->settings["username"],
  36 + $this->settings["password"]
  37 + ) or $this->error();
  38 + }
  39 + if (!mysql_select_db($this->settings["database"], $this->link)) $this->error();
  40 + if($this->link) mysql_query("SET NAMES 'utf8'");
  41 + return ($this->link) ? true : false;
  42 + }
  43 +
  44 + function query($sql) {
  45 + if (!$this->link && !$this->connect()) $this->error();
  46 + if (!($this->result = mysql_query($sql, $this->link))) $this->error($sql);
  47 + return ($this->result) ? true : false;
  48 + }
  49 +
  50 + function nextr() {
  51 + if(!$this->result) {
  52 + $this->error("No query pending");
  53 + return false;
  54 + }
  55 + unset($this->row);
  56 + $this->row = mysql_fetch_array($this->result, MYSQL_BOTH);
  57 + return ($this->row) ? true : false ;
  58 + }
  59 +
  60 + function get_row($mode = "both") {
  61 + if(!$this->row) return false;
  62 +
  63 + $return = array();
  64 + switch($mode) {
  65 + case "assoc":
  66 + foreach($this->row as $k => $v) {
  67 + if(!is_int($k)) $return[$k] = $v;
  68 + }
  69 + break;
  70 + case "num":
  71 + foreach($this->row as $k => $v) {
  72 + if(is_int($k)) $return[$k] = $v;
  73 + }
  74 + break;
  75 + default:
  76 + $return = $this->row;
  77 + break;
  78 + }
  79 + return array_map("stripslashes",$return);
  80 + }
  81 +
  82 + function get_all($mode = "both", $key = false) {
  83 + if(!$this->result) {
  84 + $this->error("No query pending");
  85 + return false;
  86 + }
  87 + $return = array();
  88 + while($this->nextr()) {
  89 + if($key !== false) $return[$this->f($key)] = $this->get_row($mode);
  90 + else $return[] = $this->get_row($mode);
  91 + }
  92 + return $return;
  93 + }
  94 +
  95 + function f($index) {
  96 + return stripslashes($this->row[$index]);
  97 + }
  98 +
  99 + function go_to($row) {
  100 + if(!$this->result) {
  101 + $this->error("No query pending");
  102 + return false;
  103 + }
  104 + if(!mysql_data_seek($this->result, $row)) $this->error();
  105 + }
  106 +
  107 + function nf() {
  108 + if ($numb = mysql_num_rows($this->result) === false) $this->error();
  109 + return mysql_num_rows($this->result);
  110 + }
  111 + function af() {
  112 + return mysql_affected_rows();
  113 + }
  114 + function error($string="") {
  115 + $error = mysql_error();
  116 + if($this->settings["show_error"]) echo $error;
  117 + if($this->settings["error_file"] !== false) {
  118 + $handle = @fopen($this->settings["error_file"], "a+");
  119 + if($handle) {
  120 + @fwrite($handle, "[".date("Y-m-d H:i:s")."] ".$string." <".$error.">\n");
  121 + @fclose($handle);
  122 + }
  123 + }
  124 + if($this->settings["dieonerror"]) {
  125 + if(isset($this->result)) mysql_free_result($this->result);
  126 + mysql_close($this->link);
  127 + die();
  128 + }
  129 + }
  130 + function insert_id() {
  131 + if(!$this->link) return false;
  132 + return mysql_insert_id();
  133 + }
  134 + function escape($string){
  135 + if(!$this->link) return addslashes($string);
  136 + return mysql_real_escape_string($string);
  137 + }
  138 +
  139 + function destroy(){
  140 + if (isset($this->result)) mysql_free_result($this->result);
  141 + if (isset($this->link)) mysql_close($this->link);
  142 + }
  143 +
  144 +
  145 +}
  146 +?>
0 147 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/_inc/class._database_i.php 0 → 100644
... ... @@ -0,0 +1,152 @@
  1 +<?php
  2 +class _database {
  3 + private $data = false;
  4 + private $result = false;
  5 + private $row = false;
  6 +
  7 + public $settings = array(
  8 + "servername"=> "localhost",
  9 + "serverport"=> "3306",
  10 + "username" => false,
  11 + "password" => false,
  12 + "database" => false,
  13 + "persist" => false,
  14 + "dieonerror"=> false,
  15 + "showerror" => false,
  16 + "error_file"=> true
  17 + );
  18 +
  19 + function __construct() {
  20 + global $db_config;
  21 + $this->settings = array_merge($this->settings, $db_config);
  22 + if($this->settings["error_file"] === true) $this->settings["error_file"] = dirname(__FILE__)."/__mysql_errors.log";
  23 + }
  24 +
  25 + function connect() {
  26 + $this->data = new mysqli(
  27 + $this->settings["servername"],
  28 + $this->settings["username"],
  29 + $this->settings["password"],
  30 + $this->settings["database"],
  31 + $this->settings["serverport"]
  32 + );
  33 +
  34 + if(mysqli_connect_errno()) {
  35 + $this->error("Connection error: ".mysqli_connect_error() );
  36 + return false;
  37 + }
  38 + if(!$this->data->set_charset("utf8")) {
  39 + $this->error("Error loading character set utf8");
  40 + return false;
  41 + }
  42 + return true;
  43 + }
  44 +
  45 + function query($sql) {
  46 + if(!$this->data && !$this->connect()) {
  47 + $this->error("Could node connect for query: ".$sql);
  48 + return false;
  49 + }
  50 + //echo $sql."<br />:";
  51 + if(!($this->result = $this->data->query($sql))) $this->error($sql);
  52 + return ($this->result) ? true : false;
  53 + }
  54 +
  55 + function nextr(){
  56 + if(!$this->result) {
  57 + $this->error("No query pending");
  58 + return false;
  59 + }
  60 + unset($this->row);
  61 + $this->row = $this->result->fetch_array(MYSQL_BOTH);
  62 + return ($this->row) ? true : false ;
  63 + }
  64 +
  65 + function get_row($mode = "both") {
  66 + if(!$this->row) return false;
  67 +
  68 + $return = array();
  69 + switch($mode) {
  70 + case "assoc":
  71 + foreach($this->row as $k => $v) {
  72 + if(!is_int($k)) $return[$k] = $v;
  73 + }
  74 + break;
  75 + case "num":
  76 + foreach($this->row as $k => $v) {
  77 + if(is_int($k)) $return[$k] = $v;
  78 + }
  79 + break;
  80 + default:
  81 + $return = $this->row;
  82 + break;
  83 + }
  84 + return array_map("stripslashes",$return);
  85 + }
  86 +
  87 + function get_all($mode = "both", $key = false) {
  88 + if(!$this->result) {
  89 + $this->error("No query pending");
  90 + return false;
  91 + }
  92 + $return = array();
  93 + while($this->nextr()) {
  94 + if($key !== false) $return[$this->f($key)] = $this->get_row($mode);
  95 + else $return[] = $this->get_row($mode);
  96 + }
  97 + return $return;
  98 + }
  99 +
  100 + function f($index) {
  101 + return stripslashes($this->row[$index]);
  102 + }
  103 +
  104 + function go_to($row) {
  105 + if(!$this->result) {
  106 + $this->error("No query pending");
  107 + return false;
  108 + }
  109 + if(!$this->data->data_seek($row)) $this->error();
  110 + }
  111 +
  112 + function nf() {
  113 + if (!$this->result) {
  114 + $this->error("nf: no result set");
  115 + return false;
  116 + }
  117 + return $this->result->num_rows;
  118 + }
  119 + function af() {
  120 + return $this->data->affected_rows;
  121 + }
  122 + function error($string = "") {
  123 + $error = $this->data->error;
  124 + if($this->settings["show_error"]) echo $error;
  125 + if($this->settings["error_file"] !== false) {
  126 + $handle = @fopen($this->settings["error_file"], "a+");
  127 + if($handle) {
  128 + @fwrite($handle, "[".date("Y-m-d H:i:s")."] ".$string." <".$error.">\n");
  129 + @fclose($handle);
  130 + }
  131 + }
  132 + if($this->settings["dieonerror"]) {
  133 + if(isset($this->result)) $this->result->free();
  134 + @$this->data->close();
  135 + die();
  136 + }
  137 + }
  138 + function insert_id() {
  139 + return $this->data->insert_id;
  140 + }
  141 + function escape($string) {
  142 + if(!$this->data) return addslashes($string);
  143 + return $this->data->escape_string($string);
  144 + }
  145 +
  146 + function destroy() {
  147 + if(isset($this->result)) $this->result->free();
  148 + if($this->data) $this->data->close();
  149 + }
  150 +
  151 +
  152 +}
0 153 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/_inc/class.tree.php 0 → 100644
... ... @@ -0,0 +1,602 @@
  1 +<?php
  2 +class _tree_struct {
  3 + // Structure table and fields
  4 + protected $table = "";
  5 + protected $fields = array(
  6 + "id" => false,
  7 + "parent_id" => false,
  8 + "position" => false,
  9 + "left" => false,
  10 + "right" => false,
  11 + "level" => false
  12 + );
  13 +
  14 + // Constructor
  15 + function __construct($table = "tree", $fields = array()) {
  16 + $this->table = $table;
  17 + if(!count($fields)) {
  18 + foreach($this->fields as $k => &$v) { $v = $k; }
  19 + }
  20 + else {
  21 + foreach($fields as $key => $field) {
  22 + switch($key) {
  23 + case "id":
  24 + case "parent_id":
  25 + case "position":
  26 + case "left":
  27 + case "right":
  28 + case "level":
  29 + $this->fields[$key] = $field;
  30 + break;
  31 + }
  32 + }
  33 + }
  34 + // Database
  35 + $this->db = new _database;
  36 + }
  37 +
  38 + function _get_node($id) {
  39 + $this->db->query("SELECT `".implode("` , `", $this->fields)."` FROM `".$this->table."` WHERE `".$this->fields["id"]."` = ".(int) $id);
  40 + $this->db->nextr();
  41 + return $this->db->nf() === 0 ? false : $this->db->get_row("assoc");
  42 + }
  43 + function _get_children($id, $recursive = false) {
  44 + $children = array();
  45 + if($recursive) {
  46 + $node = $this->_get_node($id);
  47 + $this->db->query("SELECT `".implode("` , `", $this->fields)."` FROM `".$this->table."` WHERE `".$this->fields["left"]."` >= ".(int) $node[$this->fields["left"]]." AND `".$this->fields["right"]."` <= ".(int) $node[$this->fields["right"]]." ORDER BY `".$this->fields["left"]."` ASC");
  48 + }
  49 + else {
  50 + $this->db->query("SELECT `".implode("` , `", $this->fields)."` FROM `".$this->table."` WHERE `".$this->fields["parent_id"]."` = ".(int) $id." ORDER BY `".$this->fields["position"]."` ASC");
  51 + }
  52 + while($this->db->nextr()) $children[$this->db->f($this->fields["id"])] = $this->db->get_row("assoc");
  53 + return $children;
  54 + }
  55 + function _get_path($id) {
  56 + $node = $this->_get_node($id);
  57 + $path = array();
  58 + if(!$node === false) return false;
  59 + $this->db->query("SELECT `".implode("` , `", $this->fields)."` FROM `".$this->table."` WHERE `".$this->fields["left"]."` <= ".(int) $node[$this->fields["left"]]." AND `".$this->fields["right"]."` >= ".(int) $node[$this->fields["right"]]);
  60 + while($this->db->nextr()) $path[$this->db->f($this->fields["id"])] = $this->db->get_row("assoc");
  61 + return $path;
  62 + }
  63 +
  64 + function _create($parent, $position) {
  65 + return $this->_move(0, $parent, $position);
  66 + }
  67 + function _remove($id) {
  68 + if((int)$id === 1) { return false; }
  69 + $data = $this->_get_node($id);
  70 + $lft = (int)$data[$this->fields["left"]];
  71 + $rgt = (int)$data[$this->fields["right"]];
  72 + $dif = $rgt - $lft + 1;
  73 +
  74 + // deleting node and its children
  75 + $this->db->query("" .
  76 + "DELETE FROM `".$this->table."` " .
  77 + "WHERE `".$this->fields["left"]."` >= ".$lft." AND `".$this->fields["right"]."` <= ".$rgt
  78 + );
  79 + // shift left indexes of nodes right of the node
  80 + $this->db->query("".
  81 + "UPDATE `".$this->table."` " .
  82 + "SET `".$this->fields["left"]."` = `".$this->fields["left"]."` - ".$dif." " .
  83 + "WHERE `".$this->fields["left"]."` > ".$rgt
  84 + );
  85 + // shift right indexes of nodes right of the node and the node's parents
  86 + $this->db->query("" .
  87 + "UPDATE `".$this->table."` " .
  88 + "SET `".$this->fields["right"]."` = `".$this->fields["right"]."` - ".$dif." " .
  89 + "WHERE `".$this->fields["right"]."` > ".$lft
  90 + );
  91 +
  92 + $pid = (int)$data[$this->fields["parent_id"]];
  93 + $pos = (int)$data[$this->fields["position"]];
  94 +
  95 + // Update position of siblings below the deleted node
  96 + $this->db->query("" .
  97 + "UPDATE `".$this->table."` " .
  98 + "SET `".$this->fields["position"]."` = `".$this->fields["position"]."` - 1 " .
  99 + "WHERE `".$this->fields["parent_id"]."` = ".$pid." AND `".$this->fields["position"]."` > ".$pos
  100 + );
  101 + return true;
  102 + }
  103 + function _move($id, $ref_id, $position = 0, $is_copy = false) {
  104 + if((int)$ref_id === 0 || (int)$id === 1) { return false; }
  105 + $sql = array(); // Queries executed at the end
  106 + $node = $this->_get_node($id); // Node data
  107 + $nchildren = $this->_get_children($id); // Node children
  108 + $ref_node = $this->_get_node($ref_id); // Ref node data
  109 + $rchildren = $this->_get_children($ref_id);// Ref node children
  110 +
  111 + $ndif = 2;
  112 + $node_ids = array(-1);
  113 + if($node !== false) {
  114 + $node_ids = array_keys($this->_get_children($id, true));
  115 + // TODO: should be !$is_copy && , but if copied to self - screws some right indexes
  116 + if(in_array($ref_id, $node_ids)) return false;
  117 + $ndif = $node[$this->fields["right"]] - $node[$this->fields["left"]] + 1;
  118 + }
  119 + if($position >= count($rchildren)) {
  120 + $position = count($rchildren);
  121 + }
  122 +
  123 + // Not creating or copying - old parent is cleaned
  124 + if($node !== false && $is_copy == false) {
  125 + $sql[] = "" .
  126 + "UPDATE `".$this->table."` " .
  127 + "SET `".$this->fields["position"]."` = `".$this->fields["position"]."` - 1 " .
  128 + "WHERE " .
  129 + "`".$this->fields["parent_id"]."` = ".$node[$this->fields["parent_id"]]." AND " .
  130 + "`".$this->fields["position"]."` > ".$node[$this->fields["position"]];
  131 + $sql[] = "" .
  132 + "UPDATE `".$this->table."` " .
  133 + "SET `".$this->fields["left"]."` = `".$this->fields["left"]."` - ".$ndif." " .
  134 + "WHERE `".$this->fields["left"]."` > ".$node[$this->fields["right"]];
  135 + $sql[] = "" .
  136 + "UPDATE `".$this->table."` " .
  137 + "SET `".$this->fields["right"]."` = `".$this->fields["right"]."` - ".$ndif." " .
  138 + "WHERE " .
  139 + "`".$this->fields["right"]."` > ".$node[$this->fields["left"]]." AND " .
  140 + "`".$this->fields["id"]."` NOT IN (".implode(",", $node_ids).") ";
  141 + }
  142 + // Preparing new parent
  143 + $sql[] = "" .
  144 + "UPDATE `".$this->table."` " .
  145 + "SET `".$this->fields["position"]."` = `".$this->fields["position"]."` + 1 " .
  146 + "WHERE " .
  147 + "`".$this->fields["parent_id"]."` = ".$ref_id." AND " .
  148 + "`".$this->fields["position"]."` >= ".$position." " .
  149 + ( $is_copy ? "" : " AND `".$this->fields["id"]."` NOT IN (".implode(",", $node_ids).") ");
  150 +
  151 + $ref_ind = $ref_id === 0 ? (int)$rchildren[count($rchildren) - 1][$this->fields["right"]] + 1 : (int)$ref_node[$this->fields["right"]];
  152 + $ref_ind = max($ref_ind, 1);
  153 +
  154 + $self = ($node !== false && !$is_copy && (int)$node[$this->fields["parent_id"]] == $ref_id && $position > $node[$this->fields["position"]]) ? 1 : 0;
  155 + foreach($rchildren as $k => $v) {
  156 + if($v[$this->fields["position"]] - $self == $position) {
  157 + $ref_ind = (int)$v[$this->fields["left"]];
  158 + break;
  159 + }
  160 + }
  161 + if($node !== false && !$is_copy && $node[$this->fields["left"]] < $ref_ind) {
  162 + $ref_ind -= $ndif;
  163 + }
  164 +
  165 + $sql[] = "" .
  166 + "UPDATE `".$this->table."` " .
  167 + "SET `".$this->fields["left"]."` = `".$this->fields["left"]."` + ".$ndif." " .
  168 + "WHERE " .
  169 + "`".$this->fields["left"]."` >= ".$ref_ind." " .
  170 + ( $is_copy ? "" : " AND `".$this->fields["id"]."` NOT IN (".implode(",", $node_ids).") ");
  171 + $sql[] = "" .
  172 + "UPDATE `".$this->table."` " .
  173 + "SET `".$this->fields["right"]."` = `".$this->fields["right"]."` + ".$ndif." " .
  174 + "WHERE " .
  175 + "`".$this->fields["right"]."` >= ".$ref_ind." " .
  176 + ( $is_copy ? "" : " AND `".$this->fields["id"]."` NOT IN (".implode(",", $node_ids).") ");
  177 +
  178 + $ldif = $ref_id == 0 ? 0 : $ref_node[$this->fields["level"]] + 1;
  179 + $idif = $ref_ind;
  180 + if($node !== false) {
  181 + $ldif = $node[$this->fields["level"]] - ($ref_node[$this->fields["level"]] + 1);
  182 + $idif = $node[$this->fields["left"]] - $ref_ind;
  183 + if($is_copy) {
  184 + $sql[] = "" .
  185 + "INSERT INTO `".$this->table."` (" .
  186 + "`".$this->fields["parent_id"]."`, " .
  187 + "`".$this->fields["position"]."`, " .
  188 + "`".$this->fields["left"]."`, " .
  189 + "`".$this->fields["right"]."`, " .
  190 + "`".$this->fields["level"]."`" .
  191 + ") " .
  192 + "SELECT " .
  193 + "".$ref_id.", " .
  194 + "`".$this->fields["position"]."`, " .
  195 + "`".$this->fields["left"]."` - (".($idif + ($node[$this->fields["left"]] >= $ref_ind ? $ndif : 0))."), " .
  196 + "`".$this->fields["right"]."` - (".($idif + ($node[$this->fields["left"]] >= $ref_ind ? $ndif : 0))."), " .
  197 + "`".$this->fields["level"]."` - (".$ldif.") " .
  198 + "FROM `".$this->table."` " .
  199 + "WHERE " .
  200 + "`".$this->fields["id"]."` IN (".implode(",", $node_ids).") " .
  201 + "ORDER BY `".$this->fields["level"]."` ASC";
  202 + }
  203 + else {
  204 + $sql[] = "" .
  205 + "UPDATE `".$this->table."` SET " .
  206 + "`".$this->fields["parent_id"]."` = ".$ref_id.", " .
  207 + "`".$this->fields["position"]."` = ".$position." " .
  208 + "WHERE " .
  209 + "`".$this->fields["id"]."` = ".$id;
  210 + $sql[] = "" .
  211 + "UPDATE `".$this->table."` SET " .
  212 + "`".$this->fields["left"]."` = `".$this->fields["left"]."` - (".$idif."), " .
  213 + "`".$this->fields["right"]."` = `".$this->fields["right"]."` - (".$idif."), " .
  214 + "`".$this->fields["level"]."` = `".$this->fields["level"]."` - (".$ldif.") " .
  215 + "WHERE " .
  216 + "`".$this->fields["id"]."` IN (".implode(",", $node_ids).") ";
  217 + }
  218 + }
  219 + else {
  220 + $sql[] = "" .
  221 + "INSERT INTO `".$this->table."` (" .
  222 + "`".$this->fields["parent_id"]."`, " .
  223 + "`".$this->fields["position"]."`, " .
  224 + "`".$this->fields["left"]."`, " .
  225 + "`".$this->fields["right"]."`, " .
  226 + "`".$this->fields["level"]."` " .
  227 + ") " .
  228 + "VALUES (" .
  229 + $ref_id.", " .
  230 + $position.", " .
  231 + $idif.", " .
  232 + ($idif + 1).", " .
  233 + $ldif.
  234 + ")";
  235 + }
  236 + foreach($sql as $q) { $this->db->query($q); }
  237 + $ind = $this->db->insert_id();
  238 + if($is_copy) $this->_fix_copy($ind, $position);
  239 + return $node === false || $is_copy ? $ind : true;
  240 + }
  241 + function _fix_copy($id, $position) {
  242 + $node = $this->_get_node($id);
  243 + $children = $this->_get_children($id, true);
  244 +
  245 + $map = array();
  246 + for($i = $node[$this->fields["left"]] + 1; $i < $node[$this->fields["right"]]; $i++) {
  247 + $map[$i] = $id;
  248 + }
  249 + foreach($children as $cid => $child) {
  250 + if((int)$cid == (int)$id) {
  251 + $this->db->query("UPDATE `".$this->table."` SET `".$this->fields["position"]."` = ".$position." WHERE `".$this->fields["id"]."` = ".$cid);
  252 + continue;
  253 + }
  254 + $this->db->query("UPDATE `".$this->table."` SET `".$this->fields["parent_id"]."` = ".$map[(int)$child[$this->fields["left"]]]." WHERE `".$this->fields["id"]."` = ".$cid);
  255 + for($i = $child[$this->fields["left"]] + 1; $i < $child[$this->fields["right"]]; $i++) {
  256 + $map[$i] = $cid;
  257 + }
  258 + }
  259 + }
  260 +
  261 + function _reconstruct() {
  262 + $this->db->query("" .
  263 + "CREATE TEMPORARY TABLE `temp_tree` (" .
  264 + "`".$this->fields["id"]."` INTEGER NOT NULL, " .
  265 + "`".$this->fields["parent_id"]."` INTEGER NOT NULL, " .
  266 + "`". $this->fields["position"]."` INTEGER NOT NULL" .
  267 + ") type=HEAP"
  268 + );
  269 + $this->db->query("" .
  270 + "INSERT INTO `temp_tree` " .
  271 + "SELECT " .
  272 + "`".$this->fields["id"]."`, " .
  273 + "`".$this->fields["parent_id"]."`, " .
  274 + "`".$this->fields["position"]."` " .
  275 + "FROM `".$this->table."`"
  276 + );
  277 +
  278 + $this->db->query("" .
  279 + "CREATE TEMPORARY TABLE `temp_stack` (" .
  280 + "`".$this->fields["id"]."` INTEGER NOT NULL, " .
  281 + "`".$this->fields["left"]."` INTEGER, " .
  282 + "`".$this->fields["right"]."` INTEGER, " .
  283 + "`".$this->fields["level"]."` INTEGER, " .
  284 + "`stack_top` INTEGER NOT NULL, " .
  285 + "`".$this->fields["parent_id"]."` INTEGER, " .
  286 + "`".$this->fields["position"]."` INTEGER " .
  287 + ") type=HEAP"
  288 + );
  289 + $counter = 2;
  290 + $this->db->query("SELECT COUNT(*) FROM temp_tree");
  291 + $this->db->nextr();
  292 + $maxcounter = (int) $this->db->f(0) * 2;
  293 + $currenttop = 1;
  294 + $this->db->query("" .
  295 + "INSERT INTO `temp_stack` " .
  296 + "SELECT " .
  297 + "`".$this->fields["id"]."`, " .
  298 + "1, " .
  299 + "NULL, " .
  300 + "0, " .
  301 + "1, " .
  302 + "`".$this->fields["parent_id"]."`, " .
  303 + "`".$this->fields["position"]."` " .
  304 + "FROM `temp_tree` " .
  305 + "WHERE `".$this->fields["parent_id"]."` = 0"
  306 + );
  307 + $this->db->query("DELETE FROM `temp_tree` WHERE `".$this->fields["parent_id"]."` = 0");
  308 +
  309 + while ($counter <= $maxcounter) {
  310 + $this->db->query("" .
  311 + "SELECT " .
  312 + "`temp_tree`.`".$this->fields["id"]."` AS tempmin, " .
  313 + "`temp_tree`.`".$this->fields["parent_id"]."` AS pid, " .
  314 + "`temp_tree`.`".$this->fields["position"]."` AS lid " .
  315 + "FROM `temp_stack`, `temp_tree` " .
  316 + "WHERE " .
  317 + "`temp_stack`.`".$this->fields["id"]."` = `temp_tree`.`".$this->fields["parent_id"]."` AND " .
  318 + "`temp_stack`.`stack_top` = ".$currenttop." " .
  319 + "ORDER BY `temp_tree`.`".$this->fields["position"]."` ASC LIMIT 1"
  320 + );
  321 +
  322 + if ($this->db->nextr()) {
  323 + $tmp = $this->db->f("tempmin");
  324 +
  325 + $q = "INSERT INTO temp_stack (stack_top, `".$this->fields["id"]."`, `".$this->fields["left"]."`, `".$this->fields["right"]."`, `".$this->fields["level"]."`, `".$this->fields["parent_id"]."`, `".$this->fields["position"]."`) VALUES(".($currenttop + 1).", ".$tmp.", ".$counter.", NULL, ".$currenttop.", ".$this->db->f("pid").", ".$this->db->f("lid").")";
  326 + $this->db->query($q);
  327 + $this->db->query("DELETE FROM `temp_tree` WHERE `".$this->fields["id"]."` = ".$tmp);
  328 + $counter++;
  329 + $currenttop++;
  330 + }
  331 + else {
  332 + $this->db->query("" .
  333 + "UPDATE temp_stack SET " .
  334 + "`".$this->fields["right"]."` = ".$counter.", " .
  335 + "`stack_top` = -`stack_top` " .
  336 + "WHERE `stack_top` = ".$currenttop
  337 + );
  338 + $counter++;
  339 + $currenttop--;
  340 + }
  341 + }
  342 +
  343 + $temp_fields = $this->fields;
  344 + unset($temp_fields["parent_id"]);
  345 + unset($temp_fields["position"]);
  346 + unset($temp_fields["left"]);
  347 + unset($temp_fields["right"]);
  348 + unset($temp_fields["level"]);
  349 + if(count($temp_fields) > 1) {
  350 + $this->db->query("" .
  351 + "CREATE TEMPORARY TABLE `temp_tree2` " .
  352 + "SELECT `".implode("`, `", $temp_fields)."` FROM `".$this->table."` "
  353 + );
  354 + }
  355 + $this->db->query("TRUNCATE TABLE `".$this->table."`");
  356 + $this->db->query("" .
  357 + "INSERT INTO ".$this->table." (" .
  358 + "`".$this->fields["id"]."`, " .
  359 + "`".$this->fields["parent_id"]."`, " .
  360 + "`".$this->fields["position"]."`, " .
  361 + "`".$this->fields["left"]."`, " .
  362 + "`".$this->fields["right"]."`, " .
  363 + "`".$this->fields["level"]."` " .
  364 + ") " .
  365 + "SELECT " .
  366 + "`".$this->fields["id"]."`, " .
  367 + "`".$this->fields["parent_id"]."`, " .
  368 + "`".$this->fields["position"]."`, " .
  369 + "`".$this->fields["left"]."`, " .
  370 + "`".$this->fields["right"]."`, " .
  371 + "`".$this->fields["level"]."` " .
  372 + "FROM temp_stack " .
  373 + "ORDER BY `".$this->fields["id"]."`"
  374 + );
  375 + if(count($temp_fields) > 1) {
  376 + $sql = "" .
  377 + "UPDATE `".$this->table."` v, `temp_tree2` SET v.`".$this->fields["id"]."` = v.`".$this->fields["id"]."` ";
  378 + foreach($temp_fields as $k => $v) {
  379 + if($k == "id") continue;
  380 + $sql .= ", v.`".$v."` = `temp_tree2`.`".$v."` ";
  381 + }
  382 + $sql .= " WHERE v.`".$this->fields["id"]."` = `temp_tree2`.`".$this->fields["id"]."` ";
  383 + $this->db->query($sql);
  384 + }
  385 + }
  386 +
  387 + function _analyze() {
  388 + $report = array();
  389 +
  390 + $this->db->query("" .
  391 + "SELECT " .
  392 + "`".$this->fields["left"]."` FROM `".$this->table."` s " .
  393 + "WHERE " .
  394 + "`".$this->fields["parent_id"]."` = 0 "
  395 + );
  396 + $this->db->nextr();
  397 + if($this->db->nf() == 0) {
  398 + $report[] = "[FAIL]\tNo root node.";
  399 + }
  400 + else {
  401 + $report[] = ($this->db->nf() > 1) ? "[FAIL]\tMore than one root node." : "[OK]\tJust one root node.";
  402 + }
  403 + $report[] = ($this->db->f(0) != 1) ? "[FAIL]\tRoot node's left index is not 1." : "[OK]\tRoot node's left index is 1.";
  404 +
  405 + $this->db->query("" .
  406 + "SELECT " .
  407 + "COUNT(*) FROM `".$this->table."` s " .
  408 + "WHERE " .
  409 + "`".$this->fields["parent_id"]."` != 0 AND " .
  410 + "(SELECT COUNT(*) FROM `".$this->table."` WHERE `".$this->fields["id"]."` = s.`".$this->fields["parent_id"]."`) = 0 ");
  411 + $this->db->nextr();
  412 + $report[] = ($this->db->f(0) > 0) ? "[FAIL]\tMissing parents." : "[OK]\tNo missing parents.";
  413 +
  414 + $this->db->query("SELECT MAX(`".$this->fields["right"]."`) FROM `".$this->table."`");
  415 + $this->db->nextr();
  416 + $n = $this->db->f(0);
  417 + $this->db->query("SELECT COUNT(*) FROM `".$this->table."`");
  418 + $this->db->nextr();
  419 + $c = $this->db->f(0);
  420 + $report[] = ($n/2 != $c) ? "[FAIL]\tRight index does not match node count." : "[OK]\tRight index matches count.";
  421 +
  422 + $this->db->query("" .
  423 + "SELECT COUNT(`".$this->fields["id"]."`) FROM `".$this->table."` s " .
  424 + "WHERE " .
  425 + "(SELECT COUNT(*) FROM `".$this->table."` WHERE " .
  426 + "`".$this->fields["right"]."` < s.`".$this->fields["right"]."` AND " .
  427 + "`".$this->fields["left"]."` > s.`".$this->fields["left"]."` AND " .
  428 + "`".$this->fields["level"]."` = s.`".$this->fields["level"]."` + 1" .
  429 + ") != " .
  430 + "(SELECT COUNT(*) FROM `".$this->table."` WHERE " .
  431 + "`".$this->fields["parent_id"]."` = s.`".$this->fields["id"]."`" .
  432 + ") "
  433 + );
  434 + $this->db->nextr();
  435 + $report[] = ($this->db->f(0) > 0) ? "[FAIL]\tAdjacency and nested set do not match." : "[OK]\tNS and AJ match";
  436 +
  437 + return implode("<br />",$report);
  438 + }
  439 +
  440 + function _dump($output = false) {
  441 + $nodes = array();
  442 + $this->db->query("SELECT * FROM ".$this->table." ORDER BY `".$this->fields["left"]."`");
  443 + while($this->db->nextr()) $nodes[] = $this->db->get_row("assoc");
  444 + if($output) {
  445 + echo "<pre>";
  446 + foreach($nodes as $node) {
  447 + echo str_repeat("&#160;",(int)$node[$this->fields["level"]] * 2);
  448 + echo $node[$this->fields["id"]]." (".$node[$this->fields["left"]].",".$node[$this->fields["right"]].",".$node[$this->fields["level"]].",".$node[$this->fields["parent_id"]].",".$node[$this->fields["position"]].")<br />";
  449 + }
  450 + echo str_repeat("-",40);
  451 + echo "</pre>";
  452 + }
  453 + return $nodes;
  454 + }
  455 + function _drop() {
  456 + $this->db->query("TRUNCATE TABLE `".$this->table."`");
  457 + $this->db->query("" .
  458 + "INSERT INTO `".$this->table."` (" .
  459 + "`".$this->fields["id"]."`, " .
  460 + "`".$this->fields["parent_id"]."`, " .
  461 + "`".$this->fields["position"]."`, " .
  462 + "`".$this->fields["left"]."`, " .
  463 + "`".$this->fields["right"]."`, " .
  464 + "`".$this->fields["level"]."` " .
  465 + ") " .
  466 + "VALUES (" .
  467 + "1, " .
  468 + "0, " .
  469 + "0, " .
  470 + "1, " .
  471 + "2, " .
  472 + "0 ".
  473 + ")");
  474 + }
  475 +}
  476 +
  477 +class json_tree extends _tree_struct {
  478 + function __construct($table = "tree", $fields = array(), $add_fields = array("title" => "title", "type" => "type")) {
  479 + parent::__construct($table, $fields);
  480 + $this->fields = array_merge($this->fields, $add_fields);
  481 + $this->add_fields = $add_fields;
  482 + }
  483 +
  484 + function create_node($data) {
  485 + $id = parent::_create((int)$data[$this->fields["id"]], (int)$data[$this->fields["position"]]);
  486 + if($id) {
  487 + $data["id"] = $id;
  488 + $this->set_data($data);
  489 + return "{ \"status\" : 1, \"id\" : ".(int)$id." }";
  490 + }
  491 + return "{ \"status\" : 0 }";
  492 + }
  493 + function set_data($data) {
  494 + if(count($this->add_fields) == 0) { return "{ \"status\" : 1 }"; }
  495 + $s = "UPDATE `".$this->table."` SET `".$this->fields["id"]."` = `".$this->fields["id"]."` ";
  496 + foreach($this->add_fields as $k => $v) {
  497 + if(isset($data[$k])) $s .= ", `".$this->fields[$v]."` = \"".$this->db->escape($data[$k])."\" ";
  498 + else $s .= ", `".$this->fields[$v]."` = `".$this->fields[$v]."` ";
  499 + }
  500 + $s .= "WHERE `".$this->fields["id"]."` = ".(int)$data["id"];
  501 + $this->db->query($s);
  502 + return "{ \"status\" : 1 }";
  503 + }
  504 + function rename_node($data) { return $this->set_data($data); }
  505 +
  506 + function move_node($data) {
  507 + $id = parent::_move((int)$data["id"], (int)$data["ref"], (int)$data["position"], (int)$data["copy"]);
  508 + if(!$id) return "{ \"status\" : 0 }";
  509 + if((int)$data["copy"] && count($this->add_fields)) {
  510 + $ids = array_keys($this->_get_children($id, true));
  511 + $data = $this->_get_children((int)$data["id"], true);
  512 +
  513 + $i = 0;
  514 + foreach($data as $dk => $dv) {
  515 + $s = "UPDATE `".$this->table."` SET `".$this->fields["id"]."` = `".$this->fields["id"]."` ";
  516 + foreach($this->add_fields as $k => $v) {
  517 + if(isset($dv[$k])) $s .= ", `".$this->fields[$v]."` = \"".$this->db->escape($dv[$k])."\" ";
  518 + else $s .= ", `".$this->fields[$v]."` = `".$this->fields[$v]."` ";
  519 + }
  520 + $s .= "WHERE `".$this->fields["id"]."` = ".$ids[$i];
  521 + $this->db->query($s);
  522 + $i++;
  523 + }
  524 + }
  525 + return "{ \"status\" : 1, \"id\" : ".$id." }";
  526 + }
  527 + function remove_node($data) {
  528 + $id = parent::_remove((int)$data["id"]);
  529 + return "{ \"status\" : 1 }";
  530 + }
  531 + function get_children($data) {
  532 + $tmp = $this->_get_children((int)$data["id"]);
  533 + if((int)$data["id"] === 1 && count($tmp) === 0) {
  534 + $this->_create_default();
  535 + $tmp = $this->_get_children((int)$data["id"]);
  536 + }
  537 + $result = array();
  538 + if((int)$data["id"] === 0) return json_encode($result);
  539 + foreach($tmp as $k => $v) {
  540 + $result[] = array(
  541 + "attr" => array("id" => "node_".$k, "rel" => $v[$this->fields["type"]]),
  542 + "data" => $v[$this->fields["title"]],
  543 + "state" => ((int)$v[$this->fields["right"]] - (int)$v[$this->fields["left"]] > 1) ? "closed" : ""
  544 + );
  545 + }
  546 + return json_encode($result);
  547 + }
  548 + function search($data) {
  549 + $this->db->query("SELECT `".$this->fields["left"]."`, `".$this->fields["right"]."` FROM `".$this->table."` WHERE `".$this->fields["title"]."` LIKE '%".$this->db->escape($data["search_str"])."%'");
  550 + if($this->db->nf() === 0) return "[]";
  551 + $q = "SELECT DISTINCT `".$this->fields["id"]."` FROM `".$this->table."` WHERE 0 ";
  552 + while($this->db->nextr()) {
  553 + $q .= " OR (`".$this->fields["left"]."` < ".(int)$this->db->f(0)." AND `".$this->fields["right"]."` > ".(int)$this->db->f(1).") ";
  554 + }
  555 + $result = array();
  556 + $this->db->query($q);
  557 + while($this->db->nextr()) { $result[] = "#node_".$this->db->f(0); }
  558 + return json_encode($result);
  559 + }
  560 +
  561 + function _create_default() {
  562 + $this->_drop();
  563 + $this->create_node(array(
  564 + "id" => 1,
  565 + "position" => 0,
  566 + "title" => "C:",
  567 + "type" => "drive"
  568 + ));
  569 + $this->create_node(array(
  570 + "id" => 1,
  571 + "position" => 1,
  572 + "title" => "D:",
  573 + "type" => "drive"
  574 + ));
  575 + $this->create_node(array(
  576 + "id" => 2,
  577 + "position" => 0,
  578 + "title" => "_demo",
  579 + "type" => "folder"
  580 + ));
  581 + $this->create_node(array(
  582 + "id" => 2,
  583 + "position" => 1,
  584 + "title" => "_docs",
  585 + "type" => "folder"
  586 + ));
  587 + $this->create_node(array(
  588 + "id" => 4,
  589 + "position" => 0,
  590 + "title" => "index.html",
  591 + "type" => "default"
  592 + ));
  593 + $this->create_node(array(
  594 + "id" => 5,
  595 + "position" => 1,
  596 + "title" => "doc.html",
  597 + "type" => "default"
  598 + ));
  599 + }
  600 +}
  601 +
  602 +?>
0 603 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/_install.txt 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +1) Create a database and a user with all privileges for this database.
  2 +2) Edit the config.php file and update the configuration for the database at the top of the file
  3 +3) Import the _dump.sql in your newly created database
  4 +4) You are ready to go
  5 +
  6 +*) PLEASE NOTE THAT THE PHP TREE CLASS HAS NOT BEEN THOROUGHLY TESTED
0 7 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/config.php 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +<?php
  2 +// Database config & class
  3 +$db_config = array(
  4 + "servername"=> "localhost",
  5 + "username" => "root",
  6 + "password" => "",
  7 + "database" => ""
  8 +);
  9 +if(extension_loaded("mysqli")) require_once("_inc/class._database_i.php");
  10 +else require_once("_inc/class._database.php");
  11 +
  12 +// Tree class
  13 +require_once("_inc/class.tree.php");
  14 +?>
0 15 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/file.png 0 → 100644

392 Bytes

plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/folder.png 0 → 100644

583 Bytes

plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/index.html 0 → 100644
... ... @@ -0,0 +1,461 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - Demo</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 + <link type="text/css" rel="stylesheet" href="../_docs/syntax/!style.css"/>
  13 + <link type="text/css" rel="stylesheet" href="../_docs/!style.css"/>
  14 + <script type="text/javascript" src="../_docs/syntax/!script.js"></script>
  15 +</head>
  16 +<body id="demo_body">
  17 +<div id="container">
  18 +
  19 +<h1 id="dhead">jsTree v.1.0</h1>
  20 +<h1>DEMO</h1>
  21 +<h2>Creating a tree, binding events, using the instance</h2>
  22 +<div id="description">
  23 +<p>Here is how you create an instance, bind an event and then get the instance.</p>
  24 +<div id="demo1" class="demo" style="height:100px;">
  25 + <ul>
  26 + <li id="phtml_1">
  27 + <a href="#">Root node 1</a>
  28 + <ul>
  29 + <li id="phtml_2">
  30 + <a href="#">Child node 1</a>
  31 + </li>
  32 + <li id="phtml_3">
  33 + <a href="#">Child node 2</a>
  34 + </li>
  35 + </ul>
  36 + </li>
  37 + <li id="phtml_4">
  38 + <a href="#">Root node 2</a>
  39 + </li>
  40 + </ul>
  41 +</div>
  42 +<script type="text/javascript" class="source below">
  43 +$(function () {
  44 + // TO CREATE AN INSTANCE
  45 + // select the tree container using jQuery
  46 + $("#demo1")
  47 + // call `.jstree` with the options object
  48 + .jstree({
  49 + // the `plugins` array allows you to configure the active plugins on this instance
  50 + "plugins" : ["themes","html_data","ui","crrm","hotkeys"],
  51 + // each plugin you have included can have its own config object
  52 + "core" : { "initially_open" : [ "phtml_1" ] }
  53 + // it makes sense to configure a plugin only if overriding the defaults
  54 + })
  55 + // EVENTS
  56 + // each instance triggers its own events - to process those listen on the container
  57 + // all events are in the `.jstree` namespace
  58 + // so listen for `function_name`.`jstree` - you can function names from the docs
  59 + .bind("loaded.jstree", function (event, data) {
  60 + // you get two params - event & data - check the core docs for a detailed description
  61 + });
  62 + // INSTANCES
  63 + // 1) you can call most functions just by selecting the container and calling `.jstree("func",`
  64 + setTimeout(function () { $("#demo1").jstree("set_focus"); }, 500);
  65 + // with the methods below you can call even private functions (prefixed with `_`)
  66 + // 2) you can get the focused instance using `$.jstree._focused()`.
  67 + setTimeout(function () { $.jstree._focused().select_node("#phtml_1"); }, 1000);
  68 + // 3) you can use $.jstree._reference - just pass the container, a node inside it, or a selector
  69 + setTimeout(function () { $.jstree._reference("#phtml_1").close_node("#phtml_1"); }, 1500);
  70 + // 4) when you are working with an event you can use a shortcut
  71 + $("#demo1").bind("open_node.jstree", function (e, data) {
  72 + // data.inst is the instance which triggered this event
  73 + data.inst.select_node("#phtml_2", true);
  74 + });
  75 + setTimeout(function () { $.jstree._reference("#phtml_1").open_node("#phtml_1"); }, 2500);
  76 +});
  77 +</script>
  78 +</div>
  79 +
  80 +<h2>Doing something when the tree is loaded</h2>
  81 +<div id="description">
  82 +<p>You can use a few events to do that.</p>
  83 +<div id="demo2" class="demo" style="height:100px;">
  84 + <ul>
  85 + <li id="rhtml_1" class="jstree-open">
  86 + <a href="#">Root node 1</a>
  87 + <ul>
  88 + <li id="rhtml_2">
  89 + <a href="#">Child node 1</a>
  90 + </li>
  91 + <li id="rhtml_3">
  92 + <a href="#">Child node 2</a>
  93 + </li>
  94 + </ul>
  95 + </li>
  96 + <li id="rhtml_4">
  97 + <a href="#">Root node 2</a>
  98 + </li>
  99 + </ul>
  100 +</div>
  101 +<script type="text/javascript" class="source below">
  102 +// Note method 2) and 3) use `one`, this is because if `refresh` is called those events are triggered
  103 +$(function () {
  104 + $("#demo2")
  105 + .jstree({ "plugins" : ["themes","html_data","ui"] })
  106 + // 1) the loaded event fires as soon as data is parsed and inserted
  107 + .bind("loaded.jstree", function (event, data) { })
  108 + // 2) but if you are using the cookie plugin or the core `initially_open` option:
  109 + .one("reopen.jstree", function (event, data) { })
  110 + // 3) but if you are using the cookie plugin or the UI `initially_select` option:
  111 + .one("reselect.jstree", function (event, data) { });
  112 +});
  113 +</script>
  114 +</div>
  115 +
  116 +<h2>Doing something when a node is clicked</h2>
  117 +<div id="description">
  118 +<div id="demo3" class="demo" style="height:100px;">
  119 + <ul>
  120 + <li id="shtml_1" class="jstree-open">
  121 + <a href="#">Root node 1</a>
  122 + <ul>
  123 + <li id="shtml_2">
  124 + <a href="#">Child node 1</a>
  125 + </li>
  126 + <li id="shtml_3">
  127 + <a href="#">Child node 2</a>
  128 + </li>
  129 + </ul>
  130 + </li>
  131 + <li id="shtml_4">
  132 + <a href="#">Root node 2</a>
  133 + </li>
  134 + </ul>
  135 +</div>
  136 +<script type="text/javascript" class="source below">
  137 +$(function () {
  138 + $("#demo3")
  139 + .jstree({ "plugins" : ["themes","html_data","ui"] })
  140 + // 1) if using the UI plugin bind to select_node
  141 + .bind("select_node.jstree", function (event, data) {
  142 + // `data.rslt.obj` is the jquery extended node that was clicked
  143 + alert(data.rslt.obj.attr("id"));
  144 + })
  145 + // 2) if not using the UI plugin - the Anchor tags work as expected
  146 + // so if the anchor has a HREF attirbute - the page will be changed
  147 + // you can actually prevent the default, etc (normal jquery usage)
  148 + .delegate("a", "click", function (event, data) { event.preventDefault(); })
  149 +});
  150 +</script>
  151 +</div>
  152 +
  153 +<h2>Using CSS to make nodes wrap</h2>
  154 +<div id="description">
  155 +<div id="demo4" class="demo" style="height:120px;">
  156 + <ul>
  157 + <li class="jstree-open">
  158 + <a href="#">Root node 1</a>
  159 + <ul>
  160 + <li>
  161 + <a href="#">Child node 1 with a long text which would normally just cause a scrollbar, but with this line of CSS it will actually wrap, this is not really throughly tested but it works</a>
  162 + </li>
  163 + <li>
  164 + <a href="#">Child node 2</a>
  165 + </li>
  166 + </ul>
  167 + </li>
  168 + <li>
  169 + <a href="#">Root node 2</a>
  170 + </li>
  171 + </ul>
  172 +</div>
  173 +<style type="text/css" class="source below">
  174 +#demo4 a { white-space:normal !important; height: auto; padding:1px 2px; }
  175 +#demo4 li > ins { vertical-align:top; }
  176 +#demo4 .jstree-hovered, #demo4 .jstree-clicked { border:0; }
  177 +</style>
  178 +<script type="text/javascript">
  179 +$(function () {
  180 + $("#demo4")
  181 + .jstree({ "plugins" : ["themes","html_data","ui"] });
  182 +});
  183 +</script>
  184 +</div>
  185 +
  186 +<h2>Using CSS to make the nodes bigger</h2>
  187 +<div id="description">
  188 +<div id="demo5" class="demo" style="height:120px;">
  189 + <ul>
  190 + <li class="jstree-open">
  191 + <a href="#">Root node 1</a>
  192 + <ul>
  193 + <li>
  194 + <a href="#">Child node 1 with a long text which would normally just cause a scrollbar, but with this line of CSS it will actually wrap, this is not really throughly tested but it works</a>
  195 + </li>
  196 + <li>
  197 + <a href="#">Child node 2</a>
  198 + </li>
  199 + </ul>
  200 + </li>
  201 + <li>
  202 + <a href="#">Root node 2</a>
  203 + </li>
  204 + </ul>
  205 +</div>
  206 +<style type="text/css" class="source below">
  207 +#demo5 li { min-height:22px; line-height:22px; }
  208 +#demo5 a { line-height:20px; height:20px; font-size:10px; }
  209 +#demo5 a ins { height:20px; width:20px; background-position:-56px -17px; }
  210 +</style>
  211 +<script type="text/javascript">
  212 +$(function () {
  213 + $("#demo5")
  214 + .jstree({ "plugins" : ["themes","html_data","ui"] });
  215 +});
  216 +</script>
  217 +</div>
  218 +
  219 +<h2>PHP &amp; mySQL demo + event order</h2>
  220 +<div id="description">
  221 +<p>Here is a PHP &amp; mySQL enabled demo. You can use the classes/DB structure included, but those are not thoroughly tested and not officially a part of jstree. In the log window you can also see all function calls as they happen on the instance.</p>
  222 +<div id="mmenu" style="height:30px; overflow:auto;">
  223 +<input type="button" id="add_folder" value="add folder" style="display:block; float:left;"/>
  224 +<input type="button" id="add_default" value="add file" style="display:block; float:left;"/>
  225 +<input type="button" id="rename" value="rename" style="display:block; float:left;"/>
  226 +<input type="button" id="remove" value="remove" style="display:block; float:left;"/>
  227 +<input type="button" id="cut" value="cut" style="display:block; float:left;"/>
  228 +<input type="button" id="copy" value="copy" style="display:block; float:left;"/>
  229 +<input type="button" id="paste" value="paste" style="display:block; float:left;"/>
  230 +<input type="button" id="clear_search" value="clear" style="display:block; float:right;"/>
  231 +<input type="button" id="search" value="search" style="display:block; float:right;"/>
  232 +<input type="text" id="text" value="" style="display:block; float:right;" />
  233 +</div>
  234 +
  235 +<!-- the tree container (notice NOT an UL node) -->
  236 +<div id="demo" class="demo" style="height:200px;"></div>
  237 +<div style="height:30px; text-align:center;">
  238 + <input type="button" style='width:170px; height:24px; margin:5px auto;' value="reconstruct" onclick="$.get('./server.php?reconstruct', function () { $('#demo').jstree('refresh',-1); });" />
  239 + <input type="button" style='width:170px; height:24px; margin:5px auto;' id="analyze" value="analyze" onclick="$('#alog').load('./server.php?analyze');" />
  240 + <input type="button" style='width:170px; height:24px; margin:5px auto;' value="refresh" onclick="$('#demo').jstree('refresh',-1);" />
  241 +</div>
  242 +<div id='alog' style="border:1px solid gray; padding:5px; height:100px; margin-top:15px; overflow:auto; font-family:Monospace;"></div>
  243 +<!-- JavaScript neccessary for the tree -->
  244 +<script type="text/javascript" class="source below">
  245 +$(function () {
  246 +
  247 +$("#demo")
  248 + .bind("before.jstree", function (e, data) {
  249 + $("#alog").append(data.func + "<br />");
  250 + })
  251 + .jstree({
  252 + // List of active plugins
  253 + "plugins" : [
  254 + "themes","json_data","ui","crrm","cookies","dnd","search","types","hotkeys","contextmenu"
  255 + ],
  256 +
  257 + // I usually configure the plugin that handles the data first
  258 + // This example uses JSON as it is most common
  259 + "json_data" : {
  260 + // This tree is ajax enabled - as this is most common, and maybe a bit more complex
  261 + // All the options are almost the same as jQuery's AJAX (read the docs)
  262 + "ajax" : {
  263 + // the URL to fetch the data
  264 + "url" : "./server.php",
  265 + // the `data` function is executed in the instance's scope
  266 + // the parameter is the node being loaded
  267 + // (may be -1, 0, or undefined when loading the root nodes)
  268 + "data" : function (n) {
  269 + // the result is fed to the AJAX request `data` option
  270 + return {
  271 + "operation" : "get_children",
  272 + "id" : n.attr ? n.attr("id").replace("node_","") : 1
  273 + };
  274 + }
  275 + }
  276 + },
  277 + // Configuring the search plugin
  278 + "search" : {
  279 + // As this has been a common question - async search
  280 + // Same as above - the `ajax` config option is actually jQuery's AJAX object
  281 + "ajax" : {
  282 + "url" : "./server.php",
  283 + // You get the search string as a parameter
  284 + "data" : function (str) {
  285 + return {
  286 + "operation" : "search",
  287 + "search_str" : str
  288 + };
  289 + }
  290 + }
  291 + },
  292 + // Using types - most of the time this is an overkill
  293 + // read the docs carefully to decide whether you need types
  294 + "types" : {
  295 + // I set both options to -2, as I do not need depth and children count checking
  296 + // Those two checks may slow jstree a lot, so use only when needed
  297 + "max_depth" : -2,
  298 + "max_children" : -2,
  299 + // I want only `drive` nodes to be root nodes
  300 + // This will prevent moving or creating any other type as a root node
  301 + "valid_children" : [ "drive" ],
  302 + "types" : {
  303 + // The default type
  304 + "default" : {
  305 + // I want this type to have no children (so only leaf nodes)
  306 + // In my case - those are files
  307 + "valid_children" : "none",
  308 + // If we specify an icon for the default type it WILL OVERRIDE the theme icons
  309 + "icon" : {
  310 + "image" : "./file.png"
  311 + }
  312 + },
  313 + // The `folder` type
  314 + "folder" : {
  315 + // can have files and other folders inside of it, but NOT `drive` nodes
  316 + "valid_children" : [ "default", "folder" ],
  317 + "icon" : {
  318 + "image" : "./folder.png"
  319 + }
  320 + },
  321 + // The `drive` nodes
  322 + "drive" : {
  323 + // can have files and folders inside, but NOT other `drive` nodes
  324 + "valid_children" : [ "default", "folder" ],
  325 + "icon" : {
  326 + "image" : "./root.png"
  327 + },
  328 + // those prevent the functions with the same name to be used on `drive` nodes
  329 + // internally the `before` event is used
  330 + "start_drag" : false,
  331 + "move_node" : false,
  332 + "delete_node" : false,
  333 + "remove" : false
  334 + }
  335 + }
  336 + },
  337 + // UI & core - the nodes to initially select and open will be overwritten by the cookie plugin
  338 +
  339 + // the UI plugin - it handles selecting/deselecting/hovering nodes
  340 + "ui" : {
  341 + // this makes the node with ID node_4 selected onload
  342 + "initially_select" : [ "node_4" ]
  343 + },
  344 + // the core plugin - not many options here
  345 + "core" : {
  346 + // just open those two nodes up
  347 + // as this is an AJAX enabled tree, both will be downloaded from the server
  348 + "initially_open" : [ "node_2" , "node_3" ]
  349 + }
  350 + })
  351 + .bind("create.jstree", function (e, data) {
  352 + $.post(
  353 + "./server.php",
  354 + {
  355 + "operation" : "create_node",
  356 + "id" : data.rslt.parent.attr("id").replace("node_",""),
  357 + "position" : data.rslt.position,
  358 + "title" : data.rslt.name,
  359 + "type" : data.rslt.obj.attr("rel")
  360 + },
  361 + function (r) {
  362 + if(r.status) {
  363 + $(data.rslt.obj).attr("id", "node_" + r.id);
  364 + }
  365 + else {
  366 + $.jstree.rollback(data.rlbk);
  367 + }
  368 + }
  369 + );
  370 + })
  371 + .bind("remove.jstree", function (e, data) {
  372 + data.rslt.obj.each(function () {
  373 + $.ajax({
  374 + async : false,
  375 + type: 'POST',
  376 + url: "./server.php",
  377 + data : {
  378 + "operation" : "remove_node",
  379 + "id" : this.id.replace("node_","")
  380 + },
  381 + success : function (r) {
  382 + if(!r.status) {
  383 + data.inst.refresh();
  384 + }
  385 + }
  386 + });
  387 + });
  388 + })
  389 + .bind("rename.jstree", function (e, data) {
  390 + $.post(
  391 + "./server.php",
  392 + {
  393 + "operation" : "rename_node",
  394 + "id" : data.rslt.obj.attr("id").replace("node_",""),
  395 + "title" : data.rslt.new_name
  396 + },
  397 + function (r) {
  398 + if(!r.status) {
  399 + $.jstree.rollback(data.rlbk);
  400 + }
  401 + }
  402 + );
  403 + })
  404 + .bind("move_node.jstree", function (e, data) {
  405 + data.rslt.o.each(function (i) {
  406 + $.ajax({
  407 + async : false,
  408 + type: 'POST',
  409 + url: "./server.php",
  410 + data : {
  411 + "operation" : "move_node",
  412 + "id" : $(this).attr("id").replace("node_",""),
  413 + "ref" : data.rslt.cr === -1 ? 1 : data.rslt.np.attr("id").replace("node_",""),
  414 + "position" : data.rslt.cp + i,
  415 + "title" : data.rslt.name,
  416 + "copy" : data.rslt.cy ? 1 : 0
  417 + },
  418 + success : function (r) {
  419 + if(!r.status) {
  420 + $.jstree.rollback(data.rlbk);
  421 + }
  422 + else {
  423 + $(data.rslt.oc).attr("id", "node_" + r.id);
  424 + if(data.rslt.cy && $(data.rslt.oc).children("UL").length) {
  425 + data.inst.refresh(data.inst._get_parent(data.rslt.oc));
  426 + }
  427 + }
  428 + $("#analyze").click();
  429 + }
  430 + });
  431 + });
  432 + });
  433 +
  434 +});
  435 +</script>
  436 +<script type="text/javascript" class="source below">
  437 +// Code for the menu buttons
  438 +$(function () {
  439 + $("#mmenu input").click(function () {
  440 + switch(this.id) {
  441 + case "add_default":
  442 + case "add_folder":
  443 + $("#demo").jstree("create", null, "last", { "attr" : { "rel" : this.id.toString().replace("add_", "") } });
  444 + break;
  445 + case "search":
  446 + $("#demo").jstree("search", document.getElementById("text").value);
  447 + break;
  448 + case "text": break;
  449 + default:
  450 + $("#demo").jstree(this.id);
  451 + break;
  452 + }
  453 + });
  454 +});
  455 +</script>
  456 +</div>
  457 +
  458 +</div>
  459 +
  460 +</body>
  461 +</html>
0 462 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/root.png 0 → 100644

628 Bytes

plugins/display_content/public/javascripts/jstree-v.pre1.0/_demo/server.php 0 → 100644
... ... @@ -0,0 +1,69 @@
  1 +<?php
  2 +require_once("config.php");
  3 +$jstree = new json_tree();
  4 +
  5 +//$jstree->_create_default();
  6 +//die();
  7 +
  8 +if(isset($_GET["reconstruct"])) {
  9 + $jstree->_reconstruct();
  10 + die();
  11 +}
  12 +if(isset($_GET["analyze"])) {
  13 + echo $jstree->_analyze();
  14 + die();
  15 +}
  16 +
  17 +if($_REQUEST["operation"] && strpos($_REQUEST["operation"], "_") !== 0 && method_exists($jstree, $_REQUEST["operation"])) {
  18 + header("HTTP/1.0 200 OK");
  19 + header('Content-type: application/json; charset=utf-8');
  20 + header("Cache-Control: no-cache, must-revalidate");
  21 + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  22 + header("Pragma: no-cache");
  23 + echo $jstree->{$_REQUEST["operation"]}($_REQUEST);
  24 + die();
  25 +}
  26 +header("HTTP/1.0 404 Not Found");
  27 +?>
  28 +
  29 +<?php
  30 +/*
  31 +$jstree->_drop();
  32 +$jstree->create_node(array("id"=>0,"position"=>0));
  33 +$jstree->create_node(array("id"=>1,"position"=>0));
  34 +$jstree->create_node(array("id"=>1,"position"=>0));
  35 +$jstree->create_node(array("id"=>3,"position"=>0,"name"=>"Pesho"));
  36 +$jstree->move(3,2,0,true);
  37 +$jstree->_dump(true);
  38 +$jstree->_reconstruct();
  39 +echo $jstree->_analyze();
  40 +die();
  41 +
  42 +$tree = new _tree_struct;
  43 +$tree->drop();
  44 +$tree->create(0, 0);
  45 +$tree->create(0, 0);
  46 +$tree->create(1, 0);
  47 +$tree->create(0, 3);
  48 +$tree->create(2, 3);
  49 +$tree->create(2, 0);
  50 +$tree->dump(true);
  51 +$tree->move(6,4,0);
  52 +$tree->move(1,0,0);
  53 +$tree->move(3,2,99,true);
  54 +$tree->move(7,1,0,true);
  55 +$tree->move(1,7,0);
  56 +$tree->move(1,0,1,true);
  57 +$tree->move(2, 0, 0, true);
  58 +$tree->move(13, 12, 2, true);
  59 +$tree->dump(true);
  60 +$tree->move(15, 16, 2, true);
  61 +$tree->dump(true);
  62 +$tree->move(4, 0, 0);
  63 +$tree->dump(true);
  64 +$tree->move(4, 0, 2);
  65 +$tree->dump(true);
  66 +echo $tree->analyze();
  67 +$tree->drop();
  68 +*/
  69 +?>
0 70 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/!style.css 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +html, body { margin:0; padding:0; background:#D9E3CB; }
  2 +body, td, th, pre, code, select, option, input, textarea { font-family:"lucida grande",tahoma,verdana,arial,sans-serif; font-size:10pt; }
  3 +#dhead { margin:0 0 0 -10px; padding:0; line-height:80px; font-size:18pt; font-family:Georgia; /*text-shadow:1px 1px 2px gray;*/ border-bottom:10px solid #73796B; margin-bottom:0.5em; text-align:center; width:820px; background:black; color:white; -moz-border-radius:5px 5px 0 0; border-radius:5px 5px 0 0; -webkit-border-radius:5px 5px 0 0; text-indent:-2000px; background:black url("logo.png") center center no-repeat; }
  4 +h1 { margin:0 0 0 0px; padding:0; font-size:14pt; font-family:Georgia; /*text-shadow:1px 1px 2px gray;*/ margin-bottom:1em; text-align:center; text-transform:uppercase;}
  5 +h2 { margin:0.5em 0 0.5em 0; padding:0.5em 0 0.5em 20px; font-size:12pt; font-family:Georgia; color:white; background:silver; text-shadow:1px 1px 2px gray; clear:both; -moz-border-radius:5px; border-radius:5px; -webkit-border-radius:5px; }
  6 +h3 { margin:0; padding:0.5em 0 0.5em 0; font-size:11.5pt; font-family:Georgia; color:gray; clear:both; }
  7 +p { padding:0em 0 0.5em 0; margin:0; line-height:1.8em; }
  8 +p.meta { font-size:9pt; color:gray; margin-top:-5px; }
  9 +.arguments .tp, p code { color:green; padding:0 4px; font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size:13px; }
  10 +#description, .panel { margin:0 20px; }
  11 +#container { width:800px; margin:10px auto; overflow:hidden; background:white; padding:0 10px 10px 10px; -moz-border-radius:5px; border-radius:5px; -webkit-border-radius:5px; -moz-box-shadow: 0px 0px 10px #000; }
  12 +.demo { width:255px; float:left; margin:0; border:1px solid gray; background:white; overflow:auto; }
  13 +.code { width:490px; float:right; margin:0 0 10px 0; border:1px solid gray; font-size:12px; }
  14 +pre { display:block; }
  15 +.code_f { border:1px solid gray; margin-bottom:1em; }
  16 +.syntaxhighlighter { margin:0 0 0 0 !important; padding:0 !important; line-height:18px; }
  17 +
  18 +.log { padding:4px; border:1px solid gray; margin-bottom:1em; }
  19 +.button { display:block; margin-bottom:0.5em; }
  20 +.arguments { margin:0em 1em; padding:0; list-style-type:none; }
  21 +.arguments .tp { padding:0 0 0 0; float:left; width:70px; }
  22 +.arguments strong { display:block; }
  23 +
  24 +.api h3 { margin-left:-10px; color:black; font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; font-weight: normal !important; font-size:14px; margin-top:2em; border-top:1px solid; width:780px; }
  25 +.api .arguments li strong { color:black; font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; font-weight: normal !important; font-size:13px; }
  26 +
  27 +.configuration h3 { margin-left:-10px; color:black; font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; font-weight: normal !important; font-size:14px; margin-top:2em; border-top:1px solid; width:780px; }
  28 +.note { background:#ffffee; padding:10px 20px; border:1px solid #333; -moz-border-radius:5px; border-radius:5px; -webkit-border-radius:5px; margin-bottom:15px; text-align:center; font-weight:bold; }
  29 +
  30 +.plugins, .demos { margin:0 auto 20px auto; }
  31 +
  32 +ul.columns { list-style-type:none; width:700px; margin:0px auto 15px auto; padding:0; overflow:hidden; }
  33 +ul.columns li { float:left; margin:0; padding:0 0 0 0px; line-height:18px; width:345px; }
  34 +ul.demos li, ul.plugins li { width:220px; text-align:left; padding:5px 0; }
  35 +ul.demos li a, ul.plugins li a { text-decoration:none; color:#3B5998; }
  36 +ul.demos li a:hover, ul.plugins li a:hover { text-decoration:underline; }
  37 +ul.plugins li p { text-align:left; font-size:9px; color:#333; margin:0 5px 0 0; }
  38 +
  39 +ul.demos li { width:auto; }
  40 +
  41 +.demo, .demo input, .jstree-dnd-helper, #vakata-contextmenu { font-size:10px; font-family:Verdana; }
  42 +
  43 +#demo_body .demo, #demo_body .code { width:auto; float:none; clear:both; margin:10px auto; }
  44 +#demo_body .code { margin-bottom:20px; }
  45 +
  46 +ul.jstree { width:700px; margin:0px auto 15px auto; padding:0; }
  47 +ul.jstree li { margin:0; padding:2px 0; }
  48 +ul.jstree li a { color:#3B5998; text-decoration:underline; }
0 49 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/_drive.png 0 → 100644

628 Bytes

plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/_html_data.html 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +<li class="jstree-closed"><a href="#">Node 1</a></li>
  2 +<li><a href="#">Node 2</a></li>
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/_json_data.json 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +[
  2 + { "data" : "A node", "children" : [ { "data" : "Only child", "state" : "closed" } ], "state" : "open" },
  3 + "Ajax node"
  4 +]
0 5 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/_search_data.json 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +[
  2 + "Ajax node 1",
  3 + "Ajax node 2",
  4 + "TARGET",
  5 + "Ajax node 4"
  6 +]
0 7 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/_search_result.json 0 → 100644
... ... @@ -0,0 +1 @@
  1 +[ "#root_node" ]
0 2 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/_xml_flat.xml 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<root>
  2 + <item parent_id="0" id="node_1" state="closed">
  3 + <content>
  4 + <name><![CDATA[Node 1]]></name>
  5 + </content>
  6 + </item>
  7 + <item parent_id="0" id="node_2">
  8 + <content>
  9 + <name><![CDATA[Node 2]]></name>
  10 + </content>
  11 + </item>
  12 +</root>
0 13 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/_xml_nest.xml 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<root>
  3 + <item id="pxml_1">
  4 + <content><name><![CDATA[Root node 1]]></name></content>
  5 + <item id="pxml_2">
  6 + <content><name><![CDATA[Child node 1]]></name></content>
  7 + </item>
  8 + <item id="pxml_3">
  9 + <content><name><![CDATA[Child node 2]]></name></content>
  10 + </item>
  11 + <item id="pxml_4">
  12 + <content><name><![CDATA[Some other child node]]></name></content>
  13 + </item>
  14 + </item>
  15 + <item id="pxml_5">
  16 + <content><name ><![CDATA[Root node 2]]></name></content>
  17 + </item>
  18 +</root>
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/checkbox.html 0 → 100644
... ... @@ -0,0 +1,171 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - checkbox documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>checkbox plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>checkbox</code> plugin makes multiselection possible using three-state checkboxes.</p>
  25 +</div>
  26 +
  27 +<h2 id="configuration">Configuration</h2>
  28 +<div class="panel configuration">
  29 +
  30 +<h3>override_ui</h3>
  31 +<p class="meta">A boolean. Default is <code>false</code>.</p>
  32 +<p>If set to <code>true</code> all selection will be handled by checkboxes. The checkbox plugin will map UI's <a href="ui.html#get_selected">get_selected function</a> to its own <a href="#get_checked">get_checked function</a> and overwrite the <a href="ui.html#reselect">UI reselect function</a>. It will also disable the <code>select_node</code>, <code>deselect_node</code> and <code>deselect_all</code> functions. If left as <code>false</code> nodes can be selected and checked independently. </p>
  33 +
  34 +<h3>checked_parent_open</h3>
  35 +<p class="meta">A Boolean. Default is <code>true</code>.</p>
  36 +<p>When set to <code>true</code> when programatically checking a node in the tree all of its closed parents are opened automatically.</p>
  37 +
  38 +<h3>two_state</h3>
  39 +<p class="meta">A boolean. Default is <code>false</code>.</p>
  40 +<p>If set to <code>true</code> checkboxes will be two-state only, meaning that you will be able to select parent and children independently and there will be no undetermined state.</p>
  41 +
  42 +<h3>real_checkboxes</h3>
  43 +<p class="meta">A boolean. Default is <code>false</code>.</p>
  44 +<p>If set to <code>true</code> real hidden checkboxes will be created for each element, so if the tree is part of a form, checked nodes will be submitted automatically. By default the name of the checkbox is <code>"check_" + <em>the ID of the LI element</em></code> and the value is <code>1</code>, this can be changed using the <code>real_checkboxes_names</code> config option.</p>
  45 +
  46 +<h3>real_checkboxes_names</h3>
  47 +<p class="meta">A function. Default is <code>function (n) { return [("check_" + (n[0].id || Math.ceil(Math.random() * 10000))), 1]; }</code>.</p>
  48 +<p>If real checkboxes are used this function is invoked in the current tree's scope for each new checkbox that is created. It receives a single argument - the node that will contain the checkbox. The function must return an array consisting of two values - the name for the checkbox and the value for the checkbox.</p>
  49 +
  50 +</div>
  51 +
  52 +<h2 id="demos">Demos</h2>
  53 +<div class="panel">
  54 +<h3>Using the checkbox plugin - all you need to do is include it in the list of active plugins.</h3>
  55 +<div id="demo1" class="demo">
  56 + <ul>
  57 + <li id="phtml_1">
  58 + <a href="#">Root node 1</a>
  59 + <ul>
  60 + <li id="phtml_2" class="jstree-checked">
  61 + <a href="#">Child node 1</a>
  62 + </li>
  63 + <li id="phtml_3">
  64 + <a href="#">A Child node 2</a>
  65 + </li>
  66 + </ul>
  67 + </li>
  68 + <li id="phtml_4">
  69 + <a href="#">Root node 2</a>
  70 + </li>
  71 + </ul>
  72 +</div>
  73 +<script type="text/javascript" class="source">
  74 +$(function () {
  75 + $("#demo1").jstree({
  76 + "plugins" : [ "themes", "html_data", "checkbox", "sort", "ui" ]
  77 + });
  78 +});
  79 +</script>
  80 +
  81 +</div>
  82 +
  83 +<h2 id="api">API</h2>
  84 +<div class="panel api">
  85 +<h3 id="_prepare_checkboxes">._prepare_checkboxes ( node )</h3>
  86 +<p>Inserts the checkbox icons on the node. Used internally.</p>
  87 +<ul class="arguments">
  88 + <li>
  89 + <code class="tp">mixed</code> <strong>node</strong>
  90 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree.</p>
  91 + </li>
  92 +</ul>
  93 +
  94 +<h3 id="_repair_state">._repair_state ( node )</h3>
  95 +<p>Repairs the checkbox state inside the node. Used internally.</p>
  96 +<ul class="arguments">
  97 + <li>
  98 + <code class="tp">mixed</code> <strong>node</strong>
  99 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree.</p>
  100 + </li>
  101 +</ul>
  102 +
  103 +<h3 id="change_state">.change_state ( node , uncheck )</h3>
  104 +<p>Changes the state of a node. Used mostly internally - you'd be better off using the <code>check_node</code> and <code>uncheck_node</code> functions. Triggers an event.</p>
  105 +<ul class="arguments">
  106 + <li>
  107 + <code class="tp">mixed</code> <strong>node</strong>
  108 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree.</p>
  109 + </li>
  110 + <li>
  111 + <code class="tp">boolean</code> <strong>uncheck</strong>
  112 + <p>If set to <code>true</code> the node is unchecked, if set to <code>false</code> the node is checked, otherwise - the state is toggled.</p>
  113 + </li>
  114 +</ul>
  115 +
  116 +<h3 id="check_node">.check_node ( node )</h3>
  117 +<p>Checks a node.</p>
  118 +<ul class="arguments">
  119 + <li>
  120 + <code class="tp">mixed</code> <strong>node</strong>
  121 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree.</p>
  122 + </li>
  123 +</ul>
  124 +
  125 +<h3 id="uncheck_node">.uncheck_node ( node )</h3>
  126 +<p>Unchecks a node.</p>
  127 +<ul class="arguments">
  128 + <li>
  129 + <code class="tp">mixed</code> <strong>node</strong>
  130 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree.</p>
  131 + </li>
  132 +</ul>
  133 +
  134 +<h3 id="check_all">.check_all ( )</h3>
  135 +<p>Checks all nodes.</p>
  136 +
  137 +<h3 id="uncheck_all">.uncheck_all ( )</h3>
  138 +<p>Unchecks all nodes.</p>
  139 +
  140 +<h3 id="is_checked">.is_checked ( node )</h3>
  141 +<p>Checks if a node is checked. Returns boolean.</p>
  142 +<ul class="arguments">
  143 + <li>
  144 + <code class="tp">mixed</code> <strong>node</strong>
  145 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree.</p>
  146 + </li>
  147 +</ul>
  148 +
  149 +<div style="height:1px; visibility:hidden; overflow:hidden;"><span id="get_unchecked">&#160;</span></div>
  150 +<h3 id="get_checked">.get_checked ( context, get_all ), .get_unchecked ( context, get_all )</h3>
  151 +<p>Both functions return jQuery collections.</p>
  152 +<ul class="arguments">
  153 + <li>
  154 + <code class="tp">mixed</code> <strong>context</strong>
  155 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree. If specified only nodes inside the specified context are returned, otherwise the whole tree is searched.</p>
  156 + </li>
  157 + <li>
  158 + <code class="tp">boolean</code> <strong>get_all</strong>
  159 + <p>By default these functions return only top level checked/unchecked nodes (if a node is checked its children are note returned), if this parameter is set to <code>true</code> they will return all checked/unchecked nodes.</p>
  160 + </li>
  161 +</ul>
  162 +
  163 +<div style="height:1px; visibility:hidden; overflow:hidden;"><span id="hide_checkboxes">&#160;</span></div>
  164 +<h3 id="show_checkboxes">.show_checkboxes ( ), .hide_checkboxes ( )</h3>
  165 +<p>Show or hide the checkbox icons.</p>
  166 +
  167 +</div>
  168 +
  169 +</div>
  170 +</body>
  171 +</html>
0 172 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/contextmenu.html 0 → 100644
... ... @@ -0,0 +1,121 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - contextmenu documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>contextmenu plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>contextmenu</code> plugin enables a contextual menu to be shown, when the user right-clicks a node (or when triggered programatically by the developer).</p>
  25 +</div>
  26 +
  27 +<h2 id="configuration">Configuration</h2>
  28 +<div class="panel configuration">
  29 +<h3>select_node</h3>
  30 +<p class="meta">Boolean. Default is <code>false</code>.</p>
  31 +<p>Whether to select the right clicked node when showing the context menu. If this is set to <code>true</code> and the node is not selected all currently selected nodes will be deselected.</p>
  32 +
  33 +<h3>show_at_node</h3>
  34 +<p class="meta">Boolean. Default is <code>true</code>.</p>
  35 +<p>Whether to show the context menu just below the node, or at the clicked point exactly.</p>
  36 +
  37 +<h3>items</h3>
  38 +<p>Expects an object or a function, which should return an object. If a function is used it fired in the tree's context and receives one argument - the node that was right clicked. The object format is:</p>
  39 +<div style="border:1px solid gray">
  40 +<pre class="brush:js">
  41 +{
  42 +// Some key
  43 +"rename" : {
  44 + // The item label
  45 + "label" : "Rename",
  46 + // The function to execute upon a click
  47 + "action" : function (obj) { this.rename(obj); },
  48 + // All below are optional
  49 + "_disabled" : true, // clicking the item won't do a thing
  50 + "_class" : "class", // class is applied to the item LI node
  51 + "separator_before" : false, // Insert a separator before the item
  52 + "separator_after" : true, // Insert a separator after the item
  53 + // false or string - if does not contain `/` - used as classname
  54 + "icon" : false,
  55 + "submenu" : {
  56 + /* Collection of objects (the same structure) */
  57 + }
  58 +}
  59 +/* MORE ENTRIES ... */
  60 +}
  61 +</pre>
  62 +</div>
  63 +</div>
  64 +
  65 +<h2 id="demos">Demos</h2>
  66 +<div class="panel">
  67 +
  68 +<h3>Using the contextmenu</h3>
  69 +<div id="demo1" class="demo">
  70 + <ul>
  71 + <li id="phtml_1">
  72 + <a href="#">Root node 1</a>
  73 + <ul>
  74 + <li id="phtml_2">
  75 + <a href="#">Child node 1</a>
  76 + </li>
  77 + <li id="phtml_3">
  78 + <a href="#">Child node 2</a>
  79 + </li>
  80 + </ul>
  81 + </li>
  82 + <li id="phtml_4">
  83 + <a href="#">Root node 2</a>
  84 + </li>
  85 + </ul>
  86 +</div>
  87 +<script type="text/javascript" class="source">
  88 +$(function () {
  89 + $("#demo1").jstree({
  90 + "plugins" : [ "themes", "html_data", "ui", "crrm", "contextmenu" ]
  91 + });
  92 +});
  93 +</script>
  94 +
  95 +</div>
  96 +
  97 +<h2 id="api">API</h2>
  98 +<div class="panel api">
  99 +
  100 +<h3 id="show_contextmenu">.show_contextmenu ( node , x, y )</h3>
  101 +<p>Shows the contextmenu next to a node. Triggered automatically when right-clicking a node.</p>
  102 +<ul class="arguments">
  103 + <li>
  104 + <code class="tp">mixed</code> <strong>node</strong>
  105 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree.</p>
  106 + </li>
  107 + <li>
  108 + <code class="tp">number</code> <strong>x</strong>
  109 + <p>The X-coordinate to show the menu at - may be overwritten by <code>show_at_node</code>. If you omit this the menu is shown aligned with the left of the node.</p>
  110 + </li>
  111 + <li>
  112 + <code class="tp">number</code> <strong>y</strong>
  113 + <p>The Y-coordinate to show the menu at - may be overwritten by <code>show_at_node</code>. If you omit this the menu is shown just below the node.</p>
  114 + </li>
  115 +</ul>
  116 +
  117 +</div>
  118 +
  119 +</div>
  120 +</body>
  121 +</html>
0 122 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/cookies.html 0 → 100644
... ... @@ -0,0 +1,97 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - cookies documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>cookies plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>cookies</code> enables jstree to save the state of the tree across sessions. What this does is save the opened and selected nodes in a cookie, and reopen &amp; reselect them the next time the user loads the tree. Depends on the <a href="http://plugins.jquery.com/project/cookie">jQuery.cookie</a> plugin. </p><p class="note">The nodes need to have IDs for this plugin to work.</p>
  25 +</div>
  26 +
  27 +<h2 id="configuration">Configuration</h2>
  28 +<div class="panel configuration">
  29 +
  30 +<h3>save_opened</h3>
  31 +<p class="meta">A string (or <code>false</code>). Default is <code>"jstree_open"</code>.</p>
  32 +<p>The name of the cookie to save opened nodes in. If set to <code>false</code> - opened nodes won't be saved.</p>
  33 +
  34 +<h3>save_selected</h3>
  35 +<p class="meta">A string (or <code>false</code>). Default is <code>"jstree_select"</code>.</p>
  36 +<p>The name of the cookie to save selected nodes in. If set to <code>false</code> - selected nodes won't be saved.</p>
  37 +
  38 +<h3>auto_save</h3>
  39 +<p class="meta">A Boolean. Default is <code>true</code>.</p>
  40 +<p>If set to <code>true</code> jstree will automatically update the cookies every time a change in the state occurs.</p>
  41 +
  42 +<h3>cookie_options</h3>
  43 +<p class="meta">An object. Default is <code>{}</code>.</p>
  44 +<p>The options accepted by the <a href="http://plugins.jquery.com/project/cookie">jQuery.cookie</a> plugin.</p>
  45 +
  46 +</div>
  47 +
  48 +<h2 id="demos">Demos</h2>
  49 +<div class="panel">
  50 +<p>Check your data plugin documentation (<a href="html_data.html">html_data</a>, <a href="xml_data.html">xml_data</a>, <a href="json_data.html">json_data</a>) or take a close look at these examples for information on how to specify multilanguage nodes.</p>
  51 +
  52 +<h3>Using the cookies plugin</h3>
  53 +<p>Go ahead and make changes to the tree and then <a href="javascript:document.location.reload();">refresh this page</a>.</p>
  54 +<div id="demo1" class="demo">
  55 + <ul>
  56 + <li id="phtml_1">
  57 + <a href="#">Root node 1</a>
  58 + <ul>
  59 + <li id="phtml_2">
  60 + <a href="#">Child node 1</a>
  61 + </li>
  62 + <li id="phtml_3">
  63 + <a href="#">Child node 2</a>
  64 + </li>
  65 + </ul>
  66 + </li>
  67 + <li id="phtml_4">
  68 + <a href="#">Root node 2</a>
  69 + </li>
  70 + </ul>
  71 +</div>
  72 +<script type="text/javascript" class="source">
  73 +$(function () {
  74 + $("#demo1").jstree({
  75 + "plugins" : [ "themes", "html_data", "ui", "cookies" ]
  76 + });
  77 +});
  78 +</script>
  79 +
  80 +</div>
  81 +
  82 +<h2 id="api">API</h2>
  83 +<div class="panel api">
  84 +
  85 +<h3 id="save_cookie">.save_cookie ( event )</h3>
  86 +<p>Save the current state.</p>
  87 +<ul class="arguments">
  88 + <li>
  89 + <code class="tp">string</code> <strong>event</strong>
  90 + <p>Used internally with the <code>auto_save</code> option. Do not set this manually.</p>
  91 + </li>
  92 +</ul>
  93 +</div>
  94 +
  95 +</div>
  96 +</body>
  97 +</html>
0 98 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/core.html 0 → 100644
... ... @@ -0,0 +1,689 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 Core documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>CORE</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<h3>Including the files</h3>
  25 +<p>First of all, as jsTree is a jQuery component, you need to include jQuery itself. jsTree v.1.0 requires jQuery version 1.4.2</p>
  26 +
  27 +<div class="code_f"><pre class="brush:xml;">
  28 +&lt;script type="text/javascript" src="_lib/jquery.js"&gt;&lt;/script&gt;
  29 +</pre></div>
  30 +
  31 +<p>Then you need to include jsTree:</p>
  32 +
  33 +<div class="code_f"><pre class="brush:xml;">
  34 +&lt;script type="text/javascript" src="jquery.jstree.js"&gt;&lt;/script&gt;
  35 +</pre></div>
  36 +
  37 +<p>Or you could use the minified version:</p>
  38 +
  39 +<div class="code_f"><pre class="brush:xml;">
  40 +&lt;script type="text/javascript" src="jquery.jstree.min.js"&gt;&lt/script&gt;
  41 +</pre></div>
  42 +
  43 +<p>You may change the path to whatever you like, but it is recommended not to rename <code>jquery.tree.js</code> or <code>jquery.tree.min.js</code> as the filenames may be used for path autodetection (for example in the <code>themes</code> plugin, but if you really need to rename the file most plugins will give you the option to set the path manually).</p>
  44 +
  45 +<p>Additionally some plugins have dependencies - plugins that detect a dependency is missing will throw an error.</p>
  46 +
  47 +<h3>Creating and configuring an instance</h3>
  48 +<p>You can create a tree in the following manner:</p>
  49 +
  50 +<div class="code_f"><pre class="brush:js;">
  51 +jQuery("some-selector-to-container-node-here").jstree([ config_object ]);
  52 +</pre></div>
  53 +
  54 +<p>In the optional config object you specify all the options that you want to set. Each plugin will describe its configuration and defaults. In the <a href="#configuration">configuration section</a> below you will find the options defined by the core. Each plugin's options (even the core) are set in their own subobject, which is named after the plugin. For example all of the core's options are set in the <code>core</code> key of the config object:</p>
  55 +<div class="code_f"><pre class="brush:js;">
  56 +jQuery("some-selector-to-container-node-here")
  57 + .jstree({
  58 + core : {
  59 + /* core options go here */
  60 + }
  61 + });
  62 +</pre></div>
  63 +
  64 +<p class="note">Please note that if your options for a given plugin are the same as the defaults you may omit those options or omit the subobject completely (if you do not need to modify the defaults).</p>
  65 +
  66 +<p>There is only one special config option that is not a part of any plugin - this is the <code>plugins</code> option, which defines a list of active plugins for the instance being created. Although many plugins may be included, only the ones listed in this option will be active. The only autoincluded "plugin" is the jstree core.</p>
  67 +
  68 +<div class="code_f"><pre class="brush:js;">
  69 +jQuery("some-selector-to-container-node-here")
  70 + .jstree({
  71 + core : { /* core options go here */ },
  72 + plugins : [ "themes", "html_data", "some-other-plugin" ]
  73 + });
  74 +</pre></div>
  75 +
  76 +<h3>Interacting with the tree</h3>
  77 +
  78 +<p>To perform an operation programatically on a given instance you can use two methods:</p>
  79 +<div class="code_f"><pre class="brush:js;">
  80 +/* METHOD ONE */
  81 +jQuery("some-selector-to-container-node-here")
  82 + .jstree("operation_name" [, argument_1, argument_2, ...]);
  83 +
  84 +/* METHOD TWO */
  85 +jQuery.jstree._reference(needle)
  86 + /* NEEDLE can be a DOM node or selector for the container or a node within the container */
  87 + .operation_name([ argument_1, argument_2, ...]);
  88 +</pre></div>
  89 +<p class="note">NOTE: Functions prefixed with <code>_</code> can not be called with method one.</p>
  90 +
  91 +<p>jsTree uses events to notify of any changes happening in the tree. All events fire on the tree container in the <code>jstree</code> namespace and are named after the function that triggered them. Please note that for some events it is best to bind before creating the instance. For example:</p>
  92 +<div class="code_f"><pre class="brush:js;">
  93 +jQuery("some-container")
  94 + .bind("loaded.jstree", function (event, data) {
  95 + alert("TREE IS LOADED");
  96 + })
  97 + .jstree({ /* configuration here */ });
  98 +</pre></div>
  99 +<p>Please note the second parameter <code>data</code>. Its structure is as follows:</p>
  100 +<div class="code_f"><pre class="brush:js;">
  101 +{
  102 + "inst" : /* the actual tree instance */,
  103 + "args" : /* arguments passed to the function */,
  104 + "rslt" : /* any data the function passed to the event */,
  105 + "rlbk" : /* an optional rollback object - it is not always present */
  106 +}
  107 +</pre></div>
  108 +<p>There is also one special event - <code>before.jstree</code>. This events enables you to prevent an operation from executing. Look at the <a href="#demos">demo</a> below.</p>
  109 +
  110 +</div>
  111 +
  112 +<h2 id="configuration">Configuration</h2>
  113 +<div class="panel configuration">
  114 +
  115 +<h3>html_titles</h3>
  116 +<p class="meta">Boolean. Default is <code>false</code>.</p>
  117 +<p>Defines whether titles can contain HTML code.</p>
  118 +
  119 +<h3>animation</h3>
  120 +<p class="meta">A number. Default is <code>500</code>.</p>
  121 +<p>Defines the duration of open/close animations. <code>0</code> means no animation.</p>
  122 +
  123 +<h3>initially_open</h3>
  124 +<p class="meta">An array. Default is <code>[]</code>.</p>
  125 +<p>Defines which nodes are to be automatically opened (if they are not present they will first be loaded) when the tree finishes loading - a list of IDs is expected.</p>
  126 +
  127 +<h3>initially_load</h3>
  128 +<p class="meta">An array. Default is <code>[]</code>.</p>
  129 +<p>Defines which nodes are to be automatically loaded (but not opened) when the tree finishes loading - a list of IDs is expected.</p>
  130 +
  131 +<h3>load_open</h3>
  132 +<p class="meta">A Boolean. Default is <code>false</code>.</p>
  133 +<p>When set to <code>true</code> forces loading of nodes marked as open, which do not have children. Otherwise nodes are only visualized as open without any children and opening/closing such a node won't cause it to load (make a server call).</p>
  134 +
  135 +<h3>open_parents</h3>
  136 +<p class="meta">Boolean. Default is <code>true</code>.</p>
  137 +<p>If set to true opening a node will also open any closed ancestors it has (will open the whole chain down to this node).</p>
  138 +
  139 +<h3>notify_plugins</h3>
  140 +<p class="meta">Boolean. Default is <code>true</code>.</p>
  141 +<p>If set to true loading nodes with some metadata will trigger some actions on the corresponding plugin. So you can actually set the selected/checked/etc</p>
  142 +
  143 +<h3>rtl</h3>
  144 +<p class="meta">Boolean. Default is <code>false</code>.</p>
  145 +<p>Defines whether the tree is in right-to-left mode (also make sure you are using a RTL theme - for example the included <code>default-rtl</code>).</p>
  146 +
  147 +<h3>strings</h3>
  148 +<p class="meta">Object. Default is <code>{ loading : "Loading ...", new_node : "New node" }</code>.</p>
  149 +<p>Contains strings needed for the operation of the tree so that you can localize.</p>
  150 +
  151 +
  152 +</div>
  153 +
  154 +<h2 id="demos">Demos</h2>
  155 +<div class="panel">
  156 +
  157 +<h3>Binding to an event and executing an action</h3>
  158 +<input type="button" class="button" value="toggle_node" id="toggle_node" style="clear:both;" />
  159 +<div id="demo1" class="demo">
  160 + <ul>
  161 + <li id="phtml_1">
  162 + <a href="#">Root node 1</a>
  163 + <ul>
  164 + <li id="phtml_2">
  165 + <a href="#">Child node 1</a>
  166 + </li>
  167 + <li id="phtml_3">
  168 + <a href="#">Child node 2</a>
  169 + </li>
  170 + </ul>
  171 + </li>
  172 + <li id="phtml_4">
  173 + <a href="#">Root node 2</a>
  174 + </li>
  175 + </ul>
  176 +</div>
  177 +<script type="text/javascript" class="source">
  178 +$(function () {
  179 + $("#toggle_node").click(function () {
  180 + $("#demo1").jstree("toggle_node","#phtml_1");
  181 + });
  182 + $("#demo1")
  183 + .bind("open_node.jstree close_node.jstree", function (e) {
  184 + $("#log1").html("Last operation: " + e.type);
  185 + })
  186 + .jstree({ "plugins" : [ "themes", "html_data" ] });
  187 + });
  188 +</script>
  189 +<p class="log" id="log1" style="clear:both;">&#160;</p>
  190 +
  191 +<h3>Preventing an action</h3>
  192 +<p>This is the same demo as above, but this time the operation will be prevented.</p>
  193 +<input type="button" class="button" value="toggle_node" id="toggle_node2" style="clear:both;" />
  194 +<div id="demo2" class="demo">
  195 + <ul>
  196 + <li id="html_1">
  197 + <a href="#">Root node 1</a>
  198 + <ul>
  199 + <li id="html_2">
  200 + <a href="#">Child node 1</a>
  201 + </li>
  202 + <li id="html_3">
  203 + <a href="#">Child node 2</a>
  204 + </li>
  205 + </ul>
  206 + </li>
  207 + <li id="html_4">
  208 + <a href="#">Root node 2</a>
  209 + </li>
  210 + </ul>
  211 +</div>
  212 +<script type="text/javascript">
  213 +$(function () {
  214 + $("#toggle_node2").click(function () {
  215 + $("#demo2").jstree("toggle_node","#html_1");
  216 + });
  217 + $("#demo2")
  218 + .bind("open_node.jstree close_node.jstree", function (e) {
  219 + $("#log2").html("Last operation: " + e.type);
  220 + })
  221 + .jstree({ "plugins" : [ "themes", "html_data" ] });
  222 + });
  223 +</script>
  224 +<script type="text/javascript" class="source">
  225 +$(function () {
  226 + $("#demo2").bind("before.jstree", function (e, data) {
  227 + if(data.func === "open_node") {
  228 + $("#log2").html(data.args[0].attr("id"));
  229 + e.stopImmediatePropagation();
  230 + return false;
  231 + }
  232 + });
  233 +});
  234 +</script>
  235 +<p class="log" id="log2" style="clear:both;">&#160;</p>
  236 +<p>The important part is <code>e.stopImmediatePropagation(); return false</code>.</p>
  237 +</div>
  238 +
  239 +<h2 id="api">API</h2>
  240 +<div class="panel api">
  241 +<p class="note">Use extra caution when working with functions prefixed with an underscore - <code>_</code>!<br />Those functions are probably for internal usage only.</p>
  242 +
  243 +
  244 +<h3 id="jstree.defaults">jQuery.jstree.defaults</h3>
  245 +<p class="meta">An object. Default is a collection of all included plugin's defaults.</p>
  246 +<p>This object is exposed so that you can apply standart settings to all future instances</p>
  247 +
  248 +<h3 id="jstree.plugin">jQuery.jstree.plugin ( plugin_name , plugin_data )</h3>
  249 +<p>This function is used by developers to extend jstree (add "plugins").</p>
  250 +<ul class="arguments">
  251 + <li>
  252 + <code class="tp">string</code> <strong>plugin_name</strong>
  253 + <p>The plugin name - it should be unique.</p>
  254 + </li>
  255 + <li>
  256 + <code class="tp">object</code> <strong>plugin_data</strong>
  257 + <p>The plugin itself. It consists of <code>__init</code> &amp; <code>__destroy</code> functions, <code>defaults</code> object (that of course could be an array or a simple value) and a <code>_fn</code> object, whose keys are all the functions you are extending jstree with. You can overwrite functions (but you can in your function call the overriden old function), and you are responsible for triggering events and setting rollback points. You can omit any of the elements in the <code>plugin_data</code> param. Keep in mind jstree will automatically clear classes prepended with <code>jstree-</code> and all events in the <code>jstree</code> namespace when destroying a tree, so you do not need to worry about those.</p>
  258 + <p>Read jstree's code for examples on how to develop plugins.</p>
  259 + </li>
  260 +</ul>
  261 +
  262 +<h3 id="jstree.rollback">jQuery.jstree.rollback ( rollback_object )</h3>
  263 +<p>This function will roll the tree back to the state specified by the rollback object</p>
  264 +<ul class="arguments">
  265 + <li>
  266 + <code class="tp">string</code> <strong>rollback_object</strong>
  267 + <p>Normally you will get this object from the event you are handling. You can of course use <code>.get_rollback()</code> to get the current state of the tree as a rollback object.</p>
  268 + <div class="code_f"><pre class="brush:js;">
  269 +$("some-container").bind("some-event.jstree", function (e, data) {
  270 + $.jstree.rollback(data.rlbk);
  271 +});</pre></div>
  272 + <p>Keep in mind that not all events will give you a rollback object - sometimes <code>data.rlbk</code> will be <code>false</code>.</p>
  273 + </li>
  274 +</ul>
  275 +
  276 +<h3 id="jstree._focused">jQuery.jstree._focused ()</h3>
  277 +<p>Returns the currently focused tree instance on the page. If not interaction has been made - it is the last one to be created.</p>
  278 +
  279 +<h3 id="jstree._reference">jQuery.jstree._reference ( needle )</h3>
  280 +<p>Returns the tree instance for the specified <code>needle</code>.</p>
  281 +<ul class="arguments">
  282 + <li>
  283 + <code class="tp">mixed</code> <strong>needle</strong>
  284 + <p>This can be a DOM node, jQuery node or selector pointing to the tree container, or an element within the tree.</p>
  285 + </li>
  286 +</ul>
  287 +
  288 +<h3 id="jstree._instance">jQuery.jstree._instance ( index , container , settings )</h3>
  289 +<p>This function is used internally when creating new tree instances. Calling this function by itself is not enough to create a new instance. To create a tree use the documented method <code>$("selector").jstree([ options ])</code>.</p>
  290 +
  291 +<h3 id="jstree._fn">jQuery.jstree._fn</h3>
  292 +<p>This object stores all functions included by plugins. It is used internally as a prototype for all instances - do not modify manually.</p>
  293 +
  294 +<h3 id="data">.data</h3>
  295 +<p>An object where all plugins store instance specific data. Do not modify manually.</p>
  296 +
  297 +<h3 id="get_settings">.get_settings ()</h3>
  298 +<p>Returns a copy of the instance's settings object - the defaults, extended by your own config object.</p>
  299 +
  300 +<h3 id="_get_settings">._get_settings ()</h3>
  301 +<p>Returns the instance's settings object - the defaults, extended by your own config object.</p>
  302 +
  303 +<h3 id="get_index">.get_index ()</h3>
  304 +<p>Returns the internal instance index.</p>
  305 +
  306 +<h3 id="get_container">.get_container ()</h3>
  307 +<p>Returns the jQuery extended container node of the tree.</p>
  308 +
  309 +<h3 id="get_container_ul">.get_container_ul ()</h3>
  310 +<p>Returns the jQuery extended first UL node in the container of the tree.</p>
  311 +
  312 +<h3 id="_set_settings">._set_settings ( settings )</h3>
  313 +<p>Replace the settings object with the <code>settings</code> param. Please note that not all plugins will react to the change. Unless you know exactly what you are doing you'd be better off recreating the tree with the new settings.</p>
  314 +
  315 +<h3 id="init">.init ()</h3>
  316 +<p>This function is used internally when creating a new instance. Triggers an event, which fires after the tree is initialized, but not yet loaded.</p>
  317 +
  318 +<h3 id="destroy">.destroy ()</h3>
  319 +<p>Destroys the instance - it will automatically remove all bound events in the <code>jstree</code> namespace &amp; remove all classes starting with <code>jstree-</code>. Triggers an event.</p>
  320 +
  321 +<h3 id="save_opened">.save_opened ()</h3>
  322 +<p>Stores the currently open nodes before refreshing. Used internally. Triggers an event.</p>
  323 +
  324 +<h3 id="reopen">.reopen ( is_callback )</h3>
  325 +<p>Reopens all the nodes stored by <code>save_opened</code> or set in the <code>initially_open</code> config option on first load. It is called multiple times while reopening nodes - the <code>is_callback</code> param determines if this is the first call (<code>false</code>) or not. Used internally. Triggers an event.</p>
  326 +
  327 +<h3 id="refresh">.refresh ( node )</h3>
  328 +<p>Refreshes the tree. Saves all open nodes, and reloads and then reopens all saved nodes. Triggers an event.</p>
  329 +<ul class="arguments">
  330 + <li>
  331 + <code class="tp">mixed</code> <strong>node</strong>
  332 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree. If set this will reload only the given node - otherwise - the whole tree. Passing <code>-1</code> also reloads the whole tree.</p>
  333 + </li>
  334 +</ul>
  335 +
  336 +<h3 id="loaded">.loaded ()</h3>
  337 +<p>A dummy function, whose purpose is only to trigger the loaded event. This event is triggered once after the tree's root nodes are loaded, but before any nodes set in <code>initially_open</code> are opened.</p>
  338 +
  339 +<h3 id="set_focus">.set_focus ()</h3>
  340 +<p>Makes the current instance the focused one on the page. Triggers an event.</p>
  341 +
  342 +<h3 id="unset_focus">.unset_focus ()</h3>
  343 +<p>If the current instance is focused this removes the focus. Triggers an event.</p>
  344 +
  345 +<h3 id="is_focused">.is_focused ()</h3>
  346 +<p>Returns <code>true</code> if the current instance is the focused one, otherwise returns <code>false</code>.</p>
  347 +
  348 +<h3 id="lock">.lock ()</h3>
  349 +<p>Sets the tree to a locked state - no methods can be called on that instance except for <code>unlock</code> and <code>is_locked</code>.</p>
  350 +<h3 id="unlock">.unlock ()</h3>
  351 +<p>Sets the tree to a unlocked state (the default state).</p>
  352 +<h3 id="is_locked">.is_locked ()</h3>
  353 +<p>Returns <code>true</code> if the tree is locked, otherwise returns <code>false</code>.</p>
  354 +
  355 +<h3 id="_get_node">._get_node ( node )</h3>
  356 +<p>Return the jQuery extended <code>LI</code> element of the node, <code>-1</code> if the container node is passed, or <code>false</code> otherwise.</p>
  357 +<ul class="arguments">
  358 + <li>
  359 + <code class="tp">mixed</code> <strong>node</strong>
  360 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree.</p>
  361 + </li>
  362 +</ul>
  363 +
  364 +<h3 id="_get_next">._get_next ( node , strict )</h3>
  365 +<p>Gets the <code>LI</code> element representing the node next to the passed <code>node</code>. Returns <code>false</code> on failure.</p>
  366 +<ul class="arguments">
  367 + <li>
  368 + <code class="tp">mixed</code> <strong>node</strong>
  369 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree, whose next sibling we want.</p>
  370 + </li>
  371 + <li>
  372 + <code class="tp">bool</code> <strong>strict</strong>
  373 + <p>If set to <code>true</code> only immediate siblings are calculated. Otherwise if the <code>node</code> is the last child of its parent this function will "jump out" and return the parent's next sibling, etc. Default is <code>false</code>.</p>
  374 + </li>
  375 +</ul>
  376 +
  377 +<h3 id="_get_prev">._get_prev ( node , strict )</h3>
  378 +<p>Gets the <code>LI</code> element representing the node previous to the passed <code>node</code>. Returns <code>false</code> on failure.</p>
  379 +<ul class="arguments">
  380 + <li>
  381 + <code class="tp">mixed</code> <strong>node</strong>
  382 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree, whose previous sibling we want.</p>
  383 + </li>
  384 + <li>
  385 + <code class="tp">bool</code> <strong>strict</strong>
  386 + <p>If set to <code>true</code> only immediate siblings are calculated. Otherwise if the <code>node</code> is the first child of its parent this function will "jump out" and return the parent itself. Default is <code>false</code>.</p>
  387 + </li>
  388 +</ul>
  389 +
  390 +<h3 id="_get_parent">._get_parent ( node )</h3>
  391 +<p>Gets the <code>LI</code> element representing the parent of the passed <code>node</code>. Returns <code>false</code> on failure.</p>
  392 +<ul class="arguments">
  393 + <li>
  394 + <code class="tp">mixed</code> <strong>node</strong>
  395 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree, whose parent we want.</p>
  396 + </li>
  397 +</ul>
  398 +
  399 +<h3 id="_get_children">._get_children ( node )</h3>
  400 +<p>Gets the <code>LI</code> elements representing the children of the passed <code>node</code>. Returns <code>false</code> on failure (or if the node has no children).</p>
  401 +<ul class="arguments">
  402 + <li>
  403 + <code class="tp">mixed</code> <strong>node</strong>
  404 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree, whose children we want. Use <code>-1</code> to return all root nodes.</p>
  405 + </li>
  406 +</ul>
  407 +
  408 +<h3 id="get_path">.get_path ( node , id_mode )</h3>
  409 +<p>Return the path to a node, either as an array of IDs or as an array of node names.</p>
  410 +<ul class="arguments">
  411 + <li>
  412 + <code class="tp">mixed</code> <strong>node</strong>
  413 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree, whose path we want.</p>
  414 + </li>
  415 + <li>
  416 + <code class="tp">bool</code> <strong>id_mode</strong>
  417 + <p>If set to <code>true</code> IDs are returned instead of the names of the parents. Default is <code>false</code>.</p>
  418 + </li>
  419 +</ul>
  420 +
  421 +<h3 id="correct_state">.correct_state ( node )</h3>
  422 +<p>Corrects closed items to leaf items, if no children are found. Used internally, triggers an event.</p>
  423 +<ul class="arguments">
  424 + <li>
  425 + <code class="tp">mixed</code> <strong>node</strong>
  426 + <p>This can be a DOM node, jQuery node or selector pointing to an element we want corrected.</p>
  427 + </li>
  428 +
  429 +
  430 +<h3 id="open_node">.open_node ( node , callback , skip_animation )</h3>
  431 +<p>Opens a closed node, so that its children are visible. If the <code>animation</code> config option is greater than <code>0</code> the children are revealed using a slide down animation, whose duration is the value of the <code>animation</code> config option in milliseconds. Triggers an event.</p>
  432 +<ul class="arguments">
  433 + <li>
  434 + <code class="tp">mixed</code> <strong>node</strong>
  435 + <p>This can be a DOM node, jQuery node or selector pointing to an element we want opened.</p>
  436 + </li>
  437 + <li>
  438 + <code class="tp">function</code> <strong>callback</strong>
  439 + <p>A callback function executed once the node is opened. Used mostly internally, you'd be better of waiting for the event. You can skip this, by not specifying it, or by passing <code>false</code>.</p>
  440 + </li>
  441 + <li>
  442 + <code class="tp">bool</code> <strong>skip_animation</strong>
  443 + <p>If set to <code>true</code> the animation set in the <code>animation</code> config option is skipped. Default is <code>false</code>.</p>
  444 + </li>
  445 +</ul>
  446 +
  447 +<h3 id="after_open">.after_open ( node )</h3>
  448 +<p>A dummy function, it triggers an event after the open animation has finished.</p>
  449 +
  450 +<h3 id="close_node">.close_node ( node , skip_animation )</h3>
  451 +<p>Closes an open node, so that its children are not visible. If the <code>animation</code> config option is greater than <code>0</code> the children are hidden using a slide up animation, whose duration is the value of the <code>animation</code> config option in milliseconds. Triggers an event.</p>
  452 +<ul class="arguments">
  453 + <li>
  454 + <code class="tp">mixed</code> <strong>node</strong>
  455 + <p>This can be a DOM node, jQuery node or selector pointing to an element we want closed.</p>
  456 + </li>
  457 + <li>
  458 + <code class="tp">bool</code> <strong>skip_animation</strong>
  459 + <p>If set to <code>true</code> the animation set in the <code>animation</code> config option is skipped. Default is <code>false</code>.</p>
  460 + </li>
  461 +</ul>
  462 +
  463 +<h3 id="after_close">.after_close ( node )</h3>
  464 +<p>A dummy function, it triggers an event after the close animation has finished.</p>
  465 +
  466 +<h3 id="toggle_node">.toggle_node ( node )</h3>
  467 +<p>If a node is closed - this function opens it, if it is open - calling this function will close it.</p>
  468 +<ul class="arguments">
  469 + <li>
  470 + <code class="tp">mixed</code> <strong>node</strong>
  471 + <p>This can be a DOM node, jQuery node or selector pointing to an element we want toggled.</p>
  472 + </li>
  473 +</ul>
  474 +
  475 +<h3 id="open_all">.open_all ( node , do_animation, original_obj )</h3>
  476 +<p>Opens all descendants of the <code>node</code> node.</p>
  477 +<ul class="arguments">
  478 + <li>
  479 + <code class="tp">mixed</code> <strong>node</strong>
  480 + <p>This can be a DOM node, jQuery node or selector pointing to an element whose descendants you want opened. If this param is omitted or set to <code>-1</code> all nodes in the tree are opened.</p>
  481 + </li>
  482 + <li>
  483 + <code class="tp">boolean</code> <strong>do_animation</strong>
  484 + <p>If set to <code>true</code> all nodes are opened with an animation. This can be slow on large trees.</p>
  485 + </li>
  486 + <li>
  487 + <code class="tp">mixed</code> <strong>original_obj</strong>
  488 + <p>Used internally when recursively calling the same function - do not pass this param.</p>
  489 + </li>
  490 +</ul>
  491 +
  492 +<h3 id="close_all">.close_all ( node, do_animation )</h3>
  493 +<p>Closes all descendants of the <code>node</code> node.</p>
  494 +<ul class="arguments">
  495 + <li>
  496 + <code class="tp">mixed</code> <strong>node</strong>
  497 + <p>This can be a DOM node, jQuery node or selector pointing to an element whose descendants you want closed. If this param is omitted or set to <code>-1</code> all nodes in the tree are closed.</p>
  498 + </li>
  499 + <li>
  500 + <code class="tp">boolean</code> <strong>do_animation</strong>
  501 + <p>If set to <code>true</code> all nodes are closed with an animation. This can be slow on large trees.</p>
  502 + </li>
  503 +</ul>
  504 +
  505 +<div style="height:1px; visibility:hidden;"><span id="is_leaf">&nbsp;</span><span id="is_closed">&nbsp;</span></div>
  506 +<h3 id="is_open">.is_open ( node ), .is_closed ( node ), .is_leaf ( node )</h3>
  507 +<p>Those function check if the <code>node</code> is in a state.</p>
  508 +<ul class="arguments">
  509 + <li>
  510 + <code class="tp">mixed</code> <strong>node</strong>
  511 + <p>This can be a DOM node, jQuery node or selector pointing to an element you want checked.</p>
  512 + </li>
  513 +</ul>
  514 +
  515 +<h3 id="clean_node">.clean_node ( node )</h3>
  516 +<p>Applies all necessary classes to the <code>node</code> and its descendants. Used internally. Triggers an event.</p>
  517 +<ul class="arguments">
  518 + <li>
  519 + <code class="tp">mixed</code> <strong>node</strong>
  520 + <p>This can be a DOM node, jQuery node or selector pointing to an element you want cleaned. If this param is omitted or set to <code>-1</code> all nodes in the tree are cleaned.</p>
  521 + </li>
  522 +</ul>
  523 +
  524 +<h3 id="get_rollback">.get_rollback ()</h3>
  525 +<p>Get the current tree's state in the rollback format. Used mainly internally by plugins.</p>
  526 +
  527 +<h3 id="set_rollback">.set_rollback ( html , data )</h3>
  528 +<p>Rollback the tree. Used ONLY internally! Both arguments are part of the rollback object. If you need to rollback - take a look at <a href="#jstree.rollback">jQuery.jstree.rollback()</a>. Triggers event.</p>
  529 +
  530 +<h3 id="load_node">.load_node ( node , success_callback , error_callback )</h3>
  531 +<p>A dummy function that is overwritten by data plugins. Triggers event.</p>
  532 +<ul class="arguments">
  533 + <li>
  534 + <code class="tp">mixed</code> <strong>node</strong>
  535 + <p>This can be a DOM node, jQuery node or selector pointing to an element you want loaded. Use <code>-1</code> for root nodes.</p>
  536 + </li>
  537 + <li>
  538 + <code class="tp">function</code> <strong>success_callback</strong>
  539 + <p>A function to be executed once the node is loaded successfully - used internally. You should wait for the event.</p>
  540 + </li>
  541 + <li>
  542 + <code class="tp">function</code> <strong>error_callback</strong>
  543 + <p>A function to be executed if the node is not loaded due to an error - used internally. You should wait for the event.</p>
  544 + </li>
  545 +</ul>
  546 +
  547 +<h3 id="_is_loaded">._is_loaded ( node )</h3>
  548 +<p>A dummy function that should return <code>true</code> if the node's children are loaded or <code>false</code> otherwise.</p>
  549 +<ul class="arguments">
  550 + <li>
  551 + <code class="tp">mixed</code> <strong>node</strong>
  552 + <p>This can be a DOM node, jQuery node or selector pointing to an element you want to check.</p>
  553 + </li>
  554 +</ul>
  555 +
  556 +<h3 id="create_node">.create_node ( node , position , js , callback , is_loaded )</h3>
  557 +<p>Creates the DOM structure necessary for a new node. Triggers an event.</p>
  558 +<ul class="arguments">
  559 + <li>
  560 + <code class="tp">mixed</code> <strong>node</strong>
  561 + <p>This can be a DOM node, jQuery node or selector pointing to the element you want to create in (or next to).</p>
  562 + </li>
  563 + <li>
  564 + <code class="tp">mixed</code> <strong>position</strong>
  565 + <p>The position of the newly created node. This can be a zero based index to position the element at a specific point among the current children. You can also pass in one of those strings: <code>"before"</code>, <code>"after"</code>, <code>"inside"</code>, <code>"first"</code>, <code>"last"</code>.</p>
  566 + </li>
  567 + <li>
  568 + <code class="tp">object</code> <strong>js</strong>
  569 + <p>The data for the newly created node. Consists of three keys:</p><p style="margin-left:25px;"><code class="tp">attr</code> - an object of attributes (same used for <code>jQuery.attr()</code>. You can omit this key;<br /><code class="tp">state</code> - a string - either <code>"open"</code> or <code>"closed"</code>, for a leaf node - omit this key;<br /><code class="tp">data</code> - a string or an object - if a string is passed it is used for the title of the node, if an object is passed there are two keys you can specify: <code>attr</code> and <code>title</code>;</p>
  570 + </li>
  571 + <li>
  572 + <code class="tp">function</code> <strong>callback</strong>
  573 + <p>A function to be executed once the node is created - used internally. You should wait for the event.</p>
  574 + </li>
  575 + <li>
  576 + <code class="tp">bool</code> <strong>is_loaded</strong>
  577 + <p>Specifies if the parent of the node is loaded or not - used ONLY internally.</p>
  578 + </li>
  579 +</ul>
  580 +
  581 +<h3 id="_get_string">._get_string ( node )</h3>
  582 +<p>Returns the needed string from the config object. If the key does not exist the key itself is returned.</p>
  583 +<ul class="arguments">
  584 + <li>
  585 + <code class="tp">string</code> <strong>key</strong>
  586 + <p>The name of the string you are looking for.</p>
  587 + </li>
  588 +</ul>
  589 +
  590 +<h3 id="get_text">.get_text ( node )</h3>
  591 +<p>Returns the title of a node.</p>
  592 +<ul class="arguments">
  593 + <li>
  594 + <code class="tp">mixed</code> <strong>node</strong>
  595 + <p>This can be a DOM node, jQuery node or selector pointing to the element whose title you need.</p>
  596 + </li>
  597 +</ul>
  598 +
  599 +<h3 id="set_text">.set_text ( node , text )</h3>
  600 +<p>Sets the title of a node. Triggers an event. This is used mostly internally - wait for a <a href="#rename_node">.rename_node event</a> to avoid confusion.</p>
  601 +<ul class="arguments">
  602 + <li>
  603 + <code class="tp">mixed</code> <strong>node</strong>
  604 + <p>This can be a DOM node, jQuery node or selector pointing to the element whose title you want to change.</p>
  605 + </li>
  606 + <li>
  607 + <code class="tp">string</code> <strong>text</strong>
  608 + <p>The new title.</p>
  609 + </li>
  610 +</ul>
  611 +
  612 +<h3 id="rename_node">.rename_node ( node , text )</h3>
  613 +<p>Sets the title of a node. Triggers an event.</p>
  614 +<ul class="arguments">
  615 + <li>
  616 + <code class="tp">mixed</code> <strong>node</strong>
  617 + <p>This can be a DOM node, jQuery node or selector pointing to the element whose title you want to change.</p>
  618 + </li>
  619 + <li>
  620 + <code class="tp">string</code> <strong>text</strong>
  621 + <p>The new title.</p>
  622 + </li>
  623 +</ul>
  624 +
  625 +<h3 id="delete_node">.delete_node ( node )</h3>
  626 +<p>Removes a node. Triggers an event.</p>
  627 +<ul class="arguments">
  628 + <li>
  629 + <code class="tp">mixed</code> <strong>node</strong>
  630 + <p>This can be a DOM node, jQuery node or selector pointing to the element you want to remove.</p>
  631 + </li>
  632 +</ul>
  633 +
  634 +<h3 id="prepare_move">.prepare_move ( o , r , pos , cb , is_cb )</h3>
  635 +<p>This function is used internally to prepare all necessary variables and nodes when moving a node around. It is automatically called as needed - you do not need to call it manually. Triggers an event.</p>
  636 +
  637 +<h3 id="check_move">.check_move ()</h3>
  638 +<p>Checks if the prepared move is a valid one.</p>
  639 +
  640 +<h3 id="move_node">.move_node ( node , ref , position , is_copy , is_prepared , skip_check )</h3>
  641 +<p>Moves a node to a new place. Triggers an event.</p>
  642 +<ul class="arguments">
  643 + <li>
  644 + <code class="tp">mixed</code> <strong>node</strong>
  645 + <p>This can be a DOM node, jQuery node or selector pointing to the element you want to move.</p>
  646 + </li>
  647 + <li>
  648 + <code class="tp">mixed</code> <strong>ref</strong>
  649 + <p>This can be a DOM node, jQuery node or selector pointing to the element which will be the reference element in the move. <code>-1</code> may be used too (to indicate the container node).</p>
  650 + </li>
  651 + <li>
  652 + <code class="tp">mixed</code> <strong>position</strong>
  653 + <p>The new position of the moved node. This can be a zero based index to position the element at a specific point among the reference node's current children. You can also use one of these strings: <code>"before"</code>, <code>"after"</code>, <code>"inside"</code>, <code>"first"</code>, <code>"last"</code>.</p>
  654 + </li>
  655 + <li>
  656 + <code class="tp">bool</code> <strong>is_copy</strong>
  657 + <p>Should this be a copy or a move operation.</p>
  658 + </li>
  659 + <li>
  660 + <code class="tp">bool</code> <strong>is_prepared</strong>
  661 + <p>Used internally when this function is called recursively.</p>
  662 + </li>
  663 + <li>
  664 + <code class="tp">bool</code> <strong>skip_check</strong>
  665 + <p>If this is set to <code>true</code> <a href="#check_move">check_move</a> is not called.</p>
  666 + </li>
  667 +</ul>
  668 +
  669 +<h3 id="_get_move">._get_move ()</h3>
  670 +<p>Returns the lastly prepared move. The returned object contains:<br />
  671 +<code>.o</code> - the node being moved<br />
  672 +<code>.r</code> - the reference node in the move<br />
  673 +<code>.ot</code> - the origin tree instance<br />
  674 +<code>.rt</code> - the reference tree instance<br />
  675 +<code>.p</code> - the position to move to (may be a string - <code>"last"</code>, <code>"first"</code>, etc)<br />
  676 +<code>.cp</code> - the calculated position to move to (always a number)<br />
  677 +<code>.np</code> - the new parent<br />
  678 +<code>.oc</code> - the original node (if there was a copy)<br />
  679 +<code>.cy</code> - boolen indicating if the move was a copy<br />
  680 +<code>.cr</code> - same as <code>np</code>, but if a root node is created this is -1<br />
  681 +<code>.op</code> - the former parent<br />
  682 +<code>.or</code> - the node that was previously in the position of the moved node<br />
  683 +</p>
  684 +
  685 +</div>
  686 +
  687 +</div>
  688 +</body>
  689 +</html>
0 690 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/crrm.html 0 → 100644
... ... @@ -0,0 +1,316 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - CRRM documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>crrm plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>CRRM</code> plugin handles creating, renaming, removing and moving nodes by the user.</p>
  25 +</div>
  26 +
  27 +<h2 id="configuration">Configuration</h2>
  28 +<div class="panel configuration">
  29 +<h3>input_width_limit</h3>
  30 +<p class="meta">A number. Default is <code>200</code>.</p>
  31 +<p>When renaming (or creating) nodes the input for the text will autosize - this number sets the maximum size for the input.</p>
  32 +
  33 +<h3>move</h3>
  34 +<p class="meta">An object, containing various settings - see below for more.</p>
  35 +
  36 +<h3>move.always_copy</h3>
  37 +<p class="meta"><code>true</code>, <code>false</code> or <code>"multitree"</code>. Default is <code>false</code>.</p>
  38 +<p>Defines how moves are handled - if set to <code>true</code> every move will be forced to a copy (leaving the original node in place). If set to <code>"multitree"</code> only moves between trees will be forced to a copy.</p>
  39 +
  40 +<h3>move.open_onmove</h3>
  41 +<p class="meta">A Boolean. Default is <code>true</code>.</p>
  42 +<p>If set to true, when moving a node to a new, closed parent, the parent node will be opened when the move completes.</p>
  43 +
  44 +<h3>move.default_position</h3>
  45 +<p class="meta">A string or a number. Default is <code>"last"</code>.</p>
  46 +<p>The default position to move to if no position is specified. This can be a zero based index to position the element at a specific point among the new parent's current children. You can also use one of these strings: <code>"before"</code>, <code>"after"</code>, <code>"inside"</code>, <code>"first"</code>, <code>"last"</code>.</p>
  47 +
  48 +<h3>move.check_move</h3>
  49 +<p class="meta">A function. Default is <code>function (m) { return true; }</code>.</p>
  50 +<p>The callback function enabling you to prevent some moves - just return <code>false</code>. The <code>m</code> parameter is the move object generated by jstree. The object follows the structure described in <a href="core.html#_get_move">._get_move</a>.</p>
  51 +
  52 +</div>
  53 +
  54 +<h2 id="demos">Demos</h2>
  55 +<div class="panel">
  56 +
  57 +<h3>Creating nodes</h3>
  58 +<input type="button" class="button" value="create_1" id="create_1" style="float:left;" />
  59 +<input type="button" class="button" value="create_2" id="create_2" style="float:left;" />
  60 +<input type="button" class="button" value="create_3" id="create_3" style="" />
  61 +<div id="demo1" class="demo">
  62 + <ul>
  63 + <li id="phtml_1">
  64 + <a href="#">Root node 1</a>
  65 + <ul>
  66 + <li id="phtml_2">
  67 + <a href="#">Child node 1</a>
  68 + </li>
  69 + <li id="phtml_3">
  70 + <a href="#">Child node 2</a>
  71 + </li>
  72 + </ul>
  73 + </li>
  74 + <li id="phtml_4">
  75 + <a href="#">Root node 2</a>
  76 + </li>
  77 + </ul>
  78 +</div>
  79 +<script type="text/javascript" class="source">
  80 +$(function () {
  81 + $("#create_1").click(function () {
  82 + $("#demo1").jstree("create");
  83 + });
  84 + $("#create_2").click(function () {
  85 + $("#demo1").jstree("create","#phtml_1","first","Enter a new name");
  86 + });
  87 + $("#create_3").click(function () {
  88 + $("#demo1").jstree("create",-1,false,"No rename",false,true);
  89 + });
  90 + $("#demo1").jstree({
  91 + "ui" : {
  92 + "initially_select" : [ "phtml_2" ]
  93 + },
  94 + "core" : { "initially_open" : [ "phtml_1" ] },
  95 + "plugins" : [ "themes", "html_data", "ui", "crrm" ]
  96 + });
  97 +});
  98 +</script>
  99 +
  100 +<h3>Removing nodes</h3>
  101 +<input type="button" class="button" value="remove_1" id="remove_1" style="float:left;" />
  102 +<input type="button" class="button" value="remove_2" id="remove_2" style="" />
  103 +<div id="demo2" class="demo">
  104 + <ul>
  105 + <li id="rhtml_1">
  106 + <a href="#">Root node 1</a>
  107 + <ul>
  108 + <li id="rhtml_2">
  109 + <a href="#">Child node 1</a>
  110 + </li>
  111 + <li id="rhtml_3">
  112 + <a href="#">Child node 2</a>
  113 + </li>
  114 + </ul>
  115 + </li>
  116 + <li id="rhtml_4">
  117 + <a href="#">Root node 2</a>
  118 + </li>
  119 + </ul>
  120 +</div>
  121 +<script type="text/javascript" class="source">
  122 +$(function () {
  123 + $("#remove_1").click(function () {
  124 + $("#demo2").jstree("remove");
  125 + });
  126 + $("#remove_2").click(function () {
  127 + $("#demo2").jstree("remove","#rhtml_1");
  128 + });
  129 + $("#demo2").jstree({
  130 + "ui" : {
  131 + "initially_select" : [ "rhtml_2" ]
  132 + },
  133 + "core" : { "initially_open" : [ "rhtml_1" ] },
  134 + "plugins" : [ "themes", "html_data", "ui", "crrm" ]
  135 + });
  136 +});
  137 +</script>
  138 +
  139 +<h3>Renaming nodes</h3>
  140 +<input type="button" class="button" value="rename_1" id="rename_1" style="float:left;" />
  141 +<input type="button" class="button" value="rename_2" id="rename_2" style="" />
  142 +<div id="demo3" class="demo">
  143 + <ul>
  144 + <li id="shtml_1">
  145 + <a href="#">Root node 1</a>
  146 + <ul>
  147 + <li id="shtml_2">
  148 + <a href="#">Child node 1</a>
  149 + </li>
  150 + <li id="shtml_3">
  151 + <a href="#">Child node 2</a>
  152 + </li>
  153 + </ul>
  154 + </li>
  155 + <li id="shtml_4">
  156 + <a href="#">Root node 2</a>
  157 + </li>
  158 + </ul>
  159 +</div>
  160 +<script type="text/javascript" class="source">
  161 +$(function () {
  162 + $("#rename_1").click(function () {
  163 + $("#demo3").jstree("rename");
  164 + });
  165 + $("#rename_2").click(function () {
  166 + $("#demo3").jstree("rename","#shtml_1");
  167 + });
  168 + $("#demo3").jstree({
  169 + "ui" : {
  170 + "initially_select" : [ "shtml_2" ]
  171 + },
  172 + "core" : { "initially_open" : [ "shtml_1" ] },
  173 + "plugins" : [ "themes", "html_data", "ui", "crrm" ]
  174 + });
  175 +});
  176 +</script>
  177 +
  178 +<h3>Moving nodes</h3>
  179 +<p><strong>move_1</strong> uses the default position - <code>"first"</code></p>
  180 +<p><strong>move_2</strong> specifies a position - <code>"before"</code> - meaning that the node specified as a first argument will come above the node specified as the second argument</p>
  181 +<p><strong>move_3</strong> will never work, because of the specified <code>check_move</code> function which prevents the first root node from being moved</p>
  182 +<input type="button" class="button" value="move_1" id="move_1" style="float:left;" />
  183 +<input type="button" class="button" value="move_2" id="move_2" style="float:left;" />
  184 +<input type="button" class="button" value="move_3" id="move_3" style="" />
  185 +<div id="demo4" class="demo">
  186 + <ul>
  187 + <li id="thtml_1">
  188 + <a href="#">Root node 1</a>
  189 + <ul>
  190 + <li id="thtml_2">
  191 + <a href="#">Child node 1</a>
  192 + </li>
  193 + <li id="thtml_3">
  194 + <a href="#">Child node 2</a>
  195 + </li>
  196 + </ul>
  197 + </li>
  198 + <li id="thtml_4">
  199 + <a href="#">Root node 2</a>
  200 + </li>
  201 + </ul>
  202 +</div>
  203 +<script type="text/javascript" class="source">
  204 +$(function () {
  205 + $("#move_1").click(function () {
  206 + $("#demo4").jstree("move_node","#thtml_4","#thtml_1");
  207 + });
  208 + $("#move_2").click(function () {
  209 + $("#demo4").jstree("move_node","#thtml_4","#thtml_1", "before");
  210 + });
  211 + $("#move_3").click(function () {
  212 + $("#demo4").jstree("move_node","#thtml_1","#thtml_4");
  213 + });
  214 + $("#demo4").jstree({
  215 + "crrm" : {
  216 + "move" : {
  217 + "default_position" : "first",
  218 + "check_move" : function (m) { return (m.o[0].id === "thtml_1") ? false : true; }
  219 + }
  220 + },
  221 + "ui" : {
  222 + "initially_select" : [ "thtml_2" ]
  223 + },
  224 + "core" : { "initially_open" : [ "thtml_1" ] },
  225 + "plugins" : [ "themes", "html_data", "ui", "crrm" ]
  226 + });
  227 +});
  228 +</script>
  229 +
  230 +</div>
  231 +
  232 +<h2 id="api">API</h2>
  233 +<div class="panel api">
  234 +
  235 +<h3 id="_show_input">._show_input ( node , callback )</h3>
  236 +<p>Renders an input field in a node. Used only internally.</p>
  237 +
  238 +<h3 id="rename">.rename ( node )</h3>
  239 +<p>Sets a node in rename mode and when the user has entered changes, an event is triggered.</p>
  240 +<ul class="arguments">
  241 + <li>
  242 + <code class="tp">mixed</code> <strong>node</strong>
  243 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree. If you use the UI plugin - pass <code>null</code> to use the currently selected item.</p>
  244 + </li>
  245 +</ul>
  246 +
  247 +<h3 id="create">.create ( node , position , js , callback , skip_rename )</h3>
  248 +<p>Creates a new node. Triggers an event.</p>
  249 +<ul class="arguments">
  250 + <li>
  251 + <code class="tp">mixed</code> <strong>node</strong>
  252 + <p>This can be a DOM node, jQuery node or selector pointing to the element you want to create in (or next to). If you use the UI plugin - pass <code>null</code> to use the currently selected item.</p>
  253 + </li>
  254 + <li>
  255 + <code class="tp">mixed</code> <strong>position</strong>
  256 + <p>The position of the newly created node. This can be a zero based index to position the element at a specific point among the current children. You can also pass in one of those strings: <code>"before"</code>, <code>"after"</code>, <code>"inside"</code>, <code>"first"</code>, <code>"last"</code>.</p>
  257 + </li>
  258 + <li>
  259 + <code class="tp">object</code> <strong>js</strong>
  260 + <p>The data for the newly created node. Consists of three keys:</p><p style="margin-left:25px;"><code class="tp">attr</code> - an object of attributes (same used for <code>jQuery.attr()</code>. You can omit this key;<br /><code class="tp">state</code> - a string - either <code>"open"</code> or <code>"closed"</code>, for a leaf node - omit this key;<br /><code class="tp">data</code> - a string or an object - if a string is passed it is used for the title of the node, if an object is passed there are two keys you can specify: <code>attr</code> and <code>title</code>;</p>
  261 + </li>
  262 + <li>
  263 + <code class="tp">function</code> <strong>callback</strong>
  264 + <p>A function to be executed once the node is created. You'd be better off waiting for the event.</p>
  265 + </li>
  266 + <li>
  267 + <code class="tp">bool</code> <strong>skip_rename</strong>
  268 + <p>Skips the user input step. The node is created with the data you have supplied.</p>
  269 + </li>
  270 +</ul>
  271 +
  272 +<h3 id="remove">.remove ( node )</h3>
  273 +<p>Removes a node. Triggers an event.</p>
  274 +<ul class="arguments">
  275 + <li>
  276 + <code class="tp">mixed</code> <strong>node</strong>
  277 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree. If you use the UI plugin - pass <code>null</code> to use the currently selected items.</p>
  278 + </li>
  279 +</ul>
  280 +
  281 +<div style="height:1px; visibility:hidden; overflow:hidden;"><span id="check_move">&#160;</span></div>
  282 +<h3 id="move_node">.check_move ( ), .move_node ( )</h3>
  283 +<p>Both functions are overwritten from the <a href="core.html#check_move">core</a> in order to implement the new functionality.</p>
  284 +
  285 +<h3 id="cut">.cut ( node )</h3>
  286 +<p>Cuts a node (prepares it for pasting).</p>
  287 +<ul class="arguments">
  288 + <li>
  289 + <code class="tp">mixed</code> <strong>node</strong>
  290 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree. If you use the UI plugin - pass <code>null</code> to use the currently selected item.</p>
  291 + </li>
  292 +</ul>
  293 +
  294 +<h3 id="copy">.copy ( node )</h3>
  295 +<p>Copies a node (prepares it for pasting).</p>
  296 +<ul class="arguments">
  297 + <li>
  298 + <code class="tp">mixed</code> <strong>node</strong>
  299 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree. If you use the UI plugin - pass <code>null</code> to use the currently selected item.</p>
  300 + </li>
  301 +</ul>
  302 +
  303 +<h3 id="paste">.paste ( node )</h3>
  304 +<p>Pastes copied or cut nodes inside a node.</p>
  305 +<ul class="arguments">
  306 + <li>
  307 + <code class="tp">mixed</code> <strong>node</strong>
  308 + <p>This can be a DOM node, jQuery node or selector pointing to an element within the tree. If you use the UI plugin - pass <code>null</code> to use the currently selected item.</p>
  309 + </li>
  310 +</ul>
  311 +
  312 +</div>
  313 +
  314 +</div>
  315 +</body>
  316 +</html>
0 317 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/dnd.html 0 → 100644
... ... @@ -0,0 +1,199 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - dnd documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>dnd plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>dnd</code> plugin enables drag'n'drop support for jstree, also using foreign nodes and drop targets.</p>
  25 +<p class="note">All foreign node options and callback functions in the config (drop_target, drop_check, drop_finish, drag_target, drag_check, drag_finish) are to be used ONLY when nodes that are not part of any tree are involved.<br />If moving nodes from one tree instance to another - just listen for the "move_node.jstree" event on the receiving tree.<br /><span style="color:red">DO NOT SET drag_target AND drop_target to match tree nodes!</span></p>
  26 +</div>
  27 +
  28 +<h2 id="configuration">Configuration</h2>
  29 +<div class="panel configuration">
  30 +
  31 +<h3>copy_modifier</h3>
  32 +<p class="meta">A string. Default is <code>"ctrl"</code>.</p>
  33 +<p>The special key used to make a drag copy instead of move (<code>"ctrl"</code>, <code>"shift"</code>, <code>"alt"</code>, <code>"meta"</code>).</p>
  34 +
  35 +<h3>check_timeout</h3>
  36 +<p class="meta">A number. Default is <code>200</code>.</p>
  37 +<p>The number of milliseconds to wait before checking if a move is valid upon hovering a node (while dragging). <code>200</code> is a reasonable value - a higher number means better performance but slow feedback to the user, a lower number means lower performance (possibly) but the user will get feedback faster.</p>
  38 +
  39 +<h3>open_timeout</h3>
  40 +<p class="meta">A number. Default is <code>500</code>.</p>
  41 +<p>The number of milliseconds to wait before opening a hovered if it has children (while dragging). This means that the user has to stop over the node for half a second in order to trigger the open operation. Keep in mind that a low value in combination with async data could mean a lot of unneeded traffic, so <code>500</code> is quite reasonable.</p>
  42 +
  43 +<h3>drop_target</h3>
  44 +<p class="meta">A string (jQuery selector) (or <code>false</code>). Default is <code>".jstree-drop"</code>.</p>
  45 +<p>A jquery selector matching all drop targets (you can also use the comma <code>,</code> in the string to specify multiple valid targets). If set to <code>false</code> drop targets are disabled.</p>
  46 +
  47 +<h3>drop_check</h3>
  48 +<p class="meta">A function. Default is <code>function (data) { return true; }</code>.</p>
  49 +<p>Return <code>false</code> to mark the move as invalid, otherwise return <code>true</code>. The <code>data</code> parameter is as follows:</p>
  50 +<p style="margin-left:2em;"><code>data.o</code> - the object being dragged</p>
  51 +<p style="margin-left:2em;"><code>data.r</code> - the drop target</p>
  52 +
  53 +<h3>drop_finish</h3>
  54 +<p class="meta">A function. Default is <code>$.noop</code>.</p>
  55 +<p>Gets executed after a valid drop, you get one parameter, which is as follows:</p>
  56 +<p style="margin-left:2em;"><code>data.o</code> - the object being dragged</p>
  57 +<p style="margin-left:2em;"><code>data.r</code> - the drop target</p>
  58 +
  59 +<h3>drag_target</h3>
  60 +<p class="meta">A string (jQuery selector) (or <code>false</code>). Default is <code>".jstree-draggable"</code>.</p>
  61 +<p>A jquery selector matching all foreign nodes that can be dropped on the tree (you can also use the comma <code>,</code> in the string to specify multiple valid foreign nodes). If set to <code>false</code> dragging foreign nodes is disabled.</p>
  62 +
  63 +<h3>drag_check</h3>
  64 +<p class="meta">A function. Default is <code>function (data) { return { after : false, before : false, inside : true }; }</code>.</p>
  65 +<p>Return a boolean for each position. The <code>data</code> parameter is as follows:</p>
  66 +<p style="margin-left:2em;"><code>data.o</code> - the foreign object being dragged</p>
  67 +<p style="margin-left:2em;"><code>data.r</code> - the hovered node</p>
  68 +
  69 +<h3>drag_finish</h3>
  70 +<p class="meta">A function. Default is <code>$.noop</code>.</p>
  71 +<p>Gets executed after a dropping a foreign element on a tree item, you get one parameter, which is as follows:</p>
  72 +<p style="margin-left:2em;"><code>data.o</code> - the foreign object being dragged</p>
  73 +<p style="margin-left:2em;"><code>data.r</code> - the target node</p>
  74 +
  75 +
  76 +</div>
  77 +
  78 +<h2 id="demos">Demos</h2>
  79 +<div class="panel">
  80 +<h3>Using the dnd plugin</h3>
  81 +<p>Drag stuff around!</p>
  82 +<div class="jstree-drop" style="clear:both; border:5px solid green; background:lime; color:green; height:40px; line-height:40px; text-align:center; font-size:20px;">I have the jstree-drop class</div>
  83 +<div class="jstree-draggable" style="margin:10px 0; clear:both; border:5px solid navy; background:aqua; color:navy; height:40px; line-height:40px; text-align:center; font-size:20px;">I have the jstree-draggable class</div>
  84 +<div id="demo1" class="demo">
  85 + <ul>
  86 + <li id="phtml_1">
  87 + <a href="#">Root node 1</a>
  88 + <ul>
  89 + <li id="phtml_2">
  90 + <a href="#">Child node 1</a>
  91 + </li>
  92 + <li id="phtml_3">
  93 + <a href="#">Child node 2</a>
  94 + </li>
  95 + </ul>
  96 + </li>
  97 + <li id="phtml_4">
  98 + <a href="#">Root node 2</a>
  99 + </li>
  100 + </ul>
  101 +</div>
  102 +<script type="text/javascript" class="source">
  103 +$(function () {
  104 + $("#demo1").jstree({
  105 + "dnd" : {
  106 + "drop_finish" : function () {
  107 + alert("DROP");
  108 + },
  109 + "drag_check" : function (data) {
  110 + if(data.r.attr("id") == "phtml_1") {
  111 + return false;
  112 + }
  113 + return {
  114 + after : false,
  115 + before : false,
  116 + inside : true
  117 + };
  118 + },
  119 + "drag_finish" : function (data) {
  120 + alert("DRAG OK");
  121 + }
  122 + },
  123 + "plugins" : [ "themes", "html_data", "dnd" ]
  124 + });
  125 +});
  126 +</script>
  127 +
  128 +<h3>Reorder only demo</h3>
  129 +<div id="demo2" class="demo">
  130 + <ul>
  131 + <li id="rhtml_1">
  132 + <a href="#">Root node 1</a>
  133 + <ul>
  134 + <li id="rhtml_2">
  135 + <a href="#">Child node 1</a>
  136 + </li>
  137 + <li id="rhtml_3">
  138 + <a href="#">Child node 2</a>
  139 + </li>
  140 + <li id="rhtml_4">
  141 + <a href="#">Child node 3</a>
  142 + </li>
  143 + <li id="rhtml_5">
  144 + <a href="#">Child node 4</a>
  145 + </li>
  146 + </ul>
  147 + </li>
  148 + <li id="rhtml_6">
  149 + <a href="#">Root node 2</a>
  150 + </li>
  151 + <li id="rhtml_7">
  152 + <a href="#">Root node 3</a>
  153 + </li>
  154 + </ul>
  155 +</div>
  156 +<script type="text/javascript" class="source">
  157 +$(function () {
  158 + $("#demo2").jstree({
  159 + "crrm" : {
  160 + "move" : {
  161 + "check_move" : function (m) {
  162 + var p = this._get_parent(m.o);
  163 + if(!p) return false;
  164 + p = p == -1 ? this.get_container() : p;
  165 + if(p === m.np) return true;
  166 + if(p[0] && m.np[0] && p[0] === m.np[0]) return true;
  167 + return false;
  168 + }
  169 + }
  170 + },
  171 + "dnd" : {
  172 + "drop_target" : false,
  173 + "drag_target" : false
  174 + },
  175 + "plugins" : [ "themes", "html_data", "crrm", "dnd" ]
  176 + });
  177 +});
  178 +</script>
  179 +
  180 +</div>
  181 +
  182 +<h2 id="api">API</h2>
  183 +<div class="panel api">
  184 +
  185 +<div style="height:1px; visibility:hidden;">
  186 + <span id="dnd_show">&nbsp;</span>
  187 + <span id="dnd_open">&nbsp;</span>
  188 + <span id="dnd_finish">&nbsp;</span>
  189 + <span id="dnd_enter">&nbsp;</span>
  190 + <span id="start_drag">&nbsp;</span>
  191 +</div>
  192 +<h3 id="dnd_prepare">.dnd_prepare ( ), .dnd_show ( ), .dnd_open ( ), .dnd_finish ( ), .dnd_enter ( ), .dnd_leave ( ), .start_drag ( )</h3>
  193 +<p>All those functions are used internally only. If you want more information - examine the source code.</p>
  194 +
  195 +</div>
  196 +
  197 +</div>
  198 +</body>
  199 +</html>
0 200 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/hotkeys.html 0 → 100644
... ... @@ -0,0 +1,82 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - hotkeys documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>hotkeys plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>hotkeys</code> plugin enables keyboard navigation and shortcuts. Depends on the <a href="http://github.com/jeresig/jquery.hotkeys/">jquery.hotkeys plugin</a>.</p>
  25 +</div>
  26 +
  27 +<h2 id="configuration">Configuration</h2>
  28 +<div class="panel configuration">
  29 +<p>Expects an object:<br />each key is the keyboard shortcut (for possible values check <a href="http://github.com/jeresig/jquery.hotkeys/">the hotkeys plugin</a>)<br />each value is a function executed in the instance's context, the return value is used as a return value for the event.</p>
  30 +<p>Simple example:</p>
  31 +<p><code>"del" : function () { this.remove(); }</code></p>
  32 +<p>By default <code>"up"</code>, <code>"ctrl+up"</code>, <code>"shift+up"</code>, <code>"down"</code>, <code>"ctrl+down"</code>, <code>"shift+down"</code>, <code>"left"</code>, <code>"ctrl+left"</code>, <code>"shift+left"</code>, <code>"right"</code>, <code>"ctrl+right"</code>, <code>"shift+right"</code>, <code>"space"</code>, <code>"ctrl+space"</code>, <code>"shift+space"</code>, <code>"f2"</code>, <code>"del"</code> are bound.<br />To override any of those - just specify your own function, to disable - just set to <code>false</code>.
  33 +</div>
  34 +
  35 +<h2 id="demos">Demos</h2>
  36 +<div class="panel">
  37 +
  38 +<h3>Using the hotkeys plugin</h3>
  39 +<p>Try pressing <code>up</code>/<code>down</code>/<code>left</code>/<code>right</code>/<code>space</code>/<code>f2</code>/<code>del</code>.</p>
  40 +<div id="demo1" class="demo">
  41 + <ul>
  42 + <li id="phtml_1">
  43 + <a href="#">Root node 1</a>
  44 + <ul>
  45 + <li id="phtml_2">
  46 + <a href="#">Child node 1</a>
  47 + </li>
  48 + <li id="phtml_3">
  49 + <a href="#">Child node 2</a>
  50 + </li>
  51 + </ul>
  52 + </li>
  53 + <li id="phtml_4">
  54 + <a href="#">Root node 2</a>
  55 + </li>
  56 + </ul>
  57 +</div>
  58 +<script type="text/javascript" class="source">
  59 +$(function () {
  60 + $("#demo1").jstree({
  61 + "core" : { "initially_open" : [ "phtml_1" ] },
  62 + "plugins" : ["themes","html_data","ui","crrm","hotkeys"]
  63 + });
  64 +});
  65 +</script>
  66 +
  67 +</div>
  68 +
  69 +<h2 id="api">API</h2>
  70 +<div class="panel api">
  71 +
  72 +<h3 id="enable_hotkeys">.enable_hotkeys ( )</h3>
  73 +<p>Enable shortcuts on the instance (enabled by default).</p>
  74 +
  75 +<h3 id="disable_hotkeys">.disable_hotkeys ( )</h3>
  76 +<p>Disable shortcuts on the instance.</p>
  77 +
  78 +</div>
  79 +
  80 +</div>
  81 +</body>
  82 +</html>
0 83 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/html_data.html 0 → 100644
... ... @@ -0,0 +1,175 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - html_data documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>html_data plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>html_data</code> plugin enables jsTree to convert nested unordered lists to interactive trees. jsTree can also get HTML from the server insert it into the DOM and convert that to a tree.</p>
  25 +<p>The basic structure you need to follow when supplying data in the HTML format is:</p>
  26 +<div class="code_f">
  27 +<pre class="brush:xml;">
  28 +&lt;li&gt;
  29 + &lt;a href="some_value_here"&gt;Node title&lt;/a&gt;
  30 + &lt;!-- UL node only needed for children - omit if there are no children --&gt;
  31 + &lt;ul&gt;
  32 + &lt;!-- Children LI nodes here --&gt;
  33 + &lt;/ul&gt;
  34 +&lt;/li&gt;
  35 +</pre>
  36 +</div>
  37 +<p>If you inspect the resulting structure you will find it a bit different - that is because jstree will automatically do some corrections.</p>
  38 +<div class="code_f">
  39 +<pre class="brush:xml;">
  40 +&lt;!-- one of the three classes will be applied depending on node structure --&gt;
  41 +&lt;li class="[ jstree-open | jstree-closed | jstree-leaf ]"&gt;
  42 + &lt;!-- an INS element is inserted --&gt;
  43 + &lt;ins class="jstree-icon"&gt;&amp;#160;&lt;/ins&gt;
  44 + &lt;a href="some_value_here"&gt;
  45 + &lt;!-- another INS element is inserted --&gt;
  46 + &lt;ins class="jstree-icon"&gt;&amp;#160;&lt;/ins&gt;
  47 + Node title
  48 + &lt;/a&gt;
  49 +&lt;/li&gt;
  50 +</pre>
  51 +</div>
  52 +<p>Both <code>ins</code> elements are inserted for visualization purposes. As for the class (<code>jstree-open</code>, <code>jstree-closed</code>) - you can specify that yourself to force the node to appear either closed or opened. Making a node with no children appear closed is often used - if you use ajax, opening a closed node with no children will result in jstree making a server call for the children (see the <a href="#demo3">demo below</a>).</p>
  53 +</div>
  54 +
  55 +<h2 id="configuration">Configuration</h2>
  56 +<div class="panel configuration">
  57 +<h3>data</h3>
  58 +<p class="meta">A HTML string (or <code>false</code> if not used). Default is <code>false</code>.</p>
  59 +<p>Specifies the content to load into the container and convert to a tree.</p>
  60 +<h3>ajax</h3>
  61 +<p class="meta">An object (or <code>false</code> if not used). Default is <code>false</code>.</p>
  62 +<p>The ajax config object is pretty much the same as the <a href="http://api.jquery.com/jQuery.ajax/">jQuery ajax settings object</a>.</p>
  63 +<p>You can set the <code>data</code> option to a function, that will be executed in the current tree's scope (<code>this</code> will be the tree instance) and gets the node about to be open as a paramater (or <code>-1</code> for initial load). Whatever you return in the function will be sent to the server as data (so for example you can send the node's ID).</p>
  64 +<p>You can set the <code>url</code> option to a function, that will be executed in the current tree's scope (<code>this</code> will be the tree instance) and gets the node about to be open as a paramater (or <code>-1</code> for initial load). Whatever you return in the <code>url</code> function will be used as the ajax URL (so that you can accomodate pretty paths such as /get_children/node_2).</p>
  65 +<p>The <code>error</code> and <code>success</code> functions (if present) also fire in the context of the tree, and if you return a value in the <code>success</code> function it will be used to populate the tree - this can be useful if you want to somehow change what the server returned on the client side before it is displayed in the tree.</p>
  66 +<h3>correct_state</h3>
  67 +<p class="meta">A Boolean. Default is <code>true</code>.</p>
  68 +<p>If this option is set to <code>true</code> if an AJAX request returns an empty result, the node that was about to be opened will be converted to a leaf node (the open icon will no longer be displayed).</p>
  69 +
  70 +<p class="note"><strong>NOTE:</strong><br />If both <code>data</code> and <code>ajax</code> are not set, the current container's HTML is used to build the tree.<br />If both <code>data</code> and <code>ajax</code> are set the initial tree is rendered from the <code>data</code> string. When opening a closed node (that has no loaded children) an AJAX request is made.</p>
  71 +</div>
  72 +
  73 +<h2 id="demos">Demos</h2>
  74 +<div class="panel">
  75 +
  76 +<h3>Using initial content (convert an existing list)</h3>
  77 +<div id="demo1" class="demo">
  78 + <ul>
  79 + <li id="phtml_1">
  80 + <a href="#">Root node 1</a>
  81 + <ul>
  82 + <li id="phtml_2">
  83 + <a href="#">Child node 1</a>
  84 + </li>
  85 + <li id="phtml_3">
  86 + <a href="#">Child node 2</a>
  87 + </li>
  88 + </ul>
  89 + </li>
  90 + <li id="phtml_4">
  91 + <a href="#">Root node 2</a>
  92 + </li>
  93 + </ul>
  94 +</div>
  95 +<script type="text/javascript" class="source">
  96 +$(function () {
  97 + $("#demo1").jstree({
  98 + "plugins" : [ "themes", "html_data" ]
  99 + });
  100 +});
  101 +</script>
  102 +
  103 +<h3>Using the data config option</h3>
  104 +<div id="demo2" class="demo"></div>
  105 +<script type="text/javascript" class="source">
  106 +$(function () {
  107 + $("#demo2").jstree({
  108 + "core" : { "initially_open" : [ "root" ] },
  109 + "html_data" : {
  110 + "data" : "<li id='root'><a href='#'>Root node</a><ul><li><a href='#'>Child node</a></li></ul></li>"
  111 + },
  112 + "plugins" : [ "themes", "html_data" ]
  113 + });
  114 +});
  115 +</script>
  116 +
  117 +<h3>Using the ajax config option</h3>
  118 +<div id="demo3" class="demo"></div>
  119 +<script type="text/javascript" class="source">
  120 +$(function () {
  121 + $("#demo3").jstree({
  122 + "html_data" : {
  123 + "ajax" : {
  124 + "url" : "_html_data.html",
  125 + "data" : function (n) {
  126 + return { id : n.attr ? n.attr("id") : 0 };
  127 + }
  128 + }
  129 + },
  130 + "plugins" : [ "themes", "html_data" ]
  131 + });
  132 +});
  133 +</script>
  134 +
  135 +<h3>Using both the data &amp; ajax config options</h3>
  136 +<div id="demo4" class="demo"></div>
  137 +<script type="text/javascript" class="source">
  138 +$(function () {
  139 + $("#demo4").jstree({
  140 + "core" : { "initially_open" : [ "root2" ] },
  141 + "html_data" : {
  142 + "data" : "<li class='jstree-closed' id='root2'><a href='#'>Root node</a></li>",
  143 + "ajax" : { "url" : "_html_data.html" }
  144 + },
  145 + "plugins" : [ "themes", "html_data" ]
  146 + });
  147 +});
  148 +</script>
  149 +</div>
  150 +
  151 +<h2 id="api">API</h2>
  152 +<div class="panel api">
  153 +<p>Both dummy functions - <code>_is_loaded</code> and <code>load_node</code> are overwritten.</p>
  154 +<h3 id="load_node_html">.load_node_html ( node , success_callback , error_callback )</h3>
  155 +<p>This function is called instead of <code>load_node</code>.</p>
  156 +<ul class="arguments">
  157 + <li>
  158 + <code class="tp">mixed</code> <strong>node</strong>
  159 + <p>This can be a DOM node, jQuery node or selector pointing to an element you want loaded. Use <code>-1</code> for root nodes.</p>
  160 + </li>
  161 + <li>
  162 + <code class="tp">function</code> <strong>success_callback</strong>
  163 + <p>A function to be executed once the node is loaded successfully - used internally. You should wait for the <code>load_node</code> event.</p>
  164 + </li>
  165 + <li>
  166 + <code class="tp">function</code> <strong>error_callback</strong>
  167 + <p>A function to be executed if the node is not loaded due to an error - used internally. You should wait for the <code>load_node</code> event.</p>
  168 + </li>
  169 +</ul>
  170 +
  171 +</div>
  172 +
  173 +</div>
  174 +</body>
  175 +</html>
0 176 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/index.html 0 → 100644
... ... @@ -0,0 +1,86 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 Documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree - jquery tree plugin</h1>
  21 +
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +
  25 +<h3>jsTree:</h3>
  26 +<ul class="jstree">
  27 + <li>&#9830;&#160;&#160;is a <strong>javascript based, cross browser tree component</strong>. It is packaged as a <a href="http://jquery.com">jQuery</a> plugin.</li>
  28 + <li>&#9830;&#160;&#160;<strong>is absolutely free</strong> (licensed same as jQuery – under the terms of either the MIT License or the GPL v2 License).</li>
  29 + <li>&#9830;&#160;&#160;is a <a href="http://vakata.com/">one man</a> project and relies on <a href="http://groups.google.com/group/jstree">its great community</a> for <a href="http://code.google.com/p/jstree/issues/list">feature requests &amp; bug reports</a>. Join in!</li>
  30 + <li>&#9830;&#160;&#160;passes <a href="http://jslint.com">jslint validation</a>, minifies nicely and does not modify the global scope in any way.</li>
  31 + <li>&#9830;&#160;&#160;uses plugins so feel free to remove any plugins you do not use (for an even smaller download) or create your own plugins.</li>
  32 +</ul>
  33 +
  34 +<h3>Features at a glance</h3>
  35 +<ul class="columns">
  36 + <li>Various data sources - HTML, JSON, XML</li>
  37 + <li>Supports AJAX loading</li>
  38 + <li>Drag &amp; drop support</li>
  39 + <li>Highly configurable</li>
  40 + <li>Theme support + included themes</li>
  41 + <li>Uses jQuery's event system</li>
  42 + <li>Optional keyboard navigation</li>
  43 + <li>Maintain the same tree in many languages</li>
  44 + <li>Inline editing</li>
  45 + <li>Open/close optional animation</li>
  46 + <li>Define node types and fine tune them</li>
  47 + <li>Configurable multitree drag &amp; drop</li>
  48 + <li>Optional checkbox tree support</li>
  49 + <li>Search function</li>
  50 + <li>Supports plugins</li>
  51 + <li>Optional state saving using cookies</li>
  52 + <li>RTL support</li>
  53 + <li>Optional sorting / unique management</li>
  54 +</ul>
  55 +<p style="color:gray; font-size:0.8em; text-align:center; padding:15px;">if you like the project - consider <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=paypal@vakata.com&amp;currency_code=USD&amp;amount=&amp;return=http://jstree.com/donation&amp;item_name=Buy+me+a+coffee+for+jsTree">supporting jstree</a>.</p>
  56 +</div>
  57 +
  58 +<h2 id="plugins">Plugins documentation</h2>
  59 +<div class="panel">
  60 +<p>As of version 1.0 jsTree is extremely plugin friendly, so all functionality is now wrapped in plugins, which take care of various aspects of the tree and can be removed without affecting the functionality of other plugins. Below you will find a list of plugins - each with its own documentation page. Probably a good place to start is the <a href="core.html">core</a>.</p>
  61 +<ul class="columns plugins">
  62 + <li style="float:none; width:660px;"><a href="core.html" style="font-weight:bold;">Core functionality</a><p>all core functions for manipulating the tree + basic examples of including, configuring and working with the tree, along with demos of the new event system</p></li>
  63 + <li><a href="html_data.html">HTML_DATA plugin</a><p>enables jsTree to convert nested unordered lists to interactive trees, an already existing UL may be used or data could be retrieved from a server</p></li>
  64 + <li><a href="json_data.html">JSON_DATA plugin</a><p>enables jsTree to convert JSON objects to interactive trees, data can be set up in the config or retrieved from a server</p></li>
  65 + <li><a href="xml_data.html">XML_DATA plugin</a><p>enables jsTree to convert XML objects to interactive trees (using XSL), data can be set up in the config or retrieved from a server</p></li>
  66 + <li><a href="themes.html">Themes plugin</a><p>controls the looks of jstree - without this plugin you will get a functional tree, but it will look just like an ordinary UL list</p></li>
  67 + <li><a href="ui.html">UI plugin</a><p>handles selecting, deselecting and hovering tree items</p></li>
  68 + <li><a href="crrm.html">CRRM plugin</a><p>handles creating, renaming, removing and moving nodes by the user, also includes cut/copy/paste functions</p></li>
  69 + <li><a href="hotkeys.html">Hotkeys plugin</a><p>enables support for keyboard navigation &amp; shortcuts, highly configurable</p></li>
  70 + <li><a href="languages.html">Languages plugin</a><p>enables multilanguage support - each node can have multiple titles, but only one is visible</p></li>
  71 + <li><a href="cookies.html">Cookies plugin</a><p>enables jstree to save the state of the tree across sessions, by saving selected and opened nodes in a cookie</p></li>
  72 + <li><a href="sort.html">Sort plugin</a><p>enables jstree to automatically sort all nodes<br />using a specified function</p></li>
  73 + <li><a href="dnd.html">DND plugin</a><p>enables drag'n'drop support for jstree, also using foreign nodes and drop targets</p></li>
  74 + <li><a href="checkbox.html">Checkbox plugin</a><p>makes multiselection possible using three-state checkboxes</p></li>
  75 + <li><a href="search.html">Search plugin</a><p>enables searching for nodes whose title contains a given string, works on async trees too</p></li>
  76 + <li><a href="contextmenu.html">Contextmenu plugin</a><p>enables a multilevel context menu on tree items</p></li>
  77 + <li><a href="types.html">Types plugin</a><p>each node can have a type, and you can define rules on how that type should behave</p></li>
  78 + <li><a href="themeroller.html">Themeroller plugin</a><p>adds support for jQuery UI's themes</p></li>
  79 + <li><a href="unique.html">Unique plugin</a><p>adds unique checking to jsTree</p></li>
  80 + <li><a href="#" onclick="return false" style="color:black;text-decoration:none;">Wholerow plugin</a><p>enhances UIs select &amp; hover functions</p></li>
  81 +</ul>
  82 +</div>
  83 +
  84 +</div>
  85 +</body>
  86 +</html>
0 87 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/json_data.html 0 → 100644
... ... @@ -0,0 +1,249 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - json_data documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>json_data plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>json_data</code> plugin enables jsTree to convert JSON objects to interactive trees. The data (JSON) can be set up in the config or retrieved from a server (also ondemand). Version 1.0 also introduces the experimental progressive render feature, which is suitable for large heavy trees, when the DOM would be too heavy to manipulate.</p>
  25 +<p>The basic structure you need to follow when supplying data in the JSON format is:</p>
  26 +<div class="code_f">
  27 +<pre class="brush:js;">
  28 +{
  29 + "data" : "node_title",
  30 + // omit `attr` if not needed; the `attr` object gets passed to the jQuery `attr` function
  31 + "attr" : { "id" : "node_identificator", "some-other-attribute" : "attribute_value" },
  32 + // `state` and `children` are only used for NON-leaf nodes
  33 + "state" : "closed", // or "open", defaults to "closed"
  34 + "children" : [ /* an array of child nodes objects */ ]
  35 +}
  36 +</pre>
  37 +</div>
  38 +<p>The attr object will appear as attributes on the resulting <code>li</code> node.</p>
  39 +<p>You may need to pass some attributes to the <code>a</code> node, or set some metadata, or use language versions (for the <a href="languages.html">languages plugin</a>):</p>
  40 +<div class="code_f">
  41 +<pre class="brush:js;">
  42 +{
  43 + // `data` can also be an object
  44 + "data" : {
  45 + "title" : "The node title",
  46 + // omit when not needed
  47 + "attr" : {},
  48 + // if `icon` contains a slash / it is treated as a file, used for background
  49 + // otherwise - it is added as a class to the &lt;ins&gt; node
  50 + "icon" : "folder"
  51 + },
  52 +
  53 + // the `metadata` property will be saved using the jQuery `data` function on the `li` node
  54 + "metadata" : "a string, array, object, etc",
  55 +
  56 + // if you use the language plugin - just set this property
  57 + // also make sure that `data` is an array of objects
  58 + "language" : "en" // any code you are using
  59 +}
  60 +</pre>
  61 +</div>
  62 +<p>As seen in the first example below - you can also use a simple string to define a node (Child 1 &amp; Child 2).</p>
  63 +</div>
  64 +
  65 +<h2 id="configuration">Configuration</h2>
  66 +<div class="panel configuration">
  67 +<h3>data</h3>
  68 +<p class="meta">A JSON object (or <code>false</code> if not used). Default is <code>false</code>.</p>
  69 +<p>Specifies the content to load into the container and convert to a tree. You can also set this to a function - it will be executed in the tree's scope for every node that needs to be loaded, the function will receive two arguments - the node being loaded &amp; a function to call with the data once your processing is done.</p>
  70 +<h3>ajax</h3>
  71 +<p class="meta">An object (or <code>false</code> if not used). Default is <code>false</code>.</p>
  72 +<p>The ajax config object is pretty much the same as the <a href="http://api.jquery.com/jQuery.ajax/">jQuery ajax settings object</a>.</p>
  73 +<p>You can set the <code>data</code> option to a function, that will be executed in the current tree's scope (<code>this</code> will be the tree instance) and gets the node about to be open as a paramater (or <code>-1</code> for initial load). Whatever you return in the <code>data</code> function will be sent to the server as data (so for example you can send the node's ID).</p>
  74 +<p>You can set the <code>url</code> option to a function, that will be executed in the current tree's scope (<code>this</code> will be the tree instance) and gets the node about to be open as a paramater (or <code>-1</code> for initial load). Whatever you return in the <code>url</code> function will be used as the ajax URL (so that you can accomodate pretty paths such as /get_children/node_2).</p>
  75 +<p>The <code>error</code> and <code>success</code> functions (if present) also fire in the context of the tree, and if you return a value in the <code>success</code> function it will be used to populate the tree - this can be useful if you want to somehow change what the server returned on the client side before it is displayed in the tree (for example some .NET json implementations require this to work: <code>"success" : function (data) { return data.d; }</code>.</p>
  76 +<h3>correct_state</h3>
  77 +<p class="meta">A Boolean. Default is <code>true</code>.</p>
  78 +<p>If this option is set to <code>true</code> if an AJAX returns an empty result, the node that was about to be opened will be converted to a leaf node (the open icon will no longer be displayed).</p>
  79 +<h3>progressive_render</h3>
  80 +<p class="meta">A Boolean. Default is <code>false</code>.</p>
  81 +<p>If this option is set to <code>true</code> only the visible (open nodes) parts of the returned JSON are converted to DOM nodes, any hidden parts are saved away and parsed ondemand (when a node becomes visible). This is useful when you have a large nested tree which would result in a heavy DOM.</p>
  82 +<h3>progressive_unload</h3>
  83 +<p class="meta">A Boolean. Default is <code>false</code>.</p>
  84 +<p>If this option is set to <code>true</code> when a node is closed its children are removed from the DOM and saved as metadata on the node itself, on reopen that metadata is used (much like <code>progressive_render</code>).</p>
  85 +
  86 +<p class="note"><strong>NOTE:</strong><br />If both <code>data</code> and <code>ajax</code> are set the initial tree is rendered from the <code>data</code> string. When opening a closed node (that has no loaded children) an AJAX request is made.</p>
  87 +</div>
  88 +
  89 +<h2 id="demos">Demos</h2>
  90 +<div class="panel">
  91 +
  92 +<h3>Using the data config option</h3>
  93 +<div id="demo1" class="demo"></div>
  94 +<script type="text/javascript" class="source">
  95 +$(function () {
  96 + $("#demo1").jstree({
  97 + "json_data" : {
  98 + "data" : [
  99 + {
  100 + "data" : "A node",
  101 + "metadata" : { id : 23 },
  102 + "children" : [ "Child 1", "A Child 2" ]
  103 + },
  104 + {
  105 + "attr" : { "id" : "li.node.id1" },
  106 + "data" : {
  107 + "title" : "Long format demo",
  108 + "attr" : { "href" : "#" }
  109 + }
  110 + }
  111 + ]
  112 + },
  113 + "plugins" : [ "themes", "json_data", "ui" ]
  114 + }).bind("select_node.jstree", function (e, data) { alert(jQuery.data(data.rslt.obj[0], "id")); });
  115 +});
  116 +</script>
  117 +
  118 +<h3>Using the ajax config option</h3>
  119 +<div id="demo2" class="demo"></div>
  120 +<script type="text/javascript" class="source">
  121 +$(function () {
  122 + $("#demo2").jstree({
  123 + "json_data" : {
  124 + "ajax" : {
  125 + "url" : "_json_data.json",
  126 + "data" : function (n) {
  127 + return { id : n.attr ? n.attr("id") : 0 };
  128 + }
  129 + }
  130 + },
  131 + "plugins" : [ "themes", "json_data" ]
  132 + });
  133 +});
  134 +</script>
  135 +
  136 +<h3>Using the progressive render config option</h3>
  137 +<div id="demo3" class="demo"></div>
  138 +<script type="text/javascript" class="source">
  139 +$(function () {
  140 + $("#demo3").jstree({
  141 + "json_data" : {
  142 + "data" : [
  143 + {
  144 + "data" : "A node",
  145 + "children" : [ "Child 1", "Child 2" ]
  146 + },
  147 + {
  148 + "attr" : { "id" : "li.node.id2" },
  149 + "data" : {
  150 + "title" : "Long format demo",
  151 + "attr" : { "href" : "#" }
  152 + }
  153 + }
  154 + ],
  155 + "progressive_render" : true
  156 + },
  157 + "plugins" : [ "themes", "json_data" ]
  158 + });
  159 +});
  160 +</script>
  161 +
  162 +<h3>Using both the data &amp; ajax config options</h3>
  163 +<div id="demo4" class="demo"></div>
  164 +<script type="text/javascript" class="source">
  165 +$(function () {
  166 + $("#demo4").jstree({
  167 + "json_data" : {
  168 + "data" : [
  169 + {
  170 + "data" : "A node",
  171 + "state" : "closed"
  172 + },
  173 + {
  174 + "attr" : { "id" : "li.node.id3" },
  175 + "data" : {
  176 + "title" : "Long format demo",
  177 + "attr" : { "href" : "#" }
  178 + }
  179 + }
  180 + ],
  181 + "ajax" : { "url" : "_json_data.json" }
  182 + },
  183 + "plugins" : [ "themes", "json_data" ]
  184 + });
  185 +});
  186 +</script>
  187 +</div>
  188 +
  189 +<h2 id="api">API</h2>
  190 +<div class="panel api">
  191 +<p>Both dummy functions - <code>_is_loaded</code> and <code>load_node</code> are overwritten.</p>
  192 +<h3 id="load_node_json">.load_node_json ( node , success_callback , error_callback )</h3>
  193 +<p>This function is called instead of <code>load_node</code>.</p>
  194 +<ul class="arguments">
  195 + <li>
  196 + <code class="tp">mixed</code> <strong>node</strong>
  197 + <p>This can be a DOM node, jQuery node or selector pointing to an element you want loaded. Use <code>-1</code> for root nodes.</p>
  198 + </li>
  199 + <li>
  200 + <code class="tp">function</code> <strong>success_callback</strong>
  201 + <p>A function to be executed once the node is loaded successfully - used internally. You should wait for the <code>load_node</code> event.</p>
  202 + </li>
  203 + <li>
  204 + <code class="tp">function</code> <strong>error_callback</strong>
  205 + <p>A function to be executed if the node is not loaded due to an error - used internally. You should wait for the <code>load_node</code> event.</p>
  206 + </li>
  207 +</ul>
  208 +<h3 id="_parse_json">._parse_json ( data , node , is_callback )</h3>
  209 +<p>This function converts JSON nodes to the DOM structure required by jstree. Returns a jQuery object.</p>
  210 +<ul class="arguments">
  211 + <li>
  212 + <code class="tp">mixed</code> <strong>node</strong>
  213 + <p>This can be a tree node in the JSON format described above, or an array of such JSON nodes, may also be a string.</p>
  214 + </li>
  215 + <li>
  216 + <code class="tp">mixed</code> <strong>node</strong>
  217 + <p>This is the DOM node, jQuery node or selector pointing to the element for which data is parsed. <code>-1</code> means root nodes.</p>
  218 + </li>
  219 + <li>
  220 + <code class="tp">bool</code> <strong>is_callback</strong>
  221 + <p>Specifies if the function is called recursively - used ONLY internally.</p>
  222 + </li>
  223 +</ul>
  224 +<h3 id="get_json">.get_json ( node , li_attr , a_attr )</h3>
  225 +<p>This function returns an array of tree nodes converted back to JSON.</p>
  226 +<ul class="arguments">
  227 + <li>
  228 + <code class="tp">mixed</code> <strong>node</strong>
  229 + <p>This can be a DOM node, jQuery node or selector pointing to an element you want returned. Use <code>-1</code> or omit to get the whole tree.</p>
  230 + </li>
  231 + <li>
  232 + <code class="tp">array</code> <strong>li_attr</strong>
  233 + <p>The attributes to collect from the <code>LI</code> node. Defaults to <code>[ "id" , "class" ]</p>
  234 + </li>
  235 + <li>
  236 + <code class="tp">array</code> <strong>a_attr</strong>
  237 + <p>The attributes to collect from the <code>A</code> node. Defaults to <code>[ ]</p>
  238 + </li>
  239 + <li>
  240 + <code class="tp">boolean</code> <strong>is_callback</strong>
  241 + <p>Used internally.</p>
  242 + </li>
  243 +</ul>
  244 +
  245 +</div>
  246 +
  247 +</div>
  248 +</body>
  249 +</html>
0 250 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/languages.html 0 → 100644
... ... @@ -0,0 +1,152 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - languages documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>languages plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>languages</code> plugin enables multilanguage trees. This means that each node has a specified number of titles - each in a different "language". Only one language set is visible at any given time. This is useful for maintaining the same structure in many languages (hence the name of the plugin)</p>
  25 +</div>
  26 +
  27 +<h2 id="configuration">Configuration</h2>
  28 +<div class="panel configuration">
  29 +<p>Expects an array of language codes. Each of the items is used as a CSS class name, so make sure you specify only valid CSS class name strings. The first langauge will be visible onload. For example:</p>
  30 +<p><code>[ "en", "de", "bg" ]</code></p>
  31 +</div>
  32 +
  33 +<h2 id="demos">Demos</h2>
  34 +<div class="panel">
  35 +<p>Check your data plugin documentation (<a href="html_data.html">html_data</a>, <a href="xml_data.html">xml_data</a>, <a href="json_data.html">json_data</a>) or take a close look at these examples for information on how to specify multilanguage nodes.</p>
  36 +
  37 +<h3>Using the languages plugin with HTML data</h3>
  38 +<input type="button" class="button" value="en" id="en_1" style="float:left;" />
  39 +<input type="button" class="button" value="bg" id="bg_1" style="float:left;" />
  40 +<input type="button" class="button" value="rename_1" id="rename_1" style="float:left;" />
  41 +<input type="button" class="button" value="rename_2" id="rename_2" style="" />
  42 +<div id="demo1" class="demo">
  43 + <ul>
  44 + <li id="phtml_1">
  45 + <a href="#" class="en">Root node 1</a>
  46 + <a href="#" class="bg">Корен 1</a>
  47 + <ul>
  48 + <li id="phtml_2">
  49 + <a href="#" class="en">Child node 1</a>
  50 + <a href="#" class="bg">Дете 1</a>
  51 + </li>
  52 + <li id="phtml_3">
  53 + <a href="#" class="en">Child node 2</a>
  54 + <a href="#" class="bg">Дете 2</a>
  55 + </li>
  56 + </ul>
  57 + </li>
  58 + <li id="phtml_4">
  59 + <a href="#" class="en">Root node 2</a>
  60 + <a href="#" class="bg">Корен 2</a>
  61 + </li>
  62 + </ul>
  63 +</div>
  64 +<script type="text/javascript" class="source">
  65 +$(function () {
  66 + $("#en_1, #bg_1").click(function () {
  67 + $("#demo1").jstree("set_lang", this.value);
  68 + });
  69 + $("#rename_1").click(function () {
  70 + $("#demo1").jstree("rename_node", "#phtml_1", "Rename visible lang");
  71 + });
  72 + $("#rename_2").click(function () {
  73 + $("#demo1").jstree("rename_node", "#phtml_1", "Rename `bg`", "bg");
  74 + });
  75 + $("#demo1").jstree({
  76 + "languages" : [ "en", "bg" ],
  77 + "plugins" : [ "themes", "html_data", "languages","checkbox"]
  78 + });
  79 +});
  80 +</script>
  81 +
  82 +</div>
  83 +
  84 +<h2 id="api">API</h2>
  85 +<div class="panel api">
  86 +
  87 +<h3 id="set_lang">.set_lang ( lang )</h3>
  88 +<p>Set the tree's visible language. Triggers an event.</p>
  89 +<ul class="arguments">
  90 + <li>
  91 + <code class="tp">string <br />number</code> <strong>lang</strong>
  92 + <p>Either the language code string (as specified in the config) or an index from the config array.</p>
  93 + </li>
  94 +</ul>
  95 +<h3 id="get_lang">.get_lang ( )</h3>
  96 +<p>Returns the name of the currently visible language.</p>
  97 +
  98 +<h3 id="_get_string">._get_string ( node , lang )</h3>
  99 +<p>Returns the needed string from the core config object. Overwrites the <a href="core.html#_get_string">get_string function</a> from the core. If the key does not exist in that language, but exists in the root of the object - that is returned, if even that does not exist - the key itself is returned.</p>
  100 +<ul class="arguments">
  101 + <li>
  102 + <code class="tp">string</code> <strong>key</strong>
  103 + <p>The name of the string you are looking for. If you want to use the localize option just set the strings core config option to an object like this one: <code>strings : { "lang-code-here" : { "string-key" : "string-value" ... }, "other-lang" : { ... } }</code>, otherwise _get_strings won't be affected.</p>
  104 + </li>
  105 + <li>
  106 + <code class="tp">string</code> <strong>lang</strong>
  107 + <p>The language code string (as specified in the config) to get the key in. If not specified the currently visible language is used.</p>
  108 + </li>
  109 +</ul>
  110 +
  111 +<h3 id="get_text">.get_text ( node , lang )</h3>
  112 +<p>Returns the title of a node. Overwrites the <a href="core.html#get_text">get_text function</a> from the core.</p>
  113 +<ul class="arguments">
  114 + <li>
  115 + <code class="tp">mixed</code> <strong>node</strong>
  116 + <p>This can be a DOM node, jQuery node or selector pointing to the element whose title you need.</p>
  117 + </li>
  118 + <li>
  119 + <code class="tp">string</code> <strong>lang</strong>
  120 + <p>The language code string (as specified in the config) to get the title in. If you omit this - the currently visible language is used.</p>
  121 + </li>
  122 +</ul>
  123 +
  124 +<h3 id="set_text">.set_text ( node , text , lang )</h3>
  125 +<p>Sets the title of a node. Overwrites the <a href="core.html#set_text">set_text function</a> from the core. This is used internally - you should use <a href="core.html#rename_node">rename_node</a>. Since <code>rename_node</code> uses <code>set_text</code> internally you can pass a language string as a third parameter to rename_node.</p>
  126 +<ul class="arguments">
  127 + <li>
  128 + <code class="tp">mixed</code> <strong>node</strong>
  129 + <p>This can be a DOM node, jQuery node or selector pointing to the element whose title you want to change.</p>
  130 + </li>
  131 + <li>
  132 + <code class="tp">string</code> <strong>text</strong>
  133 + <p>The new title.</p>
  134 + </li>
  135 + <li>
  136 + <code class="tp">string</code> <strong>lang</strong>
  137 + <p>The language code string (as specified in the config) to get the title in. If you omit this - the currently visible language is used.</p>
  138 + </li>
  139 +</ul>
  140 +
  141 +<h3 id="_load_css">._load_css ( )</h3>
  142 +<p>used only internally to include the CSS necessary for the plugin onload.</p>
  143 +
  144 +<h3 id="create_node">.create_node ( obj , position , js , callback )</h3>
  145 +<p>Overwrites the <a href="core.html#create_node">create_node</a> function from the core. To create a node with a few titles use an array for the <code>data</code> property of the <code>js</code> parameter:</p>
  146 +<p><code>{ "data" : [ { "title" : "EN title", language : "en" }, { "title" : "BG заглавие", language : "bg" } ] }</code></p>
  147 +
  148 +</div>
  149 +
  150 +</div>
  151 +</body>
  152 +</html>
0 153 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/logo.png 0 → 100644

6.07 KB

plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/search.html 0 → 100644
... ... @@ -0,0 +1,153 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - Search documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>search plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>search</code> plugin enables searching for nodes whose title contains a given string, works on async trees too. All found nodes get the <code>jstree-search</code> class applied to their contained <code>a</code> nodes - you can use that class to style search results.</p>
  25 +</div>
  26 +
  27 +<h2 id="configuration">Configuration</h2>
  28 +<div class="panel configuration">
  29 +
  30 +<h3>search_method</h3>
  31 +<p class="meta">A string. Default is <code>"contains"</code>.</p>
  32 +<p>The method to use for searching. The other options bundled with jstree are <code>"jstree_contains"</code> (case insensitive search) and <code>"jstree_title_contains"</code> (case insensitive based on the title tag of the A node). For multiple word search take a look this: <a href="https://github.com/vakata/jstree/issues/10">https://github.com/vakata/jstree/issues/10</a> - you can easily write your own method too.</p>
  33 +
  34 +<h3>show_only_matches</h3>
  35 +<p class="meta">A boolean. Default is <code>false</code>.</p>
  36 +<p>If set to <code>true</code> all non-matching nodes are hidden and only the matching nodes (and their parents) are left visible, until the search is cleared. Keep in mind <code>show_only_matches</code> is heavy on the browser/DOM and is still experimental.</p>
  37 +
  38 +<h3>ajax</h3>
  39 +<p class="meta">An object (or <code>false</code> if not used). Default is <code>false</code>.</p>
  40 +<p>This object can be used to make a request to the server on each search - useful if you are using async trees. That way you can return an array of IDs that need to be loaded before the actual DOM search is performed (so that all the nodes that will match the search are loaded). For example if the user searches for "string", you get that on the server side, check the database and find out that there is a node containing that string. But the node is the child of some other node, etc - so in your response you must return the path to the node (without the node itself) as ids: <code>["#root_node","#child_node_3"]</code>. This means that jstree will load those two nodes before doing the client side search, ensuring that your node will be visible.</p>
  41 +<p>The ajax config object is pretty much the same as the <a href="http://api.jquery.com/jQuery.ajax/">jQuery ajax settings object</a>.</p>
  42 +<p>You can set the <code>data</code> option to a function, that will be executed in the current tree's scope (<code>this</code> will be the tree instance) and gets the search string as a paramater. Whatever you return in the function will be sent to the server as data.</p>
  43 +<p>You can set the <code>url</code> option to a function, that will be executed in the current tree's scope (<code>this</code> will be the tree instance) and gets the search string as a paramater. Whatever you return in the function will be used as the URL of the ajax request.</p>
  44 +<p>The <code>error</code> and <code>success</code> functions (if present) also fire in the context of the tree, and if you return a value in the <code>success</code> function it will be used as the array of IDs.</p>
  45 +
  46 +</div>
  47 +
  48 +<h2 id="demos">Demos</h2>
  49 +<div class="panel">
  50 +
  51 +<h3>Searching nodes</h3>
  52 +<p>Do not open the node - instead - just press the button.</p>
  53 +<input type="button" class="button" value="Search" id="search" style="" />
  54 +<div id="demo1" class="demo"></div>
  55 +<script type="text/javascript" class="source">
  56 +$(function () {
  57 + $("#search").click(function () {
  58 + $("#demo1").jstree("search","TARGEt");
  59 + });
  60 + $("#demo1")
  61 + .jstree({
  62 + "json_data" : {
  63 + "data" : [
  64 + {
  65 + "attr" : { "id" : "root_node" },
  66 + "data" : "A closed node",
  67 + "state" : "closed"
  68 + }
  69 + ],
  70 + "ajax" : {
  71 + "url" : "_search_data.json",
  72 + "data" : function (n) {
  73 + return { id : n.attr ? n.attr("id") : 0 };
  74 + }
  75 + }
  76 + },
  77 + "search" : {
  78 + "case_insensitive" : true,
  79 + "ajax" : {
  80 + "url" : "_search_result.json"
  81 + }
  82 + },
  83 + "plugins" : [ "themes", "json_data", "search" ]
  84 + })
  85 + .bind("search.jstree", function (e, data) {
  86 + alert("Found " + data.rslt.nodes.length + " nodes matching '" + data.rslt.str + "'.");
  87 + });
  88 +});
  89 +</script>
  90 +
  91 +<h3>Using adv_search</h3>
  92 +<p>Try pressing the buttons. It will also work with AJAX searching.</p>
  93 +<input type="button" class="button" value="search for ADV_SEARCH" id="search1" rel="ADV_SEARCH" style="float:left;" />
  94 +<input type="button" class="button" value="search for Root" id="search2" rel="Root" style="float:left;" />
  95 +<input type="button" class="button" value="search for Child" id="search3" rel="Child" style="float:left;" />
  96 +<input type="button" class="button" value="Clear search" id="clear" style="" />
  97 +<div id="demo2" class="demo">
  98 +<ul>
  99 + <li class="jstree-open"><a href="#">Root node 1</a>
  100 + <ul>
  101 + <li><a href="#">Child node 1</a></li>
  102 + <li><a href="#">Child node 2</a></li>
  103 + <li><a href="#">ADV_SEARCH</a></li>
  104 + <li><a href="#">Child node 4</a></li>
  105 + </ul>
  106 + </li>
  107 + <li><a href="#">Root node 2</a>
  108 +</ul>
  109 +</div>
  110 +<script type="text/javascript" class="source">
  111 +$(function () {
  112 + $("#search1, #search2, #search3").click(function () {
  113 + $("#demo2").jstree("search", $(this).attr("rel"));
  114 + });
  115 + $("#clear").click(function () {
  116 + $("#demo2").jstree("clear_search");
  117 + });
  118 + $("#demo2")
  119 + .jstree({
  120 + "plugins" : [ "themes", "html_data", "search", "adv_search" ]
  121 + });
  122 +});
  123 +</script>
  124 +
  125 +</div>
  126 +
  127 +<h2 id="api">API</h2>
  128 +<div class="panel api">
  129 +
  130 +<h3 id="search">.search ( str , skip_async )</h3>
  131 +<p>Searches for nodes matching the supplied string. Triggers an event.</p>
  132 +<ul class="arguments">
  133 + <li>
  134 + <code class="tp">string</code> <strong>str</strong>
  135 + <p>The string to search for.</p>
  136 + </li>
  137 + <li>
  138 + <code class="tp">boolean</code> <strong>skip_async</strong>
  139 + <p>If set to <code>true</code> - skip the async search (if setup in the config). This is used mostly internally.</p>
  140 + </li>
  141 +</ul>
  142 +
  143 +<h3 id="clear_search">.clear_search ( )</h3>
  144 +<p>Clears the current search. This function is automatically called when doing a new search. Triggers an event.</p>
  145 +
  146 +<h3 id="_search_open">._search_open ( is_callback )</h3>
  147 +<p>Used internally if async is setup in the config. This functions loads the nodes returned by the server one by one.</p>
  148 +
  149 +</div>
  150 +
  151 +</div>
  152 +</body>
  153 +</html>
0 154 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/sort.html 0 → 100644
... ... @@ -0,0 +1,85 @@
  1 +<!DOCTYPE html
  2 +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3 +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7 + <title>jsTree v.1.0 - sort documentation</title>
  8 + <script type="text/javascript" src="../_lib/jquery.js"></script>
  9 + <script type="text/javascript" src="../_lib/jquery.cookie.js"></script>
  10 + <script type="text/javascript" src="../_lib/jquery.hotkeys.js"></script>
  11 + <script type="text/javascript" src="../jquery.jstree.js"></script>
  12 +
  13 + <link type="text/css" rel="stylesheet" href="syntax/!style.css"/>
  14 + <link type="text/css" rel="stylesheet" href="!style.css"/>
  15 + <script type="text/javascript" src="syntax/!script.js"></script>
  16 +</head>
  17 +<body>
  18 +<div id="container">
  19 +
  20 +<h1 id="dhead">jsTree v.1.0</h1>
  21 +<h1>sort plugin</h1>
  22 +<h2>Description</h2>
  23 +<div id="description">
  24 +<p>The <code>sort</code> enables jstree to automatically sort all nodes using a specified function. This means that when the user creates, renames or moves nodes around - they will automatically sort.</p>
  25 +</div>
  26 +
  27 +<h2 id="configuration">Configuration</h2>
  28 +<div class="panel configuration">
  29 +
  30 +<p>Expects a function. The functions receives two arguments - two nodes to be compared. Return <code>-1</code> or <code>1</code> (or any other different from -1). Default is: </p>
  31 +<p><code>function (a, b) { return this.get_text(a) > this.get_text(b) ? 1 : -1; }</code></p>
  32 +
  33 +</div>
  34 +
  35 +<h2 id="demos">Demos</h2>
  36 +<div class="panel">
  37 +<h3>Using the sort plugin</h3>
  38 +<input type="button" class="button" value="rename" id="rename" style="" />
  39 +<div id="demo1" class="demo">
  40 + <ul>
  41 + <li id="phtml_1">
  42 + <a href="#">Root node 1</a>
  43 + <ul>
  44 + <li id="phtml_2">
  45 + <a href="#">Child node 1</a>
  46 + </li>
  47 + <li id="phtml_3">
  48 + <a href="#">Child node 2</a>
  49 + </li>
  50 + </ul>
  51 + </li>
  52 + <li id="phtml_4">
  53 + <a href="#">Root node 2</a>
  54 + </li>
  55 + </ul>
  56 +</div>
  57 +<script type="text/javascript" class="source">
  58 +$(function () {
  59 + $("#rename").click(function () {
  60 + $("#demo1").jstree("rename");
  61 + });
  62 + $("#demo1").jstree({
  63 + "plugins" : [ "themes", "html_data", "ui", "crrm", "sort" ]
  64 + });
  65 +});
  66 +</script>
  67 +
  68 +</div>
  69 +
  70 +<h2 id="api">API</h2>
  71 +<div class="panel api">
  72 +
  73 +<h3 id="sort">.sort ( node )</h3>
  74 +<p>Sorts the children of the specified node - this function is called automatically.</p>
  75 +<ul class="arguments">
  76 + <li>
  77 + <code class="tp">mixed</code> <strong>node</strong>
  78 + <p>This can be a DOM node, jQuery node or selector pointing to the element.</p>
  79 + </li>
  80 +</ul>
  81 +</div>
  82 +
  83 +</div>
  84 +</body>
  85 +</html>
0 86 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/syntax/!script.js 0 → 100644
... ... @@ -0,0 +1,2232 @@
  1 +/**
  2 + * SyntaxHighlighter
  3 + * http://alexgorbatchev.com/
  4 + *
  5 + * SyntaxHighlighter is donationware. If you are using it, please donate.
  6 + * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
  7 + *
  8 + * @version
  9 + * 2.1.364 (October 15 2009)
  10 + *
  11 + * @copyright
  12 + * Copyright (C) 2004-2009 Alex Gorbatchev.
  13 + *
  14 + * @license
  15 + * This file is part of SyntaxHighlighter.
  16 + *
  17 + * SyntaxHighlighter is free software: you can redistribute it and/or modify
  18 + * it under the terms of the GNU Lesser General Public License as published by
  19 + * the Free Software Foundation, either version 3 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * SyntaxHighlighter is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with SyntaxHighlighter. If not, see <http://www.gnu.org/copyleft/lesser.html>.
  29 + */
  30 +//
  31 +// Begin anonymous function. This is used to contain local scope variables without polutting global scope.
  32 +//
  33 +if (!window.SyntaxHighlighter) var SyntaxHighlighter = function() {
  34 +
  35 +// Shortcut object which will be assigned to the SyntaxHighlighter variable.
  36 +// This is a shorthand for local reference in order to avoid long namespace
  37 +// references to SyntaxHighlighter.whatever...
  38 +var sh = {
  39 + defaults : {
  40 + /** Additional CSS class names to be added to highlighter elements. */
  41 + 'class-name' : '',
  42 +
  43 + /** First line number. */
  44 + 'first-line' : 1,
  45 +
  46 + /**
  47 + * Pads line numbers. Possible values are:
  48 + *
  49 + * false - don't pad line numbers.
  50 + * true - automaticaly pad numbers with minimum required number of leading zeroes.
  51 + * [int] - length up to which pad line numbers.
  52 + */
  53 + 'pad-line-numbers' : true,
  54 +
  55 + /** Lines to highlight. */
  56 + 'highlight' : null,
  57 +
  58 + /** Enables or disables smart tabs. */
  59 + 'smart-tabs' : true,
  60 +
  61 + /** Gets or sets tab size. */
  62 + 'tab-size' : 4,
  63 +
  64 + /** Enables or disables gutter. */
  65 + 'gutter' : true,
  66 +
  67 + /** Enables or disables toolbar. */
  68 + 'toolbar' : true,
  69 +
  70 + /** Forces code view to be collapsed. */
  71 + 'collapse' : false,
  72 +
  73 + /** Enables or disables automatic links. */
  74 + 'auto-links' : true,
  75 +
  76 + /** Gets or sets light mode. Equavalent to turning off gutter and toolbar. */
  77 + 'light' : false,
  78 +
  79 + /** Enables or disables automatic line wrapping. */
  80 + 'wrap-lines' : true,
  81 +
  82 + 'html-script' : false
  83 + },
  84 +
  85 + config : {
  86 + /** Enables use of <SCRIPT type="syntaxhighlighter" /> tags. */
  87 + useScriptTags : true,
  88 +
  89 + /** Path to the copy to clipboard SWF file. */
  90 + clipboardSwf : null,
  91 +
  92 + /** Width of an item in the toolbar. */
  93 + toolbarItemWidth : 16,
  94 +
  95 + /** Height of an item in the toolbar. */
  96 + toolbarItemHeight : 16,
  97 +
  98 + /** Blogger mode flag. */
  99 + bloggerMode : false,
  100 +
  101 + stripBrs : false,
  102 +
  103 + /** Name of the tag that SyntaxHighlighter will automatically look for. */
  104 + tagName : 'pre',
  105 +
  106 + strings : {
  107 + expandSource : 'show source',
  108 + viewSource : 'view source',
  109 + copyToClipboard : 'copy to clipboard',
  110 + copyToClipboardConfirmation : 'The code is in your clipboard now',
  111 + print : 'print',
  112 + help : '?',
  113 + alert: 'SyntaxHighlighter\n\n',
  114 + noBrush : 'Can\'t find brush for: ',
  115 + brushNotHtmlScript : 'Brush wasn\'t configured for html-script option: ',
  116 +
  117 + // this is populated by the build script
  118 + aboutDialog : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>About SyntaxHighlighter</title></head><body style="font-family:Geneva,Arial,Helvetica,sans-serif;background-color:#fff;color:#000;font-size:1em;text-align:center;"><div style="text-align:center;margin-top:3em;"><div style="font-size:xx-large;">SyntaxHighlighter</div><div style="font-size:.75em;margin-bottom:4em;"><div>version 2.1.364 (October 15 2009)</div><div><a href="http://alexgorbatchev.com" target="_blank" style="color:#0099FF;text-decoration:none;">http://alexgorbatchev.com</a></div><div>If you like this script, please <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2930402" style="color:#0099FF;text-decoration:none;">donate</a> to keep development active!</div></div><div>JavaScript code syntax highlighter.</div><div>Copyright 2004-2009 Alex Gorbatchev.</div></div></body></html>'
  119 + },
  120 +
  121 + /** If true, output will show HTML produces instead. */
  122 + debug : false
  123 + },
  124 +
  125 + /** Internal 'global' variables. */
  126 + vars : {
  127 + discoveredBrushes : null,
  128 + spaceWidth : null,
  129 + printFrame : null,
  130 + highlighters : {}
  131 + },
  132 +
  133 + /** This object is populated by user included external brush files. */
  134 + brushes : {},
  135 +
  136 + /** Common regular expressions. */
  137 + regexLib : {
  138 + multiLineCComments : /\/\*[\s\S]*?\*\//gm,
  139 + singleLineCComments : /\/\/.*$/gm,
  140 + singleLinePerlComments : /#.*$/gm,
  141 + doubleQuotedString : /"([^\\"\n]|\\.)*"/g,
  142 + singleQuotedString : /'([^\\'\n]|\\.)*'/g,
  143 + multiLineDoubleQuotedString : /"([^\\"]|\\.)*"/g,
  144 + multiLineSingleQuotedString : /'([^\\']|\\.)*'/g,
  145 + xmlComments : /(&lt;|<)!--[\s\S]*?--(&gt;|>)/gm,
  146 + url : /&lt;\w+:\/\/[\w-.\/?%&=@:;]*&gt;|\w+:\/\/[\w-.\/?%&=@:;]*/g,
  147 +
  148 + /** <?= ?> tags. */
  149 + phpScriptTags : { left: /(&lt;|<)\?=?/g, right: /\?(&gt;|>)/g },
  150 +
  151 + /** <%= %> tags. */
  152 + aspScriptTags : { left: /(&lt;|<)%=?/g, right: /%(&gt;|>)/g },
  153 +
  154 + /** <script></script> tags. */
  155 + scriptScriptTags : { left: /(&lt;|<)\s*script.*?(&gt;|>)/gi, right: /(&lt;|<)\/\s*script\s*(&gt;|>)/gi }
  156 + },
  157 +
  158 + toolbar : {
  159 + /**
  160 + * Creates new toolbar for a highlighter.
  161 + * @param {Highlighter} highlighter Target highlighter.
  162 + */
  163 + create : function(highlighter)
  164 + {
  165 + var div = document.createElement('DIV'),
  166 + items = sh.toolbar.items
  167 + ;
  168 +
  169 + div.className = 'toolbar';
  170 +
  171 + for (var name in items)
  172 + {
  173 + var constructor = items[name],
  174 + command = new constructor(highlighter),
  175 + element = command.create()
  176 + ;
  177 +
  178 + highlighter.toolbarCommands[name] = command;
  179 +
  180 + if (element == null)
  181 + continue;
  182 +
  183 + if (typeof(element) == 'string')
  184 + element = sh.toolbar.createButton(element, highlighter.id, name);
  185 +
  186 + element.className += 'item ' + name;
  187 + div.appendChild(element);
  188 + }
  189 +
  190 + return div;
  191 + },
  192 +
  193 + /**
  194 + * Create a standard anchor button for the toolbar.
  195 + * @param {String} label Label text to display.
  196 + * @param {String} highlighterId Highlighter ID that this button would belong to.
  197 + * @param {String} commandName Command name that would be executed.
  198 + * @return {Element} Returns an 'A' element.
  199 + */
  200 + createButton : function(label, highlighterId, commandName)
  201 + {
  202 + var a = document.createElement('a'),
  203 + style = a.style,
  204 + config = sh.config,
  205 + width = config.toolbarItemWidth,
  206 + height = config.toolbarItemHeight
  207 + ;
  208 +
  209 + a.href = '#' + commandName;
  210 + a.title = label;
  211 + a.highlighterId = highlighterId;
  212 + a.commandName = commandName;
  213 + a.innerHTML = label;
  214 +
  215 + if (isNaN(width) == false)
  216 + style.width = width + 'px';
  217 +
  218 + if (isNaN(height) == false)
  219 + style.height = height + 'px';
  220 +
  221 + a.onclick = function(e)
  222 + {
  223 + try
  224 + {
  225 + sh.toolbar.executeCommand(
  226 + this,
  227 + e || window.event,
  228 + this.highlighterId,
  229 + this.commandName
  230 + );
  231 + }
  232 + catch(e)
  233 + {
  234 + sh.utils.alert(e.message);
  235 + }
  236 +
  237 + return false;
  238 + };
  239 +
  240 + return a;
  241 + },
  242 +
  243 + /**
  244 + * Executes a toolbar command.
  245 + * @param {Element} sender Sender element.
  246 + * @param {MouseEvent} event Original mouse event object.
  247 + * @param {String} highlighterId Highlighter DIV element ID.
  248 + * @param {String} commandName Name of the command to execute.
  249 + * @return {Object} Passes out return value from command execution.
  250 + */
  251 + executeCommand : function(sender, event, highlighterId, commandName, args)
  252 + {
  253 + var highlighter = sh.vars.highlighters[highlighterId],
  254 + command
  255 + ;
  256 +
  257 + if (highlighter == null || (command = highlighter.toolbarCommands[commandName]) == null)
  258 + return null;
  259 +
  260 + return command.execute(sender, event, args);
  261 + },
  262 +
  263 + /** Collection of toolbar items. */
  264 + items : {
  265 + expandSource : function(highlighter)
  266 + {
  267 + this.create = function()
  268 + {
  269 + if (highlighter.getParam('collapse') != true)
  270 + return;
  271 +
  272 + return sh.config.strings.expandSource;
  273 + };
  274 +
  275 + this.execute = function(sender, event, args)
  276 + {
  277 + var div = highlighter.div;
  278 +
  279 + sender.parentNode.removeChild(sender);
  280 + div.className = div.className.replace('collapsed', '');
  281 + };
  282 + },
  283 +
  284 + /**
  285 + * Command to open a new window and display the original unformatted source code inside.
  286 + */
  287 + viewSource : function(highlighter)
  288 + {
  289 + this.create = function()
  290 + {
  291 + return sh.config.strings.viewSource;
  292 + };
  293 +
  294 + this.execute = function(sender, event, args)
  295 + {
  296 + var code = sh.utils.fixInputString(highlighter.originalCode).replace(/</g, '&lt;'),
  297 + wnd = sh.utils.popup('', '_blank', 750, 400, 'location=0, resizable=1, menubar=0, scrollbars=1')
  298 + ;
  299 +
  300 + code = sh.utils.unindent(code);
  301 +
  302 + wnd.document.write('<pre>' + code + '</pre>');
  303 + wnd.document.close();
  304 + };
  305 + },
  306 +
  307 + /**
  308 + * Command to copy the original source code in to the clipboard.
  309 + * Uses Flash method if <code>clipboardSwf</code> is configured.
  310 + */
  311 + copyToClipboard : function(highlighter)
  312 + {
  313 + var flashDiv, flashSwf,
  314 + highlighterId = highlighter.id
  315 + ;
  316 +
  317 + this.create = function()
  318 + {
  319 + var config = sh.config;
  320 +
  321 + // disable functionality if running locally
  322 + if (config.clipboardSwf == null)
  323 + return null;
  324 +
  325 + function params(list)
  326 + {
  327 + var result = '';
  328 +
  329 + for (var name in list)
  330 + result += "<param name='" + name + "' value='" + list[name] + "'/>";
  331 +
  332 + return result;
  333 + };
  334 +
  335 + function attributes(list)
  336 + {
  337 + var result = '';
  338 +
  339 + for (var name in list)
  340 + result += " " + name + "='" + list[name] + "'";
  341 +
  342 + return result;
  343 + };
  344 +
  345 + var args1 = {
  346 + width : config.toolbarItemWidth,
  347 + height : config.toolbarItemHeight,
  348 + id : highlighterId + '_clipboard',
  349 + type : 'application/x-shockwave-flash',
  350 + title : sh.config.strings.copyToClipboard
  351 + },
  352 +
  353 + // these arguments are used in IE's <param /> collection
  354 + args2 = {
  355 + allowScriptAccess : 'always',
  356 + wmode : 'transparent',
  357 + flashVars : 'highlighterId=' + highlighterId,
  358 + menu : 'false'
  359 + },
  360 + swf = config.clipboardSwf,
  361 + html
  362 + ;
  363 +
  364 + if (/msie/i.test(navigator.userAgent))
  365 + {
  366 + html = '<object'
  367 + + attributes({
  368 + classid : 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000',
  369 + codebase : 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0'
  370 + })
  371 + + attributes(args1)
  372 + + '>'
  373 + + params(args2)
  374 + + params({ movie : swf })
  375 + + '</object>'
  376 + ;
  377 + }
  378 + else
  379 + {
  380 + html = '<embed'
  381 + + attributes(args1)
  382 + + attributes(args2)
  383 + + attributes({ src : swf })
  384 + + '/>'
  385 + ;
  386 + }
  387 +
  388 + flashDiv = document.createElement('div');
  389 + flashDiv.innerHTML = html;
  390 +
  391 + return flashDiv;
  392 + };
  393 +
  394 + this.execute = function(sender, event, args)
  395 + {
  396 + var command = args.command;
  397 +
  398 + switch (command)
  399 + {
  400 + case 'get':
  401 + var code = sh.utils.unindent(
  402 + sh.utils.fixInputString(highlighter.originalCode)
  403 + .replace(/&lt;/g, '<')
  404 + .replace(/&gt;/g, '>')
  405 + .replace(/&amp;/g, '&')
  406 + );
  407 +
  408 + if(window.clipboardData)
  409 + // will fall through to the confirmation because there isn't a break
  410 + window.clipboardData.setData('text', code);
  411 + else
  412 + return sh.utils.unindent(code);
  413 +
  414 + case 'ok':
  415 + sh.utils.alert(sh.config.strings.copyToClipboardConfirmation);
  416 + break;
  417 +
  418 + case 'error':
  419 + sh.utils.alert(args.message);
  420 + break;
  421 + }
  422 + };
  423 + },
  424 +
  425 + /** Command to print the colored source code. */
  426 + printSource : function(highlighter)
  427 + {
  428 + this.create = function()
  429 + {
  430 + return sh.config.strings.print;
  431 + };
  432 +
  433 + this.execute = function(sender, event, args)
  434 + {
  435 + var iframe = document.createElement('IFRAME'),
  436 + doc = null
  437 + ;
  438 +
  439 + // make sure there is never more than one hidden iframe created by SH
  440 + if (sh.vars.printFrame != null)
  441 + document.body.removeChild(sh.vars.printFrame);
  442 +
  443 + sh.vars.printFrame = iframe;
  444 +
  445 + // this hides the iframe
  446 + iframe.style.cssText = 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;';
  447 +
  448 + document.body.appendChild(iframe);
  449 + doc = iframe.contentWindow.document;
  450 +
  451 + copyStyles(doc, window.document);
  452 + doc.write('<div class="' + highlighter.div.className.replace('collapsed', '') + ' printing">' + highlighter.div.innerHTML + '</div>');
  453 + doc.close();
  454 +
  455 + iframe.contentWindow.focus();
  456 + iframe.contentWindow.print();
  457 +
  458 + function copyStyles(destDoc, sourceDoc)
  459 + {
  460 + var links = sourceDoc.getElementsByTagName('link');
  461 +
  462 + for(var i = 0; i < links.length; i++)
  463 + if(links[i].rel.toLowerCase() == 'stylesheet' && /shCore\.css$/.test(links[i].href))
  464 + destDoc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
  465 + };
  466 + };
  467 + },
  468 +
  469 + /** Command to display the about dialog window. */
  470 + about : function(highlighter)
  471 + {
  472 + this.create = function()
  473 + {
  474 + return sh.config.strings.help;
  475 + };
  476 +
  477 + this.execute = function(sender, event)
  478 + {
  479 + var wnd = sh.utils.popup('', '_blank', 500, 250, 'scrollbars=0'),
  480 + doc = wnd.document
  481 + ;
  482 +
  483 + doc.write(sh.config.strings.aboutDialog);
  484 + doc.close();
  485 + wnd.focus();
  486 + };
  487 + }
  488 + }
  489 + },
  490 +
  491 + utils : {
  492 + /**
  493 + * Finds an index of element in the array.
  494 + * @ignore
  495 + * @param {Object} searchElement
  496 + * @param {Number} fromIndex
  497 + * @return {Number} Returns index of element if found; -1 otherwise.
  498 + */
  499 + indexOf : function(array, searchElement, fromIndex)
  500 + {
  501 + fromIndex = Math.max(fromIndex || 0, 0);
  502 +
  503 + for (var i = fromIndex; i < array.length; i++)
  504 + if(array[i] == searchElement)
  505 + return i;
  506 +
  507 + return -1;
  508 + },
  509 +
  510 + /**
  511 + * Generates a unique element ID.
  512 + */
  513 + guid : function(prefix)
  514 + {
  515 + return prefix + Math.round(Math.random() * 1000000).toString();
  516 + },
  517 +
  518 + /**
  519 + * Merges two objects. Values from obj2 override values in obj1.
  520 + * Function is NOT recursive and works only for one dimensional objects.
  521 + * @param {Object} obj1 First object.
  522 + * @param {Object} obj2 Second object.
  523 + * @return {Object} Returns combination of both objects.
  524 + */
  525 + merge: function(obj1, obj2)
  526 + {
  527 + var result = {}, name;
  528 +
  529 + for (name in obj1)
  530 + result[name] = obj1[name];
  531 +
  532 + for (name in obj2)
  533 + result[name] = obj2[name];
  534 +
  535 + return result;
  536 + },
  537 +
  538 + /**
  539 + * Attempts to convert string to boolean.
  540 + * @param {String} value Input string.
  541 + * @return {Boolean} Returns true if input was "true", false if input was "false" and value otherwise.
  542 + */
  543 + toBoolean: function(value)
  544 + {
  545 + switch (value)
  546 + {
  547 + case "true":
  548 + return true;
  549 +
  550 + case "false":
  551 + return false;
  552 + }
  553 +
  554 + return value;
  555 + },
  556 +
  557 + /**
  558 + * Opens up a centered popup window.
  559 + * @param {String} url URL to open in the window.
  560 + * @param {String} name Popup name.
  561 + * @param {int} width Popup width.
  562 + * @param {int} height Popup height.
  563 + * @param {String} options window.open() options.
  564 + * @return {Window} Returns window instance.
  565 + */
  566 + popup: function(url, name, width, height, options)
  567 + {
  568 + var x = (screen.width - width) / 2,
  569 + y = (screen.height - height) / 2
  570 + ;
  571 +
  572 + options += ', left=' + x +
  573 + ', top=' + y +
  574 + ', width=' + width +
  575 + ', height=' + height
  576 + ;
  577 + options = options.replace(/^,/, '');
  578 +
  579 + var win = window.open(url, name, options);
  580 + win.focus();
  581 + return win;
  582 + },
  583 +
  584 + /**
  585 + * Adds event handler to the target object.
  586 + * @param {Object} obj Target object.
  587 + * @param {String} type Name of the event.
  588 + * @param {Function} func Handling function.
  589 + */
  590 + addEvent: function(obj, type, func)
  591 + {
  592 + if (obj.attachEvent)
  593 + {
  594 + obj['e' + type + func] = func;
  595 + obj[type + func] = function()
  596 + {
  597 + obj['e' + type + func](window.event);
  598 + }
  599 + obj.attachEvent('on' + type, obj[type + func]);
  600 + }
  601 + else
  602 + {
  603 + obj.addEventListener(type, func, false);
  604 + }
  605 + },
  606 +
  607 + /**
  608 + * Displays an alert.
  609 + * @param {String} str String to display.
  610 + */
  611 + alert: function(str)
  612 + {
  613 + alert(sh.config.strings.alert + str)
  614 + },
  615 +
  616 + /**
  617 + * Finds a brush by its alias.
  618 + *
  619 + * @param {String} alias Brush alias.
  620 + * @param {Boolean} alert Suppresses the alert if false.
  621 + * @return {Brush} Returns bursh constructor if found, null otherwise.
  622 + */
  623 + findBrush: function(alias, alert)
  624 + {
  625 + var brushes = sh.vars.discoveredBrushes,
  626 + result = null
  627 + ;
  628 +
  629 + if (brushes == null)
  630 + {
  631 + brushes = {};
  632 +
  633 + // Find all brushes
  634 + for (var brush in sh.brushes)
  635 + {
  636 + var aliases = sh.brushes[brush].aliases;
  637 +
  638 + if (aliases == null)
  639 + continue;
  640 +
  641 + // keep the brush name
  642 + sh.brushes[brush].name = brush.toLowerCase();
  643 +
  644 + for (var i = 0; i < aliases.length; i++)
  645 + brushes[aliases[i]] = brush;
  646 + }
  647 +
  648 + sh.vars.discoveredBrushes = brushes;
  649 + }
  650 +
  651 + result = sh.brushes[brushes[alias]];
  652 +
  653 + if (result == null && alert != false)
  654 + sh.utils.alert(sh.config.strings.noBrush + alias);
  655 +
  656 + return result;
  657 + },
  658 +
  659 + /**
  660 + * Executes a callback on each line and replaces each line with result from the callback.
  661 + * @param {Object} str Input string.
  662 + * @param {Object} callback Callback function taking one string argument and returning a string.
  663 + */
  664 + eachLine: function(str, callback)
  665 + {
  666 + var lines = str.split('\n');
  667 +
  668 + for (var i = 0; i < lines.length; i++)
  669 + lines[i] = callback(lines[i]);
  670 +
  671 + return lines.join('\n');
  672 + },
  673 +
  674 + /**
  675 + * This is a special trim which only removes first and last empty lines
  676 + * and doesn't affect valid leading space on the first line.
  677 + *
  678 + * @param {String} str Input string
  679 + * @return {String} Returns string without empty first and last lines.
  680 + */
  681 + trimFirstAndLastLines: function(str)
  682 + {
  683 + return str.replace(/^[ ]*[\n]+|[\n]*[ ]*$/g, '');
  684 + },
  685 +
  686 + /**
  687 + * Parses key/value pairs into hash object.
  688 + *
  689 + * Understands the following formats:
  690 + * - name: word;
  691 + * - name: [word, word];
  692 + * - name: "string";
  693 + * - name: 'string';
  694 + *
  695 + * For example:
  696 + * name1: value; name2: [value, value]; name3: 'value'
  697 + *
  698 + * @param {String} str Input string.
  699 + * @return {Object} Returns deserialized object.
  700 + */
  701 + parseParams: function(str)
  702 + {
  703 + var match,
  704 + result = {},
  705 + arrayRegex = new XRegExp("^\\[(?<values>(.*?))\\]$"),
  706 + regex = new XRegExp(
  707 + "(?<name>[\\w-]+)" +
  708 + "\\s*:\\s*" +
  709 + "(?<value>" +
  710 + "[\\w-%#]+|" + // word
  711 + "\\[.*?\\]|" + // [] array
  712 + '".*?"|' + // "" string
  713 + "'.*?'" + // '' string
  714 + ")\\s*;?",
  715 + "g"
  716 + )
  717 + ;
  718 +
  719 + while ((match = regex.exec(str)) != null)
  720 + {
  721 + var value = match.value
  722 + .replace(/^['"]|['"]$/g, '') // strip quotes from end of strings
  723 + ;
  724 +
  725 + // try to parse array value
  726 + if (value != null && arrayRegex.test(value))
  727 + {
  728 + var m = arrayRegex.exec(value);
  729 + value = m.values.length > 0 ? m.values.split(/\s*,\s*/) : [];
  730 + }
  731 +
  732 + result[match.name] = value;
  733 + }
  734 +
  735 + return result;
  736 + },
  737 +
  738 + /**
  739 + * Wraps each line of the string into <code/> tag with given style applied to it.
  740 + *
  741 + * @param {String} str Input string.
  742 + * @param {String} css Style name to apply to the string.
  743 + * @return {String} Returns input string with each line surrounded by <span/> tag.
  744 + */
  745 + decorate: function(str, css)
  746 + {
  747 + if (str == null || str.length == 0 || str == '\n')
  748 + return str;
  749 +
  750 + str = str.replace(/</g, '&lt;');
  751 +
  752 + // Replace two or more sequential spaces with &nbsp; leaving last space untouched.
  753 + str = str.replace(/ {2,}/g, function(m)
  754 + {
  755 + var spaces = '';
  756 +
  757 + for (var i = 0; i < m.length - 1; i++)
  758 + spaces += '&nbsp;';
  759 +
  760 + return spaces + ' ';
  761 + });
  762 +
  763 + // Split each line and apply <span class="...">...</span> to them so that
  764 + // leading spaces aren't included.
  765 + if (css != null)
  766 + str = sh.utils.eachLine(str, function(line)
  767 + {
  768 + if (line.length == 0)
  769 + return '';
  770 +
  771 + var spaces = '';
  772 +
  773 + line = line.replace(/^(&nbsp;| )+/, function(s)
  774 + {
  775 + spaces = s;
  776 + return '';
  777 + });
  778 +
  779 + if (line.length == 0)
  780 + return spaces;
  781 +
  782 + return spaces + '<code class="' + css + '">' + line + '</code>';
  783 + });
  784 +
  785 + return str;
  786 + },
  787 +
  788 + /**
  789 + * Pads number with zeros until it's length is the same as given length.
  790 + *
  791 + * @param {Number} number Number to pad.
  792 + * @param {Number} length Max string length with.
  793 + * @return {String} Returns a string padded with proper amount of '0'.
  794 + */
  795 + padNumber : function(number, length)
  796 + {
  797 + var result = number.toString();
  798 +
  799 + while (result.length < length)
  800 + result = '0' + result;
  801 +
  802 + return result;
  803 + },
  804 +
  805 + /**
  806 + * Measures width of a single space character.
  807 + * @return {Number} Returns width of a single space character.
  808 + */
  809 + measureSpace : function()
  810 + {
  811 + var container = document.createElement('div'),
  812 + span,
  813 + result = 0,
  814 + body = document.body,
  815 + id = sh.utils.guid('measureSpace'),
  816 +
  817 + // variable names will be compressed, so it's better than a plain string
  818 + divOpen = '<div class="',
  819 + closeDiv = '</div>',
  820 + closeSpan = '</span>'
  821 + ;
  822 +
  823 + // we have to duplicate highlighter nested structure in order to get an acurate space measurment
  824 + container.innerHTML =
  825 + divOpen + 'syntaxhighlighter">'
  826 + + divOpen + 'lines">'
  827 + + divOpen + 'line">'
  828 + + divOpen + 'content'
  829 + + '"><span class="block"><span id="' + id + '">&nbsp;' + closeSpan + closeSpan
  830 + + closeDiv
  831 + + closeDiv
  832 + + closeDiv
  833 + + closeDiv
  834 + ;
  835 +
  836 + body.appendChild(container);
  837 + span = document.getElementById(id);
  838 +
  839 + if (/opera/i.test(navigator.userAgent))
  840 + {
  841 + var style = window.getComputedStyle(span, null);
  842 + result = parseInt(style.getPropertyValue("width"));
  843 + }
  844 + else
  845 + {
  846 + result = span.offsetWidth;
  847 + }
  848 +
  849 + body.removeChild(container);
  850 +
  851 + return result;
  852 + },
  853 +
  854 + /**
  855 + * Replaces tabs with spaces.
  856 + *
  857 + * @param {String} code Source code.
  858 + * @param {Number} tabSize Size of the tab.
  859 + * @return {String} Returns code with all tabs replaces by spaces.
  860 + */
  861 + processTabs : function(code, tabSize)
  862 + {
  863 + var tab = '';
  864 +
  865 + for (var i = 0; i < tabSize; i++)
  866 + tab += ' ';
  867 +
  868 + return code.replace(/\t/g, tab);
  869 + },
  870 +
  871 + /**
  872 + * Replaces tabs with smart spaces.
  873 + *
  874 + * @param {String} code Code to fix the tabs in.
  875 + * @param {Number} tabSize Number of spaces in a column.
  876 + * @return {String} Returns code with all tabs replaces with roper amount of spaces.
  877 + */
  878 + processSmartTabs : function(code, tabSize)
  879 + {
  880 + var lines = code.split('\n'),
  881 + tab = '\t',
  882 + spaces = ''
  883 + ;
  884 +
  885 + // Create a string with 1000 spaces to copy spaces from...
  886 + // It's assumed that there would be no indentation longer than that.
  887 + for (var i = 0; i < 50; i++)
  888 + spaces += ' '; // 20 spaces * 50
  889 +
  890 + // This function inserts specified amount of spaces in the string
  891 + // where a tab is while removing that given tab.
  892 + function insertSpaces(line, pos, count)
  893 + {
  894 + return line.substr(0, pos)
  895 + + spaces.substr(0, count)
  896 + + line.substr(pos + 1, line.length) // pos + 1 will get rid of the tab
  897 + ;
  898 + };
  899 +
  900 + // Go through all the lines and do the 'smart tabs' magic.
  901 + code = sh.utils.eachLine(code, function(line)
  902 + {
  903 + if (line.indexOf(tab) == -1)
  904 + return line;
  905 +
  906 + var pos = 0;
  907 +
  908 + while ((pos = line.indexOf(tab)) != -1)
  909 + {
  910 + // This is pretty much all there is to the 'smart tabs' logic.
  911 + // Based on the position within the line and size of a tab,
  912 + // calculate the amount of spaces we need to insert.
  913 + var spaces = tabSize - pos % tabSize;
  914 + line = insertSpaces(line, pos, spaces);
  915 + }
  916 +
  917 + return line;
  918 + });
  919 +
  920 + return code;
  921 + },
  922 +
  923 + /**
  924 + * Performs various string fixes based on configuration.
  925 + */
  926 + fixInputString : function(str)
  927 + {
  928 + var br = /<br\s*\/?>|&lt;br\s*\/?&gt;/gi;
  929 +
  930 + if (sh.config.bloggerMode == true)
  931 + str = str.replace(br, '\n');
  932 +
  933 + if (sh.config.stripBrs == true)
  934 + str = str.replace(br, '');
  935 +
  936 + return str;
  937 + },
  938 +
  939 + /**
  940 + * Removes all white space at the begining and end of a string.
  941 + *
  942 + * @param {String} str String to trim.
  943 + * @return {String} Returns string without leading and following white space characters.
  944 + */
  945 + trim: function(str)
  946 + {
  947 + return str.replace(/^\s+|\s+$/g, '');
  948 + },
  949 +
  950 + /**
  951 + * Unindents a block of text by the lowest common indent amount.
  952 + * @param {String} str Text to unindent.
  953 + * @return {String} Returns unindented text block.
  954 + */
  955 + unindent: function(str)
  956 + {
  957 + var lines = sh.utils.fixInputString(str).split('\n'),
  958 + indents = new Array(),
  959 + regex = /^\s*/,
  960 + min = 1000
  961 + ;
  962 +
  963 + // go through every line and check for common number of indents
  964 + for (var i = 0; i < lines.length && min > 0; i++)
  965 + {
  966 + var line = lines[i];
  967 +
  968 + if (sh.utils.trim(line).length == 0)
  969 + continue;
  970 +
  971 + var matches = regex.exec(line);
  972 +
  973 + // In the event that just one line doesn't have leading white space
  974 + // we can't unindent anything, so bail completely.
  975 + if (matches == null)
  976 + return str;
  977 +
  978 + min = Math.min(matches[0].length, min);
  979 + }
  980 +
  981 + // trim minimum common number of white space from the begining of every line
  982 + if (min > 0)
  983 + for (var i = 0; i < lines.length; i++)
  984 + lines[i] = lines[i].substr(min);
  985 +
  986 + return lines.join('\n');
  987 + },
  988 +
  989 + /**
  990 + * Callback method for Array.sort() which sorts matches by
  991 + * index position and then by length.
  992 + *
  993 + * @param {Match} m1 Left object.
  994 + * @param {Match} m2 Right object.
  995 + * @return {Number} Returns -1, 0 or -1 as a comparison result.
  996 + */
  997 + matchesSortCallback: function(m1, m2)
  998 + {
  999 + // sort matches by index first
  1000 + if(m1.index < m2.index)
  1001 + return -1;
  1002 + else if(m1.index > m2.index)
  1003 + return 1;
  1004 + else
  1005 + {
  1006 + // if index is the same, sort by length
  1007 + if(m1.length < m2.length)
  1008 + return -1;
  1009 + else if(m1.length > m2.length)
  1010 + return 1;
  1011 + }
  1012 +
  1013 + return 0;
  1014 + },
  1015 +
  1016 + /**
  1017 + * Executes given regular expression on provided code and returns all
  1018 + * matches that are found.
  1019 + *
  1020 + * @param {String} code Code to execute regular expression on.
  1021 + * @param {Object} regex Regular expression item info from <code>regexList</code> collection.
  1022 + * @return {Array} Returns a list of Match objects.
  1023 + */
  1024 + getMatches: function(code, regexInfo)
  1025 + {
  1026 + function defaultAdd(match, regexInfo)
  1027 + {
  1028 + return [new sh.Match(match[0], match.index, regexInfo.css)];
  1029 + };
  1030 +
  1031 + var index = 0,
  1032 + match = null,
  1033 + result = [],
  1034 + func = regexInfo.func ? regexInfo.func : defaultAdd
  1035 + ;
  1036 +
  1037 + while((match = regexInfo.regex.exec(code)) != null)
  1038 + result = result.concat(func(match, regexInfo));
  1039 +
  1040 + return result;
  1041 + },
  1042 +
  1043 + processUrls: function(code)
  1044 + {
  1045 + var lt = '&lt;',
  1046 + gt = '&gt;'
  1047 + ;
  1048 +
  1049 + return code.replace(sh.regexLib.url, function(m)
  1050 + {
  1051 + var suffix = '', prefix = '';
  1052 +
  1053 + // We include &lt; and &gt; in the URL for the common cases like <http://google.com>
  1054 + // The problem is that they get transformed into &lt;http://google.com&gt;
  1055 + // Where as &gt; easily looks like part of the URL string.
  1056 +
  1057 + if (m.indexOf(lt) == 0)
  1058 + {
  1059 + prefix = lt;
  1060 + m = m.substring(lt.length);
  1061 + }
  1062 +
  1063 + if (m.indexOf(gt) == m.length - gt.length)
  1064 + {
  1065 + m = m.substring(0, m.length - gt.length);
  1066 + suffix = gt;
  1067 + }
  1068 +
  1069 + return prefix + '<a href="' + m + '">' + m + '</a>' + suffix;
  1070 + });
  1071 + },
  1072 +
  1073 + /**
  1074 + * Finds all <SCRIPT TYPE="syntaxhighlighter" /> elements.
  1075 + * @return {Array} Returns array of all found SyntaxHighlighter tags.
  1076 + */
  1077 + getSyntaxHighlighterScriptTags: function()
  1078 + {
  1079 + var tags = document.getElementsByTagName('script'),
  1080 + result = []
  1081 + ;
  1082 +
  1083 + for (var i = 0; i < tags.length; i++)
  1084 + if (tags[i].type == 'syntaxhighlighter')
  1085 + result.push(tags[i]);
  1086 +
  1087 + return result;
  1088 + },
  1089 +
  1090 + /**
  1091 + * Strips <![CDATA[]]> from <SCRIPT /> content because it should be used
  1092 + * there in most cases for XHTML compliance.
  1093 + * @param {String} original Input code.
  1094 + * @return {String} Returns code without leading <![CDATA[]]> tags.
  1095 + */
  1096 + stripCData: function(original)
  1097 + {
  1098 + var left = '<![CDATA[',
  1099 + right = ']]>',
  1100 + // for some reason IE inserts some leading blanks here
  1101 + copy = sh.utils.trim(original),
  1102 + changed = false
  1103 + ;
  1104 +
  1105 + if (copy.indexOf(left) == 0)
  1106 + {
  1107 + copy = copy.substring(left.length);
  1108 + changed = true;
  1109 + }
  1110 +
  1111 + if (copy.indexOf(right) == copy.length - right.length)
  1112 + {
  1113 + copy = copy.substring(0, copy.length - right.length);
  1114 + changed = true;
  1115 + }
  1116 +
  1117 + return changed ? copy : original;
  1118 + }
  1119 + }, // end of utils
  1120 +
  1121 + /**
  1122 + * Shorthand to highlight all elements on the page that are marked as
  1123 + * SyntaxHighlighter source code.
  1124 + *
  1125 + * @param {Object} globalParams Optional parameters which override element's
  1126 + * parameters. Only used if element is specified.
  1127 + *
  1128 + * @param {Object} element Optional element to highlight. If none is
  1129 + * provided, all elements in the current document
  1130 + * are highlighted.
  1131 + */
  1132 + highlight : function(globalParams, element)
  1133 + {
  1134 + function toArray(source)
  1135 + {
  1136 + var result = [];
  1137 +
  1138 + for (var i = 0; i < source.length; i++)
  1139 + result.push(source[i]);
  1140 +
  1141 + return result;
  1142 + };
  1143 +
  1144 + var elements = element ? [element] : toArray(document.getElementsByTagName(sh.config.tagName)),
  1145 + propertyName = 'innerHTML',
  1146 + highlighter = null,
  1147 + conf = sh.config
  1148 + ;
  1149 +
  1150 + // support for <SCRIPT TYPE="syntaxhighlighter" /> feature
  1151 + if (conf.useScriptTags)
  1152 + elements = elements.concat(sh.utils.getSyntaxHighlighterScriptTags());
  1153 +
  1154 + if (elements.length === 0)
  1155 + return;
  1156 +
  1157 + for (var i = 0; i < elements.length; i++)
  1158 + {
  1159 + var target = elements[i],
  1160 + params = sh.utils.parseParams(target.className),
  1161 + brushName,
  1162 + code,
  1163 + result
  1164 + ;
  1165 +
  1166 + // local params take precedence over globals
  1167 + params = sh.utils.merge(globalParams, params);
  1168 + brushName = params['brush'];
  1169 +
  1170 + if (brushName == null)
  1171 + continue;
  1172 +
  1173 + // Instantiate a brush
  1174 + if (params['html-script'] == 'true' || sh.defaults['html-script'] == true)
  1175 + {
  1176 + highlighter = new sh.HtmlScript(brushName);
  1177 + brushName = 'htmlscript';
  1178 + }
  1179 + else
  1180 + {
  1181 + var brush = sh.utils.findBrush(brushName);
  1182 +
  1183 + if (brush)
  1184 + {
  1185 + brushName = brush.name;
  1186 + highlighter = new brush();
  1187 + }
  1188 + else
  1189 + {
  1190 + continue;
  1191 + }
  1192 + }
  1193 +
  1194 + code = target[propertyName];
  1195 +
  1196 + // remove CDATA from <SCRIPT/> tags if it's present
  1197 + if (conf.useScriptTags)
  1198 + code = sh.utils.stripCData(code);
  1199 +
  1200 + params['brush-name'] = brushName;
  1201 + highlighter.highlight(code, params);
  1202 +
  1203 + result = highlighter.div;
  1204 +
  1205 + if (sh.config.debug)
  1206 + {
  1207 + result = document.createElement('textarea');
  1208 + result.value = highlighter.div.innerHTML;
  1209 + result.style.width = '70em';
  1210 + result.style.height = '30em';
  1211 + }
  1212 +
  1213 + target.parentNode.replaceChild(result, target);
  1214 + }
  1215 + },
  1216 +
  1217 + /**
  1218 + * Main entry point for the SyntaxHighlighter.
  1219 + * @param {Object} params Optional params to apply to all highlighted elements.
  1220 + */
  1221 + all : function(params)
  1222 + {
  1223 + sh.utils.addEvent(
  1224 + window,
  1225 + 'load',
  1226 + function() { sh.highlight(params); }
  1227 + );
  1228 + }
  1229 +}; // end of sh
  1230 +
  1231 +/**
  1232 + * Match object.
  1233 + */
  1234 +sh.Match = function(value, index, css)
  1235 +{
  1236 + this.value = value;
  1237 + this.index = index;
  1238 + this.length = value.length;
  1239 + this.css = css;
  1240 + this.brushName = null;
  1241 +};
  1242 +
  1243 +sh.Match.prototype.toString = function()
  1244 +{
  1245 + return this.value;
  1246 +};
  1247 +
  1248 +/**
  1249 + * Simulates HTML code with a scripting language embedded.
  1250 + *
  1251 + * @param {String} scriptBrushName Brush name of the scripting language.
  1252 + */
  1253 +sh.HtmlScript = function(scriptBrushName)
  1254 +{
  1255 + var brushClass = sh.utils.findBrush(scriptBrushName),
  1256 + scriptBrush,
  1257 + xmlBrush = new sh.brushes.Xml(),
  1258 + bracketsRegex = null
  1259 + ;
  1260 +
  1261 + if (brushClass == null)
  1262 + return;
  1263 +
  1264 + scriptBrush = new brushClass();
  1265 + this.xmlBrush = xmlBrush;
  1266 +
  1267 + if (scriptBrush.htmlScript == null)
  1268 + {
  1269 + sh.utils.alert(sh.config.strings.brushNotHtmlScript + scriptBrushName);
  1270 + return;
  1271 + }
  1272 +
  1273 + xmlBrush.regexList.push(
  1274 + { regex: scriptBrush.htmlScript.code, func: process }
  1275 + );
  1276 +
  1277 + function offsetMatches(matches, offset)
  1278 + {
  1279 + for (var j = 0; j < matches.length; j++)
  1280 + matches[j].index += offset;
  1281 + }
  1282 +
  1283 + function process(match, info)
  1284 + {
  1285 + var code = match.code,
  1286 + matches = [],
  1287 + regexList = scriptBrush.regexList,
  1288 + offset = match.index + match.left.length,
  1289 + htmlScript = scriptBrush.htmlScript,
  1290 + result
  1291 + ;
  1292 +
  1293 + // add all matches from the code
  1294 + for (var i = 0; i < regexList.length; i++)
  1295 + {
  1296 + result = sh.utils.getMatches(code, regexList[i]);
  1297 + offsetMatches(result, offset);
  1298 + matches = matches.concat(result);
  1299 + }
  1300 +
  1301 + // add left script bracket
  1302 + if (htmlScript.left != null && match.left != null)
  1303 + {
  1304 + result = sh.utils.getMatches(match.left, htmlScript.left);
  1305 + offsetMatches(result, match.index);
  1306 + matches = matches.concat(result);
  1307 + }
  1308 +
  1309 + // add right script bracket
  1310 + if (htmlScript.right != null && match.right != null)
  1311 + {
  1312 + result = sh.utils.getMatches(match.right, htmlScript.right);
  1313 + offsetMatches(result, match.index + match[0].lastIndexOf(match.right));
  1314 + matches = matches.concat(result);
  1315 + }
  1316 +
  1317 + for (var j = 0; j < matches.length; j++)
  1318 + matches[j].brushName = brushClass.name;
  1319 +
  1320 + return matches;
  1321 + }
  1322 +};
  1323 +
  1324 +sh.HtmlScript.prototype.highlight = function(code, params)
  1325 +{
  1326 + this.xmlBrush.highlight(code, params);
  1327 + this.div = this.xmlBrush.div;
  1328 +}
  1329 +
  1330 +/**
  1331 + * Main Highlither class.
  1332 + * @constructor
  1333 + */
  1334 +sh.Highlighter = function()
  1335 +{
  1336 +};
  1337 +
  1338 +sh.Highlighter.prototype = {
  1339 + /**
  1340 + * Returns value of the parameter passed to the highlighter.
  1341 + * @param {String} name Name of the parameter.
  1342 + * @param {Object} defaultValue Default value.
  1343 + * @return {Object} Returns found value or default value otherwise.
  1344 + */
  1345 + getParam : function(name, defaultValue)
  1346 + {
  1347 + var result = this.params[name];
  1348 + return sh.utils.toBoolean(result == null ? defaultValue : result);
  1349 + },
  1350 +
  1351 + /**
  1352 + * Shortcut to document.createElement().
  1353 + * @param {String} name Name of the element to create (DIV, A, etc).
  1354 + * @return {HTMLElement} Returns new HTML element.
  1355 + */
  1356 + create: function(name)
  1357 + {
  1358 + return document.createElement(name);
  1359 + },
  1360 +
  1361 + /**
  1362 + * Applies all regular expression to the code and stores all found
  1363 + * matches in the `this.matches` array.
  1364 + * @param {Array} regexList List of regular expressions.
  1365 + * @param {String} code Source code.
  1366 + * @return {Array} Returns list of matches.
  1367 + */
  1368 + findMatches: function(regexList, code)
  1369 + {
  1370 + var result = [];
  1371 +
  1372 + if (regexList != null)
  1373 + for (var i = 0; i < regexList.length; i++)
  1374 + // BUG: length returns len+1 for array if methods added to prototype chain (oising@gmail.com)
  1375 + if (typeof (regexList[i]) == "object")
  1376 + result = result.concat(sh.utils.getMatches(code, regexList[i]));
  1377 +
  1378 + // sort the matches
  1379 + return result.sort(sh.utils.matchesSortCallback);
  1380 + },
  1381 +
  1382 + /**
  1383 + * Checks to see if any of the matches are inside of other matches.
  1384 + * This process would get rid of highligted strings inside comments,
  1385 + * keywords inside strings and so on.
  1386 + */
  1387 + removeNestedMatches: function()
  1388 + {
  1389 + var matches = this.matches;
  1390 +
  1391 + // Optimized by Jose Prado (http://joseprado.com)
  1392 + for (var i = 0; i < matches.length; i++)
  1393 + {
  1394 + if (matches[i] === null)
  1395 + continue;
  1396 +
  1397 + var itemI = matches[i],
  1398 + itemIEndPos = itemI.index + itemI.length
  1399 + ;
  1400 +
  1401 + for (var j = i + 1; j < matches.length && matches[i] !== null; j++)
  1402 + {
  1403 + var itemJ = matches[j];
  1404 +
  1405 + if (itemJ === null)
  1406 + continue;
  1407 + else if (itemJ.index > itemIEndPos)
  1408 + break;
  1409 + else if (itemJ.index == itemI.index && itemJ.length > itemI.length)
  1410 + this.matches[i] = null;
  1411 + else if (itemJ.index >= itemI.index && itemJ.index < itemIEndPos)
  1412 + this.matches[j] = null;
  1413 + }
  1414 + }
  1415 + },
  1416 +
  1417 + /**
  1418 + * Splits block of text into individual DIV lines.
  1419 + * @param {String} code Code to highlight.
  1420 + * @return {String} Returns highlighted code in HTML form.
  1421 + */
  1422 + createDisplayLines : function(code)
  1423 + {
  1424 + var lines = code.split(/\n/g),
  1425 + firstLine = parseInt(this.getParam('first-line')),
  1426 + padLength = this.getParam('pad-line-numbers'),
  1427 + highlightedLines = this.getParam('highlight', []),
  1428 + hasGutter = this.getParam('gutter')
  1429 + ;
  1430 +
  1431 + code = '';
  1432 +
  1433 + if (padLength == true)
  1434 + padLength = (firstLine + lines.length - 1).toString().length;
  1435 + else if (isNaN(padLength) == true)
  1436 + padLength = 0;
  1437 +
  1438 + for (var i = 0; i < lines.length; i++)
  1439 + {
  1440 + var line = lines[i],
  1441 + indent = /^(&nbsp;|\s)+/.exec(line),
  1442 + lineClass = 'alt' + (i % 2 == 0 ? 1 : 2),
  1443 + lineNumber = sh.utils.padNumber(firstLine + i, padLength),
  1444 + highlighted = sh.utils.indexOf(highlightedLines, (firstLine + i).toString()) != -1,
  1445 + spaces = null
  1446 + ;
  1447 +
  1448 + if (indent != null)
  1449 + {
  1450 + spaces = indent[0].toString();
  1451 + line = line.substr(spaces.length);
  1452 + }
  1453 +
  1454 + line = sh.utils.trim(line);
  1455 +
  1456 + if (line.length == 0)
  1457 + line = '&nbsp;';
  1458 +
  1459 + if (highlighted)
  1460 + lineClass += ' highlighted';
  1461 +
  1462 + code +=
  1463 + '<div class="line ' + lineClass + '">'
  1464 + + '<table>'
  1465 + + '<tr>'
  1466 + + (hasGutter ? '<td class="number"><code>' + lineNumber + '</code></td>' : '')
  1467 + + '<td class="content">'
  1468 + + (spaces != null ? '<code class="spaces">' + spaces.replace(' ', '&nbsp;') + '</code>' : '')
  1469 + + line
  1470 + + '</td>'
  1471 + + '</tr>'
  1472 + + '</table>'
  1473 + + '</div>'
  1474 + ;
  1475 + }
  1476 +
  1477 + return code;
  1478 + },
  1479 +
  1480 + /**
  1481 + * Finds all matches in the source code.
  1482 + * @param {String} code Source code to process matches in.
  1483 + * @param {Array} matches Discovered regex matches.
  1484 + * @return {String} Returns formatted HTML with processed mathes.
  1485 + */
  1486 + processMatches: function(code, matches)
  1487 + {
  1488 + var pos = 0,
  1489 + result = '',
  1490 + decorate = sh.utils.decorate, // make an alias to save some bytes
  1491 + brushName = this.getParam('brush-name', '')
  1492 + ;
  1493 +
  1494 + function getBrushNameCss(match)
  1495 + {
  1496 + var result = match ? (match.brushName || brushName) : brushName;
  1497 + return result ? result + ' ' : '';
  1498 + };
  1499 +
  1500 + // Finally, go through the final list of matches and pull the all
  1501 + // together adding everything in between that isn't a match.
  1502 + for (var i = 0; i < matches.length; i++)
  1503 + {
  1504 + var match = matches[i],
  1505 + matchBrushName
  1506 + ;
  1507 +
  1508 + if (match === null || match.length === 0)
  1509 + continue;
  1510 +
  1511 + matchBrushName = getBrushNameCss(match);
  1512 +
  1513 + result += decorate(code.substr(pos, match.index - pos), matchBrushName + 'plain')
  1514 + + decorate(match.value, matchBrushName + match.css)
  1515 + ;
  1516 +
  1517 + pos = match.index + match.length;
  1518 + }
  1519 +
  1520 + // don't forget to add whatever's remaining in the string
  1521 + result += decorate(code.substr(pos), getBrushNameCss() + 'plain');
  1522 +
  1523 + return result;
  1524 + },
  1525 +
  1526 + /**
  1527 + * Highlights the code and returns complete HTML.
  1528 + * @param {String} code Code to highlight.
  1529 + * @param {Object} params Parameters object.
  1530 + */
  1531 + highlight: function(code, params)
  1532 + {
  1533 + // using variables for shortcuts because JS compressor will shorten local variable names
  1534 + var conf = sh.config,
  1535 + vars = sh.vars,
  1536 + div,
  1537 + divClassName,
  1538 + tabSize,
  1539 + important = 'important'
  1540 + ;
  1541 +
  1542 + this.params = {};
  1543 + this.div = null;
  1544 + this.lines = null;
  1545 + this.code = null;
  1546 + this.bar = null;
  1547 + this.toolbarCommands = {};
  1548 + this.id = sh.utils.guid('highlighter_');
  1549 +
  1550 + // register this instance in the highlighters list
  1551 + vars.highlighters[this.id] = this;
  1552 +
  1553 + if (code === null)
  1554 + code = '';
  1555 +
  1556 + // local params take precedence over defaults
  1557 + this.params = sh.utils.merge(sh.defaults, params || {});
  1558 +
  1559 + // process light mode
  1560 + if (this.getParam('light') == true)
  1561 + this.params.toolbar = this.params.gutter = false;
  1562 +
  1563 + this.div = div = this.create('DIV');
  1564 + this.lines = this.create('DIV');
  1565 + this.lines.className = 'lines';
  1566 +
  1567 + className = 'syntaxhighlighter';
  1568 + div.id = this.id;
  1569 +
  1570 + // make collapsed
  1571 + if (this.getParam('collapse'))
  1572 + className += ' collapsed';
  1573 +
  1574 + // disable gutter
  1575 + if (this.getParam('gutter') == false)
  1576 + className += ' nogutter';
  1577 +
  1578 + // disable line wrapping
  1579 + if (this.getParam('wrap-lines') == false)
  1580 + this.lines.className += ' no-wrap';
  1581 +
  1582 + // add custom user style name
  1583 + className += ' ' + this.getParam('class-name');
  1584 +
  1585 + // add brush alias to the class name for custom CSS
  1586 + className += ' ' + this.getParam('brush-name');
  1587 +
  1588 + div.className = className;
  1589 +
  1590 + this.originalCode = code;
  1591 + this.code = sh.utils.trimFirstAndLastLines(code)
  1592 + .replace(/\r/g, ' ') // IE lets these buggers through
  1593 + ;
  1594 +
  1595 + tabSize = this.getParam('tab-size');
  1596 +
  1597 + // replace tabs with spaces
  1598 + this.code = this.getParam('smart-tabs') == true
  1599 + ? sh.utils.processSmartTabs(this.code, tabSize)
  1600 + : sh.utils.processTabs(this.code, tabSize)
  1601 + ;
  1602 +
  1603 + this.code = sh.utils.unindent(this.code);
  1604 +
  1605 + // add controls toolbar
  1606 + if (this.getParam('toolbar'))
  1607 + {
  1608 + this.bar = this.create('DIV');
  1609 + this.bar.className = 'bar';
  1610 + this.bar.appendChild(sh.toolbar.create(this));
  1611 + div.appendChild(this.bar);
  1612 +
  1613 + // set up toolbar rollover
  1614 + var bar = this.bar;
  1615 + function hide() { bar.className = bar.className.replace('show', ''); }
  1616 + div.onmouseover = function() { hide(); bar.className += ' show'; };
  1617 + div.onmouseout = function() { hide(); }
  1618 + }
  1619 +
  1620 + div.appendChild(this.lines);
  1621 +
  1622 + this.matches = this.findMatches(this.regexList, this.code);
  1623 + this.removeNestedMatches();
  1624 +
  1625 + code = this.processMatches(this.code, this.matches);
  1626 +
  1627 + // finally, split all lines so that they wrap well
  1628 + code = this.createDisplayLines(sh.utils.trim(code));
  1629 +
  1630 + // finally, process the links
  1631 + if (this.getParam('auto-links'))
  1632 + code = sh.utils.processUrls(code);
  1633 +
  1634 + this.lines.innerHTML = code;
  1635 + },
  1636 +
  1637 + /**
  1638 + * Converts space separated list of keywords into a regular expression string.
  1639 + * @param {String} str Space separated keywords.
  1640 + * @return {String} Returns regular expression string.
  1641 + */
  1642 + getKeywords: function(str)
  1643 + {
  1644 + str = str
  1645 + .replace(/^\s+|\s+$/g, '')
  1646 + .replace(/\s+/g, '|')
  1647 + ;
  1648 +
  1649 + return '\\b(?:' + str + ')\\b';
  1650 + },
  1651 +
  1652 + /**
  1653 + * Makes a brush compatible with the `html-script` functionality.
  1654 + * @param {Object} regexGroup Object containing `left` and `right` regular expressions.
  1655 + */
  1656 + forHtmlScript: function(regexGroup)
  1657 + {
  1658 + this.htmlScript = {
  1659 + left : { regex: regexGroup.left, css: 'script' },
  1660 + right : { regex: regexGroup.right, css: 'script' },
  1661 + code : new XRegExp(
  1662 + "(?<left>" + regexGroup.left.source + ")" +
  1663 + "(?<code>.*?)" +
  1664 + "(?<right>" + regexGroup.right.source + ")",
  1665 + "sgi"
  1666 + )
  1667 + };
  1668 + }
  1669 +}; // end of Highlighter
  1670 +
  1671 +return sh;
  1672 +}(); // end of anonymous function
  1673 +
  1674 +
  1675 +/**
  1676 + * XRegExp 0.6.1
  1677 + * (c) 2007-2008 Steven Levithan
  1678 + * <http://stevenlevithan.com/regex/xregexp/>
  1679 + * MIT License
  1680 + *
  1681 + * provides an augmented, cross-browser implementation of regular expressions
  1682 + * including support for additional modifiers and syntax. several convenience
  1683 + * methods and a recursive-construct parser are also included.
  1684 + */
  1685 +
  1686 +// prevent running twice, which would break references to native globals
  1687 +if (!window.XRegExp) {
  1688 +// anonymous function to avoid global variables
  1689 +(function () {
  1690 +// copy various native globals for reference. can't use the name ``native``
  1691 +// because it's a reserved JavaScript keyword.
  1692 +var real = {
  1693 + exec: RegExp.prototype.exec,
  1694 + match: String.prototype.match,
  1695 + replace: String.prototype.replace,
  1696 + split: String.prototype.split
  1697 + },
  1698 + /* regex syntax parsing with support for all the necessary cross-
  1699 + browser and context issues (escapings, character classes, etc.) */
  1700 + lib = {
  1701 + part: /(?:[^\\([#\s.]+|\\(?!k<[\w$]+>|[pP]{[^}]+})[\S\s]?|\((?=\?(?!#|<[\w$]+>)))+|(\()(?:\?(?:(#)[^)]*\)|<([$\w]+)>))?|\\(?:k<([\w$]+)>|[pP]{([^}]+)})|(\[\^?)|([\S\s])/g,
  1702 + replaceVar: /(?:[^$]+|\$(?![1-9$&`']|{[$\w]+}))+|\$(?:([1-9]\d*|[$&`'])|{([$\w]+)})/g,
  1703 + extended: /^(?:\s+|#.*)+/,
  1704 + quantifier: /^(?:[?*+]|{\d+(?:,\d*)?})/,
  1705 + classLeft: /&&\[\^?/g,
  1706 + classRight: /]/g
  1707 + },
  1708 + indexOf = function (array, item, from) {
  1709 + for (var i = from || 0; i < array.length; i++)
  1710 + if (array[i] === item) return i;
  1711 + return -1;
  1712 + },
  1713 + brokenExecUndef = /()??/.exec("")[1] !== undefined,
  1714 + plugins = {};
  1715 +
  1716 +/**
  1717 + * Accepts a pattern and flags, returns a new, extended RegExp object.
  1718 + * differs from a native regex in that additional flags and syntax are
  1719 + * supported and browser inconsistencies are ameliorated.
  1720 + * @ignore
  1721 + */
  1722 +XRegExp = function (pattern, flags) {
  1723 + if (pattern instanceof RegExp) {
  1724 + if (flags !== undefined)
  1725 + throw TypeError("can't supply flags when constructing one RegExp from another");
  1726 + return pattern.addFlags(); // new copy
  1727 + }
  1728 +
  1729 + var flags = flags || "",
  1730 + singleline = flags.indexOf("s") > -1,
  1731 + extended = flags.indexOf("x") > -1,
  1732 + hasNamedCapture = false,
  1733 + captureNames = [],
  1734 + output = [],
  1735 + part = lib.part,
  1736 + match, cc, len, index, regex;
  1737 +
  1738 + part.lastIndex = 0; // in case the last XRegExp compilation threw an error (unbalanced character class)
  1739 +
  1740 + while (match = real.exec.call(part, pattern)) {
  1741 + // comment pattern. this check must come before the capturing group check,
  1742 + // because both match[1] and match[2] will be non-empty.
  1743 + if (match[2]) {
  1744 + // keep tokens separated unless the following token is a quantifier
  1745 + if (!lib.quantifier.test(pattern.slice(part.lastIndex)))
  1746 + output.push("(?:)");
  1747 + // capturing group
  1748 + } else if (match[1]) {
  1749 + captureNames.push(match[3] || null);
  1750 + if (match[3])
  1751 + hasNamedCapture = true;
  1752 + output.push("(");
  1753 + // named backreference
  1754 + } else if (match[4]) {
  1755 + index = indexOf(captureNames, match[4]);
  1756 + // keep backreferences separate from subsequent literal numbers
  1757 + // preserve backreferences to named groups that are undefined at this point as literal strings
  1758 + output.push(index > -1 ?
  1759 + "\\" + (index + 1) + (isNaN(pattern.charAt(part.lastIndex)) ? "" : "(?:)") :
  1760 + match[0]
  1761 + );
  1762 + // unicode element (requires plugin)
  1763 + } else if (match[5]) {
  1764 + output.push(plugins.unicode ?
  1765 + plugins.unicode.get(match[5], match[0].charAt(1) === "P") :
  1766 + match[0]
  1767 + );
  1768 + // character class opening delimiter ("[" or "[^")
  1769 + // (non-native unicode elements are not supported within character classes)
  1770 + } else if (match[6]) {
  1771 + if (pattern.charAt(part.lastIndex) === "]") {
  1772 + // for cross-browser compatibility with ECMA-262 v3 behavior,
  1773 + // convert [] to (?!) and [^] to [\S\s].
  1774 + output.push(match[6] === "[" ? "(?!)" : "[\\S\\s]");
  1775 + part.lastIndex++;
  1776 + } else {
  1777 + // parse the character class with support for inner escapes and
  1778 + // ES4's infinitely nesting intersection syntax ([&&[^&&[]]]).
  1779 + cc = XRegExp.matchRecursive("&&" + pattern.slice(match.index), lib.classLeft, lib.classRight, "", {escapeChar: "\\"})[0];
  1780 + output.push(match[6] + cc + "]");
  1781 + part.lastIndex += cc.length + 1;
  1782 + }
  1783 + // dot ("."), pound sign ("#"), or whitespace character
  1784 + } else if (match[7]) {
  1785 + if (singleline && match[7] === ".") {
  1786 + output.push("[\\S\\s]");
  1787 + } else if (extended && lib.extended.test(match[7])) {
  1788 + len = real.exec.call(lib.extended, pattern.slice(part.lastIndex - 1))[0].length;
  1789 + // keep tokens separated unless the following token is a quantifier
  1790 + if (!lib.quantifier.test(pattern.slice(part.lastIndex - 1 + len)))
  1791 + output.push("(?:)");
  1792 + part.lastIndex += len - 1;
  1793 + } else {
  1794 + output.push(match[7]);
  1795 + }
  1796 + } else {
  1797 + output.push(match[0]);
  1798 + }
  1799 + }
  1800 +
  1801 + regex = RegExp(output.join(""), real.replace.call(flags, /[sx]+/g, ""));
  1802 + regex._x = {
  1803 + source: pattern,
  1804 + captureNames: hasNamedCapture ? captureNames : null
  1805 + };
  1806 + return regex;
  1807 +};
  1808 +
  1809 +/**
  1810 + * Barebones plugin support for now (intentionally undocumented)
  1811 + * @ignore
  1812 + * @param {Object} name
  1813 + * @param {Object} o
  1814 + */
  1815 +XRegExp.addPlugin = function (name, o) {
  1816 + plugins[name] = o;
  1817 +};
  1818 +
  1819 +/**
  1820 + * Adds named capture support, with values returned as ``result.name``.
  1821 + *
  1822 + * Also fixes two cross-browser issues, following the ECMA-262 v3 spec:
  1823 + * - captured values for non-participating capturing groups should be returned
  1824 + * as ``undefined``, rather than the empty string.
  1825 + * - the regex's ``lastIndex`` should not be incremented after zero-length
  1826 + * matches.
  1827 + * @ignore
  1828 + */
  1829 +RegExp.prototype.exec = function (str) {
  1830 + var match = real.exec.call(this, str),
  1831 + name, i, r2;
  1832 + if (match) {
  1833 + // fix browsers whose exec methods don't consistently return
  1834 + // undefined for non-participating capturing groups
  1835 + if (brokenExecUndef && match.length > 1) {
  1836 + // r2 doesn't need /g or /y, but they shouldn't hurt
  1837 + r2 = new RegExp("^" + this.source + "$(?!\\s)", this.getNativeFlags());
  1838 + real.replace.call(match[0], r2, function () {
  1839 + for (i = 1; i < arguments.length - 2; i++) {
  1840 + if (arguments[i] === undefined) match[i] = undefined;
  1841 + }
  1842 + });
  1843 + }
  1844 + // attach named capture properties
  1845 + if (this._x && this._x.captureNames) {
  1846 + for (i = 1; i < match.length; i++) {
  1847 + name = this._x.captureNames[i - 1];
  1848 + if (name) match[name] = match[i];
  1849 + }
  1850 + }
  1851 + // fix browsers that increment lastIndex after zero-length matches
  1852 + if (this.global && this.lastIndex > (match.index + match[0].length))
  1853 + this.lastIndex--;
  1854 + }
  1855 + return match;
  1856 +};
  1857 +})(); // end anonymous function
  1858 +} // end if(!window.XRegExp)
  1859 +
  1860 +/**
  1861 + * intentionally undocumented
  1862 + * @ignore
  1863 + */
  1864 +RegExp.prototype.getNativeFlags = function () {
  1865 + return (this.global ? "g" : "") +
  1866 + (this.ignoreCase ? "i" : "") +
  1867 + (this.multiline ? "m" : "") +
  1868 + (this.extended ? "x" : "") +
  1869 + (this.sticky ? "y" : "");
  1870 +};
  1871 +
  1872 +/**
  1873 + * Accepts flags; returns a new XRegExp object generated by recompiling
  1874 + * the regex with the additional flags (may include non-native flags).
  1875 + * The original regex object is not altered.
  1876 + * @ignore
  1877 + */
  1878 +RegExp.prototype.addFlags = function (flags) {
  1879 + var regex = new XRegExp(this.source, (flags || "") + this.getNativeFlags());
  1880 + if (this._x) {
  1881 + regex._x = {
  1882 + source: this._x.source,
  1883 + captureNames: this._x.captureNames ? this._x.captureNames.slice(0) : null
  1884 + };
  1885 + }
  1886 + return regex;
  1887 +};
  1888 +
  1889 +/**
  1890 + * Accepts a context object and string; returns the result of calling
  1891 + * ``exec`` with the provided string. the context is ignored but is
  1892 + * accepted for congruity with ``Function.prototype.call``.
  1893 + * @ignore
  1894 + */
  1895 +RegExp.prototype.call = function (context, str) {
  1896 + return this.exec(str);
  1897 +};
  1898 +
  1899 +/**
  1900 + * Accepts a context object and arguments array; returns the result of
  1901 + * calling ``exec`` with the first value in the arguments array. the context
  1902 + * is ignored but is accepted for congruity with ``Function.prototype.apply``.
  1903 + * @ignore
  1904 + */
  1905 +RegExp.prototype.apply = function (context, args) {
  1906 + return this.exec(args[0]);
  1907 +};
  1908 +
  1909 +/**
  1910 + * Accepts a pattern and flags; returns an XRegExp object. if the pattern
  1911 + * and flag combination has previously been cached, the cached copy is
  1912 + * returned, otherwise the new object is cached.
  1913 + * @ignore
  1914 + */
  1915 +XRegExp.cache = function (pattern, flags) {
  1916 + var key = "/" + pattern + "/" + (flags || "");
  1917 + return XRegExp.cache[key] || (XRegExp.cache[key] = new XRegExp(pattern, flags));
  1918 +};
  1919 +
  1920 +/**
  1921 + * Accepts a string; returns the string with regex metacharacters escaped.
  1922 + * the returned string can safely be used within a regex to match a literal
  1923 + * string. escaped characters are [, ], {, }, (, ), -, *, +, ?, ., \, ^, $,
  1924 + * |, #, [comma], and whitespace.
  1925 + * @ignore
  1926 + */
  1927 +XRegExp.escape = function (str) {
  1928 + return str.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&");
  1929 +};
  1930 +
  1931 +/**
  1932 + * Accepts a string to search, left and right delimiters as regex pattern
  1933 + * strings, optional regex flags (may include non-native s, x, and y flags),
  1934 + * and an options object which allows setting an escape character and changing
  1935 + * the return format from an array of matches to a two-dimensional array of
  1936 + * string parts with extended position data. returns an array of matches
  1937 + * (optionally with extended data), allowing nested instances of left and right
  1938 + * delimiters. use the g flag to return all matches, otherwise only the first
  1939 + * is returned. if delimiters are unbalanced within the subject data, an error
  1940 + * is thrown.
  1941 + *
  1942 + * This function admittedly pushes the boundaries of what can be accomplished
  1943 + * sensibly without a "real" parser. however, by doing so it provides flexible
  1944 + * and powerful recursive parsing capabilities with minimal code weight.
  1945 + *
  1946 + * Warning: the ``escapeChar`` option is considered experimental and might be
  1947 + * changed or removed in future versions of XRegExp.
  1948 + *
  1949 + * unsupported features:
  1950 + * - backreferences within delimiter patterns when using ``escapeChar``.
  1951 + * - although providing delimiters as regex objects adds the minor feature of
  1952 + * independent delimiter flags, it introduces other limitations and is only
  1953 + * intended to be done by the ``XRegExp`` constructor (which can't call
  1954 + * itself while building a regex).
  1955 + *
  1956 + * @ignore
  1957 + */
  1958 +XRegExp.matchRecursive = function (str, left, right, flags, options) {
  1959 + var options = options || {},
  1960 + escapeChar = options.escapeChar,
  1961 + vN = options.valueNames,
  1962 + flags = flags || "",
  1963 + global = flags.indexOf("g") > -1,
  1964 + ignoreCase = flags.indexOf("i") > -1,
  1965 + multiline = flags.indexOf("m") > -1,
  1966 + sticky = flags.indexOf("y") > -1,
  1967 + /* sticky mode has its own handling in this function, which means you
  1968 + can use flag "y" even in browsers which don't support it natively */
  1969 + flags = flags.replace(/y/g, ""),
  1970 + left = left instanceof RegExp ? (left.global ? left : left.addFlags("g")) : new XRegExp(left, "g" + flags),
  1971 + right = right instanceof RegExp ? (right.global ? right : right.addFlags("g")) : new XRegExp(right, "g" + flags),
  1972 + output = [],
  1973 + openTokens = 0,
  1974 + delimStart = 0,
  1975 + delimEnd = 0,
  1976 + lastOuterEnd = 0,
  1977 + outerStart, innerStart, leftMatch, rightMatch, escaped, esc;
  1978 +
  1979 + if (escapeChar) {
  1980 + if (escapeChar.length > 1) throw SyntaxError("can't supply more than one escape character");
  1981 + if (multiline) throw TypeError("can't supply escape character when using the multiline flag");
  1982 + escaped = XRegExp.escape(escapeChar);
  1983 + /* Escape pattern modifiers:
  1984 + /g - not needed here
  1985 + /i - included
  1986 + /m - **unsupported**, throws error
  1987 + /s - handled by XRegExp when delimiters are provided as strings
  1988 + /x - handled by XRegExp when delimiters are provided as strings
  1989 + /y - not needed here; supported by other handling in this function
  1990 + */
  1991 + esc = new RegExp(
  1992 + "^(?:" + escaped + "[\\S\\s]|(?:(?!" + left.source + "|" + right.source + ")[^" + escaped + "])+)+",
  1993 + ignoreCase ? "i" : ""
  1994 + );
  1995 + }
  1996 +
  1997 + while (true) {
  1998 + /* advance the starting search position to the end of the last delimiter match.
  1999 + a couple special cases are also covered:
  2000 + - if using an escape character, advance to the next delimiter's starting position,
  2001 + skipping any escaped characters
  2002 + - first time through, reset lastIndex in case delimiters were provided as regexes
  2003 + */
  2004 + left.lastIndex = right.lastIndex = delimEnd +
  2005 + (escapeChar ? (esc.exec(str.slice(delimEnd)) || [""])[0].length : 0);
  2006 +
  2007 + leftMatch = left.exec(str);
  2008 + rightMatch = right.exec(str);
  2009 +
  2010 + // only keep the result which matched earlier in the string
  2011 + if (leftMatch && rightMatch) {
  2012 + if (leftMatch.index <= rightMatch.index)
  2013 + rightMatch = null;
  2014 + else leftMatch = null;
  2015 + }
  2016 +
  2017 + /* paths*:
  2018 + leftMatch | rightMatch | openTokens | result
  2019 + 1 | 0 | 1 | ...
  2020 + 1 | 0 | 0 | ...
  2021 + 0 | 1 | 1 | ...
  2022 + 0 | 1 | 0 | throw
  2023 + 0 | 0 | 1 | throw
  2024 + 0 | 0 | 0 | break
  2025 + * - does not include the sticky mode special case
  2026 + - the loop ends after the first completed match if not in global mode
  2027 + */
  2028 +
  2029 + if (leftMatch || rightMatch) {
  2030 + delimStart = (leftMatch || rightMatch).index;
  2031 + delimEnd = (leftMatch ? left : right).lastIndex;
  2032 + } else if (!openTokens) {
  2033 + break;
  2034 + }
  2035 +
  2036 + if (sticky && !openTokens && delimStart > lastOuterEnd)
  2037 + break;
  2038 +
  2039 + if (leftMatch) {
  2040 + if (!openTokens++) {
  2041 + outerStart = delimStart;
  2042 + innerStart = delimEnd;
  2043 + }
  2044 + } else if (rightMatch && openTokens) {
  2045 + if (!--openTokens) {
  2046 + if (vN) {
  2047 + if (vN[0] && outerStart > lastOuterEnd)
  2048 + output.push([vN[0], str.slice(lastOuterEnd, outerStart), lastOuterEnd, outerStart]);
  2049 + if (vN[1]) output.push([vN[1], str.slice(outerStart, innerStart), outerStart, innerStart]);
  2050 + if (vN[2]) output.push([vN[2], str.slice(innerStart, delimStart), innerStart, delimStart]);
  2051 + if (vN[3]) output.push([vN[3], str.slice(delimStart, delimEnd), delimStart, delimEnd]);
  2052 + } else {
  2053 + output.push(str.slice(innerStart, delimStart));
  2054 + }
  2055 + lastOuterEnd = delimEnd;
  2056 + if (!global)
  2057 + break;
  2058 + }
  2059 + } else {
  2060 + // reset lastIndex in case delimiters were provided as regexes
  2061 + left.lastIndex = right.lastIndex = 0;
  2062 + throw Error("subject data contains unbalanced delimiters");
  2063 + }
  2064 +
  2065 + // if the delimiter matched an empty string, advance delimEnd to avoid an infinite loop
  2066 + if (delimStart === delimEnd)
  2067 + delimEnd++;
  2068 + }
  2069 +
  2070 + if (global && !sticky && vN && vN[0] && str.length > lastOuterEnd)
  2071 + output.push([vN[0], str.slice(lastOuterEnd), lastOuterEnd, str.length]);
  2072 +
  2073 + // reset lastIndex in case delimiters were provided as regexes
  2074 + left.lastIndex = right.lastIndex = 0;
  2075 +
  2076 + return output;
  2077 +};
  2078 +/**
  2079 + * SyntaxHighlighter
  2080 + * http://alexgorbatchev.com/
  2081 + *
  2082 + * SyntaxHighlighter is donationware. If you are using it, please donate.
  2083 + * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
  2084 + *
  2085 + * @version
  2086 + * 2.0.320 (May 03 2009)
  2087 + *
  2088 + * @copyright
  2089 + * Copyright (C) 2004-2009 Alex Gorbatchev.
  2090 + *
  2091 + * @license
  2092 + * This file is part of SyntaxHighlighter.
  2093 + *
  2094 + * SyntaxHighlighter is free software: you can redistribute it and/or modify
  2095 + * it under the terms of the GNU Lesser General Public License as published by
  2096 + * the Free Software Foundation, either version 3 of the License, or
  2097 + * (at your option) any later version.
  2098 + *
  2099 + * SyntaxHighlighter is distributed in the hope that it will be useful,
  2100 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2101 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2102 + * GNU General Public License for more details.
  2103 + *
  2104 + * You should have received a copy of the GNU General Public License
  2105 + * along with SyntaxHighlighter. If not, see <http://www.gnu.org/copyleft/lesser.html>.
  2106 + */
  2107 +SyntaxHighlighter.brushes.Xml = function()
  2108 +{
  2109 + function process(match, regexInfo)
  2110 + {
  2111 + var constructor = SyntaxHighlighter.Match,
  2112 + code = match[0],
  2113 + tag = new XRegExp('(&lt;|<)[\\s\\/\\?]*(?<name>[:\\w-\\.]+)', 'xg').exec(code),
  2114 + result = []
  2115 + ;
  2116 +
  2117 + if (match.attributes != null)
  2118 + {
  2119 + var attributes,
  2120 + regex = new XRegExp('(?<name> [\\w:\\-\\.]+)' +
  2121 + '\\s*=\\s*' +
  2122 + '(?<value> ".*?"|\'.*?\'|\\w+)',
  2123 + 'xg');
  2124 +
  2125 + while ((attributes = regex.exec(code)) != null)
  2126 + {
  2127 + result.push(new constructor(attributes.name, match.index + attributes.index, 'color1'));
  2128 + result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string'));
  2129 + }
  2130 + }
  2131 +
  2132 + if (tag != null)
  2133 + result.push(
  2134 + new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword')
  2135 + );
  2136 +
  2137 + return result;
  2138 + }
  2139 +
  2140 + this.regexList = [
  2141 + { regex: new XRegExp('(\\&lt;|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\&gt;|>)', 'gm'), css: 'color2' }, // <![ ... [ ... ]]>
  2142 + { regex: new XRegExp('(\\&lt;|<)!--\\s*.*?\\s*--(\\&gt;|>)', 'gm'), css: 'comments' }, // <!-- ... -->
  2143 + { regex: new XRegExp('(&lt;|<)[\\s\\/\\?]*(\\w+)(?<attributes>.*?)[\\s\\/\\?]*(&gt;|>)', 'sg'), func: process }
  2144 + ];
  2145 +};
  2146 +
  2147 +SyntaxHighlighter.brushes.Xml.prototype = new SyntaxHighlighter.Highlighter();
  2148 +SyntaxHighlighter.brushes.Xml.aliases = ['xml', 'xhtml', 'xslt', 'html', 'xhtml'];
  2149 +/**
  2150 + * SyntaxHighlighter
  2151 + * http://alexgorbatchev.com/
  2152 + *
  2153 + * SyntaxHighlighter is donationware. If you are using it, please donate.
  2154 + * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
  2155 + *
  2156 + * @version
  2157 + * 2.0.320 (May 03 2009)
  2158 + *
  2159 + * @copyright
  2160 + * Copyright (C) 2004-2009 Alex Gorbatchev.
  2161 + *
  2162 + * @license
  2163 + * This file is part of SyntaxHighlighter.
  2164 + *
  2165 + * SyntaxHighlighter is free software: you can redistribute it and/or modify
  2166 + * it under the terms of the GNU Lesser General Public License as published by
  2167 + * the Free Software Foundation, either version 3 of the License, or
  2168 + * (at your option) any later version.
  2169 + *
  2170 + * SyntaxHighlighter is distributed in the hope that it will be useful,
  2171 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2172 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2173 + * GNU General Public License for more details.
  2174 + *
  2175 + * You should have received a copy of the GNU General Public License
  2176 + * along with SyntaxHighlighter. If not, see <http://www.gnu.org/copyleft/lesser.html>.
  2177 + */
  2178 +SyntaxHighlighter.brushes.JScript = function()
  2179 +{
  2180 + var keywords = 'break case catch continue ' +
  2181 + 'default delete do else false ' +
  2182 + 'for function if in instanceof ' +
  2183 + 'new null return super switch ' +
  2184 + 'this throw true try typeof var while with'
  2185 + ;
  2186 +
  2187 + this.regexList = [
  2188 + { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments
  2189 + { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
  2190 + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
  2191 + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
  2192 + { regex: /\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion
  2193 + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keywords
  2194 + ];
  2195 +
  2196 + this.forHtmlScript(SyntaxHighlighter.regexLib.scriptScriptTags);
  2197 +};
  2198 +
  2199 +SyntaxHighlighter.brushes.JScript.prototype = new SyntaxHighlighter.Highlighter();
  2200 +SyntaxHighlighter.brushes.JScript.aliases = ['js', 'jscript', 'javascript'];
  2201 +
  2202 +
  2203 +SyntaxHighlighter.config.clipboardSwf = 'syntax/clipboard.swf';
  2204 +$(function () {
  2205 + var divs = $([]);
  2206 + $("#container .source").each(function () {
  2207 + var code = $(this).html().replace(/</g,'&lt;').replace(/>/g,'&gt;'),
  2208 + div = $('<div class="code"><pre class="brush:' + ( $(this).is("script") ? 'js' : 'xml' ) + ';">' + code + '</pre></div>'),
  2209 + demo = $(this).prevAll(".demo:eq(0)");
  2210 + $(this).after(div);
  2211 + if(!$(this).hasClass("below")) divs = divs.add(div);
  2212 + });
  2213 + SyntaxHighlighter.all();
  2214 +
  2215 + setTimeout((function (divs) {
  2216 + return function () {
  2217 + divs.each(function () {
  2218 + var div = $(this),
  2219 + demo = $(this).prevAll(".demo:eq(0)"),
  2220 + h = false;
  2221 + var h = Math.max(demo[0].offsetHeight, div[0].offsetHeight);
  2222 + if(h) {
  2223 + if(h < 198) h = 198;
  2224 + div.height(h);
  2225 + demo.height(h);
  2226 + }
  2227 + });
  2228 + }
  2229 + })(divs), 500);
  2230 +
  2231 + // $(".panel").hide().prev().click(function () { $(this).next().toggle(); }).css("cursor","pointer");
  2232 +});
0 2233 \ No newline at end of file
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/syntax/!style.css 0 → 100644
... ... @@ -0,0 +1,511 @@
  1 +/**
  2 + * SyntaxHighlighter
  3 + * http://alexgorbatchev.com/
  4 + *
  5 + * SyntaxHighlighter is donationware. If you are using it, please donate.
  6 + * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
  7 + *
  8 + * @version
  9 + * 2.1.364 (October 15 2009)
  10 + *
  11 + * @copyright
  12 + * Copyright (C) 2004-2009 Alex Gorbatchev.
  13 + *
  14 + * @license
  15 + * This file is part of SyntaxHighlighter.
  16 + *
  17 + * SyntaxHighlighter is free software: you can redistribute it and/or modify
  18 + * it under the terms of the GNU Lesser General Public License as published by
  19 + * the Free Software Foundation, either version 3 of the License, or
  20 + * (at your option) any later version.
  21 + *
  22 + * SyntaxHighlighter is distributed in the hope that it will be useful,
  23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25 + * GNU General Public License for more details.
  26 + *
  27 + * You should have received a copy of the GNU General Public License
  28 + * along with SyntaxHighlighter. If not, see <http://www.gnu.org/copyleft/lesser.html>.
  29 + */
  30 +.syntaxhighlighter,
  31 +.syntaxhighlighter div,
  32 +.syntaxhighlighter code,
  33 +.syntaxhighlighter table,
  34 +.syntaxhighlighter table td,
  35 +.syntaxhighlighter table tr,
  36 +.syntaxhighlighter table tbody
  37 +{
  38 + margin: 0 !important;
  39 + padding: 0 !important;
  40 + border: 0 !important;
  41 + outline: 0 !important;
  42 + background: none !important;
  43 + text-align: left !important;
  44 + float: none !important;
  45 + vertical-align: baseline !important;
  46 + position: static !important;
  47 + left: auto !important;
  48 + top: auto !important;
  49 + right: auto !important;
  50 + bottom: auto !important;
  51 + height: auto !important;
  52 + width: auto !important;
  53 + font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
  54 + font-weight: normal !important;
  55 + font-style: normal !important;
  56 + min-height: inherit !important; /* For IE8, FF & WebKit */
  57 + min-height: auto !important; /* For IE7 */
  58 +
  59 +
  60 +/*
  61 + line-height: 1.1em !important;
  62 + font-size: 1em !important;
  63 +*/
  64 +
  65 + font-size:12px !important;
  66 + line-height:18px !important;
  67 +
  68 +}
  69 +
  70 +.syntaxhighlighter
  71 +{
  72 + width: 99.9% !important; /* 99% fixes IE8 horizontal scrollbar */
  73 + margin: 1em 0 1em 0 !important;
  74 + padding: 1px !important; /* adds a little border on top and bottom */
  75 + position: relative !important;
  76 +}
  77 +
  78 +.syntaxhighlighter .bold
  79 +{
  80 + font-weight: bold !important;
  81 +}
  82 +
  83 +.syntaxhighlighter .italic
  84 +{
  85 + font-style: italic !important;
  86 +}
  87 +
  88 +.syntaxhighlighter .line
  89 +{
  90 +}
  91 +
  92 +.syntaxhighlighter .no-wrap .line .content
  93 +{
  94 + white-space: pre !important;
  95 +}
  96 +
  97 +.syntaxhighlighter .line table
  98 +{
  99 + border-collapse: collapse !important;
  100 +}
  101 +
  102 +.syntaxhighlighter .line td
  103 +{
  104 + vertical-align: top !important;
  105 +}
  106 +
  107 +.syntaxhighlighter .line .number
  108 +{
  109 + width: 3em !important;
  110 +}
  111 +
  112 +.syntaxhighlighter .line .number code
  113 +{
  114 + width: 2.7em !important;
  115 + padding-right: .3em !important;
  116 + text-align: right !important;
  117 + display: block !important;
  118 +}
  119 +
  120 +.syntaxhighlighter .line .content
  121 +{
  122 + padding-left: .5em !important;
  123 +}
  124 +
  125 +.syntaxhighlighter .line .spaces
  126 +{
  127 +}
  128 +
  129 +/* Disable border and margin on the lines when no gutter option is set */
  130 +.syntaxhighlighter.nogutter .line .content
  131 +{
  132 + border-left: none !important;
  133 +}
  134 +
  135 +.syntaxhighlighter .bar
  136 +{
  137 + display: none !important;
  138 +}
  139 +
  140 +.syntaxhighlighter .bar.show
  141 +{
  142 + display: block !important;
  143 +}
  144 +
  145 +.syntaxhighlighter.collapsed .bar
  146 +{
  147 + display: block !important;
  148 +}
  149 +
  150 +/* Adjust some properties when collapsed */
  151 +
  152 +.syntaxhighlighter.collapsed .lines
  153 +{
  154 + display: none !important;
  155 +}
  156 +
  157 +.syntaxhighlighter .lines.no-wrap
  158 +{
  159 + overflow: auto !important;
  160 + overflow-y: hidden !important;
  161 +}
  162 +
  163 +/* Styles for the toolbar */
  164 +
  165 +.syntaxhighlighter .toolbar
  166 +{
  167 + position: absolute !important;
  168 + right: 0px !important;
  169 + top: 0px !important;
  170 + font-size: 1px !important;
  171 + padding: 8px 8px 8px 0 !important; /* in px because images don't scale with ems */
  172 +}
  173 +
  174 +.syntaxhighlighter.collapsed .toolbar
  175 +{
  176 + font-size: 80% !important;
  177 + padding: .2em 0 .5em .5em !important;
  178 + position: static !important;
  179 +}
  180 +
  181 +.syntaxhighlighter .toolbar a.item,
  182 +.syntaxhighlighter .toolbar .item
  183 +{
  184 + display: block !important;
  185 + float: left !important;
  186 + margin-left: 8px !important;
  187 + background-repeat: no-repeat !important;
  188 + overflow: hidden !important;
  189 + text-indent: -5000px !important;
  190 +}
  191 +
  192 +.syntaxhighlighter.collapsed .toolbar .item
  193 +{
  194 + display: none !important;
  195 +}
  196 +
  197 +.syntaxhighlighter.collapsed .toolbar .item.expandSource
  198 +{
  199 + background-image: url(magnifier.png) !important;
  200 + display: inline !important;
  201 + text-indent: 0 !important;
  202 + width: auto !important;
  203 + float: none !important;
  204 + height: 16px !important;
  205 + padding-left: 20px !important;
  206 +}
  207 +
  208 +.syntaxhighlighter .toolbar .item.viewSource
  209 +{
  210 + background-image: url(page_white_code.png) !important;
  211 +}
  212 +
  213 +.syntaxhighlighter .toolbar .item.printSource
  214 +{
  215 + background-image: url(printer.png) !important;
  216 +}
  217 +
  218 +.syntaxhighlighter .toolbar .item.copyToClipboard
  219 +{
  220 + text-indent: 0 !important;
  221 + background: none !important;
  222 + overflow: visible !important;
  223 +}
  224 +
  225 +.syntaxhighlighter .toolbar .item.about
  226 +{
  227 + background-image: url(help.png) !important;
  228 +}
  229 +
  230 +/**
  231 + * Print view.
  232 + * Colors are based on the default theme without background.
  233 + */
  234 +
  235 +.syntaxhighlighter.printing,
  236 +.syntaxhighlighter.printing .line.alt1 .content,
  237 +.syntaxhighlighter.printing .line.alt2 .content,
  238 +.syntaxhighlighter.printing .line.highlighted .number,
  239 +.syntaxhighlighter.printing .line.highlighted.alt1 .content,
  240 +.syntaxhighlighter.printing .line.highlighted.alt2 .content,
  241 +{
  242 + background: none !important;
  243 +}
  244 +
  245 +/* Gutter line numbers */
  246 +.syntaxhighlighter.printing .line .number
  247 +{
  248 + color: #bbb !important;
  249 +}
  250 +
  251 +/* Add border to the lines */
  252 +.syntaxhighlighter.printing .line .content
  253 +{
  254 + color: #000 !important;
  255 +}
  256 +
  257 +/* Toolbar when visible */
  258 +.syntaxhighlighter.printing .toolbar
  259 +{
  260 + display: none !important;
  261 +}
  262 +
  263 +.syntaxhighlighter.printing a
  264 +{
  265 + text-decoration: none !important;
  266 +}
  267 +
  268 +.syntaxhighlighter.printing .plain,
  269 +.syntaxhighlighter.printing .plain a
  270 +{
  271 + color: #000 !important;
  272 +}
  273 +
  274 +.syntaxhighlighter.printing .comments,
  275 +.syntaxhighlighter.printing .comments a
  276 +{
  277 + color: #008200 !important;
  278 +}
  279 +
  280 +.syntaxhighlighter.printing .string,
  281 +.syntaxhighlighter.printing .string a
  282 +{
  283 + color: blue !important;
  284 +}
  285 +
  286 +.syntaxhighlighter.printing .keyword
  287 +{
  288 + color: #069 !important;
  289 + font-weight: bold !important;
  290 +}
  291 +
  292 +.syntaxhighlighter.printing .preprocessor
  293 +{
  294 + color: gray !important;
  295 +}
  296 +
  297 +.syntaxhighlighter.printing .variable
  298 +{
  299 + color: #a70 !important;
  300 +}
  301 +
  302 +.syntaxhighlighter.printing .value
  303 +{
  304 + color: #090 !important;
  305 +}
  306 +
  307 +.syntaxhighlighter.printing .functions
  308 +{
  309 + color: #ff1493 !important;
  310 +}
  311 +
  312 +.syntaxhighlighter.printing .constants
  313 +{
  314 + color: #0066CC !important;
  315 +}
  316 +
  317 +.syntaxhighlighter.printing .script
  318 +{
  319 + font-weight: bold !important;
  320 +}
  321 +
  322 +.syntaxhighlighter.printing .color1,
  323 +.syntaxhighlighter.printing .color1 a
  324 +{
  325 + color: #808080 !important;
  326 +}
  327 +
  328 +.syntaxhighlighter.printing .color2,
  329 +.syntaxhighlighter.printing .color2 a
  330 +{
  331 + color: #ff1493 !important;
  332 +}
  333 +
  334 +.syntaxhighlighter.printing .color3,
  335 +.syntaxhighlighter.printing .color3 a
  336 +{
  337 + color: red !important;
  338 +}
  339 +/**
  340 + * SyntaxHighlighter
  341 + * http://alexgorbatchev.com/
  342 + *
  343 + * SyntaxHighlighter is donationware. If you are using it, please donate.
  344 + * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
  345 + *
  346 + * @version
  347 + * 2.1.364 (October 15 2009)
  348 + *
  349 + * @copyright
  350 + * Copyright (C) 2004-2009 Alex Gorbatchev.
  351 + *
  352 + * @license
  353 + * This file is part of SyntaxHighlighter.
  354 + *
  355 + * SyntaxHighlighter is free software: you can redistribute it and/or modify
  356 + * it under the terms of the GNU Lesser General Public License as published by
  357 + * the Free Software Foundation, either version 3 of the License, or
  358 + * (at your option) any later version.
  359 + *
  360 + * SyntaxHighlighter is distributed in the hope that it will be useful,
  361 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  362 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  363 + * GNU General Public License for more details.
  364 + *
  365 + * You should have received a copy of the GNU General Public License
  366 + * along with SyntaxHighlighter. If not, see <http://www.gnu.org/copyleft/lesser.html>.
  367 + */
  368 +/************************************
  369 + * Default Syntax Highlighter theme.
  370 + *
  371 + * Interface elements.
  372 + ************************************/
  373 +
  374 +.syntaxhighlighter
  375 +{
  376 + background-color: #fff !important;
  377 +}
  378 +
  379 +/* Highlighed line number */
  380 +.syntaxhighlighter .line.highlighted .number
  381 +{
  382 + color: black !important;
  383 +}
  384 +
  385 +/* Highlighed line */
  386 +.syntaxhighlighter .line.highlighted.alt1,
  387 +.syntaxhighlighter .line.highlighted.alt2
  388 +{
  389 + background-color: #e0e0e0 !important;
  390 +}
  391 +
  392 +/* Gutter line numbers */
  393 +.syntaxhighlighter .line .number
  394 +{
  395 + color: #afafaf !important;
  396 +}
  397 +
  398 +/* Add border to the lines */
  399 +.syntaxhighlighter .line .content
  400 +{
  401 + border-left: 1px solid gray !important;
  402 + color: #000 !important;
  403 +}
  404 +
  405 +.syntaxhighlighter.printing .line .content
  406 +{
  407 + border: 0 !important;
  408 +}
  409 +
  410 +/* First line */
  411 +.syntaxhighlighter .line.alt1
  412 +{
  413 + background-color: #fff !important;
  414 +}
  415 +
  416 +/* Second line */
  417 +.syntaxhighlighter .line.alt2
  418 +{
  419 + background-color: #F8F8F8 !important;
  420 +}
  421 +
  422 +.syntaxhighlighter .toolbar
  423 +{
  424 + background-color: #F8F8F8 !important;
  425 + border: #E7E5DC solid 1px !important;
  426 +}
  427 +
  428 +.syntaxhighlighter .toolbar a
  429 +{
  430 + color: #a0a0a0 !important;
  431 +}
  432 +
  433 +.syntaxhighlighter .toolbar a:hover
  434 +{
  435 + color: red !important;
  436 +}
  437 +
  438 +/************************************
  439 + * Actual syntax highlighter colors.
  440 + ************************************/
  441 +.syntaxhighlighter .plain,
  442 +.syntaxhighlighter .plain a
  443 +{
  444 + color: #000 !important;
  445 +}
  446 +
  447 +.syntaxhighlighter .comments,
  448 +.syntaxhighlighter .comments a
  449 +{
  450 + color: #008200 !important;
  451 +}
  452 +
  453 +.syntaxhighlighter .string,
  454 +.syntaxhighlighter .string a
  455 +{
  456 + color: blue !important;
  457 +}
  458 +
  459 +.syntaxhighlighter .keyword
  460 +{
  461 + color: #069 !important;
  462 + font-weight: bold !important;
  463 +}
  464 +
  465 +.syntaxhighlighter .preprocessor
  466 +{
  467 + color: gray !important;
  468 +}
  469 +
  470 +.syntaxhighlighter .variable
  471 +{
  472 + color: #a70 !important;
  473 +}
  474 +
  475 +.syntaxhighlighter .value
  476 +{
  477 + color: #090 !important;
  478 +}
  479 +
  480 +.syntaxhighlighter .functions
  481 +{
  482 + color: #ff1493 !important;
  483 +}
  484 +
  485 +.syntaxhighlighter .constants
  486 +{
  487 + color: #0066CC !important;
  488 +}
  489 +
  490 +.syntaxhighlighter .script
  491 +{
  492 + background-color: yellow !important;
  493 +}
  494 +
  495 +.syntaxhighlighter .color1,
  496 +.syntaxhighlighter .color1 a
  497 +{
  498 + color: #808080 !important;
  499 +}
  500 +
  501 +.syntaxhighlighter .color2,
  502 +.syntaxhighlighter .color2 a
  503 +{
  504 + color: #ff1493 !important;
  505 +}
  506 +
  507 +.syntaxhighlighter .color3,
  508 +.syntaxhighlighter .color3 a
  509 +{
  510 + color: red !important;
  511 +}
... ...
plugins/display_content/public/javascripts/jstree-v.pre1.0/_docs/syntax/clipboard.swf 0 → 100644
No preview for this file type