<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 個性化Rails生成器與模板 Rails 生成器是提高你工作效率的有力工具。通過本章節的學習,你可以了解如何創建和個性化生成器。 通過學習本章節,你將學到: * 如何在你的Rails應用中辨別哪些生成器是可用的; * 如何使用模板創建一個生成器; * Rails應用在調用生成器之前如何找到他們; * 如何通過創建一個生成器來定制你的 scaffold ; * 如何通過改變生成器模板定制你的scaffold ; * 如何使用回調復用生成器; * 如何創建一個應用模板; ### Chapters 1. [簡單介紹](#%E7%AE%80%E5%8D%95%E4%BB%8B%E7%BB%8D-) 2. [創建你的第一個生成器](#-%E5%88%9B%E5%BB%BA%E4%BD%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%94%9F%E6%88%90%E5%99%A8) 3. [用生成器創建生成器](#%E7%94%A8%E7%94%9F%E6%88%90%E5%99%A8%E5%88%9B%E5%BB%BA%E7%94%9F%E6%88%90%E5%99%A8) 4. [生成器查找](#%E7%94%9F%E6%88%90%E5%99%A8%E6%9F%A5%E6%89%BE) 5. [個性化你的工作流 ](#%E4%B8%AA%E6%80%A7%E5%8C%96%E4%BD%A0%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81%E3%80%80) 6. [通過修改生成器模板個性化工作流](#%E9%80%9A%E8%BF%87%E4%BF%AE%E6%94%B9%E7%94%9F%E6%88%90%E5%99%A8%E6%A8%A1%E6%9D%BF%E4%B8%AA%E6%80%A7%E5%8C%96%E5%B7%A5%E4%BD%9C%E6%B5%81) 7. [讓生成器支持備選功能](#%E8%AE%A9%E7%94%9F%E6%88%90%E5%99%A8%E6%94%AF%E6%8C%81%E5%A4%87%E9%80%89%E5%8A%9F%E8%83%BD-) 8. [應用模版](#%E5%BA%94%E7%94%A8%E6%A8%A1%E7%89%88) 9. [生成器方法](#%E7%94%9F%E6%88%90%E5%99%A8%E6%96%B9%E6%B3%95) * [`gem`](#gem) * [`gem_group`](#gem_group) * [`add_source`](#add_source) * [`inject_into_file`](#inject_into_file) * [`gsub_file`](#gsub_file) * [`application`](#application) * [`git`](#git) * [`vendor`](#vendor) * [`lib`](#lib) * [`rakefile`](#rakefile) * [`initializer`](#initializer) * [`generate`](#generate) * [`rake`](#rake) * [`capify!`](#capify-bang) * [`route`](#route) * [`readme`](#readme) ### 1 簡單介紹 當使用`rails` 命令創建一個應用的時候,實際上使用的是一個Rails生成器,創建應用之后,你可以使用`rails generate`命令獲取當前可用的生成器列表: ``` $ rails new myapp $ cd myapp $ bin/rails generate ``` 你將會看到和Rails相關的生成器列表,如果想了解這些生成器的詳情,可以做如下操作: ``` $ bin/rails generate helper --help ``` ### 2 創建你的第一個生成器 從Rails 3.0開始,生成器都是基于[Thor](https://github.com/erikhuda/thor)構建的。Thor提供了強力的解析和操作文件的功能。比如,我們想讓生成器在`config/initializers`目錄下創建一個名為`initializer.rb`的文件: 第一步可以通過`lib/generators/initializer_generator.rb`中的代碼創建一個文件: ``` class InitializerGenerator < Rails::Generators::Base def create_initializer_file create_file "config/initializers/initializer.rb", "# Add initialization content here" end end ``` 提示: `Thor::Actions`提供了`create_file`方法。關于`create_file`方法的詳情可以參考[Thor's documentation](http://rdoc.info/github/erikhuda/thor/master/Thor/Actions.html) 我們創建的生成器非常簡單: 它繼承自`Rails::Generators::Base`,只包含一個方法。當一個生成器被調用時,每個在生成器內部定義的方法都會順序執行一次。最終,我們會根據程序執行環境調用`create_file`方法,在目標文件目錄下創建一個文件。 如果你很熟悉Rails應用模板API,那么你在看生成器API時,也會輕車熟路,沒什么障礙。 為了調用我們剛才創建的生成器,我們只需要做如下操作: ``` $ bin/rails generate initializer ``` 我們可以通過如下代碼,了解我們剛才創建的生成器的相關信息: `bash $ bin/rails generate initializer --help` Rails可以對一個命名空間化的生成器自動生成一個很好的描述信息。比如 `ActiveRecord::Generators::ModelGenerator`。一般而言,我們可以通過2中方式生成相關的描述。第一種是在生成器內部調用`desc`方法: ``` class InitializerGenerator < Rails::Generators::Base desc "This generator creates an initializer file at config/initializers" def create_initializer_file create_file "config/initializers/initializer.rb", "# Add initialization content here" end end ``` 現在我們可以通過`--help`選項看到剛創建的生成器的描述信息。第二種是在生成器同名的目錄下創建一個名為`USAGE`的文件存放和生成器相關的描述信息。 ### 3 用生成器創建生成器 生成器本身擁有一個生成器: ``` $ bin/rails generate generator initializer create lib/generators/initializer create lib/generators/initializer/initializer_generator.rb create lib/generators/initializer/USAGE create lib/generators/initializer/templates ``` 這個生成器實際上只創建了這些: ``` class InitializerGenerator < Rails::Generators::NamedBase source_root File.expand_path("../templates", __FILE__) end ``` 首先,我們注意到生成器是繼承自`Rails::Generators::NamedBase`而非`Rails::Generators::Base`, 這意味著,我們的生成器在被調用時,至少要接收一個參數,即初始化器的名字。這樣我們才能通過代碼中的變量`name`來訪問它。 我們可以通過查看生成器的描述信息來證實(別忘了刪除舊的生成器文件): ``` $ bin/rails generate initializer --help Usage: rails generate initializer NAME [options] ``` 我們可以看到剛才創建的生成器有一個名為`source_root`的類方法。這個方法會指定生成器模板文件的存放路徑,一般情況下,會放在 `lib/generators/initializer/templates`目錄下。 為了了解生成器模板的作用,我們在`lib/generators/initializer/templates/initializer.rb`創建該文件,并添加如下內容: ``` # Add initialization content here ``` 現在,我們來為生成器添加一個拷貝方法,將模板文件拷貝到指定目錄: ``` class InitializerGenerator < Rails::Generators::NamedBase source_root File.expand_path("../templates", __FILE__) def copy_initializer_file copy_file "initializer.rb", "config/initializers/#{file_name}.rb" end end ``` 接下來,使用剛才創建的生成器: ``` $ bin/rails generate initializer core_extensions ``` 我們可以看到通過生成器的模板在`config/initializers/core_extensions.rb`創建了一個名為core_extensions的初始化器。這說明 `copy_file` 方法從指定文件下拷貝了一個文件到目標文件夾。因為我們是繼承自`Rails::Generators::NamedBase`的,所以會自動生成`file_name`方法 。 這個方法將在本章節的[final section](#generator-methods)實現完整功能。 ### 4 生成器查找 當你運行 `rails generate initializer core_extensions` 命令時,Rails會做如下搜索: ``` rails/generators/initializer/initializer_generator.rb generators/initializer/initializer_generator.rb rails/generators/initializer_generator.rb generators/initializer_generator.rb ``` 如果沒有找到,你將會看到一個錯誤信息。 提示: 上面的例子把文件放在Rails應用的`lib`文件夾下,是因為該文件夾路徑屬于`$LOAD_PATH`。 ### 5 個性化你的工作流  Rails自帶的生成器為工作流的個性化提供了支持。它們可以在`config/application.rb`中進行配置: ``` config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :test_unit, fixture: true end ``` 在個性化我們的工作流之前,我們先看看scaffold工具會做些什么:  ``` $ bin/rails generate scaffold User name:string invoke active_record create db/migrate/20130924151154_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml invoke resource_route route resources :users invoke scaffold_controller create app/controllers/users_controller.rb invoke erb create app/views/users create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb create app/views/users/_form.html.erb invoke test_unit create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb invoke test_unit create test/helpers/users_helper_test.rb invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder invoke assets invoke coffee create app/assets/javascripts/users.js.coffee invoke scss create app/assets/stylesheets/users.css.scss invoke scss create app/assets/stylesheets/scaffolds.css.scss ``` 通過上面的內容,我們可以很容易理解Rails3.0以上版本的生成器是如何工作的。scaffold生成器幾乎不生成文件。它只是調用其他生成器去做。這樣的話,我們可以很方便的添加/替換/刪除這些被調用的生成器。比如說,scaffold生成器調用了scaffold_controller生成器(調用了erb,test_unit和helper生成器),它們每個生成器都有一個單獨的響應方法,這樣就很容易實現代碼復用。 如果我們希望scaffold 在生成工作流時不必生成樣式表,腳本文件和測試固件等文件,那么我們可以進行如下配置: ``` config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :test_unit, fixture: false g.stylesheets false g.javascripts false end ``` 如果我們使用scaffold生成器創建另外一個資源時,就會發現樣式表,腳本文件和測試固件的文件都不再創建了。如果你想更深入的進行定制,比如使用DataMapper和RSpec 替換Active Record和TestUnit ,那么只需要把相關的gem文件引入,并配置你的生成器。 為了證明這一點,我們將創建一個新的helper生成器,簡單的添加一些實例變量訪問器。首先,我們創建一個帶Rails命名空間的的生成器,因為這樣為Rails方便搜索提供了支持: ``` $ bin/rails generate generator rails/my_helper create lib/generators/rails/my_helper create lib/generators/rails/my_helper/my_helper_generator.rb create lib/generators/rails/my_helper/USAGE create lib/generators/rails/my_helper/templates ``` 現在,我們可以刪除`templates`和`source_root`文件了,因為我們將不會用到它們,接下來我們在生成器中添加如下代碼: ``` # lib/generators/rails/my_helper/my_helper_generator.rb class Rails::MyHelperGenerator < Rails::Generators::NamedBase def create_helper_file create_file "app/helpers/#{file_name}_helper.rb", <<-FILE module #{class_name}Helper attr_reader :#{plural_name}, :#{plural_name.singularize} end FILE end end ``` 我們可以使用修改過的生成器為products提供一個helper文件: ``` $ bin/rails generate my_helper products create app/helpers/products_helper.rb ``` 這將會在 `app/helpers`目錄下生成一個對應的文件: ``` module ProductsHelper attr_reader :products, :product end ``` 這就是我們希望看到的。現在,我們可以修改`config/application.rb`,告訴scaffold使用我們的helper 生成器: ``` config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :test_unit, fixture: false g.stylesheets false g.javascripts false g.helper :my_helper end ``` 你將在生成動作列表中看到上述方法的調用: ``` $ bin/rails generate scaffold Article body:text [...] invoke my_helper create app/helpers/articles_helper.rb ``` 我們注意到新的helper生成器替換了Rails默認的調用。但有一件事情卻忽略了,如何為新的生成器提供測試呢?我們可以復用原有的helpers測試生成器。 從Rails 3.0開始,簡單的實現上述功能依賴于鉤子的概念。我們新的helper方法不需要拘泥于特定的測試框架,它可以簡單的提供一個鉤子,測試框架只需要實現這個鉤子并與之一致即可。 為此,我們需要對生成器做如下修改: ``` # lib/generators/rails/my_helper/my_helper_generator.rb class Rails::MyHelperGenerator < Rails::Generators::NamedBase def create_helper_file create_file "app/helpers/#{file_name}_helper.rb", <<-FILE module #{class_name}Helper attr_reader :#{plural_name}, :#{plural_name.singularize} end FILE end hook_for :test_framework end ``` 現在,當helper生成器被調用時,與之匹配的測試框架是TestUnit,那么這將會調用`Rails::TestUnitGenerator`和 `TestUnit::MyHelperGenerator`。如果他們都沒有定義,我們可以告訴生成器調用`TestUnit::Generators::HelperGenerator`來替代。對于一個Rails生成器來說,我們只需要添加如下代碼: ``` # Search for :helper instead of :my_helper hook_for :test_framework, as: :helper ``` 現在,你再次運行scaffold生成器生成Rails應用時,它就會生成相關的測試了。 ### 6 通過修改生成器模板個性化工作流 上一章節中,我們只是簡單的在helper生成器中添加了一行代碼,沒有添加額外的功能。有一種簡便的方法可以實現它,那就是替換模版中已經存在的生成器。比如`Rails::Generators::HelperGenerator`。 從Rails 3.0開始,生成器不只是在源目錄中查找模版,它們也會搜索其他路徑。其中一個就是`lib/templates`,如果我們想定制`Rails::Generators::HelperGenerator`,那么我們可以在`lib/templates/rails/helper`中添加一個名為`helper.rb`的文件,文件內容包含如下代碼: ``` module <%= class_name %>Helper attr_reader :<%= plural_name %>, :<%= plural_name.singularize %> end ``` 將 `config/application.rb`中重復的內容刪除: ``` config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :test_unit, fixture: false g.stylesheets false g.javascripts false end ``` 現在生成另外一個Rails應用時,你會發現得到的結果幾乎一致。這是一個很有用的功能,如果你只想修改`edit.html.erb`, `index.html.erb`等文件的布局,那么可以在`lib/templates/erb/scaffold`中進行配置。 ### 7 讓生成器支持備選功能 最后將要介紹的生成器特性對插件生成器特別有用。舉個例子,如果你想給TestUnit添加一個名為 [shoulda](https://github.com/thoughtbot/shoulda)的特性,TestUnit已經實現了所有Rails要求的生成器功能,shoulda想重用其中的部分功能,shoulda不需要重新實現這些生成器,可以告訴Rails使用`TestUnit`的生成器,如果在`Shoulda`的命名空間中沒找到的話。 我們可以通過修改`config/application.rb`的內容,很方便的實現這個功能: ``` config.generators do |g| g.orm :active_record g.template_engine :erb g.test_framework :shoulda, fixture: false g.stylesheets false g.javascripts false # Add a fallback! g.fallbacks[:shoulda] = :test_unit end ``` 現在,如果你使用scaffold 創建一個Comment 資源,那么你將看到shoulda生成器被調用了,但最后調用的是TestUnit的生成器方法: ``` $ bin/rails generate scaffold Comment body:text invoke active_record create db/migrate/20130924143118_create_comments.rb create app/models/comment.rb invoke shoulda create test/models/comment_test.rb create test/fixtures/comments.yml invoke resource_route route resources :comments invoke scaffold_controller create app/controllers/comments_controller.rb invoke erb create app/views/comments create app/views/comments/index.html.erb create app/views/comments/edit.html.erb create app/views/comments/show.html.erb create app/views/comments/new.html.erb create app/views/comments/_form.html.erb invoke shoulda create test/controllers/comments_controller_test.rb invoke my_helper create app/helpers/comments_helper.rb invoke shoulda create test/helpers/comments_helper_test.rb invoke jbuilder create app/views/comments/index.json.jbuilder create app/views/comments/show.json.jbuilder invoke assets invoke coffee create app/assets/javascripts/comments.js.coffee invoke scss ``` 備選功能支持你的生成器擁有單獨的響應,可以實現代碼復用,減少重復代碼。 ### 8 應用模版 現在你已經了解如何在一個應用中使用生成器,那么你知道生成器還可以生成應用嗎? 這種生成器一般是由"template"來實現的。接下來我們會簡要介紹模版API,進一步了解可以參考[Rails Application Templates guide](rails_application_templates.html)。 ``` gem "rspec-rails", group: "test" gem "cucumber-rails", group: "test" if yes?("Would you like to install Devise?") gem "devise" generate "devise:install" model_name = ask("What would you like the user model to be called? [user]") model_name = "user" if model_name.blank? generate "devise", model_name end ``` 上述模版在`Gemfile`聲明了 `rspec-rails` 和 `cucumber-rails`兩個gem包屬于`test`組,之后會發送一個問題給使用者,是否希望安裝Devise?如果用戶同意安裝,那么模版會將Devise添加到`Gemfile`文件中,并運行 `devise:install`命令,之后根據用戶輸入的模塊名,指定`devise`所屬模塊。 假如你想使用一個名為`template.rb`的模版文件,我們可以通過在執行 `rails new`命令時,加上 `-m` 選項來改變輸出信息: ``` $ rails new thud -m template.rb ``` 上述命令將會生成`Thud` 應用,并使用模版生成輸出信息。 模版文件不一定要存儲在本地文件中, `-m`選項也支持在線模版: ``` $ rails new thud -m https://gist.github.com/radar/722911/raw/ ``` 本文最后的章節沒有介紹如何生成大家都熟知的模版,而是介紹在開發模版過程中會用到的方法。同樣這些方法也可以通過生成器來調用。 ### 9 生成器方法 下面要介紹的方法對生成器和模版來說都是可用的。 提示: Thor中未介紹的方法可以通過訪問[Thor's documentation](http://rdoc.info/github/erikhuda/thor/master/Thor/Actions.html)做進一步了解。 #### 9.1 `gem` 聲明一個gem在Rails應用中的依賴項。 ``` gem "rspec", group: "test", version: "2.1.0" gem "devise", "1.1.5" ``` 可用的選項如下: * `:group` - 在`Gemfile`中聲明所安裝的gem包所在的分組。 * `:version` - 聲明gem的版本信息,你也可以在該方法的第二個參數中聲明。 * `:git` - gem包相關的git地址 可以在該方法參數列表的最后添加額外的信息: ``` gem "devise", git: "git://github.com/plataformatec/devise", branch: "master" ``` 上述代碼將在`Gemfile`中添加如下內容: ``` gem "devise", git: "git://github.com/plataformatec/devise", branch: "master" ``` #### 9.2 `gem_group` 將gem包安裝到指定組中: ``` gem_group :development, :test do gem "rspec-rails" end ``` #### 9.3 `add_source` 為`Gemfile`文件添加指定數據源: ``` add_source "http://gems.github.com" ``` #### 9.4 `inject_into_file` 在文件中插入一段代碼: ``` inject_into_file 'name_of_file.rb', after: "#The code goes below this line. Don't forget the Line break at the end\n" do <<-'RUBY' puts "Hello World" RUBY end ``` #### 9.5 `gsub_file` 替換文件中的文本: ``` gsub_file 'name_of_file.rb', 'method.to_be_replaced', 'method.the_replacing_code' ``` 使用正則表達式可以更準確的匹配信息。同時可以分別使用`append_file`和 `prepend_file`方法從文件的開始處或末尾處匹配信息。 #### 9.6 `application` 在`config/application.rb`文件中的application類定義之后添加一行信息。 ``` application "config.asset_host = 'http://example.com'" ``` 這個方法也可以寫成一個代碼塊的方式: ``` application do "config.asset_host = 'http://example.com'" end ``` 可用的選項如下: * `:env` -為配置文件指定運行環境,如果你希望寫成代碼塊的方式,可以這么做: ``` application(nil, env: "development") do "config.asset_host = 'http://localhost:3000'" end ``` #### 9.7 `git` 運行指定的git命令: ``` git :init git add: "." git commit: "-m First commit!" git add: "onefile.rb", rm: "badfile.cxx" ``` 哈希值可以作為git命令的參數來使用,上述代碼中指定了多個git命令,但并不能保證這些命令按順序執行。 #### 9.8 `vendor` 查找`vendor`文件加下指定文件是否包含指定內容: ``` vendor "sekrit.rb", '#top secret stuff' ``` 這個方法也可以寫成一個代碼塊 : ``` vendor "seeds.rb" do "puts 'in your app, seeding your database'" end ``` #### 9.9 `lib` 查找`lib`文件加下指定文件是否包含指定內容: ``` lib "special.rb", "p Rails.root" ``` 這個方法也可以寫成一個代碼塊 : ``` lib "super_special.rb" do puts "Super special!" end ``` #### 9.10 `rakefile` 在Rails應用的 `lib/tasks`文件夾下創建一個Rake文件。 ``` rakefile "test.rake", "hello there" ``` 這個方法也可以寫成一個代碼塊 : ``` rakefile "test.rake" do %Q{ task rock: :environment do puts "Rockin'" end } end ``` #### 9.11 `initializer` 在Rails應用的`config/initializers` 目錄下創建一個初始化器: ``` initializer "begin.rb", "puts 'this is the beginning'" ``` 這個方法也可以寫成一個代碼塊,并返回一個字符串: ``` initializer "begin.rb" do "puts 'this is the beginning'" end ``` #### 9.12 `generate` 運行指定的生成器,第一個參數是生成器名字,其余的直接傳給生成器: ``` generate "scaffold", "forums title:string description:text" ``` #### 9.13 `rake` 運行指定的Rake任務: ``` rake "db:migrate" ``` 可用是選項如下: * `:env` - 聲明rake任務的執行環境。 * `:sudo` - 是否使用`sudo`命令運行rake任務,默認不使用。 #### 9.14 `capify!` 在Rails應用的根目錄下使用Capistrano運行`capify`命令,生成和Rails應用相關的Capistrano配置文件。 ``` capify! ``` #### 9.15 `route` 在`config/routes.rb` 文件中添加文本: ``` route "resources :people" ``` #### 9.16 `readme` 輸出模版的`source_path`相關的內容,通常是一個README文件。 ``` readme "README" ``` ### 反饋 歡迎幫忙改善指南質量。 如發現任何錯誤,歡迎修正。開始貢獻前,可先行閱讀[貢獻指南:文檔](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-documentation)。 翻譯如有錯誤,深感抱歉,歡迎 [Fork](https://github.com/ruby-china/guides/fork) 修正,或至此處[回報](https://github.com/ruby-china/guides/issues/new)。 文章可能有未完成或過時的內容。請先檢查 [Edge Guides](http://edgeguides.rubyonrails.org) 來確定問題在 master 是否已經修掉了。再上 master 補上缺少的文件。內容參考 [Ruby on Rails 指南準則](ruby_on_rails_guides_guidelines.html)來了解行文風格。 最后,任何關于 Ruby on Rails 文檔的討論,歡迎到 [rubyonrails-docs 郵件群組](http://groups.google.com/group/rubyonrails-docs)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看