diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-11-28 09:22:57 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-11-28 09:22:57 +0000 |
commit | 0cf0b824182fc643c4e295b7178b84e71fdded54 (patch) | |
tree | f8eb0bb1ca3effb41119a9e505395f6ba8003752 /lib/json | |
parent | 6272cf8ecd8f4cd35af10aecf505f22b8244c56d (diff) | |
download | ruby-0cf0b824182fc643c4e295b7178b84e71fdded54.tar.gz |
* ext/json, lib/json, test/json: Update to JSON 1.1.2.
(RubyForge#15447)
* math.c: fix typo.
--
M ChangeLog
M math.c
M ext/json/ext/generator/generator.c
M ext/json/ext/parser/parser.rl
M ext/json/ext/parser/parser.c
M lib/json/version.rb
M lib/json/editor.rb
M lib/json/common.rb
M lib/json/pure/parser.rb
M test/json/test_json_unicode.rb
M test/json/test_json_fixtures.rb
M test/json/test_json_generate.rb
M test/json/test_json_addition.rb
M test/json/test_json.rb
M test/json/runner.rb
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14044 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/json')
-rw-r--r-- | lib/json/common.rb | 9 | ||||
-rw-r--r-- | lib/json/editor.rb | 160 | ||||
-rw-r--r-- | lib/json/pure/parser.rb | 10 | ||||
-rw-r--r-- | lib/json/version.rb | 2 |
4 files changed, 132 insertions, 49 deletions
diff --git a/lib/json/common.rb b/lib/json/common.rb index c988677a1d..7bc5ae0656 100644 --- a/lib/json/common.rb +++ b/lib/json/common.rb @@ -115,6 +115,9 @@ module JSON # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in # defiance of RFC 4627 to be parsed by the Parser. This option defaults # to false. + # * *create_additions*: If set to false, the Parser doesn't create + # additions even if a matchin class and create_id was found. This option + # defaults to true. def parse(source, opts = {}) JSON.parser.new(source, opts).parse end @@ -131,6 +134,9 @@ module JSON # * *allow_nan*: If set to true, allow NaN, Infinity, and -Infinity in # defiance of RFC 4627 to be parsed by the Parser. This option defaults # to true. + # * *create_additions*: If set to false, the Parser doesn't create + # additions even if a matchin class and create_id was found. This option + # defaults to true. def parse!(source, opts = {}) opts = { :max_nesting => false, @@ -161,6 +167,9 @@ module JSON # * *allow_nan*: true if NaN, Infinity, and -Infinity should be # generated, otherwise an exception is thrown, if these values are # encountered. This options defaults to false. + # * *max_nesting*: The maximum depth of nesting allowed in the data + # structures from which JSON is to be generated. Disable depth checking + # with :max_nesting => false, it defaults to 19. # # See also the fast_generate for the fastest creation method with the least # amount of sanity checks, and the pretty_generate method for some diff --git a/lib/json/editor.rb b/lib/json/editor.rb index 3dbcce5536..9a65400622 100644 --- a/lib/json/editor.rb +++ b/lib/json/editor.rb @@ -457,16 +457,16 @@ module JSON def create add_item("Change node", ?n, &method(:change_node)) add_separator - add_item("Cut node", ?x, &method(:cut_node)) - add_item("Copy node", ?c, &method(:copy_node)) - add_item("Paste node (appending)", ?v, &method(:paste_node_appending)) - add_item("Paste node (inserting before)", ?V, + add_item("Cut node", ?X, &method(:cut_node)) + add_item("Copy node", ?C, &method(:copy_node)) + add_item("Paste node (appending)", ?A, &method(:paste_node_appending)) + add_item("Paste node (inserting before)", ?I, &method(:paste_node_inserting_before)) add_separator add_item("Append new node", ?a, &method(:append_new_node)) add_item("Insert new node before", ?i, &method(:insert_new_node)) add_separator - add_item("Collapse/Expand node (recursively)", ?C, + add_item("Collapse/Expand node (recursively)", ?e, &method(:collapse_expand)) menu.show_all @@ -544,17 +544,32 @@ module JSON class EditMenu include MenuExtension + # Copy data from model into primary clipboard. + def copy(item) + data = Editor.model2data(model.iter_first) + json = JSON.pretty_generate(data, :max_nesting => false) + c = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) + c.text = json + end + + # Copy json text from primary clipboard into model. + def paste(item) + c = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) + if json = c.wait_for_text + window.ask_save if @changed + begin + window.edit json + rescue JSON::ParserError + window.clear + end + end + end + # Find a string in all nodes' contents and select the found node in the # treeview. def find(item) - search = ask_for_find_term or return - begin - @search = Regexp.new(search) - rescue => e - Editor.error_dialog(self, "Evaluation of regex /#{search}/ failed: #{e}!") - return - end - iter = model.get_iter('0') + @search = ask_for_find_term(@search) or return + iter = model.get_iter('0') or return iter.recursive_each do |i| if @iter if @iter != i @@ -630,6 +645,9 @@ module JSON def create title = MenuItem.new('Edit') title.submenu = menu + add_item('Copy', ?c, &method(:copy)) + add_item('Paste', ?v, &method(:paste)) + add_separator add_item('Find', ?f, &method(:find)) add_item('Find Again', ?g, &method(:find_again)) add_separator @@ -812,12 +830,13 @@ module JSON [ Stock::OK, Dialog::RESPONSE_ACCEPT ], [ Stock::CANCEL, Dialog::RESPONSE_REJECT ] ) + dialog.width_request = 640 hbox = HBox.new(false, 5) - hbox.pack_start(Label.new("Key:")) + hbox.pack_start(Label.new("Key:"), false) hbox.pack_start(key_input = Entry.new) key_input.text = @key || '' - dialog.vbox.add(hbox) + dialog.vbox.pack_start(hbox, false) key_input.signal_connect(:activate) do if parent.any? { |c| c.content == key_input.text } toplevel.display_status('Key already exists in Hash!') @@ -828,11 +847,11 @@ module JSON end hbox = HBox.new(false, 5) - hbox.add(Label.new("Type:")) + hbox.pack_start(Label.new("Type:"), false) hbox.pack_start(type_input = ComboBox.new(true)) ALL_TYPES.each { |t| type_input.append_text(t) } type_input.active = @type || 0 - dialog.vbox.add(hbox) + dialog.vbox.pack_start(hbox, false) type_input.signal_connect(:changed) do value_input.editable = false @@ -852,10 +871,11 @@ module JSON end hbox = HBox.new(false, 5) - hbox.add(Label.new("Value:")) + hbox.pack_start(Label.new("Value:"), false) hbox.pack_start(value_input = Entry.new) + value_input.width_chars = 60 value_input.text = @value || '' - dialog.vbox.add(hbox) + dialog.vbox.pack_start(hbox, false) dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER) dialog.show_all @@ -884,7 +904,7 @@ module JSON [ Stock::CANCEL, Dialog::RESPONSE_REJECT ] ) hbox = HBox.new(false, 5) - hbox.add(Label.new("Type:")) + hbox.pack_start(Label.new("Type:"), false) hbox.pack_start(type_input = ComboBox.new(true)) default_active = 0 types = parent ? ALL_TYPES : CONTAINER_TYPES @@ -895,18 +915,19 @@ module JSON end end type_input.active = default_active - dialog.vbox.add(hbox) + dialog.vbox.pack_start(hbox, false) type_input.signal_connect(:changed) do configure_value(value_input, types[type_input.active]) end hbox = HBox.new(false, 5) - hbox.add(Label.new("Value:")) + hbox.pack_start(Label.new("Value:"), false) hbox.pack_start(value_input = Entry.new) + value_input.width_chars = 60 value_input.text = value_text if value_text configure_value(value_input, types[type_input.active]) - dialog.vbox.add(hbox) + dialog.vbox.pack_start(hbox, false) dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER) dialog.show_all @@ -940,13 +961,14 @@ module JSON ) hbox = HBox.new(false, 5) - hbox.add(Label.new("Order:")) + hbox.pack_start(Label.new("Order:"), false) hbox.pack_start(order_input = Entry.new) order_input.text = @order || 'x' + order_input.width_chars = 60 - hbox.pack_start(reverse_checkbox = CheckButton.new('Reverse')) + hbox.pack_start(reverse_checkbox = CheckButton.new('Reverse'), false) - dialog.vbox.add(hbox) + dialog.vbox.pack_start(hbox, false) dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER) dialog.show_all @@ -963,7 +985,7 @@ module JSON # Ask for a find term to search for in the tree. Returns the term as a # string. - def ask_for_find_term + def ask_for_find_term(search = nil) dialog = Dialog.new( "Find a node matching regex in tree.", nil, nil, @@ -972,18 +994,28 @@ module JSON ) hbox = HBox.new(false, 5) - hbox.add(Label.new("Regex:")) + hbox.pack_start(Label.new("Regex:"), false) hbox.pack_start(regex_input = Entry.new) - regex_input.text = @regex || '' + hbox.pack_start(icase_checkbox = CheckButton.new('Icase'), false) + regex_input.width_chars = 60 + if search + regex_input.text = search.source + icase_checkbox.active = search.casefold? + end - dialog.vbox.add(hbox) + dialog.vbox.pack_start(hbox, false) dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER) dialog.show_all self.focus = dialog dialog.run do |response| if response == Dialog::RESPONSE_ACCEPT - return @regex = regex_input.text + begin + return Regexp.new(regex_input.text, icase_checkbox.active? ? Regexp::IGNORECASE : 0) + rescue => e + Editor.error_dialog(self, "Evaluation of regex /#{regex_input.text}/ failed: #{e}!") + return + end end end return @@ -1040,6 +1072,18 @@ module JSON data = read_data(@filename) view_new_model Editor.data2model(data) end + + signal_connect(:button_release_event) do |_,event| + if event.button == 2 + c = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) + if url = c.wait_for_text + location_open url + end + false + else + true + end + end end # Creates the menu bar with the pulldown menus and returns it. @@ -1132,6 +1176,7 @@ module JSON def location_open(uri = nil) uri = ask_for_location unless uri uri or return + ask_save if @changed data = load_location(uri) or return view_new_model Editor.data2model(data) end @@ -1144,6 +1189,15 @@ module JSON view_new_model Editor.data2model(data) end + # Edit the string _json_ in the editor. + def edit(json) + if json.respond_to? :read + json = json.read + end + data = parse_json json + view_new_model Editor.data2model(data) + end + # Save the current file. def file_save if @filename @@ -1164,10 +1218,11 @@ module JSON if path data = Editor.model2data(@treeview.model.iter_first) File.open(path + '.tmp', 'wb') do |output| + data or break if @options_menu.pretty_item.active? - output.puts JSON.pretty_generate(data) + output.puts JSON.pretty_generate(data, :max_nesting => false) else - output.write JSON.unparse(data) + output.write JSON.generate(data, :max_nesting => false) end end File.rename path + '.tmp', path @@ -1205,17 +1260,22 @@ module JSON data end + def parse_json(json) + check_pretty_printed(json) + if @encoding && !/^utf8$/i.match(@encoding) + iconverter = Iconv.new('utf8', @encoding) + json = iconverter.iconv(json) + end + JSON::parse(json, :max_nesting => false, :create_additions => false) + end + private :parse_json + # Read a JSON document from the file named _filename_, parse it into a # ruby data structure, and return the data. def read_data(filename) open(filename) do |f| json = f.read - check_pretty_printed(json) - if @encoding && !/^utf8$/i.match(@encoding) - iconverter = Iconv.new('utf8', @encoding) - json = iconverter.iconv(json) - end - return JSON::parse(json, :max_nesting => false) + return parse_json(json) end rescue => e Editor.error_dialog(self, "Failed to parse JSON file: #{e}!") @@ -1226,11 +1286,15 @@ module JSON # selected filename or nil, if no file was selected. def select_file(message) filename = nil - fs = FileSelection.new(message).set_modal(true). - set_filename(Dir.pwd + "/").set_transient_for(self) + fs = FileSelection.new(message) + fs.set_modal(true) + @default_dir = File.join(Dir.pwd, '') unless @default_dir + fs.set_filename(@default_dir) + fs.set_transient_for(self) fs.signal_connect(:destroy) { Gtk.main_quit } fs.ok_button.signal_connect(:clicked) do filename = fs.filename + @default_dir = File.join(File.dirname(filename), '') fs.destroy Gtk.main_quit end @@ -1253,12 +1317,12 @@ module JSON ) hbox = HBox.new(false, 5) - hbox.add(Label.new("Location:")) + hbox.pack_start(Label.new("Location:"), false) hbox.pack_start(location_input = Entry.new) location_input.width_chars = 60 location_input.text = @location || '' - dialog.vbox.add(hbox) + dialog.vbox.pack_start(hbox, false) dialog.signal_connect(:'key-press-event', &DEFAULT_DIALOG_KEY_PRESS_HANDLER) dialog.show_all @@ -1276,8 +1340,7 @@ module JSON class << self # Starts a JSON Editor. If a block was given, it yields # to the JSON::Editor::MainWindow instance. - def start(encoding = nil) # :yield: window - encoding ||= 'utf8' + def start(encoding = 'utf8') # :yield: window Gtk.init @window = Editor::MainWindow.new(encoding) @window.icon_list = [ Editor.fetch_icon('json') ] @@ -1286,6 +1349,13 @@ module JSON Gtk.main end + # Edit the string _json_ with encoding _encoding_ in the editor. + def edit(json, encoding = 'utf8') + start(encoding) do |window| + window.edit json + end + end + attr_reader :window end end diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index 4d63464320..e886ba8d2c 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -58,6 +58,9 @@ module JSON # * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in # defiance of RFC 4627 to be parsed by the Parser. This option defaults # to false. + # * *create_additions*: If set to false, the Parser doesn't create + # additions even if a matchin class and create_id was found. This option + # defaults to true. def initialize(source, opts = {}) super if !opts.key?(:max_nesting) # defaults to 19 @@ -68,7 +71,9 @@ module JSON @max_nesting = 0 end @allow_nan = !!opts[:allow_nan] - @create_id = JSON.create_id + ca = true + ca = opts[:create_additions] if opts.key?(:create_additions) + @create_id = ca ? JSON.create_id : nil end alias source string @@ -235,11 +240,10 @@ module JSON if delim raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!" end - if klassname = result[@create_id] + if @create_id and klassname = result[@create_id] klass = JSON.deep_const_get klassname break unless klass and klass.json_creatable? result = klass.json_create(result) - result end break when skip(IGNORE) diff --git a/lib/json/version.rb b/lib/json/version.rb index 2e12c8c9e0..3d674ac44f 100644 --- a/lib/json/version.rb +++ b/lib/json/version.rb @@ -1,6 +1,6 @@ module JSON # JSON version - VERSION = '1.1.1' + VERSION = '1.1.2' VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: |