From a065e04d529da1d847b5062a12c46d916408bf32 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 21:46:22 -0500 Subject: update based on https://github.com/mdn/yari/issues/2028 --- files/zh-cn/_wikihistory.json | 50892 ------------------- .../index.html | 44 - .../index.html | 112 - .../archive/add-ons/developing_add-ons/index.html | 8 - .../index.html | 25 - files/zh-cn/archive/add-ons/index.html | 67 - .../index.html | 66 - .../archive/add-ons/jetpack_processes/index.html | 31 - .../add-ons/multiple_item_packaging/index.html | 56 - .../archive/add-ons/signing_an_xpi/index.html | 378 - .../zh-cn/archive/apps/advanced_topics/index.html | 77 - .../apps/icon_implementation_for_apps/index.html | 178 - files/zh-cn/archive/apps/index.html | 14 - .../tools_and_frameworks/app_templates/index.html | 82 - .../archive/apps/tools_and_frameworks/index.html | 47 - .../zh-cn/archive/b2g_os/api/alarm_api/index.html | 218 - .../api/bluetoothstatuschangedevent/index.html | 54 - .../zh-cn/archive/b2g_os/api/domrequest/index.html | 139 - files/zh-cn/archive/b2g_os/api/index.html | 833 - .../zh-cn/archive/b2g_os/api/navigator/index.html | 12 - .../api/navigator/mozhaspendingmessage/index.html | 117 - .../api/navigator/mozsetmessagehandler/index.html | 252 - .../b2g_os/api/navigator/moztelephony/index.html | 85 - .../archive/b2g_os/api/permissions_api/index.html | 100 - .../archive/b2g_os/api/settingslock/index.html | 55 - .../archive/b2g_os/api/settingslock/set/index.html | 80 - .../archive/b2g_os/api/settingsmanager/index.html | 66 - .../archive/b2g_os/api/tpc_socket_api/index.html | 156 - files/zh-cn/archive/b2g_os/apps/index.html | 51 - .../writing_a_web_app_for_firefox_os/index.html | 46 - .../gaia_performance_tests/index.html | 109 - .../automated_testing/gaia_unit_tests/index.html | 113 - .../archive/b2g_os/automated_testing/index.html | 124 - files/zh-cn/archive/b2g_os/building/index.html | 185 - .../b2g_os_update_packages/index.html | 477 - .../firefox_os_build_overview/index.html | 105 - .../building_and_installing_firefox_os/index.html | 70 - .../building_the_b2g_desktop_client/index.html | 262 - .../index.html | 107 - .../debugging/debugging_b2g_using_gdb/index.html | 88 - .../b2g_os/debugging/debugging_ooms/index.html | 62 - .../b2g_os/debugging/developer_settings/index.html | 161 - files/zh-cn/archive/b2g_os/debugging/index.html | 80 - .../b2g_os/debugging/taking_screenshots/index.html | 69 - .../customizing_the_b2g.sh_script/index.html | 44 - .../filing_bugs_against_firefox_os/index.html | 157 - .../b2g_os/developing_firefox_os/index.html | 45 - .../market_customizations_guide/index.html | 979 - .../modifying_hosts_file/index.html | 43 - .../index.html | 193 - .../customizing_build-time_apps/index.html | 117 - .../customizing_the_keyboard/index.html | 65 - .../different_ways_to_run_gaia/index.html | 72 - .../archive/b2g_os/developing_gaia/index.html | 54 - .../localizing_firefox_os/index.html | 107 - .../make_options_reference/index.html | 186 - .../making_gaia_code_changes/index.html | 58 - .../running_the_gaia_codebase/index.html | 81 - .../testing_gaia_code_changes/index.html | 119 - .../understanding_the_gaia_codebase/index.html | 105 - .../archive/b2g_os/events/disabled/index.html | 43 - files/zh-cn/archive/b2g_os/events/index.html | 14 - .../firefox_os_apps/building_blocks/1.x/index.html | 534 - .../1.x/\346\214\211\351\222\256/index.html" | 256 - .../firefox_os_apps/building_blocks/index.html | 187 - .../archive/b2g_os/firefox_os_apps/index.html | 85 - .../firefox_os_build_prerequisites/index.html | 267 - .../zh-cn/archive/b2g_os/firefox_os_faq/index.html | 43 - files/zh-cn/archive/b2g_os/index.html | 243 - .../installing_on_a_mobile_device/index.html | 111 - files/zh-cn/archive/b2g_os/introduction/index.html | 110 - .../index.html | 55 - .../archive/b2g_os/phone_guide/flame/index.html | 258 - files/zh-cn/archive/b2g_os/phone_guide/index.html | 35 - .../b2g_os/phone_guide/phone_specs/index.html | 439 - .../b2g_os/platform/apps_architecture/index.html | 24 - .../b2g_os/platform/architecture/index.html | 1024 - .../platform/feature_support_chart/index.html | 158 - .../platform/gaia/build_system_primer/index.html | 68 - .../platform/gaia/gaia_apps/browser/index.html | 107 - .../b2g_os/platform/gaia/gaia_apps/index.html | 90 - .../platform/gaia/gaia_apps/settings/index.html | 78 - .../platform/gaia/gaia_apps/system/index.html | 226 - .../gaia/gaia_apps/window_management/index.html | 279 - .../b2g_os/platform/gaia/hacking/index.html | 542 - .../zh-cn/archive/b2g_os/platform/gaia/index.html | 72 - .../platform/gaia/introduction_to_gaia/index.html | 28 - .../index.html" | 105 - .../zh-cn/archive/b2g_os/platform/gonk/index.html | 98 - files/zh-cn/archive/b2g_os/platform/index.html | 87 - .../index.html | 80 - .../b2g_os/platform/settings_list/index.html | 716 - files/zh-cn/archive/b2g_os/porting/index.html | 120 - .../preparing_for_your_first_b2g_build/index.html | 212 - files/zh-cn/archive/b2g_os/quickstart/index.html | 49 - .../b2g_os/quickstart/your_first_app/index.html | 261 - .../index.html" | 87 - .../index.html | 58 - .../index.html | 219 - .../security/application_security/index.html | 126 - files/zh-cn/archive/b2g_os/security/index.html | 70 - .../b2g_os/security/security_model/index.html | 285 - files/zh-cn/archive/b2g_os/simulator/index.html | 240 - .../simulator/simulator_walkthrough/index.html | 269 - .../b2g_os/using_firefox_os_simulator/index.html | 57 - .../b2g_os/using_the_app_manager/index.html | 183 - .../b2g_os/using_the_b2g_emulators/index.html | 72 - files/zh-cn/archive/css3/index.html | 1047 - .../firefox_os/api/simple_push_api/index.html | 232 - files/zh-cn/archive/index.html | 18 - files/zh-cn/archive/jxon/index.html | 1513 - files/zh-cn/archive/mdn/index.html | 16 - .../archive/meta_docs/custom_classes/index.html | 239 - files/zh-cn/archive/meta_docs/devedge/index.html | 61 - .../meta_docs/external_redirects/index.html | 74 - files/zh-cn/archive/meta_docs/index.html | 10 - .../images,_tables,_and_mysterious_gaps/index.html | 164 - files/zh-cn/archive/misc_top_level/index.html | 8 - .../index.html | 23 - .../using_xml_data_islands_in_mozilla/index.html | 192 - .../index.html | 46 - .../mozilla/getting_started_with_irc/index.html | 316 - .../creating_a_help_content_pack/index.html | 200 - files/zh-cn/archive/mozilla/help_viewer/index.html | 22 - files/zh-cn/archive/mozilla/index.html | 7 - files/zh-cn/archive/mozilla/marketplace/index.html | 134 - .../marketplace/marketplace_apis/index.html | 68 - .../marketplace/options/self_publishing/index.html | 144 - .../index.html" | 71 - .../options/\347\256\200\344\273\213/index.html" | 55 - .../marketplace/prepare/introduction/index.html | 57 - .../marketplace/publishing/submit/index.html | 10 - .../mozilla/rdf_datasource_how-to/index.html | 231 - files/zh-cn/archive/mozilla/tamarin/index.html | 104 - .../tamarin/tamarin_build_documentation/index.html | 416 - files/zh-cn/archive/mozilla/xbl/index.html | 70 - .../xbl_1.0_reference/dom_interfaces/index.html | 122 - .../mozilla/xbl/xbl_1.0_reference/index.html | 117 - files/zh-cn/archive/mozilla/xpinstall/index.html | 83 - .../archive/mozilla/xpinstall/reference/index.html | 189 - .../xpinstall/reference/install_object/index.html | 50 - .../reference/install_object/properties/index.html | 33 - .../xpinstall/scripting_by_example/index.html | 246 - .../using_xpinstall_to_install_plugins/index.html | 227 - files/zh-cn/archive/rss/article/index.html | 6 - .../index.html | 8 - files/zh-cn/archive/rss/index.html | 69 - .../archive/security/digital_signatures/index.html | 38 - .../security/encryption_and_decryption/index.html | 73 - files/zh-cn/archive/security/index.html | 14 - .../index.html | 475 - files/zh-cn/archive/web/e4x/index.html | 49 - .../e4x_tutorial/accessing_xml_children/index.html | 111 - .../descendants_and_filters/index.html | 27 - files/zh-cn/archive/web/e4x_tutorial/index.html | 39 - .../web/e4x_tutorial/introduction/index.html | 64 - .../archive/web/e4x_tutorial/namespaces/index.html | 33 - .../e4x_tutorial/the_global_xml_object/index.html | 55 - files/zh-cn/archive/web/index.html | 12 - .../index.html | 60 - .../web/javascript/handler.enumerate/index.html | 114 - files/zh-cn/archive/web/javascript/index.html | 12 - .../legacy_generator_function/index.html | 54 - .../legacy_generator_function_statement/index.html | 65 - .../microsoft_extensions/activexobject/index.html | 92 - .../date.getvardate/index.html | 40 - .../web/javascript/microsoft_extensions/index.html | 70 - .../web/javascript/reflect.enumerate/index.html | 120 - files/zh-cn/archive/web/liveconnect/index.html | 800 - .../web_\346\240\207\345\207\206/index.html" | 76 - .../index.html" | 64 - .../rdf_in_mozilla_faq/index.html" | 320 - .../index.html" | 264 - .../index.html" | 31 - files/zh-cn/components.classes/index.html | 86 - .../components.utils.evalinsandbox/index.html | 80 - files/zh-cn/components.utils.import/index.html | 82 - files/zh-cn/components_object/index.html | 110 - .../creating_a_python_xpcom_component/index.html | 96 - .../creating_xpi_installer_modules/index.html | 190 - files/zh-cn/debugging_javascript/index.html | 74 - files/zh-cn/drag_and_drop/index.html | 121 - files/zh-cn/drag_and_drop_example/index.html | 159 - .../index.html | 9 - files/zh-cn/extensions/firefox/index.html | 11 - files/zh-cn/extensions/index.html | 140 - files/zh-cn/extensions/mobile/index.html | 76 - .../index.html" | 369 - .../firefox_addons_developer_guide/index.html | 15 - .../introduction_to_extensions/index.html | 163 - files/zh-cn/firefox_sync/index.html | 50 - .../firefox_sync/javascript_client_api/index.html | 296 - files/zh-cn/generic_factory/index.html | 133 - files/zh-cn/getting_started_with_nss/index.html | 35 - .../getting_started_with_xulrunner/index.html | 202 - files/zh-cn/gre/index.html | 38 - .../index.html | 189 - files/zh-cn/implementing_queryinterface/index.html | 172 - files/zh-cn/interfaces/index.html | 6 - .../introducing_audio_api_extension/index.html | 191 - files/zh-cn/jsdbgapi_reference/index.html | 145 - .../localization_quick_start_guide/index.html | 30 - .../initial_setup/index.html | 83 - files/zh-cn/localizing_with_pontoon/index.html | 134 - files/zh-cn/localizing_with_verbatim/index.html | 156 - .../howto/link_a_github_account/index.html | 89 - .../mdn/contribute/persona_sign-in/index.html | 26 - files/zh-cn/mdn/guidelines/layout/index.html | 7 - files/zh-cn/mdn/user_guide/writing/index.html | 64 - files/zh-cn/mercurial_faq/index.html | 650 - files/zh-cn/midas/index.html | 324 - files/zh-cn/midas/security_preferences/index.html | 111 - .../index.html | 1057 - files/zh-cn/mmgc/index.html | 476 - files/zh-cn/mobile/index.html | 10 - files/zh-cn/mobile/viewport_meta_tag/index.html | 97 - files/zh-cn/mozilla/accessibility/index.html | 13 - .../software_accessibility_today/index.html | 133 - .../mozilla/add-ons/add-on_guidelines/index.html | 9 - files/zh-cn/mozilla/add-ons/amo/index.html | 11 - .../mozilla/add-ons/amo/policy/contact/index.html | 28 - files/zh-cn/mozilla/add-ons/amo/policy/index.html | 23 - .../add-ons/code_snippets/canvas/index.html | 237 - .../zh-cn/mozilla/add-ons/code_snippets/index.html | 134 - .../add-ons/code_snippets/js_xpcom/index.html | 97 - .../add-ons/code_snippets/modules/index.html | 37 - .../add-ons/code_snippets/queryselector/index.html | 114 - .../add-ons/code_snippets/timers/index.html | 67 - .../index.html | 470 - .../index.html | 159 - .../index.html | 175 - .../index.html | 35 - .../mozilla/add-ons/extension_packaging/index.html | 38 - .../mozilla/add-ons/install_manifests/index.html | 363 - .../mozilla/add-ons/legacy_add_ons/index.html | 19 - .../mozilla/add-ons/overlay_extensions/index.html | 61 - .../index.html | 91 - files/zh-cn/mozilla/add-ons/plugins/index.html | 116 - .../mozilla/add-ons/plugins/reference/index.html | 16 - .../plugins/samples_and_test_cases/index.html | 21 - .../index.html | 56 - files/zh-cn/mozilla/add-ons/sdk/builder/index.html | 13 - .../add-ons/sdk/guides/content_scripts/index.html | 486 - files/zh-cn/mozilla/add-ons/sdk/guides/index.html | 115 - .../multiprocess_firefox_and_the_sdk/index.html | 212 - .../sdk/guides/working_with_events/index.html | 122 - .../add-ons/sdk/high-level_apis/base64/index.html | 65 - .../sdk/high-level_apis/clipboard/index.html | 101 - .../mozilla/add-ons/sdk/high-level_apis/index.html | 12 - .../sdk/high-level_apis/notifications/index.html | 129 - .../add-ons/sdk/high-level_apis/panel/index.html | 899 - .../add-ons/sdk/high-level_apis/tabs/index.html | 669 - .../add-ons/sdk/high-level_apis/url/index.html | 191 - .../add-ons/sdk/high-level_apis/widget/index.html | 839 - files/zh-cn/mozilla/add-ons/sdk/index.html | 104 - .../mozilla/add-ons/sdk/low-level_apis/index.html | 26 - .../sdk/low-level_apis/test_assert/index.html | 283 - .../sdk/low-level_apis/ui_button_action/index.html | 526 - files/zh-cn/mozilla/add-ons/sdk/tools/index.html | 14 - .../zh-cn/mozilla/add-ons/sdk/tools/jpm/index.html | 652 - .../add-ons/sdk/tools/package_json/index.html | 312 - .../add_a_menu_item_to_firefox/index.html | 92 - .../adding_a_button_to_the_toolbar/index.html | 83 - .../annotator/implementing_the_widget/index.html | 92 - .../add-ons/sdk/tutorials/annotator/index.html | 36 - .../sdk/tutorials/annotator/overview/index.html | 54 - .../sdk/tutorials/display_a_popup/index.html | 135 - .../sdk/tutorials/getting_started/index.html | 172 - .../sdk/tutorials/getting_started_(jpm)/index.html | 162 - .../zh-cn/mozilla/add-ons/sdk/tutorials/index.html | 144 - .../add-ons/sdk/tutorials/installation/index.html | 135 - .../mozilla/add-ons/sdk/tutorials/l10n/index.html | 381 - .../sdk/tutorials/list_open_tabs/index.html | 72 - .../sdk/tutorials/listen_for_page_load/index.html | 42 - .../modifying_the_page_hosted_by_a_tab/index.html | 109 - .../modifying_web_pages_based_on_url/index.html | 210 - .../sdk/tutorials/open_a_web_page/index.html | 52 - .../sdk/tutorials/troubleshooting/index.html | 39 - .../add-ons/sdk/tutorials/unit_testing/index.html | 102 - .../tutorials/\346\227\245\345\277\227/index.html" | 62 - .../index.html" | 49 - .../index.html | 58 - .../add-ons/submitting_an_add-on_to_amo/index.html | 24 - files/zh-cn/mozilla/add-ons/themes/index.html | 65 - .../creating_a_skin_for_firefox/index.html | 28 - .../creating_a_skin_for_firefox/uuid/index.html | 6 - .../mozilla/add-ons/themes/obsolete/index.html | 10 - .../obsolete/theme_changes_in_firefox_3/index.html | 92 - .../embedded_webextensions/index.html | 205 - .../working_with_multiprocess_firefox/index.html | 296 - .../add-ons/\351\233\267\351\270\237/index.html" | 131 - files/zh-cn/mozilla/adding_a_new_event/index.html | 186 - files/zh-cn/mozilla/bugzilla/index.html | 58 - files/zh-cn/mozilla/bugzilla/testopia/index.html | 134 - files/zh-cn/mozilla/chrome_registration/index.html | 229 - .../zh-cn/mozilla/command_line_options/index.html | 407 - files/zh-cn/mozilla/connect/index.html | 122 - .../mozilla/debugging/existing_tools/index.html | 36 - files/zh-cn/mozilla/debugging/index.html | 139 - .../firefox/australis_add-on_compat/index.html | 130 - .../mozilla/firefox/developer_edition/index.html | 57 - .../firefox/enterprise_deployment/index.html | 138 - .../zh-cn/mozilla/firefox/headless_mode/index.html | 270 - .../cross_process_object_wrappers/index.html | 114 - .../debugging_frame_scripts/index.html | 53 - .../firefox/multiprocess_firefox/faq/index.html | 18 - .../firefox/multiprocess_firefox/index.html | 78 - .../limitations_of_chrome_scripts/index.html | 197 - .../limitations_of_frame_scripts/index.html | 101 - .../communicating_with_frame_scripts/index.html | 205 - .../frame_script_environment/index.html | 104 - .../frame_script_loading_and_lifetime/index.html | 124 - .../message_manager/index.html | 68 - .../message_manager_overview/index.html | 442 - .../message_manager/performance/index.html | 292 - .../multiprocess_firefox/motivation/index.html | 44 - .../index.html | 21 - .../technical_overview/index.html | 164 - .../which_uris_load_where/index.html | 53 - files/zh-cn/mozilla/firefox/privacy/index.html | 22 - .../storage_access_policy/errors/index.html | 24 - .../index.html" | 39 - .../privacy/storage_access_policy/index.html | 261 - .../firefox/privacy/tracking_protection/index.html | 87 - .../mozilla/firefox/the_about_protocol/index.html | 163 - files/zh-cn/mozilla/firefox_for_android/index.html | 65 - files/zh-cn/mozilla/gecko/index.html | 74 - files/zh-cn/mozilla/gecko/versions/index.html | 130 - .../\345\265\214\345\205\245mozilla/index.html" | 49 - .../how_mozilla_determines_mime_types/index.html | 94 - .../index.html | 48 - .../index.html | 76 - files/zh-cn/mozilla/instantbird/index.html | 62 - .../introduction_to_layout_in_mozilla/index.html | 360 - .../ipdl/creating_a_new_protocol/index.html | 32 - files/zh-cn/mozilla/ipdl/index.html | 33 - .../ipdl/\345\205\245\351\227\250/index.html" | 670 - .../index.html | 145 - .../javascript_code_modules/assert.jsm/index.html | 448 - .../javascript_code_modules/dict.jsm/index.html | 344 - .../downloads.jsm/download/index.html | 335 - .../downloads.jsm/index.html | 306 - .../geometry.jsm/index.html | 19 - .../geometry.jsm/services.jsm/index.html | 25 - .../javascript_code_modules/http.jsm/index.html | 74 - .../mozilla/javascript_code_modules/index.html | 84 - .../promise.jsm/deferred/index.html | 190 - .../javascript_code_modules/promise.jsm/index.html | 172 - .../promise.jsm/promise/index.html | 226 - .../javascript_code_modules/timer.jsm/index.html | 33 - .../javascript_code_modules/using/index.html | 194 - files/zh-cn/mozilla/javascript_tips/index.html | 112 - files/zh-cn/mozilla/js-ctypes/index.html | 53 - .../js-ctypes_reference/ctypes/index.html | 534 - .../js-ctypes/js-ctypes_reference/index.html | 96 - .../declaring_and_using_callbacks/index.html | 100 - .../mozilla/js-ctypes/using_js-ctypes/index.html | 210 - .../using_js-ctypes/memory_management/index.html | 88 - .../working_with_arraybuffers/index.html | 212 - files/zh-cn/mozilla/localization/faq/index.html | 17 - files/zh-cn/mozilla/localization/index.html | 20 - .../localization/l10n_style_guide/index.html | 482 - .../localizing_extension_descriptions/index.html | 60 - files/zh-cn/mozilla/mercurial/basics/index.html | 56 - files/zh-cn/mozilla/mercurial/index.html | 43 - .../mercurial/installing_mercurial/index.html | 145 - files/zh-cn/mozilla/mfbt/index.html | 48 - files/zh-cn/mozilla/mozilla_on_github/index.html | 121 - .../index.html | 94 - .../performance/about_colon_memory/index.html | 144 - files/zh-cn/mozilla/performance/index.html | 138 - .../performance/scroll-linked_effects/index.html | 121 - .../persona/bootstrapping_persona/index.html | 29 - files/zh-cn/mozilla/persona/branding/index.html | 79 - .../persona/browser_compatibility/index.html | 89 - files/zh-cn/mozilla/persona/glossary/index.html | 61 - files/zh-cn/mozilla/persona/index.html | 138 - .../mozilla/persona/protocol_overview/index.html | 96 - files/zh-cn/mozilla/persona/quick_setup/index.html | 140 - .../persona/remote_verification_api/index.html | 120 - .../persona/security_considerations/index.html | 55 - files/zh-cn/mozilla/persona/why_persona/index.html | 30 - files/zh-cn/mozilla/preferences/index.html | 6 - .../mozilla_networking_preferences/index.html | 536 - .../browser.altclicksave/index.html | 12 - .../index.html | 31 - .../index.html | 14 - .../browser.urlbar.trimurls/index.html | 12 - .../dom.event.clipboardevents.enabled/index.html | 12 - .../preferences/preference_reference/index.html | 8 - .../javascript.options.strict/index.html | 13 - .../ui.alertnotificationorigin/index.html | 12 - .../ui.spellcheckerunderline/index.html | 12 - .../ui.spellcheckerunderlinestyle/index.html | 13 - .../ui.tooltipdelay/index.html | 13 - .../view_source.syntax_highlight/index.html | 6 - .../mozilla/projects/crash_reporting/index.html | 47 - files/zh-cn/mozilla/projects/emscripten/index.html | 37 - files/zh-cn/mozilla/projects/index.html | 14 - files/zh-cn/mozilla/projects/l20n/index.html | 127 - files/zh-cn/mozilla/projects/nspr/index.html | 60 - .../mozilla/projects/nspr/reference/index.html | 770 - .../memory_management_operations/index.html | 424 - files/zh-cn/mozilla/projects/psm/index.html | 15 - files/zh-cn/mozilla/projects/rhino/bsf/index.html | 10 - .../mozilla/projects/rhino/community/index.html | 24 - .../mozilla/projects/rhino/debugger/index.html | 220 - .../projects/rhino/documentation/index.html | 81 - .../projects/rhino/download_rhino/index.html | 106 - .../projects/rhino/embedding_tutorial/index.html | 221 - .../mozilla/projects/rhino/examples/index.html | 35 - files/zh-cn/mozilla/projects/rhino/index.html | 22 - .../mozilla/projects/rhino/license/index.html | 47 - .../mozilla/projects/rhino/overview/index.html | 78 - .../rhino/requirements_and_limitations/index.html | 24 - .../projects/rhino/scripting_java/index.html | 397 - .../zh-cn/mozilla/projects/rhino/shell/index.html | 179 - files/zh-cn/mozilla/projects/social_api/index.html | 97 - .../mozilla/projects/social_api/share/index.html | 86 - .../spidermonkey/build_documentation/index.html | 294 - .../comparision_of_js_engines/index.html | 105 - .../zh-cn/mozilla/projects/spidermonkey/index.html | 132 - .../spidermonkey/internals/bytecodes/index.html | 30 - .../spidermonkey/internals/functions/index.html | 73 - .../projects/spidermonkey/internals/index.html | 292 - .../index.html | 382 - .../index.html" | 11 - .../jsapi_reference/boolean_to_jsval/index.html | 53 - .../spidermonkey/jsapi_reference/index.html | 646 - .../js_defineconstdoubles/index.html | 59 - .../jsapi_reference/js_doublecolon_call/index.html | 92 - .../js_doublecolon_ordinarytoprimitive/index.html | 66 - .../jsapi_reference/js_evaluatescript/index.html | 69 - .../jsapi_reference/js_getversion/index.html | 29 - .../jsapi_reference/js_hasownproperty/index.html | 73 - .../jsapi_reference/js_newruntime/index.html | 33 - .../jsapi_reference/js_seterrorreporter/index.html | 61 - .../jsapi_reference/js_valuetostring/index.html | 45 - .../jsapi_reference/jsclass/index.html | 137 - .../jsapi_reference/jsconstdoublespec/index.html | 56 - .../jsapi_reference/jserrorreport/index.html | 6 - .../jsapi_reference/jsproperty/index.html | 29 - .../jspropertydescriptor/index.html | 69 - .../jsapi_reference/jsruntime/index.html | 29 - .../projects/spidermonkey/parser_api/index.html | 1625 - .../projects/spidermonkey/releases/index.html | 42 - .../projects/spidermonkey/split_object/index.html | 72 - files/zh-cn/mozilla/rust/index.html | 40 - files/zh-cn/mozilla/tech/index.html | 7 - .../tech/toolkit_api/extisessionstorage/index.html | 48 - files/zh-cn/mozilla/tech/toolkit_api/index.html | 18 - .../index.html | 26 - files/zh-cn/mozilla/tech/xpcom/glue/index.html | 71 - .../mozilla/tech/xpcom/guide/arrays/index.html | 573 - .../an_overview_of_xpcom/index.html | 535 - .../building_the_weblock_ui/index.html | 297 - .../component_internals/index.html | 217 - .../creating_the_component_code/index.html | 727 - .../finishing_the_component/index.html | 337 - .../xpcom/guide/creating_components/index.html | 278 - .../packaging_weblock/index.html | 136 - .../guide/creating_components/preface/index.html | 83 - .../guide/creating_components/resources/index.html | 10 - .../setting_up_the_gecko_sdk/index.html | 204 - .../starting_weblock/index.html | 1104 - .../using_xpcom_components/index.html | 311 - .../index.html | 388 - .../mozilla/tech/xpcom/guide/hashtables/index.html | 282 - files/zh-cn/mozilla/tech/xpcom/guide/index.html | 15 - .../tech/xpcom/guide/internal_strings/index.html | 809 - files/zh-cn/mozilla/tech/xpcom/index.html | 44 - .../index.html | 141 - .../components.utils.cloneinto/index.html | 290 - .../components.utils.getglobalforobject/index.html | 41 - .../tech/xpcom/language_bindings/index.html | 20 - .../xpcom/language_bindings/javaxpcom/index.html | 49 - .../index.html" | 65 - .../javaxpcom/\345\274\200\345\217\221/index.html" | 26 - .../xpcom/language_bindings/pyxpcom/index.html | 67 - .../xpcom/language_bindings/xpconnect/index.html | 67 - .../tech/xpcom/observer_notifications/index.html | 880 - .../tech/xpcom/reference/glue_classes/index.html | 16 - .../nscomptr/getting_started_guide/index.html | 478 - .../reference/glue_classes/nscomptr/index.html | 56 - .../zh-cn/mozilla/tech/xpcom/reference/index.html | 14 - .../tech/xpcom/reference/interface/index.html | 11 - .../interface/nsiaccessibleprovider/index.html | 45 - .../reference/interface/nsiclipboard/index.html | 91 - .../interface/nsiclipboardhelper/index.html | 65 - .../interface/nsiconsoleservice/index.html | 215 - .../nsidirectoryserviceprovider/index.html | 65 - .../interface/nsidomclientrect/index.html | 92 - .../xpcom/reference/interface/nsifile/index.html | 828 - .../reference/interface/nsifilepicker/index.html | 376 - .../reference/interface/nsihttpchannel/index.html | 365 - .../reference/interface/nsiidleservice/index.html | 119 - .../reference/interface/nsilocalfile/index.html | 478 - .../reference/interface/nsiprocess/index.html | 283 - .../xpcom/reference/interface/nsiprompt/index.html | 55 - .../interface/nsipromptservice/index.html | 696 - .../nsiscriptableunicodeconverter/index.html | 609 - .../interface/nsisyncmessagesender/index.html | 65 - .../xpcom/reference/interface/nsitimer/index.html | 285 - .../interface/nsitraceablechannel/index.html | 71 - .../xpcom/reference/interface/nsiuri/index.html | 407 - .../interface/nsixmlhttprequest/index.html | 90 - .../xpcom/setting_http_request_headers/index.html | 261 - files/zh-cn/mozilla/tech/xpidl/index.html | 502 - files/zh-cn/mozilla/tech/xpidl/syntax/index.html | 127 - files/zh-cn/mozilla/tech/xpidl/xpidl/index.html | 58 - .../tech/xul/attribute/acceltext/index.html | 23 - .../tech/xul/attribute/accesskey/index.html | 43 - .../xul/attribute/activetitlebarcolor/index.html | 19 - .../mozilla/tech/xul/attribute/align/index.html | 54 - .../tech/xul/attribute/allowevents/index.html | 30 - .../attribute/allownegativeassertions/index.html | 18 - .../tech/xul/attribute/autocheck/index.html | 24 - .../tech/xul/attribute/autoscroll/index.html | 12 - .../xul/attribute/buttonaccesskeyaccept/index.html | 20 - .../xul/attribute/buttonlabelextra1/index.html | 19 - .../xul/attribute/buttonlabelextra2/index.html | 19 - .../mozilla/tech/xul/attribute/buttons/index.html | 28 - .../mozilla/tech/xul/attribute/checked/index.html | 24 - .../mozilla/tech/xul/attribute/class/index.html | 23 - .../xul/attribute/coalesceduplicatearcs/index.html | 17 - .../tech/xul/attribute/collapsed/index.html | 27 - .../mozilla/tech/xul/attribute/command/index.html | 30 - .../tech/xul/attribute/container/index.html | 18 - .../mozilla/tech/xul/attribute/control/index.html | 23 - .../mozilla/tech/xul/attribute/crop/index.html | 37 - .../tech/xul/attribute/description/index.html | 23 - .../mozilla/tech/xul/attribute/dir/index.html | 39 - .../mozilla/tech/xul/attribute/disabled/index.html | 38 - .../mozilla/tech/xul/attribute/flex/index.html | 23 - .../mozilla/tech/xul/attribute/href/index.html | 24 - .../zh-cn/mozilla/tech/xul/attribute/id/index.html | 41 - .../tech/xul/attribute/image.onload/index.html | 12 - .../mozilla/tech/xul/attribute/image/index.html | 25 - .../tech/xul/attribute/increment/index.html | 15 - files/zh-cn/mozilla/tech/xul/attribute/index.html | 304 - .../mozilla/tech/xul/attribute/label/index.html | 41 - .../mozilla/tech/xul/attribute/max/index.html | 20 - .../tech/xul/attribute/menuitem.key/index.html | 23 - .../tech/xul/attribute/menuitem.name/index.html | 38 - .../tech/xul/attribute/menuitem.type/index.html | 28 - .../mozilla/tech/xul/attribute/min/index.html | 16 - .../mozilla/tech/xul/attribute/name/index.html | 16 - .../tech/xul/attribute/onpopupshowing/index.html | 21 - .../tech/xul/attribute/onpopupshown/index.html | 21 - .../mozilla/tech/xul/attribute/orient/index.html | 16 - .../mozilla/tech/xul/attribute/pending/index.html | 15 - .../mozilla/tech/xul/attribute/persist/index.html | 24 - .../mozilla/tech/xul/attribute/selected/index.html | 28 - .../tech/xul/attribute/selectedindex/index.html | 15 - .../mozilla/tech/xul/attribute/tabindex/index.html | 18 - .../mozilla/tech/xul/attribute/validate/index.html | 27 - .../mozilla/tech/xul/attribute/value/index.html | 30 - .../zh-cn/mozilla/tech/xul/broadcaster/index.html | 91 - files/zh-cn/mozilla/tech/xul/browser/index.html | 409 - files/zh-cn/mozilla/tech/xul/button/index.html | 528 - files/zh-cn/mozilla/tech/xul/checkbox/index.html | 329 - files/zh-cn/mozilla/tech/xul/command/index.html | 105 - .../tech/xul/deprecated_defunct_markup/index.html | 50 - files/zh-cn/mozilla/tech/xul/dialog/index.html | 364 - files/zh-cn/mozilla/tech/xul/events/index.html | 497 - files/zh-cn/mozilla/tech/xul/image/index.html | 145 - files/zh-cn/mozilla/tech/xul/index.html | 79 - files/zh-cn/mozilla/tech/xul/key/index.html | 166 - files/zh-cn/mozilla/tech/xul/label/index.html | 298 - .../mozilla/tech/xul/list_of_commands/index.html | 196 - files/zh-cn/mozilla/tech/xul/listbox/index.html | 480 - files/zh-cn/mozilla/tech/xul/listheader/index.html | 180 - files/zh-cn/mozilla/tech/xul/menu/index.html | 370 - files/zh-cn/mozilla/tech/xul/menubar/index.html | 113 - files/zh-cn/mozilla/tech/xul/menuitem/index.html | 575 - files/zh-cn/mozilla/tech/xul/menulist/index.html | 509 - files/zh-cn/mozilla/tech/xul/menupopup/index.html | 324 - .../mozilla/tech/xul/menuseparator/index.html | 435 - .../mozilla/tech/xul/method/extra1/index.html | 15 - .../zh-cn/mozilla/tech/xul/method/focus/index.html | 15 - .../tech/xul/method/getbrowserfortab/index.html | 15 - .../mozilla/tech/xul/method/getbutton/index.html | 15 - .../mozilla/tech/xul/method/increase/index.html | 21 - files/zh-cn/mozilla/tech/xul/method/index.html | 170 - .../zh-cn/mozilla/tech/xul/method/reset/index.html | 15 - .../zh-cn/mozilla/tech/xul/method/stop/index.html | 15 - files/zh-cn/mozilla/tech/xul/namespaces/index.html | 73 - files/zh-cn/mozilla/tech/xul/popup/index.html | 23 - .../tech/xul/property/accessibletype/index.html | 183 - .../mozilla/tech/xul/property/accesskey/index.html | 21 - .../xul/property/browser.preferences/index.html | 15 - .../mozilla/tech/xul/property/buttons/index.html | 10 - .../mozilla/tech/xul/property/command/index.html | 21 - .../mozilla/tech/xul/property/crop/index.html | 21 - .../tech/xul/property/defaultvalue/index.html | 15 - .../mozilla/tech/xul/property/disabled/index.html | 21 - .../mozilla/tech/xul/property/image/index.html | 21 - files/zh-cn/mozilla/tech/xul/property/index.html | 266 - .../mozilla/tech/xul/property/label/index.html | 21 - .../tech/xul/property/labelelement/index.html | 21 - .../xul/property/markupdocumentviewer/index.html | 15 - .../zh-cn/mozilla/tech/xul/property/max/index.html | 15 - .../tech/xul/property/menuitem.control/index.html | 21 - .../tech/xul/property/parentcontainer/index.html | 21 - .../mozilla/tech/xul/property/selected/index.html | 18 - .../tech/xul/property/selectedindex/index.html | 21 - .../tech/xul/property/selecteditem/index.html | 21 - .../tech/xul/property/selectionstart/index.html | 16 - .../tech/xul/property/spinbuttons/index.html | 15 - .../mozilla/tech/xul/property/tabindex/index.html | 21 - .../tech/xul/property/textbox.value/index.html | 15 - .../mozilla/tech/xul/property/value/index.html | 21 - files/zh-cn/mozilla/tech/xul/radio/index.html | 379 - files/zh-cn/mozilla/tech/xul/radiogroup/index.html | 275 - files/zh-cn/mozilla/tech/xul/script/index.html | 117 - files/zh-cn/mozilla/tech/xul/statusbar/index.html | 131 - files/zh-cn/mozilla/tech/xul/style/index.html | 6 - .../tech/xul/style/menuitem-iconic/index.html | 16 - .../tech/xul/style/menuitem-non-iconic/index.html | 16 - files/zh-cn/mozilla/tech/xul/tabbox/index.html | 156 - .../mozilla/tech/xul/template_guide/index.html | 68 - files/zh-cn/mozilla/tech/xul/textbox/index.html | 653 - .../mozilla/tech/xul/toolbarpalette/index.html | 103 - .../toolbars/creating_toolbar_buttons/index.html | 183 - .../xul/toolbars/custom_toolbar_button/index.html | 332 - files/zh-cn/mozilla/tech/xul/toolbars/index.html | 65 - files/zh-cn/mozilla/tech/xul/toolbox/index.html | 6 - files/zh-cn/mozilla/tech/xul/tree/index.html | 512 - .../tech/xul/tutorial/adding_buttons/index.html | 98 - .../xul/tutorial/adding_event_handlers/index.html | 161 - .../xul/tutorial/adding_html_elements/index.html | 113 - .../tutorial/adding_labels_and_images/index.html | 40 - .../xul/tutorial/adding_more_elements/index.html | 115 - .../xul/tutorial/adding_style_sheets/index.html | 10 - .../tech/xul/tutorial/anonymous_content/index.html | 166 - .../tech/xul/tutorial/box_model_details/index.html | 6 - .../tech/xul/tutorial/content_panels/index.html | 63 - .../tech/xul/tutorial/creating_a_skin/index.html | 177 - .../tech/xul/tutorial/creating_a_window/index.html | 116 - .../xul/tutorial/creating_an_installer/index.html | 98 - .../tech/xul/tutorial/creating_dialogs/index.html | 6 - .../xul/tutorial/document_object_model/index.html | 220 - .../xul/tutorial/element_positioning/index.html | 254 - .../xul/tutorial/features_of_a_window/index.html | 6 - .../mozilla/tech/xul/tutorial/grids/index.html | 175 - .../tech/xul/tutorial/groupboxes/index.html | 85 - files/zh-cn/mozilla/tech/xul/tutorial/index.html | 171 - .../tech/xul/tutorial/input_controls/index.html | 110 - .../tech/xul/tutorial/introduction/index.html | 70 - .../xul/tutorial/introduction_to_rdf/index.html | 109 - .../tech/xul/tutorial/list_controls/index.html | 133 - .../tech/xul/tutorial/localization/index.html | 296 - .../tech/xul/tutorial/manifest_files/index.html | 113 - .../tutorial/modifying_a_xul_interface/index.html | 118 - .../tutorial/modifying_the_default_skin/index.html | 63 - .../xul/tutorial/more_button_features/index.html | 216 - .../xul/tutorial/more_event_handlers/index.html | 183 - .../xul/tutorial/more_menu_features/index.html | 108 - .../tech/xul/tutorial/more_wizards/index.html | 64 - .../tech/xul/tutorial/numeric_controls/index.html | 78 - .../tech/xul/tutorial/popup_menus/index.html | 6 - .../tech/xul/tutorial/progress_meters/index.html | 58 - .../tech/xul/tutorial/property_files/index.html | 97 - .../tech/xul/tutorial/rdf_datasources/index.html | 267 - .../tech/xul/tutorial/scroll_bars/index.html | 9 - .../tech/xul/tutorial/scrolling_menus/index.html | 45 - .../tech/xul/tutorial/simple_menu_bars/index.html | 159 - .../mozilla/tech/xul/tutorial/splitters/index.html | 85 - .../tech/xul/tutorial/stack_positioning/index.html | 30 - .../tech/xul/tutorial/stacks_and_decks/index.html | 71 - .../tech/xul/tutorial/styling_a_tree/index.html | 12 - .../mozilla/tech/xul/tutorial/tabboxes/index.html | 125 - .../mozilla/tech/xul/tutorial/templates/index.html | 77 - .../tech/xul/tutorial/the_box_model/index.html | 39 - .../tech/xul/tutorial/the_chrome_url/index.html | 74 - .../mozilla/tech/xul/tutorial/toolbars/index.html | 101 - .../mozilla/tech/xul/tutorial/trees/index.html | 8 - .../tech/xul/tutorial/using_spacers/index.html | 111 - .../tutorial/using_xbl_from_stylesheets/index.html | 223 - .../xbl\344\273\213\347\273\215/index.html" | 104 - .../xpcom_\346\216\245\345\217\243/index.html" | 179 - .../tech/xul/tutorial/xul_structure/index.html | 43 - .../index.html" | 68 - files/zh-cn/mozilla/tech/xul/vbox/index.html | 130 - files/zh-cn/mozilla/tech/xul/window/index.html | 281 - .../mozilla/tech/xul/xul_reference/index.html | 20 - files/zh-cn/mozilla/thunderbird/index.html | 75 - .../mail_client_architecture_overview/index.html | 94 - .../thunderbird/mailnews_protocols/index.html | 31 - .../mozilla/toolkit_version_format/index.html | 88 - files/zh-cn/mozilla/webidl_bindings/index.html | 920 - .../index.html | 19 - .../index.html" | 123 - .../mozilla/\346\227\245\345\216\206/index.html" | 75 - files/zh-cn/mozilla_dom_hacking_guide/index.html | 795 - .../zh-cn/mozilla_mathml_project/fonts/index.html | 95 - files/zh-cn/mozilla_mathml_project/index.html | 76 - .../zh-cn/mozilla_mathml_project/start/index.html | 77 - .../zh-cn/mozilla_quirks_mode_behavior/index.html | 116 - files/zh-cn/mozilla_svg_project/index.html | 111 - files/zh-cn/mozilla_web_developer_faq/index.html | 123 - .../mozilla\344\270\255\347\232\204xml/index.html" | 227 - .../zh-cn/new_compatibility_tables_beta/index.html | 24 - files/zh-cn/npclass/index.html | 97 - files/zh-cn/npobject/index.html | 63 - files/zh-cn/nsidomparser/index.html | 56 - files/zh-cn/nss/building/index.html | 116 - files/zh-cn/nss/index.html | 172 - .../index.html | 148 - files/zh-cn/nss/key_log_format/index.html | 20 - files/zh-cn/nss/overview/index.html | 71 - files/zh-cn/nss/tools/index.html | 89 - .../index.html" | 924 - files/zh-cn/places/index.html | 68 - .../examples/index.html | 404 - .../index.html | 155 - files/zh-cn/spidermonkey/hacking_tips/index.html | 159 - .../index.html | 132 - files/zh-cn/storage/index.html | 401 - .../structure_of_an_installable_bundle/index.html | 144 - files/zh-cn/the_mozilla_platform/index.html | 99 - files/zh-cn/theme_packaging/index.html | 108 - files/zh-cn/tools/scratchpad/index.html | 118 - files/zh-cn/tools/webide/index.html | 271 - files/zh-cn/tools/webide/monitor/index.html | 158 - files/zh-cn/tools/webide/opening_webide/index.html | 26 - .../index.html" | 53 - .../index.html | 58 - .../zh-cn/using_breakpoints_in_venkman/index.html | 73 - .../index.html | 13 - files/zh-cn/using_the_clipboard/index.html | 158 - files/zh-cn/using_workers_in_extensions/index.html | 191 - files/zh-cn/venkman/index.html | 89 - files/zh-cn/venkman_internals/index.html | 59 - files/zh-cn/venkman_introduction/index.html | 351 - .../api/cameracontrol/getpreviewstream/index.html | 64 - files/zh-cn/web/api/cameracontrol/index.html | 88 - files/zh-cn/web/api/identitymanager/index.html | 43 - .../zh-cn/web/api/identitymanager/watch/index.html | 59 - .../using_indexeddb_in_chrome/index.html | 27 - files/zh-cn/web/api/navigator/id/index.html | 45 - .../zh-cn/web/api/navigator/mozsettings/index.html | 32 - files/zh-cn/web/api/navigator/mozsms/index.html | 112 - .../zh-cn/web/api/using_the_browser_api/index.html | 214 - .../webvr_api/webvr_environment_setup/index.html | 110 - files/zh-cn/web/css/-moz-binding/index.html | 114 - .../web/css/-moz-border-bottom-colors/index.html | 131 - files/zh-cn/web/css/-ms-overflow-style/index.html | 50 - .../web/css/_doublecolon_-ms-check/index.html | 169 - .../web/css/_doublecolon_-ms-clear/index.html | 22 - files/zh-cn/web/css/overflow-clip-box/index.html | 81 - files/zh-cn/web/events/domlinkadded/index.html | 57 - files/zh-cn/web/events/mozafterpaint/index.html | 179 - files/zh-cn/web/events/tabopen/index.html | 57 - files/zh-cn/web/guide/api/camera/index.html | 219 - .../guide/css/getting_started/xml_data/index.html | 241 - .../ecmascript_7_support_in_mozilla/index.html | 82 - .../javascript/new_in_javascript/1.1/index.html | 71 - .../javascript/new_in_javascript/1.2/index.html | 89 - .../javascript/new_in_javascript/1.3/index.html | 138 - .../javascript/new_in_javascript/1.4/index.html | 25 - .../javascript/new_in_javascript/1.5/index.html | 42 - .../javascript/new_in_javascript/1.6/index.html | 35 - .../javascript/new_in_javascript/1.7/index.html | 40 - .../javascript/new_in_javascript/1.8.1/index.html | 29 - .../javascript/new_in_javascript/1.8.5/index.html | 122 - .../javascript/new_in_javascript/1.8/index.html | 39 - .../ecmascript_5_support_in_mozilla/index.html | 41 - .../ecmascript_6_support_in_mozilla/index.html | 282 - .../web/javascript/new_in_javascript/index.html | 99 - .../functions/arguments/caller/index.html | 47 - .../global_objects/array/observe/index.html | 92 - .../global_objects/array/unobserve/index.html | 86 - .../global_objects/arraybuffer/transfer/index.html | 116 - .../global_objects/date/tolocaleformat/index.html | 73 - .../global_objects/function/arity/index.html | 16 - .../global_objects/function/isgenerator/index.html | 40 - .../reference/global_objects/iterator/index.html | 188 - .../global_objects/number/tointeger/index.html | 97 - .../global_objects/object/count/index.html | 88 - .../global_objects/object/eval/index.html | 85 - .../global_objects/object/getnotifier/index.html | 93 - .../global_objects/object/nosuchmethod/index.html | 208 - .../global_objects/object/observe/index.html | 160 - .../global_objects/object/parent/index.html | 43 - .../global_objects/object/unobserve/index.html | 133 - .../global_objects/object/unwatch/index.html | 105 - .../global_objects/object/watch/index.html | 201 - .../global_objects/parallelarray/index.html | 53 - .../global_objects/string/quote/index.html | 116 - .../operators/array_comprehensions/index.html | 157 - .../operators/expression_closures/index.html | 76 - .../operators/generator_comprehensions/index.html | 193 - .../reference/statements/for_each...in/index.html | 69 - files/zh-cn/web/rdf/index.html | 82 - .../tcp_ip_\345\256\211\345\205\250/index.html" | 50 - .../vulnerabilities/index.html | 47 - .../index.html" | 35 - .../web/security/site_identity_button/index.html | 27 - files/zh-cn/web/svg/faq/index.html | 100 - .../index.html" | 62 - files/zh-cn/window_icons/index.html | 22 - files/zh-cn/working_with_bfcache/index.html | 19 - files/zh-cn/xml_extras/index.html | 114 - files/zh-cn/xml_web_services/index.html | 51 - files/zh-cn/xpi/index.html | 24 - files/zh-cn/xquery/index.html | 20 - files/zh-cn/xslt_2.0/index.html | 13 - .../index.html | 19 - files/zh-cn/xtech_2005_presentations/index.html | 6 - .../index.html | 15 - .../index.html" | 105 - files/zh-cn/xul_element_attributes/index.html | 594 - files/zh-cn/xul_explorer/index.html | 78 - .../index.html" | 89 - files/zh-cn/xulrunner/index.html | 108 - .../xulrunner/what_xulrunner_provides/index.html | 64 - files/zh-cn/xulrunner_old_releases/index.html | 23 - files/zh-cn/xulrunner_tips/index.html | 213 - files/zh-cn/zones/index.html | 55 - .../index.html" | 81 - .../index.html" | 42 - .../index.html" | 169 - .../\347\244\276\345\214\272/index.html" | 10 - .../bug_writing_guidelines/index.html" | 366 - .../index.html" | 43 - .../webrender/index.html" | 52 - 827 files changed, 166260 deletions(-) delete mode 100644 files/zh-cn/_wikihistory.json delete mode 100644 files/zh-cn/adding_extensions_using_the_windows_registry/index.html delete mode 100644 files/zh-cn/aggregating_the_in-memory_datasource/index.html delete mode 100644 files/zh-cn/archive/add-ons/developing_add-ons/index.html delete mode 100644 files/zh-cn/archive/add-ons/downloading_json_and_javascript_in_extensions/index.html delete mode 100644 files/zh-cn/archive/add-ons/index.html delete mode 100644 files/zh-cn/archive/add-ons/installing_extensions_and_themes_from_web_pages/index.html delete mode 100644 files/zh-cn/archive/add-ons/jetpack_processes/index.html delete mode 100644 files/zh-cn/archive/add-ons/multiple_item_packaging/index.html delete mode 100644 files/zh-cn/archive/add-ons/signing_an_xpi/index.html delete mode 100644 files/zh-cn/archive/apps/advanced_topics/index.html delete mode 100644 files/zh-cn/archive/apps/icon_implementation_for_apps/index.html delete mode 100644 files/zh-cn/archive/apps/index.html delete mode 100644 files/zh-cn/archive/apps/tools_and_frameworks/app_templates/index.html delete mode 100644 files/zh-cn/archive/apps/tools_and_frameworks/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/alarm_api/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/bluetoothstatuschangedevent/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/domrequest/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/navigator/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/navigator/mozhaspendingmessage/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/navigator/mozsetmessagehandler/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/navigator/moztelephony/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/permissions_api/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/settingslock/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/settingslock/set/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/settingsmanager/index.html delete mode 100644 files/zh-cn/archive/b2g_os/api/tpc_socket_api/index.html delete mode 100644 files/zh-cn/archive/b2g_os/apps/index.html delete mode 100644 files/zh-cn/archive/b2g_os/apps/writing_a_web_app_for_firefox_os/index.html delete mode 100644 files/zh-cn/archive/b2g_os/automated_testing/gaia_performance_tests/index.html delete mode 100644 files/zh-cn/archive/b2g_os/automated_testing/gaia_unit_tests/index.html delete mode 100644 files/zh-cn/archive/b2g_os/automated_testing/index.html delete mode 100644 files/zh-cn/archive/b2g_os/building/index.html delete mode 100644 files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/b2g_os_update_packages/index.html delete mode 100644 files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/firefox_os_build_overview/index.html delete mode 100644 files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/index.html delete mode 100644 files/zh-cn/archive/b2g_os/building_the_b2g_desktop_client/index.html delete mode 100644 files/zh-cn/archive/b2g_os/customization_with_the_.userconfig_file/index.html delete mode 100644 files/zh-cn/archive/b2g_os/debugging/debugging_b2g_using_gdb/index.html delete mode 100644 files/zh-cn/archive/b2g_os/debugging/debugging_ooms/index.html delete mode 100644 files/zh-cn/archive/b2g_os/debugging/developer_settings/index.html delete mode 100644 files/zh-cn/archive/b2g_os/debugging/index.html delete mode 100644 files/zh-cn/archive/b2g_os/debugging/taking_screenshots/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_firefox_os/customizing_the_b2g.sh_script/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_firefox_os/filing_bugs_against_firefox_os/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_firefox_os/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_firefox_os/market_customizations_guide/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_firefox_os/modifying_hosts_file/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_firefox_os/quickstart_guide_to_gaia_development/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/customizing_build-time_apps/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/customizing_the_keyboard/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/different_ways_to_run_gaia/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/localizing_firefox_os/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/make_options_reference/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/making_gaia_code_changes/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/running_the_gaia_codebase/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/testing_gaia_code_changes/index.html delete mode 100644 files/zh-cn/archive/b2g_os/developing_gaia/understanding_the_gaia_codebase/index.html delete mode 100644 files/zh-cn/archive/b2g_os/events/disabled/index.html delete mode 100644 files/zh-cn/archive/b2g_os/events/index.html delete mode 100644 files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/1.x/index.html delete mode 100644 "files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/1.x/\346\214\211\351\222\256/index.html" delete mode 100644 files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/index.html delete mode 100644 files/zh-cn/archive/b2g_os/firefox_os_apps/index.html delete mode 100644 files/zh-cn/archive/b2g_os/firefox_os_build_prerequisites/index.html delete mode 100644 files/zh-cn/archive/b2g_os/firefox_os_faq/index.html delete mode 100644 files/zh-cn/archive/b2g_os/index.html delete mode 100644 files/zh-cn/archive/b2g_os/installing_on_a_mobile_device/index.html delete mode 100644 files/zh-cn/archive/b2g_os/introduction/index.html delete mode 100644 files/zh-cn/archive/b2g_os/phone_guide/best_practices_open_reference_devices/index.html delete mode 100644 files/zh-cn/archive/b2g_os/phone_guide/flame/index.html delete mode 100644 files/zh-cn/archive/b2g_os/phone_guide/index.html delete mode 100644 files/zh-cn/archive/b2g_os/phone_guide/phone_specs/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/apps_architecture/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/architecture/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/feature_support_chart/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/build_system_primer/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/browser/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/settings/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/system/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/window_management/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/hacking/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/gaia/introduction_to_gaia/index.html delete mode 100644 "files/zh-cn/archive/b2g_os/platform/gaia/weinre\350\277\234\347\250\213\350\260\203\350\257\225\345\267\245\345\205\267/index.html" delete mode 100644 files/zh-cn/archive/b2g_os/platform/gonk/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/out_of_memory_management_on_firefox_os/index.html delete mode 100644 files/zh-cn/archive/b2g_os/platform/settings_list/index.html delete mode 100644 files/zh-cn/archive/b2g_os/porting/index.html delete mode 100644 files/zh-cn/archive/b2g_os/preparing_for_your_first_b2g_build/index.html delete mode 100644 files/zh-cn/archive/b2g_os/quickstart/index.html delete mode 100644 files/zh-cn/archive/b2g_os/quickstart/your_first_app/index.html delete mode 100644 "files/zh-cn/archive/b2g_os/quickstart/\345\274\200\346\272\220web\345\272\224\347\224\250\347\250\213\345\272\217\347\256\200\344\273\213/index.html" delete mode 100644 files/zh-cn/archive/b2g_os/running_tests_on_firefox_os_for_developers/index.html delete mode 100644 files/zh-cn/archive/b2g_os/screencast_series_colon__app_basics_for_firefox_os/index.html delete mode 100644 files/zh-cn/archive/b2g_os/security/application_security/index.html delete mode 100644 files/zh-cn/archive/b2g_os/security/index.html delete mode 100644 files/zh-cn/archive/b2g_os/security/security_model/index.html delete mode 100644 files/zh-cn/archive/b2g_os/simulator/index.html delete mode 100644 files/zh-cn/archive/b2g_os/simulator/simulator_walkthrough/index.html delete mode 100644 files/zh-cn/archive/b2g_os/using_firefox_os_simulator/index.html delete mode 100644 files/zh-cn/archive/b2g_os/using_the_app_manager/index.html delete mode 100644 files/zh-cn/archive/b2g_os/using_the_b2g_emulators/index.html delete mode 100644 files/zh-cn/archive/css3/index.html delete mode 100644 files/zh-cn/archive/firefox_os/api/simple_push_api/index.html delete mode 100644 files/zh-cn/archive/index.html delete mode 100644 files/zh-cn/archive/jxon/index.html delete mode 100644 files/zh-cn/archive/mdn/index.html delete mode 100644 files/zh-cn/archive/meta_docs/custom_classes/index.html delete mode 100644 files/zh-cn/archive/meta_docs/devedge/index.html delete mode 100644 files/zh-cn/archive/meta_docs/external_redirects/index.html delete mode 100644 files/zh-cn/archive/meta_docs/index.html delete mode 100644 files/zh-cn/archive/misc_top_level/images,_tables,_and_mysterious_gaps/index.html delete mode 100644 files/zh-cn/archive/misc_top_level/index.html delete mode 100644 files/zh-cn/archive/misc_top_level/same-origin_policy_for_file_colon__uris/index.html delete mode 100644 files/zh-cn/archive/misc_top_level/using_xml_data_islands_in_mozilla/index.html delete mode 100644 files/zh-cn/archive/mozilla/compiling_the_npruntime_sample_plugin_in_visual_studio/index.html delete mode 100644 files/zh-cn/archive/mozilla/getting_started_with_irc/index.html delete mode 100644 files/zh-cn/archive/mozilla/help_viewer/creating_a_help_content_pack/index.html delete mode 100644 files/zh-cn/archive/mozilla/help_viewer/index.html delete mode 100644 files/zh-cn/archive/mozilla/index.html delete mode 100644 files/zh-cn/archive/mozilla/marketplace/index.html delete mode 100644 files/zh-cn/archive/mozilla/marketplace/marketplace_apis/index.html delete mode 100644 files/zh-cn/archive/mozilla/marketplace/options/self_publishing/index.html delete mode 100644 "files/zh-cn/archive/mozilla/marketplace/options/\346\211\223\345\214\205_\345\272\224\347\224\250\347\250\213\345\272\217/index.html" delete mode 100644 "files/zh-cn/archive/mozilla/marketplace/options/\347\256\200\344\273\213/index.html" delete mode 100644 files/zh-cn/archive/mozilla/marketplace/prepare/introduction/index.html delete mode 100644 files/zh-cn/archive/mozilla/marketplace/publishing/submit/index.html delete mode 100644 files/zh-cn/archive/mozilla/rdf_datasource_how-to/index.html delete mode 100644 files/zh-cn/archive/mozilla/tamarin/index.html delete mode 100644 files/zh-cn/archive/mozilla/tamarin/tamarin_build_documentation/index.html delete mode 100644 files/zh-cn/archive/mozilla/xbl/index.html delete mode 100644 files/zh-cn/archive/mozilla/xbl/xbl_1.0_reference/dom_interfaces/index.html delete mode 100644 files/zh-cn/archive/mozilla/xbl/xbl_1.0_reference/index.html delete mode 100644 files/zh-cn/archive/mozilla/xpinstall/index.html delete mode 100644 files/zh-cn/archive/mozilla/xpinstall/reference/index.html delete mode 100644 files/zh-cn/archive/mozilla/xpinstall/reference/install_object/index.html delete mode 100644 files/zh-cn/archive/mozilla/xpinstall/reference/install_object/properties/index.html delete mode 100644 files/zh-cn/archive/mozilla/xpinstall/scripting_by_example/index.html delete mode 100644 files/zh-cn/archive/mozilla/xpinstall/using_xpinstall_to_install_plugins/index.html delete mode 100644 files/zh-cn/archive/rss/article/index.html delete mode 100644 files/zh-cn/archive/rss/article/why_well-formed_web_rss_module_is_popular_-_syndicating_your_comments/index.html delete mode 100644 files/zh-cn/archive/rss/index.html delete mode 100644 files/zh-cn/archive/security/digital_signatures/index.html delete mode 100644 files/zh-cn/archive/security/encryption_and_decryption/index.html delete mode 100644 files/zh-cn/archive/security/index.html delete mode 100644 files/zh-cn/archive/security/introduction_to_public-key_cryptography/index.html delete mode 100644 files/zh-cn/archive/web/e4x/index.html delete mode 100644 files/zh-cn/archive/web/e4x_tutorial/accessing_xml_children/index.html delete mode 100644 files/zh-cn/archive/web/e4x_tutorial/descendants_and_filters/index.html delete mode 100644 files/zh-cn/archive/web/e4x_tutorial/index.html delete mode 100644 files/zh-cn/archive/web/e4x_tutorial/introduction/index.html delete mode 100644 files/zh-cn/archive/web/e4x_tutorial/namespaces/index.html delete mode 100644 files/zh-cn/archive/web/e4x_tutorial/the_global_xml_object/index.html delete mode 100644 files/zh-cn/archive/web/index.html delete mode 100644 files/zh-cn/archive/web/indexeddb_api_using_javascript_generators_in_firefox/index.html delete mode 100644 files/zh-cn/archive/web/javascript/handler.enumerate/index.html delete mode 100644 files/zh-cn/archive/web/javascript/index.html delete mode 100644 files/zh-cn/archive/web/javascript/legacy_generator_function/index.html delete mode 100644 files/zh-cn/archive/web/javascript/legacy_generator_function_statement/index.html delete mode 100644 files/zh-cn/archive/web/javascript/microsoft_extensions/activexobject/index.html delete mode 100644 files/zh-cn/archive/web/javascript/microsoft_extensions/date.getvardate/index.html delete mode 100644 files/zh-cn/archive/web/javascript/microsoft_extensions/index.html delete mode 100644 files/zh-cn/archive/web/javascript/reflect.enumerate/index.html delete mode 100644 files/zh-cn/archive/web/liveconnect/index.html delete mode 100644 "files/zh-cn/archive/web_\346\240\207\345\207\206/index.html" delete mode 100644 "files/zh-cn/archive/web_\346\240\207\345\207\206/issues_arising_from_arbitrary-element_hover/index.html" delete mode 100644 "files/zh-cn/archive/web_\346\240\207\345\207\206/rdf_in_mozilla_faq/index.html" delete mode 100644 "files/zh-cn/archive/web_\346\240\207\345\207\206/using_the_right_markup_to_invoke_plugins/index.html" delete mode 100644 "files/zh-cn/archive/\345\234\250\346\202\250\347\232\204\347\275\221\351\241\265\344\270\255\345\272\224\347\224\250web\346\240\207\345\207\206/index.html" delete mode 100644 files/zh-cn/components.classes/index.html delete mode 100644 files/zh-cn/components.utils.evalinsandbox/index.html delete mode 100644 files/zh-cn/components.utils.import/index.html delete mode 100644 files/zh-cn/components_object/index.html delete mode 100644 files/zh-cn/creating_a_python_xpcom_component/index.html delete mode 100644 files/zh-cn/creating_xpi_installer_modules/index.html delete mode 100644 files/zh-cn/debugging_javascript/index.html delete mode 100644 files/zh-cn/drag_and_drop/index.html delete mode 100644 files/zh-cn/drag_and_drop_example/index.html delete mode 100644 files/zh-cn/dynamically_modifying_xul-based_user_interface/index.html delete mode 100644 files/zh-cn/extensions/firefox/index.html delete mode 100644 files/zh-cn/extensions/index.html delete mode 100644 files/zh-cn/extensions/mobile/index.html delete mode 100644 "files/zh-cn/extensions/\345\274\225\345\257\274\345\236\213\346\211\251\345\261\225/index.html" delete mode 100644 files/zh-cn/firefox_addons_developer_guide/index.html delete mode 100644 files/zh-cn/firefox_addons_developer_guide/introduction_to_extensions/index.html delete mode 100644 files/zh-cn/firefox_sync/index.html delete mode 100644 files/zh-cn/firefox_sync/javascript_client_api/index.html delete mode 100644 files/zh-cn/generic_factory/index.html delete mode 100644 files/zh-cn/getting_started_with_nss/index.html delete mode 100644 files/zh-cn/getting_started_with_xulrunner/index.html delete mode 100644 files/zh-cn/gre/index.html delete mode 100644 files/zh-cn/how_to_build_an_xpcom_component_in_javascript/index.html delete mode 100644 files/zh-cn/implementing_queryinterface/index.html delete mode 100644 files/zh-cn/interfaces/index.html delete mode 100644 files/zh-cn/introducing_audio_api_extension/index.html delete mode 100644 files/zh-cn/jsdbgapi_reference/index.html delete mode 100644 files/zh-cn/localization_quick_start_guide/index.html delete mode 100644 files/zh-cn/localization_quick_start_guide/initial_setup/index.html delete mode 100644 files/zh-cn/localizing_with_pontoon/index.html delete mode 100644 files/zh-cn/localizing_with_verbatim/index.html delete mode 100644 files/zh-cn/mdn/contribute/howto/link_a_github_account/index.html delete mode 100644 files/zh-cn/mdn/contribute/persona_sign-in/index.html delete mode 100644 files/zh-cn/mdn/guidelines/layout/index.html delete mode 100644 files/zh-cn/mdn/user_guide/writing/index.html delete mode 100644 files/zh-cn/mercurial_faq/index.html delete mode 100644 files/zh-cn/midas/index.html delete mode 100644 files/zh-cn/midas/security_preferences/index.html delete mode 100644 files/zh-cn/migrate_apps_from_internet_explorer_to_mozilla/index.html delete mode 100644 files/zh-cn/mmgc/index.html delete mode 100644 files/zh-cn/mobile/index.html delete mode 100644 files/zh-cn/mobile/viewport_meta_tag/index.html delete mode 100644 files/zh-cn/mozilla/accessibility/index.html delete mode 100644 files/zh-cn/mozilla/accessibility/software_accessibility_today/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/add-on_guidelines/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/amo/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/amo/policy/contact/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/amo/policy/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/code_snippets/canvas/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/code_snippets/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/code_snippets/js_xpcom/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/code_snippets/modules/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/code_snippets/queryselector/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/code_snippets/timers/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/creating_custom_firefox_extensions_with_the_mozilla_build_system/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/creating_opensearch_plugins_for_firefox/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/creating_opensearch_plugins_for_firefox_clone/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/extension_frequently_asked_questions_move/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/extension_packaging/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/install_manifests/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/legacy_add_ons/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/overlay_extensions/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/performance_best_practices_in_extensions/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/plugins/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/plugins/reference/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/plugins/samples_and_test_cases/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/plugins/shipping_a_plugin_as_a_toolkit_bundle/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/builder/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/guides/content_scripts/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/guides/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/guides/multiprocess_firefox_and_the_sdk/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/guides/working_with_events/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/high-level_apis/base64/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/high-level_apis/clipboard/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/high-level_apis/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/high-level_apis/notifications/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/high-level_apis/panel/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/high-level_apis/tabs/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/high-level_apis/url/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/high-level_apis/widget/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/low-level_apis/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/low-level_apis/test_assert/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/low-level_apis/ui_button_action/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tools/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tools/jpm/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tools/package_json/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/add_a_menu_item_to_firefox/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/adding_a_button_to_the_toolbar/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/implementing_the_widget/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/overview/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/display_a_popup/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/getting_started/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/installation/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/l10n/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/list_open_tabs/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/listen_for_page_load/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/modifying_the_page_hosted_by_a_tab/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/modifying_web_pages_based_on_url/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/open_a_web_page/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/troubleshooting/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/sdk/tutorials/unit_testing/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/sdk/tutorials/\346\227\245\345\277\227/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/sdk/tutorials/\346\267\273\345\212\240\344\270\200\344\270\252\350\217\234\345\215\225\351\241\271/index.html" delete mode 100644 files/zh-cn/mozilla/add-ons/setting_up_extension_development_environment/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/submitting_an_add-on_to_amo/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/themes/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/themes/obsolete/creating_a_skin_for_firefox/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/themes/obsolete/creating_a_skin_for_firefox/uuid/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/themes/obsolete/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/themes/obsolete/theme_changes_in_firefox_3/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/embedded_webextensions/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/working_with_multiprocess_firefox/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/\351\233\267\351\270\237/index.html" delete mode 100644 files/zh-cn/mozilla/adding_a_new_event/index.html delete mode 100644 files/zh-cn/mozilla/bugzilla/index.html delete mode 100644 files/zh-cn/mozilla/bugzilla/testopia/index.html delete mode 100644 files/zh-cn/mozilla/chrome_registration/index.html delete mode 100644 files/zh-cn/mozilla/command_line_options/index.html delete mode 100644 files/zh-cn/mozilla/connect/index.html delete mode 100644 files/zh-cn/mozilla/debugging/existing_tools/index.html delete mode 100644 files/zh-cn/mozilla/debugging/index.html delete mode 100644 files/zh-cn/mozilla/firefox/australis_add-on_compat/index.html delete mode 100644 files/zh-cn/mozilla/firefox/developer_edition/index.html delete mode 100644 files/zh-cn/mozilla/firefox/enterprise_deployment/index.html delete mode 100644 files/zh-cn/mozilla/firefox/headless_mode/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/cross_process_object_wrappers/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/debugging_frame_scripts/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/faq/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/limitations_of_chrome_scripts/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/limitations_of_frame_scripts/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/communicating_with_frame_scripts/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/frame_script_environment/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/frame_script_loading_and_lifetime/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/message_manager_overview/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/performance/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/motivation/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/tab_selection_in_multiprocess_firefox/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/technical_overview/index.html delete mode 100644 files/zh-cn/mozilla/firefox/multiprocess_firefox/which_uris_load_where/index.html delete mode 100644 files/zh-cn/mozilla/firefox/privacy/index.html delete mode 100644 files/zh-cn/mozilla/firefox/privacy/storage_access_policy/errors/index.html delete mode 100644 "files/zh-cn/mozilla/firefox/privacy/storage_access_policy/errors/\347\246\201\347\224\250\345\244\226\351\203\250cookie/index.html" delete mode 100644 files/zh-cn/mozilla/firefox/privacy/storage_access_policy/index.html delete mode 100644 files/zh-cn/mozilla/firefox/privacy/tracking_protection/index.html delete mode 100644 files/zh-cn/mozilla/firefox/the_about_protocol/index.html delete mode 100644 files/zh-cn/mozilla/firefox_for_android/index.html delete mode 100644 files/zh-cn/mozilla/gecko/index.html delete mode 100644 files/zh-cn/mozilla/gecko/versions/index.html delete mode 100644 "files/zh-cn/mozilla/gecko/\345\265\214\345\205\245mozilla/index.html" delete mode 100644 files/zh-cn/mozilla/how_mozilla_determines_mime_types/index.html delete mode 100644 files/zh-cn/mozilla/how_to_get_a_process_dump_with_windows_task_manager/index.html delete mode 100644 files/zh-cn/mozilla/implementing_pontoon_in_a_mozilla_website/index.html delete mode 100644 files/zh-cn/mozilla/instantbird/index.html delete mode 100644 files/zh-cn/mozilla/introduction_to_layout_in_mozilla/index.html delete mode 100644 files/zh-cn/mozilla/ipdl/creating_a_new_protocol/index.html delete mode 100644 files/zh-cn/mozilla/ipdl/index.html delete mode 100644 "files/zh-cn/mozilla/ipdl/\345\205\245\351\227\250/index.html" delete mode 100644 files/zh-cn/mozilla/javascript-dom_prototypes_in_mozilla/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/assert.jsm/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/dict.jsm/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/downloads.jsm/download/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/downloads.jsm/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/geometry.jsm/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/geometry.jsm/services.jsm/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/http.jsm/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/promise.jsm/deferred/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/promise.jsm/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/timer.jsm/index.html delete mode 100644 files/zh-cn/mozilla/javascript_code_modules/using/index.html delete mode 100644 files/zh-cn/mozilla/javascript_tips/index.html delete mode 100644 files/zh-cn/mozilla/js-ctypes/index.html delete mode 100644 files/zh-cn/mozilla/js-ctypes/js-ctypes_reference/ctypes/index.html delete mode 100644 files/zh-cn/mozilla/js-ctypes/js-ctypes_reference/index.html delete mode 100644 files/zh-cn/mozilla/js-ctypes/using_js-ctypes/declaring_and_using_callbacks/index.html delete mode 100644 files/zh-cn/mozilla/js-ctypes/using_js-ctypes/index.html delete mode 100644 files/zh-cn/mozilla/js-ctypes/using_js-ctypes/memory_management/index.html delete mode 100644 files/zh-cn/mozilla/js-ctypes/using_js-ctypes/working_with_arraybuffers/index.html delete mode 100644 files/zh-cn/mozilla/localization/faq/index.html delete mode 100644 files/zh-cn/mozilla/localization/index.html delete mode 100644 files/zh-cn/mozilla/localization/l10n_style_guide/index.html delete mode 100644 files/zh-cn/mozilla/localization/localizing_extension_descriptions/index.html delete mode 100644 files/zh-cn/mozilla/mercurial/basics/index.html delete mode 100644 files/zh-cn/mozilla/mercurial/index.html delete mode 100644 files/zh-cn/mozilla/mercurial/installing_mercurial/index.html delete mode 100644 files/zh-cn/mozilla/mfbt/index.html delete mode 100644 files/zh-cn/mozilla/mozilla_on_github/index.html delete mode 100644 files/zh-cn/mozilla/participating_in_the_mozilla_project/index.html delete mode 100644 files/zh-cn/mozilla/performance/about_colon_memory/index.html delete mode 100644 files/zh-cn/mozilla/performance/index.html delete mode 100644 files/zh-cn/mozilla/performance/scroll-linked_effects/index.html delete mode 100644 files/zh-cn/mozilla/persona/bootstrapping_persona/index.html delete mode 100644 files/zh-cn/mozilla/persona/branding/index.html delete mode 100644 files/zh-cn/mozilla/persona/browser_compatibility/index.html delete mode 100644 files/zh-cn/mozilla/persona/glossary/index.html delete mode 100644 files/zh-cn/mozilla/persona/index.html delete mode 100644 files/zh-cn/mozilla/persona/protocol_overview/index.html delete mode 100644 files/zh-cn/mozilla/persona/quick_setup/index.html delete mode 100644 files/zh-cn/mozilla/persona/remote_verification_api/index.html delete mode 100644 files/zh-cn/mozilla/persona/security_considerations/index.html delete mode 100644 files/zh-cn/mozilla/persona/why_persona/index.html delete mode 100644 files/zh-cn/mozilla/preferences/index.html delete mode 100644 files/zh-cn/mozilla/preferences/mozilla_networking_preferences/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/browser.altclicksave/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/browser.download.lastdir.savepersite/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/browser.search.context.loadinbackground/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/browser.urlbar.trimurls/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/dom.event.clipboardevents.enabled/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/javascript.options.strict/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/ui.alertnotificationorigin/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/ui.spellcheckerunderline/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/ui.spellcheckerunderlinestyle/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/ui.tooltipdelay/index.html delete mode 100644 files/zh-cn/mozilla/preferences/preference_reference/view_source.syntax_highlight/index.html delete mode 100644 files/zh-cn/mozilla/projects/crash_reporting/index.html delete mode 100644 files/zh-cn/mozilla/projects/emscripten/index.html delete mode 100644 files/zh-cn/mozilla/projects/index.html delete mode 100644 files/zh-cn/mozilla/projects/l20n/index.html delete mode 100644 files/zh-cn/mozilla/projects/nspr/index.html delete mode 100644 files/zh-cn/mozilla/projects/nspr/reference/index.html delete mode 100644 files/zh-cn/mozilla/projects/nspr/reference/memory_management_operations/index.html delete mode 100644 files/zh-cn/mozilla/projects/psm/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/bsf/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/community/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/debugger/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/documentation/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/download_rhino/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/examples/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/license/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/overview/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/requirements_and_limitations/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/scripting_java/index.html delete mode 100644 files/zh-cn/mozilla/projects/rhino/shell/index.html delete mode 100644 files/zh-cn/mozilla/projects/social_api/index.html delete mode 100644 files/zh-cn/mozilla/projects/social_api/share/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/build_documentation/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/comparision_of_js_engines/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/internals/bytecodes/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/internals/functions/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/internals/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/introduction_to_the_javascript_shell/index.html delete mode 100644 "files/zh-cn/mozilla/projects/spidermonkey/javascript-c\345\274\225\346\223\216\345\265\214\345\205\245\345\274\200\345\217\221\346\214\207\345\215\227/index.html" delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/boolean_to_jsval/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_defineconstdoubles/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_doublecolon_call/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_doublecolon_ordinarytoprimitive/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_evaluatescript/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_getversion/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_hasownproperty/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_newruntime/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_seterrorreporter/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_valuetostring/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsclass/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsconstdoublespec/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jserrorreport/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsproperty/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jspropertydescriptor/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsruntime/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/parser_api/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/releases/index.html delete mode 100644 files/zh-cn/mozilla/projects/spidermonkey/split_object/index.html delete mode 100644 files/zh-cn/mozilla/rust/index.html delete mode 100644 files/zh-cn/mozilla/tech/index.html delete mode 100644 files/zh-cn/mozilla/tech/toolkit_api/extisessionstorage/index.html delete mode 100644 files/zh-cn/mozilla/tech/toolkit_api/index.html delete mode 100644 files/zh-cn/mozilla/tech/viewing_and_searching_mozilla_source_code_online/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/glue/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/arrays/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/an_overview_of_xpcom/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/building_the_weblock_ui/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/component_internals/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/creating_the_component_code/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/finishing_the_component/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/packaging_weblock/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/preface/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/resources/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/setting_up_the_gecko_sdk/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/starting_weblock/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_components/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_utilities_to_make_things_easier/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/hashtables/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/guide/internal_strings/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/interfacing_with_the_xpcom_cycle_collector/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.cloneinto/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.getglobalforobject/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/language_bindings/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/index.html delete mode 100644 "files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/\344\275\277\347\224\250javaxpcom\345\234\250java\345\272\224\347\224\250\347\250\213\345\272\217\344\270\255\345\265\214\345\205\245mozilla/index.html" delete mode 100644 "files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/\345\274\200\345\217\221/index.html" delete mode 100644 files/zh-cn/mozilla/tech/xpcom/language_bindings/pyxpcom/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/language_bindings/xpconnect/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/observer_notifications/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/getting_started_guide/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiaccessibleprovider/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboard/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboardhelper/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiconsoleservice/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidirectoryserviceprovider/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidomclientrect/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifile/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifilepicker/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsihttpchannel/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiidleservice/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsilocalfile/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprocess/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprompt/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsipromptservice/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiscriptableunicodeconverter/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsisyncmessagesender/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitimer/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitraceablechannel/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiuri/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/reference/interface/nsixmlhttprequest/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpcom/setting_http_request_headers/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpidl/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpidl/syntax/index.html delete mode 100644 files/zh-cn/mozilla/tech/xpidl/xpidl/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/acceltext/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/accesskey/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/activetitlebarcolor/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/align/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/allowevents/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/allownegativeassertions/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/autocheck/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/autoscroll/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/buttonaccesskeyaccept/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/buttonlabelextra1/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/buttonlabelextra2/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/buttons/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/checked/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/class/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/coalesceduplicatearcs/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/collapsed/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/command/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/container/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/control/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/crop/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/description/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/dir/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/disabled/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/flex/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/href/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/id/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/image.onload/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/image/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/increment/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/label/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/max/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/menuitem.key/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/menuitem.name/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/menuitem.type/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/min/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/name/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/onpopupshowing/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/onpopupshown/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/orient/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/pending/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/persist/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/selected/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/selectedindex/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/tabindex/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/validate/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/attribute/value/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/broadcaster/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/browser/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/button/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/checkbox/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/command/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/deprecated_defunct_markup/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/dialog/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/events/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/image/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/key/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/label/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/list_of_commands/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/listbox/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/listheader/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/menu/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/menubar/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/menuitem/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/menulist/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/menupopup/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/menuseparator/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/method/extra1/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/method/focus/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/method/getbrowserfortab/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/method/getbutton/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/method/increase/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/method/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/method/reset/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/method/stop/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/namespaces/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/popup/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/accessibletype/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/accesskey/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/browser.preferences/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/buttons/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/command/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/crop/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/defaultvalue/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/disabled/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/image/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/label/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/labelelement/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/markupdocumentviewer/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/max/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/menuitem.control/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/parentcontainer/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/selected/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/selectedindex/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/selecteditem/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/selectionstart/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/spinbuttons/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/tabindex/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/textbox.value/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/property/value/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/radio/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/radiogroup/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/script/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/statusbar/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/style/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/style/menuitem-iconic/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/style/menuitem-non-iconic/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tabbox/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/template_guide/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/textbox/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/toolbarpalette/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/toolbars/creating_toolbar_buttons/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/toolbars/custom_toolbar_button/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/toolbars/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/toolbox/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tree/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/adding_buttons/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/adding_event_handlers/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/adding_html_elements/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/adding_labels_and_images/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/adding_more_elements/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/adding_style_sheets/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/anonymous_content/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/box_model_details/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/content_panels/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/creating_a_skin/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/creating_a_window/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/creating_an_installer/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/creating_dialogs/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/document_object_model/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/element_positioning/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/features_of_a_window/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/grids/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/groupboxes/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/input_controls/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/introduction/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/introduction_to_rdf/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/list_controls/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/localization/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/manifest_files/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/modifying_a_xul_interface/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/modifying_the_default_skin/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/more_button_features/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/more_event_handlers/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/more_menu_features/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/more_wizards/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/numeric_controls/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/popup_menus/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/progress_meters/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/property_files/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/rdf_datasources/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/scroll_bars/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/scrolling_menus/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/simple_menu_bars/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/splitters/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/stack_positioning/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/stacks_and_decks/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/styling_a_tree/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/tabboxes/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/templates/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/the_box_model/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/the_chrome_url/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/toolbars/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/trees/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/using_spacers/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/using_xbl_from_stylesheets/index.html delete mode 100644 "files/zh-cn/mozilla/tech/xul/tutorial/xbl\344\273\213\347\273\215/index.html" delete mode 100644 "files/zh-cn/mozilla/tech/xul/tutorial/xpcom_\346\216\245\345\217\243/index.html" delete mode 100644 files/zh-cn/mozilla/tech/xul/tutorial/xul_structure/index.html delete mode 100644 "files/zh-cn/mozilla/tech/xul/tutorial/\346\233\264\345\244\232\347\232\204\346\214\211\351\222\256\347\211\271\346\200\247/index.html" delete mode 100644 files/zh-cn/mozilla/tech/xul/vbox/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/window/index.html delete mode 100644 files/zh-cn/mozilla/tech/xul/xul_reference/index.html delete mode 100644 files/zh-cn/mozilla/thunderbird/index.html delete mode 100644 files/zh-cn/mozilla/thunderbird/mail_client_architecture_overview/index.html delete mode 100644 files/zh-cn/mozilla/thunderbird/mailnews_protocols/index.html delete mode 100644 files/zh-cn/mozilla/toolkit_version_format/index.html delete mode 100644 files/zh-cn/mozilla/webidl_bindings/index.html delete mode 100644 files/zh-cn/mozilla/xmlhttprequest_changes_for_gecko_1.8/index.html delete mode 100644 "files/zh-cn/mozilla/\345\220\214\346\227\266\344\275\277\347\224\250\345\244\232\344\270\252\347\233\270\344\272\222\347\213\254\347\253\213\347\232\204\347\201\253\347\213\220\346\265\217\350\247\210\345\231\250/index.html" delete mode 100644 "files/zh-cn/mozilla/\346\227\245\345\216\206/index.html" delete mode 100644 files/zh-cn/mozilla_dom_hacking_guide/index.html delete mode 100644 files/zh-cn/mozilla_mathml_project/fonts/index.html delete mode 100644 files/zh-cn/mozilla_mathml_project/index.html delete mode 100644 files/zh-cn/mozilla_mathml_project/start/index.html delete mode 100644 files/zh-cn/mozilla_quirks_mode_behavior/index.html delete mode 100644 files/zh-cn/mozilla_svg_project/index.html delete mode 100644 files/zh-cn/mozilla_web_developer_faq/index.html delete mode 100644 "files/zh-cn/mozilla\344\270\255\347\232\204xml/index.html" delete mode 100644 files/zh-cn/new_compatibility_tables_beta/index.html delete mode 100644 files/zh-cn/npclass/index.html delete mode 100644 files/zh-cn/npobject/index.html delete mode 100644 files/zh-cn/nsidomparser/index.html delete mode 100644 files/zh-cn/nss/building/index.html delete mode 100644 files/zh-cn/nss/index.html delete mode 100644 files/zh-cn/nss/introduction_to_network_security_services/index.html delete mode 100644 files/zh-cn/nss/key_log_format/index.html delete mode 100644 files/zh-cn/nss/overview/index.html delete mode 100644 files/zh-cn/nss/tools/index.html delete mode 100644 "files/zh-cn/nss/tools/nss_\345\267\245\345\205\267_certutil/index.html" delete mode 100644 files/zh-cn/places/index.html delete mode 100644 files/zh-cn/properly_using_css_and_javascript_in_xhtml_documents/examples/index.html delete mode 100644 files/zh-cn/properly_using_css_and_javascript_in_xhtml_documents/index.html delete mode 100644 files/zh-cn/spidermonkey/hacking_tips/index.html delete mode 100644 files/zh-cn/spidermonkey_garbage_collection_tips/index.html delete mode 100644 files/zh-cn/storage/index.html delete mode 100644 files/zh-cn/structure_of_an_installable_bundle/index.html delete mode 100644 files/zh-cn/the_mozilla_platform/index.html delete mode 100644 files/zh-cn/theme_packaging/index.html delete mode 100644 files/zh-cn/tools/scratchpad/index.html delete mode 100644 files/zh-cn/tools/webide/index.html delete mode 100644 files/zh-cn/tools/webide/monitor/index.html delete mode 100644 files/zh-cn/tools/webide/opening_webide/index.html delete mode 100644 "files/zh-cn/tools/webide/\351\227\256\351\242\230\346\216\222\351\231\244/index.html" delete mode 100644 files/zh-cn/updating_an_extension_to_support_multiple_mozilla_applications/index.html delete mode 100644 files/zh-cn/using_breakpoints_in_venkman/index.html delete mode 100644 files/zh-cn/using_mozilla_code_in_other_projects/index.html delete mode 100644 files/zh-cn/using_the_clipboard/index.html delete mode 100644 files/zh-cn/using_workers_in_extensions/index.html delete mode 100644 files/zh-cn/venkman/index.html delete mode 100644 files/zh-cn/venkman_internals/index.html delete mode 100644 files/zh-cn/venkman_introduction/index.html delete mode 100644 files/zh-cn/web/api/cameracontrol/getpreviewstream/index.html delete mode 100644 files/zh-cn/web/api/cameracontrol/index.html delete mode 100644 files/zh-cn/web/api/identitymanager/index.html delete mode 100644 files/zh-cn/web/api/identitymanager/watch/index.html delete mode 100644 files/zh-cn/web/api/indexeddb_api/using_indexeddb_in_chrome/index.html delete mode 100644 files/zh-cn/web/api/navigator/id/index.html delete mode 100644 files/zh-cn/web/api/navigator/mozsettings/index.html delete mode 100644 files/zh-cn/web/api/navigator/mozsms/index.html delete mode 100644 files/zh-cn/web/api/using_the_browser_api/index.html delete mode 100644 files/zh-cn/web/api/webvr_api/webvr_environment_setup/index.html delete mode 100644 files/zh-cn/web/css/-moz-binding/index.html delete mode 100644 files/zh-cn/web/css/-moz-border-bottom-colors/index.html delete mode 100644 files/zh-cn/web/css/-ms-overflow-style/index.html delete mode 100644 files/zh-cn/web/css/_doublecolon_-ms-check/index.html delete mode 100644 files/zh-cn/web/css/_doublecolon_-ms-clear/index.html delete mode 100644 files/zh-cn/web/css/overflow-clip-box/index.html delete mode 100644 files/zh-cn/web/events/domlinkadded/index.html delete mode 100644 files/zh-cn/web/events/mozafterpaint/index.html delete mode 100644 files/zh-cn/web/events/tabopen/index.html delete mode 100644 files/zh-cn/web/guide/api/camera/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/xml_data/index.html delete mode 100644 files/zh-cn/web/javascript/ecmascript_7_support_in_mozilla/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.1/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.2/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.3/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.4/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.5/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.6/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.7/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.8.1/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.8.5/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/1.8/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/ecmascript_5_support_in_mozilla/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/ecmascript_6_support_in_mozilla/index.html delete mode 100644 files/zh-cn/web/javascript/new_in_javascript/index.html delete mode 100644 files/zh-cn/web/javascript/reference/functions/arguments/caller/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/observe/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/unobserve/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/transfer/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/tolocaleformat/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/arity/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/isgenerator/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/iterator/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/tointeger/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/count/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/eval/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/getnotifier/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/nosuchmethod/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/observe/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/parent/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/unobserve/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/unwatch/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/watch/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/parallelarray/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/quote/index.html delete mode 100644 files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html delete mode 100644 files/zh-cn/web/javascript/reference/operators/expression_closures/index.html delete mode 100644 files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html delete mode 100644 files/zh-cn/web/javascript/reference/statements/for_each...in/index.html delete mode 100644 files/zh-cn/web/rdf/index.html delete mode 100644 "files/zh-cn/web/security/information_security_basics/tcp_ip_\345\256\211\345\205\250/index.html" delete mode 100644 files/zh-cn/web/security/information_security_basics/vulnerabilities/index.html delete mode 100644 "files/zh-cn/web/security/information_security_basics/\346\234\272\345\257\206\346\200\247\343\200\201\345\256\214\346\225\264\346\200\247\345\222\214\345\217\257\347\224\250\346\200\247/index.html" delete mode 100644 files/zh-cn/web/security/site_identity_button/index.html delete mode 100644 files/zh-cn/web/svg/faq/index.html delete mode 100644 "files/zh-cn/web_development/\345\223\215\345\272\224\345\274\217_web_\350\256\276\350\256\241/index.html" delete mode 100644 files/zh-cn/window_icons/index.html delete mode 100644 files/zh-cn/working_with_bfcache/index.html delete mode 100644 files/zh-cn/xml_extras/index.html delete mode 100644 files/zh-cn/xml_web_services/index.html delete mode 100644 files/zh-cn/xpi/index.html delete mode 100644 files/zh-cn/xquery/index.html delete mode 100644 files/zh-cn/xslt_2.0/index.html delete mode 100644 files/zh-cn/xtech_2005_presentations/directions_of_the_mozilla_rdf_engine/index.html delete mode 100644 files/zh-cn/xtech_2005_presentations/index.html delete mode 100644 files/zh-cn/xtech_2005_presentations/xul_-_mozilla's_xml_user_interface_language/index.html delete mode 100644 "files/zh-cn/xul/\346\240\207\351\242\230\346\240\217/index.html" delete mode 100644 files/zh-cn/xul_element_attributes/index.html delete mode 100644 files/zh-cn/xul_explorer/index.html delete mode 100644 "files/zh-cn/xul_\347\250\213\345\272\217\346\211\223\345\214\205/index.html" delete mode 100644 files/zh-cn/xulrunner/index.html delete mode 100644 files/zh-cn/xulrunner/what_xulrunner_provides/index.html delete mode 100644 files/zh-cn/xulrunner_old_releases/index.html delete mode 100644 files/zh-cn/xulrunner_tips/index.html delete mode 100644 files/zh-cn/zones/index.html delete mode 100644 "files/zh-cn/\345\212\250\346\200\201\344\277\256\346\224\271\345\237\272\344\272\216xul\347\232\204\347\224\250\346\210\267\347\225\214\351\235\242/index.html" delete mode 100644 "files/zh-cn/\346\211\251\345\261\225/using_the_dom_file_api_in_chrome_code/index.html" delete mode 100644 "files/zh-cn/\346\211\251\345\261\225/\345\206\205\345\265\214\351\200\211\351\241\271/index.html" delete mode 100644 "files/zh-cn/\346\211\251\345\261\225/\347\244\276\345\214\272/index.html" delete mode 100644 "files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/bug_writing_guidelines/index.html" delete mode 100644 "files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/index.html" delete mode 100644 "files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/webrender/index.html" (limited to 'files/zh-cn') diff --git a/files/zh-cn/_wikihistory.json b/files/zh-cn/_wikihistory.json deleted file mode 100644 index 5232363367..0000000000 --- a/files/zh-cn/_wikihistory.json +++ /dev/null @@ -1,50892 +0,0 @@ -{ - "API/Pointer_Lock_API": { - "modified": "2020-07-02T02:40:37.086Z", - "contributors": [ - "brizer", - "fscholz", - "princetoad@gmail.com" - ] - }, - "CSS/float": { - "modified": "2020-11-29T04:21:18.185Z", - "contributors": [ - "Nyaasu", - "RainSlide", - "Murphy1024", - "Jack.Works", - "zhuangyin", - "tcatche", - "Ende93", - "xgqfrms-GitHub", - "Sarlaka", - "fscholz", - "Sebastianz", - "xiaodongzai", - "AlexChao", - "linmx0130", - "FredWe", - "teoli", - "ziyunfei" - ] - }, - "Chrome": { - "modified": "2019-03-23T23:52:52.388Z", - "contributors": [ - "ziyunfei", - "Jedichou", - "Freeopen" - ] - }, - "Controlling_DNS_prefetching": { - "modified": "2020-10-15T21:21:12.955Z", - "contributors": [ - "RainSlide", - "lsvih", - "zhuangyin", - "yyhaxx", - "RequireSun", - "yowangbin", - "markyun", - "Ende93", - "hucz08" - ] - }, - "DHTML": { - "modified": "2019-03-23T23:46:38.426Z", - "contributors": [ - "ziyunfei", - "Wind930" - ] - }, - "Example_2_-_Using_UL": { - "modified": "2019-03-18T20:44:28.267Z", - "contributors": [ - "RainSlide", - "blue0125" - ] - }, - "Games": { - "modified": "2019-09-21T02:47:40.270Z", - "contributors": [ - "gogoend", - "SphinxKnight", - "GohBoonHong", - "LaneSun", - "wbamberg", - "varcat", - "lixuanh", - "ljzzkkkss", - "Hypophrenia", - "maoxiaoke", - "chrisdavidmills" - ] - }, - "Games/Anatomy": { - "modified": "2020-10-27T03:48:33.121Z", - "contributors": [ - "SphinxKnight", - "lins1105", - "GoneProtoss", - "castle-sky", - "jingkaimori", - "Fulgrim", - "ZhouWeicheng90", - "veici", - "U0Axuan", - "LaneSun", - "wbamberg", - "chaosdog", - "xrr2016", - "varcat", - "yydzxz", - "slimeball", - "hansonfang", - "Ende93", - "yjy1992" - ] - }, - "Games/Examples": { - "modified": "2019-01-16T21:48:35.297Z", - "contributors": [ - "wbamberg", - "noiron" - ] - }, - "Games/Introduction_to_HTML5_Game_Gevelopment_(summary)": { - "modified": "2019-01-17T01:15:39.320Z", - "contributors": [ - "wbamberg", - "xgqfrms-GitHub" - ] - }, - "Games/Publishing_games": { - "modified": "2019-01-17T00:50:49.182Z", - "contributors": [ - "wbamberg", - "lixuanh" - ] - }, - "Games/Publishing_games/Game_distribution": { - "modified": "2019-07-19T05:51:21.728Z", - "contributors": [ - "c03311" - ] - }, - "Games/Publishing_games/Game_promotion": { - "modified": "2019-07-22T07:42:43.723Z", - "contributors": [ - "c03311", - "wbamberg", - "chengweigao" - ] - }, - "Games/Publishing_games/游戏货币化": { - "modified": "2019-07-23T05:31:53.344Z", - "contributors": [ - "c03311", - "wbamberg", - "tannineo", - "chenXiaoZhui" - ] - }, - "Games/Techniques": { - "modified": "2020-01-16T08:22:10.237Z", - "contributors": [ - "tanpopo", - "wbamberg", - "chrisdavidmills" - ] - }, - "Games/Techniques/2D_collision_detection": { - "modified": "2019-01-17T01:15:26.140Z", - "contributors": [ - "wbamberg", - "powerdoom", - "xrr2016" - ] - }, - "Games/Techniques/3D_collision_detection": { - "modified": "2019-03-23T22:02:31.618Z", - "contributors": [ - "wbamberg", - "lhyt", - "varcat" - ] - }, - "Games/Techniques/3D_on_the_web": { - "modified": "2020-09-18T11:44:15.427Z", - "contributors": [ - "ICLOUDIRIS", - "gogoend", - "c1er", - "wbamberg", - "catchOneW", - "chrisdavidmills" - ] - }, - "Games/Techniques/3D_on_the_web/Basic_theory": { - "modified": "2019-04-11T06:22:49.380Z", - "contributors": [ - "JiamingXiao", - "wbamberg", - "kyriejoshua", - "Will.Fan", - "gooin" - ] - }, - "Games/Techniques/3D_on_the_web/Building_up_a_basic_demo_with_Three.js": { - "modified": "2019-07-10T00:02:38.721Z", - "contributors": [ - "wbamberg", - "scqilin", - "Will.Fan" - ] - }, - "Games/Techniques/3D_on_the_web/GLSL_Shaders": { - "modified": "2019-04-14T06:02:27.059Z", - "contributors": [ - "wbamberg", - "hiyoushu", - "Will.Fan" - ] - }, - "Games/Techniques/Async_scripts": { - "modified": "2019-01-17T02:09:24.311Z", - "contributors": [ - "wbamberg", - "catchOneW", - "varcat" - ] - }, - "Games/Techniques/Control_mechanisms": { - "modified": "2019-03-18T21:13:06.516Z", - "contributors": [ - "wbamberg" - ] - }, - "Games/Techniques/Control_mechanisms/移动端触摸控制": { - "modified": "2019-03-18T21:13:06.265Z", - "contributors": [ - "fisho" - ] - }, - "Games/Techniques/Controls_Gamepad_API": { - "modified": "2019-03-18T21:38:23.713Z", - "contributors": [ - "wbamberg", - "zsxeee" - ] - }, - "Games/Tools": { - "modified": "2019-01-17T01:09:58.257Z", - "contributors": [ - "wbamberg", - "dkocho4" - ] - }, - "Games/Tools/引擎和工具": { - "modified": "2019-03-23T22:12:27.616Z", - "contributors": [ - "wbamberg", - "ChenXiCC" - ] - }, - "Games/Tutorials": { - "modified": "2019-03-23T22:18:56.983Z", - "contributors": [ - "wbamberg", - "chrisdavidmills" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript": { - "modified": "2019-03-23T22:19:01.932Z", - "contributors": [ - "wbamberg", - "jiii", - "jswisher" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls": { - "modified": "2019-03-23T22:15:46.459Z", - "contributors": [ - "wbamberg", - "xrr2016", - "varcat", - "jackblackevo", - "jiii" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Build_the_brick_field": { - "modified": "2019-01-17T01:49:49.827Z", - "contributors": [ - "wbamberg", - "DHecarim", - "SphinxKnight" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection": { - "modified": "2019-01-17T02:24:24.007Z", - "contributors": [ - "wbamberg", - "DHecarim", - "ziyunfei", - "Trendymen" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it": { - "modified": "2019-03-23T22:16:30.455Z", - "contributors": [ - "Somehow", - "wbamberg", - "DHecarim", - "ziyunfei", - "jiii" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over": { - "modified": "2020-10-06T22:02:12.248Z", - "contributors": [ - "phone-burner", - "wbamberg", - "xrr2016", - "varcat", - "usernameisMan" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball": { - "modified": "2019-03-23T22:16:32.351Z", - "contributors": [ - "wbamberg", - "SwithunHan", - "Ende93", - "Heroor", - "xrr2016", - "jiii", - "ziyunfei" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls": { - "modified": "2019-01-17T00:34:32.812Z", - "contributors": [ - "wbamberg", - "xrr2016", - "varcat", - "longzhengxiong", - "lixuanh" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win": { - "modified": "2019-01-17T03:03:35.918Z", - "contributors": [ - "wbamberg", - "DHecarim" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/收尾工作": { - "modified": "2020-03-04T06:46:31.914Z", - "contributors": [ - "zmx0142857" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/鼠标控制": { - "modified": "2020-03-04T06:03:22.539Z", - "contributors": [ - "zmx0142857" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser": { - "modified": "2019-03-23T22:13:33.607Z", - "contributors": [ - "wbamberg", - "Haruhi" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Animations_and_tweens": { - "modified": "2019-06-25T06:47:26.402Z", - "contributors": [ - "kilohaty", - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Bounce_off_the_walls": { - "modified": "2019-01-17T01:42:53.509Z", - "contributors": [ - "wbamberg", - "xrr2016", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Build_the_brick_field": { - "modified": "2019-01-17T01:42:57.417Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Buttons": { - "modified": "2019-01-17T01:42:55.878Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Collision_detection": { - "modified": "2019-01-17T01:43:12.147Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Extra_lives": { - "modified": "2019-01-17T01:43:04.678Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Game_over": { - "modified": "2019-01-17T01:43:03.359Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Initialize_the_framework": { - "modified": "2019-01-17T01:04:36.974Z", - "contributors": [ - "wbamberg", - "hnliuzesen", - "Haruhi" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Load_the_assets_and_print_them_on_screen": { - "modified": "2019-01-17T01:43:00.734Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Move_the_ball": { - "modified": "2019-01-17T01:43:09.610Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Physics": { - "modified": "2019-01-17T01:42:59.576Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Player_paddle_and_controls": { - "modified": "2019-01-17T01:43:11.216Z", - "contributors": [ - "wbamberg", - "xrr2016", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Randomizing_gameplay": { - "modified": "2019-01-17T01:43:14.936Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Scaling": { - "modified": "2019-01-17T01:43:02.878Z", - "contributors": [ - "wbamberg", - "hnliuzesen", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/The_score": { - "modified": "2019-01-17T01:43:04.496Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/2D_breakout_game_Phaser/Win_the_game": { - "modified": "2019-01-17T01:43:17.617Z", - "contributors": [ - "wbamberg", - "j787701730" - ] - }, - "Games/Tutorials/HTML5_Gamedev_Phaser_Device_Orientation": { - "modified": "2019-07-13T23:45:54.990Z", - "contributors": [ - "Javen" - ] - }, - "Games/简介": { - "modified": "2019-12-05T00:08:12.532Z", - "contributors": [ - "catcatching", - "wbamberg", - "codeofjackie", - "zsxeee", - "varcat", - "WMin", - "hansonfang", - "13310", - "magiclyde", - "fierayan" - ] - }, - "Glossary": { - "modified": "2020-10-07T11:15:25.314Z", - "contributors": [ - "peterbe", - "SphinxKnight", - "RainSlide", - "wbamberg", - "Terry.Qiao", - "micblo", - "wth", - "Jack-Q", - "xhlsrj", - "iwo" - ] - }, - "Glossary/404": { - "modified": "2020-09-03T07:22:13.151Z", - "contributors": [ - "Damoness", - "NathanWangRuilin", - "心斩心鬼", - "Jiang-Xuan", - "ReyCG_sub" - ] - }, - "Glossary/502": { - "modified": "2019-03-23T22:26:50.896Z", - "contributors": [ - "zhangchen", - "cissoid" - ] - }, - "Glossary/AJAX": { - "modified": "2020-10-09T04:19:42.794Z", - "contributors": [ - "benniks", - "zzzimaple", - "jason-guo", - "心斩心鬼", - "cosformula", - "Zhong", - "Terry.Qiao", - "zsxeee", - "icaoweiwei" - ] - }, - "Glossary/ALPN": { - "modified": "2020-01-08T00:23:19.982Z", - "contributors": [ - "liuhaoXD" - ] - }, - "Glossary/API": { - "modified": "2019-03-18T21:30:37.634Z", - "contributors": [ - "sdoxiaobaomei", - "fs523577192" - ] - }, - "Glossary/ARIA": { - "modified": "2019-03-18T21:41:36.925Z", - "contributors": [ - "zhangchen", - "yuyx91" - ] - }, - "Glossary/ASCII": { - "modified": "2020-07-09T00:58:13.107Z", - "contributors": [ - "QrnKG", - "lcyzxlzy", - "RogerShen" - ] - }, - "Glossary/Accessibility": { - "modified": "2019-03-23T22:18:43.149Z", - "contributors": [ - "fan19900404" - ] - }, - "Glossary/Adobe_Flash": { - "modified": "2020-05-04T11:48:28.645Z", - "contributors": [ - "User670", - "Forbidden", - "yuyx91" - ] - }, - "Glossary/Apple_Safari": { - "modified": "2019-03-18T21:21:56.075Z", - "contributors": [ - "Chor" - ] - }, - "Glossary/Argument": { - "modified": "2019-06-18T06:46:17.127Z", - "contributors": [ - "frei-x", - "Tao-Quixote", - "NicholasCao", - "xuelin-zhao" - ] - }, - "Glossary/Arpanet": { - "modified": "2020-08-22T05:08:00.871Z", - "contributors": [ - "Milkysilk" - ] - }, - "Glossary/Attribute": { - "modified": "2019-05-03T10:09:46.825Z", - "contributors": [ - "fish-inu", - "jaiJia" - ] - }, - "Glossary/Bandwidth": { - "modified": "2019-03-23T22:25:13.091Z", - "contributors": [ - "pluwen", - "heiseshandian" - ] - }, - "Glossary/BiDi": { - "modified": "2020-03-15T11:45:20.503Z", - "contributors": [ - "supertreediagram", - "ViperWhip3325" - ] - }, - "Glossary/BigInt": { - "modified": "2020-07-28T01:48:12.060Z", - "contributors": [ - "neal1991", - "elinyuhanwu", - "zhangnan666" - ] - }, - "Glossary/Blink": { - "modified": "2019-03-23T22:32:21.790Z", - "contributors": [ - "Jack-Q" - ] - }, - "Glossary/Block": { - "modified": "2019-04-26T07:01:02.583Z", - "contributors": [ - "心斩心鬼", - "Sheppy" - ] - }, - "Glossary/Block/CSS": { - "modified": "2020-02-12T10:46:35.036Z", - "contributors": [ - "RainSlide", - "XdCareWy" - ] - }, - "Glossary/Block/Scripting": { - "modified": "2020-12-06T13:00:31.856Z", - "contributors": [ - "miticm", - "心斩心鬼" - ] - }, - "Glossary/Block_cipher_mode_of_operation": { - "modified": "2020-08-13T14:05:45.113Z", - "contributors": [ - "xh1996819" - ] - }, - "Glossary/Boolean": { - "modified": "2019-03-23T22:23:48.513Z", - "contributors": [ - "NosearY" - ] - }, - "Glossary/Browsing_context": { - "modified": "2020-12-03T02:19:51.826Z", - "contributors": [ - "LucioLu" - ] - }, - "Glossary/Bézier_curve": { - "modified": "2020-11-06T23:22:34.372Z", - "contributors": [ - "liguorain" - ] - }, - "Glossary/CDN": { - "modified": "2019-03-23T22:04:42.554Z", - "contributors": [ - "Akiq2016", - "woden0415" - ] - }, - "Glossary/CMS": { - "modified": "2019-03-23T22:04:34.697Z", - "contributors": [ - "micblo" - ] - }, - "Glossary/CORS": { - "modified": "2019-03-23T22:25:00.424Z", - "contributors": [ - "WeijianXu", - "zhangchen", - "fs523577192", - "xgqfrms" - ] - }, - "Glossary/CRLF": { - "modified": "2019-03-18T20:54:16.426Z", - "contributors": [ - "WangLeto" - ] - }, - "Glossary/CRUD": { - "modified": "2019-03-23T22:32:20.472Z", - "contributors": [ - "Jack-Q" - ] - }, - "Glossary/CSP": { - "modified": "2019-03-23T22:08:29.528Z", - "contributors": [ - "WayneCui" - ] - }, - "Glossary/CSRF": { - "modified": "2020-01-17T07:27:59.510Z", - "contributors": [ - "九千鸦", - "Toxiiic", - "zhouzhonghao", - "chanWeFun", - "wangfengzi" - ] - }, - "Glossary/CSS": { - "modified": "2020-06-24T05:27:22.049Z", - "contributors": [ - "Ende93", - "Terry.Qiao" - ] - }, - "Glossary/CSSOM": { - "modified": "2020-10-13T09:26:56.960Z", - "contributors": [ - "xgqfrms" - ] - }, - "Glossary/CSS_Selector": { - "modified": "2020-07-08T11:12:08.989Z", - "contributors": [ - "YexuanXiao", - "蓝倍", - "Ende93", - "zhangchizi", - "xgqfrms-GitHub" - ] - }, - "Glossary/CSS_pixel": { - "modified": "2020-10-09T04:26:11.951Z", - "contributors": [ - "benniks", - "Wave-SYJ" - ] - }, - "Glossary/CSS_preprocessor": { - "modified": "2019-05-30T01:07:50.857Z", - "contributors": [ - "心斩心鬼", - "Pedestrian93" - ] - }, - "Glossary/Cache": { - "modified": "2019-03-18T21:21:56.202Z", - "contributors": [ - "Chor" - ] - }, - "Glossary/Call_stack": { - "modified": "2020-09-06T21:44:49.768Z", - "contributors": [ - "xuedaobian", - "LittleBreak", - "RainSlide", - "liminjun", - "theCodingApe", - "mengsheng", - "aFlappyPig", - "nile52", - "chrisxiong" - ] - }, - "Glossary/Callback_function": { - "modified": "2019-03-18T21:27:19.181Z", - "contributors": [ - "dccxi" - ] - }, - "Glossary/Canvas": { - "modified": "2019-09-04T03:49:28.196Z", - "contributors": [ - "Luawig", - "junshine", - "micblo", - "maicss", - "crper", - "gknpezgssb", - "jiahui" - ] - }, - "Glossary/Certified": { - "modified": "2019-10-24T00:27:41.673Z", - "contributors": [ - "NathanWangRuilin" - ] - }, - "Glossary/Character": { - "modified": "2019-03-18T21:25:07.767Z", - "contributors": [ - "mengsheng" - ] - }, - "Glossary/Chrome": { - "modified": "2020-03-16T15:35:45.167Z", - "contributors": [ - "RainSlide", - "micblo", - "xgqfrms-GitHub", - "popcorner", - "yibo" - ] - }, - "Glossary/Code_splitting": { - "modified": "2020-09-18T10:31:05.240Z", - "contributors": [ - "plusmultiply0" - ] - }, - "Glossary/Codec": { - "modified": "2019-07-04T06:44:27.579Z", - "contributors": [ - "songzhenze" - ] - }, - "Glossary/Constructor": { - "modified": "2019-04-09T23:21:24.633Z", - "contributors": [ - "ThornWu" - ] - }, - "Glossary/Continuous_Media": { - "modified": "2019-03-18T21:20:34.473Z", - "contributors": [ - "xuefeng" - ] - }, - "Glossary/Control_flow": { - "modified": "2019-03-18T21:25:15.687Z", - "contributors": [ - "mengsheng" - ] - }, - "Glossary/Cookie": { - "modified": "2019-03-23T22:14:37.806Z", - "contributors": [ - "pluwen", - "RogerShen" - ] - }, - "Glossary/Copyleft": { - "modified": "2019-03-23T22:22:04.793Z", - "contributors": [ - "mengsheng", - "shuibing01" - ] - }, - "Glossary/Crawler": { - "modified": "2019-05-30T01:03:06.156Z", - "contributors": [ - "心斩心鬼" - ] - }, - "Glossary/Cross-site_scripting": { - "modified": "2020-06-19T02:30:34.442Z", - "contributors": [ - "ZSI2017", - "Coink", - "RainSlide", - "MinimalistYing", - "zhuangyin", - "boooooommmmmm", - "locknono", - "wangfengzi" - ] - }, - "Glossary/DNS": { - "modified": "2020-07-21T11:58:33.364Z", - "contributors": [ - "wr20060926", - "kagurakana", - "Marcia_gm" - ] - }, - "Glossary/DOM": { - "modified": "2019-12-20T02:38:51.238Z", - "contributors": [ - "imbant", - "yunng", - "zeyongTsai", - "Undecyce", - "moquede", - "yuyx91", - "byoungd", - "GyonGyon", - "sunnylost", - "leeziwong", - "jianzhou520", - "zsh110123" - ] - }, - "Glossary/DOS_attack": { - "modified": "2019-09-24T06:37:41.240Z", - "contributors": [ - "Umryuan", - "HardcorePhysician" - ] - }, - "Glossary/DTD": { - "modified": "2019-03-23T22:20:01.642Z", - "contributors": [ - "eforegist" - ] - }, - "Glossary/Data_structure": { - "modified": "2019-03-18T21:30:43.505Z", - "contributors": [ - "fs523577192" - ] - }, - "Glossary/Decryption": { - "modified": "2020-08-26T10:35:14.561Z", - "contributors": [ - "BrianTan" - ] - }, - "Glossary/Descriptor_(CSS)": { - "modified": "2019-04-06T08:43:55.316Z", - "contributors": [ - "RainSlide" - ] - }, - "Glossary/Developer_Tools": { - "modified": "2019-05-04T00:00:54.405Z", - "contributors": [ - "fish-inu" - ] - }, - "Glossary/Doctype": { - "modified": "2020-08-09T00:52:32.454Z", - "contributors": [ - "IdEvEbI", - "qwertyuiop6", - "CapDuan", - "pluwen", - "sudoor", - "xieranmaya" - ] - }, - "Glossary/Document_directive": { - "modified": "2019-03-23T22:08:23.918Z", - "contributors": [ - "WayneCui" - ] - }, - "Glossary/Domain": { - "modified": "2019-01-25T04:19:29.126Z", - "contributors": [ - "ChairMao", - "ElliottZheng", - "micblo", - "Folgore" - ] - }, - "Glossary/Domain_sharding": { - "modified": "2020-09-29T09:57:55.545Z", - "contributors": [ - "zuoxiaobai" - ] - }, - "Glossary/Dynamic_programming_language": { - "modified": "2020-07-10T12:09:06.736Z", - "contributors": [ - "JackyJnirvana", - "RainSlide", - "aimiy", - "lukesomnus" - ] - }, - "Glossary/ECMA": { - "modified": "2019-03-23T22:38:49.234Z", - "contributors": [ - "zhangchen", - "cissoid", - "zhangqiong" - ] - }, - "Glossary/ECMAScript": { - "modified": "2019-05-30T01:21:44.281Z", - "contributors": [ - "心斩心鬼" - ] - }, - "Glossary/Encapsulation": { - "modified": "2019-04-01T07:13:58.853Z", - "contributors": [ - "fuckupc", - "zilong-thu" - ] - }, - "Glossary/Endianness": { - "modified": "2020-03-20T23:48:00.364Z", - "contributors": [ - "johnao", - "RainSlide", - "liyongleihf2006" - ] - }, - "Glossary/Engine": { - "modified": "2019-03-18T21:21:59.905Z", - "contributors": [ - "Chor" - ] - }, - "Glossary/Entity": { - "modified": "2020-06-16T04:43:00.878Z", - "contributors": [ - "Clarkkkk" - ] - }, - "Glossary/Entity_header": { - "modified": "2019-09-29T12:16:16.178Z", - "contributors": [ - "cy234", - "huangll", - "vancentvan" - ] - }, - "Glossary/Expando": { - "modified": "2019-03-18T20:52:34.767Z", - "contributors": [ - "houfee", - "ywjco" - ] - }, - "Glossary/FTP": { - "modified": "2019-08-19T02:59:43.649Z", - "contributors": [ - "zhongvsming", - "fs523577192" - ] - }, - "Glossary/Falsy": { - "modified": "2020-09-05T10:05:18.815Z", - "contributors": [ - "zhuangyin", - "niefeng", - "kidonng", - "StephenTian", - "ceido", - "deerwar", - "AlenQi", - "lyhappy", - "stark-jarvis", - "issliu", - "LiuL0703" - ] - }, - "Glossary/Fetch_directive": { - "modified": "2019-08-11T13:04:51.577Z", - "contributors": [ - "NoroHime", - "lcw0622" - ] - }, - "Glossary/First-class_Function": { - "modified": "2020-02-12T10:43:48.192Z", - "contributors": [ - "RainSlide", - "gaoyanglol", - "theprimone", - "maoyumaoxun", - "ydostyle", - "shaodahong", - "Jiang-Xuan", - "eforegist" - ] - }, - "Glossary/First_paint": { - "modified": "2019-09-03T04:44:22.614Z", - "contributors": [ - "c1er" - ] - }, - "Glossary/Flex": { - "modified": "2019-08-29T03:23:56.150Z", - "contributors": [ - "Sandaydi", - "ZZES_REN", - "lordzxp" - ] - }, - "Glossary/Flex_Container": { - "modified": "2020-01-07T06:49:44.655Z", - "contributors": [ - "Spikef", - "Sandaydi" - ] - }, - "Glossary/Flex_Item": { - "modified": "2020-01-07T07:00:40.141Z", - "contributors": [ - "Spikef" - ] - }, - "Glossary/Flexbox": { - "modified": "2019-04-08T08:03:16.113Z", - "contributors": [ - "zjffun" - ] - }, - "Glossary/Fork": { - "modified": "2020-05-24T11:36:12.734Z", - "contributors": [ - "plusmultiply0" - ] - }, - "Glossary/Function": { - "modified": "2019-03-18T20:34:10.018Z", - "contributors": [ - "Pedestrian93", - "RainSlide", - "xgqfrms-GitHub" - ] - }, - "Glossary/GPU": { - "modified": "2020-10-09T04:30:17.457Z", - "contributors": [ - "benniks", - "lizzxc" - ] - }, - "Glossary/GZip_compression": { - "modified": "2019-03-18T20:37:26.371Z", - "contributors": [ - "RainSlide" - ] - }, - "Glossary/Garbage_collection": { - "modified": "2020-08-17T13:28:57.259Z", - "contributors": [ - "xgqfrms" - ] - }, - "Glossary/Gecko": { - "modified": "2020-06-06T07:31:22.104Z", - "contributors": [ - "plusmultiply0" - ] - }, - "Glossary/Git": { - "modified": "2020-06-29T05:36:47.029Z", - "contributors": [ - "woniuxingdong", - "rxliuli", - "micblo" - ] - }, - "Glossary/Global_object": { - "modified": "2020-05-10T10:35:37.066Z", - "contributors": [ - "Isildur46", - "R2h1", - "LIXiangChen" - ] - }, - "Glossary/Google_Chrome": { - "modified": "2020-02-19T22:23:08.425Z", - "contributors": [ - "antield", - "rxliuli" - ] - }, - "Glossary/Grid": { - "modified": "2020-10-29T03:39:41.971Z", - "contributors": [ - "ShanshanXu", - "zhangshaofeng-china", - "houzp", - "Wendy1994", - "GHLandy", - "maicss", - "QizhongFang" - ] - }, - "Glossary/Grid_Areas": { - "modified": "2019-03-18T21:34:33.118Z", - "contributors": [ - "yshenhua" - ] - }, - "Glossary/Grid_Axis": { - "modified": "2019-09-04T10:12:27.732Z", - "contributors": [ - "maicss", - "yshenhua" - ] - }, - "Glossary/Grid_Cell": { - "modified": "2019-03-18T21:34:30.593Z", - "contributors": [ - "yshenhua" - ] - }, - "Glossary/Grid_Column": { - "modified": "2020-07-05T00:36:20.062Z", - "contributors": [ - "jiang-hr", - "yshenhua" - ] - }, - "Glossary/Grid_Container": { - "modified": "2020-12-02T00:04:12.889Z", - "contributors": [ - "echoasuki" - ] - }, - "Glossary/Grid_Lines": { - "modified": "2019-03-18T21:34:33.337Z", - "contributors": [ - "yshenhua" - ] - }, - "Glossary/Grid_Rows": { - "modified": "2019-03-18T21:34:36.923Z", - "contributors": [ - "yshenhua" - ] - }, - "Glossary/Grid_Tracks": { - "modified": "2019-03-18T21:34:38.990Z", - "contributors": [ - "yshenhua" - ] - }, - "Glossary/Guard": { - "modified": "2019-03-18T20:37:40.179Z", - "contributors": [ - "aximario" - ] - }, - "Glossary/Gutters": { - "modified": "2020-06-14T12:16:58.334Z", - "contributors": [ - "lmx-Hexagram", - "yshenhua" - ] - }, - "Glossary/HMAC": { - "modified": "2020-02-12T10:25:41.300Z", - "contributors": [ - "RainSlide", - "micblo" - ] - }, - "Glossary/HSTS": { - "modified": "2019-03-23T22:04:36.602Z", - "contributors": [ - "zhangchen", - "micblo" - ] - }, - "Glossary/HTML": { - "modified": "2020-02-20T04:32:16.427Z", - "contributors": [ - "junbin123", - "Terry.Qiao", - "micblo" - ] - }, - "Glossary/HTML5": { - "modified": "2019-03-18T20:49:23.447Z", - "contributors": [ - "xgqfrms-GitHub", - "CtheSky" - ] - }, - "Glossary/HTTP": { - "modified": "2020-01-08T09:51:35.636Z", - "contributors": [ - "liuhaoXD", - "kenneth55555", - "Mr_zan", - "micblo", - "ArcherGrey" - ] - }, - "Glossary/HTTP_2": { - "modified": "2020-07-12T23:42:29.723Z", - "contributors": [ - "lizzxc", - "maicss" - ] - }, - "Glossary/HTTP_3": { - "modified": "2020-10-22T03:51:22.274Z", - "contributors": [ - "czqn8" - ] - }, - "Glossary/Head": { - "modified": "2019-03-18T21:21:56.726Z", - "contributors": [ - "Chor" - ] - }, - "Glossary/Header": { - "modified": "2020-02-12T09:54:25.924Z", - "contributors": [ - "RainSlide", - "zhangchen", - "WayneCui" - ] - }, - "Glossary/Hoisting": { - "modified": "2020-11-12T05:34:45.112Z", - "contributors": [ - "liguorain", - "Randysheng", - "RainSlide", - "frankfang1990", - "HermitSun", - "Jingle", - "Lucky4", - "liushengxin", - "johncido", - "null-br", - "xgqfrms-GitHub", - "ziyunfei" - ] - }, - "Glossary/Host": { - "modified": "2020-07-05T00:59:45.600Z", - "contributors": [ - "plusmultiply0" - ] - }, - "Glossary/Hyperlink": { - "modified": "2020-02-12T10:04:17.421Z", - "contributors": [ - "RainSlide", - "cosformula" - ] - }, - "Glossary/Hypertext": { - "modified": "2019-03-18T21:21:57.894Z", - "contributors": [ - "Chor" - ] - }, - "Glossary/I18N": { - "modified": "2020-10-06T12:00:25.687Z", - "contributors": [ - "phone-burner", - "plusmultiply0" - ] - }, - "Glossary/ICE": { - "modified": "2019-03-23T22:22:11.521Z", - "contributors": [ - "zslucky" - ] - }, - "Glossary/IDE": { - "modified": "2019-03-18T21:25:05.002Z", - "contributors": [ - "mengsheng" - ] - }, - "Glossary/IPv6": { - "modified": "2020-06-14T05:41:07.911Z", - "contributors": [ - "plusmultiply0" - ] - }, - "Glossary/IP地址": { - "modified": "2020-05-30T02:17:49.722Z", - "contributors": [ - "kagurakana" - ] - }, - "Glossary/IRC": { - "modified": "2020-01-22T01:15:44.275Z", - "contributors": [ - "yunchispk" - ] - }, - "Glossary/ISP": { - "modified": "2020-08-13T07:00:30.274Z", - "contributors": [ - "wordlesspure", - "yenava" - ] - }, - "Glossary/Identifier": { - "modified": "2019-03-23T22:41:56.682Z", - "contributors": [ - "zhangchen", - "Stone-Jay", - "Musan" - ] - }, - "Glossary/IndexedDB": { - "modified": "2019-06-06T04:56:31.067Z", - "contributors": [ - "chenyang", - "cissoid" - ] - }, - "Glossary/Information_architecture": { - "modified": "2019-03-18T21:36:43.305Z", - "contributors": [ - "maoyumaoxun" - ] - }, - "Glossary/Input_method_editor": { - "modified": "2020-11-05T12:12:12.471Z", - "contributors": [ - "xgqfrms" - ] - }, - "Glossary/Instance": { - "modified": "2019-10-29T23:14:55.679Z", - "contributors": [ - "7NZ", - "TomorrowLM" - ] - }, - "Glossary/Internet": { - "modified": "2020-08-22T05:07:47.026Z", - "contributors": [ - "Milkysilk" - ] - }, - "Glossary/JSON": { - "modified": "2020-02-20T04:52:02.459Z", - "contributors": [ - "junbin123", - "typical.dao", - "Jeffrey_Yang", - "xcffl" - ] - }, - "Glossary/Jank": { - "modified": "2020-10-27T07:41:41.881Z", - "contributors": [ - "372817632" - ] - }, - "Glossary/Java": { - "modified": "2019-03-18T21:16:33.360Z", - "contributors": [ - "zylyye", - "micblo" - ] - }, - "Glossary/JavaScript": { - "modified": "2019-03-18T20:37:32.601Z", - "contributors": [ - "codeofjackie", - "iigmir", - "RockJerffreason" - ] - }, - "Glossary/Keyword": { - "modified": "2019-03-18T21:21:58.222Z", - "contributors": [ - "Chor" - ] - }, - "Glossary/Latency": { - "modified": "2019-11-25T06:15:13.433Z", - "contributors": [ - "maicss" - ] - }, - "Glossary/Ligature": { - "modified": "2020-11-26T05:27:21.294Z", - "contributors": [ - "cheetooo" - ] - }, - "Glossary/MIME_type": { - "modified": "2019-04-10T07:56:13.977Z", - "contributors": [ - "IITII", - "icaoweiwei" - ] - }, - "Glossary/MVC": { - "modified": "2020-07-30T02:56:02.707Z", - "contributors": [ - "antield", - "hellozsh" - ] - }, - "Glossary/Main_thread": { - "modified": "2020-05-10T09:23:57.155Z", - "contributors": [ - "Isildur46" - ] - }, - "Glossary/Metadata": { - "modified": "2019-03-18T21:15:07.410Z", - "contributors": [ - "CtheSky" - ] - }, - "Glossary/Method": { - "modified": "2019-12-04T02:53:33.779Z", - "contributors": [ - "tangxiaolang101" - ] - }, - "Glossary/Microsoft_Internet_Explorer": { - "modified": "2019-03-18T21:33:24.087Z", - "contributors": [ - "codeofjackie" - ] - }, - "Glossary/MitM": { - "modified": "2019-03-18T21:23:56.814Z", - "contributors": [ - "511" - ] - }, - "Glossary/Mixin": { - "modified": "2019-12-25T03:47:56.974Z", - "contributors": [ - "c1er" - ] - }, - "Glossary/NAT": { - "modified": "2019-03-23T22:22:05.449Z", - "contributors": [ - "zslucky" - ] - }, - "Glossary/NaN": { - "modified": "2019-03-23T22:15:33.828Z", - "contributors": [ - "zsirfs" - ] - }, - "Glossary/Native": { - "modified": "2019-05-30T01:16:11.681Z", - "contributors": [ - "心斩心鬼" - ] - }, - "Glossary/Navigation_directive": { - "modified": "2019-03-23T22:08:25.696Z", - "contributors": [ - "WayneCui" - ] - }, - "Glossary/Node": { - "modified": "2020-08-14T01:06:38.799Z", - "contributors": [ - "cheiron" - ] - }, - "Glossary/Node.js": { - "modified": "2020-02-11T03:56:12.847Z", - "contributors": [ - "Himself65", - "maicss", - "Meteormatt" - ] - }, - "Glossary/Node/DOM": { - "modified": "2020-02-12T10:17:18.421Z", - "contributors": [ - "RainSlide", - "PYGC" - ] - }, - "Glossary/Null": { - "modified": "2019-03-18T21:43:01.590Z", - "contributors": [ - "weiqinl" - ] - }, - "Glossary/Nullish": { - "modified": "2020-08-16T06:30:47.071Z", - "contributors": [ - "jjc", - "TokisakiYuu" - ] - }, - "Glossary/Number": { - "modified": "2019-09-09T04:17:32.897Z", - "contributors": [ - "c1er", - "NiLinli" - ] - }, - "Glossary/Object": { - "modified": "2019-03-23T22:09:27.267Z", - "contributors": [ - "LangDonHJJ" - ] - }, - "Glossary/OpenGL": { - "modified": "2019-03-18T21:20:47.089Z", - "contributors": [ - "lyuww" - ] - }, - "Glossary/PDF": { - "modified": "2019-03-18T21:46:16.176Z", - "contributors": [ - "zhangchen", - "wanguaf2016" - ] - }, - "Glossary/PHP": { - "modified": "2019-03-23T22:04:31.653Z", - "contributors": [ - "micblo" - ] - }, - "Glossary/PNG": { - "modified": "2019-03-23T22:04:35.077Z", - "contributors": [ - "micblo" - ] - }, - "Glossary/Parse": { - "modified": "2019-03-23T22:03:03.745Z", - "contributors": [ - "ReneeGeng" - ] - }, - "Glossary/Polyfill": { - "modified": "2019-03-18T21:26:23.322Z", - "contributors": [ - "zsxeee" - ] - }, - "Glossary/Preflight_request": { - "modified": "2019-03-18T21:47:05.943Z", - "contributors": [ - "daixinye" - ] - }, - "Glossary/Presto": { - "modified": "2019-03-23T22:59:03.966Z", - "contributors": [ - "ziyunfei", - "Meteormatt" - ] - }, - "Glossary/Primitive": { - "modified": "2019-08-12T02:31:13.867Z", - "contributors": [ - "gaoyia", - "Ty-160", - "jinhuiyon", - "theCodingApe", - "zxsunrise", - "kevinfszu", - "zhangchen", - "Ende93", - "Musan", - "painty" - ] - }, - "Glossary/Protocol": { - "modified": "2020-02-12T10:58:51.176Z", - "contributors": [ - "RainSlide", - "pluwen", - "zihengCat", - "micblo" - ] - }, - "Glossary/Prototype": { - "modified": "2019-08-21T03:14:29.810Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Glossary/Prototype-based_programming": { - "modified": "2020-03-07T09:37:33.527Z", - "contributors": [ - "jingkaimori", - "zhangchen", - "Cnmahj" - ] - }, - "Glossary/Python": { - "modified": "2020-10-06T22:17:26.169Z", - "contributors": [ - "phone-burner", - "micblo" - ] - }, - "Glossary/Quality_values": { - "modified": "2020-11-28T06:01:20.390Z", - "contributors": [ - "Jisu-Woniu", - "fish-inu" - ] - }, - "Glossary/RAIL": { - "modified": "2020-06-02T00:54:01.750Z", - "contributors": [ - "shikelong" - ] - }, - "Glossary/REST": { - "modified": "2019-10-14T08:10:21.102Z", - "contributors": [ - "knightyun" - ] - }, - "Glossary/RSS": { - "modified": "2019-09-28T11:53:40.141Z", - "contributors": [ - "RainSlide", - "zhangchen", - "micblo" - ] - }, - "Glossary/Recursion": { - "modified": "2020-02-12T09:59:55.907Z", - "contributors": [ - "RainSlide", - "Jack-Q" - ] - }, - "Glossary/Reflow": { - "modified": "2019-07-24T07:01:09.046Z", - "contributors": [ - "rguanghui", - "ziyunfei", - "ghostcode" - ] - }, - "Glossary/Regular_expression": { - "modified": "2019-03-23T22:16:15.271Z", - "contributors": [ - "micblo", - "konrumi" - ] - }, - "Glossary/Response_header": { - "modified": "2019-12-12T21:27:05.429Z", - "contributors": [ - "Jinnsh", - "cy234", - "huangll", - "xgqfrms-GitHub" - ] - }, - "Glossary/SDP": { - "modified": "2019-03-18T21:38:42.702Z", - "contributors": [ - "BillgoXu" - ] - }, - "Glossary/SEO": { - "modified": "2019-03-18T21:30:54.800Z", - "contributors": [ - "zaixuzheng" - ] - }, - "Glossary/SMTP": { - "modified": "2019-09-05T00:47:03.224Z", - "contributors": [ - "ran" - ] - }, - "Glossary/SQL": { - "modified": "2019-03-18T21:15:28.379Z", - "contributors": [ - "dccxi", - "micblo" - ] - }, - "Glossary/STUN": { - "modified": "2020-07-22T04:54:18.594Z", - "contributors": [ - "brizer", - "zslucky" - ] - }, - "Glossary/SVG": { - "modified": "2019-03-18T21:36:45.698Z", - "contributors": [ - "zhangchen", - "codeofjackie", - "Zhong", - "pluwen" - ] - }, - "Glossary/SVN": { - "modified": "2019-03-23T22:04:34.134Z", - "contributors": [ - "liuzx-emily", - "micblo" - ] - }, - "Glossary/Same-origin_policy": { - "modified": "2020-06-01T19:24:49.887Z", - "contributors": [ - "HumanSean" - ] - }, - "Glossary/Scope": { - "modified": "2020-10-12T10:53:00.406Z", - "contributors": [ - "Neo42", - "lucida959595", - "RainSlide", - "fnfacun", - "Beibei0529", - "MrRENGE", - "chrislung", - "gucong", - "Capchen", - "walwimp", - "jvua", - "ziyunfei", - "ArcherGrey" - ] - }, - "Glossary/Self-Executing_Anonymous_Function": { - "modified": "2020-10-15T02:06:07.551Z", - "contributors": [ - "greatofdream" - ] - }, - "Glossary/Serialize": { - "modified": "2019-03-23T22:07:45.475Z", - "contributors": [ - "Ende93", - "JohnZengshi" - ] - }, - "Glossary/Server": { - "modified": "2019-03-18T20:48:05.867Z", - "contributors": [ - "Azurak" - ] - }, - "Glossary/Signature": { - "modified": "2019-03-23T22:21:02.397Z", - "contributors": [ - "zhangchen", - "PetiPandaRou" - ] - }, - "Glossary/Signature/Function": { - "modified": "2020-10-28T06:30:26.727Z", - "contributors": [ - "xgqfrms", - "CQBoyBrand", - "RainSlide", - "zhangchen", - "gnu4cn" - ] - }, - "Glossary/Signature/Security": { - "modified": "2019-03-23T22:05:21.249Z", - "contributors": [ - "zhangchen" - ] - }, - "Glossary/Simple_response_header": { - "modified": "2019-03-23T22:15:23.941Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Glossary/Statement": { - "modified": "2019-03-23T22:09:36.294Z", - "contributors": [ - "tjyas" - ] - }, - "Glossary/String": { - "modified": "2020-11-02T23:36:48.603Z", - "contributors": [ - "auntwei" - ] - }, - "Glossary/Symbol": { - "modified": "2020-10-15T23:14:01.224Z", - "contributors": [ - "woshiqiang1", - "BobGreen", - "zhangchen", - "after1271349141", - "7anshuai", - "zhuangyin", - "ReggieLee", - "fengma", - "JoeyChen" - ] - }, - "Glossary/Synchronous": { - "modified": "2020-02-12T10:47:09.690Z", - "contributors": [ - "RainSlide", - "dccxi" - ] - }, - "Glossary/Syntax_error": { - "modified": "2019-03-18T21:37:27.706Z", - "contributors": [ - "rxliuli", - "Tao-Quixote" - ] - }, - "Glossary/TCP": { - "modified": "2019-03-23T23:04:34.080Z", - "contributors": [ - "redoc" - ] - }, - "Glossary/TCP_slow_start": { - "modified": "2020-08-02T12:37:09.640Z", - "contributors": [ - "hellorayza" - ] - }, - "Glossary/TLS": { - "modified": "2019-03-18T21:25:48.038Z", - "contributors": [ - "YuweiZhao" - ] - }, - "Glossary/TURN": { - "modified": "2019-03-23T22:22:16.504Z", - "contributors": [ - "zslucky" - ] - }, - "Glossary/Tag": { - "modified": "2019-03-18T21:22:35.544Z", - "contributors": [ - "Chor", - "eforegist" - ] - }, - "Glossary/Three_js": { - "modified": "2019-07-31T09:49:34.401Z", - "contributors": [ - "DFFZMXJ" - ] - }, - "Glossary/Tree_shaking": { - "modified": "2019-05-21T22:39:10.055Z", - "contributors": [ - "Ende93", - "TeabugCC", - "zhanjunhao" - ] - }, - "Glossary/Truthy": { - "modified": "2019-06-24T05:28:20.142Z", - "contributors": [ - "RainSlide", - "bambooom", - "zhangwang3", - "avocadowang", - "zhaokuohaha", - "soon", - "zhuangyin", - "xgqfrms-GitHub", - "Serifx", - "chomyeong" - ] - }, - "Glossary/Type": { - "modified": "2019-03-23T22:03:20.788Z", - "contributors": [ - "AcJoker" - ] - }, - "Glossary/UI": { - "modified": "2019-03-18T20:48:04.412Z", - "contributors": [ - "Azurak" - ] - }, - "Glossary/URI": { - "modified": "2019-03-23T22:04:35.819Z", - "contributors": [ - "zhangchen", - "micblo" - ] - }, - "Glossary/URL": { - "modified": "2019-12-06T07:54:10.329Z", - "contributors": [ - "chrisdavidmills", - "ewfian", - "zhangchen", - "micblo", - "hawm" - ] - }, - "Glossary/URN": { - "modified": "2019-03-18T20:40:55.809Z", - "contributors": [ - "Yayure" - ] - }, - "Glossary/UTF-8": { - "modified": "2020-08-17T00:29:38.237Z", - "contributors": [ - "Roojay" - ] - }, - "Glossary/UX": { - "modified": "2019-04-23T03:20:51.358Z", - "contributors": [ - "wsqstar", - "qinruiy" - ] - }, - "Glossary/Unicode": { - "modified": "2020-08-17T00:15:19.555Z", - "contributors": [ - "Roojay" - ] - }, - "Glossary/User_agent": { - "modified": "2019-01-17T01:58:36.629Z", - "contributors": [ - "rianma", - "micblo" - ] - }, - "Glossary/Vendor_Prefix": { - "modified": "2020-08-23T11:56:23.098Z", - "contributors": [ - "Clarkkkk", - "Jayeley", - "Oliver_Queen", - "crabmessage", - "acooler15", - "HyattJobs", - "arbiter", - "Antqian", - "XiongAmao", - "broven" - ] - }, - "Glossary/Viewport": { - "modified": "2019-04-21T20:36:22.185Z", - "contributors": [ - "bangbangde", - "zeromike" - ] - }, - "Glossary/WHATWG": { - "modified": "2020-05-10T09:31:46.817Z", - "contributors": [ - "Isildur46", - "RainSlide" - ] - }, - "Glossary/WebGL": { - "modified": "2020-06-16T05:43:11.123Z", - "contributors": [ - "Futrime", - "39Cclound" - ] - }, - "Glossary/WebRTC": { - "modified": "2019-03-23T22:09:00.899Z", - "contributors": [ - "zhangchen", - "SolitudeRA" - ] - }, - "Glossary/WebSockets": { - "modified": "2020-04-05T01:42:34.794Z", - "contributors": [ - "mkckr0", - "fj9140" - ] - }, - "Glossary/World_Wide_Web": { - "modified": "2019-03-23T22:08:50.575Z", - "contributors": [ - "Ende93", - "TomScavo" - ] - }, - "Glossary/XHR_(XMLHttpRequest)": { - "modified": "2019-03-18T20:48:05.724Z", - "contributors": [ - "Azurak", - "HiroKHuang" - ] - }, - "Glossary/XML": { - "modified": "2019-03-23T22:18:17.668Z", - "contributors": [ - "codeofjackie", - "horizon", - "pluwen", - "eeeeeeeason", - "xgqfrms-GitHub" - ] - }, - "Glossary/XPath": { - "modified": "2019-03-18T21:21:51.767Z", - "contributors": [ - "Chor" - ] - }, - "Glossary/XQuery": { - "modified": "2019-03-18T21:21:58.755Z", - "contributors": [ - "Chor" - ] - }, - "Glossary/array": { - "modified": "2020-06-04T05:24:17.827Z", - "contributors": [ - "YanxuGong", - "lovefengruoqing", - "dccxi", - "fisker", - "hlbj105", - "eeeeeeeason", - "RogerShen", - "iigmir", - "isatis" - ] - }, - "Glossary/buffer": { - "modified": "2019-03-18T20:44:54.211Z", - "contributors": [ - "Pedestrian93" - ] - }, - "Glossary/challenge": { - "modified": "2020-01-19T06:41:34.149Z", - "contributors": [ - "cekingLu" - ] - }, - "Glossary/character_set": { - "modified": "2020-08-17T00:58:46.768Z", - "contributors": [ - "Roojay" - ] - }, - "Glossary/document_environment": { - "modified": "2019-03-23T22:19:36.978Z", - "contributors": [ - "ziyunfei", - "xinleibird", - "Saltfish" - ] - }, - "Glossary/firewall": { - "modified": "2020-05-31T01:26:50.469Z", - "contributors": [ - "plusmultiply0" - ] - }, - "Glossary/gif": { - "modified": "2019-03-23T22:04:36.350Z", - "contributors": [ - "zhangchen", - "micblo" - ] - }, - "Glossary/hash": { - "modified": "2019-03-23T22:04:28.956Z", - "contributors": [ - "zhangchen", - "micblo" - ] - }, - "Glossary/https": { - "modified": "2019-06-30T04:47:58.467Z", - "contributors": [ - "ch4zzzzz", - "micblo" - ] - }, - "Glossary/jQuery": { - "modified": "2020-05-09T23:15:26.173Z", - "contributors": [ - "RainSlide", - "yshaojun", - "iigmir" - ] - }, - "Glossary/jpeg": { - "modified": "2020-07-21T12:13:23.651Z", - "contributors": [ - "wr20060926", - "zhangchen", - "micblo" - ] - }, - "Glossary/percent-encoding": { - "modified": "2019-03-18T21:15:22.955Z", - "contributors": [ - "mySoul" - ] - }, - "Glossary/safe": { - "modified": "2020-02-12T10:37:33.808Z", - "contributors": [ - "RainSlide", - "shersty", - "joy-yu", - "maicss" - ] - }, - "Glossary/strict_mode": { - "modified": "2020-02-12T10:21:16.362Z", - "contributors": [ - "RainSlide", - "SphinxKnight", - "troyeagle", - "c1er" - ] - }, - "Glossary/undefined": { - "modified": "2019-06-05T05:27:29.432Z", - "contributors": [ - "lianxiaozhuang", - "LeeVirtue", - "VictorDu" - ] - }, - "Glossary/webp": { - "modified": "2020-11-06T23:30:24.170Z", - "contributors": [ - "liguorain" - ] - }, - "Glossary/主轴": { - "modified": "2020-05-10T10:26:14.352Z", - "contributors": [ - "Isildur46" - ] - }, - "Glossary/交叉轴": { - "modified": "2020-06-09T04:50:28.922Z", - "contributors": [ - "lmx-Hexagram", - "Isildur46" - ] - }, - "Glossary/代理服务器": { - "modified": "2019-03-18T21:22:15.777Z", - "contributors": [ - "lcw0622" - ] - }, - "Glossary/优雅降级": { - "modified": "2020-02-12T11:01:35.540Z", - "contributors": [ - "RainSlide", - "biqing" - ] - }, - "Glossary/伪类": { - "modified": "2020-09-25T11:55:47.602Z", - "contributors": [ - "Ninglo" - ] - }, - "Glossary/元素": { - "modified": "2020-08-10T23:10:02.620Z", - "contributors": [ - "IdEvEbI", - "244462375", - "RainSlide", - "dsdog1997", - "HDUCC", - "jianbinfu", - "pluwen" - ] - }, - "Glossary/卡片分类法": { - "modified": "2019-11-09T07:01:56.698Z", - "contributors": [ - "Xugen-Ma" - ] - }, - "Glossary/地址路由参数域": { - "modified": "2019-03-18T20:31:46.228Z", - "contributors": [ - "huanghe2015" - ] - }, - "Glossary/域名": { - "modified": "2019-03-23T22:04:34.305Z", - "contributors": [ - "micblo" - ] - }, - "Glossary/基线": { - "modified": "2020-05-10T09:55:14.332Z", - "contributors": [ - "Isildur46" - ] - }, - "Glossary/字符编码": { - "modified": "2020-02-12T10:38:11.288Z", - "contributors": [ - "RainSlide", - "fish-inu" - ] - }, - "Glossary/幂等": { - "modified": "2020-06-05T03:53:12.558Z", - "contributors": [ - "bytetown", - "zhangchen", - "WayneCui" - ] - }, - "Glossary/异步": { - "modified": "2020-10-16T00:10:28.593Z", - "contributors": [ - "Neo42", - "fish-inu" - ] - }, - "Glossary/抽象编程": { - "modified": "2020-01-16T01:08:30.168Z", - "contributors": [ - "Kuichen" - ] - }, - "Glossary/数字证书": { - "modified": "2019-03-23T22:26:11.405Z", - "contributors": [ - "Atester" - ] - }, - "Glossary/数据库": { - "modified": "2020-11-25T09:15:57.640Z", - "contributors": [ - "ZH-S" - ] - }, - "Glossary/正常模式": { - "modified": "2019-03-18T21:11:47.868Z", - "contributors": [ - "serverLua", - "CapDuan" - ] - }, - "Glossary/浏览器": { - "modified": "2019-03-23T22:12:12.389Z", - "contributors": [ - "micblo", - "lavenderming" - ] - }, - "Glossary/渐进增强": { - "modified": "2019-03-18T20:54:47.653Z", - "contributors": [ - "biqing" - ] - }, - "Glossary/源": { - "modified": "2019-03-23T22:21:16.972Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Glossary/禁止修改的消息首部": { - "modified": "2019-03-18T20:55:25.213Z", - "contributors": [ - "Opportunity", - "yuankunzhang", - "WayneCui" - ] - }, - "Glossary/空元素": { - "modified": "2020-05-27T05:46:24.967Z", - "contributors": [ - "changjingli", - "Ende93" - ] - }, - "Glossary/立即执行函数表达式": { - "modified": "2019-10-10T13:29:59.923Z", - "contributors": [ - "SAM.L", - "RainSlide", - "zhangchen", - "CapDuan", - "baooab", - "xgqfrms-GitHub", - "zachary05" - ] - }, - "Glossary/第一字节时间": { - "modified": "2020-08-17T07:40:42.498Z", - "contributors": [ - "Facefall" - ] - }, - "Glossary/简单头部": { - "modified": "2019-03-18T21:33:57.550Z", - "contributors": [ - "huangll" - ] - }, - "Glossary/算法": { - "modified": "2019-12-09T04:39:20.829Z", - "contributors": [ - "ran", - "huanghe2015" - ] - }, - "Glossary/类型转换": { - "modified": "2019-06-24T05:38:16.865Z", - "contributors": [ - "RainSlide", - "danielnanuk" - ] - }, - "Glossary/编译": { - "modified": "2019-03-18T21:35:31.612Z", - "contributors": [ - "ethanzway" - ] - }, - "Glossary/编译时间": { - "modified": "2019-03-18T21:35:17.139Z", - "contributors": [ - "ethanzway" - ] - }, - "Glossary/语义": { - "modified": "2020-02-12T10:16:15.832Z", - "contributors": [ - "RainSlide", - "秋色楓", - "acejerry", - "DaMber" - ] - }, - "Glossary/请求头": { - "modified": "2020-02-12T10:12:37.548Z", - "contributors": [ - "RainSlide", - "c1er", - "huangll" - ] - }, - "Glossary/通用首部": { - "modified": "2020-02-12T09:58:36.039Z", - "contributors": [ - "RainSlide", - "WayneCui" - ] - }, - "Glossary/面向对象编程": { - "modified": "2019-03-23T22:19:08.166Z", - "contributors": [ - "zhangchen", - "fan19900404" - ] - }, - "Glossary_of_translation": { - "modified": "2019-03-23T23:33:18.884Z", - "contributors": [ - "Terry.Qiao", - "xcffl", - "iwo", - "yfdyh000" - ] - }, - "HTML_in_XMLHttpRequest": { - "modified": "2019-03-24T00:17:24.579Z", - "contributors": [ - "OoOoOoOo", - "ziyunfei" - ] - }, - "Learn/Accessibility/What_is_accessibility": { - "modified": "2020-11-03T04:59:06.041Z", - "contributors": [ - "No.5972", - "freejack811", - "Firefox_mozilla", - "grape", - "Sc0tt", - "Guitenbay", - "sonwimoo", - "doubleSizeFat", - "ChuckZhang", - "Mangone", - "ziyunfei", - "651584008", - "DennisWang" - ] - }, - "Learn/CSS": { - "modified": "2020-07-16T22:25:38.885Z", - "contributors": [ - "SirnoChan", - "pacexy", - "Ende93", - "nanflower", - "VdoG", - "caoxiaoshuai", - "ALKING", - "suxiesumiao", - "maybe" - ] - }, - "Learn/CSS/Building_blocks": { - "modified": "2020-07-16T22:28:10.588Z", - "contributors": [ - "hex-puck", - "SirnoChan", - "ikomom", - "dlnb526", - "kuhnpku", - "pacexy", - "guangzhengyu", - "chrisdavidmills" - ] - }, - "Learn/CSS/Building_blocks/Advanced_styling_effects": { - "modified": "2020-07-16T22:28:23.268Z", - "contributors": [ - "chrisdavidmills", - "rtxu", - "zhuzhangliang", - "codeofjackie", - "allan_simon", - "sputnikW", - "Froggy" - ] - }, - "Learn/CSS/Building_blocks/Backgrounds_and_borders": { - "modified": "2020-10-29T13:01:37.434Z", - "contributors": [ - "DingGuangbo", - "driftingdream", - "ChongyouXu", - "a-bad-apple", - "SirnoChan", - "CharCat" - ] - }, - "Learn/CSS/Building_blocks/Cascade_and_inheritance": { - "modified": "2020-11-10T06:31:28.229Z", - "contributors": [ - "iwanderer", - "郑玉鑫", - "waipcat", - "niuqv", - "superAlibi", - "a-bad-apple", - "SirnoChan", - "dlnb526", - "flowfire", - "CharCat", - "ArcherGrey" - ] - }, - "Learn/CSS/Building_blocks/Debugging_CSS": { - "modified": "2020-07-16T22:29:30.454Z", - "contributors": [ - "fish-inu", - "SirnoChan", - "blateyang" - ] - }, - "Learn/CSS/Building_blocks/Images_media_form_elements": { - "modified": "2020-07-16T22:29:26.994Z", - "contributors": [ - "ChongyouXu", - "louxinbo", - "dlnb526", - "SirnoChan", - "Conroy-X", - "blateyang", - "probuild" - ] - }, - "Learn/CSS/Building_blocks/Images_tasks": { - "modified": "2020-07-16T22:29:35.387Z", - "contributors": [ - "so2liu", - "dlnb526" - ] - }, - "Learn/CSS/Building_blocks/Organizing": { - "modified": "2020-07-16T22:29:32.923Z", - "contributors": [ - "SirnoChan" - ] - }, - "Learn/CSS/Building_blocks/Overflowing_content": { - "modified": "2020-07-16T22:29:18.978Z", - "contributors": [ - "SirnoChan", - "CharCat" - ] - }, - "Learn/CSS/Building_blocks/Selectors": { - "modified": "2020-07-16T22:28:37.525Z", - "contributors": [ - "YexuanXiao", - "SirnoChan", - "MorrisLi" - ] - }, - "Learn/CSS/Building_blocks/Selectors/Attribute_selectors": { - "modified": "2020-07-16T22:28:51.124Z", - "contributors": [ - "SirnoChan" - ] - }, - "Learn/CSS/Building_blocks/Selectors/Combinators": { - "modified": "2020-07-20T06:27:50.186Z", - "contributors": [ - "xp44mm", - "SirnoChan" - ] - }, - "Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements": { - "modified": "2020-09-10T03:28:34.680Z", - "contributors": [ - "TodWu", - "teisyou", - "SirnoChan" - ] - }, - "Learn/CSS/Building_blocks/Selectors/Selectors_Tasks": { - "modified": "2020-11-03T14:05:32.148Z", - "contributors": [ - "liaozhifeng" - ] - }, - "Learn/CSS/Building_blocks/Selectors/Type_Class_and_ID_Selectors": { - "modified": "2020-08-09T04:04:57.278Z", - "contributors": [ - "driftingdream", - "SirnoChan" - ] - }, - "Learn/CSS/Building_blocks/Sizing_items_in_CSS": { - "modified": "2020-07-16T22:29:23.077Z", - "contributors": [ - "so2liu", - "SirnoChan", - "blateyang", - "byeyear", - "CharCat" - ] - }, - "Learn/CSS/Building_blocks/Styling_tables": { - "modified": "2020-07-16T22:28:19.224Z", - "contributors": [ - "SirnoChan", - "chrisdavidmills", - "rtxu", - "Gmuggle", - "codeofjackie", - "allan_simon", - "xp44mm", - "sputnikW", - "Froggy", - "xgqfrms-GitHub" - ] - }, - "Learn/CSS/Building_blocks/Tables_tasks": { - "modified": "2020-07-20T07:49:16.101Z", - "contributors": [ - "Road" - ] - }, - "Learn/CSS/Building_blocks/The_box_model": { - "modified": "2020-11-07T23:24:47.955Z", - "contributors": [ - "fortunatemouse", - "Young-Spark", - "SirnoChan", - "AsukaZERO2", - "LucioLu", - "CharCat", - "ArcherGrey", - "Wolf-Tungsten", - "xiaocang", - "scauwyf" - ] - }, - "Learn/CSS/Building_blocks/Values_and_units": { - "modified": "2020-07-16T22:28:59.438Z", - "contributors": [ - "tflins", - "SirnoChan", - "dilless", - "CharCat" - ] - }, - "Learn/CSS/Building_blocks/处理_不同_方向的_文本": { - "modified": "2020-07-16T22:29:14.755Z", - "contributors": [ - "ChongyouXu", - "lucida959595", - "Young-Spark", - "ZouYj", - "dlnb526", - "SirnoChan", - "sliop", - "Orzst", - "kuhnpku" - ] - }, - "Learn/CSS/CSS_layout": { - "modified": "2020-08-06T11:35:54.083Z", - "contributors": [ - "mitaosi", - "jeasion", - "bkuke", - "allan_simon", - "xp44mm", - "yydzxz", - "zhuangyin", - "keifergu", - "xgqfrms-GitHub", - "07akioni", - "xuqisheng", - "funnyChinese", - "chrisdavidmills" - ] - }, - "Learn/CSS/CSS_layout/Flexbox": { - "modified": "2020-07-16T22:26:56.499Z", - "contributors": [ - "lhj767382286", - "Damoness", - "sanfusu", - "Daazzer", - "Deepmind", - "LeoB-O", - "codingJanson", - "ssttii", - "codeofjackie", - "ZuanXiao", - "Venus14", - "xp44mm", - "MingzhaoCN", - "echoArray", - "JohannLai", - "hexianzhi", - "xgqfrms-GitHub", - "Ende93" - ] - }, - "Learn/CSS/CSS_layout/Floats": { - "modified": "2020-09-01T00:39:00.054Z", - "contributors": [ - "laodengjuntuan", - "laizenan", - "Hermedius", - "WindLo", - "codeofjackie", - "fourml", - "NPUTom", - "xp44mm", - "lowkey2046", - "yydzxz", - "Froggy", - "Code-Dmit", - "Barren", - "Wantian", - "WJoan", - "Ende93", - "1986slayer", - "xuqisheng" - ] - }, - "Learn/CSS/CSS_layout/Fundamental_Layout_Comprehension": { - "modified": "2020-07-16T22:27:25.343Z", - "contributors": [ - "Lyan831", - "littlemonkeycc" - ] - }, - "Learn/CSS/CSS_layout/Grid_skills": { - "modified": "2020-10-29T08:46:11.815Z", - "contributors": [ - "greatofdream", - "LitStronger" - ] - }, - "Learn/CSS/CSS_layout/Grids": { - "modified": "2020-09-27T04:01:08.661Z", - "contributors": [ - "Tiny-Wei", - "MmmmHeee", - "DarkStory", - "DreamLxq", - "grape", - "rtxu", - "codeofjackie", - "ddtyjmyjm", - "allan_simon", - "xp44mm", - "sputnikW", - "xycd", - "o02112", - "1986slayer", - "disoul", - "ziyunfei", - "xgqfrms-GitHub", - "07akioni" - ] - }, - "Learn/CSS/CSS_layout/Introduction": { - "modified": "2020-11-10T11:43:06.981Z", - "contributors": [ - "郑玉鑫", - "LuckyWind_sck", - "jiaruh", - "laizenan", - "PiscesXP", - "bkuke", - "Redux", - "monkey-king", - "hayahayao", - "SampsonKY", - "rtxu", - "Yayure", - "javazsh", - "zxsunrise", - "NPUTom", - "allan_simon", - "xp44mm", - "yydzxz", - "Froggy", - "xgqfrms-GitHub", - "Junetea" - ] - }, - "Learn/CSS/CSS_layout/Media_queries": { - "modified": "2020-07-16T22:27:33.217Z", - "contributors": [ - "ihua", - "SirnoChan" - ] - }, - "Learn/CSS/CSS_layout/Multiple-column_Layout": { - "modified": "2020-07-16T22:27:12.326Z", - "contributors": [ - "SirnoChan", - "sun_xiansong" - ] - }, - "Learn/CSS/CSS_layout/Normal_Flow": { - "modified": "2020-07-21T07:23:26.004Z", - "contributors": [ - "niuqv", - "boxerqyx", - "laizenan", - "sun_xiansong" - ] - }, - "Learn/CSS/CSS_layout/Position_skills": { - "modified": "2020-07-16T22:27:35.343Z", - "contributors": [ - "yuqing521" - ] - }, - "Learn/CSS/CSS_layout/Practical_positioning_examples": { - "modified": "2020-07-16T22:26:50.001Z", - "contributors": [ - "grape", - "LeoB-O", - "liy010", - "BusyToDie", - "codeofjackie", - "saifeiLee", - "Yangxulei", - "xp44mm", - "ddtyjmyjm", - "wsy", - "1986slayer" - ] - }, - "Learn/CSS/CSS_layout/Responsive_Design": { - "modified": "2020-11-06T04:59:33.514Z", - "contributors": [ - "amai0w0", - "SirnoChan" - ] - }, - "Learn/CSS/CSS_layout/Supporting_Older_Browsers": { - "modified": "2020-07-16T22:27:19.547Z", - "contributors": [ - "ihua", - "SirnoChan" - ] - }, - "Learn/CSS/CSS_layout/传统的布局方法": { - "modified": "2020-07-16T22:27:16.084Z", - "contributors": [ - "SirnoChan", - "Hermedius", - "zxxzzzzz", - "agnoCJY" - ] - }, - "Learn/CSS/CSS_layout/定位": { - "modified": "2020-12-01T00:39:03.074Z", - "contributors": [ - "zisedelinghun", - "driftingdream", - "laizenan", - "parabolazz", - "LuoYun", - "TaoXuSheng", - "codeofjackie", - "fourml", - "summercn", - "allan_simon", - "yuyx91", - "lihaoyuan", - "xp44mm", - "yydzxz", - "ddtyjmyjm", - "Froggy", - "uestcNaldo", - "Eric.Wu", - "echoArray", - "xgqfrms-GitHub", - "Ende93", - "depressedX", - "siufooncheung", - "1986slayer" - ] - }, - "Learn/CSS/First_steps": { - "modified": "2020-07-16T22:27:41.508Z", - "contributors": [ - "dlnb526", - "pacexy", - "ch4o5", - "RUAN-ZX", - "Nicet", - "Xwil", - "0x79b9", - "grape", - "kfk2454" - ] - }, - "Learn/CSS/First_steps/CSS如何运行": { - "modified": "2020-07-16T22:28:02.363Z", - "contributors": [ - "ChongyouXu", - "shizigood", - "dlnb526", - "SirnoChan", - "pacexy", - "kuhnpku", - "FrankYuanhao", - "0x79b9", - "SphinxKnight", - "xcxAscar" - ] - }, - "Learn/CSS/First_steps/How_CSS_is_structured": { - "modified": "2020-10-06T13:23:28.338Z", - "contributors": [ - "greatofdream", - "aaazz47", - "郑玉鑫", - "JiachenLi941109", - "a-bad-apple", - "dlnb526", - "kuhnpku", - "CUI-C", - "byeyear", - "operaxxx", - "hhq1801", - "AlexWuluanfeng", - "ArcherGrey" - ] - }, - "Learn/CSS/First_steps/Using_your_new_knowledge": { - "modified": "2020-07-16T22:28:05.597Z", - "contributors": [ - "dlnb526", - "kuhnpku", - "Hans0915" - ] - }, - "Learn/CSS/First_steps/What_is_CSS": { - "modified": "2020-10-15T22:22:49.061Z", - "contributors": [ - "dlnb526", - "liginity", - "sanfusu", - "Nicet", - "Xwil", - "ArcherGrey" - ] - }, - "Learn/CSS/First_steps/开始": { - "modified": "2020-07-16T22:27:52.665Z", - "contributors": [ - "dlnb526", - "SirnoChan", - "byeyear", - "HHao", - "zyzxrj", - "fondxy", - "Amano-Aki", - "RUAN-ZX" - ] - }, - "Learn/CSS/Howto": { - "modified": "2020-07-16T22:25:44.300Z", - "contributors": [ - "Coink", - "yawei", - "JobWebNie", - "githubxiaowen" - ] - }, - "Learn/CSS/Introduction_to_CSS/Fundamental_CSS_comprehension": { - "modified": "2020-10-09T04:34:43.547Z", - "contributors": [ - "benniks", - "blateyang", - "grape", - "LeoB-O", - "codeofjackie", - "allan_simon", - "phiwyc", - "yydzxz", - "ddtyjmyjm", - "nbhaohao" - ] - }, - "Learn/CSS/Styling_boxes/A_cool_looking_box": { - "modified": "2020-07-16T22:28:27.701Z", - "contributors": [ - "grape", - "Lohoyo", - "lihaoyuan" - ] - }, - "Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper": { - "modified": "2020-07-16T22:28:25.559Z", - "contributors": [ - "codeofjackie", - "ziyunfei", - "Yee", - "lihaoyuan" - ] - }, - "Learn/CSS/为文本添加样式": { - "modified": "2020-07-16T22:26:01.367Z", - "contributors": [ - "kohai", - "LJJ1996", - "allan_simon", - "zhuangyin", - "zhang-kai", - "ZhongyiChen" - ] - }, - "Learn/CSS/为文本添加样式/Fundamentals": { - "modified": "2020-07-16T22:26:10.120Z", - "contributors": [ - "AlephAlpha", - "Otaku-Glasses", - "grape", - "xiaoman", - "byeyear", - "Sinclair-Yuan", - "ssttii", - "tiange321", - "sixDregs", - "zhuzhangliang", - "liy010", - "codeofjackie", - "1862", - "maoyumaoxun", - "allan_simon", - "comehope", - "xp44mm", - "sputnikW", - "yydzxz", - "Froggy", - "nbhaohao" - ] - }, - "Learn/CSS/为文本添加样式/Styling_links": { - "modified": "2020-07-16T22:26:21.533Z", - "contributors": [ - "so2liu", - "SirnoChan", - "Map1en_", - "LeoB-O", - "dchaofei", - "codeofjackie", - "Fungzhe", - "allan_simon", - "xp44mm", - "sputnikW", - "nbhaohao" - ] - }, - "Learn/CSS/为文本添加样式/Styling_lists": { - "modified": "2020-07-16T22:26:15.817Z", - "contributors": [ - "rtxu", - "codeofjackie", - "allan_simon", - "xp44mm", - "Froggy", - "jingyiwang1209", - "Ende93", - "Barren", - "qw950027", - "dazyzsy" - ] - }, - "Learn/CSS/为文本添加样式/Typesetting_a_homepage": { - "modified": "2020-07-16T22:26:27.995Z", - "contributors": [ - "monkey-king", - "grape", - "Map1en_", - "codeofjackie", - "maplelinst" - ] - }, - "Learn/CSS/为文本添加样式/Web_字体": { - "modified": "2020-07-16T22:26:25.043Z", - "contributors": [ - "AlephAlpha", - "LeoB-O", - "zenghuiLee", - "admin1949", - "wheeljs", - "Froggy" - ] - }, - "Learn/Common_questions": { - "modified": "2020-07-16T22:35:28.142Z", - "contributors": [ - "DaniellaAngel", - "y976362357", - "yuyx91", - "ArcherGrey", - "lavenderming", - "ziyunfei", - "funnyChinese", - "wth", - "Yidada" - ] - }, - "Learn/Common_questions/Checking_that_your_web_site_is_working_properly": { - "modified": "2020-10-06T06:46:00.886Z", - "contributors": [ - "kuailekai", - "Chor" - ] - }, - "Learn/Common_questions/Common_web_layouts": { - "modified": "2020-08-08T20:06:40.833Z", - "contributors": [ - "DarkStory", - "秋色楓", - "TpOut" - ] - }, - "Learn/Common_questions/How_do_you_host_your_website_on_Google_App_Engine": { - "modified": "2020-07-16T22:35:52.536Z", - "contributors": [ - "DaniellaAngel", - "sky5454" - ] - }, - "Learn/Common_questions/How_much_does_it_cost": { - "modified": "2020-11-12T06:17:33.350Z", - "contributors": [ - "咸鱼快去读书", - "kidonng", - "SirnoChan", - "Yang_Hanlin", - "Geno1024", - "bingxl", - "xiwusheng", - "JohnJiangLA", - "sher", - "ArcherGrey" - ] - }, - "Learn/Common_questions/Pages_sites_servers_and_search_engines": { - "modified": "2020-07-16T22:35:41.034Z", - "contributors": [ - "DaniellaAngel", - "sanshuiyang", - "m4jing", - "BarryLiu1995", - "Folgore", - "ziyunfei", - "wth" - ] - }, - "Learn/Common_questions/Thinking_before_coding": { - "modified": "2020-07-16T22:35:35.095Z", - "contributors": [ - "yuandengcheng", - "StarryForce", - "Snailight", - "gaoyia", - "ziyouwa", - "Zeng", - "MinimalistYing", - "ziyunfei", - "wth" - ] - }, - "Learn/Common_questions/Upload_files_to_a_web_server": { - "modified": "2020-07-16T22:35:42.078Z", - "contributors": [ - "bingxl", - "xiwusheng", - "PokimLee", - "summerstarlee", - "ArcherGrey" - ] - }, - "Learn/Common_questions/Using_Github_pages": { - "modified": "2020-07-16T22:35:52.151Z", - "contributors": [ - "WoodCube", - "TeabugCC", - "zhangtianle", - "zhuangyin", - "Bernie_Lai" - ] - }, - "Learn/Common_questions/What_are_hyperlinks": { - "modified": "2020-07-16T22:35:43.473Z", - "contributors": [ - "jingkaimori", - "AnneBai", - "yuyx91", - "wanguaf2016", - "ziyunfei", - "wth" - ] - }, - "Learn/Common_questions/What_is_a_URL": { - "modified": "2020-10-09T04:39:23.544Z", - "contributors": [ - "benniks", - "ljybill", - "DaniellaAngel", - "miaoxiaozui2017", - "gmmxle", - "wanguaf2016", - "zhuangyin", - "ziyunfei", - "wth" - ] - }, - "Learn/Common_questions/What_is_a_domain_name": { - "modified": "2020-08-08T19:40:26.068Z", - "contributors": [ - "DarkStory", - "Adrian-Yan", - "DaniellaAngel", - "imba-tjd", - "yi2sun", - "miaoxiaozui2017", - "gmmxle", - "yydzxz", - "zhangjy90", - "ziyunfei", - "wth" - ] - }, - "Learn/Common_questions/What_is_a_web_server": { - "modified": "2020-07-16T22:35:32.316Z", - "contributors": [ - "grape", - "alhardly", - "Fogwind", - "Zzt-G", - "ZhuZhuDrinkMilk", - "gmmxle", - "BarryLiu1995", - "GHLgh", - "ziyunfei", - "wth" - ] - }, - "Learn/Common_questions/What_is_accessibility": { - "modified": "2020-07-16T22:35:46.965Z", - "contributors": [ - "ziyunfei", - "wth" - ] - }, - "Learn/Common_questions/What_software_do_I_need": { - "modified": "2020-07-16T22:35:33.819Z", - "contributors": [ - "What-username-will-make-you-feel-cute", - "GHLgh" - ] - }, - "Learn/Common_questions/set_up_a_local_testing_server": { - "modified": "2020-07-16T22:35:53.993Z", - "contributors": [ - "yi2sun", - "Singee", - "chaosdog", - "zihengCat", - "ElliottZheng", - "Kiekerti", - "overcat", - "Selence1988" - ] - }, - "Learn/Common_questions/实用文本编辑器": { - "modified": "2020-07-16T22:35:49.753Z", - "contributors": [ - "A-rise" - ] - }, - "Learn/Discover_browser_developer_tools": { - "modified": "2020-08-09T19:35:32.533Z", - "contributors": [ - "DarkStory", - "eelord", - "ziyouwa", - "Atractylodes", - "wth", - "ziyunfei", - "zhaoy875" - ] - }, - "Learn/Getting_started_with_the_web": { - "modified": "2020-09-24T11:26:23.243Z", - "contributors": [ - "chrisdavidmills", - "我不会算命", - "SuiltaPico", - "tonyxu-io", - "deliberative", - "kohai", - "xmcgcg", - "codeofjackie", - "Bearies", - "liliang-cn", - "ArcherGrey", - "wh1msy", - "fan19900404", - "Ende93", - "troywith77", - "lwxyfer", - "zhuo" - ] - }, - "Learn/Getting_started_with_the_web/CSS_basics": { - "modified": "2020-08-09T00:11:27.720Z", - "contributors": [ - "DarkStory", - "youngquan", - "Roy-Tian", - "SphinxKnight", - "Calculus9", - "MorrisLi", - "bluedrawer", - "123cxm", - "typical.dao", - "xmcgcg", - "codeofjackie", - "myfreeer", - "mvooer", - "ziyouwa", - "lavenderming", - "fan19900404", - "Roy1993sun", - "ktereyp", - "suxiesumiao", - "cuitianze", - "ladrift", - "FredWe", - "troywith77", - "ziyunfei" - ] - }, - "Learn/Getting_started_with_the_web/Dealing_with_files": { - "modified": "2020-07-16T22:34:39.613Z", - "contributors": [ - "Roy-Tian", - "cunlim", - "xmcgcg", - "erhuo233", - "14Mars", - "Planet6174", - "linw1995", - "gituser", - "EricKY26", - "eelord", - "lowkey2046", - "yzweb2018", - "fan19900404", - "S099001", - "i-PeterZhang", - "cuitianze", - "troywith77", - "lobak" - ] - }, - "Learn/Getting_started_with_the_web/HTML_basics": { - "modified": "2020-12-02T05:16:28.871Z", - "contributors": [ - "xxlovett0706", - "zrzjohn", - "Roy-Tian", - "Sphish", - "Daniel313", - "xmcgcg", - "erhuo233", - "liujinmenghaoren", - "zihengCat", - "eelord", - "mvooer", - "Hunfen", - "Alan.W.Wang", - "ArcherGrey", - "Yogayu", - "HashubWang", - "chenxingyu350128", - "nevermore1000", - "fan19900404", - "ChrisCaixx", - "troywith77", - "ldwformat" - ] - }, - "Learn/Getting_started_with_the_web/How_the_Web_works": { - "modified": "2020-09-07T00:26:56.702Z", - "contributors": [ - "guangyu890", - "DarkStory", - "yunchispk", - "Sphish", - "Li-saltair", - "grape", - "wi24rd", - "W-YaoLing", - "14Mars", - "codeofjackie", - "liliang-cn", - "ArcherGrey", - "tjyas", - "lavenderming", - "fan19900404", - "liminjun", - "ziyunfei", - "troywith77" - ] - }, - "Learn/Getting_started_with_the_web/Installing_basic_software": { - "modified": "2020-07-16T22:34:12.565Z", - "contributors": [ - "Roy-Tian", - "kidonng", - "Cybercll", - "tonyxu-io", - "ozxo", - "xmcgcg", - "codeofjackie", - "shuijingwan", - "codertomns", - "Bearies", - "overcat", - "fan19900404", - "jian86392088", - "troywith77" - ] - }, - "Learn/Getting_started_with_the_web/JavaScript_basics": { - "modified": "2020-09-07T02:11:05.975Z", - "contributors": [ - "YeLi-blip", - "DarkStory", - "liangmuyang", - "youngquan", - "Roy-Tian", - "kingeyesee", - "anguiao", - "shadynaga", - "yanyong666", - "tomatokai", - "Sphish", - "naivexcited", - "Chuang", - "coldpc", - "imba-tjd", - "SphinxKnight", - "sllLovewy", - "zaixuzheng", - "xmcgcg", - "nuzar", - "codeofjackie", - "allan_simon", - "Fangfeidenimen", - "susscc", - "runyul", - "Becky", - "PythonFo", - "Frodocz", - "dirringx", - "tjyas", - "xgqfrms-GitHub", - "frankfang1990", - "IShinji", - "HEIS", - "fan19900404", - "boredivan", - "wenxiangmao", - "troywith77", - "MrH2S", - "lwxyfer" - ] - }, - "Learn/Getting_started_with_the_web/Publishing_your_website": { - "modified": "2020-07-16T22:34:29.916Z", - "contributors": [ - "cunlim", - "jingkaimori", - "Sphish", - "WoodCube", - "WindLo", - "Yang_Hanlin", - "xmcgcg", - "Unequaled804", - "yzweb2018", - "runyul", - "b2ns", - "fan19900404", - "tntC4stl3", - "troywith77" - ] - }, - "Learn/Getting_started_with_the_web/The_web_and_web_standards": { - "modified": "2020-08-31T09:33:22.013Z", - "contributors": [ - "YiberZ" - ] - }, - "Learn/Getting_started_with_the_web/What_will_your_website_look_like": { - "modified": "2020-11-29T07:11:33.143Z", - "contributors": [ - "zrzjohn", - "Roy-Tian", - "WoodCube", - "outloudvi", - "xmcgcg", - "Harry-Zhao", - "liangshuhua", - "abc3660170", - "liminjun", - "ZhouZhou360", - "DUHZ", - "fan19900404", - "Kevin-Xi", - "troywith77", - "ziyunfei" - ] - }, - "Learn/HTML/Forms": { - "modified": "2020-07-16T22:21:02.678Z", - "contributors": [ - "615lyw", - "Lohoyo", - "lihaoyuan", - "yydzxz", - "StarryForce", - "Froggy", - "chrisdavidmills", - "ziyunfei", - "JulieLee77", - "teoli", - "Jeremie" - ] - }, - "Learn/HTML/Forms/Advanced_styling_for_HTML_forms": { - "modified": "2020-07-16T22:21:36.744Z", - "contributors": [ - "rtxu", - "Daniel313", - "codeofjackie", - "yydzxz", - "tzigang" - ] - }, - "Learn/HTML/Forms/Data_form_validation": { - "modified": "2020-07-16T22:21:53.600Z", - "contributors": [ - "dlnb526", - "wavedanger", - "WoodCube", - "PYGC", - "liudadadayu", - "Amano_Sei", - "kazimics", - "codeofjackie", - "tinyhare", - "lihaoyuan", - "dondevi", - "littledust", - "crper", - "yydzxz", - "pantao", - "Froggy", - "xianshenglu", - "songbinghui", - "monsterooo", - "liu-xiao-cui", - "jileieli" - ] - }, - "Learn/HTML/Forms/HTML_forms_in_legacy_browsers": { - "modified": "2020-07-16T22:22:04.178Z", - "contributors": [ - "haoye999", - "lovedebug", - "jaiJia", - "littledust" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets": { - "modified": "2020-07-16T22:21:58.787Z", - "contributors": [ - "WoodCube", - "rtxu", - "feixiang5754", - "lonelywhisper", - "yasminyt", - "honey6", - "codeofjackie", - "tinyhare", - "yochii", - "uselessaddress", - "crper", - "yydzxz", - "zqyue", - "darkeggler", - "Froggy", - "chrisdavidmills", - "Sheppy", - "ziyunfei", - "helloguangxue" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1": { - "modified": "2020-07-16T22:21:59.182Z", - "contributors": [ - "Qos", - "549074491", - "codeofjackie" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2": { - "modified": "2020-07-16T22:21:59.542Z", - "contributors": [ - "shc0743", - "codeofjackie" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3": { - "modified": "2020-07-16T22:21:59.861Z", - "contributors": [ - "shc0743", - "codeofjackie" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4": { - "modified": "2020-07-16T22:22:00.186Z", - "contributors": [ - "shc0743", - "codeofjackie" - ] - }, - "Learn/HTML/Forms/How_to_structure_an_HTML_form": { - "modified": "2020-07-16T22:21:16.348Z", - "contributors": [ - "lucida959595", - "imba-tjd", - "naivexcited", - "WoodCube", - "Zhang-YanQi", - "liy010", - "web-xx", - "codeofjackie", - "lihaoyuan", - "yawei", - "zqyue", - "StarryForce", - "Froggy" - ] - }, - "Learn/HTML/Forms/Property_compatibility_table_for_form_widgets": { - "modified": "2020-07-16T22:21:44.843Z", - "contributors": [ - "codeofjackie", - "lovedebug" - ] - }, - "Learn/HTML/Forms/Sending_and_retrieving_form_data": { - "modified": "2020-07-16T22:21:29.690Z", - "contributors": [ - "rtxu", - "WoodCube", - "aliang2017", - "codeofjackie", - "yydzxz", - "Froggy", - "KngZhi", - "chrisdavidmills", - "juzhiyuan" - ] - }, - "Learn/HTML/Forms/Sending_forms_through_JavaScript": { - "modified": "2020-07-16T22:22:02.523Z", - "contributors": [ - "RainSlide", - "WoodCube", - "xing2000", - "Bayes", - "codeofjackie", - "littledust", - "yydzxz", - "Chenng", - "chrisdavidmills", - "ziyunfei", - "sanxingming", - "helloguangxue", - "teoli" - ] - }, - "Learn/HTML/Forms/Styling_HTML_forms": { - "modified": "2020-07-16T22:21:32.838Z", - "contributors": [ - "jiaodk", - "rtxu", - "coder-git", - "33YANG", - "Daniel313", - "codeofjackie", - "lovedebug", - "yydzxz", - "lucoo01" - ] - }, - "Learn/HTML/Forms/The_native_form_widgets": { - "modified": "2020-09-17T23:41:07.186Z", - "contributors": [ - "aaazz47", - "853419196", - "WoodCube", - "wsyconan", - "Drizzt-Yu", - "Kavelaa", - "coldicecn", - "Danielxiey", - "codeofjackie", - "Lohoyo", - "lihaoyuan", - "xp44mm", - "uselessaddress", - "littledust", - "yydzxz", - "ddtyjmyjm", - "StarryForce", - "Froggy" - ] - }, - "Learn/HTML/Forms/Your_first_HTML_form": { - "modified": "2020-08-16T03:03:38.716Z", - "contributors": [ - "NicholasZhan", - "WoodCube", - "ChairMao", - "haoye999", - "coldicecn", - "xiangluoming", - "hddhyq", - "Lohoyo", - "maoyumaoxun", - "lyncodes", - "allan_simon", - "lihaoyuan", - "superkuang", - "ddtyjmyjm", - "StarryForce", - "Froggy", - "chrisdavidmills", - "ziyunfei", - "sanxingming" - ] - }, - "Learn/HTML/Introduction_to_HTML/Creating_hyperlinks": { - "modified": "2020-12-06T07:20:56.145Z", - "contributors": [ - "zrzjohn", - "kuailekai", - "Roy-Tian", - "eryisan", - "newryu", - "youngquan", - "MorrisLi", - "sunsimin", - "Zeapou", - "szxcool", - "haobing", - "monkey-king", - "baijingfeng", - "WindLo", - "imba-tjd", - "wblovezqy", - "ZhangDaZongWei", - "HolaForce", - "HeYuansong", - "codeofjackie", - "kidzhou", - "shiyubo", - "eelord", - "X-21", - "zhaoqize", - "littledust", - "HashubWang", - "Atractylodes", - "igigi", - "Primevera", - "hawm", - "ziyunfei", - "danlanxiaohei", - "c0ldian" - ] - }, - "Learn/HTML/Multimedia_and_embedding": { - "modified": "2020-07-16T22:24:30.708Z", - "contributors": [ - "Melo.HG", - "pacexy", - "Dongxi729", - "xmcgcg", - "key1024", - "HolaForce", - "at2008", - "xp44mm", - "xuminke", - "pengtikui", - "Ende93", - "123456zzz", - "gzw", - "cheiron", - "HashubWang", - "chrisdavidmills" - ] - }, - "Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web": { - "modified": "2020-09-22T09:07:16.536Z", - "contributors": [ - "NellPoi", - "grape", - "WindLo", - "Alexanderonepills", - "ChairMao", - "haoye999", - "codeofjackie", - "lihaoyuan", - "yydzxz", - "zhangchen", - "Amanda356421", - "cheiron", - "ziyunfei" - ] - }, - "Learn/HTML/Multimedia_and_embedding/Images_in_HTML": { - "modified": "2020-07-16T22:24:48.583Z", - "contributors": [ - "TonyAble", - "jiaodk", - "SirnoChan", - "monkey-king", - "WoodCube", - "WindLo", - "Roy-Tian", - "HolaForce", - "Planet6174", - "CaTmmao", - "lihaoyuan", - "yydzxz", - "nbhaohao", - "HashubWang", - "gzw", - "MinimalistYing" - ] - }, - "Learn/HTML/Multimedia_and_embedding/Mozilla_splash_page": { - "modified": "2020-07-16T22:25:08.878Z", - "contributors": [ - "Roy-Tian", - "FantasqueX", - "codeofjackie", - "lihaoyuan", - "superkuang", - "nbhaohao" - ] - }, - "Learn/HTML/Multimedia_and_embedding/Responsive_images": { - "modified": "2020-07-16T22:24:38.469Z", - "contributors": [ - "waipcat", - "cetewhale", - "WoodCube", - "WindLo", - "Roy-Tian", - "charvin", - "ZhangDaZongWei", - "codeofjackie", - "lihaoyuan", - "yydzxz", - "ddtyjmyjm", - "Aladdin-ADD", - "nbhaohao", - "hjb912", - "Eric.Wu", - "HashubWang", - "xuqisheng" - ] - }, - "Learn/HTML/Multimedia_and_embedding/Video_and_audio_content": { - "modified": "2020-09-10T14:24:48.534Z", - "contributors": [ - "MmmmHeee", - "DarkStory", - "niuqv", - "Clarkkkk", - "Sichen-Wang", - "luneshao", - "monkey-king", - "LALALA", - "wi24rd", - "WindLo", - "Roy-Tian", - "HolaForce", - "phiwyc", - "lihaoyuan", - "getfile", - "SheltonDong" - ] - }, - "Learn/HTML/Multimedia_and_embedding/Video_and_audio_content/Test_your_skills:_Multimedia_and_embedding": { - "modified": "2020-08-22T23:02:32.400Z", - "contributors": [ - "badwomanIloveyou" - ] - }, - "Learn/HTML/Multimedia_and_embedding/其他嵌入技术": { - "modified": "2020-09-22T04:49:55.434Z", - "contributors": [ - "NellPoi", - "yangko", - "pacexy", - "monkey-king", - "WoodCube", - "Roy-Tian", - "ChairMao", - "ZhangDaZongWei", - "Danielxiey", - "615lyw", - "CaTmmao", - "Lohoyo", - "RevolverOcelotA", - "lihaoyuan", - "superkuang", - "yydzxz", - "ddtyjmyjm", - "Eric.Wu" - ] - }, - "Learn/HTML/Tables": { - "modified": "2020-07-16T22:25:16.499Z", - "contributors": [ - "chaosdog", - "micblo", - "pantao", - "HashubWang", - "chrisdavidmills" - ] - }, - "Learn/HTML/Tables/Advanced": { - "modified": "2020-07-16T22:25:28.194Z", - "contributors": [ - "WoodCube", - "WindLo", - "MichaelMeng", - "codeofjackie", - "at2008", - "littledust", - "nbhaohao" - ] - }, - "Learn/HTML/Tables/Basics": { - "modified": "2020-09-15T09:08:11.153Z", - "contributors": [ - "LitStronger", - "WoodCube", - "WindLo", - "codeofjackie", - "chaosdog", - "lihaoyuan", - "littledust", - "nbhaohao", - "Mac_zhang", - "Carolinecjun" - ] - }, - "Learn/HTML/Tables/Structuring_planet_data": { - "modified": "2020-07-16T22:25:31.394Z", - "contributors": [ - "Roy-Tian", - "WoodCube", - "Undecyce", - "lihaoyuan", - "nbhaohao" - ] - }, - "Learn/JavaScript/Building_blocks/Events": { - "modified": "2020-08-04T06:06:58.173Z", - "contributors": [ - "driftingdream", - "KshZh", - "Carllllo", - "Isildur46", - "agnoCJY", - "chj", - "Meteormatt", - "DropDatabase", - "scsc4212", - "caifx", - "Unissn7", - "moozhu", - "jiangtian", - "gaopu", - "zaoangod", - "offcos", - "RundongZou", - "SummerVibes", - "Ray-Eldath", - "ziyunfei", - "carolinezhao", - "Ende93", - "finegao", - "Zeng", - "Hayden_Zhou" - ] - }, - "Learn/JavaScript/Client-side_web_APIs": { - "modified": "2020-07-16T22:32:43.013Z", - "contributors": [ - "Adrian-Yan", - "qazsweet", - "yinpeng123", - "tossp", - "kensz66", - "Zheng7426", - "winlans", - "XuQuan-nikkkki", - "xp44mm", - "dandanbu3", - "l987974", - "Noly1990", - "chrisdavidmills" - ] - }, - "Learn/JavaScript/Client-side_web_APIs/Client-side_storage": { - "modified": "2020-12-01T11:54:42.356Z", - "contributors": [ - "zisedelinghun", - "talentAN", - "FlyCloud", - "SphinxKnight", - "DreamLxq", - "bkuke", - "grape", - "LeoooY", - "lyuww", - "qiubite-name", - "jansona", - "kuldahar", - "Xywest", - "lscnet", - "codeofjackie", - "utopia1991" - ] - }, - "Learn/JavaScript/Client-side_web_APIs/Drawing_graphics": { - "modified": "2020-11-01T05:54:09.109Z", - "contributors": [ - "MiRinZhang", - "xuquentinyang", - "ChongyouXu", - "chrisdavidmills", - "Roy-Tian", - "YeeMarco", - "kensz66", - "Bayes", - "Ray-Eldath" - ] - }, - "Learn/JavaScript/Client-side_web_APIs/Fetching_data": { - "modified": "2020-07-16T22:32:59.652Z", - "contributors": [ - "Xugen-Ma", - "oceanMIH", - "yinpeng123", - "oubinke", - "Kavelaa", - "lscnet", - "Zheng7426", - "baoliujifeng", - "Mr.ma", - "Lyra007", - "whocare", - "moozhu", - "NotDead-NotPerish", - "xgqfrms-GitHub", - "SphinxKnight" - ] - }, - "Learn/JavaScript/Client-side_web_APIs/Introduction": { - "modified": "2020-07-16T22:32:47.021Z", - "contributors": [ - "luohuayouyi12138", - "yinpeng123", - "chrisdavidmills", - "duduindo", - "gofly1988", - "tlos142857", - "lscnet", - "aimishan", - "DFASD", - "NotDead-NotPerish", - "ShirleyM", - "Ray-Eldath", - "tzigang", - "ander_fang" - ] - }, - "Learn/JavaScript/Client-side_web_APIs/Manipulating_documents": { - "modified": "2020-07-16T22:32:50.052Z", - "contributors": [ - "yinpeng123", - "Kavelaa", - "NotDead-NotPerish", - "NightPoem", - "tzigang" - ] - }, - "Learn/JavaScript/Client-side_web_APIs/Third_party_APIs": { - "modified": "2020-10-06T13:28:36.616Z", - "contributors": [ - "AdjWang", - "notthstar", - "grape", - "yinpeng123", - "aopstudio", - "agoreal", - "HashiKudo", - "tomcat1234", - "ddr901", - "Mal_akh", - "goodstudy", - "yuyx91" - ] - }, - "Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs": { - "modified": "2020-07-16T22:32:53.172Z", - "contributors": [ - "wenshui2008", - "wangfangping", - "yinpeng123", - "kuldahar", - "FE_pangxing", - "peanutguo", - "CaoBingX" - ] - }, - "Learn/JavaScript/First_steps": { - "modified": "2020-07-16T22:29:56.585Z", - "contributors": [ - "mianlang", - "14Mars", - "AlexRen94", - "WilsonQu", - "xlongwang", - "zsxeee", - "Hysian", - "ArcherGrey", - "ZayneLiu", - "GHLgh", - "Roy1993sun", - "chrisdavidmills" - ] - }, - "Learn/JavaScript/First_steps/A_first_splash": { - "modified": "2020-07-16T22:30:22.339Z", - "contributors": [ - "Roy-Tian", - "Hermedius", - "PYGC", - "chrisdavidmills", - "quziyang", - "codeofjackie", - "lihaoyuan", - "xp44mm", - "yzweb2018", - "Ray-Eldath", - "leezw", - "iyang", - "hexianzhi", - "CyanChoi", - "sailorandy", - "Zhsirting", - "ander_fang", - "3544357727", - "Ende93", - "ziyunfei", - "Roy1993sun", - "ZhongyiChen" - ] - }, - "Learn/JavaScript/First_steps/Arrays": { - "modified": "2020-07-16T22:30:58.633Z", - "contributors": [ - "PYGC", - "42", - "rxliuli", - "codeofjackie", - "caifx", - "Enigma1912", - "lihaoyuan", - "yzweb2018", - "ddtyjmyjm", - "DaduCC", - "zjj1392372716", - "Hysian", - "wanqing19954" - ] - }, - "Learn/JavaScript/First_steps/Math": { - "modified": "2020-08-21T06:41:19.659Z", - "contributors": [ - "Alibuibui", - "ihua", - "DreamLxq", - "o0oke", - "zhuy2018", - "Hermedius", - "SphinxKnight", - "dx12", - "AlephAlpha", - "FantasqueX", - "PYGC", - "Daazzer", - "Drizzt-Yu", - "xt1995726", - "Metaloe", - "scsc4212", - "codeofjackie", - "Mmmmjnh", - "lihaoyuan", - "superkuang", - "yzweb2018", - "shinexyt", - "purefree", - "xuring", - "wubinbin0403", - "DaduCC", - "ideal.Li", - "liutao1992", - "Hysian", - "jwhitlock", - "wanqing19954", - "Junting", - "lilidongdong", - "Dragoncod" - ] - }, - "Learn/JavaScript/First_steps/Silly_story_generator": { - "modified": "2020-11-10T00:42:34.537Z", - "contributors": [ - "wj.", - "Mrbunker", - "lucida959595", - "Roy-Tian", - "fengxiakira", - "oceanMIH", - "lijinze7", - "chrisdavidmills", - "LittleMang", - "scsc4212", - "ddtyjmyjm", - "codeofjackie", - "Enigma1912", - "yzweb2018", - "shinexyt", - "ideal.Li", - "Zeng", - "FatCatRe" - ] - }, - "Learn/JavaScript/First_steps/Strings": { - "modified": "2020-07-16T22:30:42.559Z", - "contributors": [ - "exialin", - "PYGC", - "NiceGG", - "scsc4212", - "codeofjackie", - "Undecyce", - "yzweb2018", - "shinexyt", - "liutao1992", - "myrual", - "scofieldwen" - ] - }, - "Learn/JavaScript/First_steps/Test_your_skills:_variables": { - "modified": "2020-08-21T01:22:58.795Z", - "contributors": [ - "Alibuibui" - ] - }, - "Learn/JavaScript/First_steps/Useful_string_methods": { - "modified": "2020-07-16T22:30:50.643Z", - "contributors": [ - "PYGC", - "fengxiakira", - "felixfb0916", - "gen_wang", - "scsc4212", - "Undecyce", - "frankfang1990", - "shinexyt", - "ddtyjmyjm", - "TSaxj", - "DaduCC", - "INFINITSY", - "Hysian", - "wanqing19954", - "alphabet007", - "kemplaw", - "fangkai0802014232", - "icessun" - ] - }, - "Learn/JavaScript/First_steps/Variables": { - "modified": "2020-08-21T01:38:52.927Z", - "contributors": [ - "Alibuibui", - "mojiangyuan", - "urielvan", - "DreamLxq", - "Llf0703", - "FantasqueX", - "PYGC", - "Suber", - "HowieZhao", - "Metaloe", - "codeofjackie", - "Sasasu", - "xp44mm", - "yzweb2018", - "shinexyt", - "Hysian", - "ziyunfei", - "BadTudou", - "wanqing19954", - "leezw", - "Lawson.Yuan" - ] - }, - "Learn/JavaScript/First_steps/What_is_JavaScript": { - "modified": "2020-08-20T10:38:00.271Z", - "contributors": [ - "Alibuibui", - "Roy-Tian", - "exialin", - "junbin123", - "blateyang", - "HuangXin", - "Daazzer", - "Hermedius", - "guangyu890", - "no1xsyzy", - "agnoCJY", - "HowieZhao", - "web-xx", - "atmanic", - "Enigma1912", - "Zzt-G", - "huangzijian888", - "codeofjackie", - "canon", - "Anonymous", - "GreyWalker", - "hexianzhi", - "nianxiaoge", - "ithinktherforeiam", - "cruiserdou", - "GHLgh", - "eforegist" - ] - }, - "Learn/JavaScript/First_steps/What_went_wrong": { - "modified": "2020-08-20T10:28:54.393Z", - "contributors": [ - "Alibuibui", - "Roy-Tian", - "ChongyouXu", - "Ash1One", - "guikuan", - "oceanMIH", - "jwhitlock", - "HowieZhao", - "Esther-Guo", - "qiubite-name", - "Park-ma", - "scsc4212", - "codeofjackie", - "Harry-Zhao", - "yzweb2018", - "ddtyjmyjm", - "Ray-Eldath", - "jswisher", - "leezw", - "Bigbigbig", - "dudusky", - "Zhsirting", - "billdeng", - "quanjingkuan" - ] - }, - "Learn/JavaScript/Objects": { - "modified": "2020-07-16T22:31:54.525Z", - "contributors": [ - "ddcomt", - "oceanMIH", - "RainSlide", - "Drizzt-Yu", - "lihaoyuan", - "xgqfrms-GitHub", - "WavinFlag", - "chrisdavidmills" - ] - }, - "Learn/JavaScript/Objects/Basics": { - "modified": "2020-07-16T22:32:02.942Z", - "contributors": [ - "zos12", - "wujingquan", - "minguoITnan", - "Wantian", - "pompeybrain", - "supermanbin" - ] - }, - "Learn/JavaScript/Objects/Inheritance": { - "modified": "2020-07-30T15:02:15.810Z", - "contributors": [ - "Damoness", - "ZengYu", - "wnor543", - "meteorlxy", - "zxsunrise", - "lihaoyuan", - "Tuoe", - "Ray-Eldath", - "finegao", - "Zeng", - "goat91", - "liq297", - "JX-Master", - "_gebilaowang", - "WavinFlag" - ] - }, - "Learn/JavaScript/Objects/JSON": { - "modified": "2020-10-14T09:11:35.116Z", - "contributors": [ - "TonyKnight13", - "imbant", - "NonClockworkChen", - "792521221", - "ZJ_Ma", - "NotDead-NotPerish", - "bluekeroro", - "Ray-Eldath", - "shifengchen", - "1013940326", - "xgqfrms-GitHub", - "VtanSen" - ] - }, - "Learn/JavaScript/Objects/Object-oriented_JS": { - "modified": "2020-11-05T13:41:11.779Z", - "contributors": [ - "ceociocto", - "Jepson", - "ChongyouXu", - "九千鸦", - "Catherine-G", - "voidxiaobei", - "oceanMIH", - "WindLo", - "real-Row", - "GKilyar", - "Ray-Eldath", - "HYdragon", - "GloryChou", - "1013940326", - "Viki-Zhang", - "Leivy", - "breakair", - "zhangyangcisco", - "cylmemory", - "keyulin" - ] - }, - "Learn/JavaScript/Objects/Object_building_practice": { - "modified": "2020-07-16T22:32:33.084Z", - "contributors": [ - "Roy-Tian", - "gqbre", - "qiubite-name", - "Gotheir", - "yuyisuo", - "NotDead-NotPerish", - "SummerVibes", - "shifengchen", - "Zeng" - ] - }, - "Learn/JavaScript/Objects/Object_prototypes": { - "modified": "2020-07-16T22:32:22.751Z", - "contributors": [ - "CJohnny", - "scsc4212", - "SphinxKnight", - "Lukef", - "LuoYun", - "SeanShen3", - "brandonhyc", - "shawzt", - "ddtyjmyjm", - "Soarse", - "zhuangyin", - "JX-Master", - "WavinFlag" - ] - }, - "Learn/JavaScript/Objects/向“弹跳球”演示程序添加新功能": { - "modified": "2020-07-16T22:32:36.563Z", - "contributors": [ - "Wenke-D", - "Roy-Tian", - "gofly1988", - "lihaoyuan", - "bluekeroro" - ] - }, - "Learn/JavaScript/Objects/测试你的技能:面向对象的Javascript": { - "modified": "2020-08-05T11:02:17.810Z", - "contributors": [ - "driftingdream" - ] - }, - "Learn/Performance/CSS": { - "modified": "2020-07-16T22:40:41.520Z", - "contributors": [ - "Hermedius", - "chrisdavidmills", - "tomcat1234", - "Syaki" - ] - }, - "Learn/Tools_and_testing": { - "modified": "2020-07-16T22:38:58.399Z", - "contributors": [ - "xixilog", - "shinexyt", - "chrisdavidmills" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks": { - "modified": "2020-09-20T12:35:57.554Z", - "contributors": [ - "mryongzhang", - "suvyme", - "Self-Discipline-Hx", - "Lyon2018", - "ExceptionBoom", - "chrisdavidmills" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features": { - "modified": "2020-11-11T00:05:15.631Z", - "contributors": [ - "cheukle3" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components": { - "modified": "2020-08-18T22:55:31.199Z", - "contributors": [ - "BIGHAVE-maker" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started": { - "modified": "2020-11-24T09:22:12.001Z", - "contributors": [ - "liyihang", - "lima2020-root", - "liguorain", - "MachaCroissant", - "HowieZhao", - "heq1254", - "silence-BH", - "iigmir", - "SphinxKnight", - "huangcan", - "syj300" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component": { - "modified": "2020-12-04T03:44:08.883Z", - "contributors": [ - "wang_liang" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started": { - "modified": "2020-12-04T03:41:44.591Z", - "contributors": [ - "wang_liang", - "zisedelinghun", - "ZhangNing", - "MRzhangzhenhua", - "929721152", - "xyjk0917" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models": { - "modified": "2020-09-22T07:48:03.161Z", - "contributors": [ - "helldealer" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists": { - "modified": "2020-09-22T04:42:41.746Z", - "contributors": [ - "helldealer" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources": { - "modified": "2020-12-01T12:40:05.687Z", - "contributors": [ - "zisedelinghun", - "Hzbmangguo" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling": { - "modified": "2020-10-15T23:41:44.939Z", - "contributors": [ - "ygxwdls" - ] - }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/介绍": { - "modified": "2020-11-19T04:46:02.957Z", - "contributors": [ - "514059172", - "You2er", - "risejl" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing": { - "modified": "2020-07-16T22:39:02.261Z", - "contributors": [ - "LuckyWind_sck", - "wbamberg", - "ziyunfei", - "yuyx91", - "Ende93", - "123456zzz" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/Automated_testing": { - "modified": "2020-07-16T22:39:19.579Z", - "contributors": [ - "wbamberg", - "yonghuizeng", - "ziyunfei", - "liminjun" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/Feature_detection": { - "modified": "2020-07-16T22:39:24.365Z", - "contributors": [ - "shangruitong" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS": { - "modified": "2020-07-16T22:39:12.242Z", - "contributors": [ - "RainSlide", - "fisker", - "ziyunfei", - "yihongxian", - "liminjun" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/Introduction": { - "modified": "2020-07-16T22:39:05.735Z", - "contributors": [ - "FanRui12138", - "gofly1988", - "Badd", - "chrisdavidmills", - "joaner" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/JavaScript": { - "modified": "2020-07-16T22:39:15.168Z", - "contributors": [ - "ty4z2008" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment": { - "modified": "2020-07-16T22:39:21.968Z", - "contributors": [ - "yonghuizeng", - "ziyunfei", - "liminjun" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/可访问性": { - "modified": "2020-07-16T22:39:17.935Z", - "contributors": [ - "freejack811", - "Sc0tt" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/测试策略": { - "modified": "2020-07-16T22:39:08.099Z", - "contributors": [ - "wangfangping", - "YaoLIII", - "ty4z2008" - ] - }, - "Learn/Tools_and_testing/GitHub": { - "modified": "2020-08-17T07:24:09.907Z", - "contributors": [ - "blingblingredstar", - "chrisdavidmills", - "JamesUmmex" - ] - }, - "Learn/Tools_and_testing/Understanding_client-side_tools": { - "modified": "2020-08-17T11:33:08.897Z", - "contributors": [ - "NicholasZhan" - ] - }, - "Learn/Tools_and_testing/Understanding_client-side_tools/Command_line": { - "modified": "2020-11-30T05:22:05.657Z", - "contributors": [ - "YLX621" - ] - }, - "Learn/Tools_and_testing/Understanding_client-side_tools/Overview": { - "modified": "2020-11-28T10:37:11.293Z", - "contributors": [ - "YLX621" - ] - }, - "Learn/tutorial": { - "modified": "2020-07-16T22:33:40.955Z", - "contributors": [ - "Andrew_Pfeiffer" - ] - }, - "Learn/tutorial/How_to_build_a_web_site": { - "modified": "2020-07-16T22:33:41.521Z", - "contributors": [ - "LX" - ] - }, - "Localization": { - "modified": "2019-03-23T23:33:42.693Z", - "contributors": [ - "xcffl" - ] - }, - "MDC:怎样进行帮助": { - "modified": "2019-01-16T16:56:07.625Z", - "contributors": [ - "ygtyugh" - ] - }, - "MDN": { - "modified": "2020-02-19T17:55:29.065Z", - "contributors": [ - "jswisher", - "SphinxKnight", - "daydayxing", - "wbamberg", - "Forbidden", - "LiHua", - "ga20", - "maksyuki", - "Jeremie", - "ziyunfei", - "ericyang89", - "lunix01", - "tinyork", - "OlingCat", - "teoli" - ] - }, - "MDN/About": { - "modified": "2020-07-16T23:11:57.958Z", - "contributors": [ - "brizer", - "SphinxKnight", - "YunYouJun", - "wang1212", - "wbamberg", - "hhxxhg", - "FlyRecker", - "RunningTortoise", - "zihengCat", - "AberSheeran", - "X-hung", - "outloudvi", - "jswisher", - "zccz14", - "Jack-Q", - "Atester", - "AzureRay", - "lunix01" - ] - }, - "MDN/Community": { - "modified": "2020-04-03T05:16:15.416Z", - "contributors": [ - "SphinxKnight", - "shiguang", - "wbamberg", - "Planet6174", - "Forbidden", - "ZQH", - "suwenbin", - "maksyuki", - "Ende93", - "shuding", - "yun174long", - "IBuly", - "civilian", - "MofeLee", - "ziyunfei", - "Fiag" - ] - }, - "MDN/Community/Conversations": { - "modified": "2020-04-08T04:56:55.004Z", - "contributors": [ - "SirnoChan", - "ewfian", - "Chor", - "wbamberg", - "chaosdog", - "jswisher", - "tanyan2004", - "githubzh123" - ] - }, - "MDN/Community/Doc_sprints": { - "modified": "2019-03-18T20:44:27.614Z", - "contributors": [ - "RainSlide", - "wbamberg", - "ElliottZheng", - "varcat" - ] - }, - "MDN/Community/Whats_happening": { - "modified": "2020-07-16T22:45:19.757Z", - "contributors": [ - "brizer", - "wbamberg", - "IannaZhou", - "fanyj1994", - "1986slayer" - ] - }, - "MDN/Community/在社区工作": { - "modified": "2020-02-19T18:49:08.850Z", - "contributors": [ - "jswisher", - "wbamberg", - "huangzijian888" - ] - }, - "MDN/Community/角色": { - "modified": "2019-01-17T01:19:59.255Z", - "contributors": [ - "wbamberg", - "zhangchen", - "landy2014" - ] - }, - "MDN/Contribute": { - "modified": "2019-03-04T23:39:43.858Z", - "contributors": [ - "wbamberg", - "Terry.Qiao", - "xhlsrj", - "xgqfrms-GitHub", - "maksyuki", - "Ende93", - "Moressette", - "Feihei", - "yfdyh000", - "OlingCat", - "nyan", - "pixiu", - "FredWe", - "Yaty", - "act262", - "ziyunfei", - "Kaworu", - "Sheppy" - ] - }, - "MDN/Contribute/Feedback": { - "modified": "2020-09-30T17:53:31.395Z", - "contributors": [ - "chrisdavidmills", - "SphinxKnight", - "gogoend", - "z-xw", - "wbamberg", - "15010300689", - "AnthonyYY", - "pftom", - "yfdyh000", - "iamzken", - "lunix01" - ] - }, - "MDN/Contribute/Getting_started": { - "modified": "2020-09-30T17:17:11.190Z", - "contributors": [ - "chrisdavidmills", - "brizer", - "RainSlide", - "秋色楓", - "心斩心鬼", - "4325612", - "shiguang", - "assasai", - "cosformula", - "Azurak", - "wbamberg", - "kite-js", - "garyhe0780", - "liangjia", - "boltyu", - "Gszekt", - "yzweb2018", - "BearZ", - "zs808", - "woshichenyaofei", - "xiyifenheart", - "maksyuki", - "zsusyt", - "Jeery", - "Feihei", - "followgiant", - "civilian", - "yenshen", - "Sbabey", - "ziyunfei", - "Simpozigh" - ] - }, - "MDN/Contribute/Howto": { - "modified": "2020-10-15T15:37:40.278Z", - "contributors": [ - "我不会算命", - "wbamberg", - "maksyuki", - "ziyunfei", - "Sheppy" - ] - }, - "MDN/Contribute/Howto/Convert_code_samples_to_be_live": { - "modified": "2019-01-16T22:27:28.581Z", - "contributors": [ - "wbamberg", - "xhlsrj" - ] - }, - "MDN/Contribute/Howto/Create_an_MDN_account": { - "modified": "2020-08-03T02:14:19.507Z", - "contributors": [ - "zonghuaj", - "jackleeholmes", - "dwns545", - "kgbook", - "roboterwise", - "wbamberg", - "Disat", - "Zhsirting", - "jiajinning", - "BoothLuo", - "WavinFlag", - "acgpiano", - "1xxxx", - "wth", - "ziyunfei", - "fanziy75" - ] - }, - "MDN/Contribute/Howto/Create_and_edit_pages": { - "modified": "2020-08-13T06:15:42.058Z", - "contributors": [ - "ccg940521", - "driftingdream", - "jackleeholmes", - "dwns545", - "GaGaTang", - "TODAY", - "qiudongwei", - "flt1132060804", - "wbt", - "sunrong1990", - "Evangelist", - "junjie", - "daluobohao", - "MrM4", - "shilei.fun", - "wbamberg", - "shinyano", - "9240", - "blacklin", - "yinxiupei", - "augfn", - "yinzhiyizhi", - "Chrome.Ro", - "twikor", - "MAYDAY1993", - "xiaoyuan", - "Schr0dinger", - "runyul", - "Ykw", - "LemonGirl", - "feitill", - "swpuLeo", - "qson", - "akd3b", - "nickzone", - "maksyuki", - "ziyunfei", - "sweetliu" - ] - }, - "MDN/Contribute/Howto/Do_a_technical_review": { - "modified": "2020-06-06T00:56:15.988Z", - "contributors": [ - "ice-kylin", - "wbamberg", - "Mr.ma", - "zt19994", - "jianxin-zhang", - "righttoe", - "The-End-Hero", - "pidanhua", - "Roland_Reed", - "majunbao", - "pixiu" - ] - }, - "MDN/Contribute/Howto/Do_an_editorial_review": { - "modified": "2020-02-24T12:04:57.900Z", - "contributors": [ - "zhanglolo", - "IFVFORNONE", - "SphinxKnight", - "YUYUEy", - "chrislung", - "Azurak", - "wbamberg", - "quainter", - "Katherina-Miao", - "ucev", - "liujinyu", - "faremax", - "nanflower", - "YFM-getA", - "LiuTong", - "Martin.Chow", - "MMOnster", - "lunix01" - ] - }, - "MDN/Contribute/Howto/Set_the_summary_for_a_page": { - "modified": "2019-10-29T05:37:01.880Z", - "contributors": [ - "7NZ", - "Socheny", - "zhangdonglei", - "wbamberg", - "WeJie", - "Schr0dinger", - "itao1314", - "52yang", - "ivanberry", - "ziyunfei", - "Inceng", - "salmon8881", - "zzhi", - "Minnie", - "Yanzhu.Yin" - ] - }, - "MDN/Contribute/Howto/Tag": { - "modified": "2020-04-29T12:58:13.297Z", - "contributors": [ - "targeton", - "wbamberg", - "yuyx91", - "zsusyt", - "zhangqiong", - "ziyunfei", - "ganshenhai" - ] - }, - "MDN/Contribute/Howto/Tag_JavaScript_pages": { - "modified": "2019-01-16T21:47:16.976Z", - "contributors": [ - "wbamberg", - "Gale", - "BiGrEgGaErOoTs", - "joke", - "Ahkari", - "ziyunfei", - "lushunming" - ] - }, - "MDN/Contribute/Howto/Write_a_new_entry_in_the_Glossary": { - "modified": "2019-03-18T21:16:25.185Z", - "contributors": [ - "wbamberg", - "micblo" - ] - }, - "MDN/Contribute/Howto/Write_an_API_reference": { - "modified": "2019-03-18T20:48:40.005Z", - "contributors": [ - "Sheppy" - ] - }, - "MDN/Contribute/Howto/Write_an_API_reference/Information_contained_in_a_WebIDL_file": { - "modified": "2019-03-18T20:48:39.486Z", - "contributors": [ - "Syclover-u2400" - ] - }, - "MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web": { - "modified": "2020-09-06T02:30:17.183Z", - "contributors": [ - "Cheese-Chip", - "SuiltaPico", - "gu_qing", - "Azurak", - "wbamberg", - "liminjun" - ] - }, - "MDN/Contribute/Howto/Write_for_SEO": { - "modified": "2019-01-17T03:12:28.083Z", - "contributors": [ - "wbamberg", - "MartinJLiu" - ] - }, - "MDN/Contribute/Howto/如何添加或更新浏览器兼容性数据": { - "modified": "2019-03-18T21:38:16.029Z", - "contributors": [ - "wbamberg", - "kite-js" - ] - }, - "MDN/Contribute/Howto/学习_交互_在线_起步_开始": { - "modified": "2019-03-18T21:43:40.910Z", - "contributors": [ - "wbamberg", - "ZweiZhao" - ] - }, - "MDN/Contribute/Howto/成为一名测试版试验员": { - "modified": "2019-03-23T22:10:34.334Z", - "contributors": [ - "fengchunsgit", - "wbamberg", - "fbambi", - "sunnysabor" - ] - }, - "MDN/Contribute/Localize": { - "modified": "2019-03-23T23:19:30.236Z", - "contributors": [ - "Azurak", - "wbamberg", - "Terry.Qiao", - "maksyuki", - "Greenstorm", - "act262", - "ziyunfei", - "Sheppy" - ] - }, - "MDN/Contribute/Localize/Localization_projects": { - "modified": "2020-10-21T05:39:58.512Z", - "contributors": [ - "SDUTWSL", - "lastVigo", - "greatofdream", - "plusmultiply0", - "cheiron", - "Mookiepiece", - "kagurakana", - "Adrian-Yan", - "SirnoChan", - "Tindoc", - "guow10", - "CharCat", - "Lsnsh", - "mynull", - "Roronoa_Zoro", - "celdr", - "Chor", - "Louis-7", - "wbamberg", - "codeofjackie", - "zsxeee", - "Lyra007", - "pluwen", - "xjr7670", - "lulurun95", - "Terry.Qiao", - "runyul", - "johncido", - "ArcherGrey", - "Jiang-Xuan", - "binggg", - "distums", - "MarxJiao", - "ziyunfei", - "Ende93", - "kangmingxuan", - "Serifx", - "pantao", - "lttxzmj", - "lukywong", - "FredWe", - "Jacksunwei", - "kun.yan", - "charlie", - "qianjiahao", - "licop", - "nyx2014", - "Dolphin_Wood", - "Gaohaoyang", - "Light1980", - "xunmorl", - "fskuok", - "psychebb", - "saintwinkle", - "NIGHTEAGLE", - "jasonworg", - "Jone_Casper", - "ccforward", - "iakuf", - "Breezewish", - "OlingCat", - "VinceZhao", - "shenhao", - "iwo", - "wanglingzhi" - ] - }, - "MDN/Contribute/Localize/RSS_feeds": { - "modified": "2019-01-16T18:56:37.845Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "MDN/Contribute/Localize/Starting_a_localization": { - "modified": "2020-10-06T20:22:38.663Z", - "contributors": [ - "kuailekai", - "wbamberg", - "FredWe" - ] - }, - "MDN/Contribute/Localize/Translating_pages": { - "modified": "2020-02-06T00:53:16.879Z", - "contributors": [ - "BeatBoxerLrd", - "fengchao", - "all2cn", - "Azurak", - "wbamberg", - "Zhong", - "pluwen", - "alicechengsong", - "IannaZhou", - "zsxeee", - "liminjun", - "gqqnbig", - "leeziwong", - "Ende93", - "a9202", - "savannah", - "OlingCat", - "fanziy75", - "ziyunfei", - "ReyCG", - "guoyunhebrave" - ] - }, - "MDN/Editor": { - "modified": "2020-09-30T15:44:25.503Z", - "contributors": [ - "chrisdavidmills", - "thouen", - "woniuxingdong", - "TeabugCC", - "yuan81777", - "zhangqiangoffice", - "xjr7670", - "Y.Young", - "ChuckZhang", - "mona", - "jiahui", - "Roland_Reed", - "JoshuaLee", - "GeoffreyQ", - "sunxiang", - "OlingCat", - "Meteormatt" - ] - }, - "MDN/Editor/Basics": { - "modified": "2020-09-30T15:44:25.432Z", - "contributors": [ - "chrisdavidmills", - "zhangqiangoffice", - "Jeane", - "yy1107", - "world521", - "q1560760" - ] - }, - "MDN/Editor/Basics/Page_controls": { - "modified": "2020-09-30T15:44:25.715Z", - "contributors": [ - "chrisdavidmills", - "zhangqiangoffice" - ] - }, - "MDN/Editor/Basics/Page_info": { - "modified": "2020-09-30T15:44:25.570Z", - "contributors": [ - "chrisdavidmills", - "zhangqiangoffice" - ] - }, - "MDN/Editor/Edit_box": { - "modified": "2020-09-30T15:44:25.913Z", - "contributors": [ - "chrisdavidmills", - "RainSlide", - "yuan81777", - "zhangqiangoffice" - ] - }, - "MDN/Editor/Source_mode": { - "modified": "2020-09-30T15:44:26.291Z", - "contributors": [ - "chrisdavidmills", - "SirnoChan", - "yinsang", - "woniuxingdong", - "zhangqiangoffice" - ] - }, - "MDN/Guidelines": { - "modified": "2020-09-30T15:32:46.472Z", - "contributors": [ - "chrisdavidmills", - "wbamberg", - "maksyuki", - "saka6333", - "pixiu", - "OlingCat", - "Sheppy" - ] - }, - "MDN/Guidelines/CSS_style_guide": { - "modified": "2020-09-30T15:32:47.524Z", - "contributors": [ - "chrisdavidmills", - "shc0743" - ] - }, - "MDN/Guidelines/Content_blocks": { - "modified": "2020-09-30T15:32:46.742Z", - "contributors": [ - "chrisdavidmills", - "wbamberg", - "OlingCat" - ] - }, - "MDN/Guidelines/Rules_Of_MDN_Documenting": { - "modified": "2020-09-30T15:32:46.957Z", - "contributors": [ - "chrisdavidmills", - "wbamberg", - "zccz14" - ] - }, - "MDN/Guidelines/Style_guide": { - "modified": "2020-11-14T07:38:19.734Z", - "contributors": [ - "kuailekai", - "chrisdavidmills", - "jswisher", - "wbamberg", - "codeofjackie", - "Dousy", - "Terry.Qiao", - "jianxin-zhang", - "DennisWang", - "suncn", - "WynnChen", - "zmh_w", - "OlingCat" - ] - }, - "MDN/Kuma": { - "modified": "2019-09-09T15:54:47.389Z", - "contributors": [ - "SphinxKnight", - "RainSlide", - "yuan81777", - "Chor", - "wbamberg", - "myshell1983", - "popcorner", - "Jack-Q", - "xgqfrms" - ] - }, - "MDN/MDN_Product_Advisory_Board": { - "modified": "2019-01-17T01:56:35.044Z", - "contributors": [ - "wbamberg", - "pluwen", - "liminjun" - ] - }, - "MDN/MDN_Product_Advisory_Board/Members": { - "modified": "2019-01-17T01:57:07.618Z", - "contributors": [ - "wbamberg", - "liminjun" - ] - }, - "MDN/MDN_Product_Advisory_Board/Membership": { - "modified": "2019-01-17T01:56:55.424Z", - "contributors": [ - "wbamberg", - "liminjun" - ] - }, - "MDN/Structures": { - "modified": "2020-09-30T12:57:46.743Z", - "contributors": [ - "chrisdavidmills", - "shiguang", - "wbamberg", - "ArcherGrey", - "maksyuki", - "wth", - "jswisher" - ] - }, - "MDN/Structures/Compatibility_tables": { - "modified": "2020-10-15T21:37:24.190Z", - "contributors": [ - "chrisdavidmills", - "PYGC", - "ridiculousjam", - "RainSlide", - "wbamberg", - "fs523577192", - "zyq", - "AozakiOrenji", - "K.Pen", - "StorytellerF", - "popcorner", - "jswisher", - "aimiy", - "teoli", - "pixiu" - ] - }, - "MDN/Structures/Live_samples": { - "modified": "2020-09-30T12:57:48.040Z", - "contributors": [ - "chrisdavidmills", - "wbamberg", - "mhy", - "jiahui" - ] - }, - "MDN/Structures/Live_samples/Simple_live_sample_demo": { - "modified": "2020-09-30T12:57:47.049Z", - "contributors": [ - "chrisdavidmills", - "wbamberg", - "Howard.Chen" - ] - }, - "MDN/Structures/Macros": { - "modified": "2020-09-30T12:57:46.893Z", - "contributors": [ - "chrisdavidmills", - "PYGC", - "wangfangping", - "wbamberg", - "ufoqhmdt", - "Ende93", - "jswisher" - ] - }, - "MDN/Structures/Macros/Custom_macros": { - "modified": "2020-10-06T09:20:15.609Z", - "contributors": [ - "phone-burner", - "chrisdavidmills", - "wbamberg", - "teoli", - "fscholz", - "xhlsrj", - "FredWe" - ] - }, - "MDN_at_ten": { - "modified": "2019-03-23T22:50:02.795Z", - "contributors": [ - "FlyingPig", - "cughudson_1", - "WarriorWu" - ] - }, - "Mozilla": { - "modified": "2020-06-07T07:01:06.707Z", - "contributors": [ - "ice-kylin", - "iigmir", - "Yannis", - "ziyunfei", - "ethertank" - ] - }, - "Mozilla/Add-ons": { - "modified": "2019-03-18T21:08:44.382Z", - "contributors": [ - "liweiwp", - "xcffl", - "slanterns", - "lixuanh", - "Dhakkan", - "BlackGlory", - "yy1107", - "Daniel.Ma", - "ppppfly", - "CzBiX", - "GrayLight", - "deathswaltz", - "muzhen", - "Ende93", - "jsx", - "hstd998.com", - "lil9lll", - "vainl", - "alicli", - "hanna1949", - "sheguibo", - "hefangck", - "nihao", - "av990022", - "Yaty", - "Cat", - "colin-zhou", - "ziyunfei", - "ywzhaiqi", - "evolighting", - "yaya", - "YangHanlin", - "hendyzone" - ] - }, - "Mozilla/Add-ons/WebExtensions": { - "modified": "2019-07-23T03:16:13.702Z", - "contributors": [ - "still4ever", - "Gszekt", - "liweiwp", - "xcffl", - "yfdyh000", - "jinnchen", - "Olimpic2008", - "popcorner", - "GrayLight", - "zengxs", - "Mosan" - ] - }, - "Mozilla/Add-ons/WebExtensions/API": { - "modified": "2019-11-26T22:19:08.716Z", - "contributors": [ - "wbamberg", - "SphinxKnight", - "liuxiaobin", - "yfdyh000", - "abcqdsdchina", - "popcorner" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/alarms": { - "modified": "2020-10-15T21:50:01.418Z", - "contributors": [ - "wbamberg", - "abcqdsdchina", - "popcorner" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/alarms/create": { - "modified": "2020-10-15T21:52:39.539Z", - "contributors": [ - "wbamberg", - "trto1987" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/bookmarks": { - "modified": "2020-10-15T21:43:03.354Z", - "contributors": [ - "kanaza", - "wbamberg", - "popcorner", - "looch5" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/bookmarks/BookmarkTreeNode": { - "modified": "2020-10-15T21:43:03.034Z", - "contributors": [ - "wbamberg", - "popcorner", - "looch5" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/bookmarks/getTree": { - "modified": "2020-10-15T21:52:39.873Z", - "contributors": [ - "wbamberg", - "trto1987" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/bookmarks/remove": { - "modified": "2020-10-15T21:52:39.643Z", - "contributors": [ - "kanaza", - "wbamberg", - "wangtonghe" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/browserAction": { - "modified": "2020-10-15T21:52:25.826Z", - "contributors": [ - "wbamberg", - "yangwang", - "yfdyh000" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/captivePortal": { - "modified": "2020-10-15T22:25:37.934Z", - "contributors": [ - "rebloor" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/captivePortal/onStateChanged": { - "modified": "2020-10-15T22:25:37.985Z", - "contributors": [ - "iQianDuoEr" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/contentScripts": { - "modified": "2020-10-15T22:26:29.107Z", - "contributors": [ - "RainSlide" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/contextMenus": { - "modified": "2020-10-15T21:54:13.449Z", - "contributors": [ - "miracleXL", - "yangwang", - "xgqfrms-GitHub" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/cookies": { - "modified": "2020-10-15T21:52:04.120Z", - "contributors": [ - "miracleXL", - "wbamberg", - "GameXG", - "maicss" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/cookies/Cookie": { - "modified": "2020-10-15T22:33:57.478Z", - "contributors": [ - "JamesUmmex" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow": { - "modified": "2020-10-15T22:13:56.821Z", - "contributors": [ - "wbamberg", - "ClassJm" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/downloads": { - "modified": "2020-10-15T22:24:32.261Z", - "contributors": [ - "miracleXL", - "zombie110year" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/downloads/DownloadItem": { - "modified": "2020-10-15T22:25:57.415Z", - "contributors": [ - "zombie110year" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/downloads/download": { - "modified": "2020-10-15T22:24:27.098Z", - "contributors": [ - "miracleXL", - "yndj" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/find": { - "modified": "2020-10-15T22:31:34.580Z", - "contributors": [ - "duduindo", - "zhangdongxu99" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/history": { - "modified": "2020-10-15T21:56:26.866Z", - "contributors": [ - "wbamberg", - "Jessy.D." - ] - }, - "Mozilla/Add-ons/WebExtensions/API/history/onTitleChanged": { - "modified": "2020-10-15T21:56:28.485Z", - "contributors": [ - "wbamberg", - "superchow" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/i18n": { - "modified": "2020-11-19T06:00:40.404Z", - "contributors": [ - "zxy7" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/idle": { - "modified": "2020-10-15T22:22:28.994Z", - "contributors": [ - "xgqfrms" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/permissions": { - "modified": "2020-10-21T23:48:45.581Z", - "contributors": [ - "erezsh" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/permissions/contains": { - "modified": "2020-10-21T23:48:46.770Z", - "contributors": [ - "xgqfrms" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/proxy": { - "modified": "2020-10-15T22:29:18.913Z", - "contributors": [ - "YueHui", - "chen43" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime": { - "modified": "2020-10-15T21:51:03.117Z", - "contributors": [ - "Landius", - "wbamberg", - "gogogoghost", - "WEKEYSHIT" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/PlatformArch": { - "modified": "2020-10-15T21:51:03.273Z", - "contributors": [ - "wbamberg", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/PlatformOs": { - "modified": "2020-10-15T21:51:03.025Z", - "contributors": [ - "wbamberg", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/connectNative": { - "modified": "2020-10-15T21:51:00.178Z", - "contributors": [ - "wbamberg", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/getManifest": { - "modified": "2020-10-15T21:51:03.052Z", - "contributors": [ - "wbamberg", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/onConnect": { - "modified": "2020-10-15T21:59:03.906Z", - "contributors": [ - "wbamberg", - "lzfxp" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/onMessage": { - "modified": "2020-10-15T22:25:54.860Z", - "contributors": [ - "zombie110year" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/openOptionsPage": { - "modified": "2020-10-15T21:52:23.869Z", - "contributors": [ - "wbamberg", - "wangtonghe" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage": { - "modified": "2020-10-15T21:55:54.734Z", - "contributors": [ - "wbamberg", - "pea3nut" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/runtime/sendNativeMessage": { - "modified": "2020-10-15T21:53:53.955Z", - "contributors": [ - "wbamberg", - "WEKEYSHIT" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/search": { - "modified": "2020-10-15T22:31:21.665Z", - "contributors": [ - "kernp" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/search/search": { - "modified": "2020-10-15T22:31:18.403Z", - "contributors": [ - "yueli" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/sessions": { - "modified": "2020-10-15T22:30:35.721Z" - }, - "Mozilla/Add-ons/WebExtensions/API/sessions/Session": { - "modified": "2020-10-15T22:30:49.537Z", - "contributors": [ - "duduindo", - "sukura9527" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/storage": { - "modified": "2020-10-15T21:52:42.727Z", - "contributors": [ - "miracleXL", - "wbamberg", - "wangtonghe" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs": { - "modified": "2020-10-15T21:51:29.788Z", - "contributors": [ - "wbamberg", - "ivysrono", - "Hypophrenia" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs/Tab": { - "modified": "2020-10-15T22:00:50.838Z", - "contributors": [ - "yuyx91" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs/create": { - "modified": "2020-10-15T22:00:41.838Z", - "contributors": [ - "yuyx91" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs/discard": { - "modified": "2020-10-15T22:05:48.592Z", - "contributors": [ - "RainSlide" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs/executeScript": { - "modified": "2020-10-15T22:12:43.287Z", - "contributors": [ - "wbamberg", - "xgqfrms" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs/insertCSS": { - "modified": "2020-10-15T21:51:31.605Z", - "contributors": [ - "wbamberg", - "xfyanmeng", - "Hypophrenia" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs/onActivated": { - "modified": "2020-10-15T21:59:49.657Z", - "contributors": [ - "wbamberg", - "thundernet8" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs/sendMessage": { - "modified": "2020-10-15T22:12:29.653Z", - "contributors": [ - "wbamberg", - "zsgwsjj" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/tabs/查询": { - "modified": "2020-11-25T05:15:24.039Z", - "contributors": [ - "qzwvinner" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/types": { - "modified": "2020-07-06T02:37:08.205Z" - }, - "Mozilla/Add-ons/WebExtensions/API/types/BrowserSetting": { - "modified": "2020-10-15T22:31:21.913Z", - "contributors": [ - "asam49862" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/types/BrowserSetting/set": { - "modified": "2020-07-06T02:37:10.081Z", - "contributors": [ - "baige97" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/webNavigation": { - "modified": "2020-10-15T21:53:08.569Z", - "contributors": [ - "wbamberg", - "abbycar" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/webNavigation/onDOMContentLoaded": { - "modified": "2020-10-15T21:53:04.121Z", - "contributors": [ - "wbamberg", - "Tommy-White", - "xgqfrms-GitHub" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/webRequest": { - "modified": "2020-10-15T21:52:27.389Z", - "contributors": [ - "WangYuYe", - "Yumingyuan", - "wbamberg", - "fkyq01", - "h4ck2fun_xiaoshi", - "abbycar" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/webRequest/RequestFilter": { - "modified": "2020-10-15T21:52:23.592Z", - "contributors": [ - "Yumingyuan", - "wbamberg", - "wangtonghe" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/windows": { - "modified": "2020-10-15T21:52:10.540Z", - "contributors": [ - "wbamberg", - "yfdyh000" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/windows/WindowState": { - "modified": "2020-10-15T22:00:37.419Z", - "contributors": [ - "wbamberg", - "Mikasa666" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/windows/WindowType": { - "modified": "2020-10-15T22:22:30.217Z", - "contributors": [ - "dongpohezui" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/windows/create": { - "modified": "2020-10-15T21:55:10.965Z", - "contributors": [ - "wbamberg", - "Ruwind" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/剪切板": { - "modified": "2020-10-15T22:15:08.385Z", - "contributors": [ - "RainSlide", - "faliye", - "gentop" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData": { - "modified": "2020-10-15T22:15:17.586Z", - "contributors": [ - "RainSlide", - "faliye" - ] - }, - "Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar": { - "modified": "2019-03-18T21:06:43.197Z", - "contributors": [ - "Olimpic2008" - ] - }, - "Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension": { - "modified": "2019-03-18T20:52:49.678Z", - "contributors": [ - "RainSlide", - "penggang1", - "brucelei", - "yuyx91", - "Mikasa666", - "Gszekt", - "yydzxz", - "wangtonghe", - "zhzhch335", - "CXWorks", - "EdgeBoY", - "dhq8", - "onbug" - ] - }, - "Mozilla/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs": { - "modified": "2020-10-15T20:55:08.041Z", - "contributors": [ - "xcffl" - ] - }, - "Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities": { - "modified": "2020-01-07T04:15:59.888Z", - "contributors": [ - "Alan-Liang", - "SphinxKnight", - "solitarily", - "zhangchen", - "xcffl", - "yfdyh000" - ] - }, - "Mozilla/Add-ons/WebExtensions/Content_Security_Policy": { - "modified": "2020-01-05T11:25:23.297Z", - "contributors": [ - "miracleXL", - "juzhiyuan" - ] - }, - "Mozilla/Add-ons/WebExtensions/Content_scripts": { - "modified": "2019-03-18T21:06:16.802Z", - "contributors": [ - "yydzxz", - "Lxio", - "zeromake", - "Hypophrenia" - ] - }, - "Mozilla/Add-ons/WebExtensions/Examples": { - "modified": "2019-05-10T14:32:05.367Z", - "contributors": [ - "JiaZombie", - "Gszekt", - "liweiwp", - "GrayLight" - ] - }, - "Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools": { - "modified": "2020-06-18T02:50:45.530Z", - "contributors": [ - "SphinxKnight", - "codewolf", - "DKooo", - "wyssdbd" - ] - }, - "Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard": { - "modified": "2019-04-03T11:58:33.089Z", - "contributors": [ - "webFunc", - "zombie110year", - "Olimpic2008" - ] - }, - "Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests": { - "modified": "2019-03-18T21:06:48.574Z", - "contributors": [ - "ZowieGong", - "zhangchen", - "GameXG", - "EastStep", - "Olimpic2008", - "onbug" - ] - }, - "Mozilla/Add-ons/WebExtensions/Internationalization": { - "modified": "2019-03-18T21:06:07.653Z", - "contributors": [ - "yfdyh000", - "wlq105556" - ] - }, - "Mozilla/Add-ons/WebExtensions/Match_patterns": { - "modified": "2019-03-18T21:06:13.447Z", - "contributors": [ - "xgqfrms-GitHub", - "ziyunfei", - "Hypophrenia" - ] - }, - "Mozilla/Add-ons/WebExtensions/Modify_a_web_page": { - "modified": "2019-03-18T21:06:39.679Z", - "contributors": [ - "yongm126", - "Gszekt", - "13531", - "Olimpic2008" - ] - }, - "Mozilla/Add-ons/WebExtensions/Native_manifests": { - "modified": "2019-03-18T21:04:37.166Z", - "contributors": [ - "pea3nut" - ] - }, - "Mozilla/Add-ons/WebExtensions/Native_messaging": { - "modified": "2019-03-18T21:04:42.330Z", - "contributors": [ - "pea3nut" - ] - }, - "Mozilla/Add-ons/WebExtensions/Packaging_and_installation": { - "modified": "2019-03-23T22:45:12.350Z", - "contributors": [ - "GrayLight", - "yfdyh000" - ] - }, - "Mozilla/Add-ons/WebExtensions/Porting_from_Google_Chrome": { - "modified": "2019-03-18T21:08:06.832Z", - "contributors": [ - "PaperFlu", - "yfdyh000" - ] - }, - "Mozilla/Add-ons/WebExtensions/Prerequisites": { - "modified": "2019-03-23T22:45:08.369Z", - "contributors": [ - "GrayLight", - "yfdyh000" - ] - }, - "Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension": { - "modified": "2019-03-18T21:06:37.903Z", - "contributors": [ - "abcfyk", - "Smartree", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/Safely_inserting_external_content_into_a_page": { - "modified": "2020-05-01T09:44:07.553Z", - "contributors": [ - "ultiwill" - ] - }, - "Mozilla/Add-ons/WebExtensions/Walkthrough": { - "modified": "2019-09-08T06:17:56.666Z", - "contributors": [ - "Bonlin0", - "ZowieGong", - "LuminousXLB", - "Gszekt", - "boser90", - "yydzxz", - "lightsing", - "CXWorks", - "GrayLight", - "yfdyh000" - ] - }, - "Mozilla/Add-ons/WebExtensions/What_are_WebExtensions": { - "modified": "2020-05-06T06:16:11.132Z", - "contributors": [ - "yxchai", - "RainSlide", - "benniks", - "liweiwp", - "ppphp", - "xgqfrms-GitHub", - "lixuanh", - "popcorner", - "Jiang-Xuan", - "GrayLight", - "beizaibeifang19" - ] - }, - "Mozilla/Add-ons/WebExtensions/What_next_": { - "modified": "2019-05-31T00:24:51.435Z", - "contributors": [ - "joinmouse" - ] - }, - "Mozilla/Add-ons/WebExtensions/Working_with_the_Tabs_API": { - "modified": "2019-10-29T22:53:00.625Z", - "contributors": [ - "7NZ", - "LoserForLoser" - ] - }, - "Mozilla/Add-ons/WebExtensions/Your_first_WebExtension": { - "modified": "2020-05-06T07:03:30.522Z", - "contributors": [ - "yxchai", - "RainSlide", - "xixilog", - "522211qaa", - "werner-wiki", - "zhengkai2001", - "Gszekt", - "yydzxz", - "liweiwp", - "XanderChen", - "xcffl", - "lightsing", - "zengxs", - "GrayLight" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json": { - "modified": "2020-10-15T21:51:01.376Z", - "contributors": [ - "RainSlide", - "xgqfrms-GitHub", - "StevenYuysy", - "wbamberg" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/author": { - "modified": "2020-10-15T21:50:59.783Z", - "contributors": [ - "fscholz", - "1010Tech", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/background": { - "modified": "2020-10-15T21:51:02.308Z", - "contributors": [ - "fscholz", - "heyDolby", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/browser_action": { - "modified": "2020-10-15T21:56:41.386Z", - "contributors": [ - "wbamberg", - "PaperFlu" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings": { - "modified": "2019-03-18T21:06:05.570Z", - "contributors": [ - "ExE-Boss", - "8qwe24657913", - "lixuanh" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts": { - "modified": "2020-10-15T21:52:03.892Z", - "contributors": [ - "fscholz", - "shuangya" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/default_locale": { - "modified": "2020-10-15T21:53:11.153Z", - "contributors": [ - "fscholz", - "xgqfrms-GitHub" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/description": { - "modified": "2020-10-15T21:51:01.729Z", - "contributors": [ - "fscholz", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/developer": { - "modified": "2020-10-15T21:53:08.896Z", - "contributors": [ - "fscholz", - "1010Tech", - "xgqfrms-GitHub" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/manifest_version": { - "modified": "2020-10-15T21:51:02.450Z", - "contributors": [ - "RainSlide", - "fscholz", - "xgqfrms-GitHub", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/name": { - "modified": "2020-10-15T21:51:01.058Z", - "contributors": [ - "fscholz", - "dfchong", - "1010Tech", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/permissions": { - "modified": "2020-10-15T21:51:04.252Z", - "contributors": [ - "greatofdream", - "wbamberg", - "zhengkai2001", - "zimocode", - "kyle2003", - "yydzxz", - "WEKEYSHIT", - "Hypophrenia", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/short_name": { - "modified": "2020-10-15T21:51:02.002Z", - "contributors": [ - "fscholz", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/version": { - "modified": "2020-10-15T21:51:00.716Z", - "contributors": [ - "fscholz", - "xgqfrms-GitHub", - "taadis" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources": { - "modified": "2020-10-15T22:25:39.991Z", - "contributors": [ - "fish-inu" - ] - }, - "Mozilla/Add-ons/WebExtensions/manifest.json/主页地址": { - "modified": "2020-10-15T21:51:31.504Z", - "contributors": [ - "RainSlide", - "fscholz", - "1010Tech", - "Hypophrenia" - ] - }, - "Mozilla/Add-ons/WebExtensions/user_interface": { - "modified": "2019-03-18T20:52:33.784Z", - "contributors": [ - "Apricot", - "876843240", - "jinnchen" - ] - }, - "Mozilla/Add-ons/WebExtensions/user_interface/Browser_action": { - "modified": "2019-03-18T21:03:41.863Z", - "contributors": [ - "kyle2003" - ] - }, - "Mozilla/Add-ons/WebExtensions/user_interface/Browser_styles": { - "modified": "2020-10-15T22:25:56.457Z", - "contributors": [ - "DarthVaderrr" - ] - }, - "Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items": { - "modified": "2019-03-18T21:03:56.633Z", - "contributors": [ - "mengshiyue" - ] - }, - "Mozilla/Add-ons/WebExtensions/user_interface/Page_actions": { - "modified": "2019-03-18T21:03:06.637Z", - "contributors": [ - "yongm126" - ] - }, - "Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels": { - "modified": "2019-03-18T21:02:57.359Z", - "contributors": [ - "Jane47Zeng" - ] - }, - "Mozilla/Add-ons/WebExtensions/user_interface/侧边栏": { - "modified": "2019-03-18T21:02:29.279Z", - "contributors": [ - "dfchong" - ] - }, - "Mozilla/Add-ons/WebExtensions/实现一个设置页面": { - "modified": "2019-09-14T23:46:00.166Z", - "contributors": [ - "ivysrono", - "xcffl", - "Hypophrenia" - ] - }, - "Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件": { - "modified": "2020-09-17T09:25:04.236Z", - "contributors": [ - "kingcc", - "Daryl.Xu" - ] - }, - "Mozilla/Add-ons/WebExtensions/用户界面元素": { - "modified": "2019-03-18T21:06:10.178Z", - "contributors": [ - "qson", - "Hypophrenia" - ] - }, - "Mozilla/Developer_guide": { - "modified": "2020-06-26T07:13:21.797Z", - "contributors": [ - "SuiltaPico", - "ice-kylin", - "ziyunfei", - "jsm920", - "merrywoody", - "phenix" - ] - }, - "Mozilla/Developer_guide/Adding_APIs_to_the_navigator_object": { - "modified": "2019-03-23T23:34:41.037Z", - "contributors": [ - "ziyunfei", - "crazybullet" - ] - }, - "Mozilla/Developer_guide/Customizing_Firefox": { - "modified": "2019-01-17T03:58:02.226Z", - "contributors": [ - "RainSlide" - ] - }, - "Mozilla/Developer_guide/Source_Code": { - "modified": "2019-03-24T00:05:40.186Z", - "contributors": [ - "GuestRyan", - "wbamberg", - "124694738", - "moumoukings", - "ziyunfei", - "kingysu", - "merrywoody", - "phenix" - ] - }, - "Mozilla/Developer_guide/Source_Code/CVS": { - "modified": "2019-03-24T00:00:53.283Z", - "contributors": [ - "Peidong_Wang", - "miaoran2015", - "Pandaren", - "teoli", - "ziyunfei", - "phenix", - "Mgjbot", - "Klp99" - ] - }, - "Mozilla/Developer_guide/Source_Code/LatestPassingSource": { - "modified": "2019-03-24T00:00:52.967Z", - "contributors": [ - "ziyunfei", - "phenix" - ] - }, - "Mozilla/Firefox": { - "modified": "2020-01-18T14:38:03.567Z", - "contributors": [ - "leela52452", - "SphinxKnight", - "wbamberg", - "Jack-Q", - "RyanZhang", - "teoli", - "15195988307", - "iceKylin", - "lixiaoming", - "liy", - "c_king", - "Jack_No1", - "ethertank" - ] - }, - "Mozilla/Firefox/Experimental_features": { - "modified": "2019-01-17T01:35:06.796Z", - "contributors": [ - "wbamberg", - "LiHua", - "King." - ] - }, - "Mozilla/Firefox/Releases": { - "modified": "2019-01-16T17:09:06.445Z", - "contributors": [ - "wbamberg", - "Jack-Q", - "c_king", - "Jack_No1", - "ziyunfei", - "Sheppy" - ] - }, - "Mozilla/Firefox/Releases/1.5": { - "modified": "2020-11-20T04:48:59.030Z", - "contributors": [ - "wbamberg", - "Sebastianz" - ] - }, - "Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching": { - "modified": "2019-03-18T21:37:27.573Z", - "contributors": [ - "wbamberg", - "greatbug", - "Pada" - ] - }, - "Mozilla/Firefox/Releases/12": { - "modified": "2019-03-18T21:09:06.420Z", - "contributors": [ - "fscholz", - "wbamberg", - "Ende93", - "ethertank", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/14": { - "modified": "2019-03-23T23:39:39.174Z", - "contributors": [ - "wbamberg", - "Ende93", - "ethertank", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/15": { - "modified": "2019-03-23T23:39:15.652Z", - "contributors": [ - "wbamberg", - "Ende93", - "ethertank", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/16": { - "modified": "2019-03-23T23:39:27.575Z", - "contributors": [ - "wbamberg", - "Ende93", - "ziyunfei", - "ethertank" - ] - }, - "Mozilla/Firefox/Releases/17": { - "modified": "2019-03-18T21:09:08.582Z", - "contributors": [ - "fscholz", - "wbamberg", - "Ende93", - "ethertank", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/18": { - "modified": "2019-01-16T16:41:51.967Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "ethertank" - ] - }, - "Mozilla/Firefox/Releases/19": { - "modified": "2019-01-16T17:25:12.445Z", - "contributors": [ - "wbamberg", - "mrstork", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/20": { - "modified": "2019-01-16T16:54:50.861Z", - "contributors": [ - "wbamberg", - "ethertank", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/21": { - "modified": "2019-01-16T17:00:11.966Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "ethertank" - ] - }, - "Mozilla/Firefox/Releases/22": { - "modified": "2019-01-16T17:05:04.663Z", - "contributors": [ - "wbamberg", - "Ende93", - "ethertank", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/23": { - "modified": "2019-01-16T17:12:46.618Z", - "contributors": [ - "wbamberg", - "Ende93", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/24": { - "modified": "2019-01-16T17:41:58.569Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/25": { - "modified": "2019-01-16T17:41:39.671Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/25/Site_Compatibility": { - "modified": "2019-01-16T17:41:38.257Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/26": { - "modified": "2019-01-16T17:45:32.245Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/26/Site_Compatibility": { - "modified": "2019-01-16T17:48:36.057Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/27": { - "modified": "2019-01-16T17:56:24.955Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/28": { - "modified": "2019-01-16T18:02:01.001Z", - "contributors": [ - "wbamberg", - "Ende93", - "Zefling" - ] - }, - "Mozilla/Firefox/Releases/28/Site_Compatibility": { - "modified": "2019-01-16T18:02:00.053Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/3": { - "modified": "2019-03-23T23:59:15.526Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "ethertank", - "alzhu", - "jinyc", - "Gnrcn", - "Nnaabbcc", - "Feelyang", - "Starplex", - "Y001", - "Hiisee", - "Meteormatt", - "Andyyard", - "Ianyang" - ] - }, - "Mozilla/Firefox/Releases/3.6": { - "modified": "2019-12-13T20:33:19.816Z", - "contributors": [ - "wbamberg", - "SphinxKnight", - "ethertank", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/3/Site_compatibility": { - "modified": "2019-03-23T23:50:51.802Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "Fiag" - ] - }, - "Mozilla/Firefox/Releases/31": { - "modified": "2019-01-16T18:44:47.501Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/32": { - "modified": "2019-01-16T18:56:52.744Z", - "contributors": [ - "wbamberg", - "Ende93", - "yisi", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/33": { - "modified": "2019-01-16T19:07:26.172Z", - "contributors": [ - "wbamberg", - "yisi", - "ziyunfei" - ] - }, - "Mozilla/Firefox/Releases/35": { - "modified": "2019-12-13T20:33:35.958Z", - "contributors": [ - "wbamberg", - "Ende93", - "tiansh", - "Fiag" - ] - }, - "Mozilla/Firefox/Releases/41": { - "modified": "2019-01-16T20:57:02.807Z", - "contributors": [ - "wbamberg", - "Ende93", - "zhentao_lin" - ] - }, - "Mozilla/Firefox/Releases/43": { - "modified": "2019-03-23T22:45:32.059Z", - "contributors": [ - "wbamberg", - "Ende93", - "tulei555" - ] - }, - "Mozilla/Firefox/Releases/44": { - "modified": "2019-01-16T22:24:18.829Z", - "contributors": [ - "wbamberg", - "EricHedgedog" - ] - }, - "Mozilla/Firefox/Releases/45": { - "modified": "2019-01-16T22:09:44.303Z", - "contributors": [ - "wbamberg", - "Ende93", - "imeteora" - ] - }, - "Mozilla/Firefox/Releases/49": { - "modified": "2019-01-16T23:59:52.584Z", - "contributors": [ - "wbamberg", - "Ende93", - "Jiang-Xuan" - ] - }, - "Mozilla/Firefox/Releases/56": { - "modified": "2019-03-23T22:06:15.833Z", - "contributors": [ - "wbamberg", - "dapenglang" - ] - }, - "Mozilla/Firefox/Releases/59": { - "modified": "2019-03-18T21:44:42.821Z", - "contributors": [ - "wbamberg", - "ElliottZheng" - ] - }, - "Mozilla/Firefox/Releases/62": { - "modified": "2019-01-17T03:17:14.849Z", - "contributors": [ - "wbamberg", - "z2z2qp" - ] - }, - "Mozilla/Firefox/Releases/65": { - "modified": "2019-03-18T21:21:36.841Z", - "contributors": [ - "sjlleo", - "Azurak", - "wearehere8" - ] - }, - "Mozilla/Firefox/Releases/68": { - "modified": "2020-08-24T20:29:03.064Z", - "contributors": [ - "w568w", - "HondaNM" - ] - }, - "Mozilla/Firefox/Releases/69": { - "modified": "2019-10-25T04:48:07.433Z", - "contributors": [ - "KringMiao" - ] - }, - "Mozilla/Firefox/Releases/78": { - "modified": "2020-07-04T05:18:44.320Z", - "contributors": [ - "Gay夜" - ] - }, - "Mozilla/Mozilla_Persona": { - "modified": "2019-03-23T23:09:24.663Z", - "contributors": [ - "world521" - ] - }, - "Python": { - "modified": "2019-03-23T23:11:53.165Z", - "contributors": [ - "JiangLirui", - "xcffl" - ] - }, - "Quirks_Mode_and_Standards_Mode": { - "modified": "2019-03-24T00:17:27.134Z", - "contributors": [ - "OoOoOoOo", - "ziyunfei" - ] - }, - "Server-sent_events": { - "modified": "2020-03-04T10:52:34.764Z", - "contributors": [ - "femaimi", - "RainSlide", - "act262", - "raju_dasa" - ] - }, - "Server-sent_events/EventSource": { - "modified": "2020-10-15T21:21:30.406Z", - "contributors": [ - "into-piece", - "RainSlide", - "Jack.Works", - "xlaoyu", - "xgqfrms-GitHub", - "kameii", - "ziyunfei" - ] - }, - "Server-sent_events/EventSource/EventSource": { - "modified": "2019-08-07T05:55:13.404Z", - "contributors": [ - "ZZES_REN", - "kameii" - ] - }, - "Server-sent_events/EventSource/close": { - "modified": "2019-03-23T22:09:23.731Z", - "contributors": [ - "Char-Ten" - ] - }, - "Server-sent_events/EventSource/onerror": { - "modified": "2019-03-23T22:09:23.181Z", - "contributors": [ - "Char-Ten" - ] - }, - "Server-sent_events/EventSource/onopen": { - "modified": "2019-03-23T22:16:16.621Z", - "contributors": [ - "kameii" - ] - }, - "Server-sent_events/Using_server-sent_events": { - "modified": "2020-10-15T21:21:32.267Z", - "contributors": [ - "kagurakana", - "mkckr0", - "xgqfrms-GitHub", - "jamemark", - "ziyunfei" - ] - }, - "Site_Compatibility_for_Firefox_19": { - "modified": "2019-01-16T17:00:07.852Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Site_Compatibility_for_Firefox_21": { - "modified": "2019-01-16T17:20:04.063Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Site_Compatibility_for_Firefox_23": { - "modified": "2019-01-16T17:27:23.228Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Site_Compatibility_for_Firefox_24": { - "modified": "2019-01-16T17:27:30.001Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Specification_List": { - "modified": "2019-03-23T23:31:18.870Z", - "contributors": [ - "ziyunfei" - ] - }, - "Tools": { - "modified": "2020-08-19T03:34:07.960Z", - "contributors": [ - "Chell", - "paradise", - "luisleee", - "Alan-Liang", - "Tindoc", - "biurua", - "all2cn", - "SphinxKnight", - "aethu1314", - "rlgCRH", - "tonels", - "Azurak", - "yuan81777", - "wbamberg", - "wangxinhe", - "fygyx1", - "mosesguo", - "shadowdreamer", - "ShirleyM", - "Miss", - "robsean", - "Noly1990", - "bosskachen", - "yexiaoOnline", - "lixuanh", - "Ende93", - "Meteormatt", - "GrayLight", - "zhanyouwei", - "webery", - "201341", - "zaozaool", - "c_king", - "iiboys", - "YLOIHyl", - "whyletgo", - "chuxuezhe", - "ziyunfei", - "shengyouxiao" - ] - }, - "Tools/Accessibility_inspector": { - "modified": "2020-07-16T22:36:40.307Z", - "contributors": [ - "Baoer-MBY" - ] - }, - "Tools/Add-ons": { - "modified": "2020-07-16T22:36:23.904Z", - "contributors": [ - "wbamberg", - "maicss" - ] - }, - "Tools/Browser_Console": { - "modified": "2020-08-17T23:06:02.026Z", - "contributors": [ - "cellinlab", - "wbamberg", - "GrayLight", - "sona" - ] - }, - "Tools/Browser_Toolbox": { - "modified": "2020-07-16T22:35:55.951Z", - "contributors": [ - "wbamberg", - "Smartree", - "Mangon", - "frost" - ] - }, - "Tools/DOM_Property_Viewer": { - "modified": "2020-07-16T22:36:34.527Z", - "contributors": [ - "wbamberg", - "xgqfrms-GitHub", - "Jiang-Xuan" - ] - }, - "Tools/Debugger": { - "modified": "2020-12-03T00:30:34.386Z", - "contributors": [ - "sjwwjss", - "yhnmj6666", - "wbamberg", - "paopaor", - "Silly-Bo", - "lixuanh", - "Ellipse120", - "yatace", - "Jiang-Xuan", - "zeasdale", - "zhangwenhua029", - "webery", - "chan", - "jamesfancy", - "bassam", - "heyunxia", - "absqvb", - "oyangdewei8", - "q1560760", - "18113480380@163.com" - ] - }, - "Tools/Debugger-API": { - "modified": "2020-11-23T22:39:54.381Z", - "contributors": [ - "喝红酒的狼", - "tjunjun125" - ] - }, - "Tools/Debugger/How_to": { - "modified": "2020-07-16T22:35:08.602Z", - "contributors": [ - "wbamberg" - ] - }, - "Tools/Debugger/How_to/Open_the_debugger": { - "modified": "2020-07-16T22:35:09.466Z", - "contributors": [ - "wbamberg", - "webery" - ] - }, - "Tools/Debugger/How_to/Search": { - "modified": "2020-09-01T03:24:12.844Z", - "contributors": [ - "yhnmj6666" - ] - }, - "Tools/Debugger/How_to/Use_a_source_map": { - "modified": "2020-07-16T22:35:12.732Z", - "contributors": [ - "Tommy-White", - "wbamberg", - "xgqfrms-GitHub" - ] - }, - "Tools/Debugger/Source_map_errors": { - "modified": "2020-07-16T22:35:19.838Z", - "contributors": [ - "wbamberg", - "NotTwoChen", - "xlsl" - ] - }, - "Tools/Debugger/UI_Tour": { - "modified": "2020-07-16T22:35:17.289Z", - "contributors": [ - "wbamberg", - "webery", - "bosskachen" - ] - }, - "Tools/Eyedropper": { - "modified": "2020-07-16T22:36:08.089Z", - "contributors": [ - "wbamberg", - "maybe", - "seekMine", - "18113480380@163.com" - ] - }, - "Tools/Keyboard_shortcuts": { - "modified": "2020-07-16T22:35:52.694Z", - "contributors": [ - "Azurak", - "pickfire", - "wbamberg", - "c_king" - ] - }, - "Tools/Memory": { - "modified": "2020-07-16T22:36:27.540Z", - "contributors": [ - "wbamberg", - "jerryhwq" - ] - }, - "Tools/Memory/Basic_operations": { - "modified": "2020-07-16T22:36:29.732Z", - "contributors": [ - "wbamberg", - "jerryhwq" - ] - }, - "Tools/Memory/DOM_allocation_example": { - "modified": "2020-07-16T22:36:31.150Z", - "contributors": [ - "RainSlide", - "wbamberg", - "xx1124961758" - ] - }, - "Tools/Migrating_from_Firebug": { - "modified": "2020-07-16T22:36:38.013Z", - "contributors": [ - "Alan-Liang", - "wbamberg", - "maxbless", - "Wind2esg", - "lianhan", - "zhangtianle", - "ziyunfei", - "Qing", - "zs808", - "wolfpan", - "TonyKong" - ] - }, - "Tools/Network_Monitor": { - "modified": "2020-07-16T22:35:32.251Z", - "contributors": [ - "wbamberg", - "Rean", - "hdhe", - "Meteormatt", - "djh-qwe", - "webery", - "Ericlim5070..", - "18113480380@163.com", - "61867999" - ] - }, - "Tools/Network_Monitor/Performance_Analysis": { - "modified": "2020-07-16T22:35:35.971Z", - "contributors": [ - "Snake52996", - "wyapx" - ] - }, - "Tools/Network_Monitor/request_details": { - "modified": "2020-07-16T22:35:35.134Z", - "contributors": [ - "maicss" - ] - }, - "Tools/Network_Monitor/toolbar": { - "modified": "2020-07-16T22:35:33.078Z", - "contributors": [ - "wyapx" - ] - }, - "Tools/Page_Inspector": { - "modified": "2020-07-16T22:34:29.995Z", - "contributors": [ - "huijing", - "wbamberg", - "c_king", - "zmh_w", - "ziyunfei" - ] - }, - "Tools/Page_Inspector/3D_view": { - "modified": "2020-07-16T22:34:25.755Z", - "contributors": [ - "Gitai", - "wbamberg", - "ziyunfei" - ] - }, - "Tools/Page_Inspector/How_to": { - "modified": "2020-07-16T22:34:32.374Z", - "contributors": [ - "wbamberg", - "c_king", - "sidgan" - ] - }, - "Tools/Page_Inspector/How_to/Edit_CSS_filters": { - "modified": "2020-07-16T22:34:45.569Z", - "contributors": [ - "wbamberg", - "pangcq699885", - "c_king" - ] - }, - "Tools/Page_Inspector/How_to/Examine_Flexbox_layouts": { - "modified": "2020-07-16T22:34:48.651Z", - "contributors": [ - "huijing" - ] - }, - "Tools/Page_Inspector/How_to/Examine_and_edit_CSS": { - "modified": "2020-07-16T22:34:43.923Z", - "contributors": [ - "wbamberg", - "c_king" - ] - }, - "Tools/Page_Inspector/How_to/Examine_and_edit_HTML": { - "modified": "2020-07-16T22:34:41.586Z", - "contributors": [ - "wbamberg", - "zhanglei", - "c_king" - ] - }, - "Tools/Page_Inspector/How_to/Examine_and_edit_the_box_model": { - "modified": "2020-07-16T22:34:34.711Z", - "contributors": [ - "wbamberg", - "webery", - "c_king" - ] - }, - "Tools/Page_Inspector/How_to/Examine_event_listeners": { - "modified": "2020-07-16T22:34:36.027Z", - "contributors": [ - "wbamberg", - "webery", - "c_king" - ] - }, - "Tools/Page_Inspector/How_to/Inspect_and_select_colors": { - "modified": "2020-07-16T22:34:35.370Z", - "contributors": [ - "wbamberg", - "webery", - "c_king" - ] - }, - "Tools/Page_Inspector/How_to/Open_the_Inspector": { - "modified": "2020-07-16T22:34:33.282Z", - "contributors": [ - "wbamberg", - "c_king" - ] - }, - "Tools/Page_Inspector/How_to/Reposition_elements_in_the_page": { - "modified": "2020-07-16T22:34:46.324Z", - "contributors": [ - "xiaogezi" - ] - }, - "Tools/Page_Inspector/How_to/Select_an_element": { - "modified": "2020-07-16T22:34:33.944Z", - "contributors": [ - "wbamberg", - "c_king" - ] - }, - "Tools/Page_Inspector/How_to/Use_the_Inspector_from_the_Web_Console": { - "modified": "2020-07-16T22:34:44.659Z", - "contributors": [ - "wbamberg", - "webery" - ] - }, - "Tools/Page_Inspector/How_to/View_background_images": { - "modified": "2020-07-16T22:34:44.286Z", - "contributors": [ - "wbamberg", - "DyVan_Cheung" - ] - }, - "Tools/Page_Inspector/How_to/View_fonts": { - "modified": "2020-07-16T22:34:39.361Z", - "contributors": [ - "wbamberg", - "webery" - ] - }, - "Tools/Page_Inspector/How_to/Visualize_transforms": { - "modified": "2020-07-16T22:34:39.820Z", - "contributors": [ - "wbamberg", - "webery" - ] - }, - "Tools/Page_Inspector/How_to/Work_with_animations": { - "modified": "2020-07-16T22:34:37.525Z", - "contributors": [ - "alanzhchou" - ] - }, - "Tools/Page_Inspector/Keyboard_shortcuts": { - "modified": "2020-07-16T22:34:53.384Z", - "contributors": [ - "Markmax", - "wbamberg", - "c_king" - ] - }, - "Tools/Page_Inspector/UI_Tour": { - "modified": "2020-07-16T22:34:49.834Z", - "contributors": [ - "wbamberg", - "c_king" - ] - }, - "Tools/Performance": { - "modified": "2020-07-16T22:36:14.065Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "jsx", - "hstd998.com", - "laoling", - "xiaolong" - ] - }, - "Tools/Performance/Call_Tree": { - "modified": "2020-07-16T22:36:20.191Z", - "contributors": [ - "wbamberg", - "sunscheung" - ] - }, - "Tools/Performance/Frame_rate": { - "modified": "2020-07-16T22:36:19.305Z", - "contributors": [ - "damengzhang", - "nolotus" - ] - }, - "Tools/Performance/UI_Tour": { - "modified": "2020-07-16T22:36:15.489Z", - "contributors": [ - "damengzhang" - ] - }, - "Tools/Performance/Waterfall": { - "modified": "2020-07-16T22:36:18.785Z", - "contributors": [ - "damengzhang", - "wbamberg", - "daaain" - ] - }, - "Tools/Profiler": { - "modified": "2020-07-16T22:35:29.313Z", - "contributors": [ - "wbamberg", - "hstarorg", - "Qcui", - "jackyong" - ] - }, - "Tools/Remote_Debugging": { - "modified": "2020-07-16T22:35:38.510Z", - "contributors": [ - "yuan81777", - "wbamberg", - "Tweiker", - "Ende93", - "phoon1982", - "ziyunfei", - "King_Zz", - "molang", - "Leo_Ken" - ] - }, - "Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE_clone": { - "modified": "2019-03-23T23:02:33.405Z", - "contributors": [ - "wbamberg", - "qq18588696841" - ] - }, - "Tools/Remote_Debugging/Firefox_for_Android": { - "modified": "2020-07-16T22:35:39.562Z", - "contributors": [ - "wbamberg", - "miraculousDNA", - "zzangxu", - "Tony7583", - "15872036555@163.com", - "cheng@_@", - "18353573321" - ] - }, - "Tools/Responsive_Design_View": { - "modified": "2020-07-16T22:35:22.496Z", - "contributors": [ - "wbamberg", - "Meteormatt", - "maybe", - "ziyunfei", - "dannyxu" - ] - }, - "Tools/Rulers": { - "modified": "2020-07-16T22:36:26.679Z", - "contributors": [ - "wbamberg", - "xperblueray", - "ziyunfei", - "maicss" - ] - }, - "Tools/Settings": { - "modified": "2020-07-16T22:36:35.793Z", - "contributors": [ - "wbamberg", - "Meteormatt", - "DarryJH" - ] - }, - "Tools/Shader_Editor": { - "modified": "2020-07-16T22:35:55.015Z", - "contributors": [ - "SphinxKnight", - "wbamberg", - "lixuanh" - ] - }, - "Tools/Style_Editor": { - "modified": "2020-07-16T22:35:02.096Z", - "contributors": [ - "wbamberg", - "lixuanh", - "xgqfrms-GitHub", - "webery", - "Shadowyyyy", - "maybe", - "molang" - ] - }, - "Tools/Tools_Toolbox": { - "modified": "2020-07-16T22:35:28.441Z", - "contributors": [ - "wbamberg", - "ZQH", - "bosskachen", - "c_king", - "ziyunfei" - ] - }, - "Tools/Using_the_Source_Editor": { - "modified": "2020-07-16T22:34:03.695Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "Sanshao" - ] - }, - "Tools/Web_Console": { - "modified": "2020-07-16T22:34:10.632Z", - "contributors": [ - "7NZ", - "jason-guo", - "wbamberg", - "peak", - "goer", - "pixiu", - "bassam", - "huanming", - "tangxiaobaobao", - "iakuf" - ] - }, - "Tools/Web_Console/Helpers": { - "modified": "2020-09-20T02:25:41.255Z", - "contributors": [ - "EbeRybDI", - "wbamberg", - "xupingmao" - ] - }, - "Tools/Web_Console/Invoke_getters_from_autocomplete": { - "modified": "2020-07-16T22:34:24.566Z", - "contributors": [ - "c1er" - ] - }, - "Tools/Web音频编辑器": { - "modified": "2020-07-16T22:36:08.958Z", - "contributors": [ - "wbamberg", - "ab233", - "DorayHong" - ] - }, - "Tools/Working_with_iframes": { - "modified": "2020-07-16T22:36:12.232Z", - "contributors": [ - "PYkm", - "iliangdianban" - ] - }, - "Tools/about:debugging": { - "modified": "2020-07-16T22:36:33.464Z", - "contributors": [ - "7NZ", - "wbamberg", - "JackYanzhe", - "yangwang", - "Adtomdex" - ] - }, - "Tools/about:debugging/about:debugging_before_Firefox_68": { - "modified": "2020-07-16T22:36:34.042Z", - "contributors": [ - "lzrhcj" - ] - }, - "Tools/不推荐的工具": { - "modified": "2020-07-16T22:36:40.884Z", - "contributors": [ - "GMMG55" - ] - }, - "Tools/存储查看器": { - "modified": "2020-07-16T22:36:10.648Z", - "contributors": [ - "hellojackhui" - ] - }, - "Tools/小技巧": { - "modified": "2020-07-16T22:36:36.674Z", - "contributors": [ - "Argon-Pub", - "wbamberg", - "ShirleyM" - ] - }, - "Understanding_Underlines": { - "modified": "2020-06-28T08:17:09.016Z", - "contributors": [ - "riino", - "zsxeee", - "ziyunfei", - "Y001", - "Bonede" - ] - }, - "Updating_extensions_for_Firefox_3": { - "modified": "2019-12-13T20:33:30.985Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "Sheppy", - "phenix", - "Loveunk" - ] - }, - "Using_XPath": { - "modified": "2019-01-16T15:30:24.695Z", - "contributors": [ - "Cuimingda" - ] - }, - "WOFF": { - "modified": "2020-10-15T21:07:54.753Z", - "contributors": [ - "zhangchen", - "MingxunBai", - "fscholz", - "ziyunfei" - ] - }, - "Web": { - "modified": "2020-09-21T00:46:13.839Z", - "contributors": [ - "z284949127", - "c0ka", - "laampui", - "momin-gg", - "mkckr0", - "RainSlide", - "atenxyz", - "gu_qing", - "sanmao7912", - "darren-211", - "ZZIRAN", - "sijimi", - "joshchiucn", - "bedreamer", - "zhuangyin", - "hsnzj", - "kakax114", - "Bayes", - "wwwonekey", - "reetmoon", - "MsDreamm", - "Forbidden", - "qdlaoyao", - "yexueduxing", - "gzrjzcx", - "chenos", - "liliang-cn", - "pavilion2t", - "sumin", - "chinanf-boy", - "lovue", - "sywsyw", - "Mohaiyo", - "keifergu", - "yuankunzhang", - "xixilog", - "Ende93", - "Hugh", - "happywzl", - "xgqfrms-GitHub", - "ValkyrieLawliet", - "chzng", - "HongxuWei", - "sunnylost", - "ruiM92", - "Moressette", - "JunyueCao", - "rhyttr", - "luojia", - "liminjun", - "Serifx", - "paraofheaven", - "Jiasm", - "showd0wn", - "tlhezai", - "vpslijie", - "xgqfrms", - "jsx", - "hstd998.com", - "yfdyh000", - "lunix01", - "wzjg520", - "Breezewish", - "Yuan.Xulei", - "rachelz", - "ziyunfei", - "shengyouxiao", - "wanywn_0", - "shura-china", - "teddywu", - "Sheppy" - ] - }, - "Web/API": { - "modified": "2020-07-05T23:42:39.974Z", - "contributors": [ - "codevvvv9", - "Spikef", - "simon.woo", - "ridiculousjam", - "RainSlide", - "ANTI01", - "guoooofu", - "thanly", - "stuxt", - "zihengCat", - "AsukaSong", - "shizhouyu", - "heineiuo", - "fygyx1", - "keller0", - "xgqfrms-GitHub", - "teoli", - "Darrel.Hsu", - "Fiag", - "ethertank", - "ziyunfei", - "fengzilong" - ] - }, - "Web/API/ANGLE_instanced_arrays": { - "modified": "2020-10-15T21:51:30.296Z", - "contributors": [ - "SebrinaD", - "wymm0008", - "RunningBear1", - "Daibai", - "shockw4ver", - "breakair", - "camillalo" - ] - }, - "Web/API/AbortSignal": { - "modified": "2020-10-15T22:00:35.061Z", - "contributors": [ - "fenyu", - "Ende93", - "yuyx91", - "Feahter" - ] - }, - "Web/API/AbortSignal/aborted": { - "modified": "2020-10-15T22:01:06.083Z", - "contributors": [ - "fengerzh" - ] - }, - "Web/API/AbortSignal/onabort": { - "modified": "2020-10-15T22:01:12.039Z", - "contributors": [ - "syhxczy" - ] - }, - "Web/API/AbstractWorker": { - "modified": "2020-11-08T08:49:33.020Z", - "contributors": [ - "plusmultiply0", - "Alphmega", - "Darrel.Hsu" - ] - }, - "Web/API/AbstractWorker/onerror": { - "modified": "2020-10-15T21:49:22.728Z", - "contributors": [ - "Jack.Works", - "liuzeyafzy" - ] - }, - "Web/API/Accelerometer": { - "modified": "2020-10-15T22:21:10.384Z", - "contributors": [ - "Mxiaof" - ] - }, - "Web/API/AmbientLightSensor": { - "modified": "2019-03-23T22:07:10.937Z", - "contributors": [ - "shockw4ver" - ] - }, - "Web/API/AmbientLightSensor/AmbientLightSensor": { - "modified": "2019-03-23T22:07:16.629Z", - "contributors": [ - "shockw4ver" - ] - }, - "Web/API/AmbientLightSensor/reading": { - "modified": "2019-03-23T22:07:09.220Z", - "contributors": [ - "shockw4ver" - ] - }, - "Web/API/AnalyserNode": { - "modified": "2020-10-15T21:30:26.024Z", - "contributors": [ - "vivimice", - "sfilata", - "stonehuang", - "luojia", - "maicss", - "yvan0423", - "WhiteMind", - "Ambar", - "shanghui", - "teoli", - "Darrel.Hsu" - ] - }, - "Web/API/AnalyserNode/AnalyserNode": { - "modified": "2020-10-15T21:58:45.437Z", - "contributors": [ - "joy-yu" - ] - }, - "Web/API/AnalyserNode/fft": { - "modified": "2019-03-18T20:44:28.140Z", - "contributors": [ - "RainSlide", - "GabrielchenCN" - ] - }, - "Web/API/AnalyserNode/fftSize": { - "modified": "2019-03-23T22:19:56.212Z", - "contributors": [ - "uk-kaoshi", - "WhiteMind" - ] - }, - "Web/API/AnalyserNode/frequencyBinCount": { - "modified": "2019-03-23T22:19:59.260Z", - "contributors": [ - "WhiteMind" - ] - }, - "Web/API/AnalyserNode/getByteFrequencyData": { - "modified": "2019-03-23T22:20:50.673Z", - "contributors": [ - "HuShiyuFrontEnd", - "WhiteMind", - "kylin_z" - ] - }, - "Web/API/AnalyserNode/getByteTimeDomainData": { - "modified": "2020-10-15T22:17:34.702Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/AnalyserNode/getFloatFrequencyData": { - "modified": "2020-10-15T22:01:25.250Z", - "contributors": [ - "vivimice", - "HuShiyuFrontEnd" - ] - }, - "Web/API/AnalyserNode/smoothingTimeConstant": { - "modified": "2019-03-23T22:19:58.900Z", - "contributors": [ - "WhiteMind" - ] - }, - "Web/API/Animation": { - "modified": "2020-11-03T11:36:48.553Z", - "contributors": [ - "1v9", - "xgqfrms-GitHub", - "Taoja", - "wth", - "fiona23", - "thanos" - ] - }, - "Web/API/Animation/Animation": { - "modified": "2019-03-23T22:25:32.937Z", - "contributors": [ - "WhiteMind", - "Taoja" - ] - }, - "Web/API/Animation/cancel": { - "modified": "2019-03-23T22:23:31.794Z", - "contributors": [ - "xgqfrms-GitHub", - "WhiteMind" - ] - }, - "Web/API/Animation/currentTime": { - "modified": "2019-03-23T22:25:13.728Z", - "contributors": [ - "jiangbai333", - "Taoja" - ] - }, - "Web/API/Animation/effect": { - "modified": "2019-03-23T22:25:12.214Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/Animation/finish": { - "modified": "2020-10-15T22:11:39.504Z", - "contributors": [ - "fengchunsgit" - ] - }, - "Web/API/Animation/finished": { - "modified": "2019-03-23T22:25:06.254Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/Animation/id": { - "modified": "2019-03-23T22:25:01.859Z", - "contributors": [ - "jiangbai333" - ] - }, - "Web/API/Animation/oncancel": { - "modified": "2019-03-23T22:16:25.770Z", - "contributors": [ - "micblo" - ] - }, - "Web/API/Animation/play": { - "modified": "2020-10-15T22:30:09.446Z", - "contributors": [ - "kagurakana" - ] - }, - "Web/API/Animation/playState": { - "modified": "2019-03-23T22:08:28.317Z", - "contributors": [ - "Ende93", - "Geolage" - ] - }, - "Web/API/AnimationEvent": { - "modified": "2019-03-23T23:02:22.417Z", - "contributors": [ - "luneice", - "xgqfrms-GitHub", - "zmrzwj", - "teoli", - "zmh_w" - ] - }, - "Web/API/AnimationEvent/AnimationEvent": { - "modified": "2019-03-23T22:45:26.067Z", - "contributors": [ - "eqielb" - ] - }, - "Web/API/AnimationEvent/animationName": { - "modified": "2019-03-23T22:24:40.125Z", - "contributors": [ - "zmrzwj" - ] - }, - "Web/API/AnimationTimeline": { - "modified": "2019-03-18T21:43:31.909Z", - "contributors": [ - "zxsunrise", - "xiaozhuzll" - ] - }, - "Web/API/Attr": { - "modified": "2019-11-05T01:59:06.141Z", - "contributors": [ - "yuanshang", - "zdzDesigner", - "xiiiAtCn", - "nfer", - "steveyxlin", - "lixuanh", - "RIO-LI", - "jiahui", - "zeasdale", - "markof", - "qq1211178784", - "AlexChao" - ] - }, - "Web/API/Attr/localName": { - "modified": "2020-10-15T21:52:37.297Z", - "contributors": [ - "kite-js", - "lixuanh" - ] - }, - "Web/API/Attr/namespaceURI": { - "modified": "2019-03-23T22:11:30.003Z", - "contributors": [ - "AaronYehf" - ] - }, - "Web/API/Attr/prefix": { - "modified": "2020-10-15T21:52:36.917Z", - "contributors": [ - "kite-js", - "holynewbie", - "lixuanh" - ] - }, - "Web/API/AudioBuffer": { - "modified": "2020-10-15T21:48:37.724Z", - "contributors": [ - "xiaoyixiang", - "worm_kun", - "wolfpan", - "mxyzzhong", - "wenzhaoxu", - "maohhgg", - "smilewalker" - ] - }, - "Web/API/AudioBuffer/AudioBuffer": { - "modified": "2020-10-15T22:02:12.549Z", - "contributors": [ - "WhiteMind" - ] - }, - "Web/API/AudioBuffer/copyFromChannel": { - "modified": "2019-03-23T22:15:27.978Z", - "contributors": [ - "SHALLYKL" - ] - }, - "Web/API/AudioBuffer/duration": { - "modified": "2019-03-23T22:15:18.654Z", - "contributors": [ - "SHALLYKL" - ] - }, - "Web/API/AudioBuffer/getChannelData": { - "modified": "2020-10-15T22:12:50.144Z", - "contributors": [ - "kongtee" - ] - }, - "Web/API/AudioBuffer/length": { - "modified": "2019-03-23T22:15:29.469Z", - "contributors": [ - "SHALLYKL" - ] - }, - "Web/API/AudioBuffer/numberOfChannels": { - "modified": "2019-03-23T22:15:24.876Z", - "contributors": [ - "dancci", - "SHALLYKL" - ] - }, - "Web/API/AudioBuffer/sampleRate": { - "modified": "2020-10-15T21:58:20.980Z", - "contributors": [ - "dancci" - ] - }, - "Web/API/AudioBufferSourceNode": { - "modified": "2019-03-23T22:26:02.114Z", - "contributors": [ - "kongtee", - "hhxxhg", - "SphinxKnight", - "HuShiyuFrontEnd", - "benber", - "GrainBear", - "WhiteMind", - "Taoja" - ] - }, - "Web/API/AudioBufferSourceNode/AudioBufferSourceNode": { - "modified": "2020-10-15T22:21:34.284Z", - "contributors": [ - "rainy811" - ] - }, - "Web/API/AudioBufferSourceNode/buffer": { - "modified": "2020-10-15T21:58:15.980Z", - "contributors": [ - "dancci" - ] - }, - "Web/API/AudioBufferSourceNode/start": { - "modified": "2020-10-15T22:13:09.209Z", - "contributors": [ - "kongtee" - ] - }, - "Web/API/AudioContext": { - "modified": "2020-10-15T21:28:08.510Z", - "contributors": [ - "xiaoyixiang", - "Ende93", - "kongtee", - "Jack_lo", - "maicss", - "yqjiang", - "Taoja", - "ayqy", - "focus" - ] - }, - "Web/API/AudioContext/AudioContext": { - "modified": "2019-03-23T22:19:39.119Z", - "contributors": [ - "maicss", - "yqjiang" - ] - }, - "Web/API/AudioContext/baseLatency": { - "modified": "2020-10-15T22:22:03.796Z", - "contributors": [ - "CodeRookie262" - ] - }, - "Web/API/AudioContext/close": { - "modified": "2019-01-16T20:57:22.650Z", - "contributors": [ - "yqjiang", - "ayqy" - ] - }, - "Web/API/AudioContext/createAnalyser": { - "modified": "2019-03-23T22:51:30.295Z", - "contributors": [ - "Ambar", - "ayqy" - ] - }, - "Web/API/AudioContext/createBiquadFilter": { - "modified": "2019-03-23T22:19:40.757Z", - "contributors": [ - "feewb", - "yqjiang" - ] - }, - "Web/API/AudioContext/createBuffer": { - "modified": "2019-03-23T22:49:27.952Z", - "contributors": [ - "Taoja", - "LiuTong", - "Losses" - ] - }, - "Web/API/AudioContext/createBufferSource": { - "modified": "2019-03-23T22:26:08.102Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/AudioContext/createChannelMerger": { - "modified": "2019-03-23T22:21:54.996Z", - "contributors": [ - "win7killer" - ] - }, - "Web/API/AudioContext/createChannelSplitter": { - "modified": "2019-03-23T22:19:41.394Z", - "contributors": [ - "yqjiang" - ] - }, - "Web/API/AudioContext/createConvolver": { - "modified": "2019-03-23T22:31:06.367Z", - "contributors": [ - "TomdyQin" - ] - }, - "Web/API/AudioContext/createDelay": { - "modified": "2019-03-23T22:16:38.056Z", - "contributors": [ - "wang_geng", - "jb145161" - ] - }, - "Web/API/AudioContext/createMediaElementSource": { - "modified": "2019-03-23T22:09:51.262Z", - "contributors": [ - "Corps" - ] - }, - "Web/API/AudioContext/createMediaStreamDestination": { - "modified": "2019-03-23T22:12:23.111Z", - "contributors": [ - "huangxok" - ] - }, - "Web/API/AudioContext/createMediaStreamSource": { - "modified": "2019-12-05T01:43:24.167Z", - "contributors": [ - "zwmin", - "maohhgg", - "Remond" - ] - }, - "Web/API/AudioContext/createScriptProcessor": { - "modified": "2020-03-24T04:10:23.984Z", - "contributors": [ - "frankyoung0305", - "zwmin", - "fanmingfei", - "Remond", - "Melo.HG" - ] - }, - "Web/API/AudioContext/createWaveShaper": { - "modified": "2019-03-23T22:15:28.242Z", - "contributors": [ - "SHALLYKL" - ] - }, - "Web/API/AudioContext/currentTime": { - "modified": "2019-03-23T22:52:18.954Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/decodeAudioData": { - "modified": "2019-03-23T22:36:34.575Z", - "contributors": [ - "Taoja", - "huangxok" - ] - }, - "Web/API/AudioContext/destination": { - "modified": "2019-03-23T22:52:09.137Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/listener": { - "modified": "2019-03-23T22:52:15.612Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/mozAudioChannelType": { - "modified": "2019-03-23T22:52:10.983Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/onstatechange": { - "modified": "2019-03-23T22:52:09.265Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/resume": { - "modified": "2019-03-23T22:08:48.326Z", - "contributors": [ - "maicss" - ] - }, - "Web/API/AudioContext/sampleRate": { - "modified": "2019-03-23T22:52:21.186Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/state": { - "modified": "2019-03-23T22:52:21.050Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/suspend": { - "modified": "2020-11-29T00:47:49.013Z", - "contributors": [ - "saifeiLee", - "maicss" - ] - }, - "Web/API/AudioDestinationNode": { - "modified": "2019-03-23T22:26:58.184Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/AudioDestinationNode/maxChannelCount": { - "modified": "2019-03-23T22:23:37.714Z", - "contributors": [ - "xdsnet" - ] - }, - "Web/API/AudioListener": { - "modified": "2020-10-15T22:28:43.606Z", - "contributors": [ - "Fancyflame" - ] - }, - "Web/API/AudioNode": { - "modified": "2020-04-12T23:39:42.800Z", - "contributors": [ - "Fancyflame", - "joenlee", - "huangxok", - "WhiteMind", - "fscholz", - "ziyunfei", - "xcffl" - ] - }, - "Web/API/AudioNode/connect": { - "modified": "2020-10-15T22:07:14.261Z", - "contributors": [ - "MisicDemone" - ] - }, - "Web/API/AudioNode/connect(AudioParam)": { - "modified": "2019-03-23T22:18:48.818Z", - "contributors": [ - "smilewalker" - ] - }, - "Web/API/AudioNodeOptions": { - "modified": "2019-03-18T21:39:54.122Z", - "contributors": [ - "WhiteMind" - ] - }, - "Web/API/AudioParam": { - "modified": "2019-03-23T22:14:20.528Z", - "contributors": [ - "micblo" - ] - }, - "Web/API/AudioParamDescriptor": { - "modified": "2020-10-15T22:31:35.160Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/AudioScheduledSourceNode": { - "modified": "2020-10-15T22:13:09.198Z", - "contributors": [ - "GearHZBoX", - "fscholz" - ] - }, - "Web/API/AudioScheduledSourceNode/stop": { - "modified": "2020-10-15T22:13:09.202Z", - "contributors": [ - "kongtee" - ] - }, - "Web/API/AudioTrack": { - "modified": "2020-10-15T22:10:20.350Z", - "contributors": [ - "ewfian", - "903659321" - ] - }, - "Web/API/AudioWorkletNode": { - "modified": "2020-10-15T22:23:50.519Z", - "contributors": [ - "Darc" - ] - }, - "Web/API/AudioWorkletProcessor": { - "modified": "2020-10-15T22:30:34.322Z", - "contributors": [ - "ZiYang-Song" - ] - }, - "Web/API/AuthenticatorResponse": { - "modified": "2020-10-15T22:31:35.605Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/AuthenticatorResponse/clientDataJSON": { - "modified": "2020-10-15T22:31:35.415Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/Background_Tasks_API": { - "modified": "2020-10-15T22:22:15.328Z", - "contributors": [ - "wxyads", - "hulucode", - "lllbahol", - "kuangyy" - ] - }, - "Web/API/BaseAudioContext": { - "modified": "2019-03-18T21:41:51.543Z", - "contributors": [ - "Jedipedia" - ] - }, - "Web/API/BaseAudioContext/createConstantSource": { - "modified": "2019-03-18T21:41:45.788Z", - "contributors": [ - "HuShiyuFrontEnd" - ] - }, - "Web/API/BaseAudioContext/createOscillator": { - "modified": "2020-10-15T22:05:46.637Z", - "contributors": [ - "tanchi_wang" - ] - }, - "Web/API/BaseAudioContext/createPeriodicWave": { - "modified": "2020-10-15T22:17:38.951Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/BatteryManager": { - "modified": "2019-03-23T22:45:03.959Z", - "contributors": [ - "lixuanh", - "Alphmega", - "yangfeileo" - ] - }, - "Web/API/BatteryManager/charging": { - "modified": "2019-08-07T00:46:16.369Z", - "contributors": [ - "Theresa233", - "Atractylodes" - ] - }, - "Web/API/Battery_Status_API": { - "modified": "2020-10-15T21:33:07.503Z", - "contributors": [ - "1v9", - "Fantasy_shao", - "Meteormatt" - ] - }, - "Web/API/Beacon_API": { - "modified": "2019-07-22T05:58:53.240Z", - "contributors": [ - "xgqfrms", - "c1er" - ] - }, - "Web/API/Beacon_API/Using_the_Beacon_API": { - "modified": "2020-04-23T03:45:20.732Z", - "contributors": [ - "biqing", - "April421", - "xgqfrms" - ] - }, - "Web/API/BeforeInstallPromptEvent": { - "modified": "2020-08-04T05:58:35.403Z", - "contributors": [ - "SDUTWSL", - "xgqfrms-GitHub", - "marcoscaceres" - ] - }, - "Web/API/BeforeInstallPromptEvent/prompt": { - "modified": "2019-03-23T22:11:32.127Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/BeforeUnloadEvent": { - "modified": "2020-10-15T21:52:18.043Z", - "contributors": [ - "Carllllo", - "xgqfrms-GitHub", - "Jihan-Z" - ] - }, - "Web/API/BiquadFilterNode": { - "modified": "2019-03-23T22:23:28.240Z", - "contributors": [ - "huangxok", - "WhiteMind" - ] - }, - "Web/API/Blob": { - "modified": "2020-10-15T21:21:11.119Z", - "contributors": [ - "chenjsh36", - "zgayjjf", - "c1er", - "zwmin", - "AlixWang", - "RainSlide", - "mxyzzhong", - "zxsunrise", - "zhangchen", - "rolitter", - "luojia", - "kagawagao", - "xgqfrms-GitHub", - "Ende93", - "hujinglin", - "lyxuncle", - "loraine", - "gyc1299339354", - "ziyunfei" - ] - }, - "Web/API/Blob/Blob": { - "modified": "2019-08-14T23:30:46.057Z", - "contributors": [ - "luojia", - "873314461", - "xgqfrms-GitHub", - "dukai" - ] - }, - "Web/API/Blob/arrayBuffer": { - "modified": "2020-10-15T22:25:12.898Z", - "contributors": [ - "knightyun", - "SSQLQIANBB" - ] - }, - "Web/API/Blob/size": { - "modified": "2019-03-24T00:16:18.299Z", - "contributors": [ - "icyflash", - "ziyunfei" - ] - }, - "Web/API/Blob/slice": { - "modified": "2019-12-23T07:32:15.800Z", - "contributors": [ - "c1er", - "LeeVirtue", - "xgqfrms-GitHub", - "ziyunfei", - "youryida", - "zekai.zheng" - ] - }, - "Web/API/Blob/stream": { - "modified": "2020-10-15T22:25:37.060Z", - "contributors": [ - "c1er" - ] - }, - "Web/API/Blob/text": { - "modified": "2020-10-15T22:28:06.215Z", - "contributors": [ - "knightyun" - ] - }, - "Web/API/Blob/type": { - "modified": "2020-10-15T21:06:53.138Z", - "contributors": [ - "RainSlide", - "li9269391", - "xc2", - "ziyunfei", - "ethertank" - ] - }, - "Web/API/BlobBuilder": { - "modified": "2019-08-14T07:08:22.933Z", - "contributors": [ - "ziyunfei" - ] - }, - "Web/API/Bluetooth": { - "modified": "2019-03-23T22:29:44.172Z", - "contributors": [ - "githubyangwei", - "yellowkingdom", - "Joeny", - "wth" - ] - }, - "Web/API/Bluetooth/requestDevice": { - "modified": "2019-03-23T22:16:23.044Z", - "contributors": [ - "hefang" - ] - }, - "Web/API/Body": { - "modified": "2020-10-15T21:39:41.630Z", - "contributors": [ - "jason-grimm", - "xgqfrms-GitHub", - "chaosdog", - "Soyaine", - "Jeff-Kook", - "git-lt", - "fscholz" - ] - }, - "Web/API/Body/arrayBuffer": { - "modified": "2019-03-23T22:45:19.643Z", - "contributors": [ - "budblack", - "eqielb" - ] - }, - "Web/API/Body/blob": { - "modified": "2019-03-23T22:13:57.339Z", - "contributors": [ - "fyzhu", - "xiaoyixiang", - "xgqfrms-GitHub", - "thomastao0215" - ] - }, - "Web/API/Body/body": { - "modified": "2020-10-15T22:02:01.208Z", - "contributors": [ - "jason-grimm", - "jcsahnwaldt", - "Axue" - ] - }, - "Web/API/Body/bodyUsed": { - "modified": "2019-03-23T22:13:03.228Z", - "contributors": [ - "chaosdog" - ] - }, - "Web/API/Body/formData": { - "modified": "2019-03-23T22:03:43.519Z", - "contributors": [ - "Gscienty" - ] - }, - "Web/API/Body/json": { - "modified": "2020-10-15T21:54:35.260Z", - "contributors": [ - "RainSlide", - "Soyaine", - "PeixuanLi", - "linmodev", - "xgqfrms-GitHub" - ] - }, - "Web/API/Body/text": { - "modified": "2020-10-15T22:01:11.954Z", - "contributors": [ - "RainSlide", - "zhihongzhong" - ] - }, - "Web/API/BroadcastChannel": { - "modified": "2020-10-15T22:17:57.354Z", - "contributors": [ - "Spikef", - "wbamberg" - ] - }, - "Web/API/BroadcastChannel/BroadcastChannel": { - "modified": "2020-10-15T22:26:22.459Z", - "contributors": [ - "Spikef" - ] - }, - "Web/API/BroadcastChannel/close": { - "modified": "2020-10-15T22:26:23.072Z", - "contributors": [ - "Spikef" - ] - }, - "Web/API/BroadcastChannel/messageerror_event": { - "modified": "2020-10-15T22:26:23.328Z", - "contributors": [ - "Spikef" - ] - }, - "Web/API/BroadcastChannel/name": { - "modified": "2020-10-15T22:26:21.201Z", - "contributors": [ - "Spikef" - ] - }, - "Web/API/BroadcastChannel/onmessage": { - "modified": "2020-10-15T22:26:22.393Z", - "contributors": [ - "Spikef" - ] - }, - "Web/API/BroadcastChannel/onmessageerror": { - "modified": "2020-10-15T22:26:22.343Z", - "contributors": [ - "Spikef" - ] - }, - "Web/API/BroadcastChannel/postMessage": { - "modified": "2020-10-15T22:26:23.239Z", - "contributors": [ - "Spikef" - ] - }, - "Web/API/Broadcast_Channel_API": { - "modified": "2020-10-15T22:26:22.383Z", - "contributors": [ - "Spikef" - ] - }, - "Web/API/ByteString": { - "modified": "2019-07-13T11:30:42.104Z", - "contributors": [ - "RainSlide", - "zhouxu" - ] - }, - "Web/API/CDATASection": { - "modified": "2020-10-15T21:50:11.923Z", - "contributors": [ - "RainSlide", - "caoruiy" - ] - }, - "Web/API/CSS": { - "modified": "2020-10-15T21:34:37.289Z", - "contributors": [ - "EbeRybDI", - "sqhtiamo", - "dsphper", - "chenckang" - ] - }, - "Web/API/CSS/escape": { - "modified": "2019-03-18T21:43:01.457Z", - "contributors": [ - "yuyx91" - ] - }, - "Web/API/CSS/factory_functions": { - "modified": "2020-10-15T22:34:32.125Z", - "contributors": [ - "EbeRybDI" - ] - }, - "Web/API/CSS/supports": { - "modified": "2019-03-23T22:11:58.818Z", - "contributors": [ - "zhangchen", - "ElliottZheng", - "jnlong", - "caoweiju", - "xgqfrms-GitHub" - ] - }, - "Web/API/CSSConditionRule": { - "modified": "2020-10-15T22:10:11.977Z", - "contributors": [ - "Fols" - ] - }, - "Web/API/CSSGroupingRule": { - "modified": "2020-10-15T22:10:10.946Z", - "contributors": [ - "RainSlide", - "Fols" - ] - }, - "Web/API/CSSMathSum": { - "modified": "2020-10-15T22:20:29.886Z", - "contributors": [ - "liruiqi" - ] - }, - "Web/API/CSSMatrix": { - "modified": "2019-03-23T22:20:22.410Z", - "contributors": [ - "kameii" - ] - }, - "Web/API/CSSMediaRule": { - "modified": "2020-10-15T21:15:06.065Z", - "contributors": [ - "Carllllo", - "RainSlide", - "laiiihz", - "xgqfrms-GitHub", - "fscholz", - "teoli", - "ziyunfei", - "Anonymous" - ] - }, - "Web/API/CSSRule": { - "modified": "2020-10-19T22:14:52.445Z", - "contributors": [ - "lastVigo", - "RainSlide", - "ladcheng", - "fscholz", - "teoli", - "ziyunfei" - ] - }, - "Web/API/CSSRule/cssText": { - "modified": "2019-03-24T00:16:15.650Z", - "contributors": [ - "teoli", - "arunpandianp", - "ziyunfei" - ] - }, - "Web/API/CSSRule/parentStyleSheet": { - "modified": "2019-03-23T22:52:28.089Z", - "contributors": [ - "aki" - ] - }, - "Web/API/CSSRuleList": { - "modified": "2020-10-15T21:33:24.408Z", - "contributors": [ - "RainSlide", - "Twiknight", - "helloguangxue" - ] - }, - "Web/API/CSSStyleDeclaration": { - "modified": "2020-10-15T21:34:33.306Z", - "contributors": [ - "ZouYj", - "RainSlide", - "xgqfrms-GitHub", - "chenckang" - ] - }, - "Web/API/CSSStyleDeclaration/getPropertyCSSValue": { - "modified": "2020-10-15T21:54:28.282Z", - "contributors": [ - "Carllllo", - "xgqfrms-GitHub" - ] - }, - "Web/API/CSSStyleDeclaration/getPropertyPriority": { - "modified": "2019-05-30T04:45:06.340Z", - "contributors": [ - "woniuxingdong", - "Youssef-Belmeskine", - "joey" - ] - }, - "Web/API/CSSStyleDeclaration/getPropertyValue": { - "modified": "2020-10-15T22:00:21.684Z", - "contributors": [ - "Carllllo", - "1900", - "xgqfrms-GitHub", - "lugt" - ] - }, - "Web/API/CSSStyleDeclaration/item": { - "modified": "2019-03-18T21:38:41.817Z", - "contributors": [ - "gnepnaiL-oahZ", - "zhangjialiang" - ] - }, - "Web/API/CSSStyleDeclaration/length": { - "modified": "2019-08-20T08:44:41.760Z", - "contributors": [ - "Hzy0913", - "meiseayoung" - ] - }, - "Web/API/CSSStyleDeclaration/removeProperty": { - "modified": "2019-03-23T22:04:01.509Z", - "contributors": [ - "gnepnaiL-oahZ", - "Ende93", - "wanglin2" - ] - }, - "Web/API/CSSStyleDeclaration/setProperty": { - "modified": "2019-03-23T22:06:05.649Z", - "contributors": [ - "gnepnaiL-oahZ", - "xgqfrms-GitHub", - "meiseayoung" - ] - }, - "Web/API/CSSStyleRule": { - "modified": "2020-10-15T21:06:27.405Z", - "contributors": [ - "RainSlide", - "fscholz", - "teoli", - "ziyunfei" - ] - }, - "Web/API/CSSStyleRule/selectorText": { - "modified": "2019-03-23T23:00:18.938Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/API/CSSStyleRule/style": { - "modified": "2020-10-20T07:51:48.872Z", - "contributors": [ - "lastVigo", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/CSSStyleSheet": { - "modified": "2020-10-15T21:21:35.539Z", - "contributors": [ - "Carllllo", - "RainSlide", - "xgqfrms-GitHub", - "helloguangxue", - "teoli", - "less", - "ziyunfei", - "asmedrano" - ] - }, - "Web/API/CSSStyleSheet/deleteRule": { - "modified": "2019-03-23T23:34:03.241Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/CSSStyleSheet/insertRule": { - "modified": "2020-10-15T21:07:03.349Z", - "contributors": [ - "knightyun", - "WangLeto", - "teoli", - "arunpandianp", - "ziyunfei" - ] - }, - "Web/API/CSSSupportsRule": { - "modified": "2019-03-23T22:41:49.675Z", - "contributors": [ - "yun174long" - ] - }, - "Web/API/CSSValue": { - "modified": "2020-10-15T21:51:31.076Z", - "contributors": [ - "ridiculousjam", - "RainSlide", - "camillalo" - ] - }, - "Web/API/CSSValueList": { - "modified": "2020-10-15T22:16:27.371Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/API/CSSValueList/length": { - "modified": "2020-10-15T22:16:27.316Z", - "contributors": [ - "zhangchen", - "RainSlide" - ] - }, - "Web/API/CSS_Font_Loading_API": { - "modified": "2019-03-23T22:05:45.582Z", - "contributors": [ - "jinnchen" - ] - }, - "Web/API/CSS_Object_Model": { - "modified": "2019-09-27T01:23:09.560Z", - "contributors": [ - "wowill", - "mcgradty", - "teoli" - ] - }, - "Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements": { - "modified": "2019-03-18T20:59:05.764Z", - "contributors": [ - "SphinxKnight", - "zldream1106" - ] - }, - "Web/API/CSS_Object_Model/Using_dynamic_styling_information": { - "modified": "2020-02-23T16:18:55.152Z", - "contributors": [ - "RainSlide", - "hbmakeit" - ] - }, - "Web/API/CSS分页规则": { - "modified": "2020-10-15T22:24:48.715Z", - "contributors": [ - "hongz1125" - ] - }, - "Web/API/Cache": { - "modified": "2019-10-06T23:50:04.011Z", - "contributors": [ - "ShiChenCong", - "francistodo", - "joshchiucn", - "DeepinSC", - "flyingsouthwind", - "Stevenzwzhai", - "maicss", - "ChauMing", - "huaguhzheng", - "xgqfrms-GitHub", - "jpmedley" - ] - }, - "Web/API/Cache/add": { - "modified": "2019-03-23T22:12:02.847Z", - "contributors": [ - "chalecao", - "flyingsouthwind" - ] - }, - "Web/API/Cache/addAll": { - "modified": "2019-03-23T22:12:07.409Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/Cache/delete": { - "modified": "2019-03-23T22:12:12.549Z", - "contributors": [ - "JohannLai", - "flyingsouthwind" - ] - }, - "Web/API/Cache/keys": { - "modified": "2019-03-23T22:25:33.601Z", - "contributors": [ - "holynewbie" - ] - }, - "Web/API/Cache/match": { - "modified": "2020-09-04T07:43:24.730Z", - "contributors": [ - "wensugithub", - "nicodechal", - "xgqfrms-GitHub" - ] - }, - "Web/API/Cache/matchAll": { - "modified": "2020-10-15T22:06:37.255Z", - "contributors": [ - "kkocdko", - "flyingsouthwind" - ] - }, - "Web/API/Cache/put": { - "modified": "2020-10-15T22:06:36.812Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/CacheStorage": { - "modified": "2020-10-15T21:51:08.966Z", - "contributors": [ - "zhangchen", - "flyingsouthwind", - "fedwatch" - ] - }, - "Web/API/CacheStorage/delete": { - "modified": "2019-03-23T22:09:54.494Z", - "contributors": [ - "flyingsouthwind", - "liandyy" - ] - }, - "Web/API/CacheStorage/has": { - "modified": "2019-03-18T21:45:38.642Z", - "contributors": [ - "flyingsouthwind", - "ObooChin" - ] - }, - "Web/API/CacheStorage/keys": { - "modified": "2019-03-18T21:36:44.945Z", - "contributors": [ - "flyingsouthwind", - "Xarrow" - ] - }, - "Web/API/CacheStorage/match": { - "modified": "2020-10-15T22:04:02.546Z", - "contributors": [ - "flyingsouthwind", - "Xarrow", - "kuroikenshi" - ] - }, - "Web/API/CacheStorage/open": { - "modified": "2020-10-15T22:06:35.892Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/CanvasCaptureMediaStream": { - "modified": "2019-03-18T21:16:31.622Z", - "contributors": [ - "scplay" - ] - }, - "Web/API/CanvasGradient": { - "modified": "2019-03-23T23:07:24.849Z", - "contributors": [ - "Sebastianz", - "cuixiping" - ] - }, - "Web/API/CanvasGradient/addColorStop": { - "modified": "2019-06-26T03:43:18.483Z", - "contributors": [ - "roronoazoro111", - "Sebastianz", - "teoli", - "cuixiping" - ] - }, - "Web/API/CanvasImageSource": { - "modified": "2019-03-23T22:53:01.774Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasPattern": { - "modified": "2019-03-23T23:07:28.227Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/API/CanvasPattern/setTransform": { - "modified": "2019-03-23T22:53:00.924Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D": { - "modified": "2020-10-15T21:25:33.230Z", - "contributors": [ - "xgl", - "Yayure", - "lzpong", - "Runner2017", - "ice-i-snow", - "chliuqi", - "teoli", - "jack_chen" - ] - }, - "Web/API/CanvasRenderingContext2D/addHitRegion": { - "modified": "2020-05-08T12:57:25.872Z", - "contributors": [ - "Yayure", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/arc": { - "modified": "2019-09-29T12:06:14.549Z", - "contributors": [ - "jastovi", - "ice-i-snow", - "chliuqi" - ] - }, - "Web/API/CanvasRenderingContext2D/arcTo": { - "modified": "2019-04-30T05:22:45.802Z", - "contributors": [ - "lzpong", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/beginPath": { - "modified": "2019-03-23T22:57:21.891Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/bezierCurveTo": { - "modified": "2019-04-30T04:01:07.504Z", - "contributors": [ - "Ende93", - "ice-i-snow", - "ziyunfei", - "fscholz" - ] - }, - "Web/API/CanvasRenderingContext2D/canvas": { - "modified": "2020-10-15T21:34:07.928Z", - "contributors": [ - "zhangchen", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/clearHitRegions": { - "modified": "2020-05-08T13:01:10.208Z", - "contributors": [ - "Yayure", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/clearRect": { - "modified": "2020-11-08T22:22:57.995Z", - "contributors": [ - "lastVigo", - "laampui", - "42", - "WhiteMind", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/clip": { - "modified": "2019-03-23T22:57:13.006Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/closePath": { - "modified": "2019-03-23T22:57:07.110Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/createImageData": { - "modified": "2020-10-15T21:34:37.529Z", - "contributors": [ - "zhangchen", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/createLinearGradient": { - "modified": "2020-11-09T01:58:06.708Z", - "contributors": [ - "lastVigo", - "ice-i-snow", - "teoli", - "cuixiping" - ] - }, - "Web/API/CanvasRenderingContext2D/createPattern": { - "modified": "2019-03-23T23:07:28.074Z", - "contributors": [ - "jihonghai", - "ice-i-snow", - "teoli", - "cuixiping" - ] - }, - "Web/API/CanvasRenderingContext2D/createRadialGradient": { - "modified": "2020-12-04T08:28:46.036Z", - "contributors": [ - "BuluGuy", - "joenil", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/currentTransform": { - "modified": "2019-03-23T22:58:40.595Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/direction": { - "modified": "2020-10-15T21:34:10.593Z", - "contributors": [ - "Yayure", - "LiebeU", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/drawFocusIfNeeded": { - "modified": "2020-10-15T21:35:33.867Z", - "contributors": [ - "laampui", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/drawImage": { - "modified": "2020-10-15T21:35:36.993Z", - "contributors": [ - "Yayure", - "GloryWong", - "zhangchen", - "zhzh5724", - "Serifx", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/drawWidgetAsOnScreen": { - "modified": "2019-03-23T22:24:47.226Z", - "contributors": [ - "teoli", - "YeClimEric" - ] - }, - "Web/API/CanvasRenderingContext2D/drawWindow": { - "modified": "2020-11-07T01:40:12.260Z", - "contributors": [ - "liguorain", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/ellipse": { - "modified": "2020-10-15T21:36:26.633Z", - "contributors": [ - "laampui", - "lzpong", - "leunpha", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/fill": { - "modified": "2019-03-23T22:55:31.940Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/fillRect": { - "modified": "2020-11-08T23:17:01.145Z", - "contributors": [ - "lastVigo", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/fillStyle": { - "modified": "2020-10-15T21:34:08.542Z", - "contributors": [ - "Yayure", - "Sebastianz", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/fillText": { - "modified": "2020-06-16T00:15:25.757Z", - "contributors": [ - "sukura9527", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/filter": { - "modified": "2019-03-23T22:58:31.425Z", - "contributors": [ - "Sebastianz", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/font": { - "modified": "2020-10-15T21:34:18.884Z", - "contributors": [ - "Yayure", - "zhangchen", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/getImageData": { - "modified": "2020-10-15T21:36:49.529Z", - "contributors": [ - "laampui", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/getLineDash": { - "modified": "2020-10-15T21:36:51.652Z", - "contributors": [ - "Yayure", - "windyao", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/getTransform": { - "modified": "2020-10-15T22:31:29.938Z", - "contributors": [ - "cocoon98", - "laampui" - ] - }, - "Web/API/CanvasRenderingContext2D/globalAlpha": { - "modified": "2019-03-23T22:58:10.210Z", - "contributors": [ - "Marco_dev", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/globalCompositeOperation": { - "modified": "2020-10-15T21:34:14.938Z", - "contributors": [ - "Yayure", - "xgqfrms-GitHub", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/imageSmoothingEnabled": { - "modified": "2020-10-15T21:34:13.734Z", - "contributors": [ - "Yayure", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/imageSmoothingQuality": { - "modified": "2019-03-23T22:09:42.922Z", - "contributors": [ - "gabyliu" - ] - }, - "Web/API/CanvasRenderingContext2D/isPointInPath": { - "modified": "2019-03-23T22:59:01.497Z", - "contributors": [ - "ice-i-snow", - "MoltBoy" - ] - }, - "Web/API/CanvasRenderingContext2D/isPointInStroke": { - "modified": "2019-03-23T22:59:01.817Z", - "contributors": [ - "ice-i-snow", - "MoltBoy" - ] - }, - "Web/API/CanvasRenderingContext2D/lineCap": { - "modified": "2019-03-23T22:58:12.808Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/lineDashOffset": { - "modified": "2020-10-15T21:34:14.904Z", - "contributors": [ - "Yayure", - "hhxxhg", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/lineJoin": { - "modified": "2019-03-23T22:58:14.025Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/lineTo": { - "modified": "2019-03-23T22:54:01.738Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/lineWidth": { - "modified": "2020-10-15T21:34:14.942Z", - "contributors": [ - "zhangchen", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/measureText": { - "modified": "2020-10-15T21:36:58.510Z", - "contributors": [ - "zhangchen", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/miterLimit": { - "modified": "2019-03-23T22:58:11.735Z", - "contributors": [ - "shaonq", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/moveTo": { - "modified": "2019-03-23T22:54:04.260Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/putImageData": { - "modified": "2019-03-23T22:53:54.868Z", - "contributors": [ - "aimiy", - "teoli", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/quadraticCurveTo": { - "modified": "2020-10-15T21:37:03.973Z", - "contributors": [ - "Yayure", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/rect": { - "modified": "2019-03-23T22:53:31.279Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/removeHitRegion": { - "modified": "2020-05-08T13:03:28.767Z", - "contributors": [ - "Yayure", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/resetTransform": { - "modified": "2019-03-23T22:53:40.584Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/restore": { - "modified": "2019-04-30T05:25:42.562Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/rotate": { - "modified": "2019-05-27T23:49:33.260Z", - "contributors": [ - "Ray-Eldath", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/save": { - "modified": "2019-03-23T22:53:29.655Z", - "contributors": [ - "jastovi", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/scale": { - "modified": "2020-11-22T03:12:30.867Z", - "contributors": [ - "BuluGuy", - "laampui", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/scrollPathIntoView": { - "modified": "2019-03-23T22:53:40.759Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/setLineDash": { - "modified": "2020-10-15T21:37:04.054Z", - "contributors": [ - "Yayure", - "Plearner", - "zhangchen", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/setTransform": { - "modified": "2020-10-15T21:37:04.554Z", - "contributors": [ - "laampui", - "Yayure", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/shadowBlur": { - "modified": "2019-03-23T22:58:21.967Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/shadowColor": { - "modified": "2019-03-23T22:58:22.712Z", - "contributors": [ - "Sebastianz", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/shadowOffsetX": { - "modified": "2019-03-23T22:58:08.138Z", - "contributors": [ - "jihonghai", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/shadowOffsetY": { - "modified": "2019-03-23T22:58:12.327Z", - "contributors": [ - "jihonghai", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/stroke": { - "modified": "2019-03-23T22:53:38.687Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/strokeRect": { - "modified": "2020-10-15T21:37:04.061Z", - "contributors": [ - "zhangchen", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/strokeStyle": { - "modified": "2020-10-15T21:34:13.691Z", - "contributors": [ - "Yayure", - "Sebastianz", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/strokeText": { - "modified": "2019-03-23T22:53:28.850Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/textAlign": { - "modified": "2019-04-29T23:54:41.056Z", - "contributors": [ - "moker-monkey", - "Jiang-Xuan", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/textBaseline": { - "modified": "2020-10-15T21:34:13.324Z", - "contributors": [ - "Yayure", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/transform": { - "modified": "2019-11-01T00:02:12.741Z", - "contributors": [ - "gengjiawen", - "Junking", - "ice-i-snow" - ] - }, - "Web/API/CanvasRenderingContext2D/translate": { - "modified": "2020-01-06T06:35:00.727Z", - "contributors": [ - "ThisIszas", - "ice-i-snow" - ] - }, - "Web/API/Canvas_API": { - "modified": "2019-11-19T10:02:58.455Z", - "contributors": [ - "oceans42", - "Mookiepiece", - "ridiculousjam", - "yinyihui", - "jianxin-zhang", - "rlog", - "ArcherGrey", - "xgqfrms-GitHub", - "youmyyou", - "YuriTu", - "fscholz", - "ziyunfei", - "cuixiping", - "bqdove", - "LinusYu", - "ethertank", - "leegorous" - ] - }, - "Web/API/Canvas_API/A_basic_ray-caster": { - "modified": "2019-03-23T23:46:06.908Z", - "contributors": [ - "hhxxhg", - "ScorpioCat", - "Lostangle-M", - "NNNaix", - "YeClimEric", - "ziyunfei", - "Blabla cn" - ] - }, - "Web/API/Canvas_API/Drawing_graphics_with_canvas": { - "modified": "2019-03-23T23:20:14.159Z", - "contributors": [ - "ziyunfei", - "wanglingzhi" - ] - }, - "Web/API/Canvas_API/Manipulating_video_using_canvas": { - "modified": "2019-03-18T20:39:44.141Z", - "contributors": [ - "Jogiter", - "xhlsrj", - "codingwangxiansen" - ] - }, - "Web/API/Canvas_API/Tutorial": { - "modified": "2020-11-22T01:08:04.656Z", - "contributors": [ - "BuluGuy", - "Ada.H", - "AllanXYZ", - "junshine", - "jianxin-zhang", - "Oraice", - "wth", - "AzureRay", - "Jeery", - "xgqfrms", - "Ende93", - "ziyunfei", - "xcffl", - "arz", - "fiftyk" - ] - }, - "Web/API/Canvas_API/Tutorial/Advanced_animations": { - "modified": "2020-05-11T03:33:21.428Z", - "contributors": [ - "Asaki-M", - "youyouzh", - "fuchao2012", - "287207951", - "PaperFlu", - "Starrhds", - "YeClimEric", - "wyh888", - "ziyunfei", - "lcxfs1991", - "jasonworg" - ] - }, - "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors": { - "modified": "2020-11-20T08:31:05.823Z", - "contributors": [ - "BuluGuy", - "lovefengruoqing", - "rulanfenghua", - "hhxxhg", - "litmonw", - "Miscol", - "Silencesnow", - "summerdb", - "loraine", - "codingwangxiansen", - "Ende93", - "fscholz", - "summeryuan", - "ziyunfei", - "Uliyas_Fan", - "zhongsheng", - "吕辛未", - "leegorous", - "Chinese_XU", - "Qq759" - ] - }, - "Web/API/Canvas_API/Tutorial/Basic_animations": { - "modified": "2020-04-07T03:56:37.395Z", - "contributors": [ - "Ende93", - "hhxxhg", - "Lxio", - "qingxo", - "HansZhang", - "The-End-Hero", - "lxang", - "likunyan", - "qiyusjtu", - "Qing", - "fscholz", - "ziyunfei", - "YanLing", - "leegorous" - ] - }, - "Web/API/Canvas_API/Tutorial/Basic_usage": { - "modified": "2019-09-04T03:52:15.627Z", - "contributors": [ - "imbant", - "imwangpan", - "Fwu", - "pujiaxun", - "maple5233", - "TaylorPzreal", - "carlosqin", - "Cocoa", - "teoli", - "lon", - "Ende93", - "MarkoCen", - "fscholz", - "ziyunfei", - "wanglingzhi" - ] - }, - "Web/API/Canvas_API/Tutorial/Compositing": { - "modified": "2019-03-18T21:11:43.934Z", - "contributors": [ - "JinRong.Yang", - "zhangchen", - "ParkerFiend", - "fengyong160", - "Akimyou", - "zhengxinxin", - "crazy_snow", - "fscholz", - "ziyunfei", - "zhongsheng", - "leegorous" - ] - }, - "Web/API/Canvas_API/Tutorial/Compositing/Example": { - "modified": "2019-03-23T22:08:51.586Z", - "contributors": [ - "lakeinchina", - "JinRong.Yang", - "zhangchen", - "Iwakura-Lain", - "blackmomo", - "Akimyou" - ] - }, - "Web/API/Canvas_API/Tutorial/Drawing_shapes": { - "modified": "2020-11-20T08:52:01.256Z", - "contributors": [ - "BuluGuy", - "Kafuu_Chino", - "lovefengruoqing", - "rulanfenghua", - "luojia", - "zhuangyin", - "xuziang111", - "hhxxhg", - "YellowTulipShow", - "fralonra", - "litmonw", - "reserveword", - "SphinxKnight", - "bleedkaga", - "hnliuzesen", - "qq1026433705", - "Gavin_Gu", - "monsterooo", - "zhengxinxin", - "JMdner", - "XueweiZheng", - "rufeng.zhou", - "dongyu_-_", - "loraine", - "zhe13", - "teoli", - "HansenZhao", - "whrhrr", - "WarriorWu", - "JerryChin", - "Ende93", - "fscholz", - "kylinv", - "ziyunfei", - "panxianhai", - "gtlbupt", - "JunyueCao", - "luo-xuefei", - "wanglingzhi" - ] - }, - "Web/API/Canvas_API/Tutorial/Drawing_text": { - "modified": "2020-11-20T04:51:26.658Z", - "contributors": [ - "BuluGuy", - "hhxxhg", - "mutoe", - "loraine", - "whrhrr", - "Roscoe93", - "ziyunfei", - "jasonworg" - ] - }, - "Web/API/Canvas_API/Tutorial/Finale": { - "modified": "2019-03-18T21:11:41.948Z", - "contributors": [ - "ZeroJsus", - "3544357727", - "crazy_snow", - "The-End-Hero", - "wth", - "Dengjiansheng", - "ziyunfei", - "jasonworg" - ] - }, - "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility": { - "modified": "2019-03-18T21:11:42.305Z", - "contributors": [ - "fenyu", - "bluelifeleer", - "May", - "luojia", - "codingwangxiansen", - "ziyunfei", - "Sheppy", - "fiona23", - "jasonworg" - ] - }, - "Web/API/Canvas_API/Tutorial/Optimizing_canvas": { - "modified": "2020-05-09T13:07:09.942Z", - "contributors": [ - "Yayure", - "zhangchen", - "luojia", - "ziyunfei", - "lcxfs1991", - "jasonworg" - ] - }, - "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas": { - "modified": "2020-11-24T06:36:52.381Z", - "contributors": [ - "BuluGuy", - "assmdx", - "ttttttssssss", - "jimwong", - "WimZhai", - "fbambi", - "CharlotteChow", - "Z-imp", - "yinsang", - "Starrhds", - "YeClimEric", - "Lenville", - "ziyunfei", - "lcxfs1991", - "jasonworg" - ] - }, - "Web/API/Canvas_API/Tutorial/Transformations": { - "modified": "2020-10-19T23:56:41.310Z", - "contributors": [ - "WindStormrage", - "kongkgng", - "Ende93", - "purp1e", - "rulanfenghua", - "andylala-Veneno", - "mliqian", - "youyouzh", - "crazy_snow", - "chengkai", - "Dengjiansheng", - "loraine", - "fscholz", - "ziyunfei", - "zhongsheng", - "vinqon", - "YanLing", - "leegorous" - ] - }, - "Web/API/Canvas_API/Tutorial/Using_images": { - "modified": "2020-11-20T04:25:04.207Z", - "contributors": [ - "BuluGuy", - "chenzesam", - "chrisdavidmills", - "SphinxKnight", - "jvua", - "fanerge", - "xuexiongyao", - "summerdb", - "loraine", - "teoli", - "fscholz", - "ziyunfei", - "Nothing90", - "godluck", - "gtlbupt", - "JunyueCao", - "leegorous", - "Mgjbot", - "Yunmo" - ] - }, - "Web/API/ChannelMergerNode": { - "modified": "2020-10-15T22:17:55.871Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/ChannelMergerNode/ChannelMergerNode": { - "modified": "2020-10-15T22:17:54.877Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/Channel_Messaging_API": { - "modified": "2020-10-15T22:15:25.116Z", - "contributors": [ - "WangLeto" - ] - }, - "Web/API/Channel_Messaging_API/使用_channel_messaging": { - "modified": "2020-10-15T22:33:04.421Z", - "contributors": [ - "cheiron" - ] - }, - "Web/API/CharacterData": { - "modified": "2019-03-23T23:09:13.805Z", - "contributors": [ - "aoiu", - "AlexChao" - ] - }, - "Web/API/ChildNode": { - "modified": "2020-10-15T21:30:05.058Z", - "contributors": [ - "XiangHongAi", - "RainSlide", - "ZacharyZhang90S", - "zhangchen", - "ifredom", - "xgqfrms-GitHub", - "jiahui", - "AlexChao" - ] - }, - "Web/API/ChildNode/after": { - "modified": "2020-10-15T21:51:08.472Z", - "contributors": [ - "Ende93", - "Cattla" - ] - }, - "Web/API/ChildNode/before": { - "modified": "2019-03-23T22:12:22.842Z", - "contributors": [ - "caoweiju" - ] - }, - "Web/API/ChildNode/remove": { - "modified": "2020-10-15T21:27:27.352Z", - "contributors": [ - "RainSlide", - "iSmartSV", - "duola8789", - "pasturn", - "Ende93", - "xgqfrms-GitHub", - "ceverytime", - "teoli", - "khalid32", - "ziyunfei", - "Darrel.Hsu" - ] - }, - "Web/API/ChildNode/replaceWith": { - "modified": "2020-10-15T21:56:06.625Z", - "contributors": [ - "ecnelises", - "SphinxKnight", - "wzx", - "VictorDu" - ] - }, - "Web/API/Client": { - "modified": "2019-03-23T22:16:43.346Z", - "contributors": [ - "yangwr", - "chrisdavidmills" - ] - }, - "Web/API/Client/postMessage": { - "modified": "2019-05-30T12:39:54.653Z", - "contributors": [ - "prayercc", - "xgqfrms-GitHub" - ] - }, - "Web/API/Clients": { - "modified": "2020-10-15T22:07:14.323Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/Clients/claim": { - "modified": "2020-10-15T22:07:13.405Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/Clients/get": { - "modified": "2020-10-15T22:07:12.356Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/Clients/matchAll": { - "modified": "2020-10-15T22:07:13.535Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/Clients/openWindow": { - "modified": "2020-10-15T22:07:13.353Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/Clipboard": { - "modified": "2020-10-15T22:01:07.201Z", - "contributors": [ - "ReiJi", - "alanhg", - "Carllllo", - "RainSlide", - "cpdyj" - ] - }, - "Web/API/Clipboard/read": { - "modified": "2020-10-15T22:22:25.001Z", - "contributors": [ - "jason-guo" - ] - }, - "Web/API/Clipboard/readText": { - "modified": "2020-10-15T22:22:24.913Z", - "contributors": [ - "jason-guo" - ] - }, - "Web/API/Clipboard/write": { - "modified": "2020-10-15T22:17:31.613Z", - "contributors": [ - "maoyumaoxun" - ] - }, - "Web/API/Clipboard/writeText": { - "modified": "2020-10-15T22:20:36.863Z", - "contributors": [ - "jason-guo", - "hughfenghen" - ] - }, - "Web/API/ClipboardEvent": { - "modified": "2019-06-12T04:35:14.599Z", - "contributors": [ - "xgqfrms", - "fscholz", - "holynewbie" - ] - }, - "Web/API/ClipboardEvent/ClipboardEvent": { - "modified": "2020-10-15T21:46:38.488Z", - "contributors": [ - "Carllllo", - "fscholz", - "holynewbie" - ] - }, - "Web/API/ClipboardEvent/clipboardData": { - "modified": "2020-10-15T21:46:38.585Z", - "contributors": [ - "Carllllo", - "fscholz", - "maicss", - "holynewbie" - ] - }, - "Web/API/ClipboardItem": { - "modified": "2020-11-02T05:47:54.588Z", - "contributors": [ - "Rumyra" - ] - }, - "Web/API/Clipboard_API": { - "modified": "2020-10-15T22:00:45.292Z", - "contributors": [ - "Carllllo", - "RainSlide", - "1v9", - "ziyunfei", - "Charley-Hsu" - ] - }, - "Web/API/CloseEvent": { - "modified": "2020-08-03T03:54:35.388Z", - "contributors": [ - "WangXBruc", - "cissoid" - ] - }, - "Web/API/Comment": { - "modified": "2020-10-15T21:30:10.232Z", - "contributors": [ - "RainSlide", - "AshfaqHossain", - "AlexChao" - ] - }, - "Web/API/Comment/Comment": { - "modified": "2020-10-15T22:21:35.214Z", - "contributors": [ - "lifankohome" - ] - }, - "Web/API/CompositionEvent": { - "modified": "2020-10-15T22:30:04.560Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/Console": { - "modified": "2020-11-05T03:30:21.247Z", - "contributors": [ - "wuguichiroumeiyou", - "R2h1", - "Astroleander", - "xuzijie1995", - "lifankohome", - "RainSlide", - "yoodz", - "vaynewang", - "puppyer", - "xgqfrms-GitHub", - "fuchao2012", - "hefengxian", - "micblo", - "artificial", - "jerryzjq", - "fghpdf", - "houguang", - "jinboyigu", - "fortruth", - "jiereal" - ] - }, - "Web/API/Console/assert": { - "modified": "2020-10-15T21:49:40.751Z", - "contributors": [ - "zhangchen", - "shiyingyan", - "gaoyia", - "xgqfrms-GitHub", - "ZhangKaiqiang" - ] - }, - "Web/API/Console/clear": { - "modified": "2020-01-12T03:19:48.000Z", - "contributors": [ - "853419196", - "ZhangKaiqiang" - ] - }, - "Web/API/Console/count": { - "modified": "2019-08-15T04:00:38.089Z", - "contributors": [ - "teemoooo", - "gaowhen" - ] - }, - "Web/API/Console/countReset": { - "modified": "2020-10-15T22:08:08.444Z", - "contributors": [ - "Paapaapa", - "807573515" - ] - }, - "Web/API/Console/debug": { - "modified": "2020-10-15T22:15:26.417Z", - "contributors": [ - "hefang" - ] - }, - "Web/API/Console/dir": { - "modified": "2019-10-08T07:08:14.257Z", - "contributors": [ - "SphinxKnight", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Console/dirxml": { - "modified": "2019-03-23T22:11:46.371Z", - "contributors": [ - "zzw918" - ] - }, - "Web/API/Console/error": { - "modified": "2019-08-15T04:02:05.738Z", - "contributors": [ - "pluwen", - "kameii" - ] - }, - "Web/API/Console/group": { - "modified": "2019-03-24T00:18:26.661Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Console/groupCollapsed": { - "modified": "2019-03-24T00:18:28.377Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Console/groupEnd": { - "modified": "2019-03-18T21:46:40.075Z", - "contributors": [ - "hhxxhg", - "luohe" - ] - }, - "Web/API/Console/info": { - "modified": "2020-02-02T00:13:13.877Z", - "contributors": [ - "Headog", - "tsingwong", - "Jaanai-Ewain", - "yogoshary" - ] - }, - "Web/API/Console/log": { - "modified": "2020-07-27T04:01:25.975Z", - "contributors": [ - "alan10332000", - "suvyme", - "pluwen", - "ddtyjmyjm", - "yuyongjun123", - "zhouxu", - "teoli", - "charlie", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Console/profile": { - "modified": "2019-03-18T21:41:07.871Z", - "contributors": [ - "clwm01" - ] - }, - "Web/API/Console/profileEnd": { - "modified": "2020-10-15T22:04:42.916Z", - "contributors": [ - "JQ_Chan" - ] - }, - "Web/API/Console/table": { - "modified": "2020-10-15T21:54:27.285Z", - "contributors": [ - "RainSlide", - "dondevi", - "eeeeeeeason", - "zzw918" - ] - }, - "Web/API/Console/time": { - "modified": "2020-10-15T21:27:17.192Z", - "contributors": [ - "zhangchen", - "hhxxhg", - "pixiu", - "teoli", - "khalid32", - "freemen" - ] - }, - "Web/API/Console/timeEnd": { - "modified": "2020-10-15T21:50:04.648Z", - "contributors": [ - "luisleee", - "hhxxhg", - "Dcfm", - "regiondavid" - ] - }, - "Web/API/Console/timeLog": { - "modified": "2020-10-15T22:16:19.657Z", - "contributors": [ - "lifankohome", - "Reaper622" - ] - }, - "Web/API/Console/timeStamp": { - "modified": "2019-03-23T22:08:57.552Z", - "contributors": [ - "tsingwong", - "ershing" - ] - }, - "Web/API/Console/trace": { - "modified": "2020-10-15T21:04:54.511Z", - "contributors": [ - "zhangchen", - "airt", - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Console/warn": { - "modified": "2019-03-23T22:12:15.122Z", - "contributors": [ - "pluwen", - "choukin" - ] - }, - "Web/API/Console_API": { - "modified": "2020-10-15T22:22:31.495Z", - "contributors": [ - "kjyzly" - ] - }, - "Web/API/ConvolverNode": { - "modified": "2020-10-15T22:31:51.202Z", - "contributors": [ - "Kevin0z0" - ] - }, - "Web/API/Credential_Management_API": { - "modified": "2019-03-18T21:01:01.975Z", - "contributors": [ - "fscholz", - "Cuzz" - ] - }, - "Web/API/CredentialsContainer": { - "modified": "2019-03-18T21:43:44.954Z", - "contributors": [ - "nDos" - ] - }, - "Web/API/Crypto": { - "modified": "2020-10-15T21:45:02.884Z", - "contributors": [ - "zhangchen", - "Taoja", - "zbinlin" - ] - }, - "Web/API/Crypto/subtle": { - "modified": "2019-03-23T22:35:29.902Z", - "contributors": [ - "Taoja", - "zbinlin" - ] - }, - "Web/API/CryptoKey": { - "modified": "2019-03-23T22:08:25.848Z", - "contributors": [ - "Dafrok" - ] - }, - "Web/API/CustomElementRegistry": { - "modified": "2020-10-15T21:54:33.205Z", - "contributors": [ - "RainSlide", - "zhangchen", - "SphinxKnight", - "Ende93", - "fsx950223", - "xrr2016" - ] - }, - "Web/API/CustomElementRegistry/define": { - "modified": "2020-10-15T21:57:09.008Z", - "contributors": [ - "yemao", - "zhangchen", - "SphinxKnight", - "fsx950223" - ] - }, - "Web/API/CustomElementRegistry/get": { - "modified": "2020-10-15T22:04:59.389Z", - "contributors": [ - "bluetomlee" - ] - }, - "Web/API/CustomElementRegistry/upgrade": { - "modified": "2020-10-15T22:18:47.063Z", - "contributors": [ - "bei6", - "yemao" - ] - }, - "Web/API/CustomElementRegistry/whenDefined": { - "modified": "2020-10-15T22:05:00.208Z", - "contributors": [ - "soon", - "bluetomlee" - ] - }, - "Web/API/CustomEvent": { - "modified": "2020-10-15T21:05:49.982Z", - "contributors": [ - "fscholz", - "whispererWJ", - "rambo-panda", - "lilopusic", - "carllx", - "zhongming2013", - "teoli", - "ziyunfei" - ] - }, - "Web/API/CustomEvent/CustomEvent": { - "modified": "2020-10-15T21:35:33.361Z", - "contributors": [ - "fscholz", - "luyouxin84", - "rambo-panda", - "Sebastianz", - "RIO-LI", - "yulifu" - ] - }, - "Web/API/CustomEvent/detail": { - "modified": "2020-10-15T22:06:50.968Z", - "contributors": [ - "Bayes" - ] - }, - "Web/API/CustomEvent/initCustomEvent": { - "modified": "2019-03-23T22:31:56.595Z", - "contributors": [ - "zhroeqqtw", - "superwf" - ] - }, - "Web/API/DOMError": { - "modified": "2019-03-18T21:38:03.058Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/DOMException": { - "modified": "2020-10-15T22:03:22.150Z", - "contributors": [ - "Jack.Works", - "RainSlide", - "Pada" - ] - }, - "Web/API/DOMException/DOMException": { - "modified": "2019-03-18T21:38:09.420Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/DOMException/code": { - "modified": "2020-10-15T22:11:38.028Z", - "contributors": [ - "ch4o5" - ] - }, - "Web/API/DOMHighResTimeStamp": { - "modified": "2020-09-14T00:43:50.365Z", - "contributors": [ - "cumt-robin", - "suvyme", - "HiWayne", - "xgqfrms-GitHub" - ] - }, - "Web/API/DOMImplementation": { - "modified": "2019-03-23T23:11:23.058Z", - "contributors": [ - "aronlee", - "xuanhun", - "Cribug8080", - "pantao", - "AshfaqHossain", - "less" - ] - }, - "Web/API/DOMImplementation/createDocument": { - "modified": "2020-10-15T21:55:18.276Z", - "contributors": [ - "absudra", - "mySoul", - "Cribug8080" - ] - }, - "Web/API/DOMImplementation/createDocumentType": { - "modified": "2020-10-15T22:20:57.241Z", - "contributors": [ - "ridiculousjam" - ] - }, - "Web/API/DOMImplementation/createHTMLDocument": { - "modified": "2019-03-23T22:36:51.397Z", - "contributors": [ - "wbamberg", - "teoli", - "ziyunfei" - ] - }, - "Web/API/DOMImplementation/hasFeature": { - "modified": "2019-03-23T23:26:58.653Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/DOMLocator": { - "modified": "2019-03-23T22:08:16.598Z", - "contributors": [ - "ResJay" - ] - }, - "Web/API/DOMMatrix": { - "modified": "2019-03-23T22:20:29.136Z", - "contributors": [ - "kameii" - ] - }, - "Web/API/DOMParser": { - "modified": "2020-10-15T21:07:21.384Z", - "contributors": [ - "RainSlide", - "zhangchen", - "xgqfrms-GitHub", - "Frantic1048", - "teoli", - "ziyunfei" - ] - }, - "Web/API/DOMParser/DOMParser": { - "modified": "2019-07-09T00:15:09.472Z", - "contributors": [ - "leeleee" - ] - }, - "Web/API/DOMPoint": { - "modified": "2020-10-15T22:10:11.164Z", - "contributors": [ - "Fols" - ] - }, - "Web/API/DOMPoint/DOMPoint": { - "modified": "2020-10-15T22:28:28.429Z", - "contributors": [ - "Humilitas" - ] - }, - "Web/API/DOMPoint/w": { - "modified": "2020-10-15T22:28:28.018Z", - "contributors": [ - "Humilitas" - ] - }, - "Web/API/DOMPoint/x": { - "modified": "2020-10-15T22:28:29.830Z", - "contributors": [ - "Humilitas" - ] - }, - "Web/API/DOMPoint/y": { - "modified": "2020-10-15T22:28:29.779Z", - "contributors": [ - "Humilitas" - ] - }, - "Web/API/DOMPoint/z": { - "modified": "2020-10-15T22:28:28.131Z", - "contributors": [ - "Humilitas" - ] - }, - "Web/API/DOMQuad": { - "modified": "2020-10-15T22:10:11.306Z", - "contributors": [ - "Fols" - ] - }, - "Web/API/DOMRect": { - "modified": "2020-10-15T22:26:55.420Z", - "contributors": [ - "SunXinFei", - "mokunshao" - ] - }, - "Web/API/DOMRect/DOMRect": { - "modified": "2020-10-15T22:26:56.490Z", - "contributors": [ - "mokunshao" - ] - }, - "Web/API/DOMRectReadOnly": { - "modified": "2020-10-15T22:26:56.023Z", - "contributors": [ - "mokunshao" - ] - }, - "Web/API/DOMString": { - "modified": "2019-09-21T03:39:30.024Z", - "contributors": [ - "zhenghuahou", - "xgqfrms-GitHub", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/DOMString/Binary": { - "modified": "2019-07-07T10:35:50.508Z", - "contributors": [ - "zhangchen", - "imgss", - "ArtemisZ" - ] - }, - "Web/API/DOMStringList": { - "modified": "2019-03-23T22:58:47.857Z", - "contributors": [ - "Junjie_Wei" - ] - }, - "Web/API/DOMStringMap": { - "modified": "2020-10-15T21:36:49.400Z", - "contributors": [ - "RainSlide", - "wbamberg", - "ShiJianwen", - "lann1986", - "FredWe" - ] - }, - "Web/API/DOMTimeStamp": { - "modified": "2019-03-18T20:49:17.073Z", - "contributors": [ - "gnepnaiL-oahZ" - ] - }, - "Web/API/DOMTokenList": { - "modified": "2020-10-15T21:30:08.216Z", - "contributors": [ - "Carllllo", - "xcffl", - "fanerge", - "AlexChao" - ] - }, - "Web/API/DOMTokenList/add": { - "modified": "2020-10-15T22:17:33.542Z", - "contributors": [ - "weibangtuo", - "maomao" - ] - }, - "Web/API/DOMTokenList/contains": { - "modified": "2020-10-15T22:29:21.520Z", - "contributors": [ - "weibangtuo" - ] - }, - "Web/API/DOMTokenList/item": { - "modified": "2020-10-15T22:33:55.529Z", - "contributors": [ - "Nothing_bin" - ] - }, - "Web/API/DOMTokenList/keys": { - "modified": "2020-10-15T22:30:19.935Z", - "contributors": [ - "yyfyifan" - ] - }, - "Web/API/DOMTokenList/length": { - "modified": "2020-10-15T22:06:50.988Z", - "contributors": [ - "heycqing" - ] - }, - "Web/API/DOMTokenList/remove": { - "modified": "2020-10-15T22:14:59.310Z", - "contributors": [ - "Excins" - ] - }, - "Web/API/DOMTokenList/replace": { - "modified": "2020-10-15T22:31:08.118Z", - "contributors": [ - "ShiningAsuna" - ] - }, - "Web/API/DOMTokenList/toggle": { - "modified": "2019-05-07T01:02:36.363Z", - "contributors": [ - "ewfian", - "ThomasWhyne", - "xgqfrms-GitHub" - ] - }, - "Web/API/DataTransfer": { - "modified": "2020-10-15T21:36:10.012Z", - "contributors": [ - "HandyCC", - "Carllllo", - "Pada", - "hehe1111", - "Axue", - "TechQuery", - "JohnsonBryant", - "plter", - "ifredom", - "wangxb" - ] - }, - "Web/API/DataTransfer/DataTransfer": { - "modified": "2020-10-15T22:03:06.829Z", - "contributors": [ - "MCCF", - "xuqi" - ] - }, - "Web/API/DataTransfer/clearData": { - "modified": "2019-03-23T22:11:27.717Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/DataTransfer/dropEffect": { - "modified": "2020-10-15T22:16:35.841Z", - "contributors": [ - "qiudongwei", - "Mandy-Tang" - ] - }, - "Web/API/DataTransfer/effectAllowed": { - "modified": "2019-03-23T22:02:47.705Z", - "contributors": [ - "weiqinl" - ] - }, - "Web/API/DataTransfer/files": { - "modified": "2019-03-23T22:02:53.389Z", - "contributors": [ - "weiqinl" - ] - }, - "Web/API/DataTransfer/getData": { - "modified": "2020-10-15T21:52:41.516Z", - "contributors": [ - "Carllllo", - "maicss" - ] - }, - "Web/API/DataTransfer/items": { - "modified": "2020-10-15T22:21:04.177Z", - "contributors": [ - "qiudongwei" - ] - }, - "Web/API/DataTransfer/setData": { - "modified": "2019-03-23T22:16:43.162Z", - "contributors": [ - "xgqfrms-GitHub", - "imnodb", - "maicss" - ] - }, - "Web/API/DataTransfer/setDragImage": { - "modified": "2020-07-28T06:38:49.343Z", - "contributors": [ - "gjc9620", - "weiqinl" - ] - }, - "Web/API/DataTransfer/types": { - "modified": "2019-03-23T22:03:04.937Z", - "contributors": [ - "weiqinl" - ] - }, - "Web/API/DataTransferItem": { - "modified": "2020-07-02T04:26:13.439Z", - "contributors": [ - "yaoyao0127", - "woodenfish" - ] - }, - "Web/API/DataTransferItem/getAsFile": { - "modified": "2020-10-15T22:08:42.184Z", - "contributors": [ - "ty4z2008" - ] - }, - "Web/API/DataTransferItem/getAsString": { - "modified": "2020-10-15T22:31:11.013Z", - "contributors": [ - "yaoyao0127" - ] - }, - "Web/API/DataTransferItem/kind": { - "modified": "2020-10-15T22:15:09.598Z", - "contributors": [ - "ctwteam.club" - ] - }, - "Web/API/DataTransferItem/type": { - "modified": "2020-10-15T22:21:03.147Z", - "contributors": [ - "qiudongwei" - ] - }, - "Web/API/DataTransferItem/webkitGetAsEntry": { - "modified": "2020-10-15T22:21:46.317Z", - "contributors": [ - "7NZ", - "qiufeihong2018" - ] - }, - "Web/API/DataTransferItemList": { - "modified": "2020-10-15T22:21:02.187Z", - "contributors": [ - "qiudongwei" - ] - }, - "Web/API/DataTransferItemList/length": { - "modified": "2020-10-15T22:21:02.592Z", - "contributors": [ - "qiudongwei" - ] - }, - "Web/API/DedicatedWorkerGlobalScope": { - "modified": "2020-10-15T21:51:26.154Z", - "contributors": [ - "RainSlide", - "ts0307", - "Lex.Huang" - ] - }, - "Web/API/Detecting_device_orientation": { - "modified": "2020-10-15T21:21:28.912Z", - "contributors": [ - "Carllllo", - "zwcloud", - "xgqfrms-GitHub", - "ziyunfei", - "fancy", - "princetoad@gmail.com" - ] - }, - "Web/API/DeviceAcceleration": { - "modified": "2019-03-23T22:20:59.019Z", - "contributors": [ - "shuangya" - ] - }, - "Web/API/DeviceLightEvent": { - "modified": "2020-10-15T21:34:11.102Z", - "contributors": [ - "RainSlide", - "Fantastic-Chen", - "fscholz" - ] - }, - "Web/API/DeviceLightEvent/Using_light_events": { - "modified": "2020-10-15T21:34:12.225Z", - "contributors": [ - "RainSlide", - "fskuok" - ] - }, - "Web/API/DeviceMotionEvent": { - "modified": "2020-10-15T21:47:35.974Z", - "contributors": [ - "Carllllo", - "shuangya", - "Hedgehog" - ] - }, - "Web/API/DeviceMotionEvent/DeviceMotionEvent": { - "modified": "2020-10-15T22:17:29.936Z", - "contributors": [ - "greenwheat" - ] - }, - "Web/API/DeviceMotionEvent/acceleration": { - "modified": "2019-03-23T22:21:07.655Z", - "contributors": [ - "shuangya" - ] - }, - "Web/API/DeviceMotionEvent/accelerationIncludingGravity": { - "modified": "2019-03-23T22:21:01.628Z", - "contributors": [ - "Jiang-Xuan", - "shuangya" - ] - }, - "Web/API/DeviceMotionEvent/interval": { - "modified": "2019-03-23T22:21:10.116Z", - "contributors": [ - "shuangya" - ] - }, - "Web/API/DeviceMotionEvent/rotationRate": { - "modified": "2019-03-23T22:20:58.070Z", - "contributors": [ - "shuangya" - ] - }, - "Web/API/DeviceOrientationEvent": { - "modified": "2019-03-23T22:31:17.724Z", - "contributors": [ - "Mrluobo", - "gknpezgssb" - ] - }, - "Web/API/DeviceOrientationEvent/absolute": { - "modified": "2019-03-23T22:17:05.014Z", - "contributors": [ - "greatbug", - "youmyyou" - ] - }, - "Web/API/DeviceOrientationEvent/alpha": { - "modified": "2020-10-15T21:58:08.593Z", - "contributors": [ - "Jack.Works", - "TOKdawn", - "NightingaleM" - ] - }, - "Web/API/DeviceOrientationEvent/beta": { - "modified": "2019-03-18T21:38:34.155Z", - "contributors": [ - "TOKdawn" - ] - }, - "Web/API/DeviceOrientationEvent/gamma": { - "modified": "2019-03-23T22:09:56.370Z", - "contributors": [ - "CGerAJ" - ] - }, - "Web/API/DeviceProximityEvent": { - "modified": "2019-03-18T21:47:06.146Z", - "contributors": [ - "MaxTime" - ] - }, - "Web/API/Document": { - "modified": "2020-10-15T21:04:40.161Z", - "contributors": [ - "bytetown", - "RainSlide", - "nonlimiting", - "785172550", - "Spike-Leung", - "xiongcong", - "Bayes", - "zxsunrise", - "zylyye", - "BillgoXu", - "fsx950223", - "_sollrei", - "auroraeffect", - "liangyj021", - "xinleibird", - "printfalling", - "xgqfrms-GitHub", - "lext", - "wangdapeng1005", - "Soy", - "Ende93", - "teoli", - "jsx", - "less", - "ReyCG_sub", - "ziyunfei", - "Crash", - "TigerSoldier", - "JarodWang" - ] - }, - "Web/API/Document/DOMContentLoaded_event": { - "modified": "2020-10-15T22:18:28.994Z", - "contributors": [ - "baijingfeng" - ] - }, - "Web/API/Document/Document": { - "modified": "2020-10-15T21:58:17.784Z", - "contributors": [ - "RainSlide", - "jaiJia" - ] - }, - "Web/API/Document/URL": { - "modified": "2019-03-24T00:16:22.868Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/adoptNode": { - "modified": "2019-03-23T22:24:33.991Z", - "contributors": [ - "wbamberg", - "caoruiy" - ] - }, - "Web/API/Document/alinkColor": { - "modified": "2019-03-18T20:59:01.745Z", - "contributors": [ - "SphinxKnight", - "ShaocongZheng", - "Hughie", - "Houfeng" - ] - }, - "Web/API/Document/all": { - "modified": "2020-10-15T22:16:14.222Z", - "contributors": [ - "Jack.Works", - "wyhcool" - ] - }, - "Web/API/Document/anchors": { - "modified": "2019-03-24T00:17:56.385Z", - "contributors": [ - "wbamberg", - "Venus14", - "helloguangxue", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/applets": { - "modified": "2019-03-24T00:18:00.259Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/bgColor": { - "modified": "2019-03-18T20:59:10.850Z", - "contributors": [ - "SphinxKnight", - "mochen" - ] - }, - "Web/API/Document/body": { - "modified": "2019-10-05T01:49:42.746Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Document/caretRangeFromPoint": { - "modified": "2019-05-30T04:39:32.187Z", - "contributors": [ - "woniuxingdong", - "nDos" - ] - }, - "Web/API/Document/characterSet": { - "modified": "2019-03-24T00:16:21.537Z", - "contributors": [ - "kameii", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/clear": { - "modified": "2019-03-23T22:09:29.354Z", - "contributors": [ - "ZWkang", - "x1aodingdang" - ] - }, - "Web/API/Document/close": { - "modified": "2020-10-15T21:04:22.642Z", - "contributors": [ - "RainSlide", - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Document/compatMode": { - "modified": "2020-10-15T21:04:30.548Z", - "contributors": [ - "RainSlide", - "SphinxKnight", - "guitong", - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Document/contentType": { - "modified": "2019-03-24T00:17:45.428Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/cookie": { - "modified": "2020-09-07T11:32:00.983Z", - "contributors": [ - "JamesUmmex", - "githubtian", - "wcj2020", - "Liugq5713", - "kuracola", - "xgqfrms-GitHub", - "binggg", - "yola0316", - "galin", - "fskuok", - "teoli", - "AshfaqHossain", - "ReyCG" - ] - }, - "Web/API/Document/cookie/Simple_document.cookie_framework": { - "modified": "2019-03-18T20:55:13.743Z", - "contributors": [ - "Tommy-White", - "xgqfrms-GitHub" - ] - }, - "Web/API/Document/createAttribute": { - "modified": "2020-10-15T21:04:21.052Z", - "contributors": [ - "suvyme", - "RainSlide", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Document/createCDATASection": { - "modified": "2020-10-15T22:26:51.755Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/API/Document/createComment": { - "modified": "2019-03-24T00:17:51.091Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Document/createDocumentFragment": { - "modified": "2020-10-15T21:34:42.689Z", - "contributors": [ - "zhangchen", - "undermoodzyx", - "xgqfrms-GitHub", - "zhaoqize", - "yunnysunny", - "mike-j", - "charlie" - ] - }, - "Web/API/Document/createElement": { - "modified": "2020-10-15T21:37:27.205Z", - "contributors": [ - "oz9876", - "yyyang1996", - "RainSlide", - "VacantThinker", - "toBeTheLight", - "Nygma", - "xgqfrms-GitHub", - "Power-kxLee", - "Dcfm", - "gaowanxiang", - "holynewbie", - "kedgeree", - "FredWe" - ] - }, - "Web/API/Document/createElementNS": { - "modified": "2019-03-23T22:51:16.984Z", - "contributors": [ - "xgqfrms-GitHub", - "RockJerffreason", - "FredWe" - ] - }, - "Web/API/Document/createEvent": { - "modified": "2020-08-14T06:06:35.487Z", - "contributors": [ - "wanglin2", - "ucev", - "AspenLuoQiang" - ] - }, - "Web/API/Document/createExpression": { - "modified": "2019-03-24T00:17:47.128Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Document/createNSResolver": { - "modified": "2019-03-18T21:43:39.202Z", - "contributors": [ - "nDos" - ] - }, - "Web/API/Document/createNodeIterator": { - "modified": "2020-10-15T21:50:13.235Z", - "contributors": [ - "Carllllo", - "caoruiy" - ] - }, - "Web/API/Document/createProcessingInstruction": { - "modified": "2019-03-23T22:24:38.642Z", - "contributors": [ - "caoruiy" - ] - }, - "Web/API/Document/createRange": { - "modified": "2019-03-23T22:57:48.498Z", - "contributors": [ - "rguanghui" - ] - }, - "Web/API/Document/createTextNode": { - "modified": "2020-10-15T21:04:26.207Z", - "contributors": [ - "RainSlide", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/createTreeWalker": { - "modified": "2020-10-15T21:44:56.079Z", - "contributors": [ - "Carllllo", - "lbwa", - "617429782", - "TechQuery", - "gqqnbig" - ] - }, - "Web/API/Document/currentScript": { - "modified": "2020-10-15T21:04:30.027Z", - "contributors": [ - "RainSlide", - "aronlee", - "zhaoqize", - "teoli", - "khalid32", - "ziyunfei", - "zhangyaochun1987" - ] - }, - "Web/API/Document/defaultView": { - "modified": "2019-03-24T00:17:46.444Z", - "contributors": [ - "teoli", - "ziyunfei", - "zbinlin" - ] - }, - "Web/API/Document/designMode": { - "modified": "2020-10-15T21:07:17.647Z", - "contributors": [ - "RainSlide", - "xgqfrms-GitHub", - "HuazhuLi", - "AlexChao", - "teoli", - "ziyunfei", - "China zhangshuo" - ] - }, - "Web/API/Document/dir": { - "modified": "2019-03-23T22:48:59.185Z", - "contributors": [ - "caoruiy", - "MineLucky" - ] - }, - "Web/API/Document/doctype": { - "modified": "2020-10-15T21:06:34.416Z", - "contributors": [ - "ridiculousjam", - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Document/documentElement": { - "modified": "2020-10-15T21:25:18.170Z", - "contributors": [ - "RainSlide", - "zhuangyin", - "learnslagFeng", - "Ende93", - "jastovi", - "AlexChao", - "teoli", - "khalid32", - "sobear" - ] - }, - "Web/API/Document/documentURI": { - "modified": "2020-10-15T21:29:47.480Z", - "contributors": [ - "aronlee", - "lext", - "teoli", - "ziyunfei", - "AlexChao" - ] - }, - "Web/API/Document/documentURIObject": { - "modified": "2019-03-24T00:17:51.431Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Document/domain": { - "modified": "2020-10-15T21:38:19.387Z", - "contributors": [ - "Sir.Zhao", - "RainSlide", - "ziyunfei", - "happyWang" - ] - }, - "Web/API/Document/drag_event": { - "modified": "2020-02-28T04:53:00.147Z", - "contributors": [ - "鑫花", - "wbamberg", - "fscholz", - "towrabbit", - "xiazhe", - "tcatche", - "Ende93" - ] - }, - "Web/API/Document/dragend_event": { - "modified": "2019-04-30T13:44:16.179Z", - "contributors": [ - "wbamberg", - "fscholz", - "soon", - "SunOfHomeBoy", - "Ende93" - ] - }, - "Web/API/Document/dragenter_event": { - "modified": "2019-10-08T03:30:08.088Z", - "contributors": [ - "wbamberg", - "fscholz", - "Bayes", - "hefang", - "Ende93" - ] - }, - "Web/API/Document/dragleave_event": { - "modified": "2019-04-30T14:19:10.608Z", - "contributors": [ - "wbamberg", - "fscholz", - "Bayes", - "Ende93" - ] - }, - "Web/API/Document/dragover_event": { - "modified": "2019-04-30T14:26:59.210Z", - "contributors": [ - "wbamberg", - "fscholz", - "gleox", - "Ende93" - ] - }, - "Web/API/Document/dragstart_event": { - "modified": "2019-04-30T13:44:55.835Z", - "contributors": [ - "wbamberg", - "fscholz", - "Bayes", - "Ende93" - ] - }, - "Web/API/Document/drop_event": { - "modified": "2020-07-25T06:39:24.729Z", - "contributors": [ - "wiki", - "鑫花", - "wbamberg", - "fscholz", - "fanyer", - "Ende93" - ] - }, - "Web/API/Document/elementFromPoint": { - "modified": "2019-03-23T23:19:33.886Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/Document/elementsFromPoint": { - "modified": "2019-03-23T22:03:51.668Z", - "contributors": [ - "ziyunfei" - ] - }, - "Web/API/Document/embeds": { - "modified": "2020-10-15T21:04:20.744Z", - "contributors": [ - "aronlee", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/evaluate": { - "modified": "2020-10-15T21:30:36.960Z", - "contributors": [ - "RainSlide", - "kameii", - "teoli", - "lyklykkkkkkk" - ] - }, - "Web/API/Document/execCommand": { - "modified": "2020-10-15T21:27:48.220Z", - "contributors": [ - "Carllllo", - "zhangchen", - "xgqfrms", - "evan_Yuanzh", - "JJJYY", - "wjp5826", - "CNHTT", - "nDos", - "gzponline", - "justmd5", - "xgqfrms-GitHub", - "futurefeeling", - "caoruiy", - "see311", - "choldrim", - "hidehalo", - "Sebastianz", - "yishuangxi", - "laobubu", - "linmx0130", - "teoli", - "khalid32", - "mino" - ] - }, - "Web/API/Document/exitFullscreen": { - "modified": "2019-04-28T13:16:50.343Z", - "contributors": [ - "cokepluscarbon" - ] - }, - "Web/API/Document/exitPointerLock": { - "modified": "2019-03-18T21:43:39.791Z", - "contributors": [ - "nDos" - ] - }, - "Web/API/Document/fgColor": { - "modified": "2020-10-15T21:04:20.735Z", - "contributors": [ - "SphinxKnight", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/fonts": { - "modified": "2020-10-15T22:12:31.115Z", - "contributors": [ - "mimiton" - ] - }, - "Web/API/Document/forms": { - "modified": "2019-03-24T00:17:47.414Z", - "contributors": [ - "xgqfrms-GitHub", - "helloguangxue", - "teoli", - "khalid32", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Document/fullscreenchange_event": { - "modified": "2019-03-18T20:32:52.969Z", - "contributors": [ - "irenesmith", - "zhaoshouxin" - ] - }, - "Web/API/Document/getElementById": { - "modified": "2020-10-15T21:32:38.932Z", - "contributors": [ - "Payne-X", - "StudentMain", - "dhssingle", - "python012", - "HTLing", - "hhxxhg", - "Ende93", - "teoli", - "HeChenTao" - ] - }, - "Web/API/Document/getElementsByClassName": { - "modified": "2020-10-15T21:34:09.313Z", - "contributors": [ - "leplay", - "birdway", - "zxsunrise", - "yoyo837", - "nianxiaoge", - "jahentao", - "zieg", - "iugo" - ] - }, - "Web/API/Document/getElementsByName": { - "modified": "2020-10-15T21:46:15.720Z", - "contributors": [ - "Watson-WC", - "gnepnaiL-oahZ", - "LylaYuKakola", - "xcchcaptain", - "Soy" - ] - }, - "Web/API/Document/getElementsByTagName": { - "modified": "2019-03-18T20:49:57.913Z", - "contributors": [ - "xgqfrms", - "jethro2016" - ] - }, - "Web/API/Document/getElementsByTagNameNS": { - "modified": "2019-03-23T22:11:52.438Z", - "contributors": [ - "zhuangyin", - "iFee" - ] - }, - "Web/API/Document/getSelection": { - "modified": "2019-04-29T02:16:09.423Z", - "contributors": [ - "happyWang", - "teoli", - "AlexChao" - ] - }, - "Web/API/Document/hasFocus": { - "modified": "2019-04-29T02:46:37.409Z", - "contributors": [ - "sunnylost", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/hasStorageAccess": { - "modified": "2020-10-15T22:28:40.724Z", - "contributors": [ - "breakair" - ] - }, - "Web/API/Document/head": { - "modified": "2019-03-24T00:17:50.159Z", - "contributors": [ - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Document/height": { - "modified": "2020-11-06T03:11:40.153Z", - "contributors": [ - "GeekChen" - ] - }, - "Web/API/Document/hidden": { - "modified": "2020-10-15T21:51:26.318Z", - "contributors": [ - "1v9", - "nDos", - "876843240" - ] - }, - "Web/API/Document/images": { - "modified": "2020-10-15T21:06:33.648Z", - "contributors": [ - "aronlee", - "birdway", - "teoli", - "arunpandianp", - "ziyunfei" - ] - }, - "Web/API/Document/implementation": { - "modified": "2019-03-23T23:22:02.021Z", - "contributors": [ - "teoli", - "jsx", - "Nealzhu" - ] - }, - "Web/API/Document/importNode": { - "modified": "2020-10-15T21:07:15.697Z", - "contributors": [ - "fscholz", - "wbamberg", - "teoli", - "khalid32", - "Sheppy", - "ziyunfei" - ] - }, - "Web/API/Document/inputEncoding": { - "modified": "2019-03-24T00:17:51.204Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Document/keypress_event": { - "modified": "2019-04-24T12:26:46.079Z", - "contributors": [ - "chrisdavidmills", - "fscholz", - "ziyunfei", - "PudgeGG" - ] - }, - "Web/API/Document/lastModified": { - "modified": "2020-10-15T21:06:37.728Z", - "contributors": [ - "SphinxKnight", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/lastStyleSheetSet": { - "modified": "2020-10-15T22:30:54.269Z", - "contributors": [ - "jiang-hr" - ] - }, - "Web/API/Document/linkColor": { - "modified": "2019-03-18T20:58:57.157Z", - "contributors": [ - "SphinxKnight", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/links": { - "modified": "2020-10-15T21:29:38.788Z", - "contributors": [ - "RainSlide", - "teoli", - "AlexChao" - ] - }, - "Web/API/Document/location": { - "modified": "2019-04-28T04:24:07.786Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Document/mozFullScreen": { - "modified": "2019-06-11T23:50:44.389Z", - "contributors": [ - "xiaoxingchi", - "hb-bobo", - "codeofjackie", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Document/mozFullScreenElement": { - "modified": "2019-03-24T00:17:55.698Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Document/mozFullScreenEnabled": { - "modified": "2019-03-24T00:17:54.483Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/mozSyntheticDocument": { - "modified": "2019-03-23T22:10:39.057Z", - "contributors": [ - "littlemosquito", - "lxcyha" - ] - }, - "Web/API/Document/onbeforescriptexecute": { - "modified": "2019-03-24T00:14:56.790Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "teoli", - "khalid32", - "zhangyaochun1987" - ] - }, - "Web/API/Document/onfullscreenchange": { - "modified": "2020-10-15T21:49:09.799Z", - "contributors": [ - "gentlecoder", - "libmw" - ] - }, - "Web/API/Document/onfullscreenerror": { - "modified": "2019-04-27T09:18:56.721Z", - "contributors": [ - "ZWkang" - ] - }, - "Web/API/Document/onoffline": { - "modified": "2019-03-23T22:24:33.524Z", - "contributors": [ - "caoruiy" - ] - }, - "Web/API/Document/ononline": { - "modified": "2019-03-18T21:38:43.642Z", - "contributors": [ - "wanderzhang", - "githubyangwei" - ] - }, - "Web/API/Document/onvisibilitychange": { - "modified": "2020-10-15T22:25:06.098Z", - "contributors": [ - "wangzhongchunongithub" - ] - }, - "Web/API/Document/open": { - "modified": "2020-10-15T21:52:24.168Z", - "contributors": [ - "ridiculousjam", - "JobWebNie", - "luxp", - "xgqfrms-GitHub" - ] - }, - "Web/API/Document/origin": { - "modified": "2019-03-18T21:43:47.737Z", - "contributors": [ - "nDos" - ] - }, - "Web/API/Document/plugins": { - "modified": "2020-10-15T22:07:38.306Z", - "contributors": [ - "SphinxKnight", - "Sojourn2017" - ] - }, - "Web/API/Document/pointerLockElement": { - "modified": "2019-03-23T22:20:46.971Z", - "contributors": [ - "876843240" - ] - }, - "Web/API/Document/pointerlockchange_event": { - "modified": "2020-10-15T22:32:28.124Z", - "contributors": [ - "vent" - ] - }, - "Web/API/Document/preferredStyleSheetSet": { - "modified": "2020-10-15T22:21:17.584Z", - "contributors": [ - "goden.cheng" - ] - }, - "Web/API/Document/queryCommandEnabled": { - "modified": "2020-10-15T21:54:30.241Z", - "contributors": [ - "MCCF", - "nDos", - "trto1987", - "ucev" - ] - }, - "Web/API/Document/queryCommandState": { - "modified": "2019-03-23T22:16:56.994Z", - "contributors": [ - "nDos", - "BangBuYanSheng" - ] - }, - "Web/API/Document/queryCommandSupported": { - "modified": "2019-03-23T22:56:21.404Z", - "contributors": [ - "nDos", - "Yl ls" - ] - }, - "Web/API/Document/querySelector": { - "modified": "2020-10-15T21:27:57.842Z", - "contributors": [ - "jolin27144", - "stefango", - "sakuragi1111", - "zhuangyin", - "luxin88", - "littleostar", - "changesunline", - "zhangchen", - "jvua", - "hmzll", - "xgqfrms-GitHub", - "ziolau", - "TTFDG", - "azhi09", - "teoli", - "AshfaqHossain", - "ziyunfei", - "rebaomi", - "rolinli" - ] - }, - "Web/API/Document/querySelectorAll": { - "modified": "2020-10-15T21:07:21.948Z", - "contributors": [ - "yipanhuasheng", - "zhuangyin", - "isLishude", - "yydzxz", - "ZZES_REN", - "xgqfrms-GitHub", - "GeekaholicLin", - "wzx", - "helloguangxue", - "teoli", - "ziyunfei" - ] - }, - "Web/API/Document/readyState": { - "modified": "2020-10-15T21:18:48.351Z", - "contributors": [ - "Carllllo", - "SmelRain", - "SphinxKnight", - "JiaYifan", - "ielgnaw", - "xgqfrms-GitHub", - "gqqnbig", - "teoli", - "szmtcjm", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/referrer": { - "modified": "2020-10-15T21:04:24.930Z", - "contributors": [ - "volving", - "RainSlide", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Document/registerElement": { - "modified": "2020-10-15T21:37:30.950Z", - "contributors": [ - "zhangchen", - "Pada", - "Lock", - "fsx950223", - "mochen" - ] - }, - "Web/API/Document/releaseCapture": { - "modified": "2019-03-23T23:35:19.576Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "princetoad@gmail.com" - ] - }, - "Web/API/Document/rouchmove_event": { - "modified": "2019-04-30T14:14:32.752Z", - "contributors": [ - "wbamberg", - "irenesmith", - "fscholz", - "zhaosource" - ] - }, - "Web/API/Document/scripts": { - "modified": "2019-03-24T00:17:22.230Z", - "contributors": [ - "teoli", - "jsx", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Document/scroll_event": { - "modified": "2020-10-15T21:45:42.383Z", - "contributors": [ - "Carllllo", - "irenesmith", - "Alfred.W", - "lon", - "fscholz", - "xuzicn" - ] - }, - "Web/API/Document/scrollingElement": { - "modified": "2019-03-18T21:43:36.553Z", - "contributors": [ - "nDos" - ] - }, - "Web/API/Document/selectedStyleSheetSet": { - "modified": "2019-03-18T21:39:29.976Z", - "contributors": [ - "wbamberg", - "AIWWJ" - ] - }, - "Web/API/Document/selectionchange_event": { - "modified": "2020-08-19T06:04:15.985Z", - "contributors": [ - "Junezm", - "Zhang-Junzhi", - "wbamberg", - "irenesmith", - "zhaoqize" - ] - }, - "Web/API/Document/selectstart_event": { - "modified": "2019-04-30T14:03:08.442Z", - "contributors": [ - "wbamberg", - "irenesmith", - "zhangchen", - "zhaoqize" - ] - }, - "Web/API/Document/styleSheetSets": { - "modified": "2019-03-23T22:11:26.505Z", - "contributors": [ - "wbamberg", - "xgqfrms-GitHub" - ] - }, - "Web/API/Document/styleSheets": { - "modified": "2019-03-23T23:10:11.077Z", - "contributors": [ - "xgqfrms-GitHub", - "teoli", - "AlexChao" - ] - }, - "Web/API/Document/timeline": { - "modified": "2020-10-15T21:52:30.679Z", - "contributors": [ - "RainSlide", - "LiuYuan", - "CStrive" - ] - }, - "Web/API/Document/title": { - "modified": "2019-04-28T06:26:42.230Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Document/tooltipNode": { - "modified": "2019-03-24T00:17:47.811Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Document/touchcancel_event": { - "modified": "2020-10-15T22:29:23.086Z", - "contributors": [ - "Carllllo", - "anhaoan6" - ] - }, - "Web/API/Document/touchend_event": { - "modified": "2019-03-23T22:00:05.193Z", - "contributors": [ - "irenesmith", - "fscholz", - "ziyunfei", - "jtyjty99999" - ] - }, - "Web/API/Document/touchstart_event": { - "modified": "2020-10-15T22:30:05.652Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/Document/visibilityState": { - "modified": "2020-11-05T03:26:19.322Z", - "contributors": [ - "SphinxKnight", - "lianzhidong", - "nDos", - "vanishcode", - "printfalling" - ] - }, - "Web/API/Document/visibilitychange_event": { - "modified": "2020-11-12T07:43:35.987Z", - "contributors": [ - "xgqfrms", - "1v9", - "irenesmith", - "fscholz", - "ziyunfei" - ] - }, - "Web/API/Document/width": { - "modified": "2019-03-24T00:17:47.703Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document/write": { - "modified": "2020-10-15T21:29:47.332Z", - "contributors": [ - "RainSlide", - "ridiculousjam", - "six-moon", - "xgqfrms-GitHub", - "Marcia_gm", - "shisaq", - "teoli", - "jsx", - "ziyunfei", - "AlexChao" - ] - }, - "Web/API/Document/writeln": { - "modified": "2019-03-23T23:10:09.287Z", - "contributors": [ - "teoli", - "jsx", - "AlexChao" - ] - }, - "Web/API/DocumentFragment": { - "modified": "2020-10-15T21:26:49.982Z", - "contributors": [ - "losT1995", - "xoyojo", - "Fancyflame", - "RainSlide", - "zhaoqize", - "Lynn0108", - "xgqfrms-GitHub", - "kankk", - "Cattla", - "wzx", - "laobubu", - "jsx", - "endlesswind" - ] - }, - "Web/API/DocumentFragment/DocumentFragment": { - "modified": "2019-03-23T22:41:13.086Z", - "contributors": [ - "laobubu" - ] - }, - "Web/API/DocumentFragment/querySelector": { - "modified": "2020-10-15T21:41:27.431Z", - "contributors": [ - "RainSlide", - "laobubu" - ] - }, - "Web/API/DocumentFragment/querySelectorAll": { - "modified": "2020-10-15T22:17:42.026Z", - "contributors": [ - "eventao" - ] - }, - "Web/API/DocumentOrShadowRoot": { - "modified": "2020-10-15T21:55:35.186Z", - "contributors": [ - "RainSlide", - "bei6", - "iainreid629" - ] - }, - "Web/API/DocumentOrShadowRoot/activeElement": { - "modified": "2020-11-25T12:38:44.862Z", - "contributors": [ - "imgss" - ] - }, - "Web/API/DocumentOrShadowRoot/elementFromPoint": { - "modified": "2020-11-25T12:47:25.249Z", - "contributors": [ - "imgss", - "Bayes" - ] - }, - "Web/API/DocumentOrShadowRoot/elementsFromPoint": { - "modified": "2020-10-15T21:55:33.567Z", - "contributors": [ - "fscholz", - "1Cr18Ni9" - ] - }, - "Web/API/DocumentOrShadowRoot/getSelection": { - "modified": "2020-10-15T22:12:59.602Z", - "contributors": [ - "WuCongMan" - ] - }, - "Web/API/DocumentOrShadowRoot/styleSheets": { - "modified": "2020-10-19T22:22:59.095Z", - "contributors": [ - "lastVigo" - ] - }, - "Web/API/DocumentTouch": { - "modified": "2019-03-23T22:57:10.414Z", - "contributors": [ - "yangkui" - ] - }, - "Web/API/DocumentType": { - "modified": "2020-10-15T21:51:21.460Z", - "contributors": [ - "Carllllo", - "RainSlide", - "aronlee", - "yatace", - "pasturn" - ] - }, - "Web/API/Document_Object_Model": { - "modified": "2019-08-25T10:30:09.474Z", - "contributors": [ - "zeyongTsai", - "keller0", - "daibor", - "xgqfrms-GitHub", - "chasingshadow", - "Ende93", - "ziyunfei", - "ReyCG_sub", - "Dewang", - "Xagq123456" - ] - }, - "Web/API/Document_Object_Model/Events": { - "modified": "2019-07-06T03:38:22.874Z", - "contributors": [ - "ridiculousjam", - "v-killer", - "SmallBusy", - "Noly1990", - "dongyu063", - "gavinkwoe" - ] - }, - "Web/API/Document_Object_Model/Examples": { - "modified": "2019-03-24T00:15:45.643Z", - "contributors": [ - "LianJilu", - "Ke.shidong", - "Ende93", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Document_Object_Model/How_to_create_a_DOM_tree": { - "modified": "2019-03-23T22:09:45.087Z", - "contributors": [ - "ArcherGrey" - ] - }, - "Web/API/Document_Object_Model/Introduction": { - "modified": "2019-07-17T11:05:34.542Z", - "contributors": [ - "JiLiangLai", - "locknono", - "ddtyjmyjm", - "YyzclYang", - "LiXin", - "Noly1990", - "lon", - "lazurey", - "gavinkwoe", - "huozicheng", - "leunggamciu", - "arunpandianp", - "ziyunfei", - "ReyCG_sub", - "Darrel.Hsu" - ] - }, - "Web/API/Document_Object_Model/Locating_DOM_elements_using_selectors": { - "modified": "2019-03-23T22:45:22.118Z", - "contributors": [ - "xgqfrms-GitHub", - "ZhuYonglin", - "gavinkwoe", - "liurenxingyu" - ] - }, - "Web/API/Document_Object_Model/Preface": { - "modified": "2019-03-23T23:33:00.872Z", - "contributors": [ - "khalid32", - "ziyunfei", - "ReyCG_sub", - "ngoyroe" - ] - }, - "Web/API/Document_Object_Model/Using_the_W3C_DOM_Level_1_Core": { - "modified": "2019-12-13T21:06:35.933Z", - "contributors": [ - "wbamberg", - "alwxkxk", - "xhlsrj", - "EugeneZeng" - ] - }, - "Web/API/Document_Object_Model/Whitespace": { - "modified": "2020-01-30T13:21:03.275Z", - "contributors": [ - "chrisdavidmills", - "lon", - "ziyunfei" - ] - }, - "Web/API/DragEvent": { - "modified": "2019-03-23T22:58:48.150Z", - "contributors": [ - "ucev", - "yatace", - "Xiuwu.Yang", - "Junjie_Wei" - ] - }, - "Web/API/DragEvent/DragEvent": { - "modified": "2019-03-23T22:35:46.684Z", - "contributors": [ - "Fantasy_shao" - ] - }, - "Web/API/DragEvent/dataTransfer": { - "modified": "2019-03-23T22:08:50.431Z", - "contributors": [ - "shly" - ] - }, - "Web/API/DynamicsCompressorNode": { - "modified": "2020-10-15T22:12:44.169Z", - "contributors": [ - "tlos142857" - ] - }, - "Web/API/EXT_float_blend": { - "modified": "2020-10-15T22:19:37.600Z", - "contributors": [ - "RainSlide", - "rainliang65536" - ] - }, - "Web/API/EffectTiming": { - "modified": "2020-10-15T22:30:45.773Z", - "contributors": [ - "sideshowbarker" - ] - }, - "Web/API/EffectTiming/easing": { - "modified": "2020-10-15T22:30:45.316Z", - "contributors": [ - "qiufeihong2018" - ] - }, - "Web/API/Element": { - "modified": "2020-10-15T21:04:09.528Z", - "contributors": [ - "ZouYj", - "mokunshao", - "RainSlide", - "fscholz", - "daxiazilong", - "liunian1004", - "szy0syz", - "ZoomZhao", - "ifredom", - "Ende93", - "MeCKodo", - "FredWe", - "teoli", - "hjb2722404", - "AlexChao", - "ziyunfei", - "Yl ls", - "Mgjbot", - "Bingdian3721", - "Chaircat", - "Dewang" - ] - }, - "Web/API/Element/Activate_event": { - "modified": "2020-10-15T22:15:27.177Z", - "contributors": [ - "Carllllo", - "wbamberg", - "irenesmith", - "chenyanfei-m" - ] - }, - "Web/API/Element/DOMMouseScroll_event": { - "modified": "2019-03-19T08:53:40.772Z", - "contributors": [ - "irenesmith", - "fscholz", - "soYawn" - ] - }, - "Web/API/Element/accessKey": { - "modified": "2019-03-23T22:20:51.264Z", - "contributors": [ - "songlairui" - ] - }, - "Web/API/Element/animate": { - "modified": "2019-03-23T22:06:46.374Z", - "contributors": [ - "lingziyu", - "codedrinker", - "jiangyuzhen" - ] - }, - "Web/API/Element/assignedSlot": { - "modified": "2019-03-23T22:08:34.249Z", - "contributors": [ - "zwzjyxf" - ] - }, - "Web/API/Element/attachShadow": { - "modified": "2020-10-15T21:50:14.324Z", - "contributors": [ - "Sandaydi", - "RainSlide", - "xiazeyu", - "carsonxu", - "harttle" - ] - }, - "Web/API/Element/attributes": { - "modified": "2020-10-15T21:18:26.411Z", - "contributors": [ - "RainSlide", - "Ende93", - "MeCKodo", - "teoli", - "AlexChao", - "khalid32", - "ziyunfei", - "Mgjbot", - "Dewang" - ] - }, - "Web/API/Element/classList": { - "modified": "2020-10-15T21:18:29.890Z", - "contributors": [ - "yunxiaomeng", - "mokunshao", - "whwangms", - "RainSlide", - "zhangchen", - "fanerge", - "xianshenglu", - "xgqfrms-GitHub", - "NarK", - "teoli", - "AlexChao", - "ziyunfei", - "Wladimir_Palant" - ] - }, - "Web/API/Element/className": { - "modified": "2019-03-24T00:16:22.040Z", - "contributors": [ - "glbjiiii", - "xgqfrms-GitHub", - "teoli", - "khalid32", - "AlexChao", - "ziyunfei", - "dextra", - "Dewang" - ] - }, - "Web/API/Element/click_event": { - "modified": "2019-04-16T23:14:29.456Z", - "contributors": [ - "irenesmith", - "walwimp", - "hhxxhg", - "ch-zgh-1993", - "Ratin", - "fscholz", - "XHMM", - "rain1992", - "smilewalker", - "zhouxu" - ] - }, - "Web/API/Element/clientHeight": { - "modified": "2020-01-21T06:42:30.800Z", - "contributors": [ - "huoyuhao", - "lmislm", - "victorsonger", - "SphinxKnight", - "daxiazilong", - "StorytellerF", - "liuqipeng417", - "runcelim", - "teoli", - "AlexChao", - "khalid32", - "Mgjbot", - "Dewang" - ] - }, - "Web/API/Element/clientLeft": { - "modified": "2020-10-15T21:18:15.916Z", - "contributors": [ - "keqingrong", - "SphinxKnight", - "teoli", - "AlexChao", - "ziyunfei", - "Mgjbot", - "Dewang" - ] - }, - "Web/API/Element/clientTop": { - "modified": "2019-03-26T07:30:16.677Z", - "contributors": [ - "SphinxKnight", - "Linkontoask", - "Ende93", - "teoli", - "AlexChao", - "ziyunfei", - "Mgjbot", - "Dewang" - ] - }, - "Web/API/Element/clientWidth": { - "modified": "2020-10-15T21:18:25.362Z", - "contributors": [ - "zhaoshouxin", - "RainSlide", - "hehe1111", - "SphinxKnight", - "inickel", - "teoli", - "AlexChao", - "ziyunfei", - "Mgjbot", - "Dewang" - ] - }, - "Web/API/Element/closest": { - "modified": "2020-10-15T21:29:59.329Z", - "contributors": [ - "mokunshao", - "zhuangyin", - "MaxWithU", - "teoli", - "ziyunfei" - ] - }, - "Web/API/Element/contextmenu_event": { - "modified": "2020-10-15T22:22:30.927Z", - "contributors": [ - "knightyun" - ] - }, - "Web/API/Element/createShadowRoot": { - "modified": "2019-03-18T20:37:03.561Z", - "contributors": [ - "SphinxKnight", - "CrazyMushroom" - ] - }, - "Web/API/Element/currentStyle": { - "modified": "2019-03-23T22:21:18.875Z", - "contributors": [ - "wuyou" - ] - }, - "Web/API/Element/dblclick_event": { - "modified": "2019-03-18T20:42:12.102Z", - "contributors": [ - "irenesmith", - "hhxxhg", - "fscholz", - "xgqfrms-GitHub" - ] - }, - "Web/API/Element/getAttribute": { - "modified": "2019-04-29T04:23:55.908Z", - "contributors": [ - "xgqfrms-GitHub", - "teoli", - "AlexChao" - ] - }, - "Web/API/Element/getAttributeNames": { - "modified": "2020-04-12T22:20:31.990Z", - "contributors": [ - "thomaslwq", - "BLSM53" - ] - }, - "Web/API/Element/getAttributeNode": { - "modified": "2020-03-30T05:09:30.148Z", - "contributors": [ - "zjx-git", - "kameii", - "teoli", - "RobinXiong" - ] - }, - "Web/API/Element/getAttributeNodeNS": { - "modified": "2019-03-18T21:28:39.555Z", - "contributors": [ - "anderlaw" - ] - }, - "Web/API/Element/getBoundingClientRect": { - "modified": "2020-10-18T10:46:05.790Z", - "contributors": [ - "wzj8888888", - "AnthonyWang", - "LinStan", - "HermitSun", - "RainSlide", - "SphinxKnight", - "Shangleizll", - "Kongz233", - "c4605", - "allcky", - "Ende93", - "Skyang", - "kangmingxuan", - "linkarys", - "teoli", - "zldream1106" - ] - }, - "Web/API/Element/getClientRects": { - "modified": "2020-10-15T21:31:19.905Z", - "contributors": [ - "RainSlide", - "zhangchen", - "SphinxKnight", - "xiaoxiyao", - "FredWe", - "Breezewish", - "teoli", - "zldream1106" - ] - }, - "Web/API/Element/getElementsByClassName": { - "modified": "2019-03-23T23:09:26.800Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Element/getElementsByTagName": { - "modified": "2019-09-27T05:08:10.173Z", - "contributors": [ - "SphinxKnight", - "jvua", - "_sollrei", - "Sean_Zhou_Siyuan", - "xgqfrms", - "jethro2016", - "auver", - "teoli", - "ziyunfei", - "最澄" - ] - }, - "Web/API/Element/getElementsByTagNameNS": { - "modified": "2019-03-23T22:02:54.032Z", - "contributors": [ - "Topppy" - ] - }, - "Web/API/Element/hasAttribute": { - "modified": "2019-03-23T23:09:36.135Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Element/hasAttributeNS": { - "modified": "2019-03-23T22:27:44.870Z", - "contributors": [ - "clarkshao" - ] - }, - "Web/API/Element/hasAttributes": { - "modified": "2019-03-24T00:16:17.474Z", - "contributors": [ - "ziyunfei", - "teoli", - "xuancanh", - "Xiaobian" - ] - }, - "Web/API/Element/id": { - "modified": "2020-10-15T21:06:51.004Z", - "contributors": [ - "RainSlide", - "teoli", - "AlexChao", - "ziyunfei", - "Mgjbot", - "Dewang" - ] - }, - "Web/API/Element/innerHTML": { - "modified": "2020-10-15T21:15:05.546Z", - "contributors": [ - "maoyumaoxun", - "zhuangyin", - "mgdrum", - "dstyxy", - "loicaplay", - "xgqfrms-GitHub", - "yoann1103", - "RyanPan", - "teoli", - "khalid32", - "ziyunfei", - "zezhou", - "巴别塔工人" - ] - }, - "Web/API/Element/insertAdjacentElement": { - "modified": "2019-03-23T22:23:24.944Z", - "contributors": [ - "xgqfrms-GitHub", - "maicss", - "Aolose" - ] - }, - "Web/API/Element/insertAdjacentHTML": { - "modified": "2020-11-25T23:08:49.704Z", - "contributors": [ - "XboxYan", - "MCCF", - "maicss", - "xgqfrms-GitHub", - "OlafCheng", - "rguanghui", - "teoli", - "AlexChao", - "khalid32", - "ziyunfei", - "zbinlin" - ] - }, - "Web/API/Element/insertAdjacentText": { - "modified": "2019-03-23T22:14:14.895Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/Element/keydown_event": { - "modified": "2020-10-15T22:22:08.695Z", - "contributors": [ - "anysunflower" - ] - }, - "Web/API/Element/keyup_event": { - "modified": "2020-10-15T22:26:57.587Z", - "contributors": [ - "mokunshao" - ] - }, - "Web/API/Element/localName": { - "modified": "2019-03-23T22:10:39.379Z", - "contributors": [ - "Bayes", - "Ende93", - "lingyange", - "joeliu926" - ] - }, - "Web/API/Element/matches": { - "modified": "2020-10-15T21:06:49.284Z", - "contributors": [ - "zhuangyin", - "xgqfrms-GitHub", - "ssbunny", - "nbouvrette", - "monjer", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Element/mousedown_event": { - "modified": "2019-04-30T14:19:17.392Z", - "contributors": [ - "wbamberg", - "irenesmith", - "hhxxhg", - "doodlewind" - ] - }, - "Web/API/Element/mouseenter_event": { - "modified": "2020-03-06T10:24:29.743Z", - "contributors": [ - "Fancyflame", - "wbamberg", - "irenesmith", - "fscholz", - "littleostar", - "winson" - ] - }, - "Web/API/Element/mouseleave_event": { - "modified": "2019-04-30T14:24:12.359Z", - "contributors": [ - "wbamberg", - "cbtpro", - "irenesmith", - "hhxxhg", - "Hedgehog" - ] - }, - "Web/API/Element/mousemove_event": { - "modified": "2020-10-15T21:49:07.539Z", - "contributors": [ - "lianzhidong", - "ZZES_REN", - "irenesmith", - "fscholz", - "Dcfm", - "genglei01" - ] - }, - "Web/API/Element/mouseout_event": { - "modified": "2020-10-15T22:15:26.290Z", - "contributors": [ - "Carllllo", - "wbamberg", - "irenesmith", - "chenyanfei-m" - ] - }, - "Web/API/Element/mouseup_event": { - "modified": "2020-10-15T22:06:53.776Z", - "contributors": [ - "Carllllo", - "wbamberg", - "irenesmith", - "hhxxhg" - ] - }, - "Web/API/Element/name": { - "modified": "2019-03-23T23:09:29.332Z", - "contributors": [ - "mySoul", - "teoli", - "AlexChao" - ] - }, - "Web/API/Element/namespaceURI": { - "modified": "2019-03-23T22:05:50.221Z", - "contributors": [ - "nile52" - ] - }, - "Web/API/Element/onafterscriptexecute": { - "modified": "2019-03-24T00:15:00.171Z", - "contributors": [ - "wbamberg", - "teoli", - "khalid32", - "ziyunfei", - "zhangyaochun1987" - ] - }, - "Web/API/Element/onfullscreenchange": { - "modified": "2019-03-18T21:19:43.587Z", - "contributors": [ - "Wyatt" - ] - }, - "Web/API/Element/onfullscreenerror": { - "modified": "2020-10-15T22:21:46.027Z", - "contributors": [ - "kjyzly", - "LinChengDior" - ] - }, - "Web/API/Element/ongotpointercapture": { - "modified": "2019-03-18T21:45:48.501Z", - "contributors": [ - "Bayes", - "StorytellerF" - ] - }, - "Web/API/Element/openOrClosedShadowRoot": { - "modified": "2020-10-15T22:35:17.746Z", - "contributors": [ - "liuyuxiang806" - ] - }, - "Web/API/Element/outerHTML": { - "modified": "2019-03-24T00:15:11.770Z", - "contributors": [ - "zhuangyin", - "xgqfrms-GitHub", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Element/prefix": { - "modified": "2019-03-23T22:14:48.998Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/Element/querySelector": { - "modified": "2020-10-15T21:30:06.942Z", - "contributors": [ - "zhuangyin", - "gnepnaiL-oahZ", - "shanqiaosong", - "nicole-li", - "_sollrei", - "xgqfrms-GitHub", - "KngZhi", - "ziyunfei", - "teoli", - "cuixiping", - "AlexChao" - ] - }, - "Web/API/Element/querySelectorAll": { - "modified": "2019-11-07T07:29:15.093Z", - "contributors": [ - "xgqfrms", - "xgqfrms-GitHub", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Element/removeAttribute": { - "modified": "2020-10-15T21:18:22.802Z", - "contributors": [ - "pyt111", - "yagnlei", - "czmecah", - "RainSlide", - "RoXoM", - "SmallBusy", - "xgqfrms-GitHub", - "teoli", - "ziyunfei", - "Xiaobian" - ] - }, - "Web/API/Element/removeAttributeNS": { - "modified": "2019-03-18T21:38:39.565Z", - "contributors": [ - "Eason.Wu" - ] - }, - "Web/API/Element/removeAttributeNode": { - "modified": "2019-03-23T22:06:55.359Z", - "contributors": [ - "jiangyuzhen" - ] - }, - "Web/API/Element/requestFullScreen": { - "modified": "2019-08-17T13:15:53.510Z", - "contributors": [ - "Roronoa_Zoro", - "DarrenMan", - "LiuYuan", - "zhipengyan", - "edgexie1", - "zhy90655", - "LiJonsen", - "hmzll", - "cokepluscarbon" - ] - }, - "Web/API/Element/requestPointerLock": { - "modified": "2020-10-15T22:33:58.432Z", - "contributors": [ - "JoshOY" - ] - }, - "Web/API/Element/runtimeStyle": { - "modified": "2019-03-23T22:06:58.487Z", - "contributors": [ - "shockw4ver", - "jiangyuzhen" - ] - }, - "Web/API/Element/scroll": { - "modified": "2020-10-15T22:24:05.993Z", - "contributors": [ - "Isildur46" - ] - }, - "Web/API/Element/scrollBy": { - "modified": "2020-10-15T22:24:06.432Z", - "contributors": [ - "gh1031", - "Isildur46" - ] - }, - "Web/API/Element/scrollHeight": { - "modified": "2020-10-15T21:29:32.605Z", - "contributors": [ - "SphinxKnight", - "zhangchen", - "RoXoM", - "daxiazilong", - "ShoneSingLone", - "Angelki", - "teoli", - "lonelyboy" - ] - }, - "Web/API/Element/scrollIntoView": { - "modified": "2020-11-30T02:57:17.874Z", - "contributors": [ - "SphinxKnight", - "AlphabetABCX", - "xianshenglu", - "zhangchen", - "JoKer049", - "1v9", - "lujjjh", - "Capasky", - "kangsunlei", - "luojia", - "teoli", - "xuluxi" - ] - }, - "Web/API/Element/scrollIntoViewIfNeeded": { - "modified": "2020-10-15T21:55:07.003Z", - "contributors": [ - "zhangchen", - "teoli", - "tadashi-chen", - "hawtim", - "Gary-c" - ] - }, - "Web/API/Element/scrollLeft": { - "modified": "2020-10-15T21:38:16.269Z", - "contributors": [ - "zhangchen", - "SphinxKnight", - "weiqinl", - "ChanShuYi" - ] - }, - "Web/API/Element/scrollLeftMax": { - "modified": "2019-03-23T22:47:03.267Z", - "contributors": [ - "MeCKodo" - ] - }, - "Web/API/Element/scrollTo": { - "modified": "2020-10-15T22:22:54.857Z", - "contributors": [ - "zhangchen", - "chinayangzhan913" - ] - }, - "Web/API/Element/scrollTop": { - "modified": "2020-10-15T21:39:15.390Z", - "contributors": [ - "dylanyg", - "zhangchen", - "reascript", - "anefish", - "xgqfrms-GitHub", - "_sollrei", - "Freed", - "Shangxin", - "broven", - "MeCKodo" - ] - }, - "Web/API/Element/scrollTopMax": { - "modified": "2019-03-18T21:38:33.768Z", - "contributors": [ - "Eason.Wu" - ] - }, - "Web/API/Element/select_event": { - "modified": "2019-04-30T14:23:54.546Z", - "contributors": [ - "wbamberg", - "irenesmith", - "zhangchen", - "j787701730" - ] - }, - "Web/API/Element/setAttribute": { - "modified": "2020-10-15T21:30:03.484Z", - "contributors": [ - "KingAdiao", - "Fancyflame", - "RainSlide", - "RoXoM", - "xgqfrms-GitHub", - "teoli", - "AlexChao" - ] - }, - "Web/API/Element/setAttributeNS": { - "modified": "2019-03-23T22:11:56.927Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/Element/setAttributeNode": { - "modified": "2019-03-23T22:52:03.132Z", - "contributors": [ - "Hearmen", - "FredWe" - ] - }, - "Web/API/Element/setAttributeNodeNS": { - "modified": "2019-03-23T22:03:53.428Z", - "contributors": [ - "daxiazilong" - ] - }, - "Web/API/Element/setCapture": { - "modified": "2019-03-23T23:35:15.555Z", - "contributors": [ - "wbamberg", - "teoli", - "AshfaqHossain", - "ziyunfei", - "princetoad@gmail.com" - ] - }, - "Web/API/Element/setPointerCapture": { - "modified": "2020-10-15T22:05:25.129Z", - "contributors": [ - "zhangchen", - "waitkafuka" - ] - }, - "Web/API/Element/shadowRoot": { - "modified": "2019-03-18T21:37:00.532Z", - "contributors": [ - "Louis-7", - "carsonxu" - ] - }, - "Web/API/Element/show_event": { - "modified": "2019-03-29T12:10:35.602Z", - "contributors": [ - "irenesmith", - "yxunknown" - ] - }, - "Web/API/Element/slot": { - "modified": "2020-10-15T21:51:22.113Z", - "contributors": [ - "zhangchen", - "Louis-7", - "dxc111", - "Ahhaha233", - "maicss", - "xiaobudongzhang" - ] - }, - "Web/API/Element/tagName": { - "modified": "2019-03-24T06:39:14.311Z", - "contributors": [ - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Element/toggleAttribute": { - "modified": "2020-10-15T22:19:17.489Z", - "contributors": [ - "Anonymous", - "jianghongbing", - "RainSlide" - ] - }, - "Web/API/Element/touchcancel_event": { - "modified": "2020-10-15T21:59:03.732Z", - "contributors": [ - "Carllllo", - "wbamberg", - "irenesmith", - "WangLeto", - "fscholz", - "plter" - ] - }, - "Web/API/Element/touchstart_event": { - "modified": "2020-10-15T21:21:35.043Z", - "contributors": [ - "Carllllo", - "irenesmith", - "fscholz", - "plter", - "zhaosource", - "ziyunfei", - "jtyjty99999" - ] - }, - "Web/API/Element/wheel_event": { - "modified": "2020-10-15T21:37:55.783Z", - "contributors": [ - "xuanji", - "SphinxKnight", - "Missyan", - "irenesmith", - "fscholz", - "Zhang-Junzhi", - "lufengd3", - "ziyunfei" - ] - }, - "Web/API/Entity": { - "modified": "2020-06-03T01:07:43.853Z", - "contributors": [ - "RainSlide", - "xgqfrms-GitHub" - ] - }, - "Web/API/ErrorEvent": { - "modified": "2020-10-15T21:38:19.894Z", - "contributors": [ - "RainSlide", - "shuiyi", - "ziyunfei", - "Jack.Works" - ] - }, - "Web/API/Event": { - "modified": "2020-10-15T21:05:53.829Z", - "contributors": [ - "Oliver_Queen", - "RainSlide", - "NNNaix", - "JiaYifan", - "CiaoLee", - "VickyJin", - "uestcNaldo", - "luneice", - "EThan-Jam", - "sqchenxiyuan", - "xgqfrms-GitHub", - "Cattla", - "teoli", - "ReyCG_sub", - "ziyunfei", - "jinyc", - "TigerSoldier" - ] - }, - "Web/API/Event/Comparison_of_Event_Targets": { - "modified": "2019-03-18T21:17:15.255Z", - "contributors": [ - "zhuangyin" - ] - }, - "Web/API/Event/Event": { - "modified": "2020-10-15T21:37:04.498Z", - "contributors": [ - "fscholz", - "plter", - "xgqfrms-GitHub", - "Iamxiaozhu", - "sqchenxiyuan", - "Go7hic", - "Serifx", - "nuysoft", - "zhongming2013" - ] - }, - "Web/API/Event/bubbles": { - "modified": "2019-03-24T00:17:18.302Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Event/cancelable": { - "modified": "2020-10-15T21:05:13.694Z", - "contributors": [ - "Spikef", - "suchasplus", - "Ethan_y", - "helloguangxue", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Event/composed": { - "modified": "2020-07-01T11:05:05.717Z", - "contributors": [ - "mencre", - "sysiya" - ] - }, - "Web/API/Event/composedPath": { - "modified": "2020-10-15T22:04:45.008Z", - "contributors": [ - "zhangchen", - "DarrenZhang01", - "icodeajk" - ] - }, - "Web/API/Event/createEvent": { - "modified": "2019-03-23T22:56:15.340Z", - "contributors": [ - "holynewbie", - "Serifx", - "yulifu" - ] - }, - "Web/API/Event/currentTarget": { - "modified": "2020-10-15T21:05:13.846Z", - "contributors": [ - "Nothing_bin", - "Ende93", - "dsphoebe.", - "windyKite", - "329530588", - "xgqfrms-GitHub", - "timwangdev", - "collhector", - "AlexChao", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Event/deepPath": { - "modified": "2019-03-23T22:13:43.358Z", - "contributors": [ - "DarrenZhang01", - "Gyanxie" - ] - }, - "Web/API/Event/defaultPrevented": { - "modified": "2020-10-15T21:04:41.129Z", - "contributors": [ - "zhangchen", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Event/eventPhase": { - "modified": "2019-03-23T22:27:15.312Z", - "contributors": [ - "Cattla", - "guoyang" - ] - }, - "Web/API/Event/initEvent": { - "modified": "2019-03-23T22:06:47.943Z", - "contributors": [ - "wallean" - ] - }, - "Web/API/Event/isTrusted": { - "modified": "2020-10-15T22:29:47.454Z", - "contributors": [ - "BSPR0002" - ] - }, - "Web/API/Event/originalTarget": { - "modified": "2019-03-23T22:01:18.763Z", - "contributors": [ - "newued" - ] - }, - "Web/API/Event/preventDefault": { - "modified": "2020-10-15T21:02:42.076Z", - "contributors": [ - "CHAAAA", - "escattone", - "ashe12138", - "yangnaiyue", - "anderson_liu", - "SongJuXin", - "dyz001", - "Miss_MuBu", - "zhangchen", - "frankzhang718", - "Jiang-Xuan", - "HannibalKcc", - "xgqfrms-GitHub", - "dudusky", - "zhangboyuan-XD", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Event/returnValue": { - "modified": "2020-10-15T21:59:23.194Z", - "contributors": [ - "RainSlide", - "newued" - ] - }, - "Web/API/Event/srcElement": { - "modified": "2019-03-23T22:23:05.932Z", - "contributors": [ - "Cattla", - "paranoidjk" - ] - }, - "Web/API/Event/stopImmediatePropagation": { - "modified": "2020-11-22T05:22:58.517Z", - "contributors": [ - "BobGreen", - "RainSlide", - "rguanghui", - "Bayes", - "xiaojunjor", - "xgqfrms-GitHub", - "teoli", - "ziyunfei" - ] - }, - "Web/API/Event/stopPropagation": { - "modified": "2020-11-22T10:39:35.011Z", - "contributors": [ - "SphinxKnight", - "Amoyensis", - "zhuguibiao", - "xgqfrms-GitHub", - "e-cloud", - "Ende93", - "AlexChao", - "teoli", - "ziyunfei" - ] - }, - "Web/API/Event/target": { - "modified": "2020-10-15T21:34:06.328Z", - "contributors": [ - "profileCaren", - "zhuangyin", - "xgqfrms-GitHub", - "yuduxyz", - "collhector", - "AlexChao" - ] - }, - "Web/API/Event/timeStamp": { - "modified": "2019-03-24T00:17:23.556Z", - "contributors": [ - "seanhuai", - "teoli", - "arunpandianp", - "ziyunfei" - ] - }, - "Web/API/Event/type": { - "modified": "2019-03-24T00:17:01.633Z", - "contributors": [ - "wallean", - "Ende93", - "teoli", - "ziyunfei" - ] - }, - "Web/API/Event/禁用时间冒泡": { - "modified": "2019-03-23T22:20:20.011Z", - "contributors": [ - "shockw4ver", - "xgqfrms-GitHub", - "SuunZhu" - ] - }, - "Web/API/EventListener": { - "modified": "2020-10-15T21:39:17.019Z", - "contributors": [ - "RainSlide", - "SmelRain", - "linmx0130" - ] - }, - "Web/API/EventListener/handleEvent": { - "modified": "2020-10-15T22:17:52.496Z", - "contributors": [ - "RainSlide", - "lnner" - ] - }, - "Web/API/EventTarget": { - "modified": "2020-10-15T21:22:01.397Z", - "contributors": [ - "XiangHongAi", - "zhangchen", - "Ende93", - "xgqfrms-GitHub", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/EventTarget/EventTarget": { - "modified": "2020-10-15T22:01:31.033Z", - "contributors": [ - "rxxy" - ] - }, - "Web/API/EventTarget/addEventListener": { - "modified": "2020-10-15T21:06:54.644Z", - "contributors": [ - "LaiTaoGDUT", - "fortunatemouse", - "qq240814476", - "xgqfrms", - "tanchi_wang", - "takhello", - "Hi-Rube", - "MrOhyang", - "LurenAA", - "creative_fish", - "zhangchen", - "chj", - "xiaokk06", - "wbamberg", - "SQYun", - "zhangxing0716", - "ChauMing", - "ybzjsxh", - "jiladahe1997", - "suyanhanx", - "linzx1993", - "hua03", - "ParkerFiend", - "thomaslwq", - "Ray-Eldath", - "xgqfrms-GitHub", - "RayJune", - "chenyang", - "GSBL", - "ZhengYinBo", - "mike-j", - "Ende93", - "huyansheng3", - "azhi09", - "xhlsrj", - "kangmingxuan", - "xlaoyu", - "linmx0130", - "xCss", - "helloguangxue", - "teoli", - "yfdyh000", - "baiya", - "focus", - "Josephok", - "sunorry", - "ziyunfei" - ] - }, - "Web/API/EventTarget/attachEvent": { - "modified": "2019-03-23T22:20:46.552Z", - "contributors": [ - "JohnsonBryant", - "eeeeeeeason", - "JiexianYang" - ] - }, - "Web/API/EventTarget/detachEvent": { - "modified": "2019-03-23T22:15:37.296Z", - "contributors": [ - "Ende93", - "faremax", - "daisyHawen" - ] - }, - "Web/API/EventTarget/dispatchEvent": { - "modified": "2020-12-03T00:06:09.374Z", - "contributors": [ - "wang_liang", - "zailushang", - "sincisco", - "zhuangyin", - "xiaojunjor", - "faremax", - "zcxcncn", - "little-tomorrow", - "chen-Aaron", - "w-angel", - "teoli", - "charlie" - ] - }, - "Web/API/EventTarget/fireEvent": { - "modified": "2019-03-23T22:26:26.112Z", - "contributors": [ - "pod4g" - ] - }, - "Web/API/EventTarget/removeEventListener": { - "modified": "2020-10-15T21:31:36.215Z", - "contributors": [ - "Orime112", - "zhangchen", - "Roojay", - "ZZES_REN", - "Bayes", - "maoyumaoxun", - "pd4d10", - "teoli", - "ykjver" - ] - }, - "Web/API/ExtendableEvent": { - "modified": "2019-06-01T05:43:27.169Z", - "contributors": [ - "prayercc", - "chrisdavidmills" - ] - }, - "Web/API/ExtendableEvent/waitUntil": { - "modified": "2020-10-15T21:54:16.294Z", - "contributors": [ - "Clarkkkk", - "xiaoxiaojx", - "flyingsouthwind" - ] - }, - "Web/API/FetchController": { - "modified": "2020-10-15T21:56:50.608Z", - "contributors": [ - "xgqfrms", - "chjxx", - "zhangchen", - "wuCrio" - ] - }, - "Web/API/FetchController/AbortController": { - "modified": "2020-10-15T22:10:15.849Z", - "contributors": [ - "xiiiAtCn" - ] - }, - "Web/API/FetchController/abort": { - "modified": "2020-10-15T22:22:26.939Z", - "contributors": [ - "cuiwei4869" - ] - }, - "Web/API/FetchEvent": { - "modified": "2019-03-18T20:53:56.985Z", - "contributors": [ - "xty1992a", - "flyingsouthwind" - ] - }, - "Web/API/FetchEvent/respondWith": { - "modified": "2019-03-23T22:11:48.978Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/FetchObserver": { - "modified": "2019-03-23T22:06:02.004Z", - "contributors": [ - "wuCrio" - ] - }, - "Web/API/Fetch_API": { - "modified": "2020-10-15T21:39:36.250Z", - "contributors": [ - "Mookiepiece", - "RainSlide", - "zhangchen", - "wengsj11", - "fortruth", - "HDUCC", - "Zheng7426", - "JimmyBenKlieve", - "NowhereToRun", - "xgqfrms-GitHub", - "yqjiang", - "xcatliu" - ] - }, - "Web/API/Fetch_API/Basic_concepts": { - "modified": "2019-03-23T22:45:38.912Z", - "contributors": [ - "zhuangyin", - "jswisher", - "xgqfrms-GitHub", - "Jeff-Kook", - "xcatliu", - "ziyunfei" - ] - }, - "Web/API/Fetch_API/Cross-global_fetch_usage": { - "modified": "2019-03-18T21:35:40.335Z", - "contributors": [ - "DuckSoft", - "wynejan" - ] - }, - "Web/API/Fetch_API/Using_Fetch": { - "modified": "2020-10-15T21:39:39.542Z", - "contributors": [ - "WangXBruc", - "RainSlide", - "ycwangrd", - "九千鸦", - "symant233", - "zy_2071", - "shawtung", - "Soyaine", - "tangtangtangtangtang", - "iFish", - "StudentMain", - "akong", - "zhuangyin", - "zhangchen", - "luneice", - "xgqfrms-GitHub", - "hurleyfov", - "flowfire", - "semlinker", - "xinx1n", - "jfw10973", - "zhso", - "Howard.Chen", - "CarlJia", - "a1528zhang", - "Azleal", - "xcatliu" - ] - }, - "Web/API/File": { - "modified": "2020-10-15T21:21:06.294Z", - "contributors": [ - "RainSlide", - "fygyx1", - "Ende93", - "xgqfrms-GitHub", - "lofreer", - "Elric-pp", - "teoli", - "ziyunfei", - "Fiag" - ] - }, - "Web/API/File/File": { - "modified": "2020-03-13T08:09:19.064Z", - "contributors": [ - "WindStormrage", - "wizardforcel" - ] - }, - "Web/API/File/Using_files_from_web_applications": { - "modified": "2020-06-08T03:42:00.785Z", - "contributors": [ - "Ahhaha233", - "mkckr0", - "knightyun", - "leegent", - "Ara-yjx", - "Yongest", - "oceanMIH", - "CiaoLee", - "Lulu-Xue", - "xianghui-ma", - "RainSlide", - "zxsunrise", - "codevvvv9", - "chrisdavidmills", - "soraly", - "QizhongFang" - ] - }, - "Web/API/File/fileName": { - "modified": "2019-03-23T23:33:53.867Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/File/fileSize": { - "modified": "2019-03-23T23:33:53.292Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/File/getAsBinary": { - "modified": "2019-03-24T00:16:15.441Z", - "contributors": [ - "isLishude", - "HappyYawen", - "teoli", - "ziyunfei" - ] - }, - "Web/API/File/getAsDataURL": { - "modified": "2019-03-23T22:26:02.793Z", - "contributors": [ - "Liiked", - "ThomasSoloist" - ] - }, - "Web/API/File/getAsText": { - "modified": "2019-03-23T23:33:22.949Z", - "contributors": [ - "DearVikki", - "teoli", - "ziyunfei" - ] - }, - "Web/API/File/lastModified": { - "modified": "2019-03-23T22:02:46.924Z", - "contributors": [ - "AsukaSong" - ] - }, - "Web/API/File/lastModifiedDate": { - "modified": "2019-03-23T23:32:57.340Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/File/mozFullPath": { - "modified": "2019-01-17T01:28:04.491Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/API/File/name": { - "modified": "2019-03-23T23:33:54.227Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/File/size": { - "modified": "2019-03-18T21:27:15.606Z", - "contributors": [ - "levo2165" - ] - }, - "Web/API/File/type": { - "modified": "2019-03-23T22:09:04.649Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/API/File/webkitRelativePath": { - "modified": "2019-07-25T23:57:11.934Z", - "contributors": [ - "dotnetcms_org", - "wizardforcel" - ] - }, - "Web/API/FileError": { - "modified": "2019-03-24T00:16:24.896Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/FileException": { - "modified": "2019-03-23T22:09:01.875Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/API/FileList": { - "modified": "2020-10-15T21:07:20.935Z", - "contributors": [ - "RainSlide", - "fscholz", - "ucev", - "Serifx", - "teoli", - "ziyunfei", - "james.li" - ] - }, - "Web/API/FileReader": { - "modified": "2020-11-19T05:38:57.415Z", - "contributors": [ - "ZeroJsus", - "4325612", - "joinmouse", - "JohnsonBryant", - "zhangchen", - "xgqfrms-GitHub", - "PLAmao", - "AutumnFish", - "Cattla", - "Andself", - "dingziqi", - "teoli", - "charlie", - "ziyunfei" - ] - }, - "Web/API/FileReader/FileReader": { - "modified": "2019-05-30T10:11:08.541Z", - "contributors": [ - "duzc2", - "REds45" - ] - }, - "Web/API/FileReader/abort": { - "modified": "2019-03-23T22:21:50.326Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/FileReader/error": { - "modified": "2019-03-23T22:30:56.657Z", - "contributors": [ - "Cattla", - "BaiLinLin" - ] - }, - "Web/API/FileReader/load_event": { - "modified": "2020-10-15T22:20:27.471Z", - "contributors": [ - "zhangchen", - "qhy90223" - ] - }, - "Web/API/FileReader/onabort": { - "modified": "2019-04-18T04:11:44.611Z", - "contributors": [ - "allan2coder" - ] - }, - "Web/API/FileReader/onload": { - "modified": "2019-03-23T22:21:51.910Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/FileReader/readAsArrayBuffer": { - "modified": "2019-07-09T04:48:45.088Z", - "contributors": [ - "zxsunrise", - "Cattla" - ] - }, - "Web/API/FileReader/readAsBinaryString": { - "modified": "2019-07-09T04:47:27.638Z", - "contributors": [ - "teoli", - "zxsunrise", - "Cattla" - ] - }, - "Web/API/FileReader/readAsDataURL": { - "modified": "2020-10-15T21:51:07.097Z", - "contributors": [ - "qiudongwei", - "zhangchen", - "Cattla" - ] - }, - "Web/API/FileReader/readAsText": { - "modified": "2019-03-23T22:25:22.226Z", - "contributors": [ - "NumerHero", - "ziyunfei" - ] - }, - "Web/API/FileReader/readyState": { - "modified": "2019-03-23T22:21:46.928Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/FileReader/result": { - "modified": "2019-03-23T22:39:52.881Z", - "contributors": [ - "aov2005", - "wizardforcel", - "mmc" - ] - }, - "Web/API/FileReaderSync": { - "modified": "2020-10-15T21:07:17.864Z", - "contributors": [ - "jason-grimm", - "teoli", - "ziyunfei" - ] - }, - "Web/API/FileRequest": { - "modified": "2019-03-23T23:02:38.410Z", - "contributors": [ - "teoli", - "phoenix_in_the_sky" - ] - }, - "Web/API/FileSystem": { - "modified": "2019-03-23T22:48:51.462Z", - "contributors": [ - "ziyunfei", - "Jack.Works" - ] - }, - "Web/API/FileSystemDirectoryEntry": { - "modified": "2019-03-23T22:09:03.397Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/API/FileSystemDirectoryReader": { - "modified": "2020-10-15T22:21:07.408Z" - }, - "Web/API/FileSystemDirectoryReader/readEntries": { - "modified": "2020-10-15T22:21:05.549Z", - "contributors": [ - "x849770537" - ] - }, - "Web/API/FileSystemEntry": { - "modified": "2020-10-15T22:29:26.218Z", - "contributors": [ - "xiyu" - ] - }, - "Web/API/FileSystemFileEntry": { - "modified": "2019-03-23T22:08:57.866Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/API/FileSystemSync": { - "modified": "2019-03-23T22:09:05.117Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/API/File_Handle_API": { - "modified": "2020-08-20T03:55:23.869Z", - "contributors": [ - "Wessonlu", - "liuyuan0071" - ] - }, - "Web/API/File_and_Directory_Entries_API": { - "modified": "2020-10-15T22:03:12.680Z", - "contributors": [ - "RainSlide", - "xiaoxingchi", - "Clouds_W" - ] - }, - "Web/API/File_and_Directory_Entries_API/Firefox_support": { - "modified": "2019-06-11T23:33:01.083Z", - "contributors": [ - "xiaoxingchi" - ] - }, - "Web/API/FocusEvent": { - "modified": "2020-10-20T08:42:06.825Z", - "contributors": [ - "yangxindi", - "qinglong-zeng", - "RainSlide", - "xiaofeiMophsic" - ] - }, - "Web/API/FontFace": { - "modified": "2019-03-23T22:05:41.135Z", - "contributors": [ - "jinnchen" - ] - }, - "Web/API/FontFaceSet": { - "modified": "2019-03-18T21:15:31.702Z", - "contributors": [ - "jinnchen" - ] - }, - "Web/API/FontFaceSet/check": { - "modified": "2019-03-18T21:15:29.114Z", - "contributors": [ - "Ende93", - "dadajuzi" - ] - }, - "Web/API/Force_Touch_events": { - "modified": "2019-03-18T21:46:15.993Z", - "contributors": [ - "Ende93", - "yangxing1" - ] - }, - "Web/API/FormData": { - "modified": "2020-10-15T21:18:58.135Z", - "contributors": [ - "ljdmailbox", - "Explorerhz", - "Znonymous", - "JiHPeng", - "benbenye", - "soon", - "liangyj021", - "SunGuoQiang123", - "RainSlide", - "YISHI", - "Cattla", - "wzx", - "whinc", - "teoli", - "TooBug", - "ziyunfei" - ] - }, - "Web/API/FormData/FormData": { - "modified": "2019-09-24T07:19:19.213Z", - "contributors": [ - "kameii", - "sintrb" - ] - }, - "Web/API/FormData/Using_FormData_Objects": { - "modified": "2020-06-22T06:10:24.580Z", - "contributors": [ - "mountainsky13189", - "YogurtQ", - "Bayes", - "wuchunxu", - "weilong", - "banli17", - "tyw2015", - "TYPE-O56", - "ziv.zjc" - ] - }, - "Web/API/FormData/append": { - "modified": "2019-09-24T07:14:27.802Z", - "contributors": [ - "hayond", - "stevobm", - "wth" - ] - }, - "Web/API/FormData/entries": { - "modified": "2019-03-23T22:28:23.864Z", - "contributors": [ - "ianfung1998" - ] - }, - "Web/API/FormData/get": { - "modified": "2019-03-23T22:26:55.137Z", - "contributors": [ - "Cattla", - "sintrb" - ] - }, - "Web/API/FormData/getAll": { - "modified": "2019-03-23T22:21:45.811Z", - "contributors": [ - "stevobm", - "Cattla" - ] - }, - "Web/API/FormData/has": { - "modified": "2019-03-23T22:21:45.493Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/FormData/keys": { - "modified": "2019-03-23T22:21:46.384Z", - "contributors": [ - "doudoudzj", - "Cattla" - ] - }, - "Web/API/FormData/set": { - "modified": "2019-03-23T22:21:40.133Z", - "contributors": [ - "xiaoyixiang", - "Cattla" - ] - }, - "Web/API/FormData/values": { - "modified": "2019-03-23T22:27:56.986Z", - "contributors": [ - "varcat", - "wth" - ] - }, - "Web/API/FormData/删除": { - "modified": "2020-10-15T21:48:28.738Z", - "contributors": [ - "RainSlide", - "stevobm", - "tomi-li" - ] - }, - "Web/API/Frame_Timing_API": { - "modified": "2020-03-18T00:42:57.197Z", - "contributors": [ - "fzhyzamt", - "peakclown" - ] - }, - "Web/API/FullscreenOptions": { - "modified": "2020-10-15T22:20:05.430Z", - "contributors": [ - "xiaoxingchi" - ] - }, - "Web/API/Fullscreen_API": { - "modified": "2020-12-01T00:44:56.235Z", - "contributors": [ - "Frost-ZX", - "machunning", - "oujielong", - "vaynewang", - "Soyaine", - "wbamberg", - "codeofjackie" - ] - }, - "Web/API/Fullscreen_API/指南": { - "modified": "2020-10-15T22:14:45.841Z", - "contributors": [ - "Soyaine", - "wuzy_oye" - ] - }, - "Web/API/GainNode": { - "modified": "2020-10-15T21:47:52.341Z", - "contributors": [ - "jason-grimm", - "huangxok", - "SoAanyip" - ] - }, - "Web/API/GainNode/gain": { - "modified": "2019-03-23T22:12:05.317Z", - "contributors": [ - "huangxok" - ] - }, - "Web/API/Gamepad": { - "modified": "2020-10-15T21:52:38.003Z", - "contributors": [ - "zsxeee", - "lixuanh" - ] - }, - "Web/API/GamepadButton": { - "modified": "2020-10-15T22:04:17.149Z", - "contributors": [ - "zsxeee" - ] - }, - "Web/API/GamepadButton/pressed": { - "modified": "2020-10-15T22:04:35.939Z", - "contributors": [ - "zsxeee" - ] - }, - "Web/API/GamepadButton/value": { - "modified": "2020-10-15T22:04:36.754Z", - "contributors": [ - "zsxeee" - ] - }, - "Web/API/GamepadEvent": { - "modified": "2020-10-15T22:04:36.963Z", - "contributors": [ - "zsxeee" - ] - }, - "Web/API/GamepadEvent/GamepadEvent": { - "modified": "2020-10-15T22:06:40.107Z", - "contributors": [ - "zsxeee" - ] - }, - "Web/API/GamepadEvent/gamepad": { - "modified": "2020-10-15T22:06:41.485Z", - "contributors": [ - "zsxeee" - ] - }, - "Web/API/GamepadPose": { - "modified": "2020-10-15T22:15:26.758Z", - "contributors": [ - "chenqingyue" - ] - }, - "Web/API/Gamepad_API": { - "modified": "2020-10-15T22:02:57.579Z", - "contributors": [ - "zsxeee" - ] - }, - "Web/API/Gamepad_API/Using_the_Gamepad_API": { - "modified": "2020-10-15T22:02:59.574Z", - "contributors": [ - "zsxeee" - ] - }, - "Web/API/Geolocation": { - "modified": "2019-03-23T23:04:49.853Z", - "contributors": [ - "SundayNine", - "hmzll", - "Ray-Eldath", - "Cattla", - "SimGenius", - "wangxb", - "ziyunfei" - ] - }, - "Web/API/Geolocation/Using_geolocation": { - "modified": "2019-07-01T03:42:53.000Z", - "contributors": [ - "aimilu", - "Syoogool", - "rongnianzu", - "rrandom", - "ziyunfei", - "Breezewish", - "shura-china", - "xcffl" - ] - }, - "Web/API/Geolocation/clearWatch": { - "modified": "2019-03-23T22:21:23.856Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/Geolocation/getCurrentPosition": { - "modified": "2019-03-18T21:10:53.303Z", - "contributors": [ - "wangxb" - ] - }, - "Web/API/Geolocation/watchPosition": { - "modified": "2019-03-23T22:21:35.355Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/GeolocationCoordinates": { - "modified": "2019-12-10T09:35:48.824Z", - "contributors": [ - "chrisdavidmills", - "Bayes", - "wangxb" - ] - }, - "Web/API/GeolocationCoordinates/latitude": { - "modified": "2020-10-15T22:25:09.007Z", - "contributors": [ - "chrisdavidmills", - "IAMBESTMAN" - ] - }, - "Web/API/GeolocationPosition": { - "modified": "2019-12-10T11:05:05.041Z", - "contributors": [ - "chrisdavidmills", - "Ray-Eldath", - "wangxb" - ] - }, - "Web/API/GeolocationPosition/coords": { - "modified": "2020-10-15T21:36:37.390Z", - "contributors": [ - "chrisdavidmills", - "Jack.Works", - "wangxb" - ] - }, - "Web/API/GeolocationPosition/获取该位置时的时间戳": { - "modified": "2020-10-15T22:32:25.842Z", - "contributors": [ - "liu-yanlong" - ] - }, - "Web/API/GeolocationPositionError": { - "modified": "2019-12-10T10:46:31.825Z", - "contributors": [ - "chrisdavidmills", - "wangxb" - ] - }, - "Web/API/GestureEvent": { - "modified": "2020-10-15T21:50:47.359Z", - "contributors": [ - "Carllllo", - "Yangfan" - ] - }, - "Web/API/GlobalEventHandlers": { - "modified": "2019-04-24T22:32:51.813Z", - "contributors": [ - "vaynewang", - "chenqingyue", - "teoli" - ] - }, - "Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove": { - "modified": "2019-03-23T22:38:32.324Z", - "contributors": [ - "zhangqiong" - ] - }, - "Web/API/GlobalEventHandlers/onabort": { - "modified": "2019-03-23T22:38:34.243Z", - "contributors": [ - "Bayes", - "joaner", - "AutumnFish", - "liuhe", - "zhangqiong" - ] - }, - "Web/API/GlobalEventHandlers/onanimationcancel": { - "modified": "2019-03-23T22:20:43.530Z", - "contributors": [ - "876843240" - ] - }, - "Web/API/GlobalEventHandlers/onanimationend": { - "modified": "2019-03-23T22:09:40.853Z", - "contributors": [ - "JasonZzy0528", - "Aaron_Zhung", - "ziyunfei", - "littlemosquito" - ] - }, - "Web/API/GlobalEventHandlers/onanimationiteration": { - "modified": "2019-03-23T22:02:31.853Z", - "contributors": [ - "miracllife", - "xumqfaith" - ] - }, - "Web/API/GlobalEventHandlers/onauxclick": { - "modified": "2019-03-23T22:06:51.886Z", - "contributors": [ - "jjc", - "maicss" - ] - }, - "Web/API/GlobalEventHandlers/onblur": { - "modified": "2019-03-24T00:16:18.088Z", - "contributors": [ - "teoli", - "Hasilt", - "ziyunfei", - "Bingdian3721" - ] - }, - "Web/API/GlobalEventHandlers/oncancel": { - "modified": "2020-10-15T22:14:52.164Z", - "contributors": [ - "Dante-dan", - "zhanghengxin", - "kenanGao", - "c1er", - "linshehai" - ] - }, - "Web/API/GlobalEventHandlers/oncanplay": { - "modified": "2020-10-15T22:15:54.774Z", - "contributors": [ - "chenqingyue" - ] - }, - "Web/API/GlobalEventHandlers/oncanplaythrough": { - "modified": "2019-03-18T20:46:32.884Z", - "contributors": [ - "fanruhua" - ] - }, - "Web/API/GlobalEventHandlers/onchange": { - "modified": "2019-09-11T00:08:58.607Z", - "contributors": [ - "oxyg3n", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onclick": { - "modified": "2020-10-15T21:40:13.149Z", - "contributors": [ - "knightyun", - "RainSlide", - "loicaplay", - "Ende93", - "Hughie" - ] - }, - "Web/API/GlobalEventHandlers/onclose": { - "modified": "2020-10-15T21:49:07.998Z", - "contributors": [ - "cheiron", - "libmw" - ] - }, - "Web/API/GlobalEventHandlers/oncontextmenu": { - "modified": "2019-03-24T00:17:22.877Z", - "contributors": [ - "helloguangxue", - "teoli", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/oncuechange": { - "modified": "2020-10-15T22:16:52.330Z", - "contributors": [ - "c1er" - ] - }, - "Web/API/GlobalEventHandlers/ondblclick": { - "modified": "2019-03-24T00:18:08.191Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/ondrag": { - "modified": "2020-10-15T22:22:52.477Z", - "contributors": [ - "ppphp" - ] - }, - "Web/API/GlobalEventHandlers/ondragleave": { - "modified": "2019-03-23T22:05:16.218Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/GlobalEventHandlers/ondrop": { - "modified": "2019-03-23T22:07:22.391Z", - "contributors": [ - "Silencewanghui" - ] - }, - "Web/API/GlobalEventHandlers/onended": { - "modified": "2020-10-15T22:18:22.501Z", - "contributors": [ - "qiuguomuhai" - ] - }, - "Web/API/GlobalEventHandlers/onerror": { - "modified": "2020-04-01T12:26:07.930Z", - "contributors": [ - "liangbus", - "zhangchen", - "coolguy", - "xgqfrms-GitHub", - "KingMario" - ] - }, - "Web/API/GlobalEventHandlers/onfocus": { - "modified": "2019-03-24T00:18:09.356Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onformdata": { - "modified": "2020-10-15T22:29:04.448Z", - "contributors": [ - "cikelichu" - ] - }, - "Web/API/GlobalEventHandlers/ongotpointercapture": { - "modified": "2019-03-23T22:20:50.816Z", - "contributors": [ - "876843240" - ] - }, - "Web/API/GlobalEventHandlers/oninput": { - "modified": "2020-10-15T21:06:52.477Z", - "contributors": [ - "Opelar", - "zhangchen", - "teoli", - "_Coin", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/oninvalid": { - "modified": "2020-10-15T22:15:01.666Z", - "contributors": [ - "chenqingyue" - ] - }, - "Web/API/GlobalEventHandlers/onkeydown": { - "modified": "2019-03-24T00:18:04.365Z", - "contributors": [ - "teoli", - "basemnassar11", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onkeypress": { - "modified": "2020-10-15T21:06:07.437Z", - "contributors": [ - "Ende93", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onkeyup": { - "modified": "2019-03-24T00:18:07.715Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onload": { - "modified": "2019-03-23T23:15:22.431Z", - "contributors": [ - "xgqfrms-GitHub", - "teoli", - "khalid32", - "ReyCG_sub" - ] - }, - "Web/API/GlobalEventHandlers/onloadeddata": { - "modified": "2020-10-15T22:16:07.855Z", - "contributors": [ - "chenqingyue" - ] - }, - "Web/API/GlobalEventHandlers/onloadedmetadata": { - "modified": "2020-10-15T22:22:53.089Z", - "contributors": [ - "rottenpen", - "ppphp" - ] - }, - "Web/API/GlobalEventHandlers/onloadend": { - "modified": "2020-10-15T22:30:32.313Z", - "contributors": [ - "wuyouhuaz" - ] - }, - "Web/API/GlobalEventHandlers/onloadstart": { - "modified": "2020-10-15T21:57:07.506Z", - "contributors": [ - "fscholz", - "EdwinChanFullStack" - ] - }, - "Web/API/GlobalEventHandlers/onlostpointercapture": { - "modified": "2019-03-18T21:41:59.901Z", - "contributors": [ - "SphinxKnight", - "jvua" - ] - }, - "Web/API/GlobalEventHandlers/onmousedown": { - "modified": "2019-11-20T04:35:05.664Z", - "contributors": [ - "starrytky", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onmouseenter": { - "modified": "2020-10-15T22:13:59.922Z", - "contributors": [ - "DFFZMXJ", - "bedreamer" - ] - }, - "Web/API/GlobalEventHandlers/onmouseleave": { - "modified": "2020-10-15T22:14:16.070Z", - "contributors": [ - "ldc-37" - ] - }, - "Web/API/GlobalEventHandlers/onmousemove": { - "modified": "2019-03-24T00:18:03.596Z", - "contributors": [ - "WuHanJun", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onmouseout": { - "modified": "2019-03-24T00:17:16.265Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onmouseover": { - "modified": "2019-03-24T00:17:21.160Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onmouseup": { - "modified": "2019-03-24T00:18:05.848Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onpause": { - "modified": "2020-10-15T22:17:32.669Z", - "contributors": [ - "zhangnan666" - ] - }, - "Web/API/GlobalEventHandlers/onplay": { - "modified": "2020-10-15T22:17:37.610Z", - "contributors": [ - "Mozilla_" - ] - }, - "Web/API/GlobalEventHandlers/onplaying": { - "modified": "2020-10-15T22:32:26.604Z", - "contributors": [ - "yuyeqianxun", - "isaacsucn", - "283375" - ] - }, - "Web/API/GlobalEventHandlers/onpointercancel": { - "modified": "2019-03-18T21:43:48.182Z", - "contributors": [ - "loicaplay" - ] - }, - "Web/API/GlobalEventHandlers/onpointerdown": { - "modified": "2019-03-23T22:09:45.601Z", - "contributors": [ - "leonkwok1992" - ] - }, - "Web/API/GlobalEventHandlers/onpointerenter": { - "modified": "2019-03-18T21:36:28.097Z", - "contributors": [ - "WEN-JY", - "lltemplar" - ] - }, - "Web/API/GlobalEventHandlers/onpointerleave": { - "modified": "2020-10-15T22:08:42.646Z", - "contributors": [ - "ensleep" - ] - }, - "Web/API/GlobalEventHandlers/onpointermove": { - "modified": "2019-03-18T21:28:25.512Z", - "contributors": [ - "wowoqu" - ] - }, - "Web/API/GlobalEventHandlers/onpointerout": { - "modified": "2020-10-15T22:10:11.418Z", - "contributors": [ - "sweetwyx", - "Enck2015" - ] - }, - "Web/API/GlobalEventHandlers/onpointerover": { - "modified": "2020-10-15T22:12:31.069Z", - "contributors": [ - "loveWct" - ] - }, - "Web/API/GlobalEventHandlers/onpointerup": { - "modified": "2019-03-18T21:28:16.447Z", - "contributors": [ - "wowoqu" - ] - }, - "Web/API/GlobalEventHandlers/onreset": { - "modified": "2019-03-23T22:24:44.486Z", - "contributors": [ - "TyrealGray", - "caoruiy" - ] - }, - "Web/API/GlobalEventHandlers/onresize": { - "modified": "2019-03-24T00:16:24.262Z", - "contributors": [ - "btooom", - "ziyunfei", - "teoli", - "khalid32", - "TigerSoldier" - ] - }, - "Web/API/GlobalEventHandlers/onscroll": { - "modified": "2019-05-07T07:06:53.573Z", - "contributors": [ - "faliye", - "Ende93", - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onselect": { - "modified": "2019-03-24T00:16:24.778Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/onselectionchange": { - "modified": "2019-03-23T22:02:01.226Z", - "contributors": [ - "Losingyoung" - ] - }, - "Web/API/GlobalEventHandlers/onselectstart": { - "modified": "2019-06-18T03:14:39.551Z", - "contributors": [ - "joaner" - ] - }, - "Web/API/GlobalEventHandlers/onsubmit": { - "modified": "2020-10-15T21:06:48.416Z", - "contributors": [ - "RainSlide", - "Ende93", - "teoli", - "basemnassar11", - "ziyunfei" - ] - }, - "Web/API/GlobalEventHandlers/ontouchcancel": { - "modified": "2019-03-23T22:24:39.358Z", - "contributors": [ - "caoruiy" - ] - }, - "Web/API/GlobalEventHandlers/ontouchmove": { - "modified": "2019-03-18T21:44:43.652Z", - "contributors": [ - "loszer" - ] - }, - "Web/API/GlobalEventHandlers/ontouchstart": { - "modified": "2019-03-23T22:02:33.940Z", - "contributors": [ - "Cybs" - ] - }, - "Web/API/GlobalEventHandlers/ontransitioncancel": { - "modified": "2020-10-15T22:29:33.060Z", - "contributors": [ - "zhanghengxin" - ] - }, - "Web/API/GlobalEventHandlers/ontransitionend": { - "modified": "2020-10-15T22:08:08.111Z", - "contributors": [ - "Hopsken" - ] - }, - "Web/API/GlobalEventHandlers/onwheel": { - "modified": "2019-07-28T09:31:36.029Z", - "contributors": [ - "knightyun", - "1Cr18Ni9" - ] - }, - "Web/API/GlobalEventHandlers/时长改变": { - "modified": "2020-10-15T22:21:15.042Z", - "contributors": [ - "suvyme", - "amehito" - ] - }, - "Web/API/HTMLAnchorElement": { - "modified": "2019-03-23T22:49:30.797Z", - "contributors": [ - "iouioupp128", - "fnjoe", - "yansenkeler", - "Lei.C" - ] - }, - "Web/API/HTMLAnchorElement/download": { - "modified": "2020-10-15T22:09:59.378Z", - "contributors": [ - "xiaokk06", - "JinRong.Yang" - ] - }, - "Web/API/HTMLAnchorElement/referrer": { - "modified": "2019-03-23T22:47:13.629Z", - "contributors": [ - "ziyunfei" - ] - }, - "Web/API/HTMLAreaElement": { - "modified": "2019-03-23T22:59:31.575Z", - "contributors": [ - "phoenix_in_the_sky" - ] - }, - "Web/API/HTMLAudioElement": { - "modified": "2020-10-15T21:37:47.889Z", - "contributors": [ - "laampui", - "PythonVsJava", - "joeliu926", - "AutumnFish", - "FredWe" - ] - }, - "Web/API/HTMLAudioElement/Audio": { - "modified": "2020-10-15T22:23:59.265Z", - "contributors": [ - "laampui", - "RainSlide", - "18270553591" - ] - }, - "Web/API/HTMLBRElement": { - "modified": "2020-10-15T22:31:35.294Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/HTMLBaseElement": { - "modified": "2019-03-23T22:47:37.425Z", - "contributors": [ - "pantao" - ] - }, - "Web/API/HTMLBaseFontElement": { - "modified": "2020-10-15T22:31:35.341Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/HTMLBodyElement": { - "modified": "2019-03-23T22:02:20.934Z", - "contributors": [ - "hawtim" - ] - }, - "Web/API/HTMLButtonElement": { - "modified": "2019-03-23T22:46:50.591Z", - "contributors": [ - "linmx0130" - ] - }, - "Web/API/HTMLCanvasElement": { - "modified": "2020-10-15T21:21:07.929Z", - "contributors": [ - "Yayure", - "Tumailefu", - "wbamberg", - "yongxiaodu", - "myway", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/HTMLCanvasElement/getContext": { - "modified": "2020-10-15T21:48:50.841Z", - "contributors": [ - "StudentMain", - "wucuiping", - "Jin_" - ] - }, - "Web/API/HTMLCanvasElement/height": { - "modified": "2019-03-23T22:04:56.526Z", - "contributors": [ - "blackmomo" - ] - }, - "Web/API/HTMLCanvasElement/mozOpaque": { - "modified": "2020-12-03T00:14:11.082Z", - "contributors": [ - "sjwwjss" - ] - }, - "Web/API/HTMLCanvasElement/toBlob": { - "modified": "2020-10-15T21:41:25.765Z", - "contributors": [ - "Mookiepiece", - "ziyunfei", - "lyxuncle" - ] - }, - "Web/API/HTMLCanvasElement/toDataURL": { - "modified": "2020-10-15T21:46:19.888Z", - "contributors": [ - "zhuguibiao", - "fghpdf", - "HelloFun", - "jiahui" - ] - }, - "Web/API/HTMLCanvasElement/transferControlToOffscreen": { - "modified": "2020-10-15T22:32:56.202Z", - "contributors": [ - "SDUTWSL" - ] - }, - "Web/API/HTMLCanvasElement/webglcontextlost_event": { - "modified": "2020-10-15T22:30:09.190Z", - "contributors": [ - "kagurakana" - ] - }, - "Web/API/HTMLCanvasElement/width": { - "modified": "2019-03-23T22:07:48.679Z", - "contributors": [ - "xrr2016" - ] - }, - "Web/API/HTMLCanvasElement/捕获流": { - "modified": "2020-03-01T21:28:17.989Z", - "contributors": [ - "jollybearchina", - "dxiaoqi" - ] - }, - "Web/API/HTMLCollection": { - "modified": "2019-03-18T21:11:26.633Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/HTMLCollection/item": { - "modified": "2019-03-23T22:04:23.393Z", - "contributors": [ - "YeeMarco" - ] - }, - "Web/API/HTMLContentElement": { - "modified": "2020-10-15T22:31:35.188Z", - "contributors": [ - "RainSlide", - "laampui" - ] - }, - "Web/API/HTMLDataElement": { - "modified": "2020-10-15T22:23:28.834Z" - }, - "Web/API/HTMLDataElement/value": { - "modified": "2020-10-15T22:23:29.015Z", - "contributors": [ - "SageX" - ] - }, - "Web/API/HTMLDetailsElement": { - "modified": "2020-10-15T22:17:42.543Z", - "contributors": [ - "Codexiaowu", - "chrisdavidmills" - ] - }, - "Web/API/HTMLDetailsElement/toggle_event": { - "modified": "2020-10-15T22:31:37.680Z", - "contributors": [ - "qq2009" - ] - }, - "Web/API/HTMLDialogElement": { - "modified": "2019-03-23T22:39:22.796Z", - "contributors": [ - "lcw0622" - ] - }, - "Web/API/HTMLDialogElement/show": { - "modified": "2020-10-15T22:13:55.244Z", - "contributors": [ - "SherLtiangang" - ] - }, - "Web/API/HTMLDivElement": { - "modified": "2020-10-15T22:00:23.173Z", - "contributors": [ - "RainSlide", - "Ratin" - ] - }, - "Web/API/HTMLDocument": { - "modified": "2019-03-23T23:52:54.570Z", - "contributors": [ - "hhxxhg", - "sysiya", - "FredWe", - "teoli", - "ziyunfei", - "Xiaomin98" - ] - }, - "Web/API/HTMLElement": { - "modified": "2019-10-10T16:47:35.247Z", - "contributors": [ - "PilgrimErick", - "qLzhu", - "liuyuanquan", - "chengxc", - "zccst", - "fscholz", - "a06062125" - ] - }, - "Web/API/HTMLElement/accessKeyLabel": { - "modified": "2020-10-15T22:19:09.489Z", - "contributors": [ - "Chinvaejay" - ] - }, - "Web/API/HTMLElement/animationcancel_event": { - "modified": "2020-10-15T22:18:40.612Z", - "contributors": [ - "hahabazinga" - ] - }, - "Web/API/HTMLElement/animationiteration_event": { - "modified": "2020-10-15T22:30:27.165Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/API/HTMLElement/beforeinput_event": { - "modified": "2020-10-15T22:30:04.852Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/HTMLElement/blur": { - "modified": "2019-03-23T22:00:21.147Z", - "contributors": [ - "teoli", - "fscholz", - "ziyunfei" - ] - }, - "Web/API/HTMLElement/click": { - "modified": "2020-10-15T21:06:30.174Z", - "contributors": [ - "ewfian", - "zhuangyin", - "shiqianrongsx", - "Ende93", - "teoli", - "AshfaqHossain", - "jsx", - "ziyunfei" - ] - }, - "Web/API/HTMLElement/contentEditable": { - "modified": "2020-10-15T21:18:30.613Z", - "contributors": [ - "leplay", - "AlexChao", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/HTMLElement/contextMenu": { - "modified": "2020-10-15T21:55:39.844Z", - "contributors": [ - "zhangchen", - "xiaokk06", - "1Cr18Ni9" - ] - }, - "Web/API/HTMLElement/dataset": { - "modified": "2019-08-08T12:52:36.012Z", - "contributors": [ - "ilexwg", - "xgqfrms-GitHub", - "teoli", - "ziyunfei", - "ReyCG_sub", - "ReyCG" - ] - }, - "Web/API/HTMLElement/dir": { - "modified": "2019-03-24T00:16:19.875Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei", - "dextra", - "Mgjbot", - "Dewang" - ] - }, - "Web/API/HTMLElement/focus": { - "modified": "2020-10-15T21:06:47.253Z", - "contributors": [ - "RainSlide", - "slimeball", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/HTMLElement/forceSpellCheck": { - "modified": "2019-03-18T21:38:32.415Z", - "contributors": [ - "varcat" - ] - }, - "Web/API/HTMLElement/hidden": { - "modified": "2019-03-23T22:07:13.819Z", - "contributors": [ - "weiqinl" - ] - }, - "Web/API/HTMLElement/isContentEditable": { - "modified": "2019-03-23T23:39:47.858Z", - "contributors": [ - "AlexChao", - "teoli", - "mimzi_fahia", - "ziyunfei" - ] - }, - "Web/API/HTMLElement/lang": { - "modified": "2019-03-23T23:09:25.073Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/HTMLElement/nonce": { - "modified": "2020-12-05T03:41:17.381Z", - "contributors": [ - "hufeicom", - "chenqingyue" - ] - }, - "Web/API/HTMLElement/offsetHeight": { - "modified": "2020-10-15T21:33:02.404Z", - "contributors": [ - "wisecamle", - "vincentLW", - "SphinxKnight", - "McCarthey", - "Nirvana-zsy", - "liuqipeng417", - "wczy1219", - "AlexChao", - "zldream1106", - "Sean.shi" - ] - }, - "Web/API/HTMLElement/offsetLeft": { - "modified": "2019-08-22T01:46:37.168Z", - "contributors": [ - "Zhouhaimei", - "SphinxKnight", - "Nirvana-zsy", - "Howell5", - "Ende93", - "Breezewish", - "teoli", - "AlexChao", - "_Coin" - ] - }, - "Web/API/HTMLElement/offsetParent": { - "modified": "2020-10-15T21:30:06.955Z", - "contributors": [ - "hehos", - "SunGuoQiang123", - "NvanYu", - "likwotsing", - "SphinxKnight", - "winson", - "uinging", - "nuxio", - "teoli", - "AlexChao" - ] - }, - "Web/API/HTMLElement/offsetTop": { - "modified": "2020-10-15T21:30:07.482Z", - "contributors": [ - "frankyeyq", - "SphinxKnight", - "nuxio", - "ziyunfei", - "iugo", - "teoli", - "AlexChao" - ] - }, - "Web/API/HTMLElement/offsetWidth": { - "modified": "2020-02-29T05:55:47.760Z", - "contributors": [ - "RainSlide", - "SphinxKnight", - "weiqinl", - "Kemper-Yao", - "fukaWestin", - "chenzongheng", - "charlie", - "teoli", - "_Coin" - ] - }, - "Web/API/HTMLElement/oncopy": { - "modified": "2019-03-24T00:18:09.591Z", - "contributors": [ - "ziyunfei", - "teoli", - "khalid32" - ] - }, - "Web/API/HTMLElement/oncut": { - "modified": "2019-03-24T00:18:03.706Z", - "contributors": [ - "ziyunfei", - "teoli", - "khalid32" - ] - }, - "Web/API/HTMLElement/onpaste": { - "modified": "2019-03-24T00:18:09.700Z", - "contributors": [ - "ziyunfei", - "teoli", - "khalid32" - ] - }, - "Web/API/HTMLElement/outerText": { - "modified": "2019-03-23T22:14:53.113Z", - "contributors": [ - "ScaredKitty", - "weiqinl", - "xgqfrms-GitHub" - ] - }, - "Web/API/HTMLElement/pointercancel_event": { - "modified": "2020-10-15T22:34:38.435Z", - "contributors": [ - "14725" - ] - }, - "Web/API/HTMLElement/style": { - "modified": "2020-10-15T21:30:08.559Z", - "contributors": [ - "zhuangyin", - "xgqfrms-GitHub", - "distums", - "teoli", - "AlexChao" - ] - }, - "Web/API/HTMLElement/tabIndex": { - "modified": "2019-03-24T00:16:26.046Z", - "contributors": [ - "teoli", - "Hasilt", - "sleepholic", - "ziyunfei" - ] - }, - "Web/API/HTMLElement/title": { - "modified": "2020-01-21T18:29:28.077Z", - "contributors": [ - "yinsang", - "liuhe", - "teoli", - "AlexChao" - ] - }, - "Web/API/HTMLFieldSetElement": { - "modified": "2019-03-23T23:39:02.321Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/HTMLFormElement": { - "modified": "2020-04-03T05:07:37.104Z", - "contributors": [ - "Fancyflame", - "JsonMe" - ] - }, - "Web/API/HTMLFormElement/action": { - "modified": "2019-03-23T22:27:01.532Z", - "contributors": [ - "azhi09" - ] - }, - "Web/API/HTMLFormElement/elements": { - "modified": "2019-03-23T23:20:33.482Z", - "contributors": [ - "ziyunfei", - "aztack" - ] - }, - "Web/API/HTMLFormElement/enctype": { - "modified": "2020-07-16T00:42:09.525Z", - "contributors": [ - "lish1986", - "loveyunk" - ] - }, - "Web/API/HTMLFormElement/reportValidity": { - "modified": "2020-10-15T22:24:47.115Z", - "contributors": [ - "zengchao1212" - ] - }, - "Web/API/HTMLFormElement/reset": { - "modified": "2019-03-24T00:16:05.330Z", - "contributors": [ - "ziyunfei", - "Hasilt" - ] - }, - "Web/API/HTMLFormElement/reset_event": { - "modified": "2019-04-12T00:18:53.128Z", - "contributors": [ - "estelle", - "zhangchen", - "purcy" - ] - }, - "Web/API/HTMLFormElement/submit": { - "modified": "2020-10-15T21:04:55.526Z", - "contributors": [ - "Nyaasu", - "RainSlide", - "Ende93", - "ziyunfei", - "helloguangxue", - "khalid32" - ] - }, - "Web/API/HTMLFormElement/submit_event": { - "modified": "2019-09-08T10:02:59.774Z", - "contributors": [ - "mynull", - "estelle", - "fscholz", - "yangxiaoqiao" - ] - }, - "Web/API/HTMLHeadElement": { - "modified": "2019-03-23T22:46:18.469Z", - "contributors": [ - "linmx0130" - ] - }, - "Web/API/HTMLHtmlElement": { - "modified": "2019-03-23T22:27:32.393Z", - "contributors": [ - "Dongen", - "Jiang-Xuan", - "ruilee16" - ] - }, - "Web/API/HTMLHtmlElement/version": { - "modified": "2019-03-18T21:38:08.619Z", - "contributors": [ - "Dongen" - ] - }, - "Web/API/HTMLIFrameElement": { - "modified": "2020-07-10T00:21:20.932Z", - "contributors": [ - "Yovven", - "wbamberg", - "Ratin", - "harttle" - ] - }, - "Web/API/HTMLIFrameElement/contentWindow": { - "modified": "2020-10-15T22:29:38.668Z", - "contributors": [ - "meiseayoung" - ] - }, - "Web/API/HTMLImageElement": { - "modified": "2020-10-15T21:37:52.961Z", - "contributors": [ - "qiufeihong2018", - "RainSlide", - "LoveYZY", - "aimiy", - "zhenhua32" - ] - }, - "Web/API/HTMLImageElement/Image": { - "modified": "2019-03-23T22:36:53.099Z", - "contributors": [ - "moonou", - "2lei", - "yuduxyz" - ] - }, - "Web/API/HTMLImageElement/complete": { - "modified": "2020-10-15T22:29:03.657Z", - "contributors": [ - "Fogwind" - ] - }, - "Web/API/HTMLImageElement/decode": { - "modified": "2020-10-15T22:20:49.060Z", - "contributors": [ - "Pada", - "LittleGhost" - ] - }, - "Web/API/HTMLImageElement/decoding": { - "modified": "2020-10-15T22:30:19.899Z", - "contributors": [ - "Hstb1230" - ] - }, - "Web/API/HTMLImageElement/loading": { - "modified": "2020-10-15T22:32:52.862Z", - "contributors": [ - "Insopitus" - ] - }, - "Web/API/HTMLImageElement/referrerPolicy": { - "modified": "2019-07-03T09:07:41.016Z", - "contributors": [ - "shanLan", - "Ahhaha233" - ] - }, - "Web/API/HTMLImageElement/srcset": { - "modified": "2020-10-15T22:25:02.370Z", - "contributors": [ - "yinsang" - ] - }, - "Web/API/HTMLInputElement": { - "modified": "2019-06-25T16:24:46.457Z", - "contributors": [ - "seanhuai", - "SijayZheng", - "zxsunrise", - "fscholz" - ] - }, - "Web/API/HTMLInputElement/invalid_event": { - "modified": "2020-10-15T22:30:08.349Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/HTMLInputElement/labels": { - "modified": "2020-10-15T22:22:05.562Z", - "contributors": [ - "yingying1957" - ] - }, - "Web/API/HTMLInputElement/mozSetFileNameArray": { - "modified": "2019-03-23T23:32:37.731Z", - "contributors": [ - "teoli", - "basemnassar11", - "ziyunfei" - ] - }, - "Web/API/HTMLInputElement/multiple": { - "modified": "2020-10-15T22:22:05.182Z", - "contributors": [ - "yingying1957" - ] - }, - "Web/API/HTMLInputElement/select": { - "modified": "2020-10-15T21:46:17.181Z", - "contributors": [ - "zhangchen", - "houko", - "ezirmusitua", - "holynewbie" - ] - }, - "Web/API/HTMLInputElement/setSelectionRange": { - "modified": "2020-10-15T21:50:45.091Z", - "contributors": [ - "Carllllo", - "ezirmusitua", - "linningmii" - ] - }, - "Web/API/HTMLLIElement": { - "modified": "2020-10-15T22:20:12.878Z", - "contributors": [ - "RainSlide", - "SphinxKnight", - "PlanBB" - ] - }, - "Web/API/HTMLLabelElement": { - "modified": "2019-03-23T22:50:55.570Z", - "contributors": [ - "FredWe" - ] - }, - "Web/API/HTMLLinkElement": { - "modified": "2020-10-15T22:04:39.181Z", - "contributors": [ - "fscholz" - ] - }, - "Web/API/HTMLLinkElement/referrerPolicy": { - "modified": "2020-10-15T22:04:39.965Z", - "contributors": [ - "Ahhaha233" - ] - }, - "Web/API/HTMLMediaElement": { - "modified": "2020-10-15T21:37:52.467Z", - "contributors": [ - "bigben0123", - "Ende93", - "Sunly", - "miaoihan", - "snowlocked", - "chrisdavidmills", - "huhu213", - "zilong-thu", - "FredWe" - ] - }, - "Web/API/HTMLMediaElement/abort_event": { - "modified": "2020-10-15T22:25:33.324Z", - "contributors": [ - "Sunly" - ] - }, - "Web/API/HTMLMediaElement/audioTracks": { - "modified": "2019-03-23T22:41:30.706Z", - "contributors": [ - "haocity", - "hjb2722404", - "young3578671" - ] - }, - "Web/API/HTMLMediaElement/autoplay": { - "modified": "2019-03-23T22:24:22.231Z", - "contributors": [ - "WangHaoming" - ] - }, - "Web/API/HTMLMediaElement/buffered": { - "modified": "2019-03-23T22:23:01.000Z", - "contributors": [ - "wbamberg", - "haocity" - ] - }, - "Web/API/HTMLMediaElement/canPlayType": { - "modified": "2020-10-15T22:05:44.366Z", - "contributors": [ - "wbamberg", - "vvpvvp" - ] - }, - "Web/API/HTMLMediaElement/canplay_event": { - "modified": "2019-03-18T20:49:25.869Z", - "contributors": [ - "estelle", - "fscholz", - "linfengdoor", - "xgqfrms-GitHub" - ] - }, - "Web/API/HTMLMediaElement/canplaythrough_event": { - "modified": "2019-03-18T20:49:29.441Z", - "contributors": [ - "estelle", - "fscholz", - "linfengdoor" - ] - }, - "Web/API/HTMLMediaElement/controller": { - "modified": "2020-10-15T22:25:34.072Z", - "contributors": [ - "Sunly" - ] - }, - "Web/API/HTMLMediaElement/controls": { - "modified": "2019-03-23T22:23:03.409Z", - "contributors": [ - "haocity" - ] - }, - "Web/API/HTMLMediaElement/controlsList": { - "modified": "2020-10-15T22:10:53.059Z", - "contributors": [ - "fxss5201" - ] - }, - "Web/API/HTMLMediaElement/crossOrigin": { - "modified": "2020-10-15T22:27:13.813Z", - "contributors": [ - "jiahui" - ] - }, - "Web/API/HTMLMediaElement/currentSrc": { - "modified": "2020-10-15T22:20:47.251Z", - "contributors": [ - "crazymxm", - "wzwmzm" - ] - }, - "Web/API/HTMLMediaElement/currentTime": { - "modified": "2019-03-18T21:46:21.236Z", - "contributors": [ - "newming" - ] - }, - "Web/API/HTMLMediaElement/duration": { - "modified": "2020-10-15T22:04:39.273Z", - "contributors": [ - "terry-ice" - ] - }, - "Web/API/HTMLMediaElement/durationchange_event": { - "modified": "2020-10-26T09:15:40.859Z", - "contributors": [ - "Asuka109" - ] - }, - "Web/API/HTMLMediaElement/ended_event": { - "modified": "2019-03-18T20:49:28.745Z", - "contributors": [ - "estelle", - "wolfpan" - ] - }, - "Web/API/HTMLMediaElement/error_event": { - "modified": "2020-10-15T22:27:13.933Z", - "contributors": [ - "jiahui" - ] - }, - "Web/API/HTMLMediaElement/load": { - "modified": "2020-10-15T22:24:19.019Z", - "contributors": [ - "jimmyyem" - ] - }, - "Web/API/HTMLMediaElement/loadeddata_event": { - "modified": "2019-03-18T20:49:26.596Z", - "contributors": [ - "estelle", - "fscholz", - "IShinji", - "Iamxiaozhu" - ] - }, - "Web/API/HTMLMediaElement/loadstart_event": { - "modified": "2020-10-15T22:25:10.747Z", - "contributors": [ - "Mr-Wang-Ya" - ] - }, - "Web/API/HTMLMediaElement/loop": { - "modified": "2019-03-18T21:46:14.074Z", - "contributors": [ - "newming" - ] - }, - "Web/API/HTMLMediaElement/muted": { - "modified": "2020-10-15T22:11:31.992Z", - "contributors": [ - "firefish" - ] - }, - "Web/API/HTMLMediaElement/networkState": { - "modified": "2019-03-23T22:03:28.345Z", - "contributors": [ - "EmiliaMiyuki" - ] - }, - "Web/API/HTMLMediaElement/onerror": { - "modified": "2020-10-15T22:20:09.423Z", - "contributors": [ - "HaukWong" - ] - }, - "Web/API/HTMLMediaElement/pause": { - "modified": "2020-10-15T22:29:04.236Z", - "contributors": [ - "xialeistudio", - "crazymxm" - ] - }, - "Web/API/HTMLMediaElement/pause_event": { - "modified": "2020-10-15T22:24:19.462Z", - "contributors": [ - "jimmyyem" - ] - }, - "Web/API/HTMLMediaElement/paused": { - "modified": "2019-03-23T22:23:06.944Z", - "contributors": [ - "haocity" - ] - }, - "Web/API/HTMLMediaElement/play": { - "modified": "2020-10-15T21:50:47.405Z", - "contributors": [ - "Clarkkkk", - "haocity" - ] - }, - "Web/API/HTMLMediaElement/play_event": { - "modified": "2020-10-15T22:32:21.463Z", - "contributors": [ - "ShuZhong" - ] - }, - "Web/API/HTMLMediaElement/playbackRate": { - "modified": "2020-10-15T21:54:58.004Z", - "contributors": [ - "Ende93", - "betseyliu", - "shockw4ver", - "dandanbu3", - "songlairui" - ] - }, - "Web/API/HTMLMediaElement/playing_event": { - "modified": "2019-03-18T20:49:27.148Z", - "contributors": [ - "estelle", - "fscholz", - "IShinji", - "getfile" - ] - }, - "Web/API/HTMLMediaElement/progress_event": { - "modified": "2020-10-15T22:27:43.033Z", - "contributors": [ - "Fancyflame" - ] - }, - "Web/API/HTMLMediaElement/readyState": { - "modified": "2019-03-23T22:22:52.208Z", - "contributors": [ - "oldmtn", - "haocity" - ] - }, - "Web/API/HTMLMediaElement/seekable": { - "modified": "2020-10-15T22:20:08.347Z", - "contributors": [ - "SkyFuInMC" - ] - }, - "Web/API/HTMLMediaElement/src": { - "modified": "2020-10-15T22:10:53.325Z", - "contributors": [ - "Torlinone" - ] - }, - "Web/API/HTMLMediaElement/srcObject": { - "modified": "2020-12-04T03:07:38.030Z", - "contributors": [ - "Andychen", - "q09m10", - "Mukti" - ] - }, - "Web/API/HTMLMediaElement/timeupdate_event": { - "modified": "2020-10-15T21:49:06.102Z", - "contributors": [ - "Ende93", - "estelle", - "fsx950223", - "fscholz", - "aximario" - ] - }, - "Web/API/HTMLMediaElement/videoTracks": { - "modified": "2020-10-15T22:20:48.310Z", - "contributors": [ - "wzwmzm" - ] - }, - "Web/API/HTMLMediaElement/volume": { - "modified": "2020-10-15T22:27:15.201Z", - "contributors": [ - "jiahui" - ] - }, - "Web/API/HTMLOptGroupElement": { - "modified": "2020-10-15T22:30:11.943Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/HTMLOptionElement": { - "modified": "2020-10-15T21:58:14.790Z", - "contributors": [ - "Carllllo", - "garden4hu" - ] - }, - "Web/API/HTMLOptionElement/Option": { - "modified": "2019-03-23T22:03:43.262Z", - "contributors": [ - "Ende93", - "lvgx04" - ] - }, - "Web/API/HTMLParagraphElement": { - "modified": "2020-11-03T10:28:13.003Z", - "contributors": [ - "Verahuan", - "liuwenxiang" - ] - }, - "Web/API/HTMLProgressElement": { - "modified": "2019-03-23T22:02:53.611Z", - "contributors": [ - "fxss5201" - ] - }, - "Web/API/HTMLScriptElement": { - "modified": "2019-03-18T23:58:52.603Z", - "contributors": [ - "807573515", - "anchen", - "wenzi556", - "qqmmgg123" - ] - }, - "Web/API/HTMLSelectElement": { - "modified": "2020-10-15T21:38:11.546Z", - "contributors": [ - "Carllllo", - "yangtoude", - "FredWe" - ] - }, - "Web/API/HTMLSelectElement/add": { - "modified": "2020-10-15T22:30:07.679Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/HTMLSelectElement/checkValidity": { - "modified": "2019-03-23T22:08:34.501Z", - "contributors": [ - "DominicMing" - ] - }, - "Web/API/HTMLSelectElement/remove": { - "modified": "2020-10-15T22:22:52.652Z", - "contributors": [ - "WangLeto" - ] - }, - "Web/API/HTMLSelectElement/selectedIndex": { - "modified": "2020-10-15T21:55:08.030Z", - "contributors": [ - "Carllllo", - "danglisheng", - "lanlingxiaoyizi" - ] - }, - "Web/API/HTMLSelectElement/setCustomValidity": { - "modified": "2019-08-04T00:41:37.477Z", - "contributors": [ - "Kami_Fu", - "tanshaobo", - "xgqfrms-GitHub" - ] - }, - "Web/API/HTMLSlotElement": { - "modified": "2019-03-23T22:16:15.950Z", - "contributors": [ - "xx1124961758" - ] - }, - "Web/API/HTMLSlotElement/name": { - "modified": "2020-10-15T22:10:14.917Z", - "contributors": [ - "codeex" - ] - }, - "Web/API/HTMLSpanElement": { - "modified": "2020-10-15T22:07:03.222Z", - "contributors": [ - "wangxinhe" - ] - }, - "Web/API/HTMLStyleElement": { - "modified": "2020-10-15T22:29:22.451Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/HTMLTableElement": { - "modified": "2020-10-31T19:39:33.225Z", - "contributors": [ - "EbeRybDI", - "RainSlide", - "wangxinhe", - "teoli" - ] - }, - "Web/API/HTMLTableElement/createCaption": { - "modified": "2019-03-18T21:43:09.758Z", - "contributors": [ - "50774283" - ] - }, - "Web/API/HTMLTableElement/deleteTHead": { - "modified": "2020-10-15T21:06:29.521Z", - "contributors": [ - "RainSlide", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/HTMLTableElement/rows": { - "modified": "2019-04-12T08:01:10.696Z", - "contributors": [ - "zuoyixiaoku", - "xgqfrms-GitHub" - ] - }, - "Web/API/HTMLTableRowElement": { - "modified": "2020-10-15T22:30:26.019Z" - }, - "Web/API/HTMLTableRowElement/rowIndex": { - "modified": "2020-06-05T05:35:33.391Z", - "contributors": [ - "sakamoto1984" - ] - }, - "Web/API/HTMLTemplateElement": { - "modified": "2020-10-15T22:04:54.523Z", - "contributors": [ - "jingkaimori", - "zhang-quan-yi" - ] - }, - "Web/API/HTMLTemplateElement/content": { - "modified": "2020-10-15T22:24:01.666Z", - "contributors": [ - "Yayure" - ] - }, - "Web/API/HTMLTextAreaElement": { - "modified": "2020-10-15T21:52:27.752Z", - "contributors": [ - "RainSlide", - "demongodYY", - "AlixWang" - ] - }, - "Web/API/HTMLUnknownElement": { - "modified": "2019-03-23T22:18:56.230Z", - "contributors": [ - "Saltfish" - ] - }, - "Web/API/HTMLVideoElement": { - "modified": "2019-03-18T21:11:15.600Z", - "contributors": [ - "linmx0130", - "zilong-thu" - ] - }, - "Web/API/HTML_DOM_API": { - "modified": "2020-10-15T22:25:06.047Z", - "contributors": [ - "xp44mm" - ] - }, - "Web/API/HTML_DOM_API/Microtask_guide": { - "modified": "2020-01-20T06:32:59.238Z", - "contributors": [ - "Kevin-Xi", - "tonylua" - ] - }, - "Web/API/HTML_DOM_API/Microtask_guide/In_depth": { - "modified": "2020-10-21T00:44:46.830Z", - "contributors": [ - "kuitos", - "yeecai", - "Cinux-Chosan" - ] - }, - "Web/API/HTML_Drag_and_Drop_API": { - "modified": "2020-11-30T01:23:34.543Z", - "contributors": [ - "jingkaimori", - "Clarkkkk", - "Carllllo", - "ppphp", - "RainSlide", - "1056237661", - "suvyme", - "maxsize", - "stevobm", - "liujiajun1993", - "xgqfrms-GitHub", - "esc", - "OhJerry", - "zhuangyin", - "shly", - "hxl", - "yola0316" - ] - }, - "Web/API/HTML_Drag_and_Drop_API/Drag_operations": { - "modified": "2020-06-11T05:30:04.210Z", - "contributors": [ - "Carllllo", - "eforegist", - "xgqfrms-GitHub" - ] - }, - "Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop": { - "modified": "2019-12-23T04:36:06.230Z", - "contributors": [ - "Sherr_Y", - "suvyme" - ] - }, - "Web/API/HTML_Drag_and_Drop_API/Multiple_items": { - "modified": "2020-10-21T09:56:11.699Z", - "contributors": [ - "Oliverz" - ] - }, - "Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types": { - "modified": "2019-03-23T22:11:24.812Z", - "contributors": [ - "plter", - "xgqfrms-GitHub" - ] - }, - "Web/API/HashChangeEvent": { - "modified": "2020-10-15T21:34:06.847Z", - "contributors": [ - "Carllllo", - "RainSlide", - "fscholz", - "wzjg520" - ] - }, - "Web/API/HashChangeEvent/newURL": { - "modified": "2020-10-17T05:19:15.501Z", - "contributors": [ - "trp1119" - ] - }, - "Web/API/HashChangeEvent/oldURL": { - "modified": "2020-10-17T05:12:31.911Z", - "contributors": [ - "trp1119" - ] - }, - "Web/API/Headers": { - "modified": "2019-04-28T03:52:47.091Z", - "contributors": [ - "tobetobe", - "Xmader", - "liyan", - "varcat", - "xgqfrms-GitHub", - "maicss", - "Taoja", - "andward" - ] - }, - "Web/API/Headers/Headers": { - "modified": "2019-03-23T22:07:04.301Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/Headers/append": { - "modified": "2020-10-15T21:49:06.619Z", - "contributors": [ - "jason-grimm", - "Taoja" - ] - }, - "Web/API/Headers/delete": { - "modified": "2019-03-18T21:16:26.289Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/Headers/entries": { - "modified": "2019-03-28T10:22:51.491Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/Headers/get": { - "modified": "2019-06-29T00:58:09.152Z", - "contributors": [ - "chiyougithub", - "Xmader", - "Taoja" - ] - }, - "Web/API/Headers/getAll": { - "modified": "2019-03-23T22:15:47.321Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/Headers/has": { - "modified": "2019-03-18T21:43:54.084Z", - "contributors": [ - "zhengxinxin" - ] - }, - "Web/API/Headers/keys": { - "modified": "2020-10-15T22:19:49.753Z", - "contributors": [ - "rxliuli", - "astonesh" - ] - }, - "Web/API/Headers/set": { - "modified": "2020-10-15T22:19:50.256Z", - "contributors": [ - "astonesh" - ] - }, - "Web/API/Headers/values": { - "modified": "2020-10-15T22:19:49.502Z", - "contributors": [ - "astonesh" - ] - }, - "Web/API/History": { - "modified": "2020-11-15T08:56:49.154Z", - "contributors": [ - "thefirst-ma", - "zhuangyin", - "yanhaijing1234", - "tys", - "matthewshine", - "sansx", - "SandersXin", - "nbwsc", - "thomaslwq", - "ganlyun", - "CharlesWu", - "xgqfrms-GitHub", - "Cmen", - "xiongwilee" - ] - }, - "Web/API/History/back": { - "modified": "2020-10-15T22:22:47.134Z", - "contributors": [ - "c1er" - ] - }, - "Web/API/History/forward": { - "modified": "2020-10-15T22:22:46.563Z", - "contributors": [ - "c1er" - ] - }, - "Web/API/History/go": { - "modified": "2020-10-15T22:22:46.466Z", - "contributors": [ - "c1er" - ] - }, - "Web/API/History/length": { - "modified": "2020-10-15T22:06:51.004Z", - "contributors": [ - "chenqingyue", - "poppyLuo" - ] - }, - "Web/API/History/pushState": { - "modified": "2020-11-26T09:40:16.892Z", - "contributors": [ - "iamsjh", - "Junezm", - "bobzhen", - "bazinga-web", - "RainSlide", - "zhangchen", - "woody-li", - "Rudy24", - "Atester", - "zhe13" - ] - }, - "Web/API/History/replaceState": { - "modified": "2020-10-15T22:24:19.838Z", - "contributors": [ - "HytonightYX", - "dushaobindoudou" - ] - }, - "Web/API/History/scrollRestoration": { - "modified": "2020-10-15T22:30:02.596Z", - "contributors": [ - "Orime112" - ] - }, - "Web/API/History/state": { - "modified": "2020-10-15T22:23:03.493Z", - "contributors": [ - "littlebiao" - ] - }, - "Web/API/History_API": { - "modified": "2020-10-15T21:55:01.770Z", - "contributors": [ - "guigechen", - "ysyfff", - "Ende93", - "BluesVN", - "lmislm", - "skyline-123", - "zrefrain", - "xgqfrms", - "notmaster", - "houyonglu", - "Emsigant", - "suyanhanx", - "jackYouth", - "LGerry", - "Jessy.D.", - "LZM", - "wzx", - "eightHundreds", - "keshidong", - "xgqfrms-GitHub" - ] - }, - "Web/API/History_API/Example": { - "modified": "2019-07-31T00:29:31.092Z", - "contributors": [ - "Shadowhiker", - "xgqfrms" - ] - }, - "Web/API/History_API/Working_with_the_History_API": { - "modified": "2020-09-07T23:10:09.451Z", - "contributors": [ - "Nothing_bin" - ] - }, - "Web/API/IDBCursor": { - "modified": "2020-06-09T04:18:42.839Z", - "contributors": [ - "Zengyufa", - "teoli" - ] - }, - "Web/API/IDBCursor/direction": { - "modified": "2019-03-23T23:07:34.901Z", - "contributors": [ - "teoli", - "linkwisdom" - ] - }, - "Web/API/IDBCursor/key": { - "modified": "2019-03-18T21:43:09.610Z", - "contributors": [ - "Elaine87" - ] - }, - "Web/API/IDBCursorSync": { - "modified": "2019-03-18T21:28:52.330Z", - "contributors": [ - "cryingbat" - ] - }, - "Web/API/IDBDatabase": { - "modified": "2020-12-07T11:09:48.090Z", - "contributors": [ - "greennn", - "washstar", - "luckyqiao", - "Monokai" - ] - }, - "Web/API/IDBDatabase/createObjectStore": { - "modified": "2020-10-15T22:04:54.213Z", - "contributors": [ - "zquancai", - "PWAEZQS" - ] - }, - "Web/API/IDBDatabase/deleteObjectStore": { - "modified": "2020-10-15T22:22:51.946Z", - "contributors": [ - "zquancai" - ] - }, - "Web/API/IDBDatabase/onversionchange": { - "modified": "2020-10-15T22:17:00.625Z", - "contributors": [ - "seawin" - ] - }, - "Web/API/IDBEnvironment": { - "modified": "2020-10-15T22:16:53.762Z", - "contributors": [ - "CiaoLee" - ] - }, - "Web/API/IDBFactory": { - "modified": "2019-04-08T01:11:15.339Z", - "contributors": [ - "yzdd", - "Bayes", - "ZeroJsus", - "w05163", - "teoli" - ] - }, - "Web/API/IDBFactory/open": { - "modified": "2019-03-23T23:19:24.764Z", - "contributors": [ - "teoli", - "023yangbo" - ] - }, - "Web/API/IDBIndex": { - "modified": "2020-10-25T12:41:13.535Z", - "contributors": [ - "Thinker-Mars", - "list", - "focus" - ] - }, - "Web/API/IDBKeyRange": { - "modified": "2020-10-15T22:23:11.497Z", - "contributors": [ - "gkalpak" - ] - }, - "Web/API/IDBKeyRange/lowerBound": { - "modified": "2020-10-15T22:23:13.723Z", - "contributors": [ - "LuciusMa" - ] - }, - "Web/API/IDBObjectStore": { - "modified": "2020-10-15T21:21:10.593Z", - "contributors": [ - "dancci", - "xgqfrms", - "celdr", - "Sebastianz", - "teoli", - "ziyunfei", - "ZhangJianxiang" - ] - }, - "Web/API/IDBObjectStore/add": { - "modified": "2020-10-15T22:30:29.763Z", - "contributors": [ - "Zengyufa" - ] - }, - "Web/API/IDBObjectStore/autoIncrement": { - "modified": "2020-10-15T22:08:32.902Z", - "contributors": [ - "tangshuang" - ] - }, - "Web/API/IDBObjectStore/get": { - "modified": "2020-10-15T22:30:50.265Z", - "contributors": [ - "x1shi" - ] - }, - "Web/API/IDBObjectStore/indexNames": { - "modified": "2020-10-15T22:30:03.349Z", - "contributors": [ - "x1shi" - ] - }, - "Web/API/IDBObjectStore/keyPath": { - "modified": "2020-10-15T22:08:30.753Z", - "contributors": [ - "tangshuang" - ] - }, - "Web/API/IDBObjectStore/openCursor": { - "modified": "2019-04-24T23:53:33.656Z", - "contributors": [ - "KnowNothing", - "teoli", - "looch" - ] - }, - "Web/API/IDBObjectStore/put": { - "modified": "2020-10-15T22:25:34.498Z", - "contributors": [ - "pjshu" - ] - }, - "Web/API/IDBOpenDBRequest": { - "modified": "2020-10-15T22:07:32.003Z", - "contributors": [ - "Bayes" - ] - }, - "Web/API/IDBRequest": { - "modified": "2019-03-23T23:25:34.147Z", - "contributors": [ - "teoli", - "thankwsx" - ] - }, - "Web/API/IDBTransaction": { - "modified": "2019-03-23T23:05:06.894Z", - "contributors": [ - "lightrabbit", - "dawangraoming", - "teoli", - "looch" - ] - }, - "Web/API/IDBTransaction/complete_event": { - "modified": "2020-10-15T22:26:06.000Z", - "contributors": [ - "manmangirlgirl" - ] - }, - "Web/API/IDBTransaction/db": { - "modified": "2020-10-15T22:04:51.966Z", - "contributors": [ - "lightrabbit" - ] - }, - "Web/API/IdleDeadline": { - "modified": "2019-09-25T03:43:20.441Z", - "contributors": [ - "xueliang", - "Ende93", - "a372210777" - ] - }, - "Web/API/IdleDeadline/timeRemaining": { - "modified": "2020-10-15T22:32:38.084Z", - "contributors": [ - "cvSoldier" - ] - }, - "Web/API/ImageBitmap": { - "modified": "2019-03-23T22:33:11.188Z", - "contributors": [ - "Serifx" - ] - }, - "Web/API/ImageBitmap/height": { - "modified": "2020-10-15T22:03:39.373Z", - "contributors": [ - "Mactaivsh" - ] - }, - "Web/API/ImageBitmap/width": { - "modified": "2020-10-15T22:03:31.857Z", - "contributors": [ - "Mactaivsh" - ] - }, - "Web/API/ImageBitmapRenderingContext": { - "modified": "2020-10-15T22:03:31.474Z", - "contributors": [ - "teoli", - "jjc" - ] - }, - "Web/API/ImageData": { - "modified": "2020-10-15T21:06:27.025Z", - "contributors": [ - "laampui", - "LaneSun", - "Zhang-Junzhi", - "vigrodong", - "ice-i-snow", - "teoli", - "ziyunfei" - ] - }, - "Web/API/ImageData/ImageData": { - "modified": "2020-10-15T21:37:09.801Z", - "contributors": [ - "bbaa-bbaa", - "ice-i-snow" - ] - }, - "Web/API/ImageData/data": { - "modified": "2019-03-23T22:53:07.232Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/ImageData/height": { - "modified": "2019-03-23T22:53:09.636Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/ImageData/width": { - "modified": "2019-03-23T22:53:09.971Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/IndexedDB_API": { - "modified": "2020-08-17T03:58:13.141Z", - "contributors": [ - "lsvih", - "崮生", - "bytetown", - "zhangyunhai210", - "danmin25", - "grape", - "xgqfrms", - "jason-grimm", - "hooozen", - "Xavier-GZ", - "jasonjifly", - "xgqfrms-GitHub", - "roughwin", - "FideoJ", - "Taoja", - "ziyunfei", - "023yangbo", - "princetoad@gmail.com" - ] - }, - "Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB": { - "modified": "2019-09-29T21:07:32.199Z", - "contributors": [ - "Nonym", - "Zaynex", - "nztraveler", - "hooozen", - "SphinxKnight", - "gaoryrt", - "WenWu92", - "Yongest", - "RyanBeauclerc", - "em2046", - "ywwzwb", - "ziyunfei", - "mountainmoon", - "Fify", - "teoli", - "goldWind", - "karsa.si" - ] - }, - "Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria": { - "modified": "2019-06-14T00:02:23.198Z", - "contributors": [ - "flyingjust", - "jason-grimm", - "ShaojieLiu", - "Bayes", - "wenshin" - ] - }, - "Web/API/IndexedDB_API/Checking_when_a_deadline_is_due": { - "modified": "2019-04-24T01:51:23.669Z", - "contributors": [ - "jason-guo" - ] - }, - "Web/API/IndexedDB_API/Using_IndexedDB": { - "modified": "2019-12-08T23:24:54.520Z", - "contributors": [ - "Dennis273", - "thxl2010", - "microchang", - "zimocode", - "hooozen", - "luoxzhg", - "HJava", - "BreezeDealer", - "fireswork", - "johncido", - "ziyunfei", - "princetoad@gmail.com", - "karsa.si" - ] - }, - "Web/API/InputEvent": { - "modified": "2020-10-15T21:45:35.936Z", - "contributors": [ - "bbaa-bbaa", - "ziyunfei" - ] - }, - "Web/API/InputEvent/InputEvent": { - "modified": "2020-10-15T22:27:25.363Z", - "contributors": [ - "MCCF" - ] - }, - "Web/API/InputEvent/data": { - "modified": "2020-10-15T22:27:26.531Z", - "contributors": [ - "MCCF" - ] - }, - "Web/API/InputEvent/dataTransfer": { - "modified": "2020-10-15T22:27:27.757Z", - "contributors": [ - "MCCF" - ] - }, - "Web/API/InputEvent/inputType": { - "modified": "2020-10-15T22:27:27.843Z", - "contributors": [ - "MCCF" - ] - }, - "Web/API/InputEvent/isComposing": { - "modified": "2019-03-23T22:20:41.480Z", - "contributors": [ - "xiaobudongzhang" - ] - }, - "Web/API/InstallEvent": { - "modified": "2019-03-23T22:11:57.321Z", - "contributors": [ - "johnlin0207", - "flyingsouthwind" - ] - }, - "Web/API/IntersectionObserver": { - "modified": "2020-10-15T21:53:41.967Z", - "contributors": [ - "ZivHe", - "SolitudeRA", - "jpmedley" - ] - }, - "Web/API/IntersectionObserver/IntersectionObserver": { - "modified": "2020-10-15T21:56:20.681Z", - "contributors": [ - "zhangchen", - "timelessover", - "SolitudeRA" - ] - }, - "Web/API/IntersectionObserver/disconnect": { - "modified": "2020-10-15T21:58:19.365Z", - "contributors": [ - "zhangchen", - "magecn" - ] - }, - "Web/API/IntersectionObserver/observe": { - "modified": "2020-10-15T22:17:36.387Z", - "contributors": [ - "callmezhenzhen" - ] - }, - "Web/API/IntersectionObserver/root": { - "modified": "2019-03-23T22:13:38.054Z", - "contributors": [ - "ziyunfei" - ] - }, - "Web/API/IntersectionObserver/rootMargin": { - "modified": "2020-10-15T21:56:21.340Z", - "contributors": [ - "SolitudeRA" - ] - }, - "Web/API/IntersectionObserver/takeRecords": { - "modified": "2020-10-15T22:22:05.768Z", - "contributors": [ - "lmislm" - ] - }, - "Web/API/IntersectionObserver/thresholds": { - "modified": "2020-10-15T22:20:27.525Z", - "contributors": [ - "weiwentao518" - ] - }, - "Web/API/IntersectionObserver/unobserve": { - "modified": "2020-10-15T21:58:17.503Z", - "contributors": [ - "magecn" - ] - }, - "Web/API/IntersectionObserverEntry": { - "modified": "2020-10-15T21:56:47.926Z", - "contributors": [ - "shevche24", - "zcWSR" - ] - }, - "Web/API/Intersection_Observer_API": { - "modified": "2020-11-26T22:25:36.849Z", - "contributors": [ - "yulei", - "nishuzumi", - "chunnallu", - "wxyads", - "MinimalistYing", - "nemoh", - "hardo", - "lmislm", - "ZivHe", - "cyrilluce", - "iahu", - "varcat", - "joshchiucn", - "a372210777", - "DearVikki", - "xrr2016" - ] - }, - "Web/API/Intersection_Observer_API/点观察者API的时序元素可见性": { - "modified": "2019-03-23T22:11:40.163Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/Keyboard": { - "modified": "2020-10-15T22:23:40.344Z", - "contributors": [ - "Abnori" - ] - }, - "Web/API/KeyboardEvent": { - "modified": "2020-11-12T03:12:03.742Z", - "contributors": [ - "liguorain", - "hahaliangchen", - "Carllllo", - "fscholz", - "wbamberg", - "Ende93", - "522211qaa", - "teoli", - "ziyunfei" - ] - }, - "Web/API/KeyboardEvent/KeyboardEvent": { - "modified": "2019-09-25T23:44:21.954Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/API/KeyboardEvent/altKey": { - "modified": "2019-03-18T21:42:29.777Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/API/KeyboardEvent/charCode": { - "modified": "2019-03-18T21:42:20.558Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/API/KeyboardEvent/code": { - "modified": "2020-10-15T21:51:32.586Z", - "contributors": [ - "zhuangyin", - "Dcfm" - ] - }, - "Web/API/KeyboardEvent/ctrlKey": { - "modified": "2019-03-18T21:42:31.699Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/API/KeyboardEvent/initKeyEvent": { - "modified": "2019-03-18T21:15:27.272Z", - "contributors": [ - "bingxl", - "ply", - "Wonder233" - ] - }, - "Web/API/KeyboardEvent/isComposing": { - "modified": "2019-03-18T21:42:28.026Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/API/KeyboardEvent/key": { - "modified": "2020-10-15T21:51:27.323Z", - "contributors": [ - "millaCheung", - "Roy-Tian", - "maicss", - "Dcfm" - ] - }, - "Web/API/KeyboardEvent/key/Key_Values": { - "modified": "2019-07-18T03:45:00.126Z", - "contributors": [ - "sjpeter", - "SphinxKnight", - "XHMM" - ] - }, - "Web/API/KeyboardEvent/keyCode": { - "modified": "2020-10-15T22:01:35.012Z", - "contributors": [ - "jerryhwq", - "ninelords", - "CocoRoise", - "zengjiaxu", - "zhaoxieluoke" - ] - }, - "Web/API/KeyboardEvent/location": { - "modified": "2020-10-15T22:17:50.558Z", - "contributors": [ - "yanwei5322" - ] - }, - "Web/API/KeyboardEvent/metaKey": { - "modified": "2020-10-15T21:36:01.261Z", - "contributors": [ - "zhangchen", - "AlexChao" - ] - }, - "Web/API/KeyboardEvent/repeat": { - "modified": "2019-03-23T22:10:50.187Z", - "contributors": [ - "maicss" - ] - }, - "Web/API/KeyboardEvent/shiftKey": { - "modified": "2019-10-10T16:55:41.645Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/API/KeyboardEvent/which": { - "modified": "2020-10-15T22:35:00.980Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/API/LocalFileSystemSync": { - "modified": "2019-03-23T22:09:04.520Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/API/Location": { - "modified": "2019-09-21T03:45:45.370Z", - "contributors": [ - "Melo.HG", - "xgqfrms-GitHub", - "linmx0130", - "AlexChao" - ] - }, - "Web/API/Location/assign": { - "modified": "2020-10-15T21:48:42.284Z", - "contributors": [ - "RainSlide", - "mysmlz", - "LiuYuan", - "luyouxin84" - ] - }, - "Web/API/Location/hash": { - "modified": "2020-10-15T22:30:46.937Z", - "contributors": [ - "wuyou" - ] - }, - "Web/API/Location/host": { - "modified": "2020-10-21T09:06:39.663Z", - "contributors": [ - "fanyizhen" - ] - }, - "Web/API/Location/hostname": { - "modified": "2020-10-21T09:06:11.667Z", - "contributors": [ - "fanyizhen" - ] - }, - "Web/API/Location/href": { - "modified": "2020-10-15T22:29:38.493Z", - "contributors": [ - "Owen-Tsai" - ] - }, - "Web/API/Location/reload": { - "modified": "2019-09-05T06:12:44.234Z", - "contributors": [ - "Lori25", - "jianzhou520", - "ziyunfei" - ] - }, - "Web/API/Location/replace": { - "modified": "2020-10-15T21:26:20.972Z", - "contributors": [ - "flashYang", - "RainSlide", - "teoli", - "monjer" - ] - }, - "Web/API/Location/search": { - "modified": "2020-10-21T07:04:50.995Z", - "contributors": [ - "fanyizhen" - ] - }, - "Web/API/Location/toString": { - "modified": "2020-10-19T03:38:36.478Z", - "contributors": [ - "Sxxxx-x" - ] - }, - "Web/API/LockedFile": { - "modified": "2019-03-23T22:12:20.973Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/Long_Tasks_API": { - "modified": "2020-10-15T22:18:48.616Z", - "contributors": [ - "Li-saltair", - "koolc" - ] - }, - "Web/API/MIDIAccess": { - "modified": "2020-10-15T21:53:29.345Z", - "contributors": [ - "bershanskiy", - "tlos142857", - "micblo" - ] - }, - "Web/API/MIDIConnectionEvent": { - "modified": "2020-10-15T22:12:11.573Z", - "contributors": [ - "tlos142857" - ] - }, - "Web/API/MSSelection": { - "modified": "2020-02-27T01:47:20.687Z", - "contributors": [ - "MCCF" - ] - }, - "Web/API/MathMLElement": { - "modified": "2020-10-15T22:28:40.535Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/API/MediaCapabilitiesInfo": { - "modified": "2020-10-15T22:18:18.850Z", - "contributors": [ - "mmdext" - ] - }, - "Web/API/MediaDevices": { - "modified": "2020-10-15T21:49:09.617Z", - "contributors": [ - "SDUTWSL", - "DarnellChen", - "RainSlide", - "wwdn7", - "webber007", - "Victorystick" - ] - }, - "Web/API/MediaDevices/devicechange_event": { - "modified": "2019-04-30T13:59:28.469Z", - "contributors": [ - "wbamberg", - "fscholz", - "xiaosongxiaosong" - ] - }, - "Web/API/MediaDevices/enumerateDevices": { - "modified": "2020-10-15T21:50:42.089Z", - "contributors": [ - "RainSlide", - "mmdext", - "lightrabbit" - ] - }, - "Web/API/MediaDevices/getDisplayMedia": { - "modified": "2020-10-15T22:19:40.156Z", - "contributors": [ - "zhangwenwen12138", - "SphinxKnight", - "estKey", - "w3cways", - "liumingsongning" - ] - }, - "Web/API/MediaDevices/getSupportedConstraints": { - "modified": "2019-03-23T22:09:01.675Z", - "contributors": [ - "SolitudeRA" - ] - }, - "Web/API/MediaDevices/getUserMedia": { - "modified": "2020-10-15T21:49:09.210Z", - "contributors": [ - "Ende93", - "Xiaohantx", - "luojia", - "SolitudeRA", - "xgqfrms-GitHub", - "c1ngular" - ] - }, - "Web/API/MediaDevices/ondevicechange": { - "modified": "2019-03-23T22:08:09.338Z", - "contributors": [ - "qzn928" - ] - }, - "Web/API/MediaElementAudioSourceNode": { - "modified": "2019-03-23T22:09:55.508Z", - "contributors": [ - "Corps" - ] - }, - "Web/API/MediaKeySession": { - "modified": "2019-03-23T22:06:29.595Z", - "contributors": [ - "Sheppy" - ] - }, - "Web/API/MediaKeySession/load": { - "modified": "2019-03-23T22:06:32.766Z", - "contributors": [ - "Ende93", - "srainSu" - ] - }, - "Web/API/MediaList": { - "modified": "2020-10-15T22:29:23.197Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/MediaQueryList": { - "modified": "2019-03-23T23:15:38.017Z", - "contributors": [ - "teoli", - "focus", - "ziyunfei" - ] - }, - "Web/API/MediaQueryList/addListener": { - "modified": "2020-10-15T22:29:47.542Z", - "contributors": [ - "wallena3" - ] - }, - "Web/API/MediaRecorder": { - "modified": "2020-04-22T06:56:14.834Z", - "contributors": [ - "ZouYj", - "forgamer", - "dstyxy", - "leonayx123", - "knimet" - ] - }, - "Web/API/MediaRecorder/MediaRecorder": { - "modified": "2020-10-15T22:19:47.575Z", - "contributors": [ - "forgamer" - ] - }, - "Web/API/MediaRecorder/audioBitsPerSecond": { - "modified": "2020-10-15T22:19:47.663Z", - "contributors": [ - "forgamer" - ] - }, - "Web/API/MediaRecorder/isTypeSupported": { - "modified": "2019-06-06T05:26:50.779Z", - "contributors": [ - "forgamer", - "Ende93", - "wakingking77" - ] - }, - "Web/API/MediaRecorder/ondataavailable": { - "modified": "2020-10-15T22:28:21.731Z", - "contributors": [ - "BMud", - "baixiaocun" - ] - }, - "Web/API/MediaRecorder/pause": { - "modified": "2020-10-15T22:22:08.111Z", - "contributors": [ - "FionaWong" - ] - }, - "Web/API/MediaSession": { - "modified": "2020-02-02T19:09:01.605Z", - "contributors": [ - "TExL", - "Corps" - ] - }, - "Web/API/MediaSession/setActionHandler": { - "modified": "2020-10-15T22:26:53.093Z", - "contributors": [ - "Tangel", - "TExL" - ] - }, - "Web/API/MediaSource": { - "modified": "2020-10-15T21:54:54.501Z", - "contributors": [ - "Chaos33", - "cpdyj", - "Shangxin", - "maicss" - ] - }, - "Web/API/MediaSource/MediaSource": { - "modified": "2020-10-15T22:24:19.874Z", - "contributors": [ - "dushaobindoudou" - ] - }, - "Web/API/MediaSource/addSourceBuffer": { - "modified": "2019-03-23T22:09:10.431Z", - "contributors": [ - "Shangxin" - ] - }, - "Web/API/MediaSource/duration": { - "modified": "2020-10-15T22:24:19.924Z", - "contributors": [ - "dushaobindoudou" - ] - }, - "Web/API/MediaSource/endOfStream": { - "modified": "2020-10-15T22:03:54.397Z", - "contributors": [ - "shuding" - ] - }, - "Web/API/MediaSource/readyState": { - "modified": "2019-03-23T22:07:59.908Z", - "contributors": [ - "cpdyj" - ] - }, - "Web/API/MediaStream": { - "modified": "2020-10-15T21:34:18.501Z", - "contributors": [ - "bbaa-bbaa", - "kevinaskin", - "Cattla", - "luojia" - ] - }, - "Web/API/MediaStream.addTrack": { - "modified": "2019-03-23T22:37:09.665Z", - "contributors": [ - "w05163" - ] - }, - "Web/API/MediaStream/MediaStream": { - "modified": "2020-10-15T22:22:53.267Z", - "contributors": [ - "OceanKuma" - ] - }, - "Web/API/MediaStream/active": { - "modified": "2020-10-15T22:30:06.461Z", - "contributors": [ - "lds33663366" - ] - }, - "Web/API/MediaStream/clone": { - "modified": "2020-10-15T22:11:19.464Z", - "contributors": [ - "ClothArt" - ] - }, - "Web/API/MediaStream/getAudioTracks": { - "modified": "2020-10-15T22:24:04.958Z", - "contributors": [ - "beiding110" - ] - }, - "Web/API/MediaStream/getTracks": { - "modified": "2020-10-15T22:24:00.973Z", - "contributors": [ - "beiding110" - ] - }, - "Web/API/MediaStream/id": { - "modified": "2019-03-18T21:16:45.692Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/MediaStreamAudioSourceNode": { - "modified": "2019-05-06T04:46:44.390Z", - "contributors": [ - "maicss" - ] - }, - "Web/API/MediaStreamAudioSourceNode/MediaStreamAudioSourceNode": { - "modified": "2019-03-23T22:08:27.431Z", - "contributors": [ - "maicss" - ] - }, - "Web/API/MediaStreamEvent": { - "modified": "2019-03-18T21:41:18.186Z", - "contributors": [ - "Mincle" - ] - }, - "Web/API/MediaStreamTrack": { - "modified": "2019-03-23T23:06:36.944Z", - "contributors": [ - "horsefaced", - "Wunmest" - ] - }, - "Web/API/MediaStreamTrack/getCapabilities": { - "modified": "2020-10-15T22:03:28.712Z", - "contributors": [ - "jjc" - ] - }, - "Web/API/MediaStreamTrack/getConstraints": { - "modified": "2020-10-15T22:03:21.588Z", - "contributors": [ - "bingxl", - "313453488" - ] - }, - "Web/API/MediaStreamTrack/readyState": { - "modified": "2020-10-15T22:31:39.113Z", - "contributors": [ - "lizzxc" - ] - }, - "Web/API/MediaStreamTrack/stop": { - "modified": "2020-10-15T22:31:38.664Z", - "contributors": [ - "lizzxc" - ] - }, - "Web/API/MediaStream_Recording_API": { - "modified": "2020-08-19T03:57:55.620Z", - "contributors": [ - "Yukiniro", - "longwayya", - "Sheppy" - ] - }, - "Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API": { - "modified": "2019-04-01T03:51:50.008Z", - "contributors": [ - "dxyqqs", - "wonschangge" - ] - }, - "Web/API/MediaTrackConstraints": { - "modified": "2020-01-15T00:27:21.571Z", - "contributors": [ - "2071534594", - "webber007" - ] - }, - "Web/API/Media_Source_Extensions_API": { - "modified": "2019-06-03T00:30:57.632Z", - "contributors": [ - "758915145", - "maicss", - "xcffl" - ] - }, - "Web/API/Media_Streams_API": { - "modified": "2020-10-15T21:43:49.900Z", - "contributors": [ - "StorytellerF", - "lxyion", - "yzweb2018", - "w05163" - ] - }, - "Web/API/MessageChannel": { - "modified": "2020-10-15T21:53:04.720Z", - "contributors": [ - "zhangchen", - "chrisdavidmills", - "ansike", - "cddsgtc", - "Ende93", - "mona", - "lonphy", - "bingou" - ] - }, - "Web/API/MessageChannel/MessageChannel": { - "modified": "2020-10-15T22:13:51.432Z", - "contributors": [ - "cheiron", - "curry" - ] - }, - "Web/API/MessageChannel/port1": { - "modified": "2019-03-23T22:09:56.743Z", - "contributors": [ - "lonphy" - ] - }, - "Web/API/MessageChannel/port2": { - "modified": "2019-03-18T21:31:55.219Z", - "contributors": [ - "ceido" - ] - }, - "Web/API/MessageEvent": { - "modified": "2019-03-23T22:57:49.730Z", - "contributors": [ - "MaxTime", - "xgqfrms-GitHub", - "Cattla", - "vivaxy", - "ziyunfei", - "uniquefeng" - ] - }, - "Web/API/MessageEvent/MessageEvent": { - "modified": "2019-03-18T21:29:00.687Z", - "contributors": [ - "xiaoyixiang" - ] - }, - "Web/API/MessagePort": { - "modified": "2020-10-15T21:52:40.686Z", - "contributors": [ - "cheiron", - "libbymc" - ] - }, - "Web/API/MessagePort/onmessage": { - "modified": "2019-03-23T22:16:44.635Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/MimeType": { - "modified": "2019-03-23T22:09:14.611Z", - "contributors": [ - "sudoor", - "Halfsugarbar" - ] - }, - "Web/API/MouseEvent": { - "modified": "2020-10-15T21:33:54.768Z", - "contributors": [ - "zhangchen", - "fedorjia", - "doodlewind", - "Charley-Hsu", - "zhanglongdream", - "jimwmg", - "Dcfm", - "ziyunfei", - "qovciu" - ] - }, - "Web/API/MouseEvent/MouseEvent": { - "modified": "2020-10-15T21:49:05.401Z", - "contributors": [ - "huming3272", - "RainSlide", - "army8735" - ] - }, - "Web/API/MouseEvent/altKey": { - "modified": "2019-03-23T22:24:24.811Z", - "contributors": [ - "luckyqiao" - ] - }, - "Web/API/MouseEvent/button": { - "modified": "2020-10-15T21:51:25.745Z", - "contributors": [ - "Mookiepiece", - "QZhongyi", - "franose371", - "Dcfm" - ] - }, - "Web/API/MouseEvent/buttons": { - "modified": "2019-11-17T16:12:33.128Z", - "contributors": [ - "Blacktodreamlight", - "isun", - "liuzihao", - "crazybear" - ] - }, - "Web/API/MouseEvent/clientX": { - "modified": "2020-10-15T21:37:27.689Z", - "contributors": [ - "ZZES_REN", - "toastsgithub", - "Agrimonia", - "Tienyz" - ] - }, - "Web/API/MouseEvent/clientY": { - "modified": "2020-10-15T21:55:36.426Z", - "contributors": [ - "ZZES_REN", - "linfengdoor" - ] - }, - "Web/API/MouseEvent/ctrlKey": { - "modified": "2019-03-23T22:58:42.384Z", - "contributors": [ - "KtfwyCJ", - "AlexChao" - ] - }, - "Web/API/MouseEvent/getModifierState": { - "modified": "2020-10-15T22:11:39.690Z", - "contributors": [ - "fengchunsgit" - ] - }, - "Web/API/MouseEvent/initMouseEvent": { - "modified": "2019-03-23T22:27:29.232Z", - "contributors": [ - "army8735" - ] - }, - "Web/API/MouseEvent/metaKey": { - "modified": "2019-03-23T22:59:12.493Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/API/MouseEvent/movementX": { - "modified": "2019-03-23T22:06:04.444Z", - "contributors": [ - "toastsgithub" - ] - }, - "Web/API/MouseEvent/movementY": { - "modified": "2019-03-18T21:38:53.627Z", - "contributors": [ - "QZhongyi", - "LoveofRedMoon" - ] - }, - "Web/API/MouseEvent/mozInputSource": { - "modified": "2019-03-18T21:36:49.830Z", - "contributors": [ - "QZhongyi" - ] - }, - "Web/API/MouseEvent/offsetX": { - "modified": "2019-03-23T22:03:20.313Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/API/MouseEvent/offsetY": { - "modified": "2019-03-23T22:03:18.169Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/API/MouseEvent/pageX": { - "modified": "2019-09-13T23:26:41.418Z", - "contributors": [ - "litmonw", - "Charley-Hsu" - ] - }, - "Web/API/MouseEvent/pageY": { - "modified": "2019-03-23T22:05:15.893Z", - "contributors": [ - "shockw4ver" - ] - }, - "Web/API/MouseEvent/region": { - "modified": "2020-10-15T22:11:39.427Z", - "contributors": [ - "fengchunsgit" - ] - }, - "Web/API/MouseEvent/relatedTarget": { - "modified": "2020-10-15T22:15:01.671Z", - "contributors": [ - "lx544690189" - ] - }, - "Web/API/MouseEvent/screenX": { - "modified": "2020-10-15T21:58:31.278Z", - "contributors": [ - "Clarkkkk", - "snowHe2017" - ] - }, - "Web/API/MouseEvent/screenY": { - "modified": "2020-06-21T14:33:10.261Z", - "contributors": [ - "Clarkkkk", - "LoveofRedMoon" - ] - }, - "Web/API/MouseEvent/shiftKey": { - "modified": "2019-03-23T22:20:33.463Z", - "contributors": [ - "Dcfm" - ] - }, - "Web/API/MouseEvent/which": { - "modified": "2019-03-18T21:11:17.379Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/API/MouseEvent/x": { - "modified": "2019-03-23T22:05:16.814Z", - "contributors": [ - "shockw4ver" - ] - }, - "Web/API/MouseEvent/y": { - "modified": "2019-03-23T22:03:16.740Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/API/MouseScrollEvent": { - "modified": "2019-09-16T04:51:43.533Z", - "contributors": [ - "fscholz", - "ziyunfei", - "teoli" - ] - }, - "Web/API/MouseWheelEvent": { - "modified": "2019-03-23T23:38:38.526Z", - "contributors": [ - "ziyunfei", - "teoli" - ] - }, - "Web/API/MutationObserver": { - "modified": "2020-10-15T21:21:10.567Z", - "contributors": [ - "symant233", - "gentlecoder", - "Carllllo", - "zhaodidong", - "kilohaty", - "xgqfrms", - "zhangchen", - "jerrybendy", - "doterlin", - "ChrisCindy", - "noiron", - "fengw", - "teoli", - "tiansh", - "ziyunfei" - ] - }, - "Web/API/MutationObserver/MutationObserver": { - "modified": "2020-10-15T22:06:20.271Z", - "contributors": [ - "RainSlide", - "WangLeto", - "liucity", - "ceido" - ] - }, - "Web/API/MutationObserver/disconnect": { - "modified": "2020-10-15T22:14:51.873Z", - "contributors": [ - "Y____C" - ] - }, - "Web/API/MutationObserver/observe": { - "modified": "2020-10-15T22:13:52.414Z", - "contributors": [ - "RainSlide", - "lmislm", - "Y____C", - "YouHan26" - ] - }, - "Web/API/MutationObserver/takeRecords": { - "modified": "2020-10-15T22:14:49.124Z", - "contributors": [ - "Y____C" - ] - }, - "Web/API/MutationObserverInit": { - "modified": "2020-10-15T22:14:47.970Z", - "contributors": [ - "RainSlide", - "Y____C" - ] - }, - "Web/API/MutationObserverInit/attributeFilter": { - "modified": "2020-10-15T22:30:44.792Z", - "contributors": [ - "hefang" - ] - }, - "Web/API/MutationObserverInit/childList": { - "modified": "2020-10-15T22:16:10.551Z", - "contributors": [ - "kivazqy" - ] - }, - "Web/API/MutationRecord": { - "modified": "2020-10-15T21:50:28.333Z", - "contributors": [ - "RainSlide", - "lmislm", - "Visper" - ] - }, - "Web/API/NameList": { - "modified": "2019-03-23T22:46:53.836Z", - "contributors": [ - "MeCKodo" - ] - }, - "Web/API/NamedNodeMap": { - "modified": "2019-03-23T23:03:50.009Z", - "contributors": [ - "phoenix_in_the_sky", - "AlexChao" - ] - }, - "Web/API/NamedNodeMap/getNamedItem": { - "modified": "2020-10-15T21:52:39.986Z", - "contributors": [ - "RainSlide", - "zwei76" - ] - }, - "Web/API/Navigation_timing_API": { - "modified": "2019-03-23T22:26:10.873Z", - "contributors": [ - "donghua", - "xgqfrms-GitHub", - "CeHOU", - "iamyy" - ] - }, - "Web/API/Navigation_timing_API/Using_Navigation_Timing": { - "modified": "2020-04-02T23:35:26.689Z", - "contributors": [ - "Bayes", - "wolf-wolf" - ] - }, - "Web/API/Navigator": { - "modified": "2020-10-15T21:33:06.758Z", - "contributors": [ - "jingkaimori", - "mc-tracker", - "mokunshao", - "Li-saltair", - "hydRAnger", - "RainSlide", - "wbamberg", - "smartme", - "wangxinhe", - "nian0114", - "zxlSilen", - "tsingwong", - "nDos", - "borenXue", - "DHclly", - "Taoja", - "Meggin" - ] - }, - "Web/API/Navigator/activeVRDisplays": { - "modified": "2020-10-15T22:11:56.184Z", - "contributors": [ - "gdccwxx" - ] - }, - "Web/API/Navigator/battery": { - "modified": "2020-10-15T21:21:32.906Z", - "contributors": [ - "jingkaimori", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Navigator/buildID": { - "modified": "2020-10-15T21:06:57.331Z", - "contributors": [ - "Roy-Tian", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Navigator/canShare": { - "modified": "2020-10-15T22:24:17.499Z", - "contributors": [ - "zhangchen", - "Mayness" - ] - }, - "Web/API/Navigator/clipboard": { - "modified": "2020-10-15T22:12:36.311Z", - "contributors": [ - "RainSlide", - "Roy-Tian" - ] - }, - "Web/API/Navigator/connection": { - "modified": "2020-10-15T21:56:52.200Z", - "contributors": [ - "SphinxKnight", - "icecreamgaga", - "jnvf", - "anchengjian" - ] - }, - "Web/API/Navigator/cookieEnabled": { - "modified": "2020-10-15T21:06:57.715Z", - "contributors": [ - "Roy-Tian", - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Navigator/credentials": { - "modified": "2019-05-24T00:47:24.250Z", - "contributors": [ - "fsx950223" - ] - }, - "Web/API/Navigator/deviceMemory": { - "modified": "2020-10-15T22:17:15.535Z", - "contributors": [ - "duanlvxin", - "notkid", - "chenqingyue" - ] - }, - "Web/API/Navigator/doNotTrack": { - "modified": "2019-03-24T00:15:57.632Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Navigator/geolocation": { - "modified": "2019-03-23T23:04:46.800Z", - "contributors": [ - "Roy-Tian", - "nDos", - "YiChengHui", - "SimGenius", - "ziyunfei", - "teoli", - "Breezewish" - ] - }, - "Web/API/Navigator/getBattery": { - "modified": "2019-03-23T22:46:09.257Z", - "contributors": [ - "mzhejiayu" - ] - }, - "Web/API/Navigator/getGamepads": { - "modified": "2019-03-18T20:55:46.850Z", - "contributors": [ - "caoxiaoshuai", - "Hitomichan" - ] - }, - "Web/API/Navigator/getUserMedia": { - "modified": "2019-08-19T06:38:45.805Z", - "contributors": [ - "Melo.HG", - "c1ngular", - "liuzeyafzy", - "fscholz", - "jtyjty99999" - ] - }, - "Web/API/Navigator/keyboard": { - "modified": "2020-10-15T22:20:24.018Z", - "contributors": [ - "yuyang" - ] - }, - "Web/API/Navigator/maxTouchPoints": { - "modified": "2019-03-23T22:11:22.345Z", - "contributors": [ - "PawnPan", - "gu18168" - ] - }, - "Web/API/Navigator/mediaDevices": { - "modified": "2019-03-18T21:45:18.805Z", - "contributors": [ - "nDos", - "hawtim" - ] - }, - "Web/API/Navigator/mozIsLocallyAvailable": { - "modified": "2019-03-24T00:15:57.130Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Navigator/oscpu": { - "modified": "2019-03-24T00:16:00.751Z", - "contributors": [ - "teoli", - "Hasilt", - "ziyunfei" - ] - }, - "Web/API/Navigator/permissions": { - "modified": "2019-03-23T22:16:34.537Z", - "contributors": [ - "nDos", - "micblo" - ] - }, - "Web/API/Navigator/productSub": { - "modified": "2020-10-15T22:17:15.572Z", - "contributors": [ - "chenqingyue" - ] - }, - "Web/API/Navigator/registerContentHandler": { - "modified": "2019-03-24T00:16:02.965Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Navigator/registerProtocolHandler": { - "modified": "2020-11-12T06:22:45.529Z", - "contributors": [ - "xgqfrms", - "Carllllo", - "marsoln" - ] - }, - "Web/API/Navigator/registerProtocolHandler/Web-based_protocol_handlers": { - "modified": "2019-03-23T23:20:07.432Z", - "contributors": [ - "chrisdavidmills", - "ObooChin", - "jtyjty99999" - ] - }, - "Web/API/Navigator/sendBeacon": { - "modified": "2020-10-15T21:45:06.383Z", - "contributors": [ - "yugasun", - "Ende93", - "zhangchen", - "tongbin", - "RandyLoop", - "wxkuang", - "holynewbie" - ] - }, - "Web/API/Navigator/serviceWorker": { - "modified": "2019-03-23T22:35:20.078Z", - "contributors": [ - "zqyadam", - "xgqfrms-GitHub", - "wenshin" - ] - }, - "Web/API/Navigator/share": { - "modified": "2020-10-15T22:20:15.808Z", - "contributors": [ - "jingkaimori", - "polunzh", - "hufeicom", - "yuyang" - ] - }, - "Web/API/Navigator/vendor": { - "modified": "2019-03-24T00:15:58.807Z", - "contributors": [ - "teoli", - "mimzi_fahia", - "ziyunfei" - ] - }, - "Web/API/Navigator/vendorSub": { - "modified": "2019-03-24T00:16:04.036Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Navigator/vibrate": { - "modified": "2019-03-18T21:43:38.752Z", - "contributors": [ - "Tao-Quixote", - "nDos" - ] - }, - "Web/API/NavigatorConcurrentHardware": { - "modified": "2020-10-15T22:07:23.974Z", - "contributors": [ - "fscholz" - ] - }, - "Web/API/NavigatorConcurrentHardware/hardwareConcurrency": { - "modified": "2020-10-15T22:07:22.764Z", - "contributors": [ - "udo-china" - ] - }, - "Web/API/NavigatorGeolocation": { - "modified": "2019-03-23T23:01:18.415Z", - "contributors": [ - "teoli" - ] - }, - "Web/API/NavigatorID": { - "modified": "2019-03-23T23:10:30.690Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/NavigatorID/appCodeName": { - "modified": "2019-03-24T00:15:50.665Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/NavigatorID/appName": { - "modified": "2019-03-24T00:15:53.520Z", - "contributors": [ - "teoli", - "jsx", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/NavigatorID/appVersion": { - "modified": "2019-03-24T00:15:53.430Z", - "contributors": [ - "teoli", - "arunpandianp", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/NavigatorID/platform": { - "modified": "2019-03-24T00:16:03.059Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/NavigatorID/product": { - "modified": "2019-03-23T23:10:32.598Z", - "contributors": [ - "teoli", - "jsx", - "AlexChao" - ] - }, - "Web/API/NavigatorID/userAgent": { - "modified": "2020-10-27T04:48:53.819Z", - "contributors": [ - "oriengy", - "mokunshao", - "xgqfrms", - "teoli", - "khalid32", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/NavigatorLanguage": { - "modified": "2020-10-15T21:33:02.926Z", - "contributors": [ - "RainSlide", - "micblo", - "teoli" - ] - }, - "Web/API/NavigatorLanguage/language": { - "modified": "2020-10-15T21:06:56.192Z", - "contributors": [ - "Roy-Tian", - "Freed", - "teoli", - "khalid32", - "ziyunfei", - "gqqnbig" - ] - }, - "Web/API/NavigatorLanguage/languages": { - "modified": "2020-12-07T06:27:34.396Z", - "contributors": [ - "SphinxKnight", - "wick", - "fscholz", - "micblo" - ] - }, - "Web/API/NavigatorOnLine": { - "modified": "2019-03-23T23:01:18.687Z", - "contributors": [ - "VictorDu", - "teoli" - ] - }, - "Web/API/NavigatorOnLine/Online_and_offline_events": { - "modified": "2019-03-23T23:31:41.720Z", - "contributors": [ - "chrisdavidmills", - "sunnylost" - ] - }, - "Web/API/NavigatorOnLine/onLine": { - "modified": "2020-10-15T21:07:17.647Z", - "contributors": [ - "biqing", - "wth", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/NavigatorPlugins": { - "modified": "2019-03-23T23:01:19.383Z", - "contributors": [ - "teoli" - ] - }, - "Web/API/NavigatorPlugins/javaEnabled": { - "modified": "2019-03-24T00:15:58.715Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/NavigatorPlugins/mimeTypes": { - "modified": "2019-03-23T22:49:46.667Z", - "contributors": [ - "nDos", - "ChenChenJoke" - ] - }, - "Web/API/NavigatorPlugins/plugins": { - "modified": "2020-10-15T21:06:55.557Z", - "contributors": [ - "Carllllo", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/NavigatorPlugins/测试滕盖": { - "modified": "2019-03-23T22:49:37.647Z", - "contributors": [ - "ChenChenJoke" - ] - }, - "Web/API/NavigatorStorage": { - "modified": "2020-10-15T22:06:22.408Z", - "contributors": [ - "fscholz" - ] - }, - "Web/API/NavigatorStorage/storage": { - "modified": "2020-10-15T22:06:24.775Z", - "contributors": [ - "Awe" - ] - }, - "Web/API/NetworkInformation": { - "modified": "2019-06-12T05:37:17.235Z", - "contributors": [ - "anchengjian" - ] - }, - "Web/API/NetworkInformation/downlink": { - "modified": "2019-03-18T21:29:26.192Z", - "contributors": [ - "Tzxhy" - ] - }, - "Web/API/NetworkInformation/rtt": { - "modified": "2019-03-18T21:29:38.723Z", - "contributors": [ - "Tzxhy" - ] - }, - "Web/API/NetworkInformation/saveData": { - "modified": "2020-10-15T22:31:54.176Z", - "contributors": [ - "AlisaV785" - ] - }, - "Web/API/Network_Information_API": { - "modified": "2019-03-21T23:41:26.586Z", - "contributors": [ - "juniorzhp", - "ziyunfei", - "ZhouHansen" - ] - }, - "Web/API/Node": { - "modified": "2020-10-15T21:06:37.888Z", - "contributors": [ - "gh1031", - "huabingtao", - "xoyojo", - "244462375", - "multics", - "happyWang", - "RainSlide", - "imstone", - "gitdust", - "zzg19931223", - "Angelki", - "practicemp", - "ZHANG_HaiDong", - "huozicheng", - "szy0syz", - "wenshin", - "xgqfrms-GitHub", - "AlexChao", - "Losses", - "ziyunfei" - ] - }, - "Web/API/Node/appendChild": { - "modified": "2020-10-15T21:21:59.967Z", - "contributors": [ - "Edgeo-Mourner", - "Lesty", - "RainSlide", - "Dcfm", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Node/baseURI": { - "modified": "2019-03-24T00:17:49.085Z", - "contributors": [ - "xgqfrms-GitHub", - "Ende93", - "tiansh", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Node/baseURIObject": { - "modified": "2019-03-24T00:17:51.751Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Node/childNodes": { - "modified": "2019-03-24T00:16:20.224Z", - "contributors": [ - "ziyunfei", - "teoli", - "AlexChao", - "Mgjbot", - "Dewang" - ] - }, - "Web/API/Node/cloneNode": { - "modified": "2019-10-05T16:28:24.570Z", - "contributors": [ - "Ende93", - "teoli", - "AshfaqHossain", - "ziyunfei", - "monjer", - "TigerSoldier" - ] - }, - "Web/API/Node/compareDocumentPosition": { - "modified": "2020-10-15T21:04:25.601Z", - "contributors": [ - "Ende93", - "teoli", - "cuixiping", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Node/contains": { - "modified": "2019-03-24T00:17:16.817Z", - "contributors": [ - "kaixuan1992", - "frankfang1990", - "helloguangxue", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Node/firstChild": { - "modified": "2019-03-24T00:16:13.334Z", - "contributors": [ - "wbamberg", - "xgqfrms-GitHub", - "Ende93", - "teoli", - "AshfaqHossain", - "ziyunfei", - "Sheppy", - "Mgjbot", - "TigerSoldier", - "Dewang" - ] - }, - "Web/API/Node/getRootNode": { - "modified": "2020-10-15T21:59:00.254Z", - "contributors": [ - "Fancyflame", - "RainSlide", - "LoveofRedMoon", - "xuetengfei" - ] - }, - "Web/API/Node/getUserData": { - "modified": "2019-03-23T23:09:37.543Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Node/hasChildNodes": { - "modified": "2019-03-24T00:16:18.421Z", - "contributors": [ - "jszhou", - "teoli", - "khalid32", - "ziyunfei", - "Xiaobian" - ] - }, - "Web/API/Node/innerText": { - "modified": "2020-10-15T21:50:36.703Z", - "contributors": [ - "wuyou", - "RainSlide", - "keifergu", - "xgqfrms-GitHub", - "Aolose" - ] - }, - "Web/API/Node/insertBefore": { - "modified": "2020-10-15T21:22:01.727Z", - "contributors": [ - "lisiur", - "Edgeo-Mourner", - "machangkun", - "btea", - "RainSlide", - "c1er", - "_Diamond", - "zhuangyin", - "xgqfrms-GitHub", - "fengfu", - "stormtea123", - "helloguangxue", - "teoli", - "ziyunfei", - "AlexChao", - "Josephok" - ] - }, - "Web/API/Node/isConnected": { - "modified": "2020-10-15T22:01:51.865Z", - "contributors": [ - "RainSlide", - "LoveofRedMoon" - ] - }, - "Web/API/Node/isDefaultNamespace": { - "modified": "2019-03-24T00:17:58.382Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Node/isEqualNode": { - "modified": "2019-08-23T03:36:54.356Z", - "contributors": [ - "Blacktodreamlight", - "Ende93", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Node/isSameNode": { - "modified": "2019-03-24T00:17:51.664Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Node/isSupported": { - "modified": "2019-03-23T23:32:58.017Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Node/lastChild": { - "modified": "2019-03-24T00:17:55.199Z", - "contributors": [ - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Node/localName": { - "modified": "2019-03-24T00:17:44.401Z", - "contributors": [ - "teoli", - "jsx", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Node/lookupNamespaceURI": { - "modified": "2019-03-24T00:17:51.844Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/Node/lookupPrefix": { - "modified": "2019-03-24T00:17:44.706Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/Node/namespaceURI": { - "modified": "2019-03-23T23:09:34.483Z", - "contributors": [ - "LoveofRedMoon", - "teoli", - "AlexChao" - ] - }, - "Web/API/Node/nextSibling": { - "modified": "2020-10-15T21:30:01.843Z", - "contributors": [ - "yipanhuasheng", - "wbamberg", - "teoli", - "ziyunfei", - "AlexChao" - ] - }, - "Web/API/Node/nodeName": { - "modified": "2019-03-24T00:17:46.894Z", - "contributors": [ - "teoli", - "arunpandianp", - "ziyunfei" - ] - }, - "Web/API/Node/nodePrincipal": { - "modified": "2019-03-23T23:09:34.131Z", - "contributors": [ - "teoli", - "ziyunfei", - "AlexChao" - ] - }, - "Web/API/Node/nodeType": { - "modified": "2019-10-05T15:43:35.594Z", - "contributors": [ - "678", - "RainSlide", - "mrxf", - "Ende93", - "lfkid", - "laobubu", - "teoli", - "jsx", - "ziyunfei", - "ethertank" - ] - }, - "Web/API/Node/nodeValue": { - "modified": "2020-10-15T21:06:35.626Z", - "contributors": [ - "Ende93", - "xgqfrms-GitHub", - "teoli", - "khalid32", - "ziyunfei", - "Xiaobian" - ] - }, - "Web/API/Node/normalize": { - "modified": "2020-10-15T21:04:18.803Z", - "contributors": [ - "Ende93", - "teoli", - "cuixiping", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Node/outerText": { - "modified": "2019-01-17T00:59:24.641Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/Node/ownerDocument": { - "modified": "2019-03-24T00:17:19.313Z", - "contributors": [ - "kameii", - "Ende93", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Node/parentElement": { - "modified": "2020-10-15T21:06:47.226Z", - "contributors": [ - "RainSlide", - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Node/parentNode": { - "modified": "2019-03-24T00:16:17.608Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Node/prefix": { - "modified": "2019-03-24T00:17:52.444Z", - "contributors": [ - "teoli", - "jsx", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Node/previousSibling": { - "modified": "2019-11-28T06:21:40.809Z", - "contributors": [ - "lmislm", - "wbamberg", - "ifredom", - "teoli", - "AlexChao", - "ziyunfei", - "Sheppy" - ] - }, - "Web/API/Node/removeChild": { - "modified": "2019-10-05T16:35:15.353Z", - "contributors": [ - "xgqfrms-GitHub", - "iugo", - "Hyuni", - "alonprince", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Node/replaceChild": { - "modified": "2020-10-15T21:04:16.398Z", - "contributors": [ - "RainSlide", - "luobotang", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Node/rootNode": { - "modified": "2019-03-18T21:40:49.635Z", - "contributors": [ - "wbamberg", - "LoveofRedMoon" - ] - }, - "Web/API/Node/setUserData": { - "modified": "2019-03-23T23:09:32.465Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Node/textContent": { - "modified": "2020-10-15T21:24:14.842Z", - "contributors": [ - "Carllllo", - "Jamie0327", - "mokunshao", - "zhuangyin", - "xgqfrms-GitHub", - "Wushaowei", - "AlexChao", - "teoli", - "chyingp" - ] - }, - "Web/API/NodeFilter": { - "modified": "2020-10-15T21:54:21.294Z", - "contributors": [ - "Carllllo", - "RainSlide", - "krosylight" - ] - }, - "Web/API/NodeFilter/acceptNode": { - "modified": "2019-03-23T22:11:41.705Z", - "contributors": [ - "EleanorMao" - ] - }, - "Web/API/NodeIterator": { - "modified": "2020-04-29T02:09:48.854Z", - "contributors": [ - "imsasa", - "chimez", - "hawtim" - ] - }, - "Web/API/NodeList": { - "modified": "2020-10-15T21:07:19.516Z", - "contributors": [ - "xgqfrms", - "fish-inu", - "Blacktodreamlight", - "cyemeng", - "RainSlide", - "anxsec", - "linweinb", - "GuaHsu", - "PengSama", - "dudueasy", - "iplus26", - "Hawkeyes_Wind", - "teoli", - "jaka", - "ziyunfei", - "fishenal" - ] - }, - "Web/API/NodeList/entries": { - "modified": "2019-03-23T22:21:49.189Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/NodeList/forEach": { - "modified": "2020-10-15T22:27:30.561Z", - "contributors": [ - "fzhyzamt", - "joytou" - ] - }, - "Web/API/NodeList/item": { - "modified": "2019-03-24T00:16:24.999Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/NodeList/keys": { - "modified": "2020-10-15T22:21:57.032Z", - "contributors": [ - "Ende93", - "ErChuan" - ] - }, - "Web/API/NodeList/length": { - "modified": "2019-03-23T22:21:48.566Z", - "contributors": [ - "Cattla" - ] - }, - "Web/API/NodeList/values": { - "modified": "2020-10-15T22:20:51.077Z", - "contributors": [ - "Oswald111" - ] - }, - "Web/API/NonDocumentTypeChildNode": { - "modified": "2020-10-15T21:33:03.603Z", - "contributors": [ - "RainSlide", - "teoli" - ] - }, - "Web/API/NonDocumentTypeChildNode/nextElementSibling": { - "modified": "2019-10-05T16:51:15.466Z", - "contributors": [ - "VictorDu", - "rguanghui", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/NonDocumentTypeChildNode/previousElementSibling": { - "modified": "2019-10-05T16:54:41.549Z", - "contributors": [ - "rguanghui", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Notation": { - "modified": "2020-10-15T22:20:06.303Z", - "contributors": [ - "xiaoxingchi" - ] - }, - "Web/API/NotificationEvent": { - "modified": "2020-11-24T03:08:03.312Z", - "contributors": [ - "SphinxKnight", - "Guojiahao7" - ] - }, - "Web/API/Notifications_API": { - "modified": "2019-03-23T22:25:37.741Z", - "contributors": [ - "xgqfrms-GitHub", - "vankai" - ] - }, - "Web/API/NotifyAudioAvailableEvent": { - "modified": "2019-01-17T01:59:59.816Z", - "contributors": [ - "asins", - "garden4hu" - ] - }, - "Web/API/OES_vertex_array_object": { - "modified": "2020-10-15T22:26:52.417Z", - "contributors": [ - "ymyh" - ] - }, - "Web/API/OfflineAudioContext": { - "modified": "2019-03-23T22:13:42.055Z", - "contributors": [ - "micblo" - ] - }, - "Web/API/OfflineAudioContext/OfflineAudioContext": { - "modified": "2019-03-23T22:13:46.603Z", - "contributors": [ - "micblo" - ] - }, - "Web/API/OfflineAudioContext/complete": { - "modified": "2020-10-15T22:17:22.684Z", - "contributors": [ - "ewfian", - "ljx23136138" - ] - }, - "Web/API/OfflineAudioContext/length": { - "modified": "2019-03-23T22:13:45.696Z", - "contributors": [ - "micblo" - ] - }, - "Web/API/OfflineAudioContext/suspend": { - "modified": "2019-03-23T22:12:22.405Z", - "contributors": [ - "huangxok" - ] - }, - "Web/API/OffscreenCanvas": { - "modified": "2020-10-15T21:53:32.163Z", - "contributors": [ - "AmyFoxFN", - "cuixiping", - "levo2165", - "makeco", - "Youjingyu" - ] - }, - "Web/API/OffscreenCanvas/OffscreenCanvas": { - "modified": "2020-10-15T22:11:15.383Z", - "contributors": [ - "chinazhaghai" - ] - }, - "Web/API/OffscreenCanvas/height": { - "modified": "2020-10-15T22:23:12.923Z", - "contributors": [ - "smileFDD" - ] - }, - "Web/API/OffscreenCanvas/transferToImageBitmap": { - "modified": "2020-10-15T22:27:55.658Z", - "contributors": [ - "jollybearchina" - ] - }, - "Web/API/OscillatorNode": { - "modified": "2019-09-11T06:16:09.786Z", - "contributors": [ - "vivimice", - "luckykaiyi", - "Nonym", - "huangxok" - ] - }, - "Web/API/OscillatorNode/OscillatorNode": { - "modified": "2019-03-23T22:09:08.773Z", - "contributors": [ - "Nonym" - ] - }, - "Web/API/OscillatorNode/detune": { - "modified": "2019-03-23T22:09:20.220Z", - "contributors": [ - "Nonym" - ] - }, - "Web/API/OscillatorNode/frequency": { - "modified": "2019-03-23T22:09:14.475Z", - "contributors": [ - "Nonym" - ] - }, - "Web/API/OscillatorNode/setPeriodicWave": { - "modified": "2019-03-23T22:09:06.189Z", - "contributors": [ - "Nonym" - ] - }, - "Web/API/OscillatorNode/stop": { - "modified": "2019-03-23T22:09:45.455Z", - "contributors": [ - "boolean111000" - ] - }, - "Web/API/PageTransitionEvent": { - "modified": "2019-04-28T22:02:49.952Z", - "contributors": [ - "Chandler0415", - "acelan86" - ] - }, - "Web/API/PageTransitionEvent/persisted": { - "modified": "2020-10-15T22:30:53.567Z", - "contributors": [ - "thomaslwq" - ] - }, - "Web/API/Page_Visibility_API": { - "modified": "2020-10-15T21:51:01.746Z", - "contributors": [ - "jingkaimori", - "LiZheGuang", - "oujielong", - "myhirra", - "YISHI", - "zhangchen", - "Gale", - "Wineki" - ] - }, - "Web/API/ParentNode": { - "modified": "2020-10-15T21:30:05.597Z", - "contributors": [ - "codingbylch", - "RainSlide", - "Aaron-Bird", - "_sollrei", - "xgqfrms-GitHub", - "AlexChao" - ] - }, - "Web/API/ParentNode/append": { - "modified": "2020-10-15T21:51:11.120Z", - "contributors": [ - "Ende93", - "zhangchen", - "xgqfrms-GitHub", - "ziyunfei" - ] - }, - "Web/API/ParentNode/childElementCount": { - "modified": "2019-04-28T01:50:12.243Z", - "contributors": [ - "frankfang1990", - "xgqfrms-GitHub", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/ParentNode/children": { - "modified": "2019-10-05T16:42:46.088Z", - "contributors": [ - "xiaoxiyao", - "xgqfrms-GitHub", - "teoli", - "khalid32", - "ziyunfei", - "AlexChao" - ] - }, - "Web/API/ParentNode/firstElementChild": { - "modified": "2020-10-15T21:06:48.165Z", - "contributors": [ - "igoryaodev", - "imwangpan", - "gwh1312", - "RainSlide", - "xgqfrms-GitHub", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/ParentNode/lastElementChild": { - "modified": "2020-10-15T21:05:51.837Z", - "contributors": [ - "RainSlide", - "xgqfrms-GitHub", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/ParentNode/prepend": { - "modified": "2020-10-15T21:52:00.307Z", - "contributors": [ - "Ende93", - "zhuangyin", - "maicss" - ] - }, - "Web/API/ParentNode/querySelector": { - "modified": "2020-10-15T22:11:37.961Z", - "contributors": [ - "czmecah", - "guoyi" - ] - }, - "Web/API/ParentNode/querySelectorAll": { - "modified": "2020-10-15T21:55:06.009Z", - "contributors": [ - "czmecah", - "RainSlide", - "hawtim", - "_sollrei", - "ZZES_REN" - ] - }, - "Web/API/ParentNode/replaceChildren": { - "modified": "2020-10-15T22:33:59.306Z", - "contributors": [ - "JoshOY" - ] - }, - "Web/API/Path2D": { - "modified": "2019-03-23T22:53:11.857Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/Path2D/Path2D": { - "modified": "2019-03-23T22:53:20.087Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/Path2D/addPath": { - "modified": "2019-03-23T22:53:17.903Z", - "contributors": [ - "RyougiChan", - "ice-i-snow" - ] - }, - "Web/API/PaymentAddress": { - "modified": "2019-03-23T22:17:37.973Z", - "contributors": [ - "pyoor" - ] - }, - "Web/API/Performance": { - "modified": "2020-10-15T21:33:10.042Z", - "contributors": [ - "juzhiyuan", - "fscholz", - "zhangchen", - "Ende93", - "anjia", - "xgqfrms-GitHub", - "xtx1130", - "HuazhuLi", - "wenshin", - "teoli" - ] - }, - "Web/API/Performance/clearMarks": { - "modified": "2019-03-23T22:06:59.286Z", - "contributors": [ - "liuyutao" - ] - }, - "Web/API/Performance/clearMeasures": { - "modified": "2019-03-18T21:33:24.888Z", - "contributors": [ - "Yvesyao" - ] - }, - "Web/API/Performance/clearResourceTimings": { - "modified": "2020-10-15T22:16:54.863Z", - "contributors": [ - "fuchao2012" - ] - }, - "Web/API/Performance/getEntries": { - "modified": "2020-10-15T22:01:58.437Z", - "contributors": [ - "fscholz", - "ihgazni2" - ] - }, - "Web/API/Performance/getEntriesByName": { - "modified": "2020-10-15T22:20:30.656Z", - "contributors": [ - "xiaokk06" - ] - }, - "Web/API/Performance/getEntriesByType": { - "modified": "2020-10-15T22:21:28.572Z", - "contributors": [ - "dazaooo", - "lsh83718802" - ] - }, - "Web/API/Performance/mark": { - "modified": "2020-03-05T07:52:58.328Z", - "contributors": [ - "rpkingg", - "zmj97", - "Maple_Cao", - "yzw7489757", - "ihgazni2" - ] - }, - "Web/API/Performance/measure": { - "modified": "2020-10-15T22:10:01.973Z", - "contributors": [ - "chrisdavidmills", - "gcl1993", - "lwjcjmx123", - "Mangone" - ] - }, - "Web/API/Performance/navigation": { - "modified": "2020-10-15T21:49:45.765Z", - "contributors": [ - "fscholz", - "Ende93", - "Pada", - "CeHOU" - ] - }, - "Web/API/Performance/now": { - "modified": "2020-12-02T07:01:25.653Z", - "contributors": [ - "woshiqiang1", - "shanyuhai123", - "haozhaohang", - "suvyme", - "zhangchen", - "dblate", - "xgqfrms-GitHub", - "teoli", - "colder", - "ziyunfei" - ] - }, - "Web/API/Performance/onresourcetimingbufferfull": { - "modified": "2019-03-23T22:09:51.120Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/Performance/timeOrigin": { - "modified": "2019-03-18T21:40:35.097Z", - "contributors": [ - "ihgazni2" - ] - }, - "Web/API/Performance/timing": { - "modified": "2020-10-15T21:39:59.871Z", - "contributors": [ - "xgqfrms", - "16546513", - "rguanghui", - "wenshin" - ] - }, - "Web/API/Performance/toJSON": { - "modified": "2020-10-15T21:55:45.371Z", - "contributors": [ - "fscholz", - "dblate" - ] - }, - "Web/API/Performance/内存": { - "modified": "2020-10-15T22:29:17.983Z", - "contributors": [ - "biqing" - ] - }, - "Web/API/PerformanceEntry": { - "modified": "2020-10-15T21:53:01.540Z", - "contributors": [ - "fscholz", - "CCCYing", - "abbycar" - ] - }, - "Web/API/PerformanceEntry/duration": { - "modified": "2020-10-15T22:02:01.845Z", - "contributors": [ - "fscholz", - "ihgazni2" - ] - }, - "Web/API/PerformanceEntry/entryType": { - "modified": "2020-10-15T22:02:04.151Z", - "contributors": [ - "fscholz", - "ihgazni2" - ] - }, - "Web/API/PerformanceEntry/name": { - "modified": "2020-10-15T22:01:57.369Z", - "contributors": [ - "fscholz", - "ihgazni2" - ] - }, - "Web/API/PerformanceEntry/toJSON": { - "modified": "2020-10-15T21:53:01.195Z", - "contributors": [ - "fscholz", - "xgqfrms-GitHub" - ] - }, - "Web/API/PerformanceNavigation": { - "modified": "2020-10-15T22:04:14.850Z", - "contributors": [ - "fscholz", - "chrisxiong" - ] - }, - "Web/API/PerformanceNavigationTiming": { - "modified": "2020-10-15T22:26:24.857Z", - "contributors": [ - "Katherina-Miao" - ] - }, - "Web/API/PerformanceObserver": { - "modified": "2020-10-15T22:00:22.410Z", - "contributors": [ - "qq240814476", - "Jiang-Xuan", - "warmilk", - "stefanjudis" - ] - }, - "Web/API/PerformanceObserver/PerformanceObserver": { - "modified": "2020-10-15T22:16:50.431Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/PerformanceObserver/disconnect": { - "modified": "2020-10-15T22:16:50.476Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/PerformanceObserver/observe": { - "modified": "2019-03-21T11:15:27.177Z", - "contributors": [ - "warmilk" - ] - }, - "Web/API/PerformanceObserver/takeRecords": { - "modified": "2020-10-15T22:16:50.436Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/PerformancePaintTiming": { - "modified": "2019-03-23T22:06:43.310Z", - "contributors": [ - "sinbargit" - ] - }, - "Web/API/PerformanceResourceTiming": { - "modified": "2020-10-15T22:22:05.854Z", - "contributors": [ - "xiaoranzife", - "zhanym" - ] - }, - "Web/API/PerformanceTiming": { - "modified": "2020-10-15T21:24:43.959Z", - "contributors": [ - "Katherina-Miao", - "fscholz", - "micblo", - "wolf-wolf", - "CeHOU", - "Scott-Coder", - "coolguy", - "teoli", - "ziyunfei" - ] - }, - "Web/API/PerformanceTiming/connectEnd": { - "modified": "2020-10-15T21:49:46.392Z", - "contributors": [ - "fscholz", - "CeHOU" - ] - }, - "Web/API/PerformanceTiming/connectStart": { - "modified": "2020-10-15T21:53:19.882Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/domComplete": { - "modified": "2020-10-15T21:53:13.885Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/domContentLoadedEventEnd": { - "modified": "2020-10-15T21:34:13.640Z", - "contributors": [ - "fscholz", - "willworks", - "TooBug" - ] - }, - "Web/API/PerformanceTiming/domContentLoadedEventStart": { - "modified": "2020-10-15T21:53:27.255Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/domInteractive": { - "modified": "2020-10-15T21:53:27.259Z", - "contributors": [ - "viko16", - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/domLoading": { - "modified": "2020-10-15T21:53:27.255Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/domainLookupEnd": { - "modified": "2020-10-15T21:53:12.500Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/domainLookupStart": { - "modified": "2020-10-15T21:53:19.451Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/fetchStart": { - "modified": "2020-10-15T21:53:27.281Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/loadEventEnd": { - "modified": "2020-10-15T21:53:27.229Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/loadEventStart": { - "modified": "2020-10-15T21:53:27.222Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/navigationStart": { - "modified": "2020-10-15T21:53:27.293Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/redirectEnd": { - "modified": "2020-10-15T21:53:27.295Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/redirectStart": { - "modified": "2020-10-15T21:53:28.225Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/requestStart": { - "modified": "2020-10-15T21:53:28.226Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/responseEnd": { - "modified": "2020-10-15T21:53:28.257Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/responseStart": { - "modified": "2020-10-15T21:53:28.295Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/secureConnectionStart": { - "modified": "2020-10-15T21:53:28.190Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/unloadEventEnd": { - "modified": "2020-10-15T21:53:28.235Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/PerformanceTiming/unloadEventStart": { - "modified": "2020-10-15T21:53:28.200Z", - "contributors": [ - "fscholz", - "micblo" - ] - }, - "Web/API/Performance_API": { - "modified": "2020-04-20T05:51:10.170Z", - "contributors": [ - "luoway" - ] - }, - "Web/API/Performance_Timeline": { - "modified": "2020-07-10T11:47:27.766Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/PeriodicWave": { - "modified": "2020-10-15T22:17:43.050Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/Permissions": { - "modified": "2020-10-15T22:25:53.902Z", - "contributors": [ - "Li-saltair" - ] - }, - "Web/API/Permissions_API": { - "modified": "2020-10-15T22:33:59.746Z", - "contributors": [ - "Sheppy" - ] - }, - "Web/API/Permissions_API/Using_the_Permissions_API": { - "modified": "2020-11-02T23:45:53.335Z", - "contributors": [ - "cheiron", - "yinsang" - ] - }, - "Web/API/PictureInPictureWindow": { - "modified": "2020-10-31T05:51:42.758Z", - "contributors": [ - "sunfeel" - ] - }, - "Web/API/Plugin": { - "modified": "2019-03-23T22:15:53.691Z", - "contributors": [ - "yuyang", - "hefang" - ] - }, - "Web/API/PointerEvent": { - "modified": "2020-10-15T21:53:40.224Z", - "contributors": [ - "SDUTWSL", - "zhang-xiao", - "Jack.Works", - "ucev" - ] - }, - "Web/API/Pointer_events": { - "modified": "2020-10-15T22:11:40.347Z", - "contributors": [ - "Clarkkkk", - "ldwformat" - ] - }, - "Web/API/PositionOptions": { - "modified": "2019-03-23T22:19:15.525Z", - "contributors": [ - "paigextl", - "hmzll", - "leolux" - ] - }, - "Web/API/PositionOptions/timeout": { - "modified": "2019-03-23T22:19:18.285Z", - "contributors": [ - "kameii" - ] - }, - "Web/API/ProgressEvent": { - "modified": "2020-10-15T21:52:17.661Z", - "contributors": [ - "mkckr0", - "DingJunjie", - "MorePainMoreGain" - ] - }, - "Web/API/ProgressEvent/lengthComputable": { - "modified": "2019-03-18T21:44:11.310Z", - "contributors": [ - "Hew007", - "zhaifanyang" - ] - }, - "Web/API/PromiseRejectionEvent": { - "modified": "2019-04-12T11:17:09.379Z", - "contributors": [ - "zhangzhiqiang37", - "Pada" - ] - }, - "Web/API/PromiseRejectionEvent/PromiseRejectionEvent": { - "modified": "2019-03-23T22:09:36.440Z", - "contributors": [ - "Pada" - ] - }, - "Web/API/PromiseRejectionEvent/promise": { - "modified": "2020-10-15T22:12:37.323Z", - "contributors": [ - "duola8789" - ] - }, - "Web/API/PushManager": { - "modified": "2019-03-23T22:30:21.965Z", - "contributors": [ - "McCarthey", - "chrisdavidmills" - ] - }, - "Web/API/PushManager/getSubscription": { - "modified": "2020-11-02T06:22:52.298Z", - "contributors": [ - "yanchongwen101", - "chenqingyue" - ] - }, - "Web/API/PushManager/subscribe": { - "modified": "2019-03-23T22:30:26.556Z", - "contributors": [ - "jiraiya" - ] - }, - "Web/API/PushManager/supportedContentEncodings": { - "modified": "2020-10-15T22:14:59.278Z", - "contributors": [ - "chenqingyue" - ] - }, - "Web/API/PushMessageData": { - "modified": "2019-03-23T22:15:32.460Z", - "contributors": [ - "chrisdavidmills" - ] - }, - "Web/API/PushMessageData/json": { - "modified": "2019-03-23T22:15:42.623Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/Push_API": { - "modified": "2019-03-18T20:45:12.328Z", - "contributors": [ - "VictorDu", - "flyingsouthwind", - "vankai", - "xgqfrms-GitHub", - "jiraiya", - "ziyunfei", - "BettyCHEN" - ] - }, - "Web/API/Push_API/Using_the_Push_API": { - "modified": "2019-03-23T22:26:22.995Z", - "contributors": [ - "vankai", - "xgqfrms-GitHub", - "hibernake" - ] - }, - "Web/API/RTCConfiguration": { - "modified": "2019-03-23T22:18:59.231Z", - "contributors": [ - "moshoujingli" - ] - }, - "Web/API/RTCDataChannel": { - "modified": "2019-03-23T23:04:49.663Z", - "contributors": [ - "llsxily", - "teoli", - "ziyunfei", - "kmokidd" - ] - }, - "Web/API/RTCPeerConnection": { - "modified": "2020-01-14T23:16:30.161Z", - "contributors": [ - "崮生", - "Tsui", - "ztacesa", - "yxxgoogle", - "Move", - "zhuyeqing5828", - "Wunmest" - ] - }, - "Web/API/RTCPeerConnection/RTCPeerConnection": { - "modified": "2019-03-23T22:07:32.914Z", - "contributors": [ - "ztacesa" - ] - }, - "Web/API/RTCPeerConnection/addIceCandidate": { - "modified": "2019-03-23T22:04:45.584Z", - "contributors": [ - "AoLi12306", - "scplay" - ] - }, - "Web/API/RTCPeerConnection/addTrack": { - "modified": "2020-10-15T22:32:39.495Z", - "contributors": [ - "Scorpio", - "Mr.Chenzm" - ] - }, - "Web/API/RTCPeerConnection/canTrickleIceCandidates": { - "modified": "2020-10-15T22:17:37.803Z", - "contributors": [ - "PYGC", - "gerryhjs" - ] - }, - "Web/API/RTCPeerConnection/connectionState": { - "modified": "2020-10-15T22:07:32.880Z", - "contributors": [ - "HenryloveGod" - ] - }, - "Web/API/RTCPeerConnection/createDataChannel": { - "modified": "2020-10-15T22:19:11.761Z", - "contributors": [ - "hughfenghen", - "lzszone" - ] - }, - "Web/API/RTCPeerConnection/createOffer": { - "modified": "2020-10-15T22:28:40.870Z", - "contributors": [ - "王志双" - ] - }, - "Web/API/RTCPeerConnection/currentLocalDescription": { - "modified": "2020-10-15T22:34:32.333Z", - "contributors": [ - "SDUTWSL" - ] - }, - "Web/API/RTCPeerConnection/getDefaultIceServers": { - "modified": "2020-10-15T22:29:03.476Z", - "contributors": [ - "lauhua" - ] - }, - "Web/API/RTCPeerConnection/getReceivers": { - "modified": "2020-10-15T22:34:32.923Z", - "contributors": [ - "SDUTWSL" - ] - }, - "Web/API/RTCPeerConnection/iceConnectionState": { - "modified": "2019-03-23T22:52:11.739Z", - "contributors": [ - "starsun" - ] - }, - "Web/API/RTCPeerConnection/iceGatheringState": { - "modified": "2020-10-15T22:29:02.585Z", - "contributors": [ - "lauhua" - ] - }, - "Web/API/RTCPeerConnection/onaddstream": { - "modified": "2019-03-23T22:57:28.674Z", - "contributors": [ - "starsun" - ] - }, - "Web/API/RTCPeerConnection/ondatachannel": { - "modified": "2019-03-23T22:21:43.126Z", - "contributors": [ - "physihan" - ] - }, - "Web/API/RTCPeerConnection/onicecandidate": { - "modified": "2020-10-15T22:21:52.694Z", - "contributors": [ - "babaiwan" - ] - }, - "Web/API/RTCPeerConnection/ontrack": { - "modified": "2019-03-18T21:45:45.168Z", - "contributors": [ - "track_vovo" - ] - }, - "Web/API/RTCPeerConnection/peerIdentity": { - "modified": "2020-10-15T22:23:54.416Z", - "contributors": [ - "f4f5" - ] - }, - "Web/API/RTCPeerConnection/remoteDescription": { - "modified": "2020-10-15T22:11:36.122Z", - "contributors": [ - "Tsui" - ] - }, - "Web/API/RTCPeerConnection/removeStream": { - "modified": "2019-03-23T22:57:28.096Z", - "contributors": [ - "starsun" - ] - }, - "Web/API/RTCPeerConnection/setConfiguration": { - "modified": "2020-10-15T22:32:23.692Z", - "contributors": [ - "arthuang" - ] - }, - "Web/API/RTCPeerConnection/setRemoteDescription": { - "modified": "2019-03-28T04:33:35.339Z", - "contributors": [ - "a631807682", - "w05163" - ] - }, - "Web/API/RTCRtpTransceiver": { - "modified": "2020-10-15T22:34:39.974Z", - "contributors": [ - "Sheppy" - ] - }, - "Web/API/RTCRtpTransceiver/direction": { - "modified": "2020-10-15T22:34:40.693Z", - "contributors": [ - "BandOfBrothersZTS" - ] - }, - "Web/API/RTCSessionDescription": { - "modified": "2019-09-10T06:45:22.765Z", - "contributors": [ - "IsolatedTraveler", - "SolitudeRA" - ] - }, - "Web/API/RTCStats": { - "modified": "2020-10-15T22:31:33.896Z", - "contributors": [ - "Sheppy" - ] - }, - "Web/API/RTCStats/id": { - "modified": "2020-10-15T22:31:33.589Z", - "contributors": [ - "alexwen.cn" - ] - }, - "Web/API/RTCStatsReport": { - "modified": "2020-10-15T22:31:34.788Z", - "contributors": [ - "alexwen.cn" - ] - }, - "Web/API/RTCTrackEvent": { - "modified": "2020-10-15T22:34:34.903Z", - "contributors": [ - "Sheppy" - ] - }, - "Web/API/RTCTrackEvent/RTCTrackEvent": { - "modified": "2020-10-15T22:34:34.415Z", - "contributors": [ - "rmamy" - ] - }, - "Web/API/RandomSource": { - "modified": "2019-03-23T22:14:07.005Z", - "contributors": [ - "micblo" - ] - }, - "Web/API/RandomSource/getRandomValues": { - "modified": "2020-10-15T21:53:31.704Z", - "contributors": [ - "RainSlide", - "ywjco", - "micblo" - ] - }, - "Web/API/Range": { - "modified": "2020-10-15T21:14:38.719Z", - "contributors": [ - "RainSlide", - "gnepnaiL-oahZ", - "maicss", - "teoli", - "jsx", - "Losses", - "ziyunfei", - "luolonghao", - "goodkele", - "Samgolam" - ] - }, - "Web/API/Range/Range": { - "modified": "2020-09-26T05:00:50.089Z", - "contributors": [ - "TeabugCC", - "old2sun", - "DistChen" - ] - }, - "Web/API/Range/cloneContents": { - "modified": "2020-10-15T22:34:31.380Z", - "contributors": [ - "zkl2333" - ] - }, - "Web/API/Range/cloneRange": { - "modified": "2019-03-23T22:03:10.523Z", - "contributors": [ - "Jemory" - ] - }, - "Web/API/Range/collapse": { - "modified": "2020-10-15T21:53:38.240Z", - "contributors": [ - "Mookiepiece", - "enem" - ] - }, - "Web/API/Range/collapsed": { - "modified": "2019-03-23T22:22:29.507Z", - "contributors": [ - "GentleMint", - "Smart" - ] - }, - "Web/API/Range/commonAncestorContainer": { - "modified": "2020-10-15T22:16:13.137Z", - "contributors": [ - "faliye" - ] - }, - "Web/API/Range/createContextualFragment": { - "modified": "2020-10-15T22:34:57.657Z", - "contributors": [ - "Y2Lin" - ] - }, - "Web/API/Range/deleteContents": { - "modified": "2019-03-18T21:44:16.852Z", - "contributors": [ - "lbwa" - ] - }, - "Web/API/Range/endContainer": { - "modified": "2019-03-18T21:42:17.127Z", - "contributors": [ - "Hyiker" - ] - }, - "Web/API/Range/endOffset": { - "modified": "2020-10-15T22:04:46.141Z", - "contributors": [ - "Carllllo", - "gnepnaiL-oahZ" - ] - }, - "Web/API/Range/extractContents": { - "modified": "2020-10-15T21:50:21.817Z", - "contributors": [ - "SphinxKnight", - "small-Dream", - "124ztzy" - ] - }, - "Web/API/Range/getBoundingClientRect": { - "modified": "2020-10-15T21:31:18.038Z", - "contributors": [ - "Clarkkkk", - "RainSlide", - "leere", - "teoli", - "zldream1106" - ] - }, - "Web/API/Range/getClientRects": { - "modified": "2020-10-15T22:30:55.065Z", - "contributors": [ - "Clarkkkk" - ] - }, - "Web/API/Range/insertNode": { - "modified": "2019-03-23T22:09:26.561Z", - "contributors": [ - "asd79220", - "maicss" - ] - }, - "Web/API/Range/intersectsNode": { - "modified": "2020-10-15T22:21:07.418Z", - "contributors": [ - "Char-Ten" - ] - }, - "Web/API/Range/selectNode": { - "modified": "2020-10-15T21:58:24.220Z", - "contributors": [ - "Carllllo", - "gnepnaiL-oahZ", - "Mark_Zhang" - ] - }, - "Web/API/Range/selectNodeContents": { - "modified": "2020-10-15T21:54:18.202Z", - "contributors": [ - "Carllllo", - "gnepnaiL-oahZ", - "sunly8", - "AQingC" - ] - }, - "Web/API/Range/setEnd": { - "modified": "2019-03-18T21:41:00.642Z", - "contributors": [ - "xiaozhaoqi" - ] - }, - "Web/API/Range/setStart": { - "modified": "2019-03-23T22:22:20.079Z", - "contributors": [ - "Smart" - ] - }, - "Web/API/Range/setStartBefore": { - "modified": "2020-10-15T22:18:37.906Z", - "contributors": [ - "loszer" - ] - }, - "Web/API/Range/startContainer": { - "modified": "2019-03-23T22:02:05.516Z", - "contributors": [ - "li5454yong" - ] - }, - "Web/API/Range/startOffset": { - "modified": "2020-10-15T21:28:32.328Z", - "contributors": [ - "Carllllo", - "teoli", - "khalid32", - "Losses" - ] - }, - "Web/API/Range/surroundContents": { - "modified": "2020-10-15T21:31:39.712Z", - "contributors": [ - "Carllllo", - "teoli", - "chyancheng" - ] - }, - "Web/API/ReadableStream": { - "modified": "2020-10-15T21:55:06.360Z", - "contributors": [ - "hayahayao", - "jason-grimm", - "jcsahnwaldt", - "shenguoyi", - "heyiwang", - "yqjiang" - ] - }, - "Web/API/ReadableStream/ReadableStream": { - "modified": "2020-10-15T22:04:39.987Z", - "contributors": [ - "fsx950223" - ] - }, - "Web/API/ReadableStream/getReader": { - "modified": "2020-10-15T22:21:51.043Z", - "contributors": [ - "Yangmi", - "rockan007" - ] - }, - "Web/API/ReadableStreamDefaultReader": { - "modified": "2019-03-18T21:36:09.836Z", - "contributors": [ - "zhiyuanzmj" - ] - }, - "Web/API/RenderingContext": { - "modified": "2019-03-23T22:53:04.731Z", - "contributors": [ - "ice-i-snow" - ] - }, - "Web/API/Request": { - "modified": "2020-10-15T21:43:47.794Z", - "contributors": [ - "xx1124961758", - "mazeyqian", - "wyyhttp", - "freeshineit", - "johnlin0207", - "qinghaitvxq", - "mo-n", - "gafish", - "looch5" - ] - }, - "Web/API/Request/Request": { - "modified": "2020-11-30T00:48:41.078Z", - "contributors": [ - "RoXoM", - "LPegasus", - "TiaossuP" - ] - }, - "Web/API/Request/cache": { - "modified": "2020-10-15T22:03:58.215Z", - "contributors": [ - "sundakai", - "fscholz", - "Xarrow" - ] - }, - "Web/API/Request/clone": { - "modified": "2020-10-15T22:20:36.379Z", - "contributors": [ - "sixpencecl" - ] - }, - "Web/API/Request/context": { - "modified": "2020-10-15T22:30:43.048Z", - "contributors": [ - "Aliom252181" - ] - }, - "Web/API/Request/credentials": { - "modified": "2020-10-15T21:53:30.490Z", - "contributors": [ - "jzz567", - "lichao", - "Maxpsc" - ] - }, - "Web/API/Request/headers": { - "modified": "2020-10-15T22:02:37.822Z", - "contributors": [ - "flyingsouthwind", - "zyq" - ] - }, - "Web/API/Request/method": { - "modified": "2019-03-23T22:14:02.673Z", - "contributors": [ - "Maxpsc" - ] - }, - "Web/API/Request/mode": { - "modified": "2020-10-15T21:53:28.442Z", - "contributors": [ - "LPegasus", - "bytetown", - "RainSlide", - "hughfenghen", - "johnlin0207", - "FLYSLOW", - "xgqfrms-GitHub" - ] - }, - "Web/API/Request/url": { - "modified": "2019-03-23T22:18:08.784Z", - "contributors": [ - "thomastao0215" - ] - }, - "Web/API/ResizeObserver": { - "modified": "2020-10-15T22:16:57.862Z", - "contributors": [ - "vaynewang" - ] - }, - "Web/API/ResizeObserver/ResizeObserver": { - "modified": "2020-10-15T22:16:57.649Z", - "contributors": [ - "vaynewang" - ] - }, - "Web/API/ResizeObserver/disconnect": { - "modified": "2020-10-15T22:16:58.354Z", - "contributors": [ - "vaynewang" - ] - }, - "Web/API/ResizeObserver/observe": { - "modified": "2020-10-15T22:16:57.753Z", - "contributors": [ - "ZSI2017", - "vaynewang" - ] - }, - "Web/API/ResizeObserver/unobserve": { - "modified": "2020-10-15T22:16:58.792Z", - "contributors": [ - "vaynewang" - ] - }, - "Web/API/ResizeObserverEntry": { - "modified": "2020-10-15T22:18:18.516Z", - "contributors": [ - "vaynewang" - ] - }, - "Web/API/Resize_Observer_API": { - "modified": "2020-10-15T22:31:10.210Z", - "contributors": [ - "brizer" - ] - }, - "Web/API/Resource_Timing_API": { - "modified": "2019-03-18T20:44:25.988Z", - "contributors": [ - "linapengzhe", - "suchasplus" - ] - }, - "Web/API/Resource_Timing_API/Using_the_Resource_Timing_API": { - "modified": "2020-08-05T06:24:43.888Z", - "contributors": [ - "EzioShiki", - "Mukti" - ] - }, - "Web/API/Response": { - "modified": "2020-10-15T21:46:45.688Z", - "contributors": [ - "RainSlide", - "Soyaine", - "jason-grimm", - "disoul", - "maicss", - "WangYihang", - "thbgh", - "zyq930501", - "a1528zhang", - "wynn_pm2b", - "Sheppy" - ] - }, - "Web/API/Response/Response": { - "modified": "2020-12-01T03:25:15.383Z", - "contributors": [ - "RoXoM", - "alsotang", - "xgqfrms-GitHub", - "billcz" - ] - }, - "Web/API/Response/error": { - "modified": "2020-10-15T22:29:39.838Z", - "contributors": [ - "rikochyou" - ] - }, - "Web/API/Response/headers": { - "modified": "2020-10-15T21:54:27.453Z", - "contributors": [ - "jason-grimm", - "xgqfrms-GitHub" - ] - }, - "Web/API/Response/ok": { - "modified": "2019-10-08T06:04:55.007Z", - "contributors": [ - "nighca", - "tobetobe", - "flyingsouthwind", - "airt" - ] - }, - "Web/API/Response/redirect": { - "modified": "2020-10-15T22:23:27.822Z", - "contributors": [ - "fanxiaobin1024" - ] - }, - "Web/API/Response/redirected": { - "modified": "2020-10-15T22:20:40.824Z", - "contributors": [ - "Jaden1993" - ] - }, - "Web/API/Response/status": { - "modified": "2019-03-21T03:39:45.436Z", - "contributors": [ - "ChaoyueZhao", - "xgqfrms-GitHub" - ] - }, - "Web/API/Response/statusText": { - "modified": "2019-03-23T22:11:20.257Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/Response/type": { - "modified": "2019-03-23T22:12:54.001Z", - "contributors": [ - "fsx950223", - "Stevenzwzhai" - ] - }, - "Web/API/Response/url": { - "modified": "2020-10-15T22:18:40.751Z", - "contributors": [ - "wl237292950" - ] - }, - "Web/API/Response/克隆": { - "modified": "2019-03-23T22:03:57.353Z", - "contributors": [ - "Ende93", - "xiaoxiaojx" - ] - }, - "Web/API/SVGAElement": { - "modified": "2019-09-09T08:02:49.792Z", - "contributors": [ - "wxyads", - "fanxiaojie" - ] - }, - "Web/API/SVGAnimateElement": { - "modified": "2020-10-15T22:30:53.204Z", - "contributors": [ - "wellssu0" - ] - }, - "Web/API/SVGAnimatedAngle": { - "modified": "2019-03-18T21:43:11.107Z", - "contributors": [ - "luluyiluchangtong" - ] - }, - "Web/API/SVGAnimationElement": { - "modified": "2020-10-15T22:25:05.656Z", - "contributors": [ - "chrisdavidmills" - ] - }, - "Web/API/SVGAnimationElement/targetElement": { - "modified": "2020-10-15T22:25:05.105Z", - "contributors": [ - "sqchenxiyuan" - ] - }, - "Web/API/SVGCircleElement": { - "modified": "2019-03-23T22:46:23.143Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/API/SVGElement": { - "modified": "2019-03-18T21:45:45.584Z", - "contributors": [ - "hhxxhg", - "JiGuangYuan" - ] - }, - "Web/API/SVGEvent": { - "modified": "2019-10-28T02:13:30.632Z", - "contributors": [ - "Isildur46" - ] - }, - "Web/API/SVGGeometryElement": { - "modified": "2020-10-15T22:28:00.393Z" - }, - "Web/API/SVGGeometryElement/getPointAtLength": { - "modified": "2020-10-15T22:27:59.903Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/API/SVGGraphicsElement": { - "modified": "2020-11-11T22:45:23.664Z", - "contributors": [ - "Master-gg-02" - ] - }, - "Web/API/SVGGraphicsElement/getBBox": { - "modified": "2020-02-02T12:42:57.619Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/API/SVGMatrix": { - "modified": "2020-10-15T22:22:00.749Z", - "contributors": [ - "diozhu" - ] - }, - "Web/API/SVGPathElement": { - "modified": "2019-03-23T22:46:19.708Z", - "contributors": [ - "ZhengYinBo", - "fanxiaojie" - ] - }, - "Web/API/SVGPathElement/getTotalLength": { - "modified": "2020-10-15T22:32:52.448Z", - "contributors": [ - "tiny-gravel" - ] - }, - "Web/API/SVGSVGElement": { - "modified": "2020-10-15T22:20:08.511Z", - "contributors": [ - "PYGC", - "qzwg" - ] - }, - "Web/API/SVGUseElement": { - "modified": "2020-10-15T22:24:51.190Z", - "contributors": [ - "zhangchen", - "jieliu12323" - ] - }, - "Web/API/Screen": { - "modified": "2020-10-15T21:33:02.938Z", - "contributors": [ - "lizheming", - "fenyu", - "JingLMalan", - "Bayes", - "teoli" - ] - }, - "Web/API/Screen/availHeight": { - "modified": "2019-03-23T23:10:33.122Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Screen/availLeft": { - "modified": "2019-03-23T23:10:32.405Z", - "contributors": [ - "teoli", - "khalid32", - "AlexChao" - ] - }, - "Web/API/Screen/availTop": { - "modified": "2019-03-23T23:10:26.366Z", - "contributors": [ - "teoli", - "khalid32", - "AlexChao" - ] - }, - "Web/API/Screen/availWidth": { - "modified": "2019-03-23T23:10:30.530Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Screen/colorDepth": { - "modified": "2019-03-23T23:10:27.345Z", - "contributors": [ - "kameii", - "teoli", - "AlexChao" - ] - }, - "Web/API/Screen/height": { - "modified": "2019-03-23T23:10:29.306Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Screen/lockOrientation": { - "modified": "2019-03-23T22:03:27.404Z", - "contributors": [ - "cnrenqun" - ] - }, - "Web/API/Screen/orientation": { - "modified": "2020-10-15T22:29:19.914Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/Screen/pixelDepth": { - "modified": "2019-03-23T23:10:32.503Z", - "contributors": [ - "kameii", - "teoli", - "AlexChao" - ] - }, - "Web/API/Screen/width": { - "modified": "2019-03-23T23:10:29.689Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Screen_Capture_API": { - "modified": "2020-10-15T22:30:44.340Z", - "contributors": [ - "hzy", - "Sheppy" - ] - }, - "Web/API/Screen_Capture_API/使用屏幕捕获API": { - "modified": "2020-09-27T04:18:52.593Z", - "contributors": [ - "Bigsomg", - "hzy" - ] - }, - "Web/API/ScriptProcessorNode": { - "modified": "2019-03-23T22:12:23.715Z", - "contributors": [ - "Dorasan", - "evollhhan", - "huangxok" - ] - }, - "Web/API/ScrollToOptions": { - "modified": "2020-10-15T22:21:27.337Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/API/Selection": { - "modified": "2020-10-15T21:21:32.379Z", - "contributors": [ - "zhengzefanyy", - "MCCF", - "xiaotianxia", - "leere", - "ucev", - "xgqfrms-GitHub", - "BobGreen", - "laobubu", - "flowfire", - "manxingxing", - "jsx", - "Losses", - "ziyunfei", - "gqqnbig", - "JeanDavidDaviet" - ] - }, - "Web/API/Selection/addRange": { - "modified": "2020-10-15T21:28:33.678Z", - "contributors": [ - "1v9", - "Ghost_2017", - "rguanghui", - "teoli", - "khalid32", - "Losses" - ] - }, - "Web/API/Selection/anchorNode": { - "modified": "2019-03-23T23:13:31.434Z", - "contributors": [ - "mominbin", - "dclovec", - "teoli", - "jsx", - "Losses" - ] - }, - "Web/API/Selection/anchorOffset": { - "modified": "2019-03-23T22:48:56.795Z", - "contributors": [ - "jruif" - ] - }, - "Web/API/Selection/collapse": { - "modified": "2020-10-15T21:51:18.956Z", - "contributors": [ - "zhangchen", - "gnepnaiL-oahZ", - "mimiton" - ] - }, - "Web/API/Selection/collapseToEnd": { - "modified": "2019-03-23T22:48:58.200Z", - "contributors": [ - "ziyunfei" - ] - }, - "Web/API/Selection/collapseToStart": { - "modified": "2020-10-15T21:21:30.679Z", - "contributors": [ - "RainSlide", - "ziyunfei", - "jruif", - "teoli", - "khalid32" - ] - }, - "Web/API/Selection/containsNode": { - "modified": "2019-03-18T21:16:41.671Z", - "contributors": [ - "dclovec" - ] - }, - "Web/API/Selection/extend": { - "modified": "2019-08-09T05:30:40.774Z", - "contributors": [ - "inottn" - ] - }, - "Web/API/Selection/focusNode": { - "modified": "2019-03-23T23:13:28.778Z", - "contributors": [ - "dclovec", - "teoli", - "arunpandianp", - "Losses" - ] - }, - "Web/API/Selection/focusOffset": { - "modified": "2019-03-23T22:40:09.925Z", - "contributors": [ - "mimiton", - "DistChen" - ] - }, - "Web/API/Selection/getRangeAt": { - "modified": "2020-10-15T21:28:32.032Z", - "contributors": [ - "SphinxKnight", - "1v9", - "teoli", - "arunpandianp", - "Losses" - ] - }, - "Web/API/Selection/isCollapsed": { - "modified": "2019-03-23T23:13:35.500Z", - "contributors": [ - "teoli", - "jsx", - "Losses" - ] - }, - "Web/API/Selection/modify": { - "modified": "2019-03-23T22:21:21.972Z", - "contributors": [ - "mimiton" - ] - }, - "Web/API/Selection/rangeCount": { - "modified": "2020-05-05T02:47:57.127Z", - "contributors": [ - "oooooo", - "MCCF", - "licongmu" - ] - }, - "Web/API/Selection/removeAllRanges": { - "modified": "2020-10-15T21:41:17.244Z", - "contributors": [ - "HYiteam", - "1v9", - "licongmu" - ] - }, - "Web/API/Selection/removeRange": { - "modified": "2019-03-23T23:13:35.977Z", - "contributors": [ - "teoli", - "khalid32", - "Losses" - ] - }, - "Web/API/Selection/selectAllChildren": { - "modified": "2020-10-15T21:56:39.200Z", - "contributors": [ - "1v9", - "inottn", - "corlin" - ] - }, - "Web/API/Selection/setBaseAndExtent": { - "modified": "2019-03-18T21:46:17.834Z", - "contributors": [ - "XyyF" - ] - }, - "Web/API/Selection/toString": { - "modified": "2019-03-23T22:27:26.113Z", - "contributors": [ - "dclovec" - ] - }, - "Web/API/Selection/type": { - "modified": "2020-08-04T09:15:14.133Z", - "contributors": [ - "Junezm", - "yuhengliang" - ] - }, - "Web/API/Selection/从Document中删除": { - "modified": "2019-03-23T22:25:17.531Z", - "contributors": [ - "FormatFa" - ] - }, - "Web/API/Sensor_APIs": { - "modified": "2020-10-15T22:11:34.758Z", - "contributors": [ - "oldsong" - ] - }, - "Web/API/ServiceWorker": { - "modified": "2019-10-08T02:48:10.610Z", - "contributors": [ - "xgqfrms-GitHub", - "Taoja", - "marsoln" - ] - }, - "Web/API/ServiceWorker/onstatechange": { - "modified": "2019-03-23T22:08:26.258Z", - "contributors": [ - "fanyer" - ] - }, - "Web/API/ServiceWorker/scriptURL": { - "modified": "2019-03-23T22:08:31.728Z", - "contributors": [ - "fanyer" - ] - }, - "Web/API/ServiceWorker/state": { - "modified": "2019-03-23T22:08:36.804Z", - "contributors": [ - "fanyer" - ] - }, - "Web/API/ServiceWorkerContainer": { - "modified": "2019-03-23T22:22:40.555Z", - "contributors": [ - "jianxcao", - "chrisdavidmills" - ] - }, - "Web/API/ServiceWorkerContainer/controller": { - "modified": "2020-10-15T22:18:23.623Z", - "contributors": [ - "Ccigratte" - ] - }, - "Web/API/ServiceWorkerContainer/register": { - "modified": "2019-03-18T20:54:01.785Z", - "contributors": [ - "stack_vim", - "flyingsouthwind", - "xgqfrms-GitHub", - "178784676" - ] - }, - "Web/API/ServiceWorkerGlobalScope": { - "modified": "2020-10-28T00:19:37.995Z", - "contributors": [ - "peter006qi", - "TimLuo465" - ] - }, - "Web/API/ServiceWorkerGlobalScope/caches": { - "modified": "2020-10-28T03:25:10.149Z", - "contributors": [ - "peter006qi" - ] - }, - "Web/API/ServiceWorkerRegistration": { - "modified": "2019-03-23T22:12:58.327Z", - "contributors": [ - "chrisdavidmills" - ] - }, - "Web/API/ServiceWorkerRegistration/active": { - "modified": "2019-03-23T22:13:08.207Z", - "contributors": [ - "Stevenzwzhai" - ] - }, - "Web/API/ServiceWorkerRegistration/pushManager": { - "modified": "2019-03-23T22:12:14.803Z", - "contributors": [ - "flyingsouthwind" - ] - }, - "Web/API/ServiceWorkerRegistration/unregister": { - "modified": "2020-10-15T22:18:23.732Z", - "contributors": [ - "Ccigratte" - ] - }, - "Web/API/ServiceWorkerRegistration/update": { - "modified": "2020-10-15T22:22:26.321Z", - "contributors": [ - "hellolwq" - ] - }, - "Web/API/Service_Worker_API": { - "modified": "2020-09-14T14:58:18.403Z", - "contributors": [ - "Clarkkkk", - "laampui", - "zhangchen", - "varcat", - "isLishude", - "Soyaine", - "Samuel89Su", - "jinnchen", - "yellowkingdom", - "xgqfrms-GitHub", - "Jiang-Xuan", - "binggg", - "sartrey", - "178784676", - "NicoleWong007", - "whwei", - "toxic-johann", - "zilong-thu", - "nyx2014" - ] - }, - "Web/API/Service_Worker_API/Using_Service_Workers": { - "modified": "2020-10-05T03:53:38.253Z", - "contributors": [ - "plusmultiply0", - "tumingdongweb", - "LaiTaoGDUT", - "Ende93", - "wyhsz", - "xgqfrms", - "Gu.Hao", - "hongxu.Wei", - "ceido", - "luochangwei", - "ksh2016", - "simon3000", - "plter", - "paulatbeijing", - "xgqfrms-GitHub", - "CompileYouth", - "binggg", - "fedwatch", - "cyio", - "garrisonz", - "coolriver" - ] - }, - "Web/API/ShadowRoot": { - "modified": "2020-10-15T21:54:12.740Z", - "contributors": [ - "IAMSHENSH", - "Fancyflame", - "RainSlide", - "plter", - "xgqfrms-GitHub", - "Sebastianz" - ] - }, - "Web/API/ShadowRoot/delegatesFocus": { - "modified": "2020-10-15T22:28:01.762Z", - "contributors": [ - "Fancyflame" - ] - }, - "Web/API/ShadowRoot/innerHTML": { - "modified": "2019-03-23T22:12:21.460Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/ShadowRoot/mode": { - "modified": "2019-03-23T22:02:01.548Z", - "contributors": [ - "plter" - ] - }, - "Web/API/SharedWorker": { - "modified": "2020-10-15T21:50:11.679Z", - "contributors": [ - "biqing", - "ceido", - "xgqfrms-GitHub", - "zhengxinxin" - ] - }, - "Web/API/SharedWorker/SharedWorker": { - "modified": "2020-10-15T22:09:57.190Z", - "contributors": [ - "Katherina-Miao" - ] - }, - "Web/API/Slotable": { - "modified": "2020-10-15T22:26:24.148Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/API/SourceBuffer": { - "modified": "2020-10-15T22:20:48.679Z" - }, - "Web/API/SourceBuffer/appendBuffer": { - "modified": "2020-10-15T22:21:17.981Z", - "contributors": [ - "HanLess" - ] - }, - "Web/API/SourceBuffer/mode": { - "modified": "2020-10-15T22:20:47.967Z", - "contributors": [ - "wzwmzm" - ] - }, - "Web/API/SpeechGrammar": { - "modified": "2019-03-23T22:03:25.984Z", - "contributors": [ - "changkun", - "chrisdavidmills" - ] - }, - "Web/API/SpeechGrammar/SpeechGrammar": { - "modified": "2019-03-23T22:03:26.256Z", - "contributors": [ - "changkun" - ] - }, - "Web/API/SpeechGrammar/src": { - "modified": "2019-03-23T22:03:29.189Z", - "contributors": [ - "changkun" - ] - }, - "Web/API/SpeechGrammar/weight": { - "modified": "2019-03-23T22:03:29.741Z", - "contributors": [ - "changkun" - ] - }, - "Web/API/SpeechRecognitionResult": { - "modified": "2019-03-18T21:40:00.463Z", - "contributors": [ - "chrisdavidmills" - ] - }, - "Web/API/SpeechRecognitionResult/isFinal": { - "modified": "2019-03-18T21:22:52.581Z", - "contributors": [ - "anran758" - ] - }, - "Web/API/SpeechSynthesis": { - "modified": "2020-10-15T21:58:22.665Z", - "contributors": [ - "zhangchen", - "dandanbu3" - ] - }, - "Web/API/SpeechSynthesis/getVoices": { - "modified": "2020-10-15T22:13:53.655Z", - "contributors": [ - "crestin" - ] - }, - "Web/API/SpeechSynthesis/paused": { - "modified": "2019-03-23T22:03:28.522Z", - "contributors": [ - "dandanbu3" - ] - }, - "Web/API/SpeechSynthesisUtterance": { - "modified": "2020-10-15T22:33:53.663Z", - "contributors": [ - "sideshowbarker" - ] - }, - "Web/API/SpeechSynthesisUtterance/voice": { - "modified": "2020-10-15T22:33:52.374Z", - "contributors": [ - "dingFY" - ] - }, - "Web/API/Storage": { - "modified": "2020-10-15T21:34:16.549Z", - "contributors": [ - "zhangchen", - "woden0415", - "tkpromise", - "AlexChao", - "ThijsK" - ] - }, - "Web/API/Storage/LocalStorage": { - "modified": "2019-03-23T22:25:01.381Z", - "contributors": [ - "CuriosityLxn", - "jaiJia", - "lightning-zgc", - "kankk", - "tabooc", - "luneice", - "liuzeyafzy" - ] - }, - "Web/API/Storage/clear": { - "modified": "2019-03-23T22:58:05.467Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/API/Storage/getItem": { - "modified": "2019-03-23T22:58:05.779Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/API/Storage/key": { - "modified": "2020-09-21T06:38:46.859Z", - "contributors": [ - "JaxsonWang", - "tfcx-th", - "AlexChao" - ] - }, - "Web/API/Storage/length": { - "modified": "2019-03-23T22:58:05.608Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/API/Storage/removeItem": { - "modified": "2019-03-18T20:37:45.984Z", - "contributors": [ - "peteosx1x", - "Hew007", - "AlexChao" - ] - }, - "Web/API/Storage/setItem": { - "modified": "2020-10-15T21:34:18.498Z", - "contributors": [ - "imbriansun", - "zhangchen", - "AlexChao" - ] - }, - "Web/API/StorageEstimate": { - "modified": "2019-03-18T21:31:04.064Z", - "contributors": [ - "hhxxhg" - ] - }, - "Web/API/StorageEvent": { - "modified": "2019-05-20T00:34:34.333Z", - "contributors": [ - "ShuaigeLee", - "Indinity", - "toBeTheLight", - "houzp", - "FredWe" - ] - }, - "Web/API/StorageManager": { - "modified": "2020-10-15T22:25:54.629Z", - "contributors": [ - "Li-saltair" - ] - }, - "Web/API/StorageManager/estimate": { - "modified": "2020-10-15T22:25:54.613Z", - "contributors": [ - "Li-saltair" - ] - }, - "Web/API/StorageManager/persist": { - "modified": "2020-10-15T22:25:56.370Z", - "contributors": [ - "Li-saltair" - ] - }, - "Web/API/StorageManager/persisted": { - "modified": "2020-10-15T22:25:55.830Z", - "contributors": [ - "Li-saltair" - ] - }, - "Web/API/Storage_API": { - "modified": "2020-10-15T22:19:19.587Z", - "contributors": [ - "x1shi", - "RainSlide" - ] - }, - "Web/API/Streams_API": { - "modified": "2020-10-15T22:17:21.258Z", - "contributors": [ - "hayahayao", - "jiangseventeen" - ] - }, - "Web/API/Streams_API/使用可读文件流": { - "modified": "2019-08-08T09:43:09.249Z", - "contributors": [ - "qushuangru" - ] - }, - "Web/API/Streams_API/概念": { - "modified": "2020-10-27T00:49:21.364Z", - "contributors": [ - "xyzingh" - ] - }, - "Web/API/StylePropertyMap": { - "modified": "2020-10-15T22:12:27.758Z", - "contributors": [ - "RainSlide", - "kkocdko", - "zhangchen", - "SphinxKnight", - "nextdoorUncleLiu" - ] - }, - "Web/API/StyleSheet": { - "modified": "2019-03-24T00:17:16.923Z", - "contributors": [ - "yuyx91", - "wth", - "teoli", - "ziyunfei" - ] - }, - "Web/API/StyleSheet/disabled": { - "modified": "2020-10-15T21:45:10.265Z", - "contributors": [ - "Carllllo", - "nick-ChenZe" - ] - }, - "Web/API/StyleSheet/href": { - "modified": "2019-03-24T00:17:18.896Z", - "contributors": [ - "teoli", - "mimzi_fahia", - "ziyunfei" - ] - }, - "Web/API/StyleSheet/media": { - "modified": "2019-03-18T21:15:43.499Z", - "contributors": [ - "wth" - ] - }, - "Web/API/StyleSheet/title": { - "modified": "2020-10-15T21:48:24.416Z", - "contributors": [ - "fenyu", - "wth" - ] - }, - "Web/API/StyleSheetList": { - "modified": "2019-03-23T23:00:33.759Z", - "contributors": [ - "ToyYan", - "helloguangxue" - ] - }, - "Web/API/SubtleCrypto": { - "modified": "2019-06-25T03:23:16.057Z", - "contributors": [ - "Taoja", - "micblo", - "looch" - ] - }, - "Web/API/SubtleCrypto/decrypt": { - "modified": "2020-10-15T22:12:44.245Z", - "contributors": [ - "Maiko" - ] - }, - "Web/API/SubtleCrypto/encrypt": { - "modified": "2020-10-15T21:50:49.249Z", - "contributors": [ - "knightyun", - "Taoja" - ] - }, - "Web/API/Text": { - "modified": "2020-07-25T04:33:39.504Z", - "contributors": [ - "zhuhelong", - "jsx", - "AlexChao" - ] - }, - "Web/API/Text/Text": { - "modified": "2019-03-18T21:46:56.504Z", - "contributors": [ - "beyondbycyx" - ] - }, - "Web/API/Text/assignedSlot": { - "modified": "2019-03-18T21:47:01.185Z", - "contributors": [ - "beyondbycyx" - ] - }, - "Web/API/Text/isElementContentWhitespace": { - "modified": "2019-03-24T00:16:07.914Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Text/replaceWholeText": { - "modified": "2019-03-23T23:39:45.769Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Text/splitText": { - "modified": "2020-10-15T21:04:55.374Z", - "contributors": [ - "lmislm", - "RainSlide", - "teoli", - "ziyunfei" - ] - }, - "Web/API/Text/wholeText": { - "modified": "2020-07-22T00:26:07.040Z", - "contributors": [ - "ZiYang-Song", - "beyondbycyx" - ] - }, - "Web/API/TextDecoder": { - "modified": "2020-10-15T22:23:52.530Z", - "contributors": [ - "RainSlide", - "7NZ", - "lzs816" - ] - }, - "Web/API/TextEncoder": { - "modified": "2020-10-15T21:33:03.148Z", - "contributors": [ - "RainSlide", - "waitingsong", - "fscholz", - "Taoja", - "teoli" - ] - }, - "Web/API/TextEncoder/TextEncoder": { - "modified": "2019-03-23T23:26:45.874Z", - "contributors": [ - "Taoja", - "teoli", - "ziyunfei" - ] - }, - "Web/API/TextEncoder/encode": { - "modified": "2020-10-15T22:28:02.296Z", - "contributors": [ - "knightyun" - ] - }, - "Web/API/TextEncoder/encoding": { - "modified": "2020-10-15T21:53:34.941Z", - "contributors": [ - "fscholz", - "Taoja" - ] - }, - "Web/API/TextMetrics": { - "modified": "2020-10-15T21:37:09.299Z", - "contributors": [ - "gafish", - "msharedev", - "ice-i-snow" - ] - }, - "Web/API/TextMetrics/width": { - "modified": "2019-03-23T22:52:58.870Z", - "contributors": [ - "FredWe", - "ice-i-snow" - ] - }, - "Web/API/TextRange": { - "modified": "2020-02-27T01:42:43.987Z", - "contributors": [ - "MCCF" - ] - }, - "Web/API/TextRange/text": { - "modified": "2020-02-26T01:25:35.461Z", - "contributors": [ - "MCCF" - ] - }, - "Web/API/TimeRanges": { - "modified": "2019-03-18T21:37:59.069Z", - "contributors": [ - "Maysjtu" - ] - }, - "Web/API/TimeRanges/end": { - "modified": "2020-10-15T22:28:26.713Z", - "contributors": [ - "Humilitas" - ] - }, - "Web/API/TimeRanges/length": { - "modified": "2020-10-15T22:28:26.696Z", - "contributors": [ - "Humilitas" - ] - }, - "Web/API/TimeRanges/start": { - "modified": "2020-10-15T22:28:28.632Z", - "contributors": [ - "Humilitas" - ] - }, - "Web/API/Touch": { - "modified": "2020-10-15T21:22:09.520Z", - "contributors": [ - "Carllllo", - "HERMOO", - "Lux.lu", - "kenticny", - "jsx", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/Touch": { - "modified": "2019-03-23T22:25:38.560Z", - "contributors": [ - "CeHOU" - ] - }, - "Web/API/Touch/clientX": { - "modified": "2019-03-23T23:32:34.003Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/clientY": { - "modified": "2019-03-23T23:32:32.923Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/force": { - "modified": "2019-03-23T23:32:33.643Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/identifier": { - "modified": "2019-03-23T23:32:33.010Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/pageX": { - "modified": "2019-03-23T23:32:31.044Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/pageY": { - "modified": "2019-03-23T23:32:37.206Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/radiusX": { - "modified": "2019-03-23T23:32:37.628Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/radiusY": { - "modified": "2019-03-23T23:32:34.110Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/rotationAngle": { - "modified": "2019-03-23T23:32:35.532Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/screenX": { - "modified": "2019-03-23T23:32:36.422Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/screenY": { - "modified": "2019-03-23T23:32:37.830Z", - "contributors": [ - "yong.xiang", - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch/target": { - "modified": "2020-10-15T22:30:04.629Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/API/TouchEvent": { - "modified": "2020-10-15T21:22:00.912Z", - "contributors": [ - "Carllllo", - "1v9", - "INCHMAN", - "zhaosource", - "kangmingxuan", - "AshfaqHossain", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/TouchEvent/changedTouches": { - "modified": "2019-04-29T09:46:43.991Z", - "contributors": [ - "poapoc", - "Nick_Arron", - "teoli", - "khalid32", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/TouchEvent/targetTouches": { - "modified": "2020-10-15T21:38:16.552Z", - "contributors": [ - "zhangchen", - "WangLeto", - "six-moon", - "zhangxiaomiao" - ] - }, - "Web/API/TouchEvent/touches": { - "modified": "2020-10-15T21:54:08.310Z", - "contributors": [ - "ZZES_REN", - "yqwoshuai", - "Ende93", - "0123cf" - ] - }, - "Web/API/TouchList": { - "modified": "2020-10-15T21:21:34.692Z", - "contributors": [ - "zhangchen", - "kangmingxuan", - "jsx", - "ziyunfei", - "hyspace" - ] - }, - "Web/API/Touch_events": { - "modified": "2020-10-15T21:21:47.331Z", - "contributors": [ - "Roy-Tian", - "xgqfrms", - "wbamberg", - "xiaobutiaoer", - "shockw4ver", - "sszsfan", - "hebkia", - "genie88", - "ziyunfei", - "fscholz", - "ReyCG_sub", - "xcffl", - "jtyjty99999" - ] - }, - "Web/API/Touch_events/Multi-touch_interaction": { - "modified": "2019-03-18T21:29:11.313Z", - "contributors": [ - "meteorlxy" - ] - }, - "Web/API/Touch_events/Supporting_both_TouchEvent_and_MouseEvent": { - "modified": "2019-08-24T04:59:47.192Z", - "contributors": [ - "ouxuwen", - "meteorlxy" - ] - }, - "Web/API/Touch_events/Using_Touch_Events": { - "modified": "2019-03-23T22:09:03.982Z", - "contributors": [ - "niugeshenhua" - ] - }, - "Web/API/Transferable": { - "modified": "2020-10-15T21:39:40.681Z", - "contributors": [ - "RainSlide", - "Xiao4", - "teoli", - "wintertigerxu" - ] - }, - "Web/API/TransitionEvent": { - "modified": "2019-03-23T22:07:03.054Z", - "contributors": [ - "ucev" - ] - }, - "Web/API/TreeWalker": { - "modified": "2020-10-21T00:14:58.807Z", - "contributors": [ - "lastVigo", - "Carllllo" - ] - }, - "Web/API/TypeInfo": { - "modified": "2019-03-23T22:15:17.331Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/UIEvent": { - "modified": "2019-03-24T00:15:37.036Z", - "contributors": [ - "Ende93", - "teoli", - "ziyunfei" - ] - }, - "Web/API/UIEvent/UIEvent": { - "modified": "2020-10-15T22:24:06.838Z", - "contributors": [ - "csy19900206" - ] - }, - "Web/API/UIEvent/cancelBubble": { - "modified": "2019-03-24T00:17:23.644Z", - "contributors": [ - "ziyunfei", - "teoli", - "jsx" - ] - }, - "Web/API/UIEvent/detail": { - "modified": "2019-03-23T22:27:15.436Z", - "contributors": [ - "guoyang" - ] - }, - "Web/API/UIEvent/isChar": { - "modified": "2019-03-24T00:17:00.068Z", - "contributors": [ - "ziyunfei", - "teoli", - "jsx" - ] - }, - "Web/API/UIEvent/pageX": { - "modified": "2019-03-23T22:51:51.935Z", - "contributors": [ - "Tienyz" - ] - }, - "Web/API/UIEvent/pageY": { - "modified": "2019-03-24T00:16:10.292Z", - "contributors": [ - "ziyunfei", - "teoli", - "khalid32" - ] - }, - "Web/API/UIEvent/视图": { - "modified": "2020-10-15T22:25:09.871Z", - "contributors": [ - "pans9" - ] - }, - "Web/API/URL": { - "modified": "2020-10-15T21:33:08.666Z", - "contributors": [ - "Yayure", - "hutuxu", - "DirtyPP", - "ryerh", - "teoli" - ] - }, - "Web/API/URL/URL": { - "modified": "2020-10-15T21:29:21.552Z", - "contributors": [ - "jingkaimori", - "RainSlide", - "Mukti", - "hungtcs-lab", - "IrisYao", - "xgqfrms-GitHub", - "yuanfang-tony", - "teoli", - "leozdgao", - "khalid32", - "iori" - ] - }, - "Web/API/URL/createObjectURL": { - "modified": "2020-10-15T21:21:30.860Z", - "contributors": [ - "九千鸦", - "c1er", - "RainSlide", - "suyanhanx", - "yqjiang", - "GaoJun9521", - "xgqfrms-GitHub", - "PoppinL", - "teoli", - "ziyunfei" - ] - }, - "Web/API/URL/hash": { - "modified": "2020-10-15T22:14:23.531Z", - "contributors": [ - "Mukti", - "Han09", - "gcl1993" - ] - }, - "Web/API/URL/host": { - "modified": "2020-10-15T22:16:02.185Z", - "contributors": [ - "Mukti" - ] - }, - "Web/API/URL/hostname": { - "modified": "2020-10-15T22:16:02.341Z", - "contributors": [ - "Mukti" - ] - }, - "Web/API/URL/href": { - "modified": "2020-10-15T22:16:02.866Z", - "contributors": [ - "Mukti" - ] - }, - "Web/API/URL/origin": { - "modified": "2020-05-08T06:09:24.675Z", - "contributors": [ - "Owen-Tsai", - "Mukti", - "bluelifeleer" - ] - }, - "Web/API/URL/pathname": { - "modified": "2020-10-15T22:20:45.035Z", - "contributors": [ - "gongshun" - ] - }, - "Web/API/URL/port": { - "modified": "2020-10-15T22:20:16.068Z", - "contributors": [ - "corazon" - ] - }, - "Web/API/URL/protocol": { - "modified": "2020-10-15T22:20:15.923Z", - "contributors": [ - "corazon" - ] - }, - "Web/API/URL/revokeObjectURL": { - "modified": "2020-10-15T21:21:30.940Z", - "contributors": [ - "RainSlide", - "QizhongFang", - "PoppinL", - "teoli", - "ziyunfei" - ] - }, - "Web/API/URL/search": { - "modified": "2020-10-15T22:20:39.505Z", - "contributors": [ - "gongshun" - ] - }, - "Web/API/URL/searchParams": { - "modified": "2020-10-15T22:00:20.139Z", - "contributors": [ - "RainSlide", - "lujing2", - "theanarkh" - ] - }, - "Web/API/URL/toJSON": { - "modified": "2020-10-15T21:52:01.876Z", - "contributors": [ - "zhuguibiao", - "xgqfrms-GitHub", - "ziyunfei" - ] - }, - "Web/API/URL/toString": { - "modified": "2020-10-15T22:19:14.590Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/API/URL/username": { - "modified": "2020-10-15T22:20:39.496Z", - "contributors": [ - "JacobLiu", - "gongshun" - ] - }, - "Web/API/URL/密码": { - "modified": "2020-10-15T22:20:32.740Z", - "contributors": [ - "zhangchen", - "jessieic", - "jinjin" - ] - }, - "Web/API/URLSearchParams": { - "modified": "2020-10-15T21:31:23.789Z", - "contributors": [ - "mokunshao", - "Melo.HG", - "zhangchen", - "xianshenglu", - "lovue", - "scscms", - "teoli", - "ziyunfei" - ] - }, - "Web/API/URLSearchParams/URLSearchParams": { - "modified": "2019-03-23T22:07:52.553Z", - "contributors": [ - "lovue" - ] - }, - "Web/API/URLSearchParams/append": { - "modified": "2019-08-28T07:42:20.772Z", - "contributors": [ - "scscms" - ] - }, - "Web/API/URLSearchParams/delete": { - "modified": "2019-03-23T22:16:18.630Z", - "contributors": [ - "scscms" - ] - }, - "Web/API/URLSearchParams/entries": { - "modified": "2020-10-15T22:12:47.001Z", - "contributors": [ - "Heptagonnnn" - ] - }, - "Web/API/URLSearchParams/forEach": { - "modified": "2020-10-15T22:27:21.095Z", - "contributors": [ - "DIFFICULTTOGIVE" - ] - }, - "Web/API/URLSearchParams/get": { - "modified": "2020-10-15T22:11:37.713Z", - "contributors": [ - "amenging" - ] - }, - "Web/API/URLSearchParams/getAll": { - "modified": "2020-10-15T22:12:49.599Z", - "contributors": [ - "ciffelia", - "Heptagonnnn" - ] - }, - "Web/API/URLSearchParams/has": { - "modified": "2020-10-15T22:11:37.536Z", - "contributors": [ - "amenging" - ] - }, - "Web/API/URLSearchParams/keys": { - "modified": "2020-10-15T22:12:49.365Z", - "contributors": [ - "Heptagonnnn" - ] - }, - "Web/API/URLSearchParams/set": { - "modified": "2019-03-23T22:03:25.371Z", - "contributors": [ - "frankshin" - ] - }, - "Web/API/URLSearchParams/sort": { - "modified": "2019-03-23T22:19:47.633Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLSearchParams/toString": { - "modified": "2019-03-18T21:28:46.381Z", - "contributors": [ - "cysear" - ] - }, - "Web/API/URLSearchParams/values": { - "modified": "2020-10-15T22:12:49.791Z", - "contributors": [ - "Heptagonnnn" - ] - }, - "Web/API/URLUtils": { - "modified": "2020-10-15T21:33:08.803Z", - "contributors": [ - "RainSlide", - "AyAmeng", - "teoli" - ] - }, - "Web/API/URLUtils/hash": { - "modified": "2020-02-24T00:59:03.514Z", - "contributors": [ - "ikomom", - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/href": { - "modified": "2019-03-23T22:13:56.960Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/origin": { - "modified": "2019-03-23T22:12:28.154Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/password": { - "modified": "2019-03-23T22:12:38.210Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/pathname": { - "modified": "2019-03-23T22:12:27.883Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/search": { - "modified": "2019-03-23T22:16:26.271Z", - "contributors": [ - "xgqfrms-GitHub", - "kameii" - ] - }, - "Web/API/URLUtils/toString": { - "modified": "2019-03-23T22:13:59.877Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/username": { - "modified": "2019-03-23T22:12:31.600Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URL_API": { - "modified": "2020-10-15T22:31:18.077Z", - "contributors": [ - "xiaoyixiang" - ] - }, - "Web/API/USB": { - "modified": "2020-10-15T22:20:23.616Z", - "contributors": [ - "Himself65", - "yuyang" - ] - }, - "Web/API/USVString": { - "modified": "2019-06-12T04:54:37.434Z", - "contributors": [ - "zjffun", - "wizardforcel", - "xgqfrms-GitHub" - ] - }, - "Web/API/User_Timing_API": { - "modified": "2019-03-22T00:28:06.068Z", - "contributors": [ - "suvyme" - ] - }, - "Web/API/VRDisplay": { - "modified": "2019-03-23T22:25:25.766Z", - "contributors": [ - "sunwanxin213" - ] - }, - "Web/API/VRDisplay/requestAnimationFrame": { - "modified": "2019-03-23T22:12:19.956Z", - "contributors": [ - "ivyTa" - ] - }, - "Web/API/VRPose": { - "modified": "2019-03-23T22:29:44.644Z", - "contributors": [ - "SoAanyip" - ] - }, - "Web/API/VRPose/timeStamp": { - "modified": "2019-03-23T22:20:33.043Z", - "contributors": [ - "ajzeng" - ] - }, - "Web/API/ValidityState": { - "modified": "2020-10-15T21:19:36.661Z", - "contributors": [ - "Carllllo", - "ziyunfei", - "teoli", - "AshfaqHossain" - ] - }, - "Web/API/Vibration_API": { - "modified": "2019-03-23T22:20:25.275Z", - "contributors": [ - "xgqfrms-GitHub", - "Robin-fe" - ] - }, - "Web/API/VideoPlaybackQuality": { - "modified": "2019-03-23T22:18:45.577Z", - "contributors": [ - "esterTion" - ] - }, - "Web/API/VideoPlaybackQuality/totalVideoFrames": { - "modified": "2020-10-15T22:21:47.011Z", - "contributors": [ - "liangxin199045" - ] - }, - "Web/API/VideoTrackList": { - "modified": "2020-10-15T22:17:59.452Z", - "contributors": [ - "wbamberg" - ] - }, - "Web/API/VisualViewport": { - "modified": "2020-10-15T22:27:45.527Z", - "contributors": [ - "244462375", - "madebyfabian" - ] - }, - "Web/API/VisualViewport/offsetTop": { - "modified": "2020-10-15T22:29:41.734Z", - "contributors": [ - "c1er" - ] - }, - "Web/API/VisualViewport/offsetleft": { - "modified": "2020-10-15T22:27:43.850Z", - "contributors": [ - "aimaoll" - ] - }, - "Web/API/VisualViewport/onscroll": { - "modified": "2020-10-15T22:34:23.403Z", - "contributors": [ - "penneix" - ] - }, - "Web/API/WEBGL_lose_context": { - "modified": "2020-10-15T22:13:48.153Z", - "contributors": [ - "wymm0008" - ] - }, - "Web/API/WEBGL_lose_context/loseContext": { - "modified": "2020-10-15T22:28:07.619Z", - "contributors": [ - "Lucilor" - ] - }, - "Web/API/WEBGL_lose_context/restoreContext": { - "modified": "2020-10-15T22:28:07.375Z", - "contributors": [ - "Lucilor" - ] - }, - "Web/API/WakeLock": { - "modified": "2020-10-15T22:31:53.587Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/WakeLock/request": { - "modified": "2020-10-15T22:31:52.120Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/WakeLockSentinel": { - "modified": "2020-10-15T22:32:00.519Z", - "contributors": [ - "laampui" - ] - }, - "Web/API/WaveShaperNode": { - "modified": "2020-10-15T22:13:54.245Z", - "contributors": [ - "Tipwheal" - ] - }, - "Web/API/WaveShaperNode/WaveShaperNode": { - "modified": "2020-10-15T22:13:54.294Z", - "contributors": [ - "Tipwheal" - ] - }, - "Web/API/WaveShaperNode/curve": { - "modified": "2020-10-15T22:13:53.504Z", - "contributors": [ - "Tipwheal" - ] - }, - "Web/API/WaveShaperNode/oversample": { - "modified": "2020-10-15T22:13:53.511Z", - "contributors": [ - "Tipwheal" - ] - }, - "Web/API/WebGL2RenderingContext": { - "modified": "2020-10-15T21:49:54.891Z", - "contributors": [ - "NoDocCat", - "wymm0008", - "yangchengjian", - "sunwanxin213" - ] - }, - "Web/API/WebGL2RenderingContext/beginQuery": { - "modified": "2020-10-15T21:59:55.527Z", - "contributors": [ - "yangchengjian" - ] - }, - "Web/API/WebGL2RenderingContext/beginTransformFeedback": { - "modified": "2020-10-15T22:13:49.433Z", - "contributors": [ - "wymm0008" - ] - }, - "Web/API/WebGL2RenderingContext/bindBufferBase": { - "modified": "2020-10-15T22:13:49.139Z", - "contributors": [ - "wymm0008" - ] - }, - "Web/API/WebGL2RenderingContext/createSampler": { - "modified": "2020-10-15T22:21:09.791Z", - "contributors": [ - "murmur-wheel" - ] - }, - "Web/API/WebGL2RenderingContext/createVertexArray": { - "modified": "2020-10-15T22:12:38.302Z", - "contributors": [ - "konpoe" - ] - }, - "Web/API/WebGL2RenderingContext/drawBuffers": { - "modified": "2020-10-15T22:16:28.854Z", - "contributors": [ - "vent" - ] - }, - "Web/API/WebGL2RenderingContext/texImage3D": { - "modified": "2020-10-15T22:19:41.396Z", - "contributors": [ - "vent" - ] - }, - "Web/API/WebGL2RenderingContext/uniform": { - "modified": "2020-10-15T22:16:29.127Z", - "contributors": [ - "hellorayza", - "vent" - ] - }, - "Web/API/WebGL2RenderingContext/uniformMatrix": { - "modified": "2020-10-15T22:18:30.606Z", - "contributors": [ - "vent" - ] - }, - "Web/API/WebGLActiveInfo": { - "modified": "2020-10-15T21:55:58.249Z", - "contributors": [ - "XiangLuoyang" - ] - }, - "Web/API/WebGLBuffer": { - "modified": "2020-10-15T21:59:07.668Z", - "contributors": [ - "dondevi", - "anngg2008" - ] - }, - "Web/API/WebGLContextEvent": { - "modified": "2020-10-15T22:17:18.646Z", - "contributors": [ - "cracdic" - ] - }, - "Web/API/WebGLFramebuffer": { - "modified": "2020-10-15T22:22:15.158Z", - "contributors": [ - "whyjld" - ] - }, - "Web/API/WebGLProgram": { - "modified": "2020-10-15T21:54:18.558Z", - "contributors": [ - "lovefengruoqing", - "waraiotoko1108", - "wymm0008", - "codediy", - "loverinfo", - "lmx99" - ] - }, - "Web/API/WebGLQuery": { - "modified": "2020-10-15T22:05:47.017Z", - "contributors": [ - "deping_chen" - ] - }, - "Web/API/WebGLRenderbuffer": { - "modified": "2020-10-15T22:22:13.862Z", - "contributors": [ - "whyjld" - ] - }, - "Web/API/WebGLRenderingContext": { - "modified": "2020-10-15T21:40:12.989Z", - "contributors": [ - "shenwenkai", - "luojia", - "LiebeU", - "JoshuaLee", - "fscholz" - ] - }, - "Web/API/WebGLRenderingContext/activeTexture": { - "modified": "2019-03-23T22:24:12.726Z", - "contributors": [ - "LiebeU" - ] - }, - "Web/API/WebGLRenderingContext/attachShader": { - "modified": "2020-10-15T21:51:22.964Z", - "contributors": [ - "wumingdan" - ] - }, - "Web/API/WebGLRenderingContext/bindAttribLocation": { - "modified": "2020-10-15T21:53:56.112Z", - "contributors": [ - "C0DE_MONKEY" - ] - }, - "Web/API/WebGLRenderingContext/bindBuffer": { - "modified": "2020-10-15T21:53:56.509Z", - "contributors": [ - "kagurakana", - "shenwenkai", - "C0DE_MONKEY" - ] - }, - "Web/API/WebGLRenderingContext/bindFramebuffer": { - "modified": "2020-10-15T21:53:57.387Z", - "contributors": [ - "hellorayza", - "C0DE_MONKEY" - ] - }, - "Web/API/WebGLRenderingContext/bindRenderbuffer": { - "modified": "2020-10-15T21:53:58.250Z", - "contributors": [ - "hellorayza", - "C0DE_MONKEY" - ] - }, - "Web/API/WebGLRenderingContext/bindTexture": { - "modified": "2020-10-15T21:53:59.853Z", - "contributors": [ - "hellorayza", - "Sylvia_Y", - "C0DE_MONKEY" - ] - }, - "Web/API/WebGLRenderingContext/blendColor": { - "modified": "2020-10-15T21:53:58.222Z", - "contributors": [ - "C0DE_MONKEY" - ] - }, - "Web/API/WebGLRenderingContext/blendEquation": { - "modified": "2020-10-15T21:53:58.667Z", - "contributors": [ - "C0DE_MONKEY" - ] - }, - "Web/API/WebGLRenderingContext/blendEquationSeparate": { - "modified": "2020-10-15T22:14:43.676Z", - "contributors": [ - "gavinxgu" - ] - }, - "Web/API/WebGLRenderingContext/blendFunc": { - "modified": "2020-10-15T22:23:52.517Z", - "contributors": [ - "hellorayza" - ] - }, - "Web/API/WebGLRenderingContext/bufferData": { - "modified": "2020-10-15T22:06:51.527Z", - "contributors": [ - "totoro" - ] - }, - "Web/API/WebGLRenderingContext/canvas": { - "modified": "2020-10-15T21:50:17.639Z", - "contributors": [ - "wymm0008", - "luojia", - "LiebeU" - ] - }, - "Web/API/WebGLRenderingContext/clear": { - "modified": "2020-10-15T21:52:03.377Z", - "contributors": [ - "ihgazni", - "luojia" - ] - }, - "Web/API/WebGLRenderingContext/clearColor": { - "modified": "2020-10-15T21:52:02.365Z", - "contributors": [ - "luojia" - ] - }, - "Web/API/WebGLRenderingContext/clearDepth": { - "modified": "2020-10-15T21:55:10.731Z", - "contributors": [ - "shenwenkai" - ] - }, - "Web/API/WebGLRenderingContext/commit": { - "modified": "2020-10-15T21:59:26.379Z", - "contributors": [ - "dondevi" - ] - }, - "Web/API/WebGLRenderingContext/compileShader": { - "modified": "2020-10-15T21:56:26.723Z", - "contributors": [ - "yegao", - "Char-Ten" - ] - }, - "Web/API/WebGLRenderingContext/compressedTexImage2D": { - "modified": "2020-10-15T22:17:33.066Z", - "contributors": [ - "jiayuewang" - ] - }, - "Web/API/WebGLRenderingContext/createBuffer": { - "modified": "2020-10-15T21:59:09.897Z", - "contributors": [ - "anngg2008" - ] - }, - "Web/API/WebGLRenderingContext/createFramebuffer": { - "modified": "2020-10-15T22:01:50.599Z", - "contributors": [ - "hellorayza", - "Lapsec" - ] - }, - "Web/API/WebGLRenderingContext/createProgram": { - "modified": "2020-10-15T21:51:22.947Z", - "contributors": [ - "nishigouba", - "wumingdan" - ] - }, - "Web/API/WebGLRenderingContext/createRenderbuffer": { - "modified": "2020-10-15T22:04:25.034Z", - "contributors": [ - "hellorayza", - "slahser1992" - ] - }, - "Web/API/WebGLRenderingContext/createShader": { - "modified": "2020-10-15T21:56:03.049Z", - "contributors": [ - "lovefengruoqing", - "yegao", - "shahho", - "hi-zhaolei" - ] - }, - "Web/API/WebGLRenderingContext/createTexture": { - "modified": "2020-10-15T22:05:16.816Z", - "contributors": [ - "Sylvia_Y" - ] - }, - "Web/API/WebGLRenderingContext/cullFace": { - "modified": "2020-10-30T00:00:48.102Z", - "contributors": [ - "doowind" - ] - }, - "Web/API/WebGLRenderingContext/deleteBuffer": { - "modified": "2020-10-15T22:15:25.790Z", - "contributors": [ - "Char-Ten" - ] - }, - "Web/API/WebGLRenderingContext/deleteFramebuffer": { - "modified": "2020-10-15T22:23:36.993Z", - "contributors": [ - "hellorayza" - ] - }, - "Web/API/WebGLRenderingContext/deleteProgram": { - "modified": "2020-10-15T21:56:01.337Z", - "contributors": [ - "hi-zhaolei" - ] - }, - "Web/API/WebGLRenderingContext/deleteRenderbuffer": { - "modified": "2020-10-15T22:23:38.033Z", - "contributors": [ - "hellorayza" - ] - }, - "Web/API/WebGLRenderingContext/deleteShader": { - "modified": "2020-10-15T21:56:01.246Z", - "contributors": [ - "hi-zhaolei" - ] - }, - "Web/API/WebGLRenderingContext/deleteTexture": { - "modified": "2020-10-15T22:05:38.722Z", - "contributors": [ - "hellorayza", - "ewfian", - "eduwc" - ] - }, - "Web/API/WebGLRenderingContext/depthFunc": { - "modified": "2020-10-15T21:59:26.385Z", - "contributors": [ - "dondevi" - ] - }, - "Web/API/WebGLRenderingContext/depthMask": { - "modified": "2020-10-15T21:52:04.717Z", - "contributors": [ - "luojia" - ] - }, - "Web/API/WebGLRenderingContext/detachShader": { - "modified": "2020-10-15T22:11:59.621Z", - "contributors": [ - "shahho" - ] - }, - "Web/API/WebGLRenderingContext/disable": { - "modified": "2020-10-15T21:57:12.577Z", - "contributors": [ - "jack7758" - ] - }, - "Web/API/WebGLRenderingContext/drawArrays": { - "modified": "2020-10-15T21:59:30.908Z", - "contributors": [ - "qdlaoyao" - ] - }, - "Web/API/WebGLRenderingContext/drawElements": { - "modified": "2020-10-15T21:56:52.015Z", - "contributors": [ - "luludada", - "hellorayza", - "itaki" - ] - }, - "Web/API/WebGLRenderingContext/drawingBufferHeight": { - "modified": "2020-10-15T21:50:19.006Z", - "contributors": [ - "wymm0008", - "luojia", - "LiebeU" - ] - }, - "Web/API/WebGLRenderingContext/drawingBufferWidth": { - "modified": "2020-10-15T21:50:18.796Z", - "contributors": [ - "wymm0008", - "luojia", - "LiebeU" - ] - }, - "Web/API/WebGLRenderingContext/enable": { - "modified": "2020-10-15T21:55:12.469Z", - "contributors": [ - "shenwenkai" - ] - }, - "Web/API/WebGLRenderingContext/enableVertexAttribArray": { - "modified": "2020-10-15T22:24:44.627Z", - "contributors": [ - "Relia", - "shiqi-yang" - ] - }, - "Web/API/WebGLRenderingContext/getAttribLocation": { - "modified": "2020-10-15T22:00:11.731Z", - "contributors": [ - "kimmyLoveStudy" - ] - }, - "Web/API/WebGLRenderingContext/getContextAttributes": { - "modified": "2020-10-15T21:59:29.143Z", - "contributors": [ - "dondevi" - ] - }, - "Web/API/WebGLRenderingContext/getExtension": { - "modified": "2019-03-18T21:18:36.270Z", - "contributors": [ - "wymm0008" - ] - }, - "Web/API/WebGLRenderingContext/getParameter": { - "modified": "2020-10-15T21:59:31.029Z", - "contributors": [ - "dondevi" - ] - }, - "Web/API/WebGLRenderingContext/getProgramInfoLog": { - "modified": "2020-10-15T22:13:33.456Z", - "contributors": [ - "ihgazni" - ] - }, - "Web/API/WebGLRenderingContext/getProgramParameter": { - "modified": "2020-10-15T22:22:54.615Z", - "contributors": [ - "chenwuai" - ] - }, - "Web/API/WebGLRenderingContext/getShaderParameter": { - "modified": "2020-10-15T22:15:56.337Z", - "contributors": [ - "yegao", - "18569505972" - ] - }, - "Web/API/WebGLRenderingContext/getShaderSource": { - "modified": "2020-10-15T22:18:23.448Z", - "contributors": [ - "yegao" - ] - }, - "Web/API/WebGLRenderingContext/getSupportedExtensions": { - "modified": "2019-03-23T22:43:42.566Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/API/WebGLRenderingContext/getTexParameter": { - "modified": "2020-10-15T22:17:30.134Z", - "contributors": [ - "wangqi0902vip" - ] - }, - "Web/API/WebGLRenderingContext/getUniform": { - "modified": "2020-10-15T22:05:37.568Z", - "contributors": [ - "LaneSun", - "PYGC", - "ihgazni", - "eduwc" - ] - }, - "Web/API/WebGLRenderingContext/isBuffer": { - "modified": "2019-03-23T22:24:13.476Z", - "contributors": [ - "LiebeU" - ] - }, - "Web/API/WebGLRenderingContext/isContextLost": { - "modified": "2020-10-15T21:55:10.447Z", - "contributors": [ - "shenwenkai" - ] - }, - "Web/API/WebGLRenderingContext/isEnabled": { - "modified": "2019-03-23T22:24:22.077Z", - "contributors": [ - "LiebeU" - ] - }, - "Web/API/WebGLRenderingContext/isProgram": { - "modified": "2020-10-15T22:06:38.138Z", - "contributors": [ - "Tnze" - ] - }, - "Web/API/WebGLRenderingContext/isShader": { - "modified": "2020-10-15T22:13:48.637Z", - "contributors": [ - "wymm0008" - ] - }, - "Web/API/WebGLRenderingContext/linkProgram": { - "modified": "2020-10-15T21:59:57.650Z", - "contributors": [ - "lyno", - "qilinreal", - "yangchengjian" - ] - }, - "Web/API/WebGLRenderingContext/pixelStorei": { - "modified": "2020-10-15T21:53:34.990Z", - "contributors": [ - "mrzxc" - ] - }, - "Web/API/WebGLRenderingContext/renderbufferStorage": { - "modified": "2020-10-15T22:23:50.943Z", - "contributors": [ - "hellorayza" - ] - }, - "Web/API/WebGLRenderingContext/scissor": { - "modified": "2020-11-17T00:03:05.172Z", - "contributors": [ - "liguorain", - "shanghuo" - ] - }, - "Web/API/WebGLRenderingContext/shaderSource": { - "modified": "2020-10-15T21:59:49.913Z", - "contributors": [ - "weixingqi", - "cnwander" - ] - }, - "Web/API/WebGLRenderingContext/texImage2D": { - "modified": "2020-10-15T22:23:30.848Z", - "contributors": [ - "hellorayza" - ] - }, - "Web/API/WebGLRenderingContext/texParameter": { - "modified": "2020-10-15T22:14:45.546Z", - "contributors": [ - "hellorayza", - "FLYPoPo" - ] - }, - "Web/API/WebGLRenderingContext/uniform": { - "modified": "2020-11-05T23:12:32.253Z", - "contributors": [ - "yingzhiyi", - "hellorayza", - "172476032" - ] - }, - "Web/API/WebGLRenderingContext/uniformMatrix": { - "modified": "2020-10-15T22:00:22.272Z", - "contributors": [ - "kagurakana", - "hellorayza", - "neil3d" - ] - }, - "Web/API/WebGLRenderingContext/useProgram": { - "modified": "2020-10-15T22:00:11.435Z", - "contributors": [ - "kimmyLoveStudy" - ] - }, - "Web/API/WebGLRenderingContext/validateProgram": { - "modified": "2020-10-15T22:21:15.408Z", - "contributors": [ - "lovefengruoqing" - ] - }, - "Web/API/WebGLRenderingContext/vertexAttrib": { - "modified": "2020-10-15T22:00:37.377Z", - "contributors": [ - "qdlaoyao" - ] - }, - "Web/API/WebGLRenderingContext/vertexAttribPointer": { - "modified": "2020-10-15T22:11:59.630Z", - "contributors": [ - "hellorayza", - "Anichkov", - "shahho" - ] - }, - "Web/API/WebGLRenderingContext/viewport": { - "modified": "2020-10-15T21:55:12.327Z", - "contributors": [ - "shenwenkai" - ] - }, - "Web/API/WebGLRenderingContext/多边形偏移(polygonOffset)": { - "modified": "2020-10-15T22:09:39.645Z", - "contributors": [ - "ZhaoYaoSheng" - ] - }, - "Web/API/WebGLSampler": { - "modified": "2020-10-15T22:13:50.281Z", - "contributors": [ - "wymm0008" - ] - }, - "Web/API/WebGLShader": { - "modified": "2020-10-15T21:50:39.192Z", - "contributors": [ - "wymm0008", - "chuang85", - "carllx" - ] - }, - "Web/API/WebGLShaderPrecisionFormat": { - "modified": "2020-10-15T22:28:56.669Z", - "contributors": [ - "ithanmang" - ] - }, - "Web/API/WebGLSync": { - "modified": "2020-10-15T21:55:04.570Z", - "contributors": [ - "loverinfo" - ] - }, - "Web/API/WebGLTexture": { - "modified": "2020-10-15T22:03:31.496Z", - "contributors": [ - "PYGC", - "eduwc", - "anngg2008" - ] - }, - "Web/API/WebGLUniformLocation": { - "modified": "2019-03-23T22:24:45.064Z", - "contributors": [ - "BeastHan" - ] - }, - "Web/API/WebGLVertexArrayObject": { - "modified": "2020-10-15T22:03:32.816Z", - "contributors": [ - "wymm0008", - "konpoe", - "anngg2008" - ] - }, - "Web/API/WebGL_API": { - "modified": "2020-10-21T14:15:17.476Z", - "contributors": [ - "KaiserZh", - "Futrime", - "Yayure", - "wymm0008", - "RoXoM", - "yzweb2018", - "guzhongren", - "shenwenkai", - "wqQudian", - "xgqfrms-GitHub", - "lunix01", - "marsoln", - "wth", - "JoshuaLee", - "peterwang1996", - "xgqfrms", - "shawntsia", - "fscholz", - "MoYuLing", - "Zhining", - "teoli", - "RobberPhex", - "ethertank", - "KangKai", - "ziyunfei", - "bean" - ] - }, - "Web/API/WebGL_API/Basic_2D_animation_example": { - "modified": "2019-09-18T04:51:49.381Z", - "contributors": [ - "XYZ-99", - "wscodinglover", - "guooni", - "LeoLRH" - ] - }, - "Web/API/WebGL_API/By_example": { - "modified": "2019-03-23T22:07:31.638Z", - "contributors": [ - "chrisdavidmills", - "fsx950223", - "Zealxxxz", - "luneice" - ] - }, - "Web/API/WebGL_API/By_example/Basic_scissoring": { - "modified": "2019-03-18T21:34:11.506Z", - "contributors": [ - "chrisdavidmills", - "brickswong7" - ] - }, - "Web/API/WebGL_API/By_example/Boilerplate_1": { - "modified": "2019-03-18T21:28:26.120Z", - "contributors": [ - "chrisdavidmills", - "joydezhong" - ] - }, - "Web/API/WebGL_API/By_example/Canvas_size_and_WebGL": { - "modified": "2019-03-18T21:28:18.039Z", - "contributors": [ - "chrisdavidmills", - "joydezhong" - ] - }, - "Web/API/WebGL_API/By_example/Clearing_by_clicking": { - "modified": "2019-03-18T21:40:28.499Z", - "contributors": [ - "chrisdavidmills", - "fsx950223" - ] - }, - "Web/API/WebGL_API/By_example/Clearing_with_colors": { - "modified": "2019-03-18T21:43:21.601Z", - "contributors": [ - "chrisdavidmills", - "fsx950223", - "Zealxxxz" - ] - }, - "Web/API/WebGL_API/By_example/Color_masking": { - "modified": "2019-03-18T21:21:16.498Z", - "contributors": [ - "shahho" - ] - }, - "Web/API/WebGL_API/By_example/Detect_WebGL": { - "modified": "2019-03-23T22:05:37.595Z", - "contributors": [ - "chrisdavidmills", - "LinFengYnu" - ] - }, - "Web/API/WebGL_API/By_example/Hello_GLSL": { - "modified": "2019-03-18T21:37:28.441Z", - "contributors": [ - "chrisdavidmills", - "anngg2008" - ] - }, - "Web/API/WebGL_API/By_example/Scissor_animation": { - "modified": "2019-03-18T21:28:16.595Z", - "contributors": [ - "chrisdavidmills", - "joydezhong" - ] - }, - "Web/API/WebGL_API/By_example/Simple_color_animation": { - "modified": "2019-03-18T21:24:11.822Z", - "contributors": [ - "chrisdavidmills", - "YexChen" - ] - }, - "Web/API/WebGL_API/Constants": { - "modified": "2020-03-02T05:35:38.583Z", - "contributors": [ - "Pada", - "xuhbd", - "kongxiaojian123", - "TangYanXia", - "dondevi", - "BeastHan", - "charlie" - ] - }, - "Web/API/WebGL_API/Data": { - "modified": "2020-08-04T00:38:49.118Z", - "contributors": [ - "lifei-2019", - "Yue-plus", - "whyjld" - ] - }, - "Web/API/WebGL_API/Matrix_math_for_the_web": { - "modified": "2019-08-01T01:30:31.099Z", - "contributors": [ - "wbamberg", - "yokiyang", - "ShirleyM", - "ZhouQD", - "xgqfrms-GitHub", - "Jerry.M.WLong" - ] - }, - "Web/API/WebGL_API/Tutorial": { - "modified": "2020-05-14T05:38:04.380Z", - "contributors": [ - "wxyads", - "doodlewind", - "BeastHan", - "lunix01", - "JoshuaLee", - "zhe13", - "Will.Fan", - "fscholz" - ] - }, - "Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context": { - "modified": "2020-06-14T01:26:42.320Z", - "contributors": [ - "Futrime", - "li2go", - "aute", - "antiDestiny", - "gordon-lee", - "Kemper-Diao", - "kimmyLoveStudy", - "Sincoyw", - "fscholz", - "ziyunfei", - "yukai", - "Phaeton", - "Zhining" - ] - }, - "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL": { - "modified": "2020-05-18T11:01:31.337Z", - "contributors": [ - "Yayure", - "Sincoyw", - "ZhangMenghe" - ] - }, - "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL": { - "modified": "2020-05-20T11:16:19.138Z", - "contributors": [ - "Yayure", - "Tnze", - "chinaPrototypeBoy", - "Awe", - "liuzheng644607", - "Gaohaoyang" - ] - }, - "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL": { - "modified": "2019-03-18T21:14:57.654Z", - "contributors": [ - "Sincoyw" - ] - }, - "Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL": { - "modified": "2020-09-27T10:55:44.005Z", - "contributors": [ - "jingkaimori", - "Futrime", - "SphinxKnight", - "Kongwsh", - "tianxingqian", - "shangdibaozi", - "lovelyun", - "yangchengjian", - "eMe-404", - "Sincoyw", - "yola0316", - "JoshuaLee", - "fscholz", - "braveoyster", - "zhuzisheng", - "Zhining", - "teoli", - "RobberPhex", - "ziyunfei" - ] - }, - "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL": { - "modified": "2019-03-23T22:28:52.832Z", - "contributors": [ - "Sincoyw", - "Jerry.M.WLong" - ] - }, - "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL": { - "modified": "2019-08-04T13:30:09.829Z", - "contributors": [ - "Amarillys", - "Sincoyw", - "FuZhenn", - "ZhangMenghe" - ] - }, - "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL": { - "modified": "2019-03-23T22:29:22.461Z", - "contributors": [ - "amluck", - "Sincoyw" - ] - }, - "Web/API/WebGL_API/Types": { - "modified": "2019-03-23T22:34:13.965Z", - "contributors": [ - "luojia", - "charlie" - ] - }, - "Web/API/WebGL_API/Using_Extensions": { - "modified": "2019-03-23T22:34:03.533Z", - "contributors": [ - "breakair", - "xgqfrms-GitHub", - "charlie" - ] - }, - "Web/API/WebGL_API/WebGL_best_practices": { - "modified": "2020-10-14T00:00:10.949Z", - "contributors": [ - "zousongqi0213", - "makeco", - "zxh19890103", - "tianxingqian", - "xgqfrms-GitHub" - ] - }, - "Web/API/WebGL_API/WebGL_model_view_projection": { - "modified": "2020-02-12T07:12:53.456Z", - "contributors": [ - "Pada", - "wbamberg", - "xgqfrms-GitHub" - ] - }, - "Web/API/WebRTC_API": { - "modified": "2019-06-10T03:58:45.088Z", - "contributors": [ - "Tsui", - "SolitudeRA", - "SparrowLiu", - "ziyunfei" - ] - }, - "Web/API/WebRTC_API/Architecture": { - "modified": "2020-04-24T05:54:00.386Z", - "contributors": [ - "xgqfrms", - "ziyunfei", - "SparrowLiu" - ] - }, - "Web/API/WebRTC_API/Connectivity": { - "modified": "2020-07-13T03:42:02.521Z", - "contributors": [ - "crazymxm", - "OoOs1r1u5", - "Move" - ] - }, - "Web/API/WebRTC_API/Overview": { - "modified": "2019-03-23T22:45:00.042Z", - "contributors": [ - "Ling.kevin" - ] - }, - "Web/API/WebRTC_API/Protocols": { - "modified": "2020-04-24T06:06:42.725Z", - "contributors": [ - "xgqfrms", - "plter", - "warmilk", - "zslucky", - "Ling.kevin" - ] - }, - "Web/API/WebRTC_API/Signaling_and_video_calling": { - "modified": "2019-09-23T22:04:46.695Z", - "contributors": [ - "gaoyingie", - "Mangone", - "wh.D", - "fscholz", - "Chen-Sanjia" - ] - }, - "Web/API/WebRTC_API/Simple_RTCDataChannel_sample": { - "modified": "2019-03-23T22:13:47.101Z", - "contributors": [ - "fscholz", - "wbamberg", - "chen4w", - "bigfat", - "yxxgoogle" - ] - }, - "Web/API/WebRTC_API/Taking_still_photos": { - "modified": "2020-03-10T16:08:27.768Z", - "contributors": [ - "lxuewu", - "崮生", - "Move" - ] - }, - "Web/API/WebRTC_API/WebRTC_basics": { - "modified": "2019-09-24T02:45:56.457Z", - "contributors": [ - "lixl", - "huangcheng", - "SparrowLiu" - ] - }, - "Web/API/WebRTC_API/adapter.js": { - "modified": "2020-04-17T09:34:28.178Z", - "contributors": [ - "charliex2", - "physihan" - ] - }, - "Web/API/WebSocket": { - "modified": "2020-10-15T21:37:01.958Z", - "contributors": [ - "symant233", - "kdxcxs", - "mkckr0", - "xgqfrms", - "skylinebin", - "SphinxKnight", - "kevintrung", - "Channely", - "rguanghui", - "HJava", - "xiazhe", - "daibin91", - "luojia", - "xdhhbank", - "Ende93", - "changeeeeeeeeeeeeeeeeeeeeee", - "shhdgit", - "cissoid", - "homfen", - "linmx0130" - ] - }, - "Web/API/WebSocket/WebSocket": { - "modified": "2020-10-15T22:07:03.429Z", - "contributors": [ - "shugen002", - "LemonTree", - "kevintrung", - "wjp5826", - "wasdjkl", - "P-der" - ] - }, - "Web/API/WebSocket/bufferedAmount": { - "modified": "2020-10-15T22:14:27.041Z", - "contributors": [ - "xianghui-ma" - ] - }, - "Web/API/WebSocket/close": { - "modified": "2020-10-15T22:08:49.281Z", - "contributors": [ - "HiWeChat", - "xtreme", - "YuanGYao", - "FlyingPig", - "en20" - ] - }, - "Web/API/WebSocket/error_event": { - "modified": "2020-10-15T22:32:26.989Z", - "contributors": [ - "hellorayza", - "chengchaos", - "ZhaoxingZhang", - "echoechoin" - ] - }, - "Web/API/WebSocket/extensions": { - "modified": "2020-10-15T22:16:17.843Z", - "contributors": [ - "TeabugCC" - ] - }, - "Web/API/WebSocket/message_event": { - "modified": "2020-10-15T22:28:18.680Z", - "contributors": [ - "mmdjiji", - "Firefox_mozilla" - ] - }, - "Web/API/WebSocket/onclose": { - "modified": "2019-08-17T08:15:18.133Z", - "contributors": [ - "lihuakkk", - "FlyingPig" - ] - }, - "Web/API/WebSocket/onerror": { - "modified": "2020-10-15T22:12:36.891Z", - "contributors": [ - "sntkwtjf", - "Firefox_mozilla", - "HIKALU-Z" - ] - }, - "Web/API/WebSocket/onmessage": { - "modified": "2020-10-15T22:11:41.439Z", - "contributors": [ - "hishark", - "caslt", - "Ray-Eldath" - ] - }, - "Web/API/WebSocket/onopen": { - "modified": "2020-10-15T22:12:40.029Z", - "contributors": [ - "Mr.Chenzm", - "TeabugCC", - "suciy" - ] - }, - "Web/API/WebSocket/protocol": { - "modified": "2020-11-25T08:46:40.368Z", - "contributors": [ - "ZH-S", - "TeabugCC", - "plter" - ] - }, - "Web/API/WebSocket/readyState": { - "modified": "2020-12-03T07:13:50.811Z", - "contributors": [ - "yinyunsan", - "yoyo837", - "rguanghui" - ] - }, - "Web/API/WebSocket/send": { - "modified": "2020-10-15T22:11:41.819Z", - "contributors": [ - "yoyo837", - "zhangminggeek", - "ivila", - "Ray-Eldath" - ] - }, - "Web/API/WebSocket/url": { - "modified": "2020-10-15T22:12:37.210Z", - "contributors": [ - "TeabugCC", - "HIKALU-Z" - ] - }, - "Web/API/WebSocket/二进制类型": { - "modified": "2020-10-15T22:11:38.195Z", - "contributors": [ - "snowwolfjay", - "jaredhan418" - ] - }, - "Web/API/WebSockets_API": { - "modified": "2019-03-23T22:06:25.324Z", - "contributors": [ - "xiaoyixiang", - "RainSlide", - "wodewone", - "luojia" - ] - }, - "Web/API/WebSockets_API/WebSocket_Server_Vb.NET": { - "modified": "2019-03-18T21:29:02.340Z", - "contributors": [ - "xiaoyixiang" - ] - }, - "Web/API/WebSockets_API/Writing_WebSocket_client_applications": { - "modified": "2019-03-23T22:05:13.416Z", - "contributors": [ - "fscholz", - "xiaoyixiang", - "Bayes", - "bambooom", - "wubaodong", - "yydzxz", - "MegaThomas" - ] - }, - "Web/API/WebSockets_API/Writing_WebSocket_server": { - "modified": "2019-08-25T02:32:37.878Z", - "contributors": [ - "InJeCTrL", - "vaynewang", - "NutAcorn" - ] - }, - "Web/API/WebSockets_API/Writing_WebSocket_servers": { - "modified": "2020-05-19T10:49:49.144Z", - "contributors": [ - "haojiesss", - "mkckr0", - "xgqfrms", - "RainKolwa", - "xiaoyixiang", - "Kenenth", - "philwu", - "zyt", - "yuyx91", - "yydzxz" - ] - }, - "Web/API/WebSockets_API/Writing_a_WebSocket_server_in_Java": { - "modified": "2019-06-28T00:34:27.083Z", - "contributors": [ - "hgaong", - "yydzxz" - ] - }, - "Web/API/WebVR_API": { - "modified": "2019-03-23T22:32:52.319Z", - "contributors": [ - "warmilk", - "M.Yingshi", - "fscholz", - "SoAanyip", - "Mr-walter-wang", - "vtejuf", - "huzhihang" - ] - }, - "Web/API/WebVR_API/Concepts": { - "modified": "2019-03-23T22:32:15.145Z", - "contributors": [ - "chrisdavidmills", - "arthas-cui", - "Mr-walter-wang" - ] - }, - "Web/API/WebVR_API/Using_VR_controllers_with_WebVR": { - "modified": "2019-03-18T21:44:22.653Z", - "contributors": [ - "M.Yingshi" - ] - }, - "Web/API/WebVR_API/Using_the_WebVR_API": { - "modified": "2019-03-23T22:20:29.452Z", - "contributors": [ - "emanruoy", - "ajzeng" - ] - }, - "Web/API/WebVTT_API": { - "modified": "2020-10-15T22:19:15.221Z", - "contributors": [ - "853419196", - "sjpeter", - "RainSlide" - ] - }, - "Web/API/WebXR_Device_API": { - "modified": "2020-10-15T22:25:12.473Z", - "contributors": [ - "kmokidd", - "jingyu" - ] - }, - "Web/API/Web_Animations_API": { - "modified": "2019-03-23T22:25:28.986Z", - "contributors": [ - "yangzi", - "xgqfrms-GitHub", - "Taoja" - ] - }, - "Web/API/Web_Animations_API/Keyframe_Formats": { - "modified": "2019-03-18T21:29:50.687Z", - "contributors": [ - "Lim" - ] - }, - "Web/API/Web_Animations_API/Using_the_Web_Animations_API": { - "modified": "2019-03-23T22:10:37.938Z", - "contributors": [ - "old2sun", - "Hallz", - "dujun", - "leeseean" - ] - }, - "Web/API/Web_Audio_API": { - "modified": "2019-09-24T21:47:01.552Z", - "contributors": [ - "sfilata", - "oldmtn", - "CelestialPhineas", - "Mukti", - "maicss", - "Iamxiaozhu", - "Sincoyw", - "SHALLYKL", - "bobiscool", - "smilewalker", - "SoAanyip", - "z__", - "wwj", - "luojia", - "sunwulovelove1" - ] - }, - "Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API": { - "modified": "2019-03-23T22:34:33.356Z", - "contributors": [ - "akamos01", - "fanpaa", - "LiuTong" - ] - }, - "Web/API/Web_Audio_API/Using_Web_Audio_API": { - "modified": "2020-04-13T06:31:32.889Z", - "contributors": [ - "KotoriK", - "Pada", - "muyouruguo", - "yilinglulala", - "Helloooooooooo", - "smilewalker" - ] - }, - "Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API": { - "modified": "2019-03-23T23:03:57.834Z", - "contributors": [ - "luojia", - "LiuTong", - "timqian92", - "ziyunfei" - ] - }, - "Web/API/Web_Audio_API/Web_audio_spatialization_basics": { - "modified": "2019-04-25T14:55:16.639Z", - "contributors": [ - "Pada", - "budblack", - "smilewalker" - ] - }, - "Web/API/Web_Audio_API/最佳实践": { - "modified": "2020-04-13T06:14:13.545Z", - "contributors": [ - "KotoriK" - ] - }, - "Web/API/Web_Authentication_API": { - "modified": "2020-03-16T06:43:10.491Z", - "contributors": [ - "Axton", - "bingxl" - ] - }, - "Web/API/Web_Crypto_API": { - "modified": "2020-10-15T21:55:38.831Z", - "contributors": [ - "cissoid", - "LiangXingYong", - "auver", - "TooBug" - ] - }, - "Web/API/Web_Speech_API": { - "modified": "2020-10-15T21:52:01.054Z", - "contributors": [ - "windsting", - "zhangchen", - "changkun", - "rzYunjing", - "xgqfrms-GitHub" - ] - }, - "Web/API/Web_Speech_API/Using_the_Web_Speech_API": { - "modified": "2019-03-23T22:05:56.160Z", - "contributors": [ - "TTtuntuntutu" - ] - }, - "Web/API/Web_Storage_API": { - "modified": "2020-10-15T21:36:04.978Z", - "contributors": [ - "fzhyzamt", - "CaTmmao", - "CuriosityLxn", - "Dafrok", - "xgqfrms-GitHub", - "FideoJ", - "xgqfrms", - "y3093", - "WentaoMa", - "williamchu123", - "Naijing", - "HereChen", - "lijunchengbeyond", - "zhaofengli11", - "chrisdavidmills" - ] - }, - "Web/API/Web_Storage_API/Using_the_Web_Storage_API": { - "modified": "2020-10-15T21:35:52.205Z", - "contributors": [ - "RoXoM", - "DevOps", - "xiaomochen520", - "WentaoMa", - "AlexChao" - ] - }, - "Web/API/Web_Workers_API": { - "modified": "2020-03-10T11:03:26.387Z", - "contributors": [ - "zhangchen", - "hydRAnger", - "LiHwsqh", - "QIUFAN", - "madinsect", - "xgqfrms-GitHub", - "isLishude", - "usernameisMan", - "DoubleK2013", - "wendy_zcs", - "peterwang1996", - "forclan", - "wth", - "chrisdavidmills" - ] - }, - "Web/API/Web_Workers_API/Functions_and_classes_available_to_workers": { - "modified": "2020-07-13T06:02:56.731Z", - "contributors": [ - "sunstaotao", - "Syclover-u2400", - "DoubleK2013", - "xgqfrms-GitHub" - ] - }, - "Web/API/Web_Workers_API/Using_web_workers": { - "modified": "2020-11-19T06:15:36.517Z", - "contributors": [ - "TheFirstSunday", - "lisiur", - "WindrunnerMax", - "Ende93", - "zhangchen", - "qq240814476", - "stonehuang", - "SphinxKnight", - "zhongzi", - "ramseyfeng", - "YehaiChen", - "lhywell", - "xgqfrms-GitHub", - "Qcui", - "Jessy.D.", - "ziyunfei", - "fscholz", - "siberiawolf0307", - "sunnylost", - "xcffl" - ] - }, - "Web/API/WheelEvent": { - "modified": "2020-10-15T21:19:51.116Z", - "contributors": [ - "Carllllo", - "Zhang-Junzhi", - "mahuan2", - "teoli", - "ziyunfei" - ] - }, - "Web/API/WheelEvent/deltaMode": { - "modified": "2019-03-18T21:43:31.616Z", - "contributors": [ - "Jiang-Xuan" - ] - }, - "Web/API/WheelEvent/deltaX": { - "modified": "2019-03-18T21:43:31.426Z", - "contributors": [ - "Jiang-Xuan" - ] - }, - "Web/API/WheelEvent/deltaY": { - "modified": "2019-03-18T21:43:18.794Z", - "contributors": [ - "Jiang-Xuan" - ] - }, - "Web/API/WheelEvent/deltaZ": { - "modified": "2019-03-18T21:43:28.360Z", - "contributors": [ - "Jiang-Xuan" - ] - }, - "Web/API/Window": { - "modified": "2020-11-16T00:18:58.730Z", - "contributors": [ - "hellorayza", - "RainSlide", - "chrisdavidmills", - "locknono", - "_sollrei", - "RyougiChan", - "Alex.Wang", - "sartrey", - "teoli", - "khalid32", - "ReyCG_sub", - "ziyunfei", - "TigerSoldier", - "Linuxyun", - "JarodWang", - "Langdom" - ] - }, - "Web/API/Window/URL": { - "modified": "2019-03-23T22:22:37.359Z", - "contributors": [ - "xgqfrms-GitHub", - "Boring" - ] - }, - "Web/API/Window/Window.blur()": { - "modified": "2019-03-23T22:13:16.814Z", - "contributors": [ - "Toxni" - ] - }, - "Web/API/Window/alert": { - "modified": "2019-03-30T09:23:53.924Z", - "contributors": [ - "Pedestrian93", - "xgqfrms-GitHub", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/applicationCache": { - "modified": "2019-03-23T23:31:44.274Z", - "contributors": [ - "xgqfrms-GitHub", - "inJs", - "teoli", - "ziyunfei", - "sunnylost" - ] - }, - "Web/API/Window/back": { - "modified": "2019-03-23T22:12:59.387Z", - "contributors": [ - "xilixinluo" - ] - }, - "Web/API/Window/blur_event": { - "modified": "2020-10-15T22:18:42.062Z", - "contributors": [ - "zhangchen", - "mozzix" - ] - }, - "Web/API/Window/cancelAnimationFrame": { - "modified": "2019-03-23T23:39:18.899Z", - "contributors": [ - "teoli", - "insideyiqi", - "ziyunfei" - ] - }, - "Web/API/Window/cancelIdleCallback": { - "modified": "2019-03-23T22:04:56.080Z", - "contributors": [ - "Awe" - ] - }, - "Web/API/Window/clearImmediate": { - "modified": "2019-03-23T23:32:55.452Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei", - "movinghorse" - ] - }, - "Web/API/Window/clearInterval": { - "modified": "2020-10-15T21:21:33.193Z", - "contributors": [ - "RainCruise", - "RainSlide", - "luojia", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/close": { - "modified": "2020-10-15T21:06:33.538Z", - "contributors": [ - "RainSlide", - "SphinxKnight", - "tiansh", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/closed": { - "modified": "2019-03-18T20:58:50.844Z", - "contributors": [ - "SphinxKnight", - "dadaboar", - "dujun", - "Qcui" - ] - }, - "Web/API/Window/confirm": { - "modified": "2019-03-23T22:18:25.335Z", - "contributors": [ - "xgqfrms-GitHub", - "maicss" - ] - }, - "Web/API/Window/console": { - "modified": "2019-03-23T22:25:36.373Z", - "contributors": [ - "dujun", - "seajean", - "WwupengP" - ] - }, - "Web/API/Window/content": { - "modified": "2019-10-10T16:55:47.838Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/controllers": { - "modified": "2020-09-19T14:18:22.315Z", - "contributors": [ - "RainSlide", - "zhongrui97", - "ShaojieLiu", - "FEhaoxinjie" - ] - }, - "Web/API/Window/copy_event": { - "modified": "2020-10-15T22:30:15.212Z", - "contributors": [ - "Jee" - ] - }, - "Web/API/Window/crypto": { - "modified": "2019-03-23T22:22:09.825Z", - "contributors": [ - "koaqiu", - "Taoja" - ] - }, - "Web/API/Window/customElements": { - "modified": "2020-10-15T22:02:36.021Z", - "contributors": [ - "RainSlide", - "shhider", - "bluetomlee", - "lltemplar", - "Mmzer" - ] - }, - "Web/API/Window/defaultStatus": { - "modified": "2019-03-23T22:02:52.798Z", - "contributors": [ - "zhouinfo", - "webber007" - ] - }, - "Web/API/Window/devicePixelRatio": { - "modified": "2020-10-15T21:44:13.198Z", - "contributors": [ - "wallena3", - "Jic1993", - "zhanghbin", - "blue0125", - "Jiang-Xuan" - ] - }, - "Web/API/Window/deviceorientation_event": { - "modified": "2019-04-11T18:37:50.677Z", - "contributors": [ - "estelle", - "fscholz", - "laobubu" - ] - }, - "Web/API/Window/dialogArguments": { - "modified": "2019-03-23T22:13:58.259Z", - "contributors": [ - "koaqiu", - "ChrisChan" - ] - }, - "Web/API/Window/directories": { - "modified": "2019-03-18T21:41:58.715Z", - "contributors": [ - "LoadChange" - ] - }, - "Web/API/Window/document": { - "modified": "2020-10-15T21:21:32.735Z", - "contributors": [ - "jingkaimori", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/dump": { - "modified": "2019-03-23T22:07:13.628Z", - "contributors": [ - "Ende93", - "baiweichen" - ] - }, - "Web/API/Window/error_event": { - "modified": "2020-10-15T22:20:31.894Z", - "contributors": [ - "JojoWangOk" - ] - }, - "Web/API/Window/event": { - "modified": "2019-07-22T23:20:15.504Z", - "contributors": [ - "lichao", - "Mr.ma", - "Aaron_Zhung" - ] - }, - "Web/API/Window/external": { - "modified": "2020-10-15T22:13:52.002Z", - "contributors": [ - "RainSlide", - "EqualMa" - ] - }, - "Web/API/Window/find": { - "modified": "2019-03-23T23:39:40.804Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Window/focus": { - "modified": "2019-03-23T22:04:06.274Z", - "contributors": [ - "jaiJia" - ] - }, - "Web/API/Window/focus_event": { - "modified": "2020-10-15T22:30:08.102Z", - "contributors": [ - "Jee" - ] - }, - "Web/API/Window/frameElement": { - "modified": "2019-03-23T23:39:43.510Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Window/frames": { - "modified": "2019-07-17T07:11:01.232Z", - "contributors": [ - "NoroHime", - "SongXin-Controller", - "FredWe" - ] - }, - "Web/API/Window/fullScreen": { - "modified": "2019-03-23T22:45:03.600Z", - "contributors": [ - "lovue", - "Chimen" - ] - }, - "Web/API/Window/gamepadconnected_event": { - "modified": "2020-04-16T06:50:14.920Z", - "contributors": [ - "weiwentao518", - "irenesmith", - "fscholz", - "libin2866" - ] - }, - "Web/API/Window/getAttention": { - "modified": "2020-10-15T22:21:28.407Z", - "contributors": [ - "luoxue-victor" - ] - }, - "Web/API/Window/getComputedStyle": { - "modified": "2020-10-15T21:29:18.864Z", - "contributors": [ - "Bayes", - "zhangchen", - "xgqfrms-GitHub", - "gaoxuerong", - "Ende93", - "tudewutong", - "fannie-z", - "teoli", - "TwoYou", - "RobinXiong", - "arcy" - ] - }, - "Web/API/Window/getDefaultComputedStyle": { - "modified": "2019-03-18T20:36:51.313Z", - "contributors": [ - "teoli", - "xgqfrms-GitHub", - "ektx" - ] - }, - "Web/API/Window/getSelection": { - "modified": "2020-10-15T21:28:34.122Z", - "contributors": [ - "sytclh", - "MCCF", - "isLishude", - "zhicongyang", - "xgqfrms-GitHub", - "teoli", - "AlexChao", - "AshfaqHossain", - "Losses" - ] - }, - "Web/API/Window/hashchange_event": { - "modified": "2020-10-15T21:21:34.268Z", - "contributors": [ - "Carllllo", - "fscholz", - "xgqfrms-GitHub", - "ziyunfei", - "monjer" - ] - }, - "Web/API/Window/history": { - "modified": "2019-09-19T09:48:51.675Z", - "contributors": [ - "SphinxKnight", - "joodo", - "teoli", - "khalid32", - "monjer" - ] - }, - "Web/API/Window/innerHeight": { - "modified": "2019-03-18T20:46:35.962Z", - "contributors": [ - "WangLeto", - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/innerWidth": { - "modified": "2020-10-15T22:30:06.986Z", - "contributors": [ - "Jee" - ] - }, - "Web/API/Window/isSecureContext": { - "modified": "2019-03-23T22:07:53.475Z", - "contributors": [ - "FEhaoxinjie" - ] - }, - "Web/API/Window/languagechange_event": { - "modified": "2019-04-02T08:34:33.657Z", - "contributors": [ - "fscholz", - "xgqfrms-GitHub" - ] - }, - "Web/API/Window/length": { - "modified": "2019-03-23T23:33:15.311Z", - "contributors": [ - "teoli", - "basemnassar11", - "ziyunfei" - ] - }, - "Web/API/Window/localStorage": { - "modified": "2020-10-15T21:35:58.686Z", - "contributors": [ - "fuzhongfeng", - "night-full-moon", - "zstiu", - "zhangxk", - "xgqfrms", - "RainSlide", - "ldc-37", - "jjc", - "mySoul", - "nodebq", - "loicaplay", - "kameii", - "Marcia_gm", - "AlexChao" - ] - }, - "Web/API/Window/location": { - "modified": "2020-10-15T21:22:02.219Z", - "contributors": [ - "mySoul", - "xgqfrms-GitHub", - "Conan06", - "Ende93", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Window/locationbar": { - "modified": "2019-03-23T22:08:02.467Z", - "contributors": [ - "FEhaoxinjie" - ] - }, - "Web/API/Window/matchMedia": { - "modified": "2020-10-15T21:27:47.807Z", - "contributors": [ - "wallena3", - "teoli", - "focus", - "ziyunfei" - ] - }, - "Web/API/Window/menubar": { - "modified": "2019-03-23T22:07:59.661Z", - "contributors": [ - "Bayes", - "FEhaoxinjie" - ] - }, - "Web/API/Window/minimize": { - "modified": "2019-01-16T17:02:20.467Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/Window/moveBy": { - "modified": "2019-03-23T23:10:30.097Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/moveTo": { - "modified": "2020-09-11T06:03:40.111Z", - "contributors": [ - "Crazycheng", - "teoli", - "AshfaqHossain", - "AlexChao", - "ziyunfei" - ] - }, - "Web/API/Window/mozAnimationStartTIme": { - "modified": "2019-03-23T23:39:18.582Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/mozInnerScreenX": { - "modified": "2019-03-23T22:07:48.096Z", - "contributors": [ - "FEhaoxinjie" - ] - }, - "Web/API/Window/mozInnerScreenY": { - "modified": "2019-03-23T22:08:00.425Z", - "contributors": [ - "FEhaoxinjie" - ] - }, - "Web/API/Window/mozPaintCount": { - "modified": "2019-03-23T22:35:06.349Z", - "contributors": [ - "Qcui" - ] - }, - "Web/API/Window/name": { - "modified": "2020-10-15T21:29:36.392Z", - "contributors": [ - "RainSlide", - "HermitSun", - "microJ", - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/navigator": { - "modified": "2020-10-15T21:06:59.227Z", - "contributors": [ - "RainSlide", - "fscholz", - "zhanghbin", - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Window/offline_event": { - "modified": "2019-04-18T11:21:46.570Z", - "contributors": [ - "irenesmith", - "hhxxhg", - "fscholz", - "charlie" - ] - }, - "Web/API/Window/onappinstalled": { - "modified": "2019-03-18T21:40:44.436Z", - "contributors": [ - "Aaron_Zhung", - "echoArray" - ] - }, - "Web/API/Window/onbeforeinstallprompt": { - "modified": "2019-03-23T22:11:25.289Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/Window/onbeforeunload": { - "modified": "2019-05-09T03:05:32.709Z", - "contributors": [ - "johnlin0207", - "Etoile984816138", - "1Cr18Ni9", - "teoli", - "khalid32", - "ziyunfei", - "WenbingZheng" - ] - }, - "Web/API/Window/ondevicelight": { - "modified": "2019-03-18T21:46:43.834Z", - "contributors": [ - "Tiny12138" - ] - }, - "Web/API/Window/ondevicemotion": { - "modified": "2019-03-18T21:39:10.384Z", - "contributors": [ - "pinpinye", - "Mmzer" - ] - }, - "Web/API/Window/ondeviceorientation": { - "modified": "2019-03-18T21:38:06.143Z", - "contributors": [ - "Aaron_Zhung" - ] - }, - "Web/API/Window/ondeviceorientationabsolute": { - "modified": "2020-10-15T22:09:12.548Z", - "contributors": [ - "webber007" - ] - }, - "Web/API/Window/ondeviceproximity": { - "modified": "2019-03-18T21:36:54.017Z", - "contributors": [ - "eiddie" - ] - }, - "Web/API/Window/ondragdrop": { - "modified": "2020-06-28T00:52:25.247Z", - "contributors": [ - "PengyaoZhang" - ] - }, - "Web/API/Window/ongamepadconnected": { - "modified": "2020-10-15T22:22:28.465Z", - "contributors": [ - "VoidRain" - ] - }, - "Web/API/Window/ongamepaddisconnected": { - "modified": "2020-10-15T22:23:08.406Z", - "contributors": [ - "AWhiteMouse" - ] - }, - "Web/API/Window/onhashchange": { - "modified": "2020-10-15T21:06:52.013Z", - "contributors": [ - "Arnie97", - "xgqfrms-GitHub", - "Ende93", - "vuji", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/online_event": { - "modified": "2019-04-18T11:22:47.220Z", - "contributors": [ - "irenesmith", - "hhxxhg", - "fscholz", - "getfile" - ] - }, - "Web/API/Window/onmouseup": { - "modified": "2019-03-24T00:16:16.641Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/onmozbeforepaint": { - "modified": "2019-03-18T21:35:53.123Z", - "contributors": [ - "plightfield" - ] - }, - "Web/API/Window/onpaint": { - "modified": "2019-03-23T22:06:38.393Z", - "contributors": [ - "JARROWXU" - ] - }, - "Web/API/Window/onpopstate": { - "modified": "2020-10-15T21:07:15.381Z", - "contributors": [ - "SUCHMOKUO", - "wuyou", - "ReedSun", - "wenshin", - "xiaomingming", - "vose2008", - "teoli", - "Hasilt", - "ziyunfei" - ] - }, - "Web/API/Window/onscroll": { - "modified": "2019-03-24T00:15:58.211Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/onunload": { - "modified": "2020-10-23T06:31:44.836Z", - "contributors": [ - "liguorain", - "lon", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Window/onuserproximity": { - "modified": "2020-10-15T22:25:33.168Z", - "contributors": [ - "xAmast" - ] - }, - "Web/API/Window/open": { - "modified": "2019-10-15T12:07:15.007Z", - "contributors": [ - "RainSlide", - "Eriice", - "PythonVsJava", - "mySoul", - "SphinxKnight", - "xgqfrms-GitHub", - "jigs12", - "tiansh", - "helloguangxue", - "teoli", - "khalid32", - "Ghostheaven", - "GT", - "Mgjbot", - "Mickeyboy" - ] - }, - "Web/API/Window/openDialog": { - "modified": "2019-03-23T23:44:59.136Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei", - "Mickeyboy" - ] - }, - "Web/API/Window/opener": { - "modified": "2020-10-15T21:06:35.488Z", - "contributors": [ - "woshiqiang1", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/orientationchange_event": { - "modified": "2020-10-15T22:00:40.756Z", - "contributors": [ - "Carllllo", - "fscholz", - "zxsunrise", - "Jijmin" - ] - }, - "Web/API/Window/outerHeight": { - "modified": "2019-07-20T05:24:24.610Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/outerWidth": { - "modified": "2019-03-23T23:10:28.668Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/pageXOffset": { - "modified": "2019-03-23T22:24:38.179Z", - "contributors": [ - "Ende93" - ] - }, - "Web/API/Window/pageYOffset": { - "modified": "2019-08-28T13:19:48.429Z", - "contributors": [ - "Bayes", - "Ende93" - ] - }, - "Web/API/Window/pagehide_event": { - "modified": "2020-11-12T00:42:52.516Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/API/Window/parent": { - "modified": "2019-03-24T00:16:12.247Z", - "contributors": [ - "givebest", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/performance": { - "modified": "2019-08-22T06:18:57.970Z", - "contributors": [ - "vebuqi", - "xgqfrms-GitHub", - "AceMood" - ] - }, - "Web/API/Window/personalbar": { - "modified": "2019-03-18T21:37:01.272Z", - "contributors": [ - "aushy" - ] - }, - "Web/API/Window/popstate_event": { - "modified": "2020-05-14T02:46:36.204Z", - "contributors": [ - "igblee", - "chrisdavidmills", - "acelibin", - "irenesmith", - "mengxiaoixao", - "fscholz", - "xgqfrms-GitHub", - "HuarenYu", - "saviroyu", - "monjer", - "ziyunfei" - ] - }, - "Web/API/Window/postMessage": { - "modified": "2020-10-15T21:22:50.474Z", - "contributors": [ - "zhouzhongyuan", - "mokunshao", - "kiinlam", - "xgl", - "KingJch", - "hugg95", - "gitnewer", - "lltemplar", - "DarrenMan", - "asnowwolf", - "AllanJian", - "yuanhang", - "Dafrok", - "xgqfrms-GitHub", - "Hedgehog", - "Hearmen", - "lon", - "Newper", - "Ende93", - "nabice", - "WarriorWu", - "MoltBoy", - "teoli", - "khalid32", - "ziyunfei", - "Himno" - ] - }, - "Web/API/Window/print": { - "modified": "2019-03-24T00:16:06.807Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Window/prompt": { - "modified": "2019-03-24T00:15:16.672Z", - "contributors": [ - "guoyi", - "jjc", - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/rejectionhandled_event": { - "modified": "2020-10-15T22:26:00.037Z", - "contributors": [ - "mengli404" - ] - }, - "Web/API/Window/requestAnimationFrame": { - "modified": "2020-10-15T23:30:32.456Z", - "contributors": [ - "wudexiang", - "ruiyang0012", - "oxyg3n", - "Yifang-Tongxing", - "hawtim", - "xianghui-ma", - "zhuangyin", - "LiaoNa", - "luoway", - "liuliangsir", - "tangj1206", - "PaperFlu", - "RayJune", - "King.", - "xgqfrms-GitHub", - "aki", - "chinaliyun", - "teoli", - "warmhug", - "ziyunfei", - "MiyagiRyota" - ] - }, - "Web/API/Window/requestFileSystem": { - "modified": "2020-10-15T22:21:45.553Z", - "contributors": [ - "meiseayoung" - ] - }, - "Web/API/Window/requestIdleCallback": { - "modified": "2020-10-15T21:50:24.832Z", - "contributors": [ - "Junezm", - "zhangchen", - "xgqfrms", - "xlaoyu", - "ZSI2017", - "dinger", - "samuel1112", - "yiyizym", - "hepeguo" - ] - }, - "Web/API/Window/resizeBy": { - "modified": "2019-12-05T06:11:55.089Z", - "contributors": [ - "wudada", - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/resizeTo": { - "modified": "2019-09-07T03:28:03.924Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/resize_event": { - "modified": "2019-04-26T09:49:39.294Z", - "contributors": [ - "chrisdavidmills", - "irenesmith", - "Fangfeidenimen", - "fscholz", - "VictorDu", - "leehomeok", - "zhangqiong" - ] - }, - "Web/API/Window/restore": { - "modified": "2020-10-15T22:06:41.722Z", - "contributors": [ - "Bayes" - ] - }, - "Web/API/Window/screen": { - "modified": "2019-03-18T21:16:53.760Z", - "contributors": [ - "webber007", - "koalaxiaot", - "wushuyi" - ] - }, - "Web/API/Window/screenLeft": { - "modified": "2020-10-15T22:16:03.484Z", - "contributors": [ - "244462375", - "chenqingyue" - ] - }, - "Web/API/Window/screenTop": { - "modified": "2020-10-15T22:16:54.491Z", - "contributors": [ - "chenqingyue" - ] - }, - "Web/API/Window/screenX": { - "modified": "2019-03-23T23:10:28.531Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/screenY": { - "modified": "2019-03-23T23:10:27.250Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/scroll": { - "modified": "2019-10-14T05:51:07.033Z", - "contributors": [ - "imbant", - "kidonng", - "lovue", - "Chimen" - ] - }, - "Web/API/Window/scrollBy": { - "modified": "2019-09-17T22:22:22.410Z", - "contributors": [ - "yukinotech", - "Veneno", - "Bayes", - "lovue" - ] - }, - "Web/API/Window/scrollByLines": { - "modified": "2019-03-23T22:06:37.667Z", - "contributors": [ - "wangchenxunum", - "HAAAAADION" - ] - }, - "Web/API/Window/scrollByPages": { - "modified": "2019-03-26T06:12:18.633Z", - "contributors": [ - "LilyWakana", - "teoli", - "Hasilt", - "ziyunfei" - ] - }, - "Web/API/Window/scrollMaxX": { - "modified": "2020-10-15T22:22:14.462Z", - "contributors": [ - "sriting" - ] - }, - "Web/API/Window/scrollMaxY": { - "modified": "2020-10-15T22:28:25.211Z", - "contributors": [ - "johnao" - ] - }, - "Web/API/Window/scrollTo": { - "modified": "2020-10-15T21:37:24.186Z", - "contributors": [ - "iugo", - "wp56610", - "lovue", - "zmy", - "hephecqq" - ] - }, - "Web/API/Window/scrollX": { - "modified": "2019-03-23T23:10:28.781Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/scrollY": { - "modified": "2019-08-28T13:20:03.423Z", - "contributors": [ - "Ende93", - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/scrollbars": { - "modified": "2019-03-23T22:05:14.848Z", - "contributors": [ - "fangyulovechina", - "Bayes", - "xumqfaith", - "leo19920823" - ] - }, - "Web/API/Window/self": { - "modified": "2019-03-23T23:10:29.785Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/API/Window/sessionStorage": { - "modified": "2020-10-15T21:36:07.771Z", - "contributors": [ - "imbriansun", - "fzhyzamt", - "woshiqiang1", - "viRingbells", - "xgqfrms", - "XuQuan-nikkkki", - "CuriosityLxn", - "kameii", - "Ende93", - "AlexChao" - ] - }, - "Web/API/Window/setCursor": { - "modified": "2019-03-23T22:06:17.696Z", - "contributors": [ - "tsilone" - ] - }, - "Web/API/Window/setImmediate": { - "modified": "2020-10-15T21:07:15.089Z", - "contributors": [ - "zhangchen", - "ZZES_REN", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Window/setInterval": { - "modified": "2020-11-25T18:16:55.949Z", - "contributors": [ - "RayTang-hub", - "cellinlab", - "Jiangmenghao", - "TXYjing", - "Soul", - "fengbin", - "RainSlide", - "brandonhyc", - "xgqfrms-GitHub", - "shery", - "xgqfrms", - "teoli", - "khalid32", - "ziyunfei", - "sonicview" - ] - }, - "Web/API/Window/setTimeout": { - "modified": "2020-10-15T21:19:52.746Z", - "contributors": [ - "SnowGojira", - "iyow", - "johnao", - "chrisdavidmills", - "csga31971", - "baijingfeng", - "Reci-z", - "horrylala", - "Adashuai5", - "LilyWakana", - "Mars687", - "pinpinye", - "Lby876176278", - "Chancefeng", - "fscholz", - "xiazhe", - "Frorice", - "yhtml5", - "righttoe", - "Toxni", - "piemonSong", - "xgqfrms-GitHub", - "heke2929", - "SnowOnion", - "Chimen", - "hbkdsm", - "paddingme", - "teoli", - "khalid32", - "Meteormatt", - "ziyunfei" - ] - }, - "Web/API/Window/showModalDialog": { - "modified": "2019-07-21T23:38:59.262Z", - "contributors": [ - "fanyue", - "SphinxKnight", - "teoli", - "ziyunfei", - "c_king" - ] - }, - "Web/API/Window/sidebar": { - "modified": "2019-03-23T23:03:07.222Z", - "contributors": [ - "ziyunfei", - "felix_wang" - ] - }, - "Web/API/Window/sizeToContent": { - "modified": "2020-10-15T22:09:35.483Z", - "contributors": [ - "usernameisMan" - ] - }, - "Web/API/Window/stop": { - "modified": "2020-10-15T21:53:11.557Z", - "contributors": [ - "RainSlide", - "hughfenghen", - "esc", - "dujun" - ] - }, - "Web/API/Window/storage_event": { - "modified": "2019-04-26T08:47:49.360Z", - "contributors": [ - "chrisdavidmills", - "irenesmith", - "manggo", - "lishizhi", - "fscholz", - "cheiron" - ] - }, - "Web/API/Window/top": { - "modified": "2020-10-15T21:25:02.128Z", - "contributors": [ - "fordream001", - "teoli", - "AlexChao", - "Josephok" - ] - }, - "Web/API/Window/updateCommands": { - "modified": "2020-10-15T22:09:40.955Z", - "contributors": [ - "usernameisMan" - ] - }, - "Web/API/Window/visualViewport": { - "modified": "2019-03-18T21:36:53.168Z", - "contributors": [ - "eiddie" - ] - }, - "Web/API/Window/window": { - "modified": "2019-06-03T06:03:48.881Z", - "contributors": [ - "lewayjack", - "lovue" - ] - }, - "Web/API/WindowBase64/Base64_encoding_and_decoding": { - "modified": "2020-09-03T07:22:36.242Z", - "contributors": [ - "WangXBruc", - "waitingsong", - "RainSlide", - "luojia", - "fghpdf", - "ahcheqiu" - ] - }, - "Web/API/WindowBase64/atob": { - "modified": "2020-10-15T21:07:00.713Z", - "contributors": [ - "RainSlide", - "zhangchen", - "nkliyc", - "dingyanhe", - "xgqfrms-GitHub", - "ziyunfei", - "happyWang", - "teoli", - "khalid32" - ] - }, - "Web/API/WindowBase64/btoa": { - "modified": "2020-10-15T21:06:58.236Z", - "contributors": [ - "RainSlide", - "zhangchen", - "RoXoM", - "Carrotzpc", - "dingyanhe", - "xgqfrms-GitHub", - "ziyunfei", - "teoli", - "khalid32", - "cuixiping" - ] - }, - "Web/API/WindowClient": { - "modified": "2019-03-23T22:11:45.641Z", - "contributors": [ - "chrisdavidmills" - ] - }, - "Web/API/WindowClient/navigate": { - "modified": "2019-03-23T22:11:36.969Z", - "contributors": [ - "xrr2016" - ] - }, - "Web/API/WindowEventHandlers": { - "modified": "2019-03-27T10:53:28.796Z", - "contributors": [ - "fanerge", - "fscholz" - ] - }, - "Web/API/WindowEventHandlers/onafterprint": { - "modified": "2019-09-27T06:08:53.846Z", - "contributors": [ - "cwc", - "shockw4ver" - ] - }, - "Web/API/WindowEventHandlers/onbeforeprint": { - "modified": "2020-10-15T22:30:28.485Z", - "contributors": [ - "wuyouhuaz" - ] - }, - "Web/API/WindowEventHandlers/onlanguagechange": { - "modified": "2019-03-23T22:16:38.614Z", - "contributors": [ - "micblo" - ] - }, - "Web/API/WindowEventHandlers/onmessage": { - "modified": "2019-03-18T21:42:57.236Z", - "contributors": [ - "singi2016cn" - ] - }, - "Web/API/WindowEventHandlers/onmessageerror": { - "modified": "2019-03-18T21:36:58.502Z", - "contributors": [ - "eiddie" - ] - }, - "Web/API/WindowEventHandlers/onstorage": { - "modified": "2020-01-09T03:11:34.593Z", - "contributors": [ - "Yangfan", - "lynnic26" - ] - }, - "Web/API/WindowOrWorkerGlobalScope": { - "modified": "2019-09-06T05:03:39.492Z", - "contributors": [ - "TiaossuP", - "chrisdavidmills" - ] - }, - "Web/API/WindowOrWorkerGlobalScope/caches": { - "modified": "2019-09-21T03:33:16.440Z", - "contributors": [ - "JarvanMo" - ] - }, - "Web/API/WindowOrWorkerGlobalScope/createImageBitmap": { - "modified": "2019-03-18T20:44:01.174Z", - "contributors": [ - "fanerge", - "varcat" - ] - }, - "Web/API/WindowOrWorkerGlobalScope/crossOriginIsolated": { - "modified": "2020-10-15T22:26:03.129Z", - "contributors": [ - "Fulgrim" - ] - }, - "Web/API/WindowOrWorkerGlobalScope/fetch": { - "modified": "2020-10-15T21:38:47.827Z", - "contributors": [ - "hughfenghen", - "jingkaimori", - "c1er", - "ldc-37", - "Rhys_211", - "zhangchen", - "fscholz", - "TiaossuP", - "Yanzengyong", - "wxs77577", - "Ende93", - "xuzhijun", - "ziyunfei", - "camsong", - "fuchao2012" - ] - }, - "Web/API/WindowOrWorkerGlobalScope/indexedDB": { - "modified": "2019-09-21T03:34:03.050Z", - "contributors": [ - "FEhaoxinjie" - ] - }, - "Web/API/WindowOrWorkerGlobalScope/isSecureContext": { - "modified": "2019-09-21T03:37:23.951Z", - "contributors": [ - "Awe" - ] - }, - "Web/API/WindowOrWorkerGlobalScope/origin": { - "modified": "2019-03-23T22:03:28.077Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/WindowOrWorkerGlobalScope/queueMicrotask": { - "modified": "2020-10-15T22:23:11.878Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/API/WindowTimers/clearTimeout": { - "modified": "2020-06-09T04:49:33.480Z", - "contributors": [ - "Humilitas", - "zhangchen", - "luojia", - "paddingme" - ] - }, - "Web/API/Worker": { - "modified": "2020-10-15T21:22:11.206Z", - "contributors": [ - "liguorain", - "zsirfs", - "LeoSpark", - "Syclover-u2400", - "hl4a", - "xuxun", - "Jiang-Xuan", - "xgqfrms-GitHub", - "Alphmega", - "khalid32", - "ziyunfei", - "sunnylost" - ] - }, - "Web/API/Worker/Worker": { - "modified": "2020-10-15T21:40:42.692Z", - "contributors": [ - "hex-puck", - "foomow", - "bbaa-bbaa", - "C_Kite", - "Syclover-u2400", - "xgqfrms-GitHub", - "liuzeyafzy", - "Alphmega" - ] - }, - "Web/API/Worker/message_event": { - "modified": "2020-10-15T22:22:03.834Z", - "contributors": [ - "LittleIQ" - ] - }, - "Web/API/Worker/messageerror_event": { - "modified": "2020-10-15T22:22:03.822Z", - "contributors": [ - "LittleIQ" - ] - }, - "Web/API/Worker/onmessage": { - "modified": "2020-11-04T10:01:25.018Z", - "contributors": [ - "szdytom", - "Syclover-u2400", - "spatio" - ] - }, - "Web/API/Worker/onmessageerror": { - "modified": "2020-10-15T22:08:23.141Z", - "contributors": [ - "Syclover-u2400", - "hl4a", - "xiaoweb" - ] - }, - "Web/API/Worker/postMessage": { - "modified": "2019-03-23T22:18:22.780Z", - "contributors": [ - "ceido", - "xgqfrms-GitHub" - ] - }, - "Web/API/Worker/terminate": { - "modified": "2019-03-18T21:45:26.915Z", - "contributors": [ - "umbrella_coder", - "kamilic" - ] - }, - "Web/API/WorkerGlobalScope": { - "modified": "2019-04-27T23:16:37.252Z", - "contributors": [ - "zxxzzzzz", - "AFBarstow" - ] - }, - "Web/API/WorkerGlobalScope/importScripts": { - "modified": "2020-10-15T21:49:31.141Z", - "contributors": [ - "RainSlide", - "xgqfrms-GitHub", - "fghpdf" - ] - }, - "Web/API/WorkerGlobalScope/self": { - "modified": "2020-10-15T22:08:49.410Z", - "contributors": [ - "librajt" - ] - }, - "Web/API/XDomainRequest": { - "modified": "2019-03-23T23:03:13.932Z", - "contributors": [ - "biqing", - "cungen" - ] - }, - "Web/API/XMLDocument": { - "modified": "2020-10-15T21:15:38.976Z", - "contributors": [ - "RainSlide", - "mySoul", - "teoli", - "ziyunfei", - "Xiaomin98" - ] - }, - "Web/API/XMLDocument/async": { - "modified": "2019-04-24T21:14:27.334Z", - "contributors": [ - "ExE-Boss", - "teoli", - "ziyunfei" - ] - }, - "Web/API/XMLDocument/load": { - "modified": "2019-03-24T00:15:45.480Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/XMLHttpRequest": { - "modified": "2020-10-15T21:07:25.396Z", - "contributors": [ - "RainSlide", - "NicoNicoNicoNico", - "jsonz1993", - "fscholz", - "xiaoyixiang", - "huhushengwei", - "Df0620", - "xianjiezh", - "frankfang1990", - "Ratin", - "yzzhuo", - "linkqjlin", - "righttoe", - "Ende93", - "konrumi", - "xgqfrms-GitHub", - "roberthow", - "vivian-xu", - "wangcansunking", - "WinstonZheng", - "holynewbie", - "Brandy_Jin", - "johncido", - "williamchu123", - "jamemark", - "RyanZhang", - "teoli", - "ziyunfei", - "sunnylost", - "hanzhao", - "Carrie zhxj", - "Kook pudding" - ] - }, - "Web/API/XMLHttpRequest/HTML_in_XMLHttpRequest": { - "modified": "2019-03-23T22:09:30.230Z", - "contributors": [ - "wbamberg", - "XiaoyaoChen" - ] - }, - "Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data": { - "modified": "2020-08-05T21:51:20.534Z", - "contributors": [ - "Ende93", - "knightyun", - "StudentMain", - "qyue", - "soraly", - "ziyunfei" - ] - }, - "Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests": { - "modified": "2019-03-18T21:11:50.541Z", - "contributors": [ - "Reveur", - "zhangchen", - "Lby876176278", - "xgqfrms-GitHub", - "ziyunfei" - ] - }, - "Web/API/XMLHttpRequest/Using_XMLHttpRequest": { - "modified": "2020-10-15T21:19:05.341Z", - "contributors": [ - "Aierklk", - "coder-git", - "knightyun", - "RainSlide", - "mynull", - "ZengYu", - "zhuruipeng", - "hongxu.Wei", - "banli17", - "ZZES_REN", - "makaria", - "hogaFarming", - "learnslagFeng", - "peterwang1996", - "Harvesty", - "Hawkeyes_Wind", - "lncwwn", - "FredWe", - "mengzyou", - "movever1", - "ziyunfei", - "ethertank" - ] - }, - "Web/API/XMLHttpRequest/Using_XMLHttpRequest_in_IE6": { - "modified": "2019-11-11T06:43:23.528Z", - "contributors": [ - "codimiracle" - ] - }, - "Web/API/XMLHttpRequest/XMLHttpRequest": { - "modified": "2020-05-20T05:15:18.208Z", - "contributors": [ - "RainSlide", - "roberthow" - ] - }, - "Web/API/XMLHttpRequest/abort": { - "modified": "2020-10-15T21:46:06.798Z", - "contributors": [ - "zhangchen", - "chenyang", - "maicss", - "holynewbie" - ] - }, - "Web/API/XMLHttpRequest/abort_event": { - "modified": "2020-10-15T22:23:57.824Z", - "contributors": [ - "shaodahong" - ] - }, - "Web/API/XMLHttpRequest/channel": { - "modified": "2019-03-18T21:15:22.341Z", - "contributors": [ - "Wallen_Han" - ] - }, - "Web/API/XMLHttpRequest/error_event": { - "modified": "2020-10-15T22:19:47.705Z", - "contributors": [ - "lnh" - ] - }, - "Web/API/XMLHttpRequest/getAllResponseHeaders": { - "modified": "2019-05-07T04:02:32.986Z", - "contributors": [ - "banli17", - "holynewbie" - ] - }, - "Web/API/XMLHttpRequest/getResponseHeader": { - "modified": "2020-08-15T07:46:26.724Z", - "contributors": [ - "awathefox", - "wsico", - "winson", - "xgqfrms-GitHub" - ] - }, - "Web/API/XMLHttpRequest/load_event": { - "modified": "2020-10-15T22:18:39.683Z", - "contributors": [ - "logTXT", - "hzy" - ] - }, - "Web/API/XMLHttpRequest/mozAnon": { - "modified": "2019-03-18T21:30:25.736Z", - "contributors": [ - "ssdemajia" - ] - }, - "Web/API/XMLHttpRequest/mozBackgroundRequest": { - "modified": "2019-03-18T21:22:39.629Z", - "contributors": [ - "hilsion" - ] - }, - "Web/API/XMLHttpRequest/mozResponseArrayBuffer": { - "modified": "2020-08-01T02:48:55.334Z", - "contributors": [ - "MEDASSSSSSS", - "YanxuGong" - ] - }, - "Web/API/XMLHttpRequest/mozSystem": { - "modified": "2020-04-24T04:34:54.490Z", - "contributors": [ - "Andew.D", - "tangzhe7" - ] - }, - "Web/API/XMLHttpRequest/onreadystatechange": { - "modified": "2019-09-24T22:57:24.203Z", - "contributors": [ - "Ende93", - "Koopos", - "Cmen", - "holynewbie" - ] - }, - "Web/API/XMLHttpRequest/open": { - "modified": "2020-10-16T05:36:39.774Z", - "contributors": [ - "hanjc1993", - "ZZES_REN", - "LIXiangChen", - "maicss" - ] - }, - "Web/API/XMLHttpRequest/openRequest": { - "modified": "2019-03-18T21:28:11.436Z", - "contributors": [ - "Arktische" - ] - }, - "Web/API/XMLHttpRequest/overrideMimeType": { - "modified": "2020-10-15T22:03:22.512Z", - "contributors": [ - "Reveur", - "651291702", - "xchenGitHub" - ] - }, - "Web/API/XMLHttpRequest/readyState": { - "modified": "2020-10-15T21:46:16.958Z", - "contributors": [ - "zhangchen", - "harryhao", - "holynewbie" - ] - }, - "Web/API/XMLHttpRequest/response": { - "modified": "2020-10-15T21:52:12.557Z", - "contributors": [ - "RainSlide", - "scottxu", - "xgqfrms-GitHub" - ] - }, - "Web/API/XMLHttpRequest/responseText": { - "modified": "2019-08-04T06:46:14.126Z", - "contributors": [ - "xiaojingzhao", - "idwenwe", - "2017gdgzoi48", - "ScottCXQ", - "xgqfrms-GitHub", - "Dcfm" - ] - }, - "Web/API/XMLHttpRequest/responseType": { - "modified": "2020-10-15T21:52:06.346Z", - "contributors": [ - "urain39", - "scottxu", - "CodingSherlock", - "breakair", - "xgqfrms-GitHub" - ] - }, - "Web/API/XMLHttpRequest/responseURL": { - "modified": "2019-05-07T03:18:13.650Z", - "contributors": [ - "banli17", - "CodingSherlock", - "xgqfrms-GitHub", - "holynewbie" - ] - }, - "Web/API/XMLHttpRequest/responseXML": { - "modified": "2019-10-11T23:10:10.259Z", - "contributors": [ - "pacexy", - "banli17", - "faremax", - "xgqfrms-GitHub" - ] - }, - "Web/API/XMLHttpRequest/send": { - "modified": "2020-07-27T04:57:23.174Z", - "contributors": [ - "xuanji", - "Hallz", - "knightyun", - "hzy", - "zxlSilen", - "Dcfm" - ] - }, - "Web/API/XMLHttpRequest/setRequestHeader": { - "modified": "2019-09-24T07:19:26.198Z", - "contributors": [ - "mt001mt", - "maicss" - ] - }, - "Web/API/XMLHttpRequest/status": { - "modified": "2020-10-15T22:03:12.471Z", - "contributors": [ - "cccxu", - "xuqi" - ] - }, - "Web/API/XMLHttpRequest/statusText": { - "modified": "2020-10-15T22:03:25.097Z", - "contributors": [ - "sgnilo", - "CoulsonWang" - ] - }, - "Web/API/XMLHttpRequest/timeout": { - "modified": "2019-03-23T22:33:05.345Z", - "contributors": [ - "kameii", - "Cmen", - "letiantian", - "yangmiao1995", - "holynewbie" - ] - }, - "Web/API/XMLHttpRequest/timeout_event": { - "modified": "2019-04-08T08:24:47.314Z", - "contributors": [ - "irenesmith", - "kameii" - ] - }, - "Web/API/XMLHttpRequest/upload": { - "modified": "2019-04-19T09:12:27.378Z", - "contributors": [ - "Bayes", - "957398123", - "roberthow", - "sqchenxiyuan", - "Cmen", - "Rainsho" - ] - }, - "Web/API/XMLHttpRequest/withCredentials": { - "modified": "2019-03-23T22:24:27.128Z", - "contributors": [ - "muuma", - "JesuisTong", - "bigZ-again", - "Cuixote", - "Cmen" - ] - }, - "Web/API/XMLHttpRequestEventTarget": { - "modified": "2020-10-15T21:34:13.586Z", - "contributors": [ - "RainSlide", - "rubyisapm" - ] - }, - "Web/API/XMLHttpRequestEventTarget/onabort": { - "modified": "2020-10-15T22:25:54.233Z", - "contributors": [ - "liushuyu" - ] - }, - "Web/API/XMLHttpRequestEventTarget/onerror": { - "modified": "2020-10-15T22:08:29.854Z", - "contributors": [ - "weiqinl" - ] - }, - "Web/API/XMLHttpRequestEventTarget/onload": { - "modified": "2020-10-15T22:03:25.613Z", - "contributors": [ - "evestorm" - ] - }, - "Web/API/XMLHttpRequestEventTarget/onloadstart": { - "modified": "2020-10-15T22:09:01.294Z", - "contributors": [ - "luxin88" - ] - }, - "Web/API/XMLHttpRequestEventTarget/onprogress": { - "modified": "2020-10-15T21:53:38.407Z", - "contributors": [ - "liushuyu", - "holynewbie" - ] - }, - "Web/API/XMLHttpRequestResponseType": { - "modified": "2020-10-15T22:12:33.990Z", - "contributors": [ - "RainSlide", - "scottxu" - ] - }, - "Web/API/XPathEvaluator": { - "modified": "2020-10-15T22:15:17.137Z", - "contributors": [ - "CarmeloXue", - "Sebastianz" - ] - }, - "Web/API/element/scrollWidth": { - "modified": "2019-12-11T06:18:59.921Z", - "contributors": [ - "Sinosaurus", - "SageX", - "SphinxKnight", - "JobbyM", - "silhouettesia", - "ChanShuYi", - "leeluolee", - "teoli", - "kuugua" - ] - }, - "Web/API/event.altKey": { - "modified": "2019-03-24T00:16:10.184Z", - "contributors": [ - "ziyunfei", - "teoli", - "jsx" - ] - }, - "Web/API/event.button": { - "modified": "2019-03-24T00:18:20.119Z", - "contributors": [ - "ziyunfei", - "teoli", - "AshfaqHossain" - ] - }, - "Web/API/event.relatedTarget": { - "modified": "2019-03-23T23:09:12.340Z", - "contributors": [ - "wbamberg", - "zhangqiong", - "ziyunfei", - "teoli", - "Darrel.Hsu" - ] - }, - "Web/API/event.shiftKey": { - "modified": "2019-03-24T00:16:22.591Z", - "contributors": [ - "ziyunfei", - "teoli", - "khalid32" - ] - }, - "Web/API/notification": { - "modified": "2020-09-28T00:03:47.900Z", - "contributors": [ - "zch233", - "gjc9620", - "woshiguabi", - "AnnAngela", - "yexiaosong", - "ZZES_REN", - "xgqfrms-GitHub", - "Hawkeyes_Wind" - ] - }, - "Web/API/notification/Notification": { - "modified": "2019-03-23T22:21:04.469Z", - "contributors": [ - "xgqfrms-GitHub", - "Jiang-Xuan", - "fengwuxin" - ] - }, - "Web/API/notification/Using_Web_Notifications": { - "modified": "2020-03-18T06:57:06.393Z", - "contributors": [ - "wangyb1026", - "Yifang-Tongxing", - "845056166", - "xgqfrms-GitHub", - "Hawkeyes_Wind" - ] - }, - "Web/API/notification/actions": { - "modified": "2019-03-23T22:09:42.603Z", - "contributors": [ - "alery123456", - "oopsguy" - ] - }, - "Web/API/notification/badge": { - "modified": "2019-03-23T22:09:46.052Z", - "contributors": [ - "oopsguy" - ] - }, - "Web/API/notification/body": { - "modified": "2019-03-23T22:07:19.982Z", - "contributors": [ - "unliar" - ] - }, - "Web/API/notification/close": { - "modified": "2019-03-23T22:12:06.547Z", - "contributors": [ - "zhengxinxin", - "xgqfrms-GitHub" - ] - }, - "Web/API/notification/data": { - "modified": "2019-03-18T21:42:17.555Z", - "contributors": [ - "luyouxin84" - ] - }, - "Web/API/notification/dir": { - "modified": "2019-03-23T22:04:23.551Z", - "contributors": [ - "borankux" - ] - }, - "Web/API/notification/icon": { - "modified": "2020-10-15T22:11:53.817Z", - "contributors": [ - "zhangchen", - "alery123456" - ] - }, - "Web/API/notification/image": { - "modified": "2020-10-15T22:20:44.715Z", - "contributors": [ - "earthengine" - ] - }, - "Web/API/notification/onclick": { - "modified": "2019-03-23T22:12:07.878Z", - "contributors": [ - "linfeng2gh", - "xgqfrms-GitHub" - ] - }, - "Web/API/notification/onclose": { - "modified": "2019-03-23T22:12:14.658Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/notification/onerror": { - "modified": "2019-03-23T22:12:14.085Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/notification/onshow": { - "modified": "2019-03-23T22:12:09.480Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/notification/permission": { - "modified": "2019-03-18T21:45:17.792Z", - "contributors": [ - "linfeng2gh" - ] - }, - "Web/API/notification/renotify": { - "modified": "2020-10-15T22:20:44.508Z", - "contributors": [ - "HKMHD", - "earthengine" - ] - }, - "Web/API/notification/requestPermission": { - "modified": "2019-03-18T20:42:33.685Z", - "contributors": [ - "codehz", - "xgqfrms-GitHub" - ] - }, - "Web/API/notification/requireInteraction": { - "modified": "2020-10-15T22:33:08.253Z", - "contributors": [ - "BSPR0002" - ] - }, - "Web/API/notification/sound": { - "modified": "2019-03-18T21:17:44.470Z", - "contributors": [ - "ZZES_REN" - ] - }, - "Web/API/指数": { - "modified": "2020-09-07T03:42:22.980Z", - "contributors": [ - "SphinxKnight", - "hl7514576" - ] - }, - "Web/API/支付_请求_接口": { - "modified": "2020-10-15T22:21:11.974Z", - "contributors": [ - "CapriceLi" - ] - }, - "Web/API/支付_请求_接口/Concepts": { - "modified": "2019-07-19T05:54:54.946Z", - "contributors": [ - "CapriceLi" - ] - }, - "Web/API/语音识别": { - "modified": "2020-10-15T22:15:39.263Z", - "contributors": [ - "burt1025lzz" - ] - }, - "Web/API/语音识别/result_event": { - "modified": "2020-10-15T22:28:01.971Z", - "contributors": [ - "coock1996" - ] - }, - "Web/Accessibility": { - "modified": "2020-08-04T10:11:09.882Z", - "contributors": [ - "liunian", - "SphinxKnight", - "Planet6174", - "kindredPP", - "ElliottZheng", - "Harry-Zhao", - "yzweb2018", - "chinanf-boy", - "lukeupup", - "zhanglun", - "Sheppy", - "teoli", - "The.walkers", - "FabioMagnoni" - ] - }, - "Web/Accessibility/ARIA": { - "modified": "2020-10-17T12:24:45.056Z", - "contributors": [ - "phone-burner", - "shayminsky", - "Freemanyu", - "Lucy-Lu", - "HJIO", - "fjh352", - "luobotang", - "xieheihei", - "zhanglun", - "eminor" - ] - }, - "Web/Accessibility/ARIA/ARIA_Live_Regions": { - "modified": "2020-10-17T22:30:15.097Z", - "contributors": [ - "phone-burner", - "liruiqi" - ] - }, - "Web/Accessibility/ARIA/ARIA_Techniques": { - "modified": "2019-03-23T23:19:58.513Z", - "contributors": [ - "oooooo", - "Sheppy" - ] - }, - "Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute": { - "modified": "2019-03-23T23:19:53.211Z", - "contributors": [ - "fjh352", - "ldwformat", - "princetoad@gmail.com" - ] - }, - "Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-labelledby_attribute": { - "modified": "2019-03-23T22:54:23.298Z", - "contributors": [ - "ldwformat" - ] - }, - "Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role": { - "modified": "2019-03-23T22:05:01.811Z", - "contributors": [ - "TiaossuP" - ] - }, - "Web/Accessibility/ARIA/ARIA_Techniques/使用aria-hidden属性": { - "modified": "2019-10-31T22:25:58.797Z", - "contributors": [ - "YoMiao", - "civerzhang" - ] - }, - "Web/Accessibility/ARIA/forms": { - "modified": "2019-03-23T22:16:33.505Z", - "contributors": [ - "jack-chensonglin" - ] - }, - "Web/Accessibility/ARIA/forms/alerts": { - "modified": "2020-10-07T05:07:53.958Z", - "contributors": [ - "phone-burner" - ] - }, - "Web/Accessibility/An_overview_of_accessible_web_applications_and_widgets": { - "modified": "2019-03-23T22:13:24.205Z", - "contributors": [ - "huguangju" - ] - }, - "Web/Accessibility/Keyboard-navigable_JavaScript_widgets": { - "modified": "2019-03-23T23:19:10.459Z", - "contributors": [ - "ChuckZhang", - "xiaole.tao@gmail.com", - "Othella" - ] - }, - "Web/Accessibility/Mobile_accessibility_checklist": { - "modified": "2019-03-18T21:44:26.081Z", - "contributors": [ - "hbwhzk" - ] - }, - "Web/Accessibility/Web_Development": { - "modified": "2019-03-23T22:29:25.203Z", - "contributors": [ - "qianzhangcheng" - ] - }, - "Web/CSS": { - "modified": "2020-12-02T23:03:48.358Z", - "contributors": [ - "zisedelinghun", - "mitaosi", - "so2liu", - "LARE", - "yuyuanqiu", - "liqingyi178", - "SphinxKnight", - "gzl", - "cosformula", - "taoyouh", - "XiangHongAi", - "zjffun", - "icyhat", - "Pedestrian93", - "ewfian", - "fenyu", - "Azurak", - "xjr7670", - "codeofjackie", - "RainSlide", - "NTbad", - "pluwen", - "smancang", - "AntoninSorrento", - "Froggy", - "fskuok", - "BobGreen", - "EvanYY", - "nitan2001", - "neverthelesso", - "zhang-kai", - "Smartree", - "Yelmor", - "FrontENG", - "yatace", - "lunix01", - "Soy", - "kevinfszu", - "kindy", - "Breezewish", - "ReyCG", - "xuxun", - "teoli", - "yan", - "sunnylost", - "TimZhao", - "evantre", - "ziyunfei", - "OoOoOoOo", - "Kaixin110", - "Ianyang", - "Mickeyboy", - "Blabla cn", - "Mgjbot", - "Gonefish", - "Kakurady", - "Eric Chu", - "Bloggercat" - ] - }, - "Web/CSS/--*": { - "modified": "2020-10-15T21:52:54.202Z", - "contributors": [ - "zhangchen", - "Ende93", - "yisibl", - "Huooo" - ] - }, - "Web/CSS/-moz-image-rect": { - "modified": "2020-10-15T22:24:48.334Z", - "contributors": [ - "yangzhitong918" - ] - }, - "Web/CSS/-moz-outline-radius": { - "modified": "2020-10-15T22:20:52.978Z", - "contributors": [ - "ridiculousjam" - ] - }, - "Web/CSS/-moz-outline-radius-bottomleft": { - "modified": "2019-07-06T01:57:22.206Z", - "contributors": [ - "ridiculousjam" - ] - }, - "Web/CSS/-moz-outline-radius-bottomright": { - "modified": "2019-07-06T01:58:23.148Z", - "contributors": [ - "ridiculousjam" - ] - }, - "Web/CSS/-moz-outline-radius-topleft": { - "modified": "2019-07-06T01:58:40.164Z", - "contributors": [ - "ridiculousjam" - ] - }, - "Web/CSS/-moz-outline-radius-topright": { - "modified": "2019-07-06T01:58:56.471Z", - "contributors": [ - "ridiculousjam" - ] - }, - "Web/CSS/-moz-user-input": { - "modified": "2019-03-23T22:17:53.560Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/CSS/-webkit-border-before": { - "modified": "2020-10-15T22:25:58.369Z", - "contributors": [ - "Jackjun724" - ] - }, - "Web/CSS/-webkit-line-clamp": { - "modified": "2020-10-15T22:24:06.241Z", - "contributors": [ - "liuruiqi1993", - "herotangabc", - "litaoAurora" - ] - }, - "Web/CSS/-webkit-mask-attachment": { - "modified": "2019-03-18T21:45:10.830Z", - "contributors": [ - "mobiuskaikai" - ] - }, - "Web/CSS/-webkit-overflow-scrolling": { - "modified": "2019-03-23T23:02:52.440Z", - "contributors": [ - "teoli", - "Ende93", - "FrontENG", - "limichange", - "ccforward" - ] - }, - "Web/CSS/-webkit-tap-highlight-color": { - "modified": "2019-03-23T22:22:56.346Z", - "contributors": [ - "smilewalker" - ] - }, - "Web/CSS/-webkit-text-stroke": { - "modified": "2020-11-09T04:48:30.804Z", - "contributors": [ - "sideshowbarker", - "codingdudecom", - "wr20060926", - "Die4passion", - "wangyi96", - "Vera0707" - ] - }, - "Web/CSS/-webkit-touch-callout": { - "modified": "2019-03-23T22:50:15.755Z", - "contributors": [ - "charlie", - "FredWe" - ] - }, - "Web/CSS/:-moz-only-whitespace": { - "modified": "2020-10-15T22:10:00.132Z", - "contributors": [ - "ExE-Boss", - "LoveofRedMoon" - ] - }, - "Web/CSS/:-moz-placeholder": { - "modified": "2019-03-23T23:21:19.033Z", - "contributors": [ - "teoli", - "bowen-shi" - ] - }, - "Web/CSS/:-moz-window-inactive": { - "modified": "2019-03-18T21:33:22.659Z", - "contributors": [ - "teoli", - "Lim", - "apple1juice" - ] - }, - "Web/CSS/::-moz-placeholder": { - "modified": "2019-03-23T23:21:18.757Z", - "contributors": [ - "FrontENG", - "teoli", - "bowen-shi" - ] - }, - "Web/CSS/::-moz-progress-bar": { - "modified": "2020-07-10T07:07:20.466Z", - "contributors": [ - "YexuanXiao", - "NoobxzZhang" - ] - }, - "Web/CSS/::-moz-range-progress": { - "modified": "2020-11-18T23:08:06.930Z", - "contributors": [ - "jimmy_kmi", - "jcplus" - ] - }, - "Web/CSS/::-webkit-progress-bar": { - "modified": "2020-07-09T14:05:36.446Z", - "contributors": [ - "YexuanXiao", - "teoli", - "smilewalker" - ] - }, - "Web/CSS/::-webkit-progress-inner-element": { - "modified": "2020-10-15T22:31:38.757Z", - "contributors": [ - "YexuanXiao" - ] - }, - "Web/CSS/::-webkit-progress-value": { - "modified": "2020-10-15T22:31:18.416Z", - "contributors": [ - "YexuanXiao", - "Roger_Chi" - ] - }, - "Web/CSS/::-webkit-scrollbar": { - "modified": "2019-03-23T22:08:23.176Z", - "contributors": [ - "Sally-he", - "LoveofRedMoon", - "Messiah" - ] - }, - "Web/CSS/::-webkit-slider-runnable-track": { - "modified": "2019-03-18T21:28:09.437Z", - "contributors": [ - "Songyakang" - ] - }, - "Web/CSS/::-webkit-slider-thumb": { - "modified": "2019-03-18T21:28:12.932Z", - "contributors": [ - "Songyakang" - ] - }, - "Web/CSS/::after": { - "modified": "2020-10-15T21:21:09.850Z", - "contributors": [ - "HayashiMei", - "wink", - "xgqfrms-GitHub", - "liubobuzhidao", - "lixinxin93", - "shuihuo", - "LichMscy", - "FredWe", - "fskuok", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/::backdrop": { - "modified": "2020-10-15T21:55:05.681Z", - "contributors": [ - "tabunnnn", - "RainSlide", - "nDos", - "old2sun" - ] - }, - "Web/CSS/::before": { - "modified": "2020-10-15T21:33:30.692Z", - "contributors": [ - "Mookiepiece", - "LeonWuV", - "tanshaobo", - "nDos", - "xiaokk06", - "AutumnFish", - "zhengxinxin", - "noiron", - "johncido", - "FredWe", - "Fadeoc" - ] - }, - "Web/CSS/::cue": { - "modified": "2020-10-15T21:55:37.580Z", - "contributors": [ - "Render" - ] - }, - "Web/CSS/::first-letter": { - "modified": "2019-03-23T22:49:07.025Z", - "contributors": [ - "nDos", - "guonanci", - "lizhihua" - ] - }, - "Web/CSS/::first-line": { - "modified": "2019-03-23T22:21:01.435Z", - "contributors": [ - "skywalker_z", - "maoyumaoxun", - "myfreeer", - "nDos", - "xiaojunjor", - "MinimalistYing", - "876843240" - ] - }, - "Web/CSS/::grammar-error": { - "modified": "2019-03-23T22:07:07.087Z", - "contributors": [ - "JewelYueng" - ] - }, - "Web/CSS/::marker": { - "modified": "2020-10-15T22:30:50.099Z", - "contributors": [ - "conorzhong" - ] - }, - "Web/CSS/::part": { - "modified": "2020-11-30T21:33:51.481Z", - "contributors": [ - "seawaywen", - "jcplus" - ] - }, - "Web/CSS/::placeholder": { - "modified": "2019-03-23T22:12:08.952Z", - "contributors": [ - "Adashuai5", - "maoyumaoxun", - "nDos", - "Colin.Go", - "LiuYuan" - ] - }, - "Web/CSS/::selection": { - "modified": "2020-10-15T21:33:48.415Z", - "contributors": [ - "greyyyyy", - "zhangchen", - "ziyunfei", - "Serifx", - "ranwu", - "johncido", - "vagusX", - "monjer", - "hikarievo" - ] - }, - "Web/CSS/::slotted": { - "modified": "2020-10-15T22:09:58.940Z", - "contributors": [ - "LoveofRedMoon" - ] - }, - "Web/CSS/::spelling-error": { - "modified": "2020-10-15T22:00:46.705Z", - "contributors": [ - "nDos" - ] - }, - "Web/CSS/:active": { - "modified": "2020-10-15T21:34:14.296Z", - "contributors": [ - "yclup", - "RainSlide", - "HayashiMei", - "fskuok", - "psychebb" - ] - }, - "Web/CSS/:any": { - "modified": "2019-03-23T22:23:18.210Z", - "contributors": [ - "Minya_Chan", - "LinYunweb", - "shuihuo", - "tigercao" - ] - }, - "Web/CSS/:any-link": { - "modified": "2020-10-15T21:56:20.733Z", - "contributors": [ - "walacewang", - "anjia" - ] - }, - "Web/CSS/:blank空白伪类": { - "modified": "2020-10-15T22:21:57.411Z", - "contributors": [ - "RainSlide", - "karma2014" - ] - }, - "Web/CSS/:checked": { - "modified": "2020-10-15T21:42:35.145Z", - "contributors": [ - "Ritr", - "hiyangguo", - "FrontENG", - "WarriorWu", - "wktdh" - ] - }, - "Web/CSS/:default": { - "modified": "2019-03-23T22:20:32.874Z", - "contributors": [ - "NorthWind", - "nDos", - "NoobxzZhang", - "eddiexxxx", - "dongchaoge", - "faremax" - ] - }, - "Web/CSS/:defined": { - "modified": "2020-10-15T22:04:25.058Z", - "contributors": [ - "sisibeloved", - "forever_youyou" - ] - }, - "Web/CSS/:dir": { - "modified": "2019-03-23T22:58:41.550Z", - "contributors": [ - "nick-ChenZe", - "fskuok" - ] - }, - "Web/CSS/:disabled": { - "modified": "2019-03-23T21:45:44.263Z", - "contributors": [ - "zxsunrise", - "AlexChao" - ] - }, - "Web/CSS/:empty": { - "modified": "2020-10-15T21:37:28.617Z", - "contributors": [ - "xgqfrms", - "zhuangyin", - "xgqfrms-GitHub", - "DaPanda", - "FredWe" - ] - }, - "Web/CSS/:enabled": { - "modified": "2020-10-15T21:32:21.465Z", - "contributors": [ - "RainSlide", - "AlexChao" - ] - }, - "Web/CSS/:first": { - "modified": "2019-03-23T22:15:57.420Z", - "contributors": [ - "xingkongs" - ] - }, - "Web/CSS/:first-child": { - "modified": "2020-10-15T21:22:57.317Z", - "contributors": [ - "Ritr", - "silhouettesia", - "xgqfrms-GitHub", - "FredWe", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/:first-of-type": { - "modified": "2020-10-15T21:38:15.943Z", - "contributors": [ - "Ende93", - "Ritr", - "zhangchen", - "xgqfrms-GitHub", - "ZackBee", - "sgzzy", - "Orange-C", - "sudo2015" - ] - }, - "Web/CSS/:focus": { - "modified": "2020-10-15T21:34:35.352Z", - "contributors": [ - "Ritr", - "zhangchen", - "Harvesty", - "Fadeoc", - "FredWe", - "Gaohaoyang" - ] - }, - "Web/CSS/:focus-visible": { - "modified": "2020-10-15T22:10:22.689Z", - "contributors": [ - "AlphaGo88" - ] - }, - "Web/CSS/:focus-within": { - "modified": "2020-10-15T21:58:43.977Z", - "contributors": [ - "RainSlide", - "Ritr", - "nDos", - "qdlaoyao", - "15207108156" - ] - }, - "Web/CSS/:fullscreen": { - "modified": "2019-03-18T20:54:18.077Z", - "contributors": [ - "LeonDWong" - ] - }, - "Web/CSS/:has": { - "modified": "2020-10-15T22:01:57.515Z", - "contributors": [ - "kidonng", - "LoveofRedMoon" - ] - }, - "Web/CSS/:host": { - "modified": "2020-10-15T22:16:15.558Z", - "contributors": [ - "zhangchen" - ] - }, - "Web/CSS/:host()": { - "modified": "2020-10-15T22:16:54.122Z", - "contributors": [ - "karma2014", - "no1xsyzy", - "764777472" - ] - }, - "Web/CSS/:host-context()": { - "modified": "2020-10-15T22:22:18.002Z", - "contributors": [ - "jhjocelyn" - ] - }, - "Web/CSS/:hover": { - "modified": "2019-03-23T23:09:30.132Z", - "contributors": [ - "JacksonSui", - "shifengchen", - "liuhanru", - "HIS" - ] - }, - "Web/CSS/:in-range": { - "modified": "2020-10-15T22:01:15.650Z", - "contributors": [ - "Ritr", - "ShirelyGong" - ] - }, - "Web/CSS/:indeterminate": { - "modified": "2020-10-15T21:53:09.179Z", - "contributors": [ - "Ritr", - "nDos", - "holynewbie" - ] - }, - "Web/CSS/:invalid": { - "modified": "2020-10-15T21:49:18.604Z", - "contributors": [ - "Ritr", - "ShirelyGong", - "liyongleihf2006", - "King." - ] - }, - "Web/CSS/:is": { - "modified": "2020-10-15T22:11:21.465Z", - "contributors": [ - "Ende93", - "ExE-Boss", - "Ritr" - ] - }, - "Web/CSS/:lang": { - "modified": "2020-10-15T21:38:56.937Z", - "contributors": [ - "Ritr", - "ShirelyGong", - "DongyaGe", - "L520" - ] - }, - "Web/CSS/:last-child": { - "modified": "2020-10-15T21:51:06.148Z", - "contributors": [ - "Ritr", - "FrontENG", - "AlexChao" - ] - }, - "Web/CSS/:last-of-type": { - "modified": "2020-10-15T21:37:08.616Z", - "contributors": [ - "Ritr", - "FrontENG", - "FredWe" - ] - }, - "Web/CSS/:left": { - "modified": "2020-10-15T22:01:55.037Z", - "contributors": [ - "LoveofRedMoon" - ] - }, - "Web/CSS/:link": { - "modified": "2020-10-15T21:45:58.577Z", - "contributors": [ - "leoxiao2012", - "Ritr", - "lixinxin93", - "FuckingChestnut", - "w0wbin", - "gengsinan" - ] - }, - "Web/CSS/:not": { - "modified": "2020-10-15T21:37:03.676Z", - "contributors": [ - "skywalker_z", - "jaredhan418", - "RainSlide", - "Ritr", - "ly525", - "nick-ChenZe", - "FredWe" - ] - }, - "Web/CSS/:nth-child": { - "modified": "2019-09-08T12:03:00.754Z", - "contributors": [ - "DingZehua", - "Ritr", - "km-c", - "tsukimiya", - "yusan77", - "kensz66", - "genezx", - "ShinningFire", - "PoppinL", - "xgqfrms-GitHub", - "BiggerCheng", - "hstarorg", - "FredWe", - "hutuxu" - ] - }, - "Web/CSS/:nth-last-child": { - "modified": "2020-10-15T21:33:53.402Z", - "contributors": [ - "happyWang", - "Ritr", - "PoppinL", - "hutuxu" - ] - }, - "Web/CSS/:nth-last-of-type": { - "modified": "2020-10-15T21:54:40.871Z", - "contributors": [ - "Ritr", - "PoppinL" - ] - }, - "Web/CSS/:nth-of-type": { - "modified": "2020-10-15T21:36:59.567Z", - "contributors": [ - "xiumingxu", - "parabolazz", - "Ritr", - "PythonVsJava", - "infinite-knowledge", - "genezx", - "RainSlide", - "liwenkang", - "xgqfrms-GitHub", - "PoppinL", - "Pandapm", - "PageYe", - "sudo2015", - "FredWe" - ] - }, - "Web/CSS/:only-child": { - "modified": "2020-10-15T21:22:55.479Z", - "contributors": [ - "aute", - "Jiang-Xuan", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/:only-of-type": { - "modified": "2019-05-09T23:53:55.894Z", - "contributors": [ - "Ritr", - "maoyumaoxun", - "FredWe" - ] - }, - "Web/CSS/:optional": { - "modified": "2019-03-23T22:20:45.289Z", - "contributors": [ - "maoyumaoxun", - "liyongleihf2006" - ] - }, - "Web/CSS/:out-of-range": { - "modified": "2020-10-15T22:05:19.472Z", - "contributors": [ - "maoyumaoxun" - ] - }, - "Web/CSS/:placeholder-shown": { - "modified": "2020-10-15T22:01:57.789Z", - "contributors": [ - "LoveofRedMoon" - ] - }, - "Web/CSS/:read-only": { - "modified": "2020-10-15T22:00:12.983Z", - "contributors": [ - "fscholz", - "maoyumaoxun", - "King." - ] - }, - "Web/CSS/:read-write": { - "modified": "2020-10-15T22:05:20.778Z", - "contributors": [ - "maoyumaoxun" - ] - }, - "Web/CSS/:required": { - "modified": "2020-07-04T13:27:54.236Z", - "contributors": [ - "mdn_idealist", - "liyongleihf2006" - ] - }, - "Web/CSS/:right": { - "modified": "2020-10-15T22:18:16.757Z", - "contributors": [ - "7NZ", - "LittleBearForCode", - "LeonZou", - "vaynewang" - ] - }, - "Web/CSS/:root": { - "modified": "2019-09-20T05:29:11.272Z", - "contributors": [ - "mingzhang6", - "PoppinL", - "keqingrong", - "movinghorse" - ] - }, - "Web/CSS/:scope": { - "modified": "2020-10-15T21:54:59.545Z", - "contributors": [ - "cuixiping", - "saifeiLee", - "zhaoqize" - ] - }, - "Web/CSS/:target": { - "modified": "2020-10-15T21:37:32.170Z", - "contributors": [ - "zhangchen", - "LasyIsLazy", - "ShirelyGong", - "gqqnbig", - "Le-Fu", - "FredWe" - ] - }, - "Web/CSS/:valid": { - "modified": "2020-10-15T21:51:30.912Z", - "contributors": [ - "Ende93", - "xgqfrms-GitHub", - "liyongleihf2006" - ] - }, - "Web/CSS/:visited": { - "modified": "2019-09-22T23:26:27.997Z", - "contributors": [ - "hhxxhg", - "Adashuai5", - "FredWe" - ] - }, - "Web/CSS/:where": { - "modified": "2020-10-15T22:12:05.129Z", - "contributors": [ - "RainSlide", - "zhangchizi" - ] - }, - "Web/CSS/@charset": { - "modified": "2020-10-15T21:52:27.106Z", - "contributors": [ - "Ritr", - "xgqfrms-GitHub", - "frankfang1990", - "yofine" - ] - }, - "Web/CSS/@counter-style": { - "modified": "2019-03-23T22:52:04.265Z", - "contributors": [ - "lixinxin93", - "FredWe" - ] - }, - "Web/CSS/@counter-style/additive-symbols": { - "modified": "2020-10-15T21:55:56.428Z", - "contributors": [ - "liuruiqi1993", - "HayashiMei", - "lixinxin93" - ] - }, - "Web/CSS/@counter-style/pad": { - "modified": "2020-10-15T22:03:38.361Z", - "contributors": [ - "LoveofRedMoon" - ] - }, - "Web/CSS/@counter-style/speak-as": { - "modified": "2020-10-15T22:25:44.554Z", - "contributors": [ - "kmokidd" - ] - }, - "Web/CSS/@document": { - "modified": "2020-10-15T21:19:42.707Z", - "contributors": [ - "RainSlide", - "fsx950223", - "fscholz", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/@font-face": { - "modified": "2020-10-15T21:22:05.346Z", - "contributors": [ - "symant233", - "1v9", - "fengzhineng2", - "codedrinker", - "Howard.Chen", - "AozakiOrenji", - "mozhs", - "gqqnbig", - "TiaossuP", - "King.", - "fscholz", - "Go7hic", - "teoli", - "xcffl" - ] - }, - "Web/CSS/@font-face/font-display": { - "modified": "2020-10-15T22:05:45.748Z", - "contributors": [ - "suyanhanx", - "RainSlide", - "littlee", - "Lim", - "tiger102010" - ] - }, - "Web/CSS/@font-face/font-family": { - "modified": "2019-03-23T22:16:12.530Z", - "contributors": [ - "mozhs" - ] - }, - "Web/CSS/@font-face/font-style": { - "modified": "2019-03-23T22:16:15.746Z", - "contributors": [ - "mozhs" - ] - }, - "Web/CSS/@font-face/src": { - "modified": "2020-10-15T22:12:37.602Z", - "contributors": [ - "Capchen" - ] - }, - "Web/CSS/@font-feature-values": { - "modified": "2020-09-21T04:47:20.263Z", - "contributors": [ - "xiaoman", - "xgqfrms-GitHub" - ] - }, - "Web/CSS/@import": { - "modified": "2019-03-23T22:41:07.257Z", - "contributors": [ - "xgqfrms-GitHub", - "seed-fe", - "Guillaume-Heras", - "mrstork", - "gqqnbig" - ] - }, - "Web/CSS/@keyframes": { - "modified": "2020-10-30T00:35:27.014Z", - "contributors": [ - "uxk0587", - "RainSlide", - "Lim", - "codeofjackie", - "haocity", - "pot-code", - "LiuXiangyu", - "Sebastianz", - "zhangqiong", - "codert", - "fscholz", - "xiaodongzai", - "Sheppy", - "fannie-z", - "zmh_w", - "ziyunfei", - "qinmudi" - ] - }, - "Web/CSS/@media": { - "modified": "2020-10-15T21:15:45.575Z", - "contributors": [ - "wallena3", - "KeBaob", - "zjffun", - "Gwokhou", - "SphinxKnight", - "JulesWang", - "1060881984", - "Ray-Eldath", - "maicss", - "eeeeeeeason", - "xgqfrms-GitHub", - "bear-x", - "xuwenyuan", - "VdoG", - "Ende93", - "ziyunfei", - "Mgjbot", - "TigerSoldier" - ] - }, - "Web/CSS/@media/-webkit-device-pixel-ratio": { - "modified": "2019-03-23T22:17:04.750Z", - "contributors": [ - "charlie" - ] - }, - "Web/CSS/@media/any-hover": { - "modified": "2020-10-19T22:47:55.316Z", - "contributors": [ - "cuishuo" - ] - }, - "Web/CSS/@media/any-pointer": { - "modified": "2020-10-19T06:15:19.281Z", - "contributors": [ - "cuishuo" - ] - }, - "Web/CSS/@media/aspect-ratio": { - "modified": "2020-10-15T22:29:41.881Z", - "contributors": [ - "huyuqiong", - "wallena3" - ] - }, - "Web/CSS/@media/device-height": { - "modified": "2020-10-15T22:18:00.176Z", - "contributors": [ - "houzp" - ] - }, - "Web/CSS/@media/hover": { - "modified": "2020-10-15T22:04:18.656Z", - "contributors": [ - "fscholz", - "sdc37h" - ] - }, - "Web/CSS/@media/orientation": { - "modified": "2020-10-15T22:15:58.369Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/CSS/@media/prefers-color-scheme": { - "modified": "2020-10-15T22:17:29.903Z", - "contributors": [ - "RainSlide", - "ZZES_REN", - "urusai-me", - "SimGenius" - ] - }, - "Web/CSS/@media/prefers-reduced-motion": { - "modified": "2020-10-15T22:26:02.459Z", - "contributors": [ - "kmokidd" - ] - }, - "Web/CSS/@media/width": { - "modified": "2019-03-26T01:54:43.033Z", - "contributors": [ - "sdc37h" - ] - }, - "Web/CSS/@namespace": { - "modified": "2019-03-23T22:25:10.485Z", - "contributors": [ - "gardenia", - "TiaossuP" - ] - }, - "Web/CSS/@page": { - "modified": "2020-10-15T21:53:43.116Z", - "contributors": [ - "RainSlide", - "Boringboy" - ] - }, - "Web/CSS/@supports": { - "modified": "2020-11-15T05:35:58.924Z", - "contributors": [ - "RolkerMan", - "mailwwc", - "RainSlide", - "gucong", - "fscholz", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/@viewport": { - "modified": "2020-10-15T21:48:57.222Z", - "contributors": [ - "zzzimaple", - "aovitatechnology", - "Han1015", - "Zhang-Junzhi", - "Junetea", - "DKLost", - "cvrebert" - ] - }, - "Web/CSS/@viewport/height": { - "modified": "2020-11-27T23:49:12.467Z", - "contributors": [ - "xusy" - ] - }, - "Web/CSS/@viewport/orientation": { - "modified": "2019-03-23T22:28:00.871Z", - "contributors": [ - "Minya_Chan" - ] - }, - "Web/CSS/@viewport/viewport-fit": { - "modified": "2020-10-15T22:19:15.758Z", - "contributors": [ - "PYGC", - "gzbitzxx", - "zhangchen", - "x1aodingdang" - ] - }, - "Web/CSS/@viewport/width": { - "modified": "2019-10-22T01:59:54.524Z", - "contributors": [ - "Zhang-Junzhi", - "xpromise" - ] - }, - "Web/CSS/@viewport/zoom": { - "modified": "2020-10-15T21:50:31.298Z", - "contributors": [ - "zhangchen", - "azhi09" - ] - }, - "Web/CSS/Adjacent_sibling_combinator": { - "modified": "2020-10-15T21:22:13.249Z", - "contributors": [ - "peterbe", - "XiangHongAi", - "tss1006", - "ExE-Boss", - "zhangqiangoffice", - "Ricardo-Ke", - "fscholz", - "teoli", - "alimon" - ] - }, - "Web/CSS/All_About_The_Containing_Block": { - "modified": "2020-10-09T00:31:23.855Z", - "contributors": [ - "Chellyyy", - "Young-Spark", - "laizenan", - "alattalatta", - "thxiami", - "studyMakesMeHappy", - "peppermintCode", - "tolerious", - "hehex9", - "littlelake", - "ucev" - ] - }, - "Web/CSS/Alternative_style_sheets": { - "modified": "2020-10-15T22:30:11.278Z", - "contributors": [ - "14725" - ] - }, - "Web/CSS/At-rule": { - "modified": "2019-08-08T06:46:40.777Z", - "contributors": [ - "xgqfrms-GitHub", - "teoli", - "yan", - "alimon" - ] - }, - "Web/CSS/Attribute_selectors": { - "modified": "2020-10-15T21:22:08.999Z", - "contributors": [ - "Lucy", - "imwangpan", - "juzco", - "RainSlide", - "littleostar", - "Ende93", - "zy343134464", - "xgqfrms-GitHub", - "win5do", - "AnnAngela", - "fzhw88", - "fscholz", - "teoli", - "alimon" - ] - }, - "Web/CSS/CSSOM_View": { - "modified": "2019-03-23T22:13:17.107Z", - "contributors": [ - "Pada" - ] - }, - "Web/CSS/CSSOM_View/坐标系": { - "modified": "2019-03-18T21:28:19.895Z", - "contributors": [ - "1Cr18Ni9" - ] - }, - "Web/CSS/CSS_Animations": { - "modified": "2020-10-15T21:40:13.943Z", - "contributors": [ - "1v9", - "xgqfrms-GitHub", - "esterTion", - "luhai.cui@gmail.com", - "teoli" - ] - }, - "Web/CSS/CSS_Animations/Detecting_CSS_animation_support": { - "modified": "2019-08-08T07:17:10.798Z", - "contributors": [ - "wbamberg", - "zhengxinxin", - "luhai.cui@gmail.com" - ] - }, - "Web/CSS/CSS_Animations/Tips": { - "modified": "2019-08-08T06:48:05.151Z", - "contributors": [ - "yangwr", - "mrzhao1129", - "DevQiao" - ] - }, - "Web/CSS/CSS_Animations/Using_CSS_animations": { - "modified": "2019-08-08T07:19:41.823Z", - "contributors": [ - "xgqfrms-GitHub", - "SphinxKnight", - "teoli", - "ChanYuLeung", - "johncido", - "hutuxu" - ] - }, - "Web/CSS/CSS_Background_and_Borders": { - "modified": "2019-03-23T22:45:29.966Z", - "contributors": [ - "FrontENG", - "teoli" - ] - }, - "Web/CSS/CSS_Background_and_Borders/Border-image_generator": { - "modified": "2019-03-18T21:15:13.389Z", - "contributors": [ - "Ende93", - "yellowstar1992" - ] - }, - "Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds": { - "modified": "2019-03-23T23:28:25.343Z", - "contributors": [ - "imwangpan", - "teoli", - "Nightingale" - ] - }, - "Web/CSS/CSS_Background_and_Borders/圆角边框发生器": { - "modified": "2019-03-23T22:42:48.406Z", - "contributors": [ - "FrontENG", - "beyoursun", - "regiondavid" - ] - }, - "Web/CSS/CSS_Backgrounds_and_Borders": { - "modified": "2019-03-18T21:45:20.317Z", - "contributors": [ - "PythonVsJava", - "RainSlide", - "Sheppy" - ] - }, - "Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images": { - "modified": "2019-03-18T21:38:07.175Z", - "contributors": [ - "Aaron_Zhung" - ] - }, - "Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds": { - "modified": "2019-03-18T21:45:25.619Z", - "contributors": [ - "HHUchenmin" - ] - }, - "Web/CSS/CSS_Basic_User_Interface": { - "modified": "2020-09-16T00:31:43.061Z", - "contributors": [ - "namklaw" - ] - }, - "Web/CSS/CSS_Box_Alignment": { - "modified": "2020-02-11T06:02:03.390Z", - "contributors": [ - "HareInWeed", - "mfuji09" - ] - }, - "Web/CSS/CSS_Box_Alignment/Box_Alignment_in_Flexbox": { - "modified": "2019-03-18T20:34:13.411Z", - "contributors": [ - "DecadeCode" - ] - }, - "Web/CSS/CSS_Box_Model": { - "modified": "2019-05-21T23:58:20.696Z", - "contributors": [ - "celdr", - "zjffun", - "RainSlide", - "liangmuyang", - "ziyunfei" - ] - }, - "Web/CSS/CSS_Box_Model/Box-shadow_generator": { - "modified": "2019-03-18T20:43:42.671Z", - "contributors": [ - "BychekRU", - "TiaossuP", - "charlie" - ] - }, - "Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model": { - "modified": "2019-10-01T21:50:12.174Z", - "contributors": [ - "123456zzz", - "RainSlide", - "tanapok", - "shuaihuGao", - "xiaojichao", - "xgqfrms-GitHub", - "YehaiChen", - "CompileYouth", - "ouzz413", - "kevinfszu", - "fscholz", - "stephaniehobson", - "Ende93", - "teoli", - "yan" - ] - }, - "Web/CSS/CSS_Box_Model/Mastering_margin_collapsing": { - "modified": "2020-07-05T13:43:32.769Z", - "contributors": [ - "mdn_idealist", - "lingxiao-Zhu", - "youcanping", - "tangweikun", - "fanerge", - "Terry.Qiao", - "KMKNKK", - "superkuang", - "jscgq", - "BarryLiu1995", - "xgqfrms-GitHub", - "frankfang1990", - "ChuckZhang", - "TiaossuP", - "StarXY", - "lemopo", - "teoli", - "Ende93", - "fscholz", - "sartrey", - "yan" - ] - }, - "Web/CSS/CSS_Color": { - "modified": "2020-11-28T00:06:47.995Z", - "contributors": [ - "xusy" - ] - }, - "Web/CSS/CSS_Colors": { - "modified": "2019-03-23T22:09:37.851Z", - "contributors": [ - "GHLandy", - "Krenair" - ] - }, - "Web/CSS/CSS_Colors/Color_picker_tool": { - "modified": "2019-09-28T22:09:24.320Z", - "contributors": [ - "smnet1999", - "KrisLee", - "wendyzang", - "miaoxiaozui2017", - "sdc37h", - "nalanrola" - ] - }, - "Web/CSS/CSS_Columns": { - "modified": "2020-09-13T09:14:37.310Z", - "contributors": [ - "SolidBlock", - "vampire624", - "maicss", - "DaiZhiTao", - "Sebastianz" - ] - }, - "Web/CSS/CSS_Columns/Basic_Concepts_of_Multicol": { - "modified": "2019-03-18T21:22:33.531Z", - "contributors": [ - "userkang" - ] - }, - "Web/CSS/CSS_Columns/Handling_Overflow_in_Multicol": { - "modified": "2019-12-09T22:59:53.171Z", - "contributors": [ - "maicss" - ] - }, - "Web/CSS/CSS_Conditional_Rules": { - "modified": "2020-10-22T05:31:36.474Z", - "contributors": [ - "wbamberg" - ] - }, - "Web/CSS/CSS_Conditional_Rules/Using_Feature_Queries": { - "modified": "2020-10-22T05:31:37.700Z", - "contributors": [ - "SDUTWSL" - ] - }, - "Web/CSS/CSS_Containment": { - "modified": "2020-10-23T12:43:13.528Z", - "contributors": [ - "AielloChan" - ] - }, - "Web/CSS/CSS_Counter_Styles": { - "modified": "2019-03-18T21:38:16.217Z", - "contributors": [ - "ZZES_REN" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout": { - "modified": "2019-09-20T14:46:03.892Z", - "contributors": [ - "Heaan", - "rtxu", - "zjffun", - "ouyangyun", - "cantoraz", - "ryanlid", - "yofine", - "xgqfrms", - "WynnChen", - "Humyang", - "teoli" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container": { - "modified": "2020-08-31T23:01:11.688Z", - "contributors": [ - "lmislm", - "woshiqiang1", - "SphinxKnight", - "richard1225", - "cantoraz", - "coddingBoy", - "LWBliuwenbo", - "zhang-hongwei" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox": { - "modified": "2020-08-28T05:40:29.406Z", - "contributors": [ - "ysqzhang", - "BlingBling93", - "Bearies", - "yuliangmu", - "SylviaZ", - "yszou", - "hellotaotao", - "luoyelusheng", - "JodieShi", - "pluwen", - "imgss" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Controlling_Ratios_of_Flex_Items_Along_the_Main_Ax": { - "modified": "2020-05-17T05:12:56.231Z", - "contributors": [ - "YangYaPing", - "renq460", - "Fancyflame", - "jack_l", - "Bearies", - "aszx-fyh", - "zhuangyin", - "tianqingyu", - "helloyong" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持": { - "modified": "2020-02-11T09:41:01.217Z", - "contributors": [ - "knightyun", - "fanjianfeng1010", - "EndlessSong", - "minvedacat", - "Ran_Lyu", - "xieminjie" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Mastering_Wrapping_of_Flex_Items": { - "modified": "2020-10-21T03:55:55.262Z", - "contributors": [ - "Riemann", - "qwertty" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Mixins": { - "modified": "2019-03-23T22:33:55.727Z", - "contributors": [ - "chrisdavidmills", - "SmilyLiang", - "SolitudeRA", - "zhicongyang", - "xgqfrms", - "jiahui" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items": { - "modified": "2020-10-15T23:39:20.262Z", - "contributors": [ - "huanggm", - "kidonng", - "youcanping" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes": { - "modified": "2019-03-23T23:31:49.899Z", - "contributors": [ - "hanliuxin5", - "xgqfrms-GitHub", - "mogewcy", - "fedwatch", - "dongyu_-_", - "zrj570543941", - "TiaossuP", - "xgqfrms", - "WynnChen", - "jokeviner", - "fscholz", - "Huxpro", - "ziyunfei", - "yan", - "nighca", - "Kasuganosora", - "yisi", - "Ribery", - "TimZhao", - "Nightingale" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications": { - "modified": "2019-03-23T22:27:26.278Z", - "contributors": [ - "Anshiii", - "SphinxKnight", - "lon", - "fscholz", - "lazurey" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox": { - "modified": "2020-06-21T23:26:55.230Z", - "contributors": [ - "cell", - "mileyho", - "xzhyj93", - "SkyeYoung", - "devindwan", - "xieminjie" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系": { - "modified": "2020-07-03T00:45:14.544Z", - "contributors": [ - "jin_wang", - "Wulakaka" - ] - }, - "Web/CSS/CSS_Flow_Layout": { - "modified": "2019-03-18T20:48:13.355Z", - "contributors": [ - "Bpeanut" - ] - }, - "Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow": { - "modified": "2020-09-10T14:45:56.661Z", - "contributors": [ - "MmmmHeee", - "ongg", - "islet", - "chinarabbit01", - "Arwinz", - "xunzhonglee", - "sunkaila" - ] - }, - "Web/CSS/CSS_Flow_Layout/Flow_Layout_and_Overflow": { - "modified": "2019-08-24T06:48:49.998Z", - "contributors": [ - "xunzhonglee" - ] - }, - "Web/CSS/CSS_Flow_Layout/Flow_Layout_and_Writing_Modes": { - "modified": "2019-08-24T07:10:58.090Z", - "contributors": [ - "xunzhonglee" - ] - }, - "Web/CSS/CSS_Flow_Layout/Intro_to_formatting_contexts": { - "modified": "2020-10-09T02:26:15.552Z", - "contributors": [ - "Chellyyy", - "xunzhonglee" - ] - }, - "Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外": { - "modified": "2019-08-26T05:12:18.778Z", - "contributors": [ - "xuduotom", - "wython", - "kernellmd", - "feaswcy" - ] - }, - "Web/CSS/CSS_Fonts": { - "modified": "2019-03-23T22:13:50.386Z", - "contributors": [ - "xiaoxiangwendao", - "Ryogiazaka" - ] - }, - "Web/CSS/CSS_Fonts/OpenType_fonts_guide": { - "modified": "2019-06-08T12:32:17.386Z", - "contributors": [ - "Zhuikang", - "WangLeto" - ] - }, - "Web/CSS/CSS_Fonts/Variable_Fonts_Guide": { - "modified": "2020-09-10T07:44:15.006Z", - "contributors": [ - "CelestialPhineas", - "nicelanlan", - "ldwformat" - ] - }, - "Web/CSS/CSS_Functions": { - "modified": "2020-11-20T07:10:42.861Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/CSS/CSS_Generated_Content": { - "modified": "2020-10-15T22:02:59.653Z", - "contributors": [ - "Jack.Works", - "BlackBirch" - ] - }, - "Web/CSS/CSS_Grid_Layout": { - "modified": "2019-09-04T22:46:50.423Z", - "contributors": [ - "xgqfrms", - "icyhat", - "lyz810", - "zxsunrise", - "daxiazilong", - "chentao106", - "jiamicu", - "nsxz", - "zhuangyin", - "fskuok", - "axiu", - "Ende93", - "goodluckforever", - "ziyunfei", - "Slayer1986" - ] - }, - "Web/CSS/CSS_Grid_Layout/Auto-placement_in_CSS_Grid_Layout": { - "modified": "2019-03-23T22:03:41.100Z", - "contributors": [ - "comehope" - ] - }, - "Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout": { - "modified": "2019-10-10T16:32:12.515Z", - "contributors": [ - "L9m", - "danmin25", - "hackingzhang", - "hooozen", - "tsukimiya", - "huasheng", - "Ende93", - "Marsh", - "fskuok", - "zsxeee", - "lipd", - "EzioW", - "1986slayer" - ] - }, - "Web/CSS/CSS_Grid_Layout/Box_Alignment_in_CSS_Grid_Layout": { - "modified": "2020-06-17T09:42:12.785Z", - "contributors": [ - "lmx-Hexagram", - "comehope" - ] - }, - "Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes": { - "modified": "2019-03-18T21:44:18.420Z", - "contributors": [ - "comehope" - ] - }, - "Web/CSS/CSS_Grid_Layout/CSS_Grid_Layout_and_Accessibility": { - "modified": "2019-09-04T22:47:22.673Z", - "contributors": [ - "comehope" - ] - }, - "Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement": { - "modified": "2020-06-22T07:00:15.555Z", - "contributors": [ - "suvyme", - "cheetooo" - ] - }, - "Web/CSS/CSS_Grid_Layout/Grid_Template_Areas": { - "modified": "2019-03-18T20:53:31.538Z", - "contributors": [ - "xuqighub", - "comehope" - ] - }, - "Web/CSS/CSS_Grid_Layout/Layout_using_Named_Grid_Lines": { - "modified": "2019-03-23T22:13:51.803Z", - "contributors": [ - "comehope", - "1986slayer" - ] - }, - "Web/CSS/CSS_Grid_Layout/Line-based_Placement_with_CSS_Grid": { - "modified": "2019-05-31T04:50:27.843Z", - "contributors": [ - "chentao106", - "crazy_rat", - "dreampasssser", - "fskuok" - ] - }, - "Web/CSS/CSS_Grid_Layout/Relationship_of_Grid_Layout": { - "modified": "2019-09-10T12:32:25.247Z", - "contributors": [ - "Hermedius", - "comehope", - "Liiked", - "wolf-wolf", - "Marsh", - "eliseguilian", - "fskuok", - "ucev" - ] - }, - "Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局": { - "modified": "2019-09-04T22:46:41.081Z", - "contributors": [ - "zhangchen", - "Juvon", - "SphinxKnight" - ] - }, - "Web/CSS/CSS_Logical_Properties": { - "modified": "2020-10-12T22:45:52.532Z", - "contributors": [ - "RainSlide", - "Ende93" - ] - }, - "Web/CSS/CSS_Logical_Properties/Basic_conceptsjie": { - "modified": "2019-03-28T00:11:41.934Z", - "contributors": [ - "Aamperor" - ] - }, - "Web/CSS/CSS_Masking": { - "modified": "2019-03-18T21:28:40.615Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/CSS/CSS_Positioning": { - "modified": "2019-03-23T22:16:58.595Z", - "contributors": [ - "ZZES_REN" - ] - }, - "Web/CSS/CSS_Properties_Reference": { - "modified": "2019-03-18T21:18:08.850Z", - "contributors": [ - "zhangchen" - ] - }, - "Web/CSS/CSS_Scroll_Snap": { - "modified": "2020-11-30T06:24:22.073Z", - "contributors": [ - "SphinxKnight", - "y-z-ui" - ] - }, - "Web/CSS/CSS_Scrollbars": { - "modified": "2020-10-15T22:16:38.483Z", - "contributors": [ - "kioyang" - ] - }, - "Web/CSS/CSS_Selectors": { - "modified": "2020-09-07T23:56:18.761Z", - "contributors": [ - "aaazz47", - "xgqfrms", - "RainSlide", - "williamjing", - "hjl19911127", - "mutoe", - "yuansuye", - "dream-in-night", - "Ende93", - "wh1msy", - "wy-ei" - ] - }, - "Web/CSS/CSS_Selectors/Comparison_with_XPath": { - "modified": "2019-03-18T21:23:06.866Z", - "contributors": [ - "zhanghengxin" - ] - }, - "Web/CSS/CSS_Shapes": { - "modified": "2019-07-30T22:05:51.456Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/CSS/CSS_Shapes/From_box_values": { - "modified": "2019-08-22T06:52:09.530Z", - "contributors": [ - "xunzhonglee" - ] - }, - "Web/CSS/CSS_Shapes/Overview_of_CSS_Shapes": { - "modified": "2020-03-21T05:15:07.734Z", - "contributors": [ - "linuxbckp" - ] - }, - "Web/CSS/CSS_Table": { - "modified": "2020-12-01T03:09:38.045Z", - "contributors": [ - "suvyme" - ] - }, - "Web/CSS/CSS_Text": { - "modified": "2020-09-16T00:45:53.626Z", - "contributors": [ - "namklaw", - "RainSlide", - "zjffun", - "LuXuanqing" - ] - }, - "Web/CSS/CSS_Text_Decoration": { - "modified": "2019-04-19T11:09:51.086Z", - "contributors": [ - "zjffun" - ] - }, - "Web/CSS/CSS_Transforms": { - "modified": "2019-09-28T03:26:55.908Z", - "contributors": [ - "CharCat", - "zhuangyin", - "Sebastianz", - "fscholz" - ] - }, - "Web/CSS/CSS_Transforms/Using_CSS_transforms": { - "modified": "2019-12-12T06:29:17.372Z", - "contributors": [ - "WangYiCong", - "RainSlide", - "zsxeee", - "kyriejoshua", - "funnyChinese", - "fscholz", - "troywith77", - "FredWe", - "ziyunfei", - "teoli", - "TimZhao", - "xcffl" - ] - }, - "Web/CSS/CSS_Transitions": { - "modified": "2019-03-23T22:44:13.456Z", - "contributors": [ - "MingxunBai", - "teoli" - ] - }, - "Web/CSS/CSS_Transitions/Using_CSS_transitions": { - "modified": "2019-09-29T00:37:10.013Z", - "contributors": [ - "SingularityXD", - "Venus14", - "tiansh", - "zhuangyin", - "ucev", - "xgqfrms-GitHub", - "brave-for-you", - "Ende93", - "SphinxKnight", - "fscholz", - "ziyunfei", - "yan" - ] - }, - "Web/CSS/CSS_Types": { - "modified": "2019-03-23T22:08:42.415Z", - "contributors": [ - "Ende93", - "h2x" - ] - }, - "Web/CSS/CSS_Values_and_Units": { - "modified": "2020-07-17T05:52:14.158Z", - "contributors": [ - "bdawn", - "Owen-Tsai" - ] - }, - "Web/CSS/CSS_Writing_Modes": { - "modified": "2019-08-24T07:12:47.677Z", - "contributors": [ - "xunzhonglee" - ] - }, - "Web/CSS/CSS_animated_properties": { - "modified": "2019-04-01T03:31:52.769Z", - "contributors": [ - "xgqfrms-GitHub", - "Sebastianz", - "teoli", - "ziyunfei", - "feiwen8772" - ] - }, - "Web/CSS/CSS_分片": { - "modified": "2019-12-03T13:06:14.108Z", - "contributors": [ - "pans9" - ] - }, - "Web/CSS/Cascade": { - "modified": "2020-04-12T01:15:48.713Z", - "contributors": [ - "laizenan", - "zjffun", - "Seize-cf", - "distums" - ] - }, - "Web/CSS/Child_combinator": { - "modified": "2019-03-23T23:32:26.113Z", - "contributors": [ - "ExE-Boss", - "fscholz", - "teoli", - "alimon" - ] - }, - "Web/CSS/Class_selectors": { - "modified": "2019-03-23T23:32:32.359Z", - "contributors": [ - "fscholz", - "teoli", - "alimon" - ] - }, - "Web/CSS/Column_combinator": { - "modified": "2020-10-15T22:20:12.960Z", - "contributors": [ - "karma2014", - "laguarage", - "woshisbb43" - ] - }, - "Web/CSS/Comments": { - "modified": "2020-06-11T09:14:45.384Z", - "contributors": [ - "Carllllo", - "m4jing", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/Common_CSS_Questions": { - "modified": "2020-07-16T22:25:46.153Z", - "contributors": [ - "Robinx", - "Jack-Q", - "ChenDong", - "DavidGuan", - "zd9027", - "xuxun", - "teoli", - "ziyunfei", - "xcffl" - ] - }, - "Web/CSS/Descendant_combinator": { - "modified": "2020-11-23T07:09:12.864Z", - "contributors": [ - "zhuangyin", - "ExE-Boss", - "RainSlide", - "fscholz", - "teoli", - "alimon" - ] - }, - "Web/CSS/General_sibling_combinator": { - "modified": "2020-10-15T21:22:20.373Z", - "contributors": [ - "Shiner", - "XiangHongAi", - "ExE-Boss", - "xlaoyu", - "fscholz", - "teoli", - "alimon" - ] - }, - "Web/CSS/ID_selectors": { - "modified": "2020-10-15T21:22:13.845Z", - "contributors": [ - "RainSlide", - "zhangqiangoffice", - "fscholz", - "teoli", - "alimon" - ] - }, - "Web/CSS/Inline_formatting_context": { - "modified": "2020-07-05T02:58:59.465Z", - "contributors": [ - "ylc395" - ] - }, - "Web/CSS/Layout_cookbook": { - "modified": "2020-11-06T10:41:23.256Z", - "contributors": [ - "Verahuan", - "9237074", - "SummerGua", - "creative_fish" - ] - }, - "Web/CSS/Layout_cookbook/Breadcrumb_Navigation": { - "modified": "2020-10-15T22:29:06.501Z", - "contributors": [ - "Mirai-explorer" - ] - }, - "Web/CSS/Layout_cookbook/Center_an_element": { - "modified": "2020-10-15T22:27:08.549Z", - "contributors": [ - "HareInWeed" - ] - }, - "Web/CSS/Layout_cookbook/Column_layouts": { - "modified": "2020-10-15T22:20:32.590Z", - "contributors": [ - "creative_fish" - ] - }, - "Web/CSS/Layout_cookbook/Contribute_a_recipe": { - "modified": "2020-04-13T12:50:05.549Z", - "contributors": [ - "Mirai-explorer" - ] - }, - "Web/CSS/Layout_cookbook/Split_Navigation": { - "modified": "2020-10-15T22:27:06.538Z", - "contributors": [ - "HareInWeed" - ] - }, - "Web/CSS/Layout_cookbook/卡片": { - "modified": "2020-10-15T22:28:29.154Z", - "contributors": [ - "fanyuedong" - ] - }, - "Web/CSS/Layout_cookbook/媒体对象": { - "modified": "2020-10-15T22:18:51.901Z", - "contributors": [ - "wre232114" - ] - }, - "Web/CSS/Layout_mode": { - "modified": "2019-03-23T22:27:53.945Z", - "contributors": [ - "wh1msy", - "xgqfrms-GitHub", - "xgqfrms" - ] - }, - "Web/CSS/Paged_Media": { - "modified": "2020-03-18T05:04:22.843Z", - "contributors": [ - "RainSlide", - "Princess_Knight" - ] - }, - "Web/CSS/Privacy_and_the_:visited_selector": { - "modified": "2019-03-23T23:07:40.024Z", - "contributors": [ - "tiansh", - "599316527" - ] - }, - "Web/CSS/Pseudo-classes": { - "modified": "2019-04-12T03:53:10.441Z", - "contributors": [ - "Soyaine", - "RainSlide", - "Ende93", - "xgqfrms-GitHub", - "teoli", - "alimon" - ] - }, - "Web/CSS/Pseudo-elements": { - "modified": "2019-04-06T09:41:11.172Z", - "contributors": [ - "RainSlide", - "StudentMain", - "anderson_liu", - "linyang4", - "nDos", - "xgqfrms-GitHub", - "lizhihua", - "FredWe", - "xiaowtz", - "Fadeoc", - "teoli", - "alimon" - ] - }, - "Web/CSS/Reference": { - "modified": "2020-06-18T20:37:42.635Z", - "contributors": [ - "zixuan945", - "mengli404", - "RainSlide", - "flowfire", - "codeofjackie", - "Idealist_EZ", - "Ende93", - "PaperFlu", - "zsxeee", - "PerlaHGL", - "0lightbee0", - "fygyx1", - "Go7hic", - "zhang-kai", - "zhyupe", - "kevinfszu", - "chliuqi", - "xiaolong", - "Breezewish", - "ziyunfei", - "teoli", - "anjianshi", - "Jimmie_Felidae", - "alimon", - "tregagnon", - "Mgjbot", - "TigerSoldier", - "Emcc", - "Mickeyboy" - ] - }, - "Web/CSS/Replaced_element": { - "modified": "2019-04-23T06:58:57.516Z", - "contributors": [ - "Lulu-Xue", - "pujiaxun", - "RainSlide", - "kevinfszu", - "peanut_tao", - "yaway" - ] - }, - "Web/CSS/Scaling_of_SVG_backgrounds": { - "modified": "2020-05-06T01:51:11.555Z", - "contributors": [ - "vvian00", - "rguanghui" - ] - }, - "Web/CSS/Selector_list": { - "modified": "2020-10-15T22:25:15.562Z", - "contributors": [ - "RainSlide", - "Cherrison" - ] - }, - "Web/CSS/Shorthand_properties": { - "modified": "2020-07-31T21:45:47.905Z", - "contributors": [ - "Ende93", - "vuji", - "fscholz", - "XingxianLI", - "anjia" - ] - }, - "Web/CSS/Specificity": { - "modified": "2020-10-31T01:29:03.940Z", - "contributors": [ - "syt-honey", - "Ninglo", - "imbant", - "laizenan", - "fzhyzamt", - "janyin", - "RainSlide", - "itibbers", - "Douglas_zx", - "sevenen", - "Ende93", - "ghostcode", - "NNNaix", - "xuxun", - "wengwengweng", - "xgqfrms-GitHub", - "tiansh", - "voidzhou", - "xgqfrms", - "kevinfszu", - "zhujun24", - "insekkei", - "ReyCG_sub", - "teoli", - "sleepholic", - "alimon" - ] - }, - "Web/CSS/Syntax": { - "modified": "2020-01-08T04:59:07.628Z", - "contributors": [ - "flowfire", - "sgzzy", - "Ende93", - "haofu", - "ReyCG_sub", - "teoli", - "yan" - ] - }, - "Web/CSS/Tools": { - "modified": "2019-03-23T22:29:45.280Z", - "contributors": [ - "runyul", - "pluwen", - "edwards1101", - "lucia007", - "lunix01" - ] - }, - "Web/CSS/Tutorials": { - "modified": "2019-03-23T23:32:32.218Z", - "contributors": [ - "teoli", - "jtyjty99999" - ] - }, - "Web/CSS/Type_selectors": { - "modified": "2019-03-23T23:32:35.434Z", - "contributors": [ - "funnyChinese", - "fscholz", - "teoli", - "alimon" - ] - }, - "Web/CSS/Universal_selectors": { - "modified": "2019-04-23T23:13:42.979Z", - "contributors": [ - "HomeLH", - "fscholz", - "xiaolong", - "iwillbe", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/Using_CSS_custom_properties": { - "modified": "2020-10-15T21:34:42.532Z", - "contributors": [ - "kingfree", - "MinimalistYing", - "TTtuntuntutu", - "chrisdavidmills", - "longhaiyan", - "xgqfrms-GitHub", - "Mark_Zhang", - "ObooChin", - "beyoursun", - "XGHeaven", - "ReyCG_sub" - ] - }, - "Web/CSS/Value_definition_syntax": { - "modified": "2020-03-13T13:15:23.549Z", - "contributors": [ - "AchooLuv", - "zjffun", - "wjp5826", - "Tankunpeng", - "Sebastianz", - "Guillaume-Heras", - "prayash", - "uolcano", - "ljwrer", - "teoli", - "Jimmie_Felidae" - ] - }, - "Web/CSS/Viewport_concepts": { - "modified": "2020-04-19T23:11:40.286Z", - "contributors": [ - "PerfectVirgo", - "244462375", - "Hew007", - "delbertbeta", - "kioyang" - ] - }, - "Web/CSS/WebKit_Extensions": { - "modified": "2019-03-24T00:17:24.198Z", - "contributors": [ - "ExE-Boss", - "ziyunfei", - "teoli", - "OoOoOoOo" - ] - }, - "Web/CSS/actual_value": { - "modified": "2019-03-23T22:33:27.273Z", - "contributors": [ - "ziyunfei", - "songpj", - "Soy" - ] - }, - "Web/CSS/align-content": { - "modified": "2020-10-15T21:34:12.754Z", - "contributors": [ - "liuruiqi1993", - "RainSlide", - "HayashiMei", - "CharCat", - "fbambi", - "Sandaydi", - "Tiny-Fendy", - "qLzhu", - "sqchenxiyuan", - "alphago", - "Ende93", - "dongyu_-_", - "holynewbie", - "fscholz", - "Sebastianz", - "FredWe", - "fskuok" - ] - }, - "Web/CSS/align-items": { - "modified": "2020-10-15T21:37:09.798Z", - "contributors": [ - "淡空醉花", - "HayashiMei", - "HuangXin", - "XuShunyi", - "zhuangyin", - "eliseguilian", - "Ende93", - "jiahui", - "nick-ChenZe", - "fscholz", - "Go7hic", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/align-self": { - "modified": "2020-10-15T21:37:32.750Z", - "contributors": [ - "淡空醉花", - "xiaoman", - "xiaokk06", - "RainSlide", - "HayashiMei", - "ThisIszas", - "yofine", - "fscholz", - "Go7hic", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/all": { - "modified": "2020-10-15T21:34:09.929Z", - "contributors": [ - "zhangchen", - "RainSlide", - "shuihuo", - "Sebastianz", - "fskuok" - ] - }, - "Web/CSS/angle": { - "modified": "2020-10-15T21:49:53.373Z", - "contributors": [ - "LZM", - "ZackBee", - "mozhs", - "zhichao" - ] - }, - "Web/CSS/angle-percentage": { - "modified": "2020-10-15T22:17:42.224Z", - "contributors": [ - "TrumanGu" - ] - }, - "Web/CSS/animation": { - "modified": "2020-10-15T21:26:29.276Z", - "contributors": [ - "zhaoshouxin", - "zjffun", - "Yayure", - "callmezhenzhen", - "ShirleyM", - "zhuangyin", - "xgqfrms-GitHub", - "mrstork", - "Ende93", - "teoli", - "Sebastianz", - "ziyunfei", - "fishenal" - ] - }, - "Web/CSS/animation-delay": { - "modified": "2020-10-15T21:34:12.178Z", - "contributors": [ - "HayashiMei", - "bibi941", - "wdpm", - "teoli", - "Sebastianz", - "fskuok" - ] - }, - "Web/CSS/animation-direction": { - "modified": "2020-10-15T21:26:25.868Z", - "contributors": [ - "HayashiMei", - "dongyu_-_", - "mimimic", - "teoli", - "Sebastianz", - "fishenal" - ] - }, - "Web/CSS/animation-duration": { - "modified": "2020-09-17T08:27:58.494Z", - "contributors": [ - "sclchic", - "teoli", - "Sebastianz", - "hutuxu" - ] - }, - "Web/CSS/animation-fill-mode": { - "modified": "2020-10-15T21:26:17.373Z", - "contributors": [ - "zjffun", - "teoli", - "Sebastianz", - "wy-ei", - "ziyunfei", - "fishenal" - ] - }, - "Web/CSS/animation-iteration-count": { - "modified": "2019-08-16T04:38:38.286Z", - "contributors": [ - "AlisaLiCn", - "SilenMark", - "seven-lh" - ] - }, - "Web/CSS/animation-name": { - "modified": "2019-06-21T05:37:24.111Z", - "contributors": [ - "chengkai", - "seeamong", - "zhuangyin", - "teoli", - "Sebastianz", - "hutuxu" - ] - }, - "Web/CSS/animation-play-state": { - "modified": "2020-07-13T06:32:25.611Z", - "contributors": [ - "Joker09", - "infinnie", - "lushen" - ] - }, - "Web/CSS/animation-timing-function": { - "modified": "2020-10-15T21:34:13.075Z", - "contributors": [ - "HayashiMei", - "zhuangyin", - "distums", - "mrstork", - "teoli", - "Sebastianz", - "fskuok" - ] - }, - "Web/CSS/appearance": { - "modified": "2020-10-15T21:50:06.957Z", - "contributors": [ - "ExE-Boss", - "RainSlide", - "xgqfrms-GitHub", - "ThomasSoloist" - ] - }, - "Web/CSS/aspect-ratio": { - "modified": "2020-10-30T10:24:33.576Z", - "contributors": [ - "jcplus" - ] - }, - "Web/CSS/attr()": { - "modified": "2020-11-04T08:52:10.558Z", - "contributors": [ - "chrisdavidmills", - "Mookiepiece", - "mrstork", - "prayash", - "duXing", - "cuixiping", - "teoli", - "Jimmie_Felidae" - ] - }, - "Web/CSS/backdrop-filter": { - "modified": "2020-10-15T22:06:19.969Z", - "contributors": [ - "RainSlide", - "lyz810" - ] - }, - "Web/CSS/backface-visibility": { - "modified": "2020-10-15T21:27:34.015Z", - "contributors": [ - "zjffun", - "broven", - "fscholz", - "Sebastianz", - "hutuxu" - ] - }, - "Web/CSS/background": { - "modified": "2020-10-15T21:12:34.014Z", - "contributors": [ - "Bob_Liu", - "tanapok", - "RainSlide", - "codevvvv9", - "Tankunpeng", - "kevinfszu", - "xwell", - "SphinxKnight", - "fscholz", - "Sebastianz", - "zldream1106", - "yan", - "ethertank", - "Yuichiro", - "Mgjbot", - "Steekid", - "Mickeyboy" - ] - }, - "Web/CSS/background-attachment": { - "modified": "2020-10-15T21:16:23.273Z", - "contributors": [ - "XiuYingLingFeng", - "zjffun", - "SphinxKnight", - "SamuraiMe", - "teoli", - "Sebastianz", - "fscholz", - "FredWe", - "TigerSoldier", - "Mickeyboy" - ] - }, - "Web/CSS/background-blend-mode": { - "modified": "2019-03-23T22:58:36.469Z", - "contributors": [ - "mrstork", - "Sebastianz", - "ziyunfei", - "fskuok" - ] - }, - "Web/CSS/background-clip": { - "modified": "2020-10-15T21:22:12.968Z", - "contributors": [ - "conorzhong", - "ZouYj", - "wjshean", - "ReggieLee", - "RainSlide", - "JiangTeng", - "1862", - "DPJune1", - "hiyangguo", - "SphinxKnight", - "teoli", - "Sebastianz", - "iplus26", - "yan" - ] - }, - "Web/CSS/background-color": { - "modified": "2019-09-03T10:56:38.354Z", - "contributors": [ - "litmonw", - "Sebastianz", - "xhlsrj", - "slientomorrr", - "SphinxKnight", - "teoli", - "fscholz", - "FredWe", - "Mickeyboy" - ] - }, - "Web/CSS/background-image": { - "modified": "2020-10-15T21:17:20.971Z", - "contributors": [ - "LARE", - "tanpopo", - "RainSlide", - "ssttii", - "marsorsun", - "xuxun", - "liwangft_tf", - "dche", - "Sebastianz", - "amghost", - "SphinxKnight", - "teoli", - "fscholz", - "FredWe", - "JeanLee", - "ziyunfei", - "Mickeyboy" - ] - }, - "Web/CSS/background-origin": { - "modified": "2019-09-04T03:33:45.849Z", - "contributors": [ - "zhuangshq", - "hgy9473", - "sss63232", - "Soyaine", - "fscholz", - "Sebastianz", - "FredWe", - "xiaoho" - ] - }, - "Web/CSS/background-position": { - "modified": "2020-10-15T21:16:21.352Z", - "contributors": [ - "bigbird231", - "daGaiGuanYu", - "zhangchen", - "Ceiba_Li", - "linyb", - "xgqfrms-GitHub", - "hgy9473", - "zhuangyin", - "zhangailing", - "HongxuWei", - "TomIsion", - "Sebastianz", - "Simplexible", - "mrstork", - "SphinxKnight", - "teoli", - "fscholz", - "hikarievo", - "FredWe", - "TigerSoldier", - "Mickeyboy" - ] - }, - "Web/CSS/background-position-x": { - "modified": "2020-10-15T21:52:12.312Z", - "contributors": [ - "maicss" - ] - }, - "Web/CSS/background-position-y": { - "modified": "2020-10-15T21:56:17.113Z", - "contributors": [ - "codeofjackie", - "AugustEchoStone" - ] - }, - "Web/CSS/background-repeat": { - "modified": "2020-10-15T21:16:19.803Z", - "contributors": [ - "zjffun", - "PythonVsJava", - "xgqfrms-GitHub", - "zhenhua32", - "SphinxKnight", - "teoli", - "TigerSoldier", - "Ianyang", - "Mickeyboy" - ] - }, - "Web/CSS/background-size": { - "modified": "2020-10-15T21:22:10.968Z", - "contributors": [ - "leverglowh", - "wolfdream080", - "StaicCai", - "maoyumaoxun", - "xiayao", - "DeadSoul", - "RunhuaXue", - "toldtoldcool", - "Ende93", - "fedwatch", - "Sebastianz", - "teoli", - "yan" - ] - }, - "Web/CSS/basic-shape": { - "modified": "2020-10-15T22:00:24.491Z", - "contributors": [ - "Mookiepiece", - "ScaredKitty" - ] - }, - "Web/CSS/blend-mode": { - "modified": "2020-10-15T21:52:17.089Z", - "contributors": [ - "RainSlide", - "ziyunfei", - "1986slayer" - ] - }, - "Web/CSS/block-size": { - "modified": "2020-10-15T22:16:46.814Z", - "contributors": [ - "Aamperor" - ] - }, - "Web/CSS/border": { - "modified": "2020-10-15T21:15:55.859Z", - "contributors": [ - "dlnb526", - "ssttii", - "VdoG", - "Sebastianz", - "fscholz", - "linmx0130", - "teoli", - "Zmylxb" - ] - }, - "Web/CSS/border-block": { - "modified": "2020-10-27T03:40:42.303Z", - "contributors": [ - "SphinxKnight", - "nxqlzhk" - ] - }, - "Web/CSS/border-block-end": { - "modified": "2020-10-15T22:12:06.538Z", - "contributors": [ - "avrinfly" - ] - }, - "Web/CSS/border-bottom": { - "modified": "2020-10-15T21:40:15.103Z", - "contributors": [ - "RainSlide", - "wbamberg", - "SolitudeRA" - ] - }, - "Web/CSS/border-bottom-color": { - "modified": "2019-03-23T22:36:23.158Z", - "contributors": [ - "xhlsrj" - ] - }, - "Web/CSS/border-bottom-left-radius": { - "modified": "2020-06-30T13:48:43.752Z", - "contributors": [ - "mdn_idealist", - "EveryC", - "luyouxin84" - ] - }, - "Web/CSS/border-bottom-right-radius": { - "modified": "2019-03-23T22:08:50.808Z", - "contributors": [ - "dzh" - ] - }, - "Web/CSS/border-bottom-style": { - "modified": "2019-03-23T22:07:06.056Z", - "contributors": [ - "CJWbiu" - ] - }, - "Web/CSS/border-bottom-width": { - "modified": "2020-10-15T22:00:36.171Z", - "contributors": [ - "Tamce" - ] - }, - "Web/CSS/border-collapse": { - "modified": "2020-10-15T21:40:09.855Z", - "contributors": [ - "RainSlide", - "wbamberg", - "HUO-Zhaoheng", - "xhlsrj", - "ziyunfei", - "sweetliu" - ] - }, - "Web/CSS/border-color": { - "modified": "2019-10-17T03:43:04.222Z", - "contributors": [ - "yzbas123", - "fragno", - "Sebastianz", - "Howard.Chen" - ] - }, - "Web/CSS/border-image": { - "modified": "2020-10-15T21:22:13.418Z", - "contributors": [ - "RoXoM", - "wanbei", - "xgqfrms-GitHub", - "Ende93", - "VdoG", - "teoli", - "Sebastianz", - "fskuok", - "yan" - ] - }, - "Web/CSS/border-image-outset": { - "modified": "2019-03-23T22:58:28.037Z", - "contributors": [ - "jdk137", - "Simplexible", - "Prinz_Rana", - "teoli", - "Sebastianz", - "fskuok" - ] - }, - "Web/CSS/border-image-repeat": { - "modified": "2019-03-23T23:32:24.337Z", - "contributors": [ - "yangxiaoqiao", - "teoli", - "Sebastianz", - "yan" - ] - }, - "Web/CSS/border-image-slice": { - "modified": "2020-10-15T21:54:34.521Z", - "contributors": [ - "oubinke", - "RoXoM", - "ShawnMichealBaker", - "sqchenxiyuan" - ] - }, - "Web/CSS/border-image-source": { - "modified": "2020-10-15T21:51:15.043Z", - "contributors": [ - "monkey-king", - "RoXoM", - "goblinZxc" - ] - }, - "Web/CSS/border-image-width": { - "modified": "2020-10-15T22:34:45.274Z", - "contributors": [ - "TrenlinHuang" - ] - }, - "Web/CSS/border-inline-color": { - "modified": "2020-10-15T22:33:03.476Z", - "contributors": [ - "Electronics" - ] - }, - "Web/CSS/border-left": { - "modified": "2019-03-23T22:08:44.943Z", - "contributors": [ - "Huooo" - ] - }, - "Web/CSS/border-left-color": { - "modified": "2020-10-15T22:00:38.609Z", - "contributors": [ - "Tamce" - ] - }, - "Web/CSS/border-left-style": { - "modified": "2020-10-15T22:02:34.648Z", - "contributors": [ - "catherinejing" - ] - }, - "Web/CSS/border-left-width": { - "modified": "2020-10-15T22:04:55.496Z", - "contributors": [ - "ZZES_REN" - ] - }, - "Web/CSS/border-radius": { - "modified": "2020-10-15T21:22:13.979Z", - "contributors": [ - "RainSlide", - "zhuangyin", - "Simplexible", - "Sebastianz", - "Prinz_Rana", - "Breezewish", - "xiaoho", - "teoli", - "yan" - ] - }, - "Web/CSS/border-right": { - "modified": "2019-03-23T22:08:44.488Z", - "contributors": [ - "Huooo" - ] - }, - "Web/CSS/border-right-color": { - "modified": "2020-10-15T22:10:25.194Z", - "contributors": [ - "javazsh" - ] - }, - "Web/CSS/border-right-style": { - "modified": "2020-10-15T22:08:48.922Z", - "contributors": [ - "Bob_Liu" - ] - }, - "Web/CSS/border-right-width": { - "modified": "2020-10-15T22:12:50.170Z", - "contributors": [ - "graybin" - ] - }, - "Web/CSS/border-spacing": { - "modified": "2019-06-18T01:24:16.700Z", - "contributors": [ - "Aaron-Bird", - "wbamberg", - "Sebastianz", - "xhlsrj", - "fscholz", - "FredWe" - ] - }, - "Web/CSS/border-style": { - "modified": "2020-10-15T21:31:41.486Z", - "contributors": [ - "Mookiepiece", - "liuzeyafzy", - "Sebastianz", - "Breezewish" - ] - }, - "Web/CSS/border-top": { - "modified": "2020-10-15T21:55:50.134Z", - "contributors": [ - "dlnb526", - "Huooo" - ] - }, - "Web/CSS/border-top-color": { - "modified": "2020-10-15T22:07:32.349Z", - "contributors": [ - "eeewl1250" - ] - }, - "Web/CSS/border-top-left-radius": { - "modified": "2019-01-16T21:53:03.397Z", - "contributors": [ - "liusw" - ] - }, - "Web/CSS/border-top-right-radius": { - "modified": "2019-03-23T23:03:23.652Z", - "contributors": [ - "Sebastianz", - "teoli", - "ziyunfei", - "finder" - ] - }, - "Web/CSS/border-top-style": { - "modified": "2020-10-15T22:15:15.802Z", - "contributors": [ - "LoveofRedMoon", - "fog3211", - "shawbena" - ] - }, - "Web/CSS/border-top-width": { - "modified": "2020-10-15T22:03:25.052Z", - "contributors": [ - "peppermintCode" - ] - }, - "Web/CSS/border-width": { - "modified": "2020-10-15T21:41:30.420Z", - "contributors": [ - "Mookiepiece", - "hechenggang", - "Sebastianz", - "uolcano" - ] - }, - "Web/CSS/bottom": { - "modified": "2020-10-15T21:41:13.711Z", - "contributors": [ - "Zhang-Junzhi", - "pinkroom", - "xupea", - "ohhyoung", - "yangjiayang222", - "mozhs", - "Sebastianz", - "Gavin_Yang" - ] - }, - "Web/CSS/box-decoration-break": { - "modified": "2020-10-15T22:31:12.535Z", - "contributors": [ - "Oliverz", - "阮若凡" - ] - }, - "Web/CSS/box-orient": { - "modified": "2020-10-15T22:17:32.483Z", - "contributors": [ - "litmonw", - "callmezhenzhen" - ] - }, - "Web/CSS/box-shadow": { - "modified": "2020-10-15T21:19:36.093Z", - "contributors": [ - "losT1995", - "huiye98", - "Louis-7", - "RainSlide", - "Ende93", - "Cirzear", - "PanClear", - "christopherxxshi", - "Azurak", - "xlgp", - "littleostar", - "HeyRaingirl", - "wky0615", - "XiaoLe", - "weiqinl", - "851091009", - "coolqiyu", - "ZhengYinBo", - "DecadeCode", - "Sebastianz", - "jwhitlock", - "sikaco", - "Prinz_Rana", - "teoli", - "FredWe", - "luomingzhong", - "yan", - "ethertank", - "guirong" - ] - }, - "Web/CSS/box-sizing": { - "modified": "2020-10-15T21:23:39.228Z", - "contributors": [ - "litmonw", - "ldc-37", - "xgqfrms", - "RainSlide", - "Soyaine", - "zhuangyin", - "MinimalistYing", - "ibufu", - "gaopu", - "xiazhe", - "xgqfrms-GitHub", - "2power10", - "Cattla", - "Fizco", - "feeldesignstudio.com", - "Sebastianz", - "wy-ei", - "guoyunhebrave", - "teoli", - "yan", - "damon" - ] - }, - "Web/CSS/break-after": { - "modified": "2020-10-15T21:53:35.128Z", - "contributors": [ - "RainSlide", - "garricke", - "xgqfrms-GitHub" - ] - }, - "Web/CSS/break-before": { - "modified": "2020-10-15T22:00:22.634Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/CSS/break-inside": { - "modified": "2020-10-15T21:54:57.296Z", - "contributors": [ - "bershanskiy", - "AngelName", - "RoXoM", - "SheltonDong" - ] - }, - "Web/CSS/calc()": { - "modified": "2020-11-04T09:08:38.821Z", - "contributors": [ - "chrisdavidmills", - "RainSlide", - "xunzhonglee", - "AnthonyWang", - "YWithT", - "LeonZou", - "JethroChiang", - "SphinxKnight", - "9aoyang", - "xgqfrms-GitHub", - "JohannLai", - "ihewro", - "jdk137", - "TiaossuP", - "Prinz_Rana", - "cuixiping", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/caption-side": { - "modified": "2020-10-15T22:00:44.246Z", - "contributors": [ - "RainSlide", - "trangles", - "alongite" - ] - }, - "Web/CSS/caret-color": { - "modified": "2020-10-15T21:55:42.268Z", - "contributors": [ - "hit1205", - "ziyunfei" - ] - }, - "Web/CSS/clamp()": { - "modified": "2020-11-05T09:58:52.297Z", - "contributors": [ - "chrisdavidmills", - "natee" - ] - }, - "Web/CSS/clear": { - "modified": "2020-10-15T21:29:32.788Z", - "contributors": [ - "XSun771", - "happyLiGoGo", - "Ende93", - "Bayes", - "luneice", - "xgqfrms-GitHub", - "yrk0556", - "Lingfighting", - "fscholz", - "Sebastianz", - "sartrey", - "Hey-Ray" - ] - }, - "Web/CSS/clip": { - "modified": "2019-03-23T23:29:44.055Z", - "contributors": [ - "Yelmor", - "mrstork", - "Sebastianz", - "teoli", - "sunnylost" - ] - }, - "Web/CSS/clip-path": { - "modified": "2020-10-15T21:50:48.819Z", - "contributors": [ - "Kingbultsea", - "ZouYj", - "xgqfrms", - "zhaoshouxin", - "RainSlide", - "AozakiOrenji", - "gaolil", - "xrr2016", - "Clark-Zhao", - "scplay", - "Jeffrey.Wang", - "smilewalker" - ] - }, - "Web/CSS/color": { - "modified": "2020-10-15T21:37:30.633Z", - "contributors": [ - "SolidBlock", - "Yang_Gia", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/color_value": { - "modified": "2020-10-15T21:36:48.886Z", - "contributors": [ - "SolidBlock", - "yangyun", - "Swordying", - "PYGC", - "redoc", - "xgqfrms-GitHub", - "Soyaine", - "xhlsrj", - "Sebastianz", - "liweimin", - "fscholz", - "KwenString", - "FredWe" - ] - }, - "Web/CSS/column-count": { - "modified": "2019-03-23T22:54:20.989Z", - "contributors": [ - "xgqfrms-GitHub", - "FuckingChestnut", - "Sebastianz", - "billcz", - "fscholz", - "FredWe" - ] - }, - "Web/CSS/column-fill": { - "modified": "2019-03-23T22:52:19.442Z", - "contributors": [ - "fscholz", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/column-gap": { - "modified": "2020-10-15T21:37:26.470Z", - "contributors": [ - "narol", - "Minya_Chan", - "billcz", - "fscholz", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/column-rule": { - "modified": "2020-10-11T05:38:08.650Z", - "contributors": [ - "淡空醉花", - "Dennis273", - "Sebastianz", - "fscholz", - "FredWe" - ] - }, - "Web/CSS/column-rule-color": { - "modified": "2019-03-23T22:52:25.809Z", - "contributors": [ - "Bayes", - "Sebastianz", - "fscholz", - "FredWe" - ] - }, - "Web/CSS/column-rule-style": { - "modified": "2019-03-23T22:52:25.404Z", - "contributors": [ - "Bayes", - "fscholz", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/column-rule-width": { - "modified": "2020-08-10T10:51:03.635Z", - "contributors": [ - "windqyoung", - "Bayes", - "Sebastianz", - "fscholz", - "FredWe" - ] - }, - "Web/CSS/column-span": { - "modified": "2019-03-23T22:54:23.106Z", - "contributors": [ - "lyqandy", - "DPJune1", - "fscholz", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/columns": { - "modified": "2020-10-15T21:36:49.737Z", - "contributors": [ - "fscholz", - "zjffun", - "Minya_Chan", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/computed_value": { - "modified": "2019-09-20T06:02:39.952Z", - "contributors": [ - "Michael-Zhang-Xian-Sen", - "luna666", - "DarrenZhang01", - "Ende93", - "xgqfrms-GitHub", - "Soyaine", - "haofu" - ] - }, - "Web/CSS/contain": { - "modified": "2020-10-23T17:48:25.808Z", - "contributors": [ - "RainSlide", - "淡空醉花", - "Yelmor", - "kmokidd", - "Gaohaoyang" - ] - }, - "Web/CSS/content": { - "modified": "2019-03-23T23:16:18.537Z", - "contributors": [ - "fengchunsgit", - "wbamberg", - "SphinxKnight", - "Go7hic", - "Sebastianz", - "NicoleRao", - "peanut_tao", - "ziyunfei", - "Darrel.Hsu" - ] - }, - "Web/CSS/counter()": { - "modified": "2020-11-09T07:18:40.908Z", - "contributors": [ - "chrisdavidmills", - "SphinxKnight", - "David-C0pperfield", - "sanxun515" - ] - }, - "Web/CSS/counter-increment": { - "modified": "2019-08-19T00:47:39.500Z", - "contributors": [ - "cheerylong", - "GitKou", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/counter-reset": { - "modified": "2020-10-15T21:37:30.285Z", - "contributors": [ - "RoXoM", - "cheerylong", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/counters()": { - "modified": "2020-11-09T07:19:47.276Z", - "contributors": [ - "chrisdavidmills", - "sanxun515" - ] - }, - "Web/CSS/cursor": { - "modified": "2020-10-15T21:22:03.463Z", - "contributors": [ - "淡空醉花", - "wallena3", - "Mookiepiece", - "wbamberg", - "fsx950223", - "BillgoXu", - "lizhonggang", - "xgqfrms-GitHub", - "cuilongjin", - "mrstork", - "Sebastianz", - "fskuok", - "teoli" - ] - }, - "Web/CSS/cursor/url": { - "modified": "2019-03-23T23:32:59.999Z", - "contributors": [ - "xgqfrms-GitHub", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/custom-ident": { - "modified": "2020-02-13T02:01:31.997Z", - "contributors": [ - "knightyun", - "lingziyu", - "greeneryhu" - ] - }, - "Web/CSS/dimension": { - "modified": "2020-10-15T22:16:57.387Z", - "contributors": [ - "StudentMain" - ] - }, - "Web/CSS/direction": { - "modified": "2020-10-15T22:16:11.539Z", - "contributors": [ - "fe.wuqian" - ] - }, - "Web/CSS/display": { - "modified": "2020-11-25T05:45:07.247Z", - "contributors": [ - "zhuangyin", - "bolu_gogoo", - "shangcode", - "Tindoc", - "junbin123", - "hhxxhg", - "yanabcd", - "cissoid", - "zhangchen", - "Bayes", - "DaySunx2", - "fanerge", - "Elviretoffoli", - "songwear", - "alphabet007", - "ddtyjmyjm", - "xgqfrms-GitHub", - "KrasnayaPloshchad", - "teoli", - "201341", - "lwxyfer", - "Sebastianz", - "FredWe", - "paddingme", - "valiantk", - "aaron4512", - "TigerSoldier" - ] - }, - "Web/CSS/display-box": { - "modified": "2020-10-15T22:26:55.789Z", - "contributors": [ - "frankzhang718" - ] - }, - "Web/CSS/display-internal": { - "modified": "2020-10-15T22:17:18.162Z", - "contributors": [ - "nuo2000" - ] - }, - "Web/CSS/display-legacy": { - "modified": "2020-10-15T22:16:15.339Z", - "contributors": [ - "btconfig" - ] - }, - "Web/CSS/display-outside": { - "modified": "2020-11-07T04:35:35.050Z", - "contributors": [ - "urusai-me" - ] - }, - "Web/CSS/easing-function": { - "modified": "2020-10-15T22:28:49.856Z", - "contributors": [ - "ran" - ] - }, - "Web/CSS/element()": { - "modified": "2020-11-10T11:07:35.733Z", - "contributors": [ - "chrisdavidmills", - "Witaya1978", - "RainSlide", - "wizAmit", - "cuixiping" - ] - }, - "Web/CSS/empty-cells": { - "modified": "2020-10-15T22:00:47.715Z", - "contributors": [ - "alongite" - ] - }, - "Web/CSS/env()": { - "modified": "2020-11-10T11:12:04.536Z", - "contributors": [ - "chrisdavidmills", - "Ocean-ZH" - ] - }, - "Web/CSS/filter": { - "modified": "2020-10-15T21:30:51.073Z", - "contributors": [ - "grape", - "zhangchen", - "lyz810", - "RoXoM", - "Jiang-Xuan", - "zhuangyin", - "xgqfrms", - "Sebastianz", - "lazurey", - "teoli", - "AzureRay", - "ziyunfei", - "lzf0402" - ] - }, - "Web/CSS/filter-function": { - "modified": "2019-03-18T21:39:39.661Z", - "contributors": [ - "lyz810", - "mfluehr" - ] - }, - "Web/CSS/filter-function/blur()": { - "modified": "2020-11-05T09:45:54.071Z", - "contributors": [ - "chrisdavidmills", - "qq2009", - "cheetooo" - ] - }, - "Web/CSS/filter-function/brightness()": { - "modified": "2020-11-05T09:57:28.957Z", - "contributors": [ - "chrisdavidmills", - "shirlay-Chang", - "cheetooo" - ] - }, - "Web/CSS/filter-function/contrast()": { - "modified": "2020-11-09T07:21:22.300Z", - "contributors": [ - "chrisdavidmills", - "shirlay-Chang" - ] - }, - "Web/CSS/filter-function/drop-shadow()": { - "modified": "2020-11-10T10:59:15.589Z", - "contributors": [ - "chrisdavidmills", - "HJrookie", - "deajax" - ] - }, - "Web/CSS/filter-function/grayscale()": { - "modified": "2020-11-10T11:21:16.375Z", - "contributors": [ - "chrisdavidmills", - "Longxi", - "MichealXie" - ] - }, - "Web/CSS/filter-function/opacity()": { - "modified": "2020-11-16T09:08:21.720Z", - "contributors": [ - "chrisdavidmills", - "Pedestrian93" - ] - }, - "Web/CSS/fit-content": { - "modified": "2020-10-15T22:25:14.593Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/CSS/flex": { - "modified": "2020-11-02T06:24:46.920Z", - "contributors": [ - "xgqfrms", - "webkb", - "zjffun", - "Soyaine", - "sccdluochao", - "weiqinl", - "xianshenglu", - "luckyYao", - "yufengjue", - "zhuangyin", - "zcWSR", - "SolitudeRA", - "Joyee", - "cizezsy", - "dongyu_-_", - "riversYeHaha", - "Sebastianz", - "fscholz", - "ranwu", - "lazurey", - "fskuok" - ] - }, - "Web/CSS/flex-basis": { - "modified": "2020-10-15T21:37:30.128Z", - "contributors": [ - "rollinhup", - "masterZSH", - "Hyphon", - "Ende93", - "KrisLee", - "AozakiOrenji", - "imgss", - "dongyu_-_", - "fscholz", - "BenFei", - "Go7hic", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/flex-direction": { - "modified": "2019-03-23T22:52:11.932Z", - "contributors": [ - "hackingzhang", - "zhuangyin", - "dongyu_-_", - "lxlzq11", - "zhaochangok", - "jingchenxu", - "fscholz", - "Go7hic", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/flex-flow": { - "modified": "2019-03-23T22:54:55.390Z", - "contributors": [ - "dongyu_-_", - "fscholz", - "Go7hic", - "Sebastianz", - "jianzhou520", - "f2ebill" - ] - }, - "Web/CSS/flex-grow": { - "modified": "2020-10-15T21:25:06.814Z", - "contributors": [ - "teaware", - "zhuguibiao", - "zhicongyang", - "dongyu_-_", - "Sebastianz", - "fscholz", - "fskuok", - "teoli", - "Ribery" - ] - }, - "Web/CSS/flex-shrink": { - "modified": "2019-03-23T22:53:05.874Z", - "contributors": [ - "Ende93", - "dongyu_-_", - "Sebastianz", - "fscholz", - "BenFei", - "Go7hic", - "FredWe" - ] - }, - "Web/CSS/flex-wrap": { - "modified": "2019-07-05T05:32:21.200Z", - "contributors": [ - "xgqfrms", - "SolitudeRA", - "JX-Master", - "dongyu_-_", - "lijim", - "fscholz", - "Go7hic", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/flex_value": { - "modified": "2020-10-15T21:58:42.376Z", - "contributors": [ - "fscholz", - "huasheng" - ] - }, - "Web/CSS/font": { - "modified": "2020-10-15T21:37:13.316Z", - "contributors": [ - "yangyun", - "zjffun", - "PythonVsJava", - "xhlsrj", - "fscholz", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/font-family": { - "modified": "2020-11-15T03:59:22.343Z", - "contributors": [ - "Felicity", - "FS-Luo", - "RainSlide", - "zxsunrise", - "blue0125", - "yuduxyz", - "fscholz", - "Sebastianz", - "iLeemo", - "linmx0130", - "FredWe" - ] - }, - "Web/CSS/font-feature-settings": { - "modified": "2020-10-15T22:00:50.177Z", - "contributors": [ - "Carllllo", - "zxsunrise", - "ljyf5593", - "yuyx91" - ] - }, - "Web/CSS/font-kerning": { - "modified": "2020-10-15T22:14:32.296Z", - "contributors": [ - "clark_liu", - "WangLeto" - ] - }, - "Web/CSS/font-language-override": { - "modified": "2020-10-15T22:30:35.406Z", - "contributors": [ - "benniks", - "dzy19", - "GeorgeMiao219" - ] - }, - "Web/CSS/font-size": { - "modified": "2019-04-29T02:45:12.346Z", - "contributors": [ - "ye125440", - "eeewl1250", - "xgqfrms-GitHub", - "Sebastianz", - "fscholz", - "AlexChao", - "fskuok" - ] - }, - "Web/CSS/font-size-adjust": { - "modified": "2019-03-23T22:58:28.499Z", - "contributors": [ - "wbamberg", - "fscholz", - "Sebastianz", - "fskuok" - ] - }, - "Web/CSS/font-smooth": { - "modified": "2019-03-23T23:25:47.948Z", - "contributors": [ - "teoli", - "zhangchen", - "hiyangguo", - "Fantasy_shao", - "xgqfrms", - "Wenbin" - ] - }, - "Web/CSS/font-stretch": { - "modified": "2019-03-23T22:16:13.390Z", - "contributors": [ - "gnepnaiL-oahZ", - "mozhs" - ] - }, - "Web/CSS/font-style": { - "modified": "2020-10-15T21:44:29.481Z", - "contributors": [ - "RainSlide", - "xhlsrj" - ] - }, - "Web/CSS/font-synthesis": { - "modified": "2020-10-15T22:22:32.457Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/CSS/font-variant": { - "modified": "2020-10-15T22:03:38.932Z", - "contributors": [ - "Carllllo", - "Lael" - ] - }, - "Web/CSS/font-variant-alternates": { - "modified": "2020-10-15T22:33:30.278Z", - "contributors": [ - "Mext" - ] - }, - "Web/CSS/font-variant-caps": { - "modified": "2020-10-15T22:20:47.141Z", - "contributors": [ - "CapriceLi" - ] - }, - "Web/CSS/font-variant-ligatures": { - "modified": "2020-11-26T05:42:25.721Z", - "contributors": [ - "cheetooo" - ] - }, - "Web/CSS/font-variant-numeric": { - "modified": "2020-11-24T00:06:10.318Z", - "contributors": [ - "snovey" - ] - }, - "Web/CSS/font-variant-position": { - "modified": "2020-10-15T22:24:51.623Z", - "contributors": [ - "LanShiLiang" - ] - }, - "Web/CSS/font-variation-settings": { - "modified": "2020-10-15T22:25:30.354Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/CSS/font-weight": { - "modified": "2020-10-15T21:37:06.874Z", - "contributors": [ - "infinnie", - "XiangHongAi", - "kaigeliao2018", - "xhlsrj", - "luzhe610", - "ghxin", - "SphinxKnight", - "fscholz", - "NaomiGeng", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/frequency": { - "modified": "2020-10-15T21:52:26.520Z", - "contributors": [ - "RainSlide", - "xgqfrms-GitHub" - ] - }, - "Web/CSS/gap": { - "modified": "2020-10-15T22:08:12.728Z", - "contributors": [ - "淡空醉花", - "zhangchen", - "narol" - ] - }, - "Web/CSS/gradient": { - "modified": "2019-03-23T22:52:09.991Z", - "contributors": [ - "ScaredKitty", - "Sebastianz", - "Quilljou", - "fscholz", - "sclchic" - ] - }, - "Web/CSS/grid": { - "modified": "2020-10-15T21:58:07.893Z", - "contributors": [ - "zhangchen", - "huasheng", - "BingqiChen" - ] - }, - "Web/CSS/grid-area": { - "modified": "2020-02-13T01:00:18.242Z", - "contributors": [ - "knightyun", - "L9m", - "huasheng" - ] - }, - "Web/CSS/grid-auto-columns": { - "modified": "2020-10-15T22:09:30.310Z", - "contributors": [ - "knightyun", - "Bayes" - ] - }, - "Web/CSS/grid-auto-flow": { - "modified": "2020-10-15T22:03:09.210Z", - "contributors": [ - "Ende93", - "RainSlide", - "Bayes", - "L9m" - ] - }, - "Web/CSS/grid-auto-rows": { - "modified": "2020-10-15T22:19:20.997Z", - "contributors": [ - "chentao106" - ] - }, - "Web/CSS/grid-column": { - "modified": "2020-10-15T22:23:34.678Z", - "contributors": [ - "MmmmHeee", - "billsmithgf", - "liminjun" - ] - }, - "Web/CSS/grid-row": { - "modified": "2020-10-15T22:27:14.412Z", - "contributors": [ - "knightyun" - ] - }, - "Web/CSS/grid-template": { - "modified": "2020-10-15T21:54:38.799Z", - "contributors": [ - "DFFZMXJ", - "zhangchen", - "xgqfrms-GitHub" - ] - }, - "Web/CSS/grid-template-areas": { - "modified": "2020-10-15T21:58:14.904Z", - "contributors": [ - "VacantThinker", - "RainSlide", - "TommyFu" - ] - }, - "Web/CSS/grid-template-columns": { - "modified": "2020-10-15T22:05:18.097Z", - "contributors": [ - "narol", - "Alone88" - ] - }, - "Web/CSS/hanging-punctuation": { - "modified": "2020-07-15T04:15:54.866Z", - "contributors": [ - "SphinxKnight", - "HashiKudo", - "catherinejing", - "LJJ1996" - ] - }, - "Web/CSS/height": { - "modified": "2020-10-15T21:25:05.161Z", - "contributors": [ - "riino", - "Ende93", - "yongchenyc", - "mozhs", - "NNNaix", - "QAQMiao", - "Sebastianz", - "SphinxKnight", - "teoli", - "yan" - ] - }, - "Web/CSS/hyphens": { - "modified": "2019-09-20T10:45:31.993Z", - "contributors": [ - "geallean", - "luobotang" - ] - }, - "Web/CSS/image": { - "modified": "2019-03-23T22:53:16.583Z", - "contributors": [ - "familyuu", - "mozhs", - "Sebastianz", - "mrstork", - "fscholz", - "ziyunfei", - "MoYuLing", - "vicvinc", - "FredWe" - ] - }, - "Web/CSS/image-orientation": { - "modified": "2020-10-15T21:24:56.385Z", - "contributors": [ - "fscholz", - "prayash", - "Sebastianz", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/image-rendering": { - "modified": "2020-10-15T21:44:11.450Z", - "contributors": [ - "RainSlide", - "Go7hic", - "L9m" - ] - }, - "Web/CSS/inherit": { - "modified": "2020-10-15T22:03:05.362Z", - "contributors": [ - "zhangchen", - "kongdanchen" - ] - }, - "Web/CSS/inheritance": { - "modified": "2020-05-20T07:33:19.452Z", - "contributors": [ - "AlenYing", - "laizenan", - "Mookiepiece", - "FickXu", - "mike-j", - "xiaahui", - "RainSlide", - "zhiquan_yu", - "kevinfszu", - "teoli", - "yan" - ] - }, - "Web/CSS/initial": { - "modified": "2020-10-15T21:59:31.745Z", - "contributors": [ - "zhangchen", - "beyondbycyx" - ] - }, - "Web/CSS/initial_value": { - "modified": "2020-08-17T11:00:04.470Z", - "contributors": [ - "Facefall", - "zhangchen", - "Ende93", - "teoli", - "anjianshi", - "alimon" - ] - }, - "Web/CSS/inline-size": { - "modified": "2020-10-15T22:26:53.209Z", - "contributors": [ - "Mookiepiece" - ] - }, - "Web/CSS/integer": { - "modified": "2019-09-04T12:55:55.655Z", - "contributors": [ - "xunzhonglee", - "ziyunfei", - "singi2016cn" - ] - }, - "Web/CSS/isolation": { - "modified": "2020-01-14T06:27:58.234Z", - "contributors": [ - "117sparta", - "mrstork", - "teoli", - "Sebastianz", - "fskuok" - ] - }, - "Web/CSS/justify-content": { - "modified": "2020-09-01T23:23:58.569Z", - "contributors": [ - "Thinker-z", - "Fancyflame", - "catlair", - "huangcheng", - "KeBaob", - "hutingting119", - "GShen", - "yong_a", - "vidahaha", - "archi__", - "zhuangyin", - "dongyu_-_", - "Ende93", - "jiahui", - "fscholz", - "Go7hic", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/justify-items": { - "modified": "2020-10-15T22:25:38.763Z", - "contributors": [ - "Hokori23", - "daibor" - ] - }, - "Web/CSS/justify-self": { - "modified": "2020-11-16T07:59:55.098Z", - "contributors": [ - "SDUTWSL" - ] - }, - "Web/CSS/left": { - "modified": "2020-10-15T21:49:54.700Z", - "contributors": [ - "Zhang-Junzhi", - "uniquexiaobai", - "Elity", - "zhangchen", - "xupea", - "1136863240", - "zhengxinxin" - ] - }, - "Web/CSS/length": { - "modified": "2020-11-07T12:34:52.744Z", - "contributors": [ - "sidWang", - "ezirmusitua", - "mdn_idealist", - "luolei", - "RainSlide", - "sabrinaluo", - "zhangchen", - "yijie_sun", - "gai871013", - "Phoebe-choi", - "WynnChen", - "fukaWestin", - "hiyangguo", - "_da", - "liyongleihf2006", - "Sebastianz", - "Serifx", - "zbinlin", - "feeldesignstudio.com", - "fscholz", - "ziyunfei", - "lttxzmj", - "sartrey", - "FredWe" - ] - }, - "Web/CSS/length-percentage": { - "modified": "2020-10-15T22:22:39.552Z", - "contributors": [ - "xunzhonglee" - ] - }, - "Web/CSS/letter-spacing": { - "modified": "2020-10-15T21:37:11.260Z", - "contributors": [ - "RainSlide", - "zy_2071", - "LJJ1996", - "Sebastianz", - "SphinxKnight", - "fscholz", - "Fadeoc", - "FredWe" - ] - }, - "Web/CSS/line-break": { - "modified": "2020-10-15T21:46:26.028Z", - "contributors": [ - "RainSlide", - "Ende93", - "zhangchen", - "zephyrer", - "luobotang" - ] - }, - "Web/CSS/line-height": { - "modified": "2020-10-15T21:32:56.594Z", - "contributors": [ - "RainSlide", - "yinzhiyizhi", - "zxsunrise", - "lujing2", - "wdpm", - "zhuangyin", - "coolqiyu", - "Alaleo", - "mozhs", - "web677", - "fa-ge", - "Sebastianz", - "noiron", - "FredWe", - "NicoleBear" - ] - }, - "Web/CSS/linear-gradient()": { - "modified": "2020-11-16T08:58:15.083Z", - "contributors": [ - "chrisdavidmills", - "PaddyWang", - "dxc111", - "KadirTopal", - "Dandelion-drq", - "forever_youyou", - "getatny", - "victorsonger", - "xianshenglu", - "offcos", - "ScaredKitty", - "kmokidd", - "DaiZhiTao", - "xgqfrms-GitHub", - "zhengxinxin", - "dongsuo", - "Sebastianz", - "hkfn123", - "jiahui", - "huangcheng", - "prayash", - "JohnnyYang", - "concefly", - "XiaoYi", - "kuangfan", - "wileam" - ] - }, - "Web/CSS/list-style": { - "modified": "2019-03-18T20:46:34.398Z", - "contributors": [ - "chenqingyue", - "SphinxKnight", - "Sebastianz", - "paddingme" - ] - }, - "Web/CSS/list-style-image": { - "modified": "2019-03-23T22:34:08.478Z", - "contributors": [ - "Laurensesss" - ] - }, - "Web/CSS/list-style-position": { - "modified": "2020-11-14T11:17:42.275Z", - "contributors": [ - "DingGuangbo", - "SphinxKnight", - "ranwu" - ] - }, - "Web/CSS/list-style-type": { - "modified": "2020-10-15T21:26:52.961Z", - "contributors": [ - "ziiyan", - "Ende93", - "liwangft_tf", - "SphinxKnight", - "ranwu", - "Sebastianz", - "teoli", - "guoyunhebrave" - ] - }, - "Web/CSS/margin": { - "modified": "2020-10-15T21:31:25.387Z", - "contributors": [ - "PaperFlu", - "joshchiucn", - "fanerge", - "tanshaobo", - "LuSitong", - "Sebastianz", - "SphinxKnight", - "fscholz", - "ComMouse", - "NIGHTEAGLE", - "carwestsam" - ] - }, - "Web/CSS/margin-block": { - "modified": "2020-10-15T22:13:44.517Z", - "contributors": [ - "avrinfly" - ] - }, - "Web/CSS/margin-block-start": { - "modified": "2020-10-15T22:09:58.357Z", - "contributors": [ - "haizhuling" - ] - }, - "Web/CSS/margin-bottom": { - "modified": "2019-03-23T22:35:35.268Z", - "contributors": [ - "laijunjie", - "coolqiyu", - "OlafCheng", - "Simplexible", - "Sebastianz", - "Prinz_Rana", - "johncido" - ] - }, - "Web/CSS/margin-left": { - "modified": "2019-03-18T20:34:35.706Z", - "contributors": [ - "victyyh", - "JustACodeGirl", - "daisyHawen", - "MidLinn" - ] - }, - "Web/CSS/margin-right": { - "modified": "2019-03-23T22:23:02.943Z", - "contributors": [ - "VictorDu", - "ChuckZhang" - ] - }, - "Web/CSS/margin-top": { - "modified": "2019-03-23T22:21:22.508Z", - "contributors": [ - "lijim" - ] - }, - "Web/CSS/mask": { - "modified": "2020-10-15T21:51:09.203Z", - "contributors": [ - "ZouYj", - "RainSlide", - "syshu", - "FE_dev", - "smilewalker" - ] - }, - "Web/CSS/mask-border": { - "modified": "2019-03-18T21:18:31.471Z", - "contributors": [ - "BingLee1994" - ] - }, - "Web/CSS/mask-border-mode": { - "modified": "2019-06-12T22:50:29.174Z", - "contributors": [ - "kangour", - "ragnar-document" - ] - }, - "Web/CSS/mask-border-repeat": { - "modified": "2019-06-12T22:48:51.074Z", - "contributors": [ - "kangour" - ] - }, - "Web/CSS/mask-border-slice": { - "modified": "2020-12-04T03:01:08.346Z", - "contributors": [ - "SphinxKnight", - "Jade-beads" - ] - }, - "Web/CSS/mask-border-width": { - "modified": "2019-03-26T04:03:28.139Z", - "contributors": [ - "luchao" - ] - }, - "Web/CSS/mask-image": { - "modified": "2020-04-28T23:32:28.192Z", - "contributors": [ - "nyz123", - "yatsov", - "luchao", - "sqhtiamo" - ] - }, - "Web/CSS/mask-mode": { - "modified": "2020-10-15T22:25:07.362Z", - "contributors": [ - "wjeek" - ] - }, - "Web/CSS/mask-repeat": { - "modified": "2020-10-15T21:51:09.262Z", - "contributors": [ - "RainSlide", - "smilewalker" - ] - }, - "Web/CSS/max()": { - "modified": "2020-11-16T09:03:04.400Z", - "contributors": [ - "chrisdavidmills", - "shugen002", - "webprogamar" - ] - }, - "Web/CSS/max-height": { - "modified": "2020-10-15T22:31:17.352Z", - "contributors": [ - "mdn_idealist" - ] - }, - "Web/CSS/max-width": { - "modified": "2019-03-23T22:51:11.243Z", - "contributors": [ - "kankk", - "Sebastianz", - "monsuns" - ] - }, - "Web/CSS/min()": { - "modified": "2020-11-16T09:04:41.929Z", - "contributors": [ - "chrisdavidmills", - "cinob", - "RogerShen" - ] - }, - "Web/CSS/min-height": { - "modified": "2020-10-19T04:58:30.402Z", - "contributors": [ - "aca14rh", - "tanapok", - "FreyaOne" - ] - }, - "Web/CSS/min-width": { - "modified": "2020-10-15T21:23:59.128Z", - "contributors": [ - "BayouBao", - "shhider", - "Sebastianz", - "hdming", - "teoli", - "sunnylost" - ] - }, - "Web/CSS/minmax()": { - "modified": "2020-11-16T09:06:57.403Z", - "contributors": [ - "chrisdavidmills", - "chentao106" - ] - }, - "Web/CSS/mix-blend-mode": { - "modified": "2020-10-15T21:37:38.925Z", - "contributors": [ - "sqchenxiyuan", - "shenxiang11", - "ExE-Boss", - "ClassicOldSong", - "mrstork", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/number": { - "modified": "2020-10-13T03:42:11.118Z", - "contributors": [ - "CyanCherry", - "ssttii", - "zhazhjie", - "Sebastianz", - "fscholz", - "fskuok" - ] - }, - "Web/CSS/object-fit": { - "modified": "2020-10-15T21:49:53.632Z", - "contributors": [ - "RainSlide", - "Ahhaha233", - "pujiaxun", - "n313893254", - "someblue", - "jingqianduan" - ] - }, - "Web/CSS/object-position": { - "modified": "2020-10-15T21:58:34.045Z", - "contributors": [ - "mailwwc", - "EthanW", - "RainSlide", - "Ahhaha233" - ] - }, - "Web/CSS/opacity": { - "modified": "2020-11-07T00:12:19.854Z", - "contributors": [ - "liguorain", - "CharCat", - "LuSitong", - "Sebastianz", - "zjsonic", - "SphinxKnight", - "FredWe" - ] - }, - "Web/CSS/order": { - "modified": "2019-05-15T04:32:30.587Z", - "contributors": [ - "dongyu_-_", - "dche", - "fscholz", - "Go7hic", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/outline": { - "modified": "2020-11-13T02:40:48.637Z", - "contributors": [ - "lins1105", - "conorzhong", - "Carllllo", - "zhengxinxin", - "broven", - "fscholz", - "Sebastianz", - "FredWe" - ] - }, - "Web/CSS/outline-color": { - "modified": "2020-10-15T22:07:00.554Z", - "contributors": [ - "hhxxhg" - ] - }, - "Web/CSS/outline-offset": { - "modified": "2019-05-22T11:15:45.877Z", - "contributors": [ - "merelydust", - "xgqfrms-GitHub" - ] - }, - "Web/CSS/outline-style": { - "modified": "2020-10-15T21:53:59.469Z", - "contributors": [ - "hhxxhg", - "Erdoszrf", - "xgqfrms-GitHub" - ] - }, - "Web/CSS/outline-width": { - "modified": "2020-10-15T22:23:11.714Z", - "contributors": [ - "HDC" - ] - }, - "Web/CSS/overflow": { - "modified": "2020-01-20T23:51:06.208Z", - "contributors": [ - "Cocoa", - "ntnyq", - "weiqinl", - "StaicCai", - "zhuangyin", - "VictorDu", - "xgqfrms-GitHub", - "everywill", - "Ende93", - "zhe13", - "yfdyh000", - "Sebastianz", - "fscholz", - "FredWe", - "teoli", - "TigerSoldier" - ] - }, - "Web/CSS/overflow-anchor": { - "modified": "2020-10-15T22:29:02.711Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/CSS/overflow-anchor/Guide_to_scroll_anchoring": { - "modified": "2020-12-03T07:08:34.545Z", - "contributors": [ - "Da-Fei-total" - ] - }, - "Web/CSS/overflow-block": { - "modified": "2020-10-15T22:33:25.455Z", - "contributors": [ - "MarkShawn2020" - ] - }, - "Web/CSS/overflow-x": { - "modified": "2020-10-15T21:24:21.061Z", - "contributors": [ - "sukka", - "Sebastianz", - "teoli", - "Jimmie_Felidae" - ] - }, - "Web/CSS/overflow-y": { - "modified": "2020-05-30T07:59:13.148Z", - "contributors": [ - "bytetown", - "VacantThinker", - "Sebastianz", - "teoli", - "Jimmie_Felidae" - ] - }, - "Web/CSS/overscroll-behavior": { - "modified": "2020-10-15T22:04:14.564Z", - "contributors": [ - "PaulHan", - "changwei", - "WangLeto", - "JanWing1995" - ] - }, - "Web/CSS/overscroll-behavior-x": { - "modified": "2020-10-15T22:18:49.252Z", - "contributors": [ - "boxu-zhang" - ] - }, - "Web/CSS/overscroll-behavior-y": { - "modified": "2020-10-15T22:25:04.290Z", - "contributors": [ - "fsxitutu" - ] - }, - "Web/CSS/padding": { - "modified": "2020-10-15T21:37:13.722Z", - "contributors": [ - "PaperFlu", - "rxliuli", - "ZZES_REN", - "Jiasm", - "PattyChen", - "liuyidi", - "xgqfrms", - "Sebastianz", - "fscholz", - "teoli", - "FredWe" - ] - }, - "Web/CSS/padding-bottom": { - "modified": "2019-03-23T22:08:45.109Z", - "contributors": [ - "Huooo" - ] - }, - "Web/CSS/padding-inline-start": { - "modified": "2019-03-23T22:24:26.412Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/CSS/padding-left": { - "modified": "2020-10-30T10:10:04.473Z", - "contributors": [ - "imyMuyang" - ] - }, - "Web/CSS/padding-right": { - "modified": "2019-03-23T22:08:46.043Z", - "contributors": [ - "Huooo" - ] - }, - "Web/CSS/padding-top": { - "modified": "2019-03-18T20:45:40.154Z", - "contributors": [ - "WangLeto", - "uestcNaldo", - "Huooo" - ] - }, - "Web/CSS/page-break-after": { - "modified": "2020-06-16T04:33:57.554Z", - "contributors": [ - "wangxu", - "xgqfrms-GitHub" - ] - }, - "Web/CSS/page-break-inside": { - "modified": "2020-10-15T22:00:22.695Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/CSS/paint-order": { - "modified": "2020-10-15T22:10:30.071Z", - "contributors": [ - "guoguangkun" - ] - }, - "Web/CSS/percentage": { - "modified": "2020-10-15T21:36:50.696Z", - "contributors": [ - "StudentMain", - "yangmei123", - "RainSlide", - "The-End-Hero", - "xhlsrj", - "mrstork", - "fscholz", - "FredWe" - ] - }, - "Web/CSS/perspective": { - "modified": "2020-10-15T21:25:04.557Z", - "contributors": [ - "1259364843", - "hardo", - "zjffun", - "Sebastianz", - "Ende93", - "fscholz", - "FredWe", - "teoli", - "hutuxu", - "luommingzhong" - ] - }, - "Web/CSS/perspective-origin": { - "modified": "2020-10-15T21:27:26.630Z", - "contributors": [ - "zjffun", - "Sebastianz", - "fscholz", - "FredWe", - "hutuxu" - ] - }, - "Web/CSS/place-content": { - "modified": "2020-10-15T22:24:19.967Z", - "contributors": [ - "chrimer", - "yunng" - ] - }, - "Web/CSS/place-items": { - "modified": "2020-10-15T22:32:41.625Z", - "contributors": [ - "natee" - ] - }, - "Web/CSS/pointer-events": { - "modified": "2020-10-15T21:26:15.711Z", - "contributors": [ - "Jeff.w", - "shhider", - "jinyaoo86", - "zhangchen", - "xgqfrms-GitHub", - "holynewbie", - "ruoyiqing", - "teoli", - "hutuxu" - ] - }, - "Web/CSS/position": { - "modified": "2020-10-15T21:16:00.419Z", - "contributors": [ - "mdn_idealist", - "jaredhan418", - "keisei77", - "YouMoeYi", - "msy", - "keizure", - "iTrustGuid", - "Bayes", - "momopig", - "rikochyou", - "zhangchen", - "KokoTa", - "andrewwan", - "GHLandy", - "JohannLai", - "ZackBee", - "coolguy", - "xgqfrms-GitHub", - "pengtikui", - "hackingzhang", - "TidePeng", - "doodlewind", - "kkxujq", - "StoneYao", - "evisong", - "OnlyLasia", - "Gavin_Yang", - "fscholz", - "JoeZhou", - "Sebastianz", - "charlie", - "FredWe", - "ziyunfei", - "teoli", - "TigerSoldier" - ] - }, - "Web/CSS/position_value": { - "modified": "2019-03-23T22:53:52.651Z", - "contributors": [ - "xhlsrj", - "xgqfrms-GitHub", - "mrstork", - "fscholz", - "zhujun24" - ] - }, - "Web/CSS/quotes": { - "modified": "2020-10-15T22:18:29.221Z", - "contributors": [ - "RoXoM", - "silkwromzf" - ] - }, - "Web/CSS/radial-gradient()": { - "modified": "2020-11-29T05:12:03.962Z", - "contributors": [ - "KaiserZh", - "chrisdavidmills", - "Ende93", - "HeyRaingirl", - "xgqfrms-GitHub", - "zhengxinxin", - "Sebastianz", - "mrstork", - "concefly", - "lyxuncle", - "jiereal" - ] - }, - "Web/CSS/ratio": { - "modified": "2020-10-15T22:08:11.112Z", - "contributors": [ - "YouHeng", - "The-great-Lord", - "SphinxKnight", - "BKHK" - ] - }, - "Web/CSS/repeat()": { - "modified": "2020-11-18T14:44:47.276Z", - "contributors": [ - "chrisdavidmills", - "JC-Ge", - "xgqfrms" - ] - }, - "Web/CSS/repeating-linear-gradient()": { - "modified": "2020-11-18T14:46:37.002Z", - "contributors": [ - "chrisdavidmills", - "royIdoodle", - "zway", - "zhuangyin", - "Sebastianz", - "prayash", - "littleXiaosi" - ] - }, - "Web/CSS/repeating-radial-gradient()": { - "modified": "2020-11-18T14:47:47.109Z", - "contributors": [ - "chrisdavidmills", - "royIdoodle", - "zway" - ] - }, - "Web/CSS/resize": { - "modified": "2019-03-23T22:21:07.833Z", - "contributors": [ - "xgqfrms-GitHub", - "LuXuanqing" - ] - }, - "Web/CSS/resolution": { - "modified": "2020-10-15T22:19:42.217Z", - "contributors": [ - "loveloki", - "jason-guo" - ] - }, - "Web/CSS/resolved_value": { - "modified": "2019-03-23T22:19:11.781Z", - "contributors": [ - "Go7hic" - ] - }, - "Web/CSS/right": { - "modified": "2020-10-15T21:41:28.939Z", - "contributors": [ - "Zhang-Junzhi", - "codevvvv9", - "xupea", - "Sebastianz", - "omega4github" - ] - }, - "Web/CSS/rotate": { - "modified": "2020-11-12T04:21:26.220Z", - "contributors": [ - "yisibl", - "xrr2016", - "lppking" - ] - }, - "Web/CSS/row-gap": { - "modified": "2020-10-15T22:08:22.925Z", - "contributors": [ - "narol" - ] - }, - "Web/CSS/scale": { - "modified": "2020-10-15T22:11:31.472Z", - "contributors": [ - "RainSlide", - "GoromitLeo", - "Zoey" - ] - }, - "Web/CSS/scroll-behavior": { - "modified": "2020-10-15T21:50:40.323Z", - "contributors": [ - "RainSlide", - "Pada", - "lunix01" - ] - }, - "Web/CSS/scroll-margin": { - "modified": "2020-10-15T22:22:51.470Z", - "contributors": [ - "demongodYY", - "srq18211" - ] - }, - "Web/CSS/scroll-margin-top": { - "modified": "2020-11-27T01:35:52.693Z", - "contributors": [ - "EryouHao" - ] - }, - "Web/CSS/scroll-snap-coordinate": { - "modified": "2019-01-16T21:50:21.410Z", - "contributors": [ - "rockywen" - ] - }, - "Web/CSS/scroll-snap-destination": { - "modified": "2019-03-23T22:42:44.523Z", - "contributors": [ - "rockywen" - ] - }, - "Web/CSS/scroll-snap-points-x": { - "modified": "2019-03-23T22:42:35.765Z", - "contributors": [ - "rockywen" - ] - }, - "Web/CSS/scroll-snap-points-y": { - "modified": "2019-03-23T22:42:33.911Z", - "contributors": [ - "rockywen" - ] - }, - "Web/CSS/scroll-snap-type": { - "modified": "2020-10-15T21:40:51.208Z", - "contributors": [ - "suyanhanx", - "RoXoM", - "rockywen" - ] - }, - "Web/CSS/scrollbar-color": { - "modified": "2020-10-28T05:53:46.146Z", - "contributors": [ - "SDUTWSL", - "Johnny-yellowboy" - ] - }, - "Web/CSS/scrollbar-width": { - "modified": "2020-10-15T22:21:53.614Z", - "contributors": [ - "luxin88" - ] - }, - "Web/CSS/shape-image-threshold": { - "modified": "2020-10-15T22:27:34.354Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/CSS/shape-margin": { - "modified": "2020-10-15T22:27:34.408Z", - "contributors": [ - "Carllllo" - ] - }, - "Web/CSS/shape-outside": { - "modified": "2020-10-15T21:58:42.005Z", - "contributors": [ - "superadmin", - "zhangchen", - "xgqfrms-GitHub", - "Ahhaha233" - ] - }, - "Web/CSS/specified_value": { - "modified": "2019-03-23T23:23:58.697Z", - "contributors": [ - "seiry", - "teoli", - "anjianshi" - ] - }, - "Web/CSS/string": { - "modified": "2019-03-18T21:46:27.858Z", - "contributors": [ - "LiuYuan" - ] - }, - "Web/CSS/tab-size": { - "modified": "2020-10-15T21:46:28.486Z", - "contributors": [ - "RainSlide", - "Sebastianz", - "luobotang" - ] - }, - "Web/CSS/table-layout": { - "modified": "2020-10-15T21:39:24.700Z", - "contributors": [ - "Wulakaka", - "Jack.Works", - "xgqfrms-GitHub", - "Serifx" - ] - }, - "Web/CSS/text-align": { - "modified": "2020-08-11T23:14:09.267Z", - "contributors": [ - "niices", - "wbamberg", - "WhiteYin", - "zhuangyin", - "Guillaume-Heras", - "Sebastianz", - "fscholz", - "FredWe", - "fskuok", - "ziyunfei" - ] - }, - "Web/CSS/text-align-last": { - "modified": "2020-10-15T21:56:50.948Z", - "contributors": [ - "AchooLuv", - "Miss-violet" - ] - }, - "Web/CSS/text-decoration": { - "modified": "2020-10-15T21:35:29.312Z", - "contributors": [ - "Zshining", - "molly", - "Mookiepiece", - "liyuhang1997", - "The-End-Hero", - "SunGuona", - "fscholz", - "Sebastianz", - "ziyunfei", - "Deguang" - ] - }, - "Web/CSS/text-decoration-color": { - "modified": "2020-10-15T22:00:19.428Z", - "contributors": [ - "RainSlide", - "comehope" - ] - }, - "Web/CSS/text-decoration-line": { - "modified": "2020-10-15T22:00:17.031Z", - "contributors": [ - "comehope" - ] - }, - "Web/CSS/text-decoration-skip": { - "modified": "2020-10-15T22:05:17.788Z", - "contributors": [ - "allen0815" - ] - }, - "Web/CSS/text-decoration-style": { - "modified": "2020-10-15T22:00:19.174Z", - "contributors": [ - "Ende93", - "comehope" - ] - }, - "Web/CSS/text-indent": { - "modified": "2020-10-15T21:22:18.269Z", - "contributors": [ - "Mookiepiece", - "helloyong", - "liyuhang1997", - "Sebastianz", - "fscholz", - "shuaiyunzhang", - "teoli", - "sunorry" - ] - }, - "Web/CSS/text-justify": { - "modified": "2020-10-22T00:21:44.611Z", - "contributors": [ - "baiheng", - "zxsunrise", - "Miss-violet" - ] - }, - "Web/CSS/text-orientation": { - "modified": "2020-10-15T22:35:18.905Z", - "contributors": [ - "SphinxKnight", - "SDUTWSL" - ] - }, - "Web/CSS/text-overflow": { - "modified": "2020-08-08T07:20:32.903Z", - "contributors": [ - "litmonw", - "zjffun", - "AC-greener", - "xiaokk06", - "Lynn0108", - "xgqfrms-GitHub", - "ws69", - "Guillaume-Heras", - "Sebastianz", - "zilong-thu", - "FredWe" - ] - }, - "Web/CSS/text-rendering": { - "modified": "2019-03-23T23:28:52.791Z", - "contributors": [ - "billcz", - "wenshin", - "relaxgo", - "xgqfrms", - "fscholz", - "teoli", - "fakefish" - ] - }, - "Web/CSS/text-shadow": { - "modified": "2020-10-15T21:22:12.615Z", - "contributors": [ - "tfcx-th", - "yang-r", - "zhangchen", - "zhengxinxin", - "Sebastianz", - "kevinfszu", - "FredWe", - "teoli", - "yan" - ] - }, - "Web/CSS/text-size-adjust": { - "modified": "2020-10-15T21:53:18.468Z", - "contributors": [ - "RainSlide", - "scplay", - "thomaslwq", - "Kongwsh" - ] - }, - "Web/CSS/text-transform": { - "modified": "2019-10-10T16:36:19.881Z", - "contributors": [ - "Bayes", - "cenyoujin", - "xgqfrms-GitHub", - "ziyunfei", - "Hbjswj" - ] - }, - "Web/CSS/text-underline-position": { - "modified": "2020-10-15T22:04:29.701Z", - "contributors": [ - "zxsunrise", - "maoyumaoxun" - ] - }, - "Web/CSS/time": { - "modified": "2020-10-15T21:58:38.356Z", - "contributors": [ - "zhangchen", - "huasheng" - ] - }, - "Web/CSS/time-percentage": { - "modified": "2020-10-15T22:19:41.820Z", - "contributors": [ - "jason-guo" - ] - }, - "Web/CSS/timing-function": { - "modified": "2020-10-15T21:21:10.131Z", - "contributors": [ - "tzgong", - "WangYiCong", - "woshixixi", - "wqq1992324", - "zhangchen", - "Huahua-Chen", - "Sebastianz", - "jiahui", - "fscholz", - "cungen", - "teoli", - "ziyunfei" - ] - }, - "Web/CSS/top": { - "modified": "2020-10-15T21:37:12.500Z", - "contributors": [ - "btea", - "HuangXin", - "Zhang-Junzhi", - "xupea", - "superkuang", - "Sebastianz", - "fscholz", - "FredWe" - ] - }, - "Web/CSS/touch-action": { - "modified": "2020-10-15T21:39:05.097Z", - "contributors": [ - "xgqfrms", - "linxiaodong0538", - "RoXoM", - "Katherina-Miao", - "Ende93", - "teoli", - "TooBug" - ] - }, - "Web/CSS/transform": { - "modified": "2020-10-15T21:04:54.257Z", - "contributors": [ - "cracdic", - "zhuangyin", - "zhangchen", - "futurefeeling", - "zsxeee", - "codedrinker", - "xgqfrms-GitHub", - "zhengxinxin", - "Sebastianz", - "kevinfszu", - "FredWe", - "teoli", - "ethertank", - "lmorchard", - "OoOoOoOo", - "leeli" - ] - }, - "Web/CSS/transform-box": { - "modified": "2019-06-13T02:11:00.164Z", - "contributors": [ - "yangnaiyue", - "WarriorWu" - ] - }, - "Web/CSS/transform-function": { - "modified": "2020-02-27T11:59:15.845Z", - "contributors": [ - "skywalker_z", - "baylin87", - "lbwa", - "Miss-violet", - "Ende93", - "LeoEatle", - "xgqfrms-GitHub", - "leafdog", - "lijim", - "mrstork", - "prayash", - "FredWe" - ] - }, - "Web/CSS/transform-function/matrix()": { - "modified": "2020-11-16T09:00:25.677Z", - "contributors": [ - "chrisdavidmills", - "wc5858", - "mdn_idealist", - "Sinosaurus", - "zsirfs", - "Kujoto", - "mrstork", - "tonnylyz" - ] - }, - "Web/CSS/transform-function/matrix3d()": { - "modified": "2020-11-16T09:01:45.264Z", - "contributors": [ - "chrisdavidmills", - "mdn_idealist" - ] - }, - "Web/CSS/transform-function/perspective()": { - "modified": "2020-11-16T09:11:13.696Z", - "contributors": [ - "chrisdavidmills", - "eeeeeeeason" - ] - }, - "Web/CSS/transform-function/rotate()": { - "modified": "2020-11-19T16:06:30.046Z", - "contributors": [ - "chrisdavidmills", - "fish-inu", - "zhangchen", - "DaiZhiTao", - "FlowingRiver" - ] - }, - "Web/CSS/transform-function/rotate3d()": { - "modified": "2020-11-19T16:07:52.729Z", - "contributors": [ - "chrisdavidmills", - "hardo", - "AngelName", - "zhangchen", - "AozakiOrenji", - "xgqfrms-GitHub", - "Serifx" - ] - }, - "Web/CSS/transform-function/rotateX()": { - "modified": "2020-11-19T16:09:23.631Z", - "contributors": [ - "chrisdavidmills", - "CharCat" - ] - }, - "Web/CSS/transform-function/rotateY()": { - "modified": "2020-11-19T16:10:17.879Z", - "contributors": [ - "chrisdavidmills", - "CharCat" - ] - }, - "Web/CSS/transform-function/rotateZ()": { - "modified": "2020-11-30T10:07:54.353Z", - "contributors": [ - "chrisdavidmills", - "CharCat" - ] - }, - "Web/CSS/transform-function/scale()": { - "modified": "2020-11-30T10:16:03.265Z", - "contributors": [ - "chrisdavidmills", - "Chaslee", - "Jack-Q" - ] - }, - "Web/CSS/transform-function/scaleX()": { - "modified": "2020-11-30T10:21:00.840Z", - "contributors": [ - "chrisdavidmills", - "xgqfrms-GitHub" - ] - }, - "Web/CSS/transform-function/scaleY()": { - "modified": "2020-11-30T10:22:06.571Z", - "contributors": [ - "chrisdavidmills", - "xgqfrms" - ] - }, - "Web/CSS/transform-function/skew()": { - "modified": "2020-11-30T10:26:15.757Z", - "contributors": [ - "chrisdavidmills", - "CharCat", - "HuangXin", - "fr1ee" - ] - }, - "Web/CSS/transform-function/skewX()": { - "modified": "2020-11-30T10:27:30.549Z", - "contributors": [ - "chrisdavidmills", - "CharCat" - ] - }, - "Web/CSS/transform-function/skewY()": { - "modified": "2020-11-30T10:28:32.252Z", - "contributors": [ - "chrisdavidmills", - "CharCat", - "Kuichen" - ] - }, - "Web/CSS/transform-function/translate()": { - "modified": "2020-11-30T10:30:52.319Z", - "contributors": [ - "chrisdavidmills", - "jiang-hr" - ] - }, - "Web/CSS/transform-function/translate3d()": { - "modified": "2020-11-30T12:59:28.646Z", - "contributors": [ - "chrisdavidmills", - "codeyu", - "litmonw", - "pluwen", - "kino0o", - "zxk7516" - ] - }, - "Web/CSS/transform-function/translateX": { - "modified": "2019-10-06T06:39:48.638Z", - "contributors": [ - "LexieAlreadyTaken", - "lanesky", - "Vimo" - ] - }, - "Web/CSS/transform-function/translateY()": { - "modified": "2020-11-30T13:01:20.573Z", - "contributors": [ - "chrisdavidmills", - "fish-inu", - "LangDonHJJ" - ] - }, - "Web/CSS/transform-origin": { - "modified": "2020-10-15T21:34:19.804Z", - "contributors": [ - "Niefee", - "xiangle", - "zhangchen", - "Simplexible", - "Sebastianz", - "Prinz_Rana", - "fscholz", - "FredWe", - "fskuok" - ] - }, - "Web/CSS/transform-style": { - "modified": "2020-10-15T21:27:25.289Z", - "contributors": [ - "zjffun", - "zhuangyin", - "Jiasm", - "fscholz", - "Sebastianz", - "FredWe", - "hutuxu" - ] - }, - "Web/CSS/transition": { - "modified": "2020-10-15T21:22:27.680Z", - "contributors": [ - "zjffun", - "zhangchen", - "parabolazz", - "fengchunsgit", - "lingziyu", - "zhuangyin", - "RoXoM", - "codedrinker", - "ucev", - "xgqfrms-GitHub", - "DrakeXiang", - "kevinfszu", - "fscholz", - "Sebastianz", - "teoli", - "yan" - ] - }, - "Web/CSS/transition-delay": { - "modified": "2019-03-23T22:44:46.901Z", - "contributors": [ - "xiaoyueyue", - "byr-gdp" - ] - }, - "Web/CSS/transition-duration": { - "modified": "2019-03-23T22:38:53.651Z", - "contributors": [ - "jiahui", - "mrstork", - "luneice" - ] - }, - "Web/CSS/transition-property": { - "modified": "2019-03-23T22:32:24.273Z", - "contributors": [ - "jiahui" - ] - }, - "Web/CSS/transition-timing-function": { - "modified": "2019-05-31T06:03:55.883Z", - "contributors": [ - "mrstork", - "fscholz", - "teoli", - "jtyjty99999" - ] - }, - "Web/CSS/translate": { - "modified": "2020-10-15T22:07:45.438Z", - "contributors": [ - "Carllllo", - "Bayes" - ] - }, - "Web/CSS/unicode-bidi": { - "modified": "2020-10-15T22:00:46.664Z", - "contributors": [ - "RainSlide", - "anjia" - ] - }, - "Web/CSS/unset": { - "modified": "2020-10-15T21:48:47.329Z", - "contributors": [ - "FS-Luo", - "zhangchen", - "luna666", - "FE_dev", - "willard", - "LiNengNeng" - ] - }, - "Web/CSS/url": { - "modified": "2019-03-23T22:25:44.664Z", - "contributors": [ - "zhyupe" - ] - }, - "Web/CSS/used_value": { - "modified": "2019-03-23T23:29:45.690Z", - "contributors": [ - "gujunmin", - "teoli", - "yan" - ] - }, - "Web/CSS/user-select": { - "modified": "2020-10-15T21:24:21.697Z", - "contributors": [ - "RainSlide", - "xgqfrms", - "yipanhuasheng", - "wbamberg", - "xlaoyu", - "SamuraiMe", - "Sheppy", - "teoli", - "MrFish" - ] - }, - "Web/CSS/var()": { - "modified": "2020-11-04T09:10:48.035Z", - "contributors": [ - "chrisdavidmills", - "RoXoM", - "AnnAngela", - "xgqfrms-GitHub", - "hiyangguo" - ] - }, - "Web/CSS/vertical-align": { - "modified": "2020-10-15T21:21:34.903Z", - "contributors": [ - "yuhengshen", - "Ende93", - "luoway", - "Bayes", - "NNNaix", - "TiaossuP", - "Sebastianz", - "collhector", - "p2world", - "FredWe", - "teoli", - "yan", - "zbinlin" - ] - }, - "Web/CSS/visibility": { - "modified": "2019-05-04T04:36:17.525Z", - "contributors": [ - "hddhyq", - "zhuangyin", - "Linkontoask", - "ziyunfei", - "teoli", - "TigerSoldier" - ] - }, - "Web/CSS/white-space": { - "modified": "2020-10-15T21:32:04.890Z", - "contributors": [ - "linxz_", - "yatsov", - "Zhang-Junzhi", - "zhangchen", - "yuansu", - "OlafCheng", - "changjingli", - "fscholz", - "Sebastianz", - "FredWe", - "paddingme", - "szmtcjm" - ] - }, - "Web/CSS/widows": { - "modified": "2020-10-15T22:31:59.036Z", - "contributors": [ - "Oliverz" - ] - }, - "Web/CSS/width": { - "modified": "2020-10-15T21:25:05.066Z", - "contributors": [ - "RainSlide", - "QAQK", - "dlnb526", - "Ende93", - "changjingli", - "Simplexible", - "Prinz_Rana", - "johncido", - "SphinxKnight", - "Sebastianz", - "teoli", - "evantre" - ] - }, - "Web/CSS/will-change": { - "modified": "2019-03-23T23:05:58.730Z", - "contributors": [ - "Sebastianz", - "ziyunfei", - "TooBug" - ] - }, - "Web/CSS/word-break": { - "modified": "2020-10-15T21:24:17.045Z", - "contributors": [ - "litmonw", - "yatsov", - "luckymore", - "zhuangyin", - "liu-xiao-cui", - "Ende93", - "teoli", - "fscholz", - "Sebastianz", - "paddingme", - "yan" - ] - }, - "Web/CSS/word-spacing": { - "modified": "2019-03-23T23:32:25.736Z", - "contributors": [ - "Sebastianz", - "luobotang", - "fscholz", - "FredWe", - "teoli", - "sunorry" - ] - }, - "Web/CSS/word-wrap": { - "modified": "2020-10-15T21:32:14.809Z", - "contributors": [ - "litmonw", - "dlnb526", - "WangWenZhang", - "pengwenbin7", - "xgqfrms", - "SAWSAWSAW", - "fscholz", - "Sebastianz", - "paddingme" - ] - }, - "Web/CSS/writing-mode": { - "modified": "2020-10-15T22:00:00.250Z", - "contributors": [ - "liuruiqi1993", - "abueavan", - "RoXoM", - "Tzcodejs", - "ihepta", - "virgil66" - ] - }, - "Web/CSS/z-index": { - "modified": "2020-11-23T06:27:46.896Z", - "contributors": [ - "chrisdavidmills", - "mdn_idealist", - "realstephenzhao", - "StudentMain", - "Huooo", - "Ende93", - "cipengxu", - "LySnake", - "yuuko", - "Sebastianz", - "aki", - "FredWe", - "teoli", - "TimZhao" - ] - }, - "Web/CSS/偏移": { - "modified": "2020-10-15T22:07:46.289Z", - "contributors": [ - "congyuandong", - "yichengxian" - ] - }, - "Web/CSS/媒体查询": { - "modified": "2020-10-15T21:56:18.732Z", - "contributors": [ - "RainSlide", - "zjffun", - "Charley-Hsu" - ] - }, - "Web/CSS/文本装饰线厚度(粗细)": { - "modified": "2020-10-15T22:25:42.153Z", - "contributors": [ - "tanapok", - "Zshining" - ] - }, - "Web/CSS/网格-模板-列": { - "modified": "2020-10-15T21:53:37.639Z", - "contributors": [ - "narol", - "RainSlide", - "tsukimiya", - "Xiao4", - "1986slayer" - ] - }, - "Web/EXSLT": { - "modified": "2019-01-16T21:33:48.141Z", - "contributors": [ - "Sheppy" - ] - }, - "Web/EXSLT/regexp": { - "modified": "2019-01-16T21:33:33.048Z", - "contributors": [ - "Sheppy" - ] - }, - "Web/EXSLT/regexp/match": { - "modified": "2019-03-23T22:46:14.875Z", - "contributors": [ - "thanos" - ] - }, - "Web/Events": { - "modified": "2020-08-14T06:47:09.660Z", - "contributors": [ - "lc15011977647", - "pe4ch", - "RainSlide", - "wbamberg", - "zhangchen", - "purcy", - "WjmNightingale", - "plter", - "XiaoyaoChen", - "BobGreen", - "xgqfrms-GitHub", - "zliy", - "tcatche", - "Ende93", - "ziyunfei", - "ReyCG_sub", - "louisremi" - ] - }, - "Web/Events/DOMContentLoaded": { - "modified": "2020-10-15T21:21:31.073Z", - "contributors": [ - "windybniw", - "shaw1121", - "knightyun", - "1v9", - "wbamberg", - "hhxxhg", - "274659281", - "fscholz", - "Niefee", - "xgqfrms-GitHub", - "BoatGina", - "broven", - "bambooom", - "ZivHe", - "ziyunfei", - "less", - "monjer", - "jtyjty99999" - ] - }, - "Web/Events/abort": { - "modified": "2019-04-30T14:23:21.618Z", - "contributors": [ - "wbamberg", - "hhxxhg", - "fscholz", - "xgqfrms-GitHub", - "m2mbob" - ] - }, - "Web/Events/afterprint": { - "modified": "2020-10-15T21:52:37.979Z", - "contributors": [ - "weibangtuo", - "fscholz", - "xgqfrms-GitHub" - ] - }, - "Web/Events/afterscriptexecute": { - "modified": "2020-10-15T21:52:39.291Z", - "contributors": [ - "RainSlide", - "fscholz", - "xgqfrms-GitHub" - ] - }, - "Web/Events/animationend": { - "modified": "2019-03-23T22:08:23.322Z", - "contributors": [ - "PaperFlu" - ] - }, - "Web/Events/animationstart": { - "modified": "2019-03-23T23:17:59.744Z", - "contributors": [ - "PaperFlu", - "fscholz", - "ziyunfei", - "shevche24" - ] - }, - "Web/Events/beforeprint": { - "modified": "2020-10-15T21:52:38.969Z", - "contributors": [ - "weibangtuo", - "fscholz", - "xgqfrms-GitHub" - ] - }, - "Web/Events/beforescriptexecute": { - "modified": "2020-10-15T21:29:36.732Z", - "contributors": [ - "RainSlide", - "fscholz", - "ziyunfei", - "LinusYu" - ] - }, - "Web/Events/beforeunload": { - "modified": "2020-10-15T21:34:03.122Z", - "contributors": [ - "pe4ch", - "Carllllo", - "MikeLeon23", - "Junezm", - "xgqfrms", - "wbamberg", - "HereChen", - "luhaimin", - "sqchenxiyuan", - "tcatche", - "maxsky", - "Tienyz", - "monjer" - ] - }, - "Web/Events/blur": { - "modified": "2019-03-23T22:23:55.603Z", - "contributors": [ - "hhxxhg", - "hyh19962008", - "fscholz", - "m2mbob" - ] - }, - "Web/Events/change": { - "modified": "2020-10-15T21:32:01.453Z", - "contributors": [ - "ljdmailbox", - "Clarkkkk", - "LIXiangChen", - "fscholz", - "yangxiaoqiao", - "xgqfrms-GitHub", - "azhi09", - "ziyunfei", - "charlie" - ] - }, - "Web/Events/compositionend": { - "modified": "2019-04-30T13:56:51.967Z", - "contributors": [ - "wbamberg", - "TreeVie", - "leehomeok" - ] - }, - "Web/Events/compositionstart": { - "modified": "2020-10-15T21:43:38.190Z", - "contributors": [ - "Carllllo", - "wbamberg", - "superfighter", - "StaicCai", - "laobubu" - ] - }, - "Web/Events/compositionupdate": { - "modified": "2019-04-30T14:03:15.654Z", - "contributors": [ - "wbamberg", - "fscholz", - "laobubu" - ] - }, - "Web/Events/copy": { - "modified": "2019-04-30T13:59:22.378Z", - "contributors": [ - "wbamberg", - "zhangchen", - "fscholz", - "inottn", - "maicss" - ] - }, - "Web/Events/cut": { - "modified": "2019-04-30T14:14:11.414Z", - "contributors": [ - "wbamberg", - "chenyanfei-m" - ] - }, - "Web/Events/error": { - "modified": "2020-10-15T21:34:06.283Z", - "contributors": [ - "pe4ch", - "liuruiqi1993", - "fscholz", - "Daqin", - "monjer" - ] - }, - "Web/Events/focus": { - "modified": "2019-03-31T11:52:42.546Z", - "contributors": [ - "fscholz", - "VictorDu" - ] - }, - "Web/Events/focusout": { - "modified": "2019-03-23T22:15:46.626Z", - "contributors": [ - "fscholz", - "liuhe" - ] - }, - "Web/Events/icecandidate": { - "modified": "2020-02-07T11:21:30.934Z", - "contributors": [ - "zotille", - "wbamberg", - "BillgoXu" - ] - }, - "Web/Events/input": { - "modified": "2020-10-15T21:30:28.054Z", - "contributors": [ - "Carllllo", - "Freezer", - "chess99", - "shijistar", - "fscholz", - "xgqfrms-GitHub", - "laobubu", - "ziyunfei", - "lyklykkkkkkk" - ] - }, - "Web/Events/load": { - "modified": "2020-10-15T21:36:32.271Z", - "contributors": [ - "pe4ch", - "Mookiepiece", - "fscholz", - "xgqfrms-GitHub", - "kun.yan" - ] - }, - "Web/Events/loadend": { - "modified": "2019-03-23T22:16:58.948Z", - "contributors": [ - "fscholz", - "wudexiang", - "xgqfrms-GitHub" - ] - }, - "Web/Events/loadstart": { - "modified": "2019-03-23T22:29:32.098Z", - "contributors": [ - "fscholz", - "faremax", - "Lxxyx" - ] - }, - "Web/Events/message": { - "modified": "2020-10-15T21:57:50.780Z", - "contributors": [ - "Spikef", - "wbamberg", - "Lim", - "CrystalY", - "Yongest", - "hellowrenfei" - ] - }, - "Web/Events/mousewheel": { - "modified": "2019-03-18T21:09:07.563Z", - "contributors": [ - "fscholz", - "soYawn" - ] - }, - "Web/Events/pageshow": { - "modified": "2020-05-15T03:40:03.122Z", - "contributors": [ - "BluesVN", - "lalaemls", - "WangShaoyu1", - "fscholz", - "shm" - ] - }, - "Web/Events/paste": { - "modified": "2020-10-15T21:52:19.374Z", - "contributors": [ - "qiudongwei", - "wbamberg", - "maicss" - ] - }, - "Web/Events/readystatechange事件": { - "modified": "2020-10-15T21:56:00.168Z", - "contributors": [ - "Carllllo", - "RainSlide", - "zhangchen", - "fscholz", - "abc45628" - ] - }, - "Web/Events/transitionend": { - "modified": "2019-11-15T05:44:51.899Z", - "contributors": [ - "joshchiucn", - "fscholz", - "zhuangyin", - "SeriousL", - "dlengks", - "ziyunfei", - "jtyjty99999" - ] - }, - "Web/Events/unhandledrejection": { - "modified": "2020-10-15T22:03:35.162Z", - "contributors": [ - "xuquentinyang", - "liangbus", - "RainSlide", - "wbamberg", - "Lie8466", - "zhaoqize" - ] - }, - "Web/Events/unload": { - "modified": "2020-10-15T21:21:37.553Z", - "contributors": [ - "pe4ch", - "acelibin", - "fscholz", - "xgqfrms-GitHub", - "ziyunfei", - "jtyjty99999" - ] - }, - "Web/Events/进度条": { - "modified": "2020-10-15T21:49:44.294Z", - "contributors": [ - "Ende93", - "957398123", - "fscholz", - "roberthow", - "fengfu" - ] - }, - "Web/Guide": { - "modified": "2020-09-13T04:05:26.959Z", - "contributors": [ - "Futrime", - "Oliver_Queen", - "RainSlide", - "codekissyoung", - "jiahui", - "yuntian", - "Go7hic", - "Ende93", - "slzll", - "zengAlex", - "lunix01", - "markyun", - "wtb", - "Kasuganosora", - "ethertank" - ] - }, - "Web/Guide/AJAX": { - "modified": "2020-08-06T07:28:20.783Z", - "contributors": [ - "luojia", - "Yang-yibu", - "anchen", - "makaria", - "chunnallu", - "chrisdavidmills", - "renzhengyu", - "MMHGH", - "zjhch123", - "XiaoyaoChen", - "Noly1990" - ] - }, - "Web/Guide/AJAX/Getting_Started": { - "modified": "2020-05-09T09:42:30.390Z", - "contributors": [ - "Mookiepiece", - "JiLiangLai", - "HCSkatana", - "realchoi", - "Mew_MDN", - "SalmonDaze", - "zazaliu", - "chrisdavidmills", - "shifengchen", - "tangc1", - "RogerShen" - ] - }, - "Web/Guide/API": { - "modified": "2019-03-23T23:17:06.067Z", - "contributors": [ - "RainSlide", - "Sheppy" - ] - }, - "Web/Guide/API/DOM": { - "modified": "2019-03-23T23:28:38.723Z", - "contributors": [ - "ziyunfei", - "paddingme", - "Carrott", - "Kasuganosora", - "Sheppy" - ] - }, - "Web/Guide/API/DOM/Storage": { - "modified": "2019-03-24T00:14:59.754Z", - "contributors": [ - "ziyunfei", - "celinestar", - "hutuxu", - "Sheppy", - "qiumaoyuan", - "aokihu", - "zhengzong.fu", - "Carrie zhxj" - ] - }, - "Web/Guide/API/DOM/The_structured_clone_algorithm": { - "modified": "2019-03-23T22:19:28.512Z", - "contributors": [ - "zhangchen", - "xgqfrms-GitHub", - "kameii", - "liuqipeng417", - "FredWe" - ] - }, - "Web/Guide/Audio_and_video_delivery": { - "modified": "2020-07-13T02:25:56.180Z", - "contributors": [ - "lizzxc", - "chrisdavidmills" - ] - }, - "Web/Guide/Audio_and_video_delivery/Adding_captions_and_subtitles_to_HTML5_video": { - "modified": "2020-10-27T07:00:04.677Z", - "contributors": [ - "ICLOUDIRIS", - "FranzList" - ] - }, - "Web/Guide/Audio_and_video_delivery/WebAudio_playbackRate_explained": { - "modified": "2019-03-18T20:51:41.158Z", - "contributors": [ - "chrisdavidmills", - "dandanbu3" - ] - }, - "Web/Guide/Audio_and_video_delivery/buffering_seeking_time_ranges": { - "modified": "2019-03-18T20:51:41.383Z", - "contributors": [ - "chrisdavidmills", - "zhangqiong" - ] - }, - "Web/Guide/CSS/Block_formatting_context": { - "modified": "2020-11-24T23:44:11.668Z", - "contributors": [ - "SDUTWSL", - "Ninglo", - "MinimalistYing", - "shanyuhai123", - "ylc395", - "GlowMonster", - "SageX", - "dylanyg", - "xunzhonglee", - "wavesheep", - "Mookiepiece", - "awayjin", - "dongsuo", - "ju1234", - "maoyumaoxun", - "helloyong", - "Terry.Qiao", - "Akiq2016", - "luoway", - "lanyuechen", - "zerosrat", - "young122849", - "Programmox", - "herofei", - "xgqfrms-GitHub", - "XiongAmao", - "yisibl", - "Ende93", - "zengkan0703", - "TiaossuP", - "kevinfszu", - "FredWe", - "ziyunfei", - "haofu", - "xmlovecss", - "teoli", - "yan" - ] - }, - "Web/Guide/CSS/CSS_Image_Sprites": { - "modified": "2019-03-23T23:22:22.347Z", - "contributors": [ - "RainSlide", - "ReyCG_sub", - "bingguo", - "Wenbin" - ] - }, - "Web/Guide/CSS/CSS基础": { - "modified": "2019-03-18T20:41:49.035Z", - "contributors": [ - "fscholz", - "Go7hic", - "Mrzzchao" - ] - }, - "Web/Guide/CSS/Consistent_list_indentation": { - "modified": "2019-03-23T23:22:24.362Z", - "contributors": [ - "freshSep", - "Wenbin" - ] - }, - "Web/Guide/CSS/Counters": { - "modified": "2019-03-23T23:28:24.261Z", - "contributors": [ - "Ende93", - "Jiang-Xuan", - "Jiasm", - "Nightingale" - ] - }, - "Web/Guide/CSS/Getting_started": { - "modified": "2019-03-23T23:51:15.283Z", - "contributors": [ - "Harvesty", - "Ende93", - "ziyunfei", - "teoli", - "Chajn", - "sunnylost", - "playts", - "Ianyang", - "Verruckt", - "Mgjbot", - "Zuzu" - ] - }, - "Web/Guide/CSS/Getting_started/Boxes": { - "modified": "2019-03-21T02:43:58.945Z", - "contributors": [ - "seozed", - "Robinx", - "Harvesty", - "ziyunfei", - "teoli", - "Chajn", - "hxl" - ] - }, - "Web/Guide/CSS/Getting_started/Cascading_and_inheritance": { - "modified": "2019-03-23T23:20:58.387Z", - "contributors": [ - "HelloFun", - "ziyunfei", - "teoli", - "jedmeng", - "Chajn" - ] - }, - "Web/Guide/CSS/Getting_started/Color": { - "modified": "2019-07-23T22:49:50.958Z", - "contributors": [ - "moposx", - "HelloFun", - "Harvesty", - "jasonzhyan", - "ziyunfei", - "teoli", - "Chajn", - "lilyh" - ] - }, - "Web/Guide/CSS/Getting_started/Content": { - "modified": "2020-07-16T22:25:48.610Z", - "contributors": [ - "Kilimanjaro", - "Robinx", - "Harvesty", - "ziyunfei", - "teoli", - "Chajn", - "aztack" - ] - }, - "Web/Guide/CSS/Getting_started/How_CSS_works": { - "modified": "2019-03-23T23:23:25.849Z", - "contributors": [ - "HelloFun", - "ziyunfei", - "teoli", - "Chajn", - "reygreen1" - ] - }, - "Web/Guide/CSS/Getting_started/JavaScript": { - "modified": "2019-03-23T23:14:19.406Z", - "contributors": [ - "chengzise", - "Chajn", - "reygreen1" - ] - }, - "Web/Guide/CSS/Getting_started/Layout": { - "modified": "2019-03-23T23:35:32.514Z", - "contributors": [ - "Harvesty", - "jasonzhyan", - "shuson", - "ziyunfei", - "mengzyou", - "teoli", - "Chajn", - "larryzhang" - ] - }, - "Web/Guide/CSS/Getting_started/Lists": { - "modified": "2019-03-23T23:20:46.740Z", - "contributors": [ - "Harvesty", - "jasonzhyan", - "tolerious", - "mengzyou", - "ziyunfei", - "teoli", - "Chajn", - "aztack" - ] - }, - "Web/Guide/CSS/Getting_started/Media": { - "modified": "2019-03-23T23:12:04.497Z", - "contributors": [ - "Robinx", - "Harvesty", - "jasonzhyan", - "ziyunfei", - "yeol", - "teoli", - "Chajn" - ] - }, - "Web/Guide/CSS/Getting_started/Readable_CSS": { - "modified": "2019-03-23T23:20:58.835Z", - "contributors": [ - "FlameZheng", - "HelloFun", - "Harvesty", - "jasonzhyan", - "Synyan", - "neutrous", - "ziyunfei", - "teoli", - "aztack", - "reygreen1" - ] - }, - "Web/Guide/CSS/Getting_started/SVG_and_CSS": { - "modified": "2019-03-23T23:20:53.389Z", - "contributors": [ - "ziyunfei", - "teoli", - "aztack" - ] - }, - "Web/Guide/CSS/Getting_started/Selectors": { - "modified": "2019-03-21T05:33:31.497Z", - "contributors": [ - "yijie_sun", - "Robinx", - "HelloFun", - "Harvesty", - "jasonzhyan", - "yihuanZhang", - "futurefeeling", - "FredWe", - "chenguangqi", - "yilksd", - "ziyunfei", - "teoli", - "Chajn", - "aztack", - "bingguo" - ] - }, - "Web/Guide/CSS/Getting_started/Tables": { - "modified": "2019-03-23T23:20:48.505Z", - "contributors": [ - "023Sparrow", - "Harvesty", - "mengzyou", - "ziyunfei", - "teoli", - "Chajn", - "aztack" - ] - }, - "Web/Guide/CSS/Getting_started/Text_styles": { - "modified": "2019-03-23T23:20:39.790Z", - "contributors": [ - "Harvesty", - "neutrous", - "ziyunfei", - "teoli", - "bingguo", - "gadgetboy", - "Chajn" - ] - }, - "Web/Guide/CSS/Getting_started/What_is_CSS": { - "modified": "2019-03-18T20:41:48.849Z", - "contributors": [ - "HelloFun", - "Ende93", - "haofu", - "ziyunfei", - "teoli", - "Chajn", - "sunnylost" - ] - }, - "Web/Guide/CSS/Getting_started/Why_use_CSS": { - "modified": "2019-03-23T23:24:15.853Z", - "contributors": [ - "TomatoLovve", - "HelloFun", - "ziyunfei", - "haofu", - "teoli", - "Chajn", - "aihua" - ] - }, - "Web/Guide/CSS/Media_queries": { - "modified": "2020-05-17T23:15:16.911Z", - "contributors": [ - "wallena3", - "Swordword", - "RainSlide", - "wuguichiroumeiyou", - "LemonTency", - "AielloChan", - "lllvantis", - "chaiyu2002", - "ziyunfei", - "xgqfrms-GitHub", - "Junetea", - "jggnice", - "fidejade", - "liyongleihf2006", - "AozakiOrenji", - "lokyoung", - "Sebastianz", - "mrstork", - "malayaleecoder", - "pantao", - "Ende93", - "Wenbin", - "anjianshi", - "ZhaoMing", - "Nightingale" - ] - }, - "Web/Guide/CSS/Scaling_background_images": { - "modified": "2019-03-23T23:22:21.195Z", - "contributors": [ - "Ende93", - "mrstork", - "anjia", - "figure7", - "Wenbin" - ] - }, - "Web/Guide/CSS/Testing_media_queries": { - "modified": "2020-10-15T21:25:42.378Z", - "contributors": [ - "RainSlide", - "Chajn", - "reygreen1", - "Wenbin" - ] - }, - "Web/Guide/CSS/Understanding_z_index": { - "modified": "2019-03-23T23:33:08.995Z", - "contributors": [ - "zhangchen", - "ZQH", - "Go7hic", - "ziyunfei", - "teoli", - "ArthasTree" - ] - }, - "Web/Guide/CSS/Understanding_z_index/Adding_z-index": { - "modified": "2019-03-23T23:21:48.784Z", - "contributors": [ - "ziyunfei", - "teoli", - "ArthasTree" - ] - }, - "Web/Guide/CSS/Understanding_z_index/Stacking_and_float": { - "modified": "2019-03-23T23:29:39.696Z", - "contributors": [ - "lixuguang", - "Marcia_gm", - "ziyunfei", - "teoli", - "sunnylost" - ] - }, - "Web/Guide/CSS/Understanding_z_index/Stacking_context_example_1": { - "modified": "2020-04-09T03:35:06.982Z", - "contributors": [ - "liuyibo", - "VickyJin" - ] - }, - "Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2": { - "modified": "2019-03-23T22:25:59.868Z", - "contributors": [ - "Skyrelu" - ] - }, - "Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3": { - "modified": "2020-01-19T10:58:58.576Z", - "contributors": [ - "zenHeart", - "Skyrelu" - ] - }, - "Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index": { - "modified": "2019-08-23T06:42:17.114Z", - "contributors": [ - "allan_simon", - "ziyunfei", - "teoli", - "sunnylost", - "endlesswind" - ] - }, - "Web/Guide/CSS/Understanding_z_index/The_stacking_context": { - "modified": "2020-01-02T04:20:32.161Z", - "contributors": [ - "Sl0v3C", - "realstephenzhao", - "hayahayao", - "SakuraSnow", - "zjffun", - "gzponline", - "kevinfszu", - "Ende93", - "huangcheng", - "yisibl", - "ziyunfei", - "Dolphin_Wood", - "davin107", - "fake", - "teoli", - "ethertank", - "tzyeah" - ] - }, - "Web/Guide/CSS/Using_CSS_gradients": { - "modified": "2020-08-08T22:22:01.317Z", - "contributors": [ - "funicular", - "pe4ch", - "sanxun515", - "Aamperor", - "zhangnan666", - "zjffun", - "weedwong", - "Gaven-Xu", - "yatace", - "Sebastianz", - "hkfn123", - "lttxzmj", - "RogerShen", - "anjianshi" - ] - }, - "Web/Guide/CSS/Using_multi-column_layouts": { - "modified": "2019-03-23T23:28:24.667Z", - "contributors": [ - "Bayes", - "xgqfrms-GitHub", - "fscholz", - "Nightingale" - ] - }, - "Web/Guide/CSS/Using_the_:target_selector": { - "modified": "2019-03-23T22:52:16.056Z", - "contributors": [ - "Ende93", - "huangcheng", - "FredWe" - ] - }, - "Web/Guide/CSS/Visual_formatting_model": { - "modified": "2019-03-18T21:10:31.376Z", - "contributors": [ - "guangzai", - "ssttii", - "qw8880000", - "Terry.Qiao", - "ziyunfei", - "zhanglun", - "teoli", - "sunnylost", - "yan" - ] - }, - "Web/Guide/Events": { - "modified": "2019-03-23T23:20:12.541Z", - "contributors": [ - "Imagine-Tom", - "tcatche", - "NoDocCat", - "Tankunpeng", - "Jeremie" - ] - }, - "Web/Guide/Events/Creating_and_triggering_events": { - "modified": "2020-05-27T10:29:01.846Z", - "contributors": [ - "Carllllo", - "xingleizhao", - "but0n", - "zhangchen", - "LuSitong", - "Iamxiaozhu", - "ucev", - "xgqfrms-GitHub", - "ZhengYinBo", - "carllx", - "timwangdev", - "FredWe", - "ReyCG_sub" - ] - }, - "Web/Guide/Events/Event_handlers": { - "modified": "2019-03-23T23:20:11.825Z", - "contributors": [ - "tcatche", - "Le-Fu", - "xgqfrms-GitHub", - "ziyunfei", - "Darrel.Hsu" - ] - }, - "Web/Guide/Events/Media_events": { - "modified": "2020-07-02T07:14:48.714Z", - "contributors": [ - "9aoyang", - "haocity", - "TimRChen", - "maicss", - "GSBL", - "bizbin", - "esterTion", - "SudoKillMe", - "zilong-thu", - "ziyunfei", - "Anonymous" - ] - }, - "Web/Guide/Events/Mutation_events": { - "modified": "2019-03-23T22:51:23.609Z", - "contributors": [ - "Pada", - "peonyriver", - "FredWe" - ] - }, - "Web/Guide/Events/Orientation_and_motion_data_explained": { - "modified": "2019-03-23T23:10:07.666Z", - "contributors": [ - "fancy" - ] - }, - "Web/Guide/Events/Overview_of_Events_and_Handlers": { - "modified": "2019-03-23T22:51:31.630Z", - "contributors": [ - "Song2017", - "FredWe" - ] - }, - "Web/Guide/Graphics": { - "modified": "2020-12-07T03:47:26.253Z", - "contributors": [ - "SphinxKnight", - "Vongola-czr", - "Mookiepiece", - "RainSlide", - "zhuangyin", - "ITxiaochong", - "pluwen", - "m4jing", - "jinger7281", - "wth", - "rockywen", - "ryerh", - "wanglingzhi", - "Kasuganosora", - "Hikerpig" - ] - }, - "Web/Guide/HTML/Content_Editable": { - "modified": "2020-09-22T00:31:12.632Z", - "contributors": [ - "imarco", - "YogurtQ", - "xianghui-ma", - "Hew007", - "zhuangyin", - "jamesxu", - "ziyunfei", - "teoli", - "sunnylost", - "ethertank" - ] - }, - "Web/Guide/HTML/Content_Editable/Rich-Text_Editing_in_Mozilla": { - "modified": "2019-11-25T00:57:33.951Z", - "contributors": [ - "gao5252", - "SphinxKnight", - "chrisdavidmills", - "sijinglei", - "doodlewind", - "zezhou", - "Cbgrape", - "Teago" - ] - }, - "Web/Guide/HTML/Content_categories": { - "modified": "2019-09-24T00:45:30.074Z", - "contributors": [ - "Metaloe", - "gnepnaiL-oahZ", - "unclesamnumberone", - "jizhi77", - "ZeroJsus", - "huozicheng", - "AllenYangFly", - "arya0822", - "kevinfszu", - "pantao", - "LuyaoWang", - "FredWe" - ] - }, - "Web/Guide/HTML/Email_links": { - "modified": "2020-05-25T10:01:07.179Z", - "contributors": [ - "sweeney", - "xgqfrms" - ] - }, - "Web/Guide/HTML/Forms_in_HTML": { - "modified": "2019-03-23T23:33:41.492Z", - "contributors": [ - "huozicheng", - "xgqfrms-GitHub", - "ziyunfei", - "teoli", - "sunnylost", - "jtyjty99999" - ] - }, - "Web/Guide/HTML/HTML": { - "modified": "2019-06-25T10:18:27.080Z", - "contributors": [ - "xiajun1996", - "ziyunfei", - "zzangxu" - ] - }, - "Web/Guide/HTML/HTML5": { - "modified": "2019-04-29T21:49:51.078Z", - "contributors": [ - "vanpipy", - "mike-j", - "GameWang", - "fanerge", - "mfoonirlee", - "Summer1026", - "xgqfrms-GitHub", - "Go7hic", - "panhe-xue", - "ObooChin", - "kevinfszu", - "teoli", - "xgqfrms", - "fghycode", - "jasonworg", - "mengzyou", - "Breezewish", - "Jianming", - "ziyunfei", - "xuxun", - "TimZhao", - "sunnylost", - "xcffl", - "princetoad@gmail.com" - ] - }, - "Web/Guide/HTML/HTML5/Constraint_validation": { - "modified": "2020-08-07T06:53:08.941Z", - "contributors": [ - "Nierifeng", - "shiyi25928988", - "yongchen" - ] - }, - "Web/Guide/HTML/HTML5/HTML5_Thematic_Classification": { - "modified": "2019-03-23T23:39:08.496Z", - "contributors": [ - "ziyunfei", - "kevmdn" - ] - }, - "Web/Guide/HTML/HTML5/HTML5_element_list": { - "modified": "2020-01-10T02:18:08.432Z", - "contributors": [ - "yinsang", - "Jevol", - "yongdi", - "Breezewish", - "ziyunfei" - ] - }, - "Web/Guide/HTML/HTML5/Introduction_to_HTML5": { - "modified": "2019-03-24T00:12:23.341Z", - "contributors": [ - "eeeeeeeason", - "YueBiYang", - "008", - "guotingchaopr", - "ziyunfei", - "ibeen", - "gaoyanqi", - "leegorous" - ] - }, - "Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document": { - "modified": "2019-03-21T10:38:08.111Z", - "contributors": [ - "RainSlide", - "jimmy-sum", - "VdoG", - "StarXY", - "kevinfszu", - "mengzyou", - "xuexiaocai" - ] - }, - "Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages": { - "modified": "2020-07-16T22:22:33.856Z", - "contributors": [ - "Dorence", - "Banhave", - "boltyu", - "TheaAo", - "wth", - "Samoay", - "ziyunfei", - "Y001", - "Mgjbot", - "Carrie zhxj" - ] - }, - "Web/Guide/HTML/Using_HTML5_audio_and_video": { - "modified": "2019-09-28T22:50:38.146Z", - "contributors": [ - "zaixuzheng", - "wth", - "Cindy_Liu", - "lyxuncle", - "flyonok", - "zhaiyu.zhaiyu", - "troywith77", - "ArthasTree", - "rogueduola", - "tankhanleng", - "shenhao" - ] - }, - "Web/Guide/HTML/Using_data_attributes": { - "modified": "2020-07-16T22:22:37.588Z", - "contributors": [ - "zhangchen", - "hhxxhg", - "lavenderming", - "xgqfrms-GitHub", - "hellotaotao", - "Go7hic", - "marshalYuan", - "monjer", - "Deryckxie" - ] - }, - "Web/Guide/Localizations_and_character_encodings": { - "modified": "2020-05-07T10:52:56.537Z", - "contributors": [ - "Ende93", - "91JOJO", - "xdsnet" - ] - }, - "Web/Guide/Mobile": { - "modified": "2019-03-23T23:20:37.061Z", - "contributors": [ - "TaoWei", - "mywentu", - "peterwang1996", - "qry", - "liminjun", - "xbzhs", - "duan.xiaodong", - "wanglong", - "ziyunfei" - ] - }, - "Web/Guide/Parsing_and_serializing_XML": { - "modified": "2019-08-12T08:51:44.801Z", - "contributors": [ - "RainSlide", - "haaling" - ] - }, - "Web/Guide/Performance": { - "modified": "2020-10-09T03:08:14.338Z", - "contributors": [ - "kite-js", - "SphinxKnight", - "Imagine-Tom", - "yexk", - "leozhang", - "sunnylost", - "DAVINDAI", - "ziyunfei" - ] - }, - "Web/HTML": { - "modified": "2020-05-18T02:45:10.401Z", - "contributors": [ - "SphinxKnight", - "MrWangYaNan", - "mkckr0", - "Mengli", - "853419196", - "xmcgcg", - "xq20160912", - "RainSlide", - "fanerge", - "abramsz", - "wangfy", - "fenyu", - "asthman666", - "mao001", - "vizardsLau", - "Planet6174", - "pluwen", - "ChangJun2018", - "robsean", - "ldwformat", - "xixilog", - "wh1msy", - "xx1124961758", - "little-love", - "Shadowhiker", - "Blink", - "ylws", - "liugev6", - "fygyx1", - "pkl6612", - "mona", - "PoppinL", - "ziyunfei", - "lunix01", - "Breezewish", - "xuxun", - "allan_simon", - "TimZhao", - "jessiecaisme", - "Futao.Gao" - ] - }, - "Web/HTML/Applying_color": { - "modified": "2020-07-22T05:27:42.410Z", - "contributors": [ - "WinterCicada", - "Dorence" - ] - }, - "Web/HTML/Attributes": { - "modified": "2020-08-28T22:38:07.073Z", - "contributors": [ - "nodeZ", - "fygyx1", - "tys", - "Carllllo", - "MartinsYong", - "enoorez", - "yhs-APerson", - "yuehp", - "PoppinL", - "ziyunfei", - "phoenixLU" - ] - }, - "Web/HTML/Attributes/自动完成属性": { - "modified": "2020-10-15T22:25:13.539Z", - "contributors": [ - "pans9" - ] - }, - "Web/HTML/Block-level_elements": { - "modified": "2019-03-18T20:38:24.578Z", - "contributors": [ - "kmc947373", - "CraigZeng", - "FredWe", - "Breezewish", - "teoli", - "ziyunfei", - "wdlth" - ] - }, - "Web/HTML/CORS_enabled_image": { - "modified": "2020-05-06T06:27:48.960Z", - "contributors": [ - "oxyg3n", - "guow10", - "PaulHan", - "wYhooo", - "xgqfrms-GitHub", - "kmc947373", - "ziyunfei", - "Breezewish" - ] - }, - "Web/HTML/CORS_settings_attributes": { - "modified": "2019-11-26T01:56:32.661Z", - "contributors": [ - "wangjian", - "Melo.HG", - "xgqfrms-GitHub", - "mygaochunming", - "xgqfrms", - "kmc947373" - ] - }, - "Web/HTML/DASH_Adaptive_Streaming_for_HTML_5_Video": { - "modified": "2019-12-03T21:07:25.830Z", - "contributors": [ - "guow10", - "xcffl" - ] - }, - "Web/HTML/Element": { - "modified": "2019-12-03T05:56:52.523Z", - "contributors": [ - "RainSlide", - "eforegist", - "XiangHongAi", - "mdnjcc", - "hoyt", - "jian86392088", - "VdoG", - "ruilee16", - "jesse0x90", - "Ende93", - "Martin.Chow", - "Breezewish", - "ziyunfei", - "gqqnbig", - "jessiecaisme", - "xcffl", - "teoli", - "Cnmahj" - ] - }, - "Web/HTML/Element/Heading_Elements": { - "modified": "2020-10-15T21:08:04.205Z", - "contributors": [ - "gafish", - "imba-tjd", - "RainSlide", - "wizardforcel", - "HashubWang", - "venden", - "Ende93", - "ziyunfei" - ] - }, - "Web/HTML/Element/Input": { - "modified": "2020-05-27T10:36:01.533Z", - "contributors": [ - "Carllllo", - "Rem486", - "wxyads", - "853419196", - "JuliusKingsley", - "zhangchen", - "qihuanlu01", - "zaixuzheng", - "yangshang01", - "yuyx91", - "voidzhou", - "hebby", - "jiangseventeen", - "fsx950223", - "Tiaen", - "xgqfrms-GitHub", - "liaoyinglong", - "adam198824", - "liyongleihf2006", - "AutumnFish", - "luobotang", - "gqqnbig", - "Ivan_V", - "zilong-thu", - "Metalooze", - "tiansh", - "ziyunfei", - "rnoka" - ] - }, - "Web/HTML/Element/Input/button": { - "modified": "2019-03-18T21:28:02.958Z", - "contributors": [ - "zaixuzheng", - "bear-x" - ] - }, - "Web/HTML/Element/Input/checkbox": { - "modified": "2019-07-01T05:04:47.435Z", - "contributors": [ - "konrumi" - ] - }, - "Web/HTML/Element/Input/color": { - "modified": "2019-03-23T22:16:45.281Z", - "contributors": [ - "ecnelises", - "litmonw", - "konrumi" - ] - }, - "Web/HTML/Element/Input/date": { - "modified": "2019-03-23T22:01:59.059Z", - "contributors": [ - "LeonH", - "WeiGrand", - "tangj1206" - ] - }, - "Web/HTML/Element/Input/datetime": { - "modified": "2019-07-13T11:00:17.487Z", - "contributors": [ - "853419196", - "wizardforcel" - ] - }, - "Web/HTML/Element/Input/datetime-local": { - "modified": "2020-10-24T12:05:38.587Z", - "contributors": [ - "HermitSun", - "ThaddeusJiang", - "zhangchen", - "kite-js" - ] - }, - "Web/HTML/Element/Input/email": { - "modified": "2020-10-15T22:07:09.640Z", - "contributors": [ - "Chattille", - "CiaoLee", - "zaixuzheng" - ] - }, - "Web/HTML/Element/Input/file": { - "modified": "2020-10-15T21:55:53.292Z", - "contributors": [ - "mkckr0", - "DreamLxq", - "hehe1111", - "alfredchan3", - "zhangchen", - "vippiv", - "AmyFoxFN", - "YinlongCoding", - "chinafootballyu", - "zxc5800", - "wizardforcel", - "ezirmusitua" - ] - }, - "Web/HTML/Element/Input/hidden": { - "modified": "2020-10-15T22:15:28.120Z", - "contributors": [ - "guow10", - "RainSlide" - ] - }, - "Web/HTML/Element/Input/image": { - "modified": "2020-10-15T21:49:38.681Z", - "contributors": [ - "SphinxKnight", - "Henry", - "yu.xcode", - "MissingDreamland" - ] - }, - "Web/HTML/Element/Input/number": { - "modified": "2019-03-23T22:10:11.887Z", - "contributors": [ - "zxsunrise", - "XXXS", - "hmzll", - "Ende93", - "xgqfrms-GitHub" - ] - }, - "Web/HTML/Element/Input/password": { - "modified": "2020-10-15T22:06:31.185Z", - "contributors": [ - "byouw", - "zaixuzheng" - ] - }, - "Web/HTML/Element/Input/radio": { - "modified": "2020-10-15T21:55:25.436Z", - "contributors": [ - "luohuayouyi12138", - "LeonZou", - "zhangchen", - "wizardforcel" - ] - }, - "Web/HTML/Element/Input/reset": { - "modified": "2020-10-15T22:25:10.687Z", - "contributors": [ - "guow10" - ] - }, - "Web/HTML/Element/Input/search": { - "modified": "2020-10-15T22:25:21.244Z", - "contributors": [ - "Lin-dreamer", - "guow10" - ] - }, - "Web/HTML/Element/Input/submit": { - "modified": "2020-10-15T22:05:11.959Z", - "contributors": [ - "guow10", - "RainSlide", - "bingxl" - ] - }, - "Web/HTML/Element/Input/tel": { - "modified": "2019-03-18T21:42:44.923Z", - "contributors": [ - "yuyx91" - ] - }, - "Web/HTML/Element/Input/text": { - "modified": "2020-10-15T22:14:33.627Z", - "contributors": [ - "guow10", - "acuptea" - ] - }, - "Web/HTML/Element/Input/time": { - "modified": "2020-10-15T22:19:46.814Z", - "contributors": [ - "kuailekai", - "jason-guo" - ] - }, - "Web/HTML/Element/Input/url": { - "modified": "2020-10-15T22:31:25.105Z", - "contributors": [ - "yu.xcode" - ] - }, - "Web/HTML/Element/Input/week": { - "modified": "2020-10-15T22:25:21.176Z", - "contributors": [ - "pans9" - ] - }, - "Web/HTML/Element/Input/月份": { - "modified": "2020-10-15T21:57:03.537Z", - "contributors": [ - "RainSlide", - "AliasZet" - ] - }, - "Web/HTML/Element/Input/范围": { - "modified": "2020-10-15T22:25:22.859Z", - "contributors": [ - "q.z", - "hzy", - "pans9" - ] - }, - "Web/HTML/Element/Shadow": { - "modified": "2019-03-23T22:10:02.975Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/a": { - "modified": "2020-10-15T21:24:07.101Z", - "contributors": [ - "gmaso", - "gafish", - "RainSlide", - "JimmieMax", - "JinRong.Yang", - "sunbeyond", - "zhaoqize", - "wizardforcel", - "Dafrok", - "xgqfrms-GitHub", - "simonguo", - "Ende93", - "Yelmor", - "yaoliyc", - "yatace", - "venden", - "FredWe", - "NIGHTEAGLE", - "ziyunfei", - "TimZhao", - "jessiecaisme" - ] - }, - "Web/HTML/Element/abbr": { - "modified": "2020-10-15T21:24:12.293Z", - "contributors": [ - "Astroleander", - "shuihuo", - "greyyyyy", - "RainSlide", - "xianshenglu", - "Ende93", - "xgqfrms-GitHub", - "fscholz", - "xingzhi", - "ziyunfei", - "jessiecaisme" - ] - }, - "Web/HTML/Element/acronym": { - "modified": "2019-03-23T22:47:31.151Z", - "contributors": [ - "wizardforcel", - "xgqfrms-GitHub", - "YaohuiWu", - "pantao" - ] - }, - "Web/HTML/Element/address": { - "modified": "2020-10-15T21:28:19.569Z", - "contributors": [ - "gafish", - "Huangyilin19", - "RainSlide", - "rguanghui", - "xingzhi" - ] - }, - "Web/HTML/Element/applet": { - "modified": "2019-03-23T22:30:12.481Z", - "contributors": [ - "chhpt" - ] - }, - "Web/HTML/Element/area": { - "modified": "2019-03-23T22:50:07.483Z", - "contributors": [ - "CLoli", - "purcy", - "Undecyce", - "lily121", - "maicss", - "liangmuyang", - "TheaAo", - "naive233", - "xrds" - ] - }, - "Web/HTML/Element/article": { - "modified": "2020-10-15T21:26:55.414Z", - "contributors": [ - "gafish", - "SphinxKnight", - "916106840510", - "GalvinGao", - "rguanghui", - "ziyunfei", - "hutuxu" - ] - }, - "Web/HTML/Element/aside": { - "modified": "2020-10-15T21:34:26.905Z", - "contributors": [ - "gafish", - "RainSlide", - "shlugood", - "Jacky-88", - "YifangDONG", - "kevinfszu", - "rguanghui" - ] - }, - "Web/HTML/Element/audio": { - "modified": "2020-11-26T10:10:23.964Z", - "contributors": [ - "xusy", - "tanshaobo", - "Clarkkkk", - "RoXoM", - "wbamberg", - "HUxiaoAlinNG", - "little-tomorrow", - "Gerhut", - "mage3k", - "zhouyg", - "ziyunfei", - "snadn" - ] - }, - "Web/HTML/Element/b": { - "modified": "2019-03-18T20:42:37.816Z", - "contributors": [ - "kite-js", - "Benjamin-Smith", - "lc-soft", - "zhuangyin", - "markyun", - "PoppinL" - ] - }, - "Web/HTML/Element/base": { - "modified": "2020-10-15T21:32:52.441Z", - "contributors": [ - "guow10", - "RainSlide", - "dodoBehind", - "Lux.lu", - "xgqfrms-GitHub", - "TheaAo", - "betseyliu", - "eforegist", - "PythonFo", - "RainKolwa", - "chinaliyun", - "mengzyou", - "nobug" - ] - }, - "Web/HTML/Element/basefont": { - "modified": "2019-03-23T22:20:23.098Z", - "contributors": [ - "hoyt" - ] - }, - "Web/HTML/Element/bdi": { - "modified": "2020-10-15T21:45:31.840Z", - "contributors": [ - "yofine", - "gafish", - "ZackBee", - "hoyt", - "Ende93" - ] - }, - "Web/HTML/Element/bdo": { - "modified": "2020-10-15T22:29:52.953Z", - "contributors": [ - "JerryYoung" - ] - }, - "Web/HTML/Element/bgsound": { - "modified": "2019-03-23T22:20:25.683Z", - "contributors": [ - "hoyt" - ] - }, - "Web/HTML/Element/big": { - "modified": "2019-03-23T22:20:25.885Z", - "contributors": [ - "hoyt" - ] - }, - "Web/HTML/Element/blink": { - "modified": "2019-03-23T22:20:26.966Z", - "contributors": [ - "teoli", - "hoyt" - ] - }, - "Web/HTML/Element/blockquote": { - "modified": "2020-10-15T21:31:05.486Z", - "contributors": [ - "RainSlide", - "pantao", - "lisnb" - ] - }, - "Web/HTML/Element/body": { - "modified": "2020-10-15T21:39:08.650Z", - "contributors": [ - "RainSlide", - "eforegist", - "kite-js", - "hoyt", - "CodeDreamfy", - "JoshuaLee", - "sweetliu", - "pantao" - ] - }, - "Web/HTML/Element/br": { - "modified": "2020-10-15T21:41:22.726Z", - "contributors": [ - "kite-js", - "hoyt", - "gqqnbig", - "venden" - ] - }, - "Web/HTML/Element/button": { - "modified": "2020-10-15T21:34:26.939Z", - "contributors": [ - "ilexwg", - "YuanGYao", - "kite-js", - "WeJie", - "wizardforcel", - "ezirmusitua", - "AnitaYin", - "JulieLee77" - ] - }, - "Web/HTML/Element/canvas": { - "modified": "2020-10-15T21:21:53.234Z", - "contributors": [ - "Mookiepiece", - "Martin.Chow", - "pantao", - "King.521", - "lunix01", - "qguor", - "ziyunfei", - "xcffl" - ] - }, - "Web/HTML/Element/caption": { - "modified": "2019-03-23T22:47:30.729Z", - "contributors": [ - "_sollrei", - "gqqnbig", - "pantao" - ] - }, - "Web/HTML/Element/center": { - "modified": "2019-03-23T22:10:15.013Z", - "contributors": [ - "maoyumaoxun", - "wizardforcel" - ] - }, - "Web/HTML/Element/cite": { - "modified": "2020-10-15T21:41:43.390Z", - "contributors": [ - "Humilitas", - "yuyuanqiu", - "gafish", - "lucoo01", - "ma125120", - "King." - ] - }, - "Web/HTML/Element/code": { - "modified": "2019-03-23T23:19:07.452Z", - "contributors": [ - "ziyunfei", - "guoyunhebrave" - ] - }, - "Web/HTML/Element/col": { - "modified": "2019-04-13T00:08:55.934Z", - "contributors": [ - "Rominez", - "zxcvbnm", - "FredWe" - ] - }, - "Web/HTML/Element/colgroup": { - "modified": "2020-10-15T21:37:46.269Z", - "contributors": [ - "RainSlide", - "Soyaine", - "PandaadnaP", - "FredWe" - ] - }, - "Web/HTML/Element/command": { - "modified": "2019-03-18T20:43:33.481Z", - "contributors": [ - "wbamberg", - "practicemp", - "ziyunfei" - ] - }, - "Web/HTML/Element/content": { - "modified": "2019-03-23T22:10:12.369Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/data": { - "modified": "2020-10-15T21:28:38.554Z", - "contributors": [ - "RainSlide", - "hxl" - ] - }, - "Web/HTML/Element/datalist": { - "modified": "2020-10-15T21:19:07.919Z", - "contributors": [ - "gafish", - "zhangchen", - "mfranzke", - "wbamberg", - "Jianming", - "SphinxKnight", - "koaqiu", - "JulieLee77", - "ziyunfei" - ] - }, - "Web/HTML/Element/dd": { - "modified": "2019-03-23T22:39:17.576Z", - "contributors": [ - "zhuangyin", - "PoppinL" - ] - }, - "Web/HTML/Element/del": { - "modified": "2020-10-15T21:44:56.125Z", - "contributors": [ - "lastVigo", - "Ende93" - ] - }, - "Web/HTML/Element/details": { - "modified": "2020-10-15T21:40:23.093Z", - "contributors": [ - "Sc0tt", - "RainSlide", - "moquede", - "Jiang-Xuan", - "wh1msy", - "xgqfrms-GitHub", - "Martin.Chow" - ] - }, - "Web/HTML/Element/dfn": { - "modified": "2020-08-14T22:28:54.156Z", - "contributors": [ - "liujtani", - "harttle" - ] - }, - "Web/HTML/Element/dialog": { - "modified": "2020-10-15T21:53:47.497Z", - "contributors": [ - "bambooom", - "RainSlide", - "Bayes", - "xgqfrms-GitHub" - ] - }, - "Web/HTML/Element/dir": { - "modified": "2019-03-21T11:22:00.363Z", - "contributors": [ - "RainSlide", - "wizardforcel" - ] - }, - "Web/HTML/Element/div": { - "modified": "2020-10-15T21:37:14.662Z", - "contributors": [ - "imdsc", - "guofai", - "BurNing1993", - "RainSlide", - "gafish", - "YunZhongZi", - "pantao", - "FredWe" - ] - }, - "Web/HTML/Element/dl": { - "modified": "2020-04-29T06:50:25.527Z", - "contributors": [ - "tanshaobo", - "wenchuyang", - "zhuangyin", - "PoppinL", - "teoli", - "pantao" - ] - }, - "Web/HTML/Element/dt": { - "modified": "2019-03-23T22:52:08.449Z", - "contributors": [ - "PoppinL", - "pantao", - "FredWe" - ] - }, - "Web/HTML/Element/element": { - "modified": "2019-03-23T22:13:42.917Z", - "contributors": [ - "angelllls" - ] - }, - "Web/HTML/Element/em": { - "modified": "2019-08-13T01:09:58.820Z", - "contributors": [ - "huxinsen", - "eMUQI", - "bobo159357456", - "xgqfrms", - "pantao" - ] - }, - "Web/HTML/Element/embed": { - "modified": "2020-10-15T21:28:42.719Z", - "contributors": [ - "RainSlide", - "chenos", - "Martin.Chow", - "Startan" - ] - }, - "Web/HTML/Element/fieldset": { - "modified": "2020-10-15T21:49:19.693Z", - "contributors": [ - "Carllllo", - "lucoo01", - "ezirmusitua", - "abowloflrf", - "cyxlj" - ] - }, - "Web/HTML/Element/figcaption": { - "modified": "2019-03-23T22:35:32.183Z", - "contributors": [ - "wizardforcel", - "travellingkite", - "Ende93" - ] - }, - "Web/HTML/Element/figure": { - "modified": "2020-10-15T21:38:52.140Z", - "contributors": [ - "gafish", - "RainSlide", - "lcw0622", - "ajfg93", - "Ende93", - "041008725", - "you0509" - ] - }, - "Web/HTML/Element/font": { - "modified": "2019-03-23T22:10:03.224Z", - "contributors": [ - "yinsang", - "wizardforcel" - ] - }, - "Web/HTML/Element/footer": { - "modified": "2020-10-15T21:38:27.121Z", - "contributors": [ - "gafish", - "Ende93", - "sweetliu", - "W.D.L" - ] - }, - "Web/HTML/Element/form": { - "modified": "2020-10-15T21:14:51.331Z", - "contributors": [ - "Clarkkkk", - "Carllllo", - "Daqin", - "xuiang", - "RainSlide", - "Alfxjx", - "l613", - "gafish", - "linjialiang", - "HJ8848", - "luzhe610", - "Structure88", - "wizardforcel", - "maicss", - "zrtalent", - "FredWe", - "ziyunfei", - "lenvens" - ] - }, - "Web/HTML/Element/frame": { - "modified": "2019-03-23T22:10:16.682Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/frameset": { - "modified": "2020-10-15T21:48:59.254Z", - "contributors": [ - "Ende93", - "xgqfrms-GitHub", - "Fogwind" - ] - }, - "Web/HTML/Element/head": { - "modified": "2020-10-15T21:31:48.499Z", - "contributors": [ - "eforegist", - "jesse0x90", - "AlexChao" - ] - }, - "Web/HTML/Element/header": { - "modified": "2020-10-15T21:27:00.445Z", - "contributors": [ - "gafish", - "RainSlide", - "wbamberg", - "ziyunfei", - "hutuxu" - ] - }, - "Web/HTML/Element/hgroup": { - "modified": "2020-09-15T22:26:38.462Z", - "contributors": [ - "hellorayza", - "emanruoy", - "allan_simon", - "diqiuxin", - "Ende93" - ] - }, - "Web/HTML/Element/hr": { - "modified": "2020-10-15T21:39:09.045Z", - "contributors": [ - "mitaosi", - "tanshaobo", - "gafish", - "lucoo01", - "azheng", - "nicholas-yangding", - "Ende93", - "pantao" - ] - }, - "Web/HTML/Element/html": { - "modified": "2020-10-15T21:37:17.396Z", - "contributors": [ - "gafish", - "eforegist", - "xgqfrms-GitHub", - "thinklittle", - "VdoG", - "ruilee16", - "jesse0x90", - "jasonnn331", - "Ende93", - "FredWe" - ] - }, - "Web/HTML/Element/i": { - "modified": "2019-03-23T23:11:10.638Z", - "contributors": [ - "StormBR1120", - "ccn1010", - "ranwu", - "pantao", - "Hey-Ray" - ] - }, - "Web/HTML/Element/iframe": { - "modified": "2020-10-15T21:21:27.595Z", - "contributors": [ - "卡尔维斯特", - "HHH-can", - "frankli0324", - "gafish", - "Aslower", - "hexianzhi", - "xgqfrms", - "wbamberg", - "GameWang", - "AlvinBlack", - "Ende93", - "shiddong", - "xuxun", - "xgqfrms-GitHub", - "hoyt", - "Marcia_gm", - "Sivan", - "ReyCG_sub", - "ziyunfei", - "monjer", - "Josephok", - "ZhangJianxiang" - ] - }, - "Web/HTML/Element/image": { - "modified": "2019-03-30T00:32:55.632Z", - "contributors": [ - "raygift", - "hoyt" - ] - }, - "Web/HTML/Element/img": { - "modified": "2020-10-15T21:34:27.415Z", - "contributors": [ - "liangmuyang", - "HaoyuA", - "XLCYun", - "RainSlide", - "LexieAlreadyTaken", - "imbant", - "zzykillu", - "gafish", - "Ahhaha233", - "Everain", - "iefreer", - "fuchao2012", - "anjia" - ] - }, - "Web/HTML/Element/ins": { - "modified": "2020-10-15T21:39:08.740Z", - "contributors": [ - "gafish", - "lastVigo", - "Martin.Chow", - "pantao" - ] - }, - "Web/HTML/Element/isindex": { - "modified": "2019-03-23T22:43:17.045Z", - "contributors": [ - "Martin.Chow" - ] - }, - "Web/HTML/Element/kbd": { - "modified": "2019-08-13T06:01:57.840Z", - "contributors": [ - "kenneth55555", - "hoyt", - "perillasy" - ] - }, - "Web/HTML/Element/keygen": { - "modified": "2019-04-05T05:50:18.178Z", - "contributors": [ - "Ende93" - ] - }, - "Web/HTML/Element/label": { - "modified": "2020-10-15T21:34:28.099Z", - "contributors": [ - "Carllllo", - "plusmultiply0", - "one-day-day", - "kuei0221", - "yuyuanqiu", - "loveyunk", - "Ende93", - "tinunkai", - "codevvvv9", - "yinsang", - "xgqfrms-GitHub", - "TooBug", - "ObooChin", - "JulieLee77" - ] - }, - "Web/HTML/Element/legend": { - "modified": "2020-10-15T21:28:02.232Z", - "contributors": [ - "Carllllo", - "xingzhi" - ] - }, - "Web/HTML/Element/li": { - "modified": "2019-04-06T23:38:24.006Z", - "contributors": [ - "lwj621", - "wizardforcel", - "changwu", - "JoshuaLee" - ] - }, - "Web/HTML/Element/link": { - "modified": "2020-10-15T21:43:08.607Z", - "contributors": [ - "woshiqiang1", - "mitaosi", - "dlnb526", - "Yayure", - "LINYI", - "seanyue", - "csideakevin", - "gafish", - "Blue-momo", - "wh.D", - "zhangqiangoffice", - "VdoG", - "sdc37h", - "zhengjianqiao", - "jethro2016", - "ZackBee", - "cissoid", - "jesse0x90", - "gqqnbig", - "041008725" - ] - }, - "Web/HTML/Element/listing": { - "modified": "2019-03-23T22:10:12.488Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/main": { - "modified": "2020-10-15T21:34:53.469Z", - "contributors": [ - "panda2134", - "kidwen", - "RainSlide", - "agannwei", - "gafish", - "sun_all", - "Alexanderonepills", - "zhangchen", - "yuyang", - "beiweiqiang", - "pantao", - "holynewbie", - "TANRUI", - "oxygen16" - ] - }, - "Web/HTML/Element/map": { - "modified": "2020-06-30T05:42:09.220Z", - "contributors": [ - "ikomom", - "Feel-Joy", - "wizardforcel", - "xycd", - "naive233" - ] - }, - "Web/HTML/Element/mark": { - "modified": "2020-01-10T01:04:18.292Z", - "contributors": [ - "yuyuanqiu", - "XiaoWinter", - "puppyer", - "Benjamin-Smith", - "looso", - "iigmir", - "Byronic94", - "marchen" - ] - }, - "Web/HTML/Element/marquee": { - "modified": "2019-03-23T22:16:10.183Z", - "contributors": [ - "siyecao", - "Easton605", - "wizardforcel", - "viazure", - "snovey" - ] - }, - "Web/HTML/Element/menu": { - "modified": "2020-10-15T21:37:16.105Z", - "contributors": [ - "RainSlide", - "yuyx91", - "kgojiwong", - "pantao", - "holynewbie" - ] - }, - "Web/HTML/Element/menuitem": { - "modified": "2020-10-15T21:58:27.361Z", - "contributors": [ - "RainSlide", - "wangxuedongovo" - ] - }, - "Web/HTML/Element/meta": { - "modified": "2020-10-15T21:34:02.227Z", - "contributors": [ - "RainSlide", - "Carllllo", - "chanvin", - "dlnb526", - "vanestone", - "xq20160912", - "ceido", - "Bayes", - "VdoG", - "zxsunrise", - "wpc1403s2", - "fsx950223", - "yellow-lines", - "yunikoro", - "scl930227", - "daixinye", - "zt2", - "Noly1990", - "aimiy", - "clarkzsd", - "qixi", - "xgqfrms-GitHub", - "wangdapeng1005", - "zhouyu1993", - "SolitudeRA", - "Annlix", - "littlee", - "pantao", - "SimplyY", - "Fadeoc" - ] - }, - "Web/HTML/Element/meta/name": { - "modified": "2020-10-15T22:33:39.182Z", - "contributors": [ - "RainSlide", - "hanochrosebush" - ] - }, - "Web/HTML/Element/meter": { - "modified": "2019-03-23T22:20:26.204Z", - "contributors": [ - "hoyt" - ] - }, - "Web/HTML/Element/multicol": { - "modified": "2019-03-23T22:18:36.663Z", - "contributors": [ - "wizardforcel", - "xgqfrms-GitHub" - ] - }, - "Web/HTML/Element/nav": { - "modified": "2020-10-15T21:26:27.913Z", - "contributors": [ - "gafish", - "wbamberg", - "yatace", - "ziyunfei", - "TimZhao", - "bowen-shi" - ] - }, - "Web/HTML/Element/nextid": { - "modified": "2020-10-15T22:25:21.460Z", - "contributors": [ - "pans9" - ] - }, - "Web/HTML/Element/nobr": { - "modified": "2019-03-23T22:10:16.065Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/noembed": { - "modified": "2019-03-23T22:10:11.377Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/noframes": { - "modified": "2019-03-23T22:10:12.853Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/noscript": { - "modified": "2020-10-15T21:41:44.231Z", - "contributors": [ - "gafish", - "Serendipity96", - "williamjing", - "xgqfrms-GitHub", - "wleonid" - ] - }, - "Web/HTML/Element/object": { - "modified": "2020-10-15T21:25:11.550Z", - "contributors": [ - "gafish", - "zaixuzheng", - "Martin.Chow", - "ziyunfei", - "TimZhao" - ] - }, - "Web/HTML/Element/ol": { - "modified": "2020-10-15T21:37:41.454Z", - "contributors": [ - "RainSlide", - "gafish", - "fcg55254", - "nuo2000", - "benpigchu", - "tcatche", - "Ende93", - "dongnanzhan", - "FredWe" - ] - }, - "Web/HTML/Element/optgroup": { - "modified": "2020-10-15T21:48:34.575Z", - "contributors": [ - "Carllllo", - "shinnqy" - ] - }, - "Web/HTML/Element/option": { - "modified": "2020-10-15T21:37:43.170Z", - "contributors": [ - "Carllllo", - "wizardforcel", - "King.", - "ziyunfei", - "zhache12345" - ] - }, - "Web/HTML/Element/output": { - "modified": "2020-10-15T21:41:37.216Z", - "contributors": [ - "wbamberg", - "zhangchen", - "King." - ] - }, - "Web/HTML/Element/p": { - "modified": "2019-03-23T23:14:26.595Z", - "contributors": [ - "Adashuai5", - "MrZhang", - "Ende93", - "FredWe", - "xingzhi" - ] - }, - "Web/HTML/Element/param": { - "modified": "2020-10-15T21:50:13.073Z", - "contributors": [ - "gafish", - "JinRong.Yang", - "naive233" - ] - }, - "Web/HTML/Element/picture": { - "modified": "2020-10-15T21:48:04.092Z", - "contributors": [ - "imba-tjd", - "yisibl", - "PoppinL" - ] - }, - "Web/HTML/Element/plaintext": { - "modified": "2019-03-23T22:10:03.107Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/pre": { - "modified": "2020-10-15T21:39:48.026Z", - "contributors": [ - "gafish", - "xgqfrms-GitHub", - "jiangseventeen", - "VdoG", - "Ende93", - "pengliheng" - ] - }, - "Web/HTML/Element/progress": { - "modified": "2020-10-15T21:05:48.761Z", - "contributors": [ - "wonschangge", - "mkckr0", - "fscholz", - "wbamberg", - "ziyunfei", - "ethertank" - ] - }, - "Web/HTML/Element/q": { - "modified": "2020-10-15T21:44:22.274Z", - "contributors": [ - "kenneth55555", - "fscholz", - "Zyan", - "Ende93", - "Jiang-Xuan" - ] - }, - "Web/HTML/Element/rb": { - "modified": "2020-10-15T22:14:32.981Z", - "contributors": [ - "richardmyu", - "zhaohaodang", - "astak" - ] - }, - "Web/HTML/Element/rp": { - "modified": "2020-05-03T03:15:11.285Z", - "contributors": [ - "tangallison2", - "wizardforcel" - ] - }, - "Web/HTML/Element/rt": { - "modified": "2019-04-18T06:06:40.759Z", - "contributors": [ - "Yujiyang", - "Benjamin-Smith", - "wizardforcel" - ] - }, - "Web/HTML/Element/rtc": { - "modified": "2019-04-18T06:06:45.477Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/ruby": { - "modified": "2020-10-15T21:40:22.004Z", - "contributors": [ - "xgqfrms", - "studyMakesMeHappy", - "zhangchen", - "Roger-WIN", - "wizardforcel", - "Martin.Chow" - ] - }, - "Web/HTML/Element/s": { - "modified": "2020-10-15T21:55:24.184Z", - "contributors": [ - "gafish", - "wizardforcel" - ] - }, - "Web/HTML/Element/samp": { - "modified": "2019-03-23T22:33:11.911Z", - "contributors": [ - "luobotang" - ] - }, - "Web/HTML/Element/script": { - "modified": "2020-08-05T19:13:19.581Z", - "contributors": [ - "mitaosi", - "michalska.lucyna88", - "harryzcy", - "namklaw", - "heekei", - "Soy", - "unclesamnumberone", - "Jackandjohn", - "xhlsrj", - "xgqfrms-GitHub", - "Ende93", - "ahwassa", - "gqqnbig", - "fskuok" - ] - }, - "Web/HTML/Element/section": { - "modified": "2020-10-15T21:22:44.033Z", - "contributors": [ - "shawn20111416", - "gafish", - "wbamberg", - "kevinfszu", - "Annlix", - "ziyunfei", - "TimZhao" - ] - }, - "Web/HTML/Element/select": { - "modified": "2020-10-15T21:27:52.792Z", - "contributors": [ - "Carllllo", - "zhangchen", - "wbamberg", - "pavilion2t", - "DUHZ", - "brandonzhu", - "ReyCG", - "ziyunfei" - ] - }, - "Web/HTML/Element/slot": { - "modified": "2020-10-15T21:54:42.237Z", - "contributors": [ - "Jennyshining", - "xgqfrms", - "maicss", - "n313893254" - ] - }, - "Web/HTML/Element/small": { - "modified": "2020-10-15T21:51:17.821Z", - "contributors": [ - "gafish", - "wizardforcel", - "rollinhup", - "Tidejade" - ] - }, - "Web/HTML/Element/source": { - "modified": "2019-07-01T10:30:44.709Z", - "contributors": [ - "l613", - "flyingsouthwind", - "naive233", - "ziyunfei", - "x-false" - ] - }, - "Web/HTML/Element/spacer": { - "modified": "2019-03-23T22:10:12.608Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/span": { - "modified": "2020-11-23T03:27:28.387Z", - "contributors": [ - "Ende93", - "mitaosi", - "gafish", - "wh.D", - "OlafCheng", - "King.", - "Fadeoc" - ] - }, - "Web/HTML/Element/strike": { - "modified": "2019-03-23T22:10:15.972Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/strong": { - "modified": "2019-03-23T22:28:05.903Z", - "contributors": [ - "bobo159357456", - "liwenkang", - "coolguy" - ] - }, - "Web/HTML/Element/style": { - "modified": "2020-10-15T21:33:11.824Z", - "contributors": [ - "dlnb526", - "VdoG", - "linghuam", - "RandyOu", - "mengzyou" - ] - }, - "Web/HTML/Element/sub": { - "modified": "2019-03-23T22:10:11.284Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/summary": { - "modified": "2020-10-15T21:40:24.548Z", - "contributors": [ - "JulesWang", - "xgqfrms-GitHub", - "Martin.Chow" - ] - }, - "Web/HTML/Element/sup": { - "modified": "2019-10-01T21:38:22.903Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Element/table": { - "modified": "2020-10-15T21:37:19.437Z", - "contributors": [ - "Ende93", - "stormyyd", - "Toobubble", - "codevvvv9", - "xgqfrms-GitHub", - "eforegist", - "jdk137", - "studentytj", - "PandaadnaP", - "Simcookies", - "zhe13", - "hexiaoming", - "FredWe" - ] - }, - "Web/HTML/Element/td": { - "modified": "2020-10-15T21:37:19.273Z", - "contributors": [ - "RainSlide", - "853419196", - "FredWe" - ] - }, - "Web/HTML/Element/template": { - "modified": "2020-10-15T21:31:49.045Z", - "contributors": [ - "zhangchen", - "sky5454", - "xgqfrms-GitHub", - "Breezewish" - ] - }, - "Web/HTML/Element/textarea": { - "modified": "2020-10-15T21:37:11.943Z", - "contributors": [ - "Carllllo", - "wuzhibo", - "gafish", - "Bayes", - "xianjiezh", - "koaqiu", - "celinaYu", - "maicss", - "xgqfrms-GitHub", - "DeronLee", - "FredWe" - ] - }, - "Web/HTML/Element/tfoot": { - "modified": "2020-10-15T22:04:34.366Z", - "contributors": [ - "nagisa", - "tomoru" - ] - }, - "Web/HTML/Element/th": { - "modified": "2020-10-15T21:59:42.026Z", - "contributors": [ - "853419196", - "silkey", - "levinweb" - ] - }, - "Web/HTML/Element/thead": { - "modified": "2020-10-15T21:52:32.187Z", - "contributors": [ - "gafish", - "fscholz", - "gilking", - "xgqfrms-GitHub", - "wzvoid" - ] - }, - "Web/HTML/Element/time": { - "modified": "2019-03-24T00:15:12.173Z", - "contributors": [ - "wbamberg", - "RandyOu", - "xunmorl", - "hxl", - "ziyunfei" - ] - }, - "Web/HTML/Element/title": { - "modified": "2020-10-15T21:41:22.327Z", - "contributors": [ - "dlnb526", - "tomcat1234", - "Annlix", - "venden" - ] - }, - "Web/HTML/Element/tr": { - "modified": "2019-03-23T22:12:39.535Z", - "contributors": [ - "Bayes", - "zxcvbnm" - ] - }, - "Web/HTML/Element/track": { - "modified": "2020-10-15T21:28:38.735Z", - "contributors": [ - "lizheming", - "Alex-DMC", - "gafish", - "flyingsouthwind", - "wbamberg", - "naive233", - "Martin.Chow", - "hxl" - ] - }, - "Web/HTML/Element/tt": { - "modified": "2019-03-23T22:22:44.407Z", - "contributors": [ - "wizardforcel", - "sayNo123" - ] - }, - "Web/HTML/Element/u": { - "modified": "2020-10-15T21:52:32.682Z", - "contributors": [ - "liruiux", - "yuyuanqiu", - "gafish", - "wizardforcel", - "hawm" - ] - }, - "Web/HTML/Element/ul": { - "modified": "2020-10-15T21:45:30.830Z", - "contributors": [ - "xq20160912", - "gafish", - "RainSlide", - "ChaunceyWang", - "TangiDing", - "Eternaldeath", - "kgojiwong", - "Invar", - "Ende93" - ] - }, - "Web/HTML/Element/var": { - "modified": "2020-10-15T21:40:23.614Z", - "contributors": [ - "xgqfrms", - "Martin.Chow" - ] - }, - "Web/HTML/Element/video": { - "modified": "2020-10-15T21:26:33.227Z", - "contributors": [ - "myy7362", - "Yangjia23", - "hahaaha", - "kirbey", - "DonSen", - "beautyTang", - "jnvf", - "Soyaine", - "wbamberg", - "Shangxin", - "esterTion", - "jfw10973", - "ziyunfei", - "hxl" - ] - }, - "Web/HTML/Element/wbr": { - "modified": "2020-10-15T21:55:23.940Z", - "contributors": [ - "Ende93", - "wizardforcel" - ] - }, - "Web/HTML/Element/xmp": { - "modified": "2020-10-15T21:40:04.585Z", - "contributors": [ - "GitHub-XQ", - "RainSlide", - "Martin.Chow" - ] - }, - "Web/HTML/Focus_management_in_HTML": { - "modified": "2019-03-23T23:31:56.410Z", - "contributors": [ - "xgqfrms-GitHub", - "kmc947373", - "sxxxsz", - "Breezewish", - "teoli", - "sunnylost" - ] - }, - "Web/HTML/Global_attributes": { - "modified": "2020-10-15T21:24:25.636Z", - "contributors": [ - "wangfangping", - "gafish", - "fangshuaituo", - "depcorn", - "nagisa", - "qihuanlu01", - "eforegist", - "Ende93", - "sdc37h", - "Jasery", - "xgqfrms-GitHub", - "hawm", - "OlafCheng", - "vicvinc", - "Shaoqiang.Zhang", - "zhangking", - "TimZhao", - "ziyunfei", - "bugknightyyp" - ] - }, - "Web/HTML/Global_attributes/accesskey": { - "modified": "2020-10-15T21:54:59.494Z", - "contributors": [ - "zhangchen", - "eforegist", - "ziyunfei", - "Ende93", - "wizardforcel", - "moque" - ] - }, - "Web/HTML/Global_attributes/autocapitalize": { - "modified": "2020-10-15T22:07:56.542Z", - "contributors": [ - "zhangchen", - "eforegist" - ] - }, - "Web/HTML/Global_attributes/class": { - "modified": "2020-10-15T21:39:56.865Z", - "contributors": [ - "zhangchen", - "eforegist", - "YehaiChen", - "ChuckZhang", - "Feihei" - ] - }, - "Web/HTML/Global_attributes/contenteditable": { - "modified": "2020-10-15T21:37:25.983Z", - "contributors": [ - "zhangchen", - "xgqfrms", - "eforegist", - "AlexChao" - ] - }, - "Web/HTML/Global_attributes/contextmenu": { - "modified": "2020-10-15T21:51:27.709Z", - "contributors": [ - "SphinxKnight", - "eforegist", - "Ende93", - "shuangya" - ] - }, - "Web/HTML/Global_attributes/data-*": { - "modified": "2020-10-15T21:36:49.775Z", - "contributors": [ - "wallena3", - "symant233", - "zhangchen", - "Bonlin0", - "eforegist", - "xgqfrms-GitHub", - "kameii", - "FredWe" - ] - }, - "Web/HTML/Global_attributes/dir": { - "modified": "2019-03-18T20:38:23.878Z", - "contributors": [ - "jdk137", - "mona" - ] - }, - "Web/HTML/Global_attributes/draggable": { - "modified": "2019-03-23T23:03:48.842Z", - "contributors": [ - "TooBug" - ] - }, - "Web/HTML/Global_attributes/dropzone": { - "modified": "2019-03-23T22:10:15.156Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/hidden": { - "modified": "2020-10-08T07:06:44.011Z", - "contributors": [ - "Martin730913", - "LeoQuote", - "wizardforcel", - "bestdream", - "gaopu" - ] - }, - "Web/HTML/Global_attributes/id": { - "modified": "2020-10-15T21:37:13.339Z", - "contributors": [ - "shawn20111416", - "kidonng", - "YehaiChen", - "JoshuaLee", - "zhangyudan" - ] - }, - "Web/HTML/Global_attributes/inputmode": { - "modified": "2020-10-15T22:20:42.369Z", - "contributors": [ - "qiudongwei" - ] - }, - "Web/HTML/Global_attributes/is": { - "modified": "2020-10-15T22:04:17.093Z", - "contributors": [ - "Kollar93" - ] - }, - "Web/HTML/Global_attributes/itemid": { - "modified": "2019-03-23T22:10:08.155Z", - "contributors": [ - "Ende93", - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/itemprop": { - "modified": "2019-03-23T22:09:25.188Z", - "contributors": [ - "xzy112233", - "MZI", - "bestdream" - ] - }, - "Web/HTML/Global_attributes/itemref": { - "modified": "2019-07-13T06:25:04.662Z", - "contributors": [ - "wangfangping", - "Mukti", - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/itemscope": { - "modified": "2019-03-23T22:04:34.982Z", - "contributors": [ - "codedrinker", - "Mukti" - ] - }, - "Web/HTML/Global_attributes/itemtype": { - "modified": "2019-03-23T22:10:01.057Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/lang": { - "modified": "2019-10-01T21:48:16.715Z", - "contributors": [ - "wangfangping", - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/part": { - "modified": "2020-10-15T22:31:54.138Z", - "contributors": [ - "wuding" - ] - }, - "Web/HTML/Global_attributes/slot": { - "modified": "2020-10-15T21:55:11.414Z", - "contributors": [ - "zhangchen", - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/spellcheck": { - "modified": "2019-03-23T22:18:18.900Z", - "contributors": [ - "wizardforcel", - "xcffl", - "fjh352", - "xgqfrms-GitHub" - ] - }, - "Web/HTML/Global_attributes/style": { - "modified": "2019-03-23T22:10:06.901Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/tabindex": { - "modified": "2020-10-15T21:55:15.899Z", - "contributors": [ - "xrkffgg", - "zhangchen", - "fjh352", - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/title": { - "modified": "2020-03-11T07:59:38.824Z", - "contributors": [ - "YangYihui", - "monkeyDyang", - "wizardforcel" - ] - }, - "Web/HTML/Global_attributes/translate": { - "modified": "2019-06-05T06:41:04.292Z", - "contributors": [ - "Martin.Chow" - ] - }, - "Web/HTML/Global_attributes/x-ms-加速装置键": { - "modified": "2019-12-03T17:45:24.248Z", - "contributors": [ - "pans9" - ] - }, - "Web/HTML/Global_attributes/x-ms-格式-检测": { - "modified": "2019-12-03T17:54:04.795Z", - "contributors": [ - "pans9" - ] - }, - "Web/HTML/Index": { - "modified": "2019-03-21T11:52:09.419Z", - "contributors": [ - "RainSlide", - "xcffl" - ] - }, - "Web/HTML/Inline_elements": { - "modified": "2020-08-05T19:04:54.777Z", - "contributors": [ - "mitaosi", - "chrisdavidmills", - "Raine_Huang", - "FredWe", - "ziyunfei", - "pmtao" - ] - }, - "Web/HTML/Link_types": { - "modified": "2020-10-15T21:31:40.375Z", - "contributors": [ - "chanvin", - "Yayure", - "gafish", - "JuliusKingsley", - "songlime", - "liutongshuo", - "idlefire", - "hstarorg", - "Ende93", - "grtreexyz", - "blue0125", - "Breezewish" - ] - }, - "Web/HTML/Link_types/prefetch": { - "modified": "2020-10-15T22:29:06.249Z", - "contributors": [ - "chanvin" - ] - }, - "Web/HTML/Link_types/preload": { - "modified": "2020-10-15T22:29:06.417Z", - "contributors": [ - "chanvin" - ] - }, - "Web/HTML/Microdata": { - "modified": "2019-07-13T06:56:53.858Z", - "contributors": [ - "wangfangping" - ] - }, - "Web/HTML/Optimizing_your_pages_for_speculative_parsing": { - "modified": "2019-03-23T22:46:26.910Z", - "contributors": [ - "huangcheng", - "ziyunfei", - "mengshukun" - ] - }, - "Web/HTML/Preloading_content": { - "modified": "2020-06-09T23:26:32.370Z", - "contributors": [ - "huyue", - "chanvin", - "sutaojie", - "haoliangwu", - "Axue", - "ldwformat" - ] - }, - "Web/HTML/Quirks_Mode_and_Standards_Mode": { - "modified": "2020-01-30T04:57:28.634Z", - "contributors": [ - "RainSlide", - "Kacoo", - "chrisdavidmills", - "iigmir", - "anfGG8G0G8" - ] - }, - "Web/HTML/Reference": { - "modified": "2019-09-09T07:23:44.694Z", - "contributors": [ - "SphinxKnight", - "wbamberg", - "FredWe", - "Breezewish" - ] - }, - "Web/HTML/Supported_media_formats": { - "modified": "2019-07-03T23:42:04.646Z", - "contributors": [ - "l613", - "zodiac-xl", - "ziyunfei" - ] - }, - "Web/HTML/Using_the_application_cache": { - "modified": "2019-10-29T05:43:20.065Z", - "contributors": [ - "7NZ", - "xgqfrms-GitHub", - "eforegist", - "liuzeyafzy", - "nianiaJR", - "shajiquan", - "hdwills", - "teoli", - "fsy0718", - "sunnylost", - "karsa.si" - ] - }, - "Web/HTTP": { - "modified": "2020-08-27T09:08:49.830Z", - "contributors": [ - "Lsnsh", - "dujun", - "RainSlide", - "taoyouh", - "shengjieli", - "userand", - "syt-honey", - "Pengfei", - "zhuangyin", - "JamieYang", - "xuxun", - "Ende93", - "xgqfrms-GitHub", - "sunnylost", - "cissoid", - "TomasRan", - "DreamerKing", - "ziyunfei" - ] - }, - "Web/HTTP/Access_control_CORS": { - "modified": "2020-11-30T22:27:21.749Z", - "contributors": [ - "seawaywen", - "fuweichin", - "jsonz1993", - "shens3", - "chanvin", - "SirnoChan", - "skywalker_z", - "Noodles006", - "yantong", - "hansnow", - "leoxiao2012", - "kunyaoxu", - "zjffun", - "show-rosarugosa", - "hnzxmutex", - "miuchan", - "ChenShihao", - "alvan", - "BobGreen", - "jiladahe1997", - "ErCargo", - "s1len0eye", - "zhang-hongwei", - "zthxxx", - "NineRec", - "recursion", - "libmw", - "bestvow", - "JuFoFu", - "xgqfrms-GitHub", - "bigZ-again", - "yuankunzhang", - "FideoJ", - "AlenQi", - "Ende93", - "wanglijie", - "yumingzhe", - "mygaochunming", - "Marcia_gm", - "xgqfrms", - "ybwdaisy", - "fjywan", - "holynewbie", - "gqqnbig", - "EdwardStudy", - "ssjssh", - "Kevin-Xi", - "8427003", - "Meteormatt", - "OOP-Code-Bunny", - "CManLH", - "qiumaoyuan" - ] - }, - "Web/HTTP/Authentication": { - "modified": "2020-01-19T22:05:27.998Z", - "contributors": [ - "cekingLu", - "gsxuan", - "zjffun", - "fanjieqi", - "rianma", - "wangpin", - "crper", - "WayneCui", - "GeJusdot", - "thomastao0215" - ] - }, - "Web/HTTP/Basics_of_HTTP": { - "modified": "2020-05-07T23:19:31.676Z", - "contributors": [ - "Filon", - "HardcorePhysician", - "Yayure", - "695919451", - "BobGreen", - "magiclyde", - "cissoid" - ] - }, - "Web/HTTP/Basics_of_HTTP/Choosing_between_www_and_non-www_URLs": { - "modified": "2019-03-23T22:18:43.282Z", - "contributors": [ - "zqyue", - "Ende93", - "xgqfrms-GitHub", - "ziyunfei", - "chaos_zhang" - ] - }, - "Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP": { - "modified": "2020-02-20T03:41:08.272Z", - "contributors": [ - "Babyfaceqian", - "XFJGitHub", - "lc-soft", - "BobGreen", - "enjolras1205", - "zihengCat", - "GuoShuai", - "Haruhi", - "huangchanghuan", - "keifergu", - "JsonLi", - "WeijieZhu" - ] - }, - "Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web": { - "modified": "2019-05-06T05:35:10.899Z", - "contributors": [ - "wolfzZ", - "heyv5", - "springapple", - "Wendy_Love", - "yuankunzhang", - "little-tomorrow", - "DreamerKing" - ] - }, - "Web/HTTP/Basics_of_HTTP/MIME_types": { - "modified": "2020-11-04T00:16:29.009Z", - "contributors": [ - "lujjjh", - "andysongs", - "rascalquan", - "BobGreen", - "NewbieAndy", - "zhangchen", - "xgqfrms-GitHub", - "w11th", - "YuriTu" - ] - }, - "Web/HTTP/Basics_of_HTTP/MIME_types/Common_types": { - "modified": "2020-02-28T13:11:23.222Z", - "contributors": [ - "chrisdavidmills", - "RainSlide", - "qq58553442", - "sam-dingkang", - "xgqfrms-GitHub", - "choury", - "pasturn" - ] - }, - "Web/HTTP/Browser_detection_using_the_user_agent": { - "modified": "2019-03-23T22:26:23.825Z", - "contributors": [ - "xgqfrms-GitHub", - "konrumi", - "Leogh", - "jianyi1995" - ] - }, - "Web/HTTP/CORS/Errors": { - "modified": "2019-05-27T00:23:38.306Z", - "contributors": [ - "waka3", - "nchevobbe", - "luna666", - "Sheppy" - ] - }, - "Web/HTTP/CORS/Errors/CORSAllowOriginNotMatchingOrigin": { - "modified": "2019-07-18T02:34:22.209Z", - "contributors": [ - "PYGC", - "ty1921" - ] - }, - "Web/HTTP/CORS/Errors/CORSDidNotSucceed": { - "modified": "2019-07-29T07:01:42.837Z", - "contributors": [ - "crvdgc", - "levo2165", - "luna666" - ] - }, - "Web/HTTP/CORS/Errors/CORSDisabled": { - "modified": "2019-05-09T05:04:22.066Z", - "contributors": [ - "luna666" - ] - }, - "Web/HTTP/CORS/Errors/CORSExternalRedirectNotAllowed": { - "modified": "2019-03-18T21:29:51.027Z", - "contributors": [ - "luna666" - ] - }, - "Web/HTTP/CORS/Errors/CORSMethodNotFound": { - "modified": "2019-08-27T04:22:52.153Z", - "contributors": [ - "laingke" - ] - }, - "Web/HTTP/CORS/Errors/CORSMissingAllowOrigin": { - "modified": "2019-03-18T21:22:06.783Z", - "contributors": [ - "zhangchen", - "coderyyx" - ] - }, - "Web/HTTP/CORS/Errors/CORSMultipleAllowOriginNotAllowed": { - "modified": "2019-10-30T01:07:54.026Z", - "contributors": [ - "Fimreal" - ] - }, - "Web/HTTP/CORS/Errors/CORSNotSupportingCredentials": { - "modified": "2019-06-16T23:37:59.140Z", - "contributors": [ - "feiyuerenhai" - ] - }, - "Web/HTTP/CORS/Errors/CORSOriginHeaderNotAdded": { - "modified": "2019-03-18T21:29:48.470Z", - "contributors": [ - "luna666" - ] - }, - "Web/HTTP/CORS/Errors/CORSPreflightDidNotSucceed": { - "modified": "2019-03-18T21:17:44.250Z", - "contributors": [ - "MinimalistYing" - ] - }, - "Web/HTTP/CORS/Errors/CORSRequestNotHttp": { - "modified": "2019-09-20T04:35:01.396Z", - "contributors": [ - "RainSlide", - "grape", - "xuyuehang", - "luna666" - ] - }, - "Web/HTTP/CORS/Errors/CORS错误允许凭证": { - "modified": "2020-09-18T12:19:26.611Z", - "contributors": [ - "Cooper-Kou" - ] - }, - "Web/HTTP/CSP": { - "modified": "2020-10-15T21:34:44.353Z", - "contributors": [ - "fanjieqi", - "phodal", - "ceido", - "jwhitlock", - "ldwformat", - "wang1dot0", - "WayneCui", - "xgqfrms-GitHub", - "zhang-quan-yi", - "hxl", - "zhi.lin", - "yuankunzhang", - "ziyunfei", - "Breezewish" - ] - }, - "Web/HTTP/Caching_FAQ": { - "modified": "2020-07-01T23:23:40.319Z", - "contributors": [ - "qnlz", - "xgqfrms", - "yqz0203", - "oppoffice", - "SAM.L", - "baijingfeng", - "YongzeYao", - "immortal-wm", - "YiBanCangBai", - "2585479524", - "fanjieqi", - "BobGreen", - "athena0304", - "dgeibi", - "cielsk", - "tianyuqingkong", - "xiaohp", - "tiancaiwuyue", - "hiyoushu", - "ch-zgh-1993", - "marsoln", - "wanglijie", - "xx1124961758", - "onedaywen", - "shengoo", - "sunnylost", - "followgiant", - "ziyunfei" - ] - }, - "Web/HTTP/Compression": { - "modified": "2019-06-20T00:32:44.768Z", - "contributors": [ - "liangzhaorong", - "BobGreen", - "zhangchen", - "WayneCui" - ] - }, - "Web/HTTP/Conditional_requests": { - "modified": "2019-09-19T06:11:16.911Z", - "contributors": [ - "leah_humlelu", - "Trendymen", - "xianweics", - "WayneCui" - ] - }, - "Web/HTTP/Configuring_servers_for_Ogg_media": { - "modified": "2019-12-27T03:08:09.838Z", - "contributors": [ - "Syaki" - ] - }, - "Web/HTTP/Connection_management_in_HTTP_1.x": { - "modified": "2019-11-07T04:16:26.733Z", - "contributors": [ - "woshiqiang1", - "Jack.Works", - "HardcorePhysician", - "jianglinghao", - "YiBanCangBai", - "guoshencheng", - "fanjieqi", - "athena0304", - "springapple", - "shaunlee" - ] - }, - "Web/HTTP/Content_negotiation": { - "modified": "2020-10-08T10:02:32.752Z", - "contributors": [ - "mh47838704", - "SunnyWind", - "lhc0101", - "WayneCui" - ] - }, - "Web/HTTP/Content_negotiation/Accept_默认值": { - "modified": "2019-03-18T21:35:18.474Z", - "contributors": [ - "heekei" - ] - }, - "Web/HTTP/Cookies": { - "modified": "2020-10-13T05:17:34.094Z", - "contributors": [ - "fzhyzamt", - "dake0805", - "RoXoM", - "ysqzhang", - "zh244135370", - "luvsunlight", - "mingzhang6", - "rascalquan", - "houyewei", - "huangyingjie", - "zihengCat", - "lc-soft", - "zhang-hongwei", - "yenshen", - "keifergu", - "FideoJ", - "AlenQi", - "sintrb", - "jdk137", - "charlie" - ] - }, - "Web/HTTP/HTTP_Strict_Transport_Security": { - "modified": "2020-11-19T14:34:26.997Z", - "contributors": [ - "chrisdavidmills", - "sunbeams001", - "kidonng", - "Jack.Works", - "zhangzhen", - "ToBo", - "udo-china", - "zhangchen", - "little-tomorrow", - "Eward.song" - ] - }, - "Web/HTTP/HTTP_response_codes": { - "modified": "2019-01-16T13:20:30.376Z", - "contributors": [ - "ziyunfei" - ] - }, - "Web/HTTP/Headers": { - "modified": "2020-05-20T02:33:50.716Z", - "contributors": [ - "spe-shun", - "cy234", - "c1er", - "Bayes", - "Jacksonary", - "rikkif", - "Weix", - "xgqfrms-GitHub", - "AlenQi", - "linzhixiong" - ] - }, - "Web/HTTP/Headers/Accept": { - "modified": "2020-10-15T21:50:50.340Z", - "contributors": [ - "xiaozhaofu", - "WayneCui", - "xgqfrms-GitHub", - "stevobm" - ] - }, - "Web/HTTP/Headers/Accept-CH": { - "modified": "2020-10-15T22:24:12.153Z", - "contributors": [ - "xuhui98" - ] - }, - "Web/HTTP/Headers/Accept-CH-Lifetime": { - "modified": "2020-10-15T22:25:10.809Z", - "contributors": [ - "chen3feng" - ] - }, - "Web/HTTP/Headers/Accept-Charset": { - "modified": "2020-10-15T21:50:53.082Z", - "contributors": [ - "shinken008", - "Dorllen", - "WayneCui", - "xgqfrms-GitHub" - ] - }, - "Web/HTTP/Headers/Accept-Encoding": { - "modified": "2020-10-15T21:53:10.909Z", - "contributors": [ - "xiaozhaofu", - "WayneCui", - "felixwang-1989", - "yt449", - "xgqfrms-GitHub" - ] - }, - "Web/HTTP/Headers/Accept-Language": { - "modified": "2020-10-15T21:53:13.880Z", - "contributors": [ - "ran", - "RainSlide", - "WayneCui", - "yuankunzhang" - ] - }, - "Web/HTTP/Headers/Accept-Patch": { - "modified": "2020-10-15T22:19:49.009Z", - "contributors": [ - "Sod-Momas" - ] - }, - "Web/HTTP/Headers/Accept-Ranges": { - "modified": "2020-10-15T21:54:15.134Z", - "contributors": [ - "Vincent-Hy", - "km-c", - "JianmingXia", - "crper", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Access-Control-Allow-Credentials": { - "modified": "2020-10-15T21:51:29.367Z", - "contributors": [ - "deping_chen", - "Bayes", - "xiasha", - "fscholz", - "crper", - "keqingrong", - "TiaossuP", - "tty4" - ] - }, - "Web/HTTP/Headers/Access-Control-Allow-Headers": { - "modified": "2020-10-15T21:54:48.443Z", - "contributors": [ - "GuoYaxiang", - "shadowkimi520", - "Soyaine", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Access-Control-Allow-Methods": { - "modified": "2020-10-15T21:54:49.842Z", - "contributors": [ - "Jat", - "crper", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Access-Control-Allow-Origin": { - "modified": "2020-10-15T21:52:46.095Z", - "contributors": [ - "TiaossuP", - "konrumi" - ] - }, - "Web/HTTP/Headers/Access-Control-Expose-Headers": { - "modified": "2020-10-15T21:54:48.426Z", - "contributors": [ - "lijsh", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Access-Control-Max-Age": { - "modified": "2020-10-15T21:54:52.194Z", - "contributors": [ - "zkerhcy", - "xiaozhaofu", - "jinliming2", - "crper", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Access-Control-Request-Headers": { - "modified": "2020-10-15T21:54:29.946Z", - "contributors": [ - "xiaozhaofu", - "crper", - "WayneCui", - "xgqfrms-GitHub" - ] - }, - "Web/HTTP/Headers/Access-Control-Request-Method": { - "modified": "2020-10-15T21:54:31.833Z", - "contributors": [ - "xiaozhaofu", - "WayneCui", - "xgqfrms-GitHub" - ] - }, - "Web/HTTP/Headers/Age": { - "modified": "2020-10-15T21:54:37.562Z", - "contributors": [ - "wangtongchao", - "fscholz", - "crper", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Allow": { - "modified": "2019-03-23T22:14:32.513Z", - "contributors": [ - "yuankunzhang" - ] - }, - "Web/HTTP/Headers/Alt-Svc": { - "modified": "2020-10-15T22:12:25.895Z", - "contributors": [ - "liuhaoXD", - "Light.G" - ] - }, - "Web/HTTP/Headers/Authorization": { - "modified": "2019-03-23T22:11:31.823Z", - "contributors": [ - "Bayes", - "crper", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Cache-Control": { - "modified": "2020-10-15T21:50:34.341Z", - "contributors": [ - "kidonng", - "woshiqiang1", - "DanielCui", - "taoyouh", - "tenghuanhe", - "ngulee", - "kaliExist", - "wangtongchao", - "marsorsun", - "cnc233", - "codevvvv9", - "pearzl", - "tianyuqingkong", - "zliy", - "NatureFeng", - "schickal", - "fscholz", - "shaunsxj", - "paranoidjk", - "visten" - ] - }, - "Web/HTTP/Headers/Clear-Site-Data": { - "modified": "2020-10-15T22:07:13.779Z", - "contributors": [ - "bershanskiy", - "wangtongchao" - ] - }, - "Web/HTTP/Headers/Connection": { - "modified": "2020-10-15T21:51:42.086Z", - "contributors": [ - "zhuguibiao", - "ujsxn", - "shinyoo" - ] - }, - "Web/HTTP/Headers/Content-Disposition": { - "modified": "2020-11-15T00:23:13.412Z", - "contributors": [ - "Alan-Liang", - "xiaozhaofu", - "WayneCui", - "icaoweiwei", - "JavacPro" - ] - }, - "Web/HTTP/Headers/Content-Encoding": { - "modified": "2020-10-15T21:54:51.398Z", - "contributors": [ - "DynamicAnt", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Content-Language": { - "modified": "2020-10-15T21:54:49.923Z", - "contributors": [ - "HankXu", - "yuantongkang", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Content-Length": { - "modified": "2020-10-15T21:54:51.554Z", - "contributors": [ - "rascalquan", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Content-Location": { - "modified": "2020-10-15T21:54:51.676Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Content-Range": { - "modified": "2020-10-15T21:54:39.510Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy": { - "modified": "2020-10-15T21:51:40.481Z", - "contributors": [ - "xiao11lang", - "hq5544", - "SphinxKnight", - "lowerpierman", - "taoyouh", - "imba-tjd", - "lvgg3271", - "alan199355", - "anchen", - "9ii", - "Forbidden", - "crper", - "lcw0622", - "SuunZhu" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy-Report-Only": { - "modified": "2020-10-15T21:55:30.073Z", - "contributors": [ - "Pada" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/base-uri": { - "modified": "2020-10-15T21:56:06.256Z", - "contributors": [ - "SphinxKnight", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/block-all-mixed-content": { - "modified": "2020-10-15T21:56:06.231Z", - "contributors": [ - "SphinxKnight", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/child-src": { - "modified": "2020-10-15T22:22:07.630Z", - "contributors": [ - "SphinxKnight", - "1930082875" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/connect-src": { - "modified": "2020-10-15T22:04:24.950Z", - "contributors": [ - "SphinxKnight", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/default-src": { - "modified": "2020-10-15T21:55:35.542Z", - "contributors": [ - "SphinxKnight", - "eachcan", - "shevacjs", - "Forbidden", - "WayneCui", - "EEord" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/font-src": { - "modified": "2020-10-15T22:11:53.390Z", - "contributors": [ - "SphinxKnight", - "eachcan" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/form-action": { - "modified": "2020-10-15T22:20:11.267Z", - "contributors": [ - "SphinxKnight", - "feiyuerenhai" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/frame-ancestors": { - "modified": "2020-10-15T21:56:28.759Z", - "contributors": [ - "SphinxKnight", - "ldwformat" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/report-to": { - "modified": "2020-10-15T22:04:25.324Z", - "contributors": [ - "SphinxKnight", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/require-sri-for": { - "modified": "2020-10-15T22:04:29.993Z", - "contributors": [ - "SphinxKnight", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/sandbox": { - "modified": "2020-10-15T22:18:49.969Z", - "contributors": [ - "SphinxKnight", - "Syclover-u2400" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/script-src-elem": { - "modified": "2020-10-15T22:32:24.500Z", - "contributors": [ - "davidguhao" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests": { - "modified": "2020-10-15T22:04:14.644Z", - "contributors": [ - "SphinxKnight", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Content-Security-Policy/worker-src": { - "modified": "2020-10-15T22:30:56.058Z", - "contributors": [ - "oyyunttt" - ] - }, - "Web/HTTP/Headers/Content-Type": { - "modified": "2020-10-15T21:50:48.235Z", - "contributors": [ - "ZL1019", - "kadoufall", - "WayneCui", - "xgqfrms-GitHub", - "wanhh" - ] - }, - "Web/HTTP/Headers/Cookie": { - "modified": "2020-10-15T21:54:53.599Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Cookie2": { - "modified": "2020-10-15T21:54:52.521Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Cross-Origin-Embedder-Policy": { - "modified": "2020-10-15T22:33:37.678Z", - "contributors": [ - "jguo0118", - "hellorayza" - ] - }, - "Web/HTTP/Headers/Cross-Origin-Resource-Policy": { - "modified": "2020-10-15T22:17:29.651Z", - "contributors": [ - "NightKing_hmsf" - ] - }, - "Web/HTTP/Headers/DNT": { - "modified": "2020-10-15T21:54:53.651Z", - "contributors": [ - "yenshen", - "WayneCui" - ] - }, - "Web/HTTP/Headers/DPR": { - "modified": "2020-10-15T22:25:12.812Z", - "contributors": [ - "zhangchen", - "charles-debug" - ] - }, - "Web/HTTP/Headers/Date": { - "modified": "2020-10-15T21:54:52.166Z", - "contributors": [ - "liaozhaonan", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Device-Memory": { - "modified": "2020-10-15T22:27:14.967Z", - "contributors": [ - "csliubo" - ] - }, - "Web/HTTP/Headers/Digest": { - "modified": "2020-10-15T22:22:30.332Z", - "contributors": [ - "Mulan" - ] - }, - "Web/HTTP/Headers/ETag": { - "modified": "2020-10-15T21:54:16.091Z", - "contributors": [ - "Opportunity", - "zhangchen", - "LeoQuote", - "qihaiyan", - "Mdxin", - "WayneCui", - "luckymore" - ] - }, - "Web/HTTP/Headers/Early-Data": { - "modified": "2020-10-15T22:10:58.660Z", - "contributors": [ - "Greenstorm", - "TUARAN" - ] - }, - "Web/HTTP/Headers/Expect": { - "modified": "2019-03-23T22:11:24.440Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Expect-CT": { - "modified": "2020-10-15T22:03:02.147Z", - "contributors": [ - "ariable" - ] - }, - "Web/HTTP/Headers/Expires": { - "modified": "2020-10-15T21:50:45.740Z", - "contributors": [ - "stuxu", - "Fiag", - "marsorsun", - "sunyanan891114", - "Simba.Lin", - "paranoidjk" - ] - }, - "Web/HTTP/Headers/Feature-Policy": { - "modified": "2020-10-15T22:18:06.274Z", - "contributors": [ - "roostinghawk" - ] - }, - "Web/HTTP/Headers/Feature-Policy/autoplay": { - "modified": "2020-10-15T22:18:28.072Z", - "contributors": [ - "baijingfeng" - ] - }, - "Web/HTTP/Headers/Feature-Policy/camera": { - "modified": "2020-10-15T22:26:24.357Z", - "contributors": [ - "K.Pen" - ] - }, - "Web/HTTP/Headers/Forwarded": { - "modified": "2019-03-23T22:11:01.048Z", - "contributors": [ - "ujsxn", - "WayneCui" - ] - }, - "Web/HTTP/Headers/From": { - "modified": "2020-10-15T21:54:57.725Z", - "contributors": [ - "LiquidLiquids", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Host": { - "modified": "2020-10-15T21:51:42.418Z", - "contributors": [ - "xinu", - "chentao106", - "wallen", - "crper", - "shinyoo" - ] - }, - "Web/HTTP/Headers/If-Match": { - "modified": "2020-10-15T21:55:00.013Z", - "contributors": [ - "ShiChenCong", - "Bayes", - "WayneCui" - ] - }, - "Web/HTTP/Headers/If-Modified-Since": { - "modified": "2020-10-15T21:55:01.333Z", - "contributors": [ - "wangtongchao", - "WayneCui" - ] - }, - "Web/HTTP/Headers/If-None-Match": { - "modified": "2020-10-15T21:54:59.997Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/If-Range": { - "modified": "2020-10-15T21:51:54.830Z", - "contributors": [ - "Froguard", - "LiuTong" - ] - }, - "Web/HTTP/Headers/If-Unmodified-Since": { - "modified": "2020-10-15T21:54:37.820Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Index": { - "modified": "2019-08-30T03:36:19.849Z", - "contributors": [ - "whuhyw" - ] - }, - "Web/HTTP/Headers/Keep-Alive": { - "modified": "2020-10-15T21:55:00.550Z", - "contributors": [ - "zhangchen", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Large-Allocation": { - "modified": "2020-10-15T21:56:09.177Z", - "contributors": [ - "wyapx", - "crper", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Last-Modified": { - "modified": "2020-10-15T21:55:00.234Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Link": { - "modified": "2020-10-15T22:20:52.111Z", - "contributors": [ - "pangyujie" - ] - }, - "Web/HTTP/Headers/Location": { - "modified": "2020-10-15T21:54:51.524Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Origin": { - "modified": "2020-10-15T21:53:11.797Z", - "contributors": [ - "JasonJunJun", - "yuankunzhang" - ] - }, - "Web/HTTP/Headers/Pragma": { - "modified": "2020-10-15T21:54:59.607Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Proxy-Authenticate": { - "modified": "2019-03-23T22:10:44.148Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Proxy-Authorization": { - "modified": "2019-03-23T22:10:44.333Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Public-Key-Pins": { - "modified": "2020-10-15T21:55:02.367Z", - "contributors": [ - "shevacjs", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Public-Key-Pins-Report-Only": { - "modified": "2020-10-15T22:04:11.647Z", - "contributors": [ - "ujsxn", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Range": { - "modified": "2020-10-15T21:54:38.123Z", - "contributors": [ - "Meteormatt", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Referer": { - "modified": "2020-10-15T21:55:01.465Z", - "contributors": [ - "xiaozhaofu", - "yenshen", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Referrer-Policy": { - "modified": "2020-10-15T21:54:58.993Z", - "contributors": [ - "gadflysu", - "WeihanLi", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Retry-After": { - "modified": "2020-10-15T21:54:59.380Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Save-Data": { - "modified": "2020-10-15T22:21:57.010Z", - "contributors": [ - "Mulan", - "fuxingZhang" - ] - }, - "Web/HTTP/Headers/Sec-Fetch-Dest": { - "modified": "2020-10-17T03:01:57.521Z", - "contributors": [ - "hebing0415", - "hellorayza" - ] - }, - "Web/HTTP/Headers/Sec-Fetch-Mode": { - "modified": "2020-10-15T22:31:17.439Z", - "contributors": [ - "EbeRybDI", - "haolayo" - ] - }, - "Web/HTTP/Headers/Sec-Fetch-Site": { - "modified": "2020-10-15T22:32:55.276Z", - "contributors": [ - "EbeRybDI" - ] - }, - "Web/HTTP/Headers/Sec-Fetch-User": { - "modified": "2020-10-15T22:32:45.194Z", - "contributors": [ - "EbeRybDI" - ] - }, - "Web/HTTP/Headers/Sec-WebSocket-Accept": { - "modified": "2020-10-15T22:11:54.497Z", - "contributors": [ - "Greenstorm" - ] - }, - "Web/HTTP/Headers/Server": { - "modified": "2020-10-15T21:54:58.617Z", - "contributors": [ - "yenshen", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Server-Timing": { - "modified": "2020-10-15T22:22:26.582Z", - "contributors": [ - "Mulan", - "laingke" - ] - }, - "Web/HTTP/Headers/Set-Cookie": { - "modified": "2020-10-15T21:54:55.958Z", - "contributors": [ - "wenlonghuo", - "superATM", - "royIdoodle", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Set-Cookie/SameSite": { - "modified": "2020-10-15T22:28:42.430Z", - "contributors": [ - "EbeRybDI", - "tinaawang" - ] - }, - "Web/HTTP/Headers/Set-Cookie2": { - "modified": "2020-10-15T21:54:57.437Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/SourceMap": { - "modified": "2020-10-15T21:55:30.390Z", - "contributors": [ - "Pada" - ] - }, - "Web/HTTP/Headers/TE": { - "modified": "2020-10-15T21:54:38.379Z", - "contributors": [ - "ujsxn", - "shevacjs", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Timing-Allow-Origin": { - "modified": "2020-10-15T21:58:04.341Z", - "contributors": [ - "firesun", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Tk": { - "modified": "2019-03-23T22:07:59.446Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Trailer": { - "modified": "2020-10-15T21:54:41.193Z", - "contributors": [ - "yuankunzhang", - "WayneCui" - ] - }, - "Web/HTTP/Headers/Transfer-Encoding": { - "modified": "2020-10-15T21:54:37.943Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/Upgrade-Insecure-Requests": { - "modified": "2020-10-15T21:55:00.901Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/User-Agent": { - "modified": "2020-10-15T21:55:01.835Z", - "contributors": [ - "RainSlide", - "zidian257", - "wangshi3", - "qwqmeow", - "AaronGod", - "WayneCui" - ] - }, - "Web/HTTP/Headers/User-Agent/Firefox": { - "modified": "2019-03-18T21:31:55.000Z", - "contributors": [ - "RainSlide", - "konrumi" - ] - }, - "Web/HTTP/Headers/Vary": { - "modified": "2020-10-15T21:53:14.511Z", - "contributors": [ - "swanf", - "WayneCui", - "ujsxn", - "newhuan" - ] - }, - "Web/HTTP/Headers/Via": { - "modified": "2020-10-15T21:54:55.047Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/WWW-Authenticate": { - "modified": "2020-09-03T05:56:40.972Z", - "contributors": [ - "EbeRybDI", - "zslucky" - ] - }, - "Web/HTTP/Headers/Warning": { - "modified": "2020-10-15T21:55:02.128Z", - "contributors": [ - "liaozhaonan", - "WayneCui" - ] - }, - "Web/HTTP/Headers/X-Content-Type-Options": { - "modified": "2020-10-15T21:54:52.946Z", - "contributors": [ - "kidonng", - "kbyyd24", - "WayneCui" - ] - }, - "Web/HTTP/Headers/X-Forwarded-For": { - "modified": "2019-03-23T22:11:03.571Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/X-Forwarded-Host": { - "modified": "2019-03-23T22:10:57.844Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Headers/X-Forwarded-Proto": { - "modified": "2019-03-23T22:11:05.199Z", - "contributors": [ - "hbbalfred", - "WayneCui" - ] - }, - "Web/HTTP/Headers/X-XSS-Protection": { - "modified": "2020-10-15T21:53:06.446Z", - "contributors": [ - "weibangtuo", - "kidonng", - "yenshen", - "WayneCui", - "oopsguy", - "xgqfrms-GitHub" - ] - }, - "Web/HTTP/Link_prefetching_FAQ": { - "modified": "2019-10-09T13:08:42.395Z", - "contributors": [ - "Yayure", - "vivaxy", - "iamyy", - "xgqfrms-GitHub" - ] - }, - "Web/HTTP/Messages": { - "modified": "2020-04-19T05:44:17.609Z", - "contributors": [ - "liangmuyang", - "HardcorePhysician", - "keifergu", - "ziyunfei", - "gbcwbz", - "JsonLi" - ] - }, - "Web/HTTP/Methods": { - "modified": "2020-10-15T21:49:13.002Z", - "contributors": [ - "yzb161114", - "zhuangyin", - "xgqfrms-GitHub", - "fscholz", - "cissoid" - ] - }, - "Web/HTTP/Methods/CONNECT": { - "modified": "2020-10-15T21:55:02.299Z", - "contributors": [ - "champkeh", - "WayneCui" - ] - }, - "Web/HTTP/Methods/DELETE": { - "modified": "2020-10-15T21:54:31.457Z", - "contributors": [ - "fnjoe", - "yzweb2018", - "horsefaced", - "Ende93", - "WayneCui", - "xgqfrms-GitHub" - ] - }, - "Web/HTTP/Methods/GET": { - "modified": "2020-10-15T21:49:15.328Z", - "contributors": [ - "joy-yu", - "Ende93", - "fscholz", - "cissoid" - ] - }, - "Web/HTTP/Methods/HEAD": { - "modified": "2020-10-15T21:49:15.693Z", - "contributors": [ - "liveabean", - "iugo", - "fscholz", - "horsefaced", - "cissoid" - ] - }, - "Web/HTTP/Methods/OPTIONS": { - "modified": "2020-10-15T21:53:13.191Z", - "contributors": [ - "safarishi", - "yuankunzhang" - ] - }, - "Web/HTTP/Methods/PATCH": { - "modified": "2019-03-23T22:11:06.658Z", - "contributors": [ - "Ende93", - "WayneCui" - ] - }, - "Web/HTTP/Methods/POST": { - "modified": "2020-10-15T21:49:12.507Z", - "contributors": [ - "weapon-x", - "cracdic", - "wangtongchao", - "mySoul", - "shellphon", - "fscholz", - "cissoid" - ] - }, - "Web/HTTP/Methods/PUT": { - "modified": "2020-10-15T21:54:38.885Z", - "contributors": [ - "lnh", - "maicss", - "WayneCui" - ] - }, - "Web/HTTP/Methods/TRACE": { - "modified": "2020-10-15T22:06:09.943Z", - "contributors": [ - "chenaptx", - "fs523577192", - "ppphp" - ] - }, - "Web/HTTP/Overview": { - "modified": "2020-11-10T09:12:40.960Z", - "contributors": [ - "pocketdr", - "bkuke", - "hehe1111", - "Umryuan", - "yuyuanqiu", - "psaren", - "wakaoniganma", - "BobGreen", - "hiyoushu", - "LuoYun", - "RayJune", - "Akiq2016", - "zihengCat", - "usernameisMan", - "Ende93", - "w11th", - "joezheng", - "MagicLee" - ] - }, - "Web/HTTP/Protocol_upgrade_mechanism": { - "modified": "2020-11-12T12:36:28.458Z", - "contributors": [ - "yan647", - "Xiaosha61", - "mayunmeiyouming", - "nientsu", - "raunyuyuan", - "wc5858" - ] - }, - "Web/HTTP/Proxy_servers_and_tunneling": { - "modified": "2020-08-19T02:44:17.258Z", - "contributors": [ - "SunnyWind", - "0229xiang", - "teoli" - ] - }, - "Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file": { - "modified": "2020-10-30T02:28:12.093Z", - "contributors": [ - "StudentMain", - "Nishikinor", - "DuckSoft", - "Futrime", - "hryen", - "RainSlide", - "maber", - "cnryb", - "archerc", - "msy" - ] - }, - "Web/HTTP/Public_Key_Pinning": { - "modified": "2020-10-15T22:15:40.587Z", - "contributors": [ - "Yayure" - ] - }, - "Web/HTTP/Range_requests": { - "modified": "2019-03-23T22:10:18.914Z", - "contributors": [ - "huangtt", - "heyv5", - "warmilk", - "asurin", - "WayneCui" - ] - }, - "Web/HTTP/Redirections": { - "modified": "2020-06-22T12:27:42.624Z", - "contributors": [ - "RoXoM", - "BobGreen", - "shevacjs", - "yenshen", - "WayneCui", - "ziyunfei", - "mushang11", - "zhi.lin", - "ZhongyiChen" - ] - }, - "Web/HTTP/Resources_and_URIs": { - "modified": "2019-09-05T00:27:21.660Z", - "contributors": [ - "ran" - ] - }, - "Web/HTTP/Resources_and_specifications": { - "modified": "2019-03-23T22:14:32.179Z", - "contributors": [ - "ppphp", - "shevacjs", - "yuankunzhang" - ] - }, - "Web/HTTP/Server-Side_Access_Control": { - "modified": "2019-03-23T23:14:41.414Z", - "contributors": [ - "GerryLon", - "xgqfrms-GitHub", - "holynewbie", - "jearylee" - ] - }, - "Web/HTTP/Session": { - "modified": "2019-08-30T04:49:50.525Z", - "contributors": [ - "HardcorePhysician", - "2585479524", - "zihengCat", - "zhuangyin", - "keifergu", - "cissoid" - ] - }, - "Web/HTTP/Status": { - "modified": "2020-10-15T21:47:25.564Z", - "contributors": [ - "kendalbaba8", - "sideshowbarker", - "lesikolerina23", - "bifan", - "zhongjunyao", - "cznno", - "skylinebin", - "Opportunity", - "sluggishpj", - "Riverside", - "NowTime", - "konantian", - "PWAEZQS", - "corele", - "x1zbin", - "Zeng", - "teaist", - "zhuangyin", - "change-hdb", - "Geniusning", - "fscholz", - "fuchao2012" - ] - }, - "Web/HTTP/Status/100": { - "modified": "2020-10-15T21:49:13.185Z", - "contributors": [ - "fscholz", - "cissoid" - ] - }, - "Web/HTTP/Status/101": { - "modified": "2020-07-28T20:14:16.827Z", - "contributors": [ - "rockhamx", - "xiazhe", - "WayneCui" - ] - }, - "Web/HTTP/Status/103": { - "modified": "2020-10-15T22:20:13.143Z", - "contributors": [ - "TsingJyujing" - ] - }, - "Web/HTTP/Status/200": { - "modified": "2020-10-15T21:52:50.809Z", - "contributors": [ - "Yang_Hanlin", - "Limbo1223", - "yenshen", - "doterlin", - "mojiajuzi" - ] - }, - "Web/HTTP/Status/201": { - "modified": "2020-10-15T21:54:40.492Z", - "contributors": [ - "Dante_Zzzz", - "WayneCui" - ] - }, - "Web/HTTP/Status/202": { - "modified": "2019-03-23T22:10:36.745Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/203": { - "modified": "2019-03-23T22:10:30.257Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/204": { - "modified": "2020-10-15T21:51:39.388Z", - "contributors": [ - "xgqfrms", - "WayneCui", - "fscholz", - "abc950309" - ] - }, - "Web/HTTP/Status/205": { - "modified": "2019-03-23T22:10:24.312Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/206": { - "modified": "2020-10-15T21:54:17.456Z", - "contributors": [ - "WayneCui", - "xgqfrms-GitHub" - ] - }, - "Web/HTTP/Status/300": { - "modified": "2019-03-23T22:10:32.313Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/301": { - "modified": "2020-10-15T21:53:56.245Z", - "contributors": [ - "WayneCui", - "dyllen", - "ujsxn" - ] - }, - "Web/HTTP/Status/302": { - "modified": "2020-10-15T21:52:41.868Z", - "contributors": [ - "juzhiyuan", - "WayneCui", - "ziyunfei", - "ujsxn", - "07akioni" - ] - }, - "Web/HTTP/Status/303": { - "modified": "2020-10-15T21:53:57.078Z", - "contributors": [ - "ADTC", - "WayneCui", - "ujsxn" - ] - }, - "Web/HTTP/Status/304": { - "modified": "2020-10-15T21:53:56.017Z", - "contributors": [ - "MinimalistYing", - "piaoyuliang", - "maicss", - "ujsxn" - ] - }, - "Web/HTTP/Status/307": { - "modified": "2020-10-15T21:53:56.226Z", - "contributors": [ - "RainSlide", - "qwertyuiop6", - "WayneCui", - "ujsxn" - ] - }, - "Web/HTTP/Status/308": { - "modified": "2020-10-15T21:53:56.251Z", - "contributors": [ - "迷子碳", - "WayneCui", - "ujsxn" - ] - }, - "Web/HTTP/Status/400": { - "modified": "2019-03-23T22:14:37.056Z", - "contributors": [ - "WayneCui", - "zsirfs" - ] - }, - "Web/HTTP/Status/401": { - "modified": "2020-10-15T21:55:04.907Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/402": { - "modified": "2020-10-15T22:21:27.856Z", - "contributors": [ - "SphinxKnight", - "Craster", - "AlphaGir", - "youngseaz" - ] - }, - "Web/HTTP/Status/403": { - "modified": "2020-10-15T21:55:04.765Z", - "contributors": [ - "bobo.debila", - "iSakuraNyan", - "WayneCui" - ] - }, - "Web/HTTP/Status/404": { - "modified": "2020-10-15T21:55:04.823Z", - "contributors": [ - "bobo.debila", - "yenshen", - "WayneCui" - ] - }, - "Web/HTTP/Status/405": { - "modified": "2020-09-29T09:31:27.183Z", - "contributors": [ - "wonerlilo", - "sideshowbarker", - "lesikolerina23", - "nicholascw", - "yuankunzhang" - ] - }, - "Web/HTTP/Status/406": { - "modified": "2020-10-15T21:54:36.544Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/407": { - "modified": "2020-10-15T21:55:05.803Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/408": { - "modified": "2019-03-23T22:10:32.195Z", - "contributors": [ - "Juanni", - "WayneCui" - ] - }, - "Web/HTTP/Status/409": { - "modified": "2019-03-23T22:10:22.894Z", - "contributors": [ - "liaozhaonan", - "WayneCui" - ] - }, - "Web/HTTP/Status/410": { - "modified": "2020-10-15T21:53:57.979Z", - "contributors": [ - "yyz940922", - "ujsxn" - ] - }, - "Web/HTTP/Status/411": { - "modified": "2019-03-23T22:10:31.298Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/412": { - "modified": "2020-10-15T21:53:03.480Z", - "contributors": [ - "RainSlide", - "WayneCui", - "xgqfrms-GitHub", - "LangDonHJJ" - ] - }, - "Web/HTTP/Status/413": { - "modified": "2019-03-23T22:10:34.207Z", - "contributors": [ - "liaozhaonan", - "WayneCui" - ] - }, - "Web/HTTP/Status/414": { - "modified": "2019-03-23T22:10:20.896Z", - "contributors": [ - "liaozhaonan", - "jokechat", - "WayneCui" - ] - }, - "Web/HTTP/Status/415": { - "modified": "2019-03-23T22:10:21.961Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/416": { - "modified": "2020-10-15T21:54:41.290Z", - "contributors": [ - "liaozhaonan", - "WayneCui" - ] - }, - "Web/HTTP/Status/417": { - "modified": "2019-03-23T22:11:26.822Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/418": { - "modified": "2020-10-15T22:03:59.306Z", - "contributors": [ - "iSakuraNyan", - "dzamlo", - "ujsxn", - "youngseaz" - ] - }, - "Web/HTTP/Status/422": { - "modified": "2019-10-08T22:59:23.853Z", - "contributors": [ - "fuxingZhang", - "SphinxKnight", - "uniforest", - "ihgazni2" - ] - }, - "Web/HTTP/Status/425": { - "modified": "2020-10-15T22:09:53.408Z", - "contributors": [ - "liaozhaonan", - "ibard" - ] - }, - "Web/HTTP/Status/426": { - "modified": "2019-03-23T22:10:22.184Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/428": { - "modified": "2019-03-23T22:11:11.819Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/429": { - "modified": "2019-03-23T22:11:18.935Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/431": { - "modified": "2019-03-23T22:10:21.832Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/451": { - "modified": "2020-10-15T21:55:07.508Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/500": { - "modified": "2020-10-15T21:55:08.324Z", - "contributors": [ - "danmurch77", - "sideshowbarker", - "lesikolerina23", - "davywsr", - "slivenred", - "RainSlide", - "WayneCui", - "ziyunfei", - "aosan002" - ] - }, - "Web/HTTP/Status/501": { - "modified": "2020-10-15T21:52:25.911Z", - "contributors": [ - "WayneCui", - "fscholz", - "hxl" - ] - }, - "Web/HTTP/Status/502": { - "modified": "2020-10-15T21:55:11.141Z", - "contributors": [ - "davywsr", - "iSakuraNyan", - "slivenred", - "wangtongchao", - "WayneCui" - ] - }, - "Web/HTTP/Status/503": { - "modified": "2020-10-15T21:55:07.373Z", - "contributors": [ - "davywsr", - "slivenred", - "WayneCui" - ] - }, - "Web/HTTP/Status/504": { - "modified": "2020-10-15T21:55:08.765Z", - "contributors": [ - "davywsr", - "slivenred", - "WayneCui" - ] - }, - "Web/HTTP/Status/505": { - "modified": "2019-03-23T22:10:20.789Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/Status/506": { - "modified": "2020-01-19T03:41:58.311Z", - "contributors": [ - "radarfyh" - ] - }, - "Web/HTTP/Status/507": { - "modified": "2020-01-19T03:58:16.574Z", - "contributors": [ - "radarfyh" - ] - }, - "Web/HTTP/Status/508": { - "modified": "2020-01-19T04:02:35.671Z", - "contributors": [ - "radarfyh" - ] - }, - "Web/HTTP/Status/510": { - "modified": "2020-01-19T04:08:53.633Z", - "contributors": [ - "radarfyh" - ] - }, - "Web/HTTP/Status/511": { - "modified": "2019-03-23T22:10:19.671Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/HTTP/X-Frame-Options": { - "modified": "2020-10-15T21:31:36.643Z", - "contributors": [ - "RainSlide", - "Soyaine", - "Fiag" - ] - }, - "Web/HTTP/data_URIs": { - "modified": "2020-10-15T21:06:54.948Z", - "contributors": [ - "leegent", - "2585479524", - "BobGreen", - "bramblex", - "tlos142857", - "Ende93", - "xgqfrms-GitHub", - "little-tomorrow", - "ziyunfei" - ] - }, - "Web/HTTP/策略特征": { - "modified": "2020-10-15T22:13:12.541Z", - "contributors": [ - "xiaomaokeke", - "chenqingyue", - "RainSlide", - "joechan" - ] - }, - "Web/HTTP/策略特征/Using_Feature_Policy": { - "modified": "2019-05-06T05:13:36.251Z", - "contributors": [ - "roostinghawk" - ] - }, - "Web/HTTP/跨域资源共享(CORS)_": { - "modified": "2020-10-15T22:28:24.198Z", - "contributors": [ - "huangjihua" - ] - }, - "Web/Houdini": { - "modified": "2020-11-21T05:08:58.458Z", - "contributors": [ - "xusy", - "bingoYB", - "cutefcc", - "sunfeel", - "xgqfrms" - ] - }, - "Web/JavaScript": { - "modified": "2020-09-21T00:46:20.876Z", - "contributors": [ - "mkckr0", - "sengang", - "SeaAster", - "liunanchenFYJJ", - "SphinxKnight", - "iworkerweb", - "lifankohome", - "huhufufu", - "marslord", - "leo_yang", - "zhao_nanli", - "limingqian", - "xunyegege", - "price", - "konantian", - "xclhs", - "qazsweet", - "Frederick-S", - "fenyu", - "ZengYu", - "toyflivver", - "yonbo", - "ThomasWhyne", - "pluwen", - "loveagri", - "edwards1101", - "ngtmuzi", - "wemamawe", - "danmin25", - "ghb609840612", - "zxsunrise", - "wangwenhao", - "WinnerNew", - "yokiyang", - "XuQuan-nikkkki", - "Jonham", - "ElliottZheng", - "towerman1990", - "qdlaoyao", - "yong_a", - "sqchenxiyuan", - "ZhangQiRong", - "lixw1994", - "qyjs", - "zhangchen", - "baooab", - "Mr-Li-admin", - "shaodahong", - "marsoln", - "Cnmahj", - "lemonsWen", - "lppking", - "viko16", - "leafdog", - "Ende93", - "VdoG", - "xiaokk06", - "xgqfrms", - "Rusion-Wayne", - "xiaoyusilen", - "Moressette", - "simongfxu", - "eforegist", - "nperhb", - "wth", - "WentaoMa", - "Roland_Reed", - "leonine", - "stdupp", - "lunix01", - "sammuelyee", - "MMOnster", - "redman9", - "wangsai", - "flyingdew", - "Yaty", - "yenshen", - "apollo", - "azzndmy", - "yiding_he", - "Brainor", - "ReyCG_sub", - "teoli", - "7anshuai", - "xcffl", - "ziyunfei", - "Asvel", - "sonzero@163.com", - "xiaoxiong", - "iwo", - "lins05" - ] - }, - "Web/JavaScript/A_re-introduction_to_JavaScript": { - "modified": "2020-11-25T02:59:29.704Z", - "contributors": [ - "SphinxKnight", - "BruceHong666", - "koo4", - "hechenxi", - "hufeicom", - "eMUQI", - "houfengqaz", - "licia-tia", - "necokeine", - "Pro-A", - "TianLangStudio", - "Frederick-S", - "123Jonne", - "fenglui", - "RainSlide", - "zhaoke2018", - "coldfog", - "edenpan", - "kanaza", - "LeoB-O", - "panle666", - "SAM.L", - "YRFT", - "Park-ma", - "LuoYun", - "mysmlz", - "OldisNewXrf", - "Jiasm", - "HoldDie", - "byoungd", - "TheLostXianXian", - "RockJerffreason", - "JayceZhang9602", - "funnyChinese", - "liubiantao", - "suxiesumiao", - "Jack-Q", - "w-halo", - "marsoln", - "Poisonloc", - "ngtmuzi", - "pramper", - "wangbin2015", - "Ende93", - "machao", - "Tienyz", - "susutou", - "xlyimi", - "ziyunfei", - "arniu", - "Breezewish", - "ticketock", - "teoli", - "xuxun", - "Joe_Zhao", - "xcffl", - "ethertank", - "Mgjbot", - "Physacco", - "Carrie zhxj", - "Laser" - ] - }, - "Web/JavaScript/About_JavaScript": { - "modified": "2020-03-12T19:36:16.731Z", - "contributors": [ - "Poisonloc", - "ziyunfei", - "Breezewish", - "gelin", - "teoli", - "Meteormatt", - "ethertank", - "undercooled" - ] - }, - "Web/JavaScript/Closures": { - "modified": "2020-10-14T01:19:42.853Z", - "contributors": [ - "Neo42", - "sunan112", - "xuqian", - "xvusrmqj", - "Lazy_Bone", - "mkckr0", - "fish-inu", - "Nonym", - "kingsley2036", - "watsonhaw", - "LuoYun", - "maoyumaoxun", - "HongjinLI", - "dreampasssser", - "foshhh", - "Akiq2016", - "szengtal", - "zhang-hongwei", - "helloli", - "xgqfrms-GitHub", - "ziyunfei", - "zhuangyin", - "springfish", - "ZZES_REN", - "righttoe", - "hiyoushu", - "KngZhi", - "eeeeeeeason", - "HeSijie", - "calidion", - "mr.code", - "lihx_hit", - "_da", - "xgqfrms", - "wth", - "Jack-Q", - "distums", - "Poisonloc", - "mysticzap", - "vino24", - "putdownTheCode", - "yang.rc", - "maybe", - "fskuok", - "devyps", - "Breezewish", - "phoenix.huang", - "kangkai92", - "teoli", - "hui314", - "rogersuen" - ] - }, - "Web/JavaScript/Data_structures": { - "modified": "2020-06-05T03:23:50.915Z", - "contributors": [ - "zangbianxuegu", - "wallena3", - "Logan-Li", - "xuanji", - "huxinsen", - "molee1905", - "WangLeto", - "wemamawe", - "ywjco", - "ShirleyM", - "wblovezqy", - "eyasliu", - "issliu", - "hangyangws", - "Musan", - "Ende93", - "eric183", - "Jacobwang", - "knightf", - "JsonMe", - "asdzxcqwe", - "holsety", - "Breezewish", - "ElsaHuang", - "7anshuai", - "teoli", - "keechi", - "polucy", - "_WhiteCusp" - ] - }, - "Web/JavaScript/Enumerability_and_ownership_of_properties": { - "modified": "2020-08-31T07:44:40.404Z", - "contributors": [ - "unbyte", - "RainSlide", - "leavesster", - "Ende93", - "walfud", - "funroller", - "monjer", - "Gaohaoyang", - "xiefei89", - "Jack-Q", - "ziyunfei", - "yenshen" - ] - }, - "Web/JavaScript/Equality_comparisons_and_sameness": { - "modified": "2020-10-17T07:01:49.622Z", - "contributors": [ - "jaredhan418", - "zjffun", - "RenzHoly", - "gongzhibin", - "xiayao", - "esphas", - "dy21335", - "Charlotte007", - "fun3c", - "Ende93", - "xgqfrms-GitHub", - "vincenting", - "Roland_Reed", - "Jack-Q", - "ngtmuzi", - "i-PeterZhang", - "xufeng", - "ziyunfei", - "fskuok", - "tiansh", - "faceach", - "ilia" - ] - }, - "Web/JavaScript/EventLoop": { - "modified": "2020-08-12T23:49:07.122Z", - "contributors": [ - "JobbyM", - "johnao", - "penglianglee", - "molee1905", - "sundi78634", - "xgl", - "SterileSummer", - "esphas", - "daxiazilong", - "zhangchen", - "Thoxvi", - "zhuangyin", - "LeoSpark", - "mozhs", - "xgqfrms-GitHub", - "LiXin", - "xycd", - "hxyoo1990", - "guoqiang", - "fengma", - "Ende93", - "xiaojichao", - "liyongleihf2006", - "slayerxj", - "timwangdev", - "distums", - "xufeng", - "ziyunfei", - "jcouyang", - "shinv", - "lcxfs1991", - "HectorGuo", - "Fantasy_shao" - ] - }, - "Web/JavaScript/Getting_Started": { - "modified": "2019-03-23T23:35:23.323Z", - "contributors": [ - "xCss", - "KMethod", - "lifeng", - "maslak", - "Eridanus_Sora", - "ywang1724", - "reygreen1", - "teoli", - "Lyper", - "Simontechwriter" - ] - }, - "Web/JavaScript/Guide": { - "modified": "2020-04-10T23:43:33.112Z", - "contributors": [ - "lyno", - "RainSlide", - "Soy", - "Wenfang_Du", - "mumu-one", - "xuziang111", - "miffy24", - "shannonZhong", - "bowen-wu", - "Pomelo1213", - "Jamamm", - "xiaozhi1", - "bibi941", - "zhumengyua", - "XINHE", - "frankfang1990", - "zhangchen", - "santong", - "Grizzly-Eric", - "WavinFlag", - "Moressette", - "nperhb", - "yenshen", - "ngtmuzi", - "taccelerate", - "456wyc", - "lunix01", - "kacoro", - "ssbunny", - "wsxyeah", - "teoli", - "ziyunfei", - "rogersuen" - ] - }, - "Web/JavaScript/Guide/About": { - "modified": "2019-03-23T23:36:14.591Z", - "contributors": [ - "wbamberg", - "Breezewish", - "ReyCG_sub", - "ReyCG", - "teoli", - "LieGroup", - "rogersuen" - ] - }, - "Web/JavaScript/Guide/Control_flow_and_error_handling": { - "modified": "2020-03-12T19:37:58.561Z", - "contributors": [ - "ChenZhuoSteve", - "xclhs", - "fanqw", - "zhangchen", - "Hitomichan", - "sqchenxiyuan", - "123456zzz", - "zsxeee", - "xgqfrms-GitHub", - "cdz", - "lwxyfer", - "hpcherry", - "funnyChinese", - "ticketock", - "anbang", - "xdsnet", - "codetaro", - "think3t", - "Moressette", - "eforegist", - "boredivan", - "kavon", - "victor0801x", - "eating_miao", - "tangolivesky", - "zouyonghao", - "GodEngine", - "binhex", - "lushunming", - "MurphyL", - "zhaozhb", - "DeepDarkSpirit", - "kictpov", - "wenxiangmao", - "gabrielwu", - "tao0923", - "wolfFN", - "wangxb", - "ziyunfei", - "tonypupp", - "Shimo", - "teoli" - ] - }, - "Web/JavaScript/Guide/Details_of_the_Object_Model": { - "modified": "2020-07-21T04:10:47.398Z", - "contributors": [ - "suvyme", - "johnao", - "tzmf", - "zjffun", - "wbamberg", - "AlphaGo88", - "ThomasWhyne", - "yokiyang", - "zhangchen", - "MiRinZhang", - "Ende93", - "michelia", - "ywang1724", - "ReyCG", - "teoli", - "key", - "ziyunfei", - "zsytssk", - "rogersuen" - ] - }, - "Web/JavaScript/Guide/Expressions_and_Operators": { - "modified": "2020-07-02T00:51:30.893Z", - "contributors": [ - "Ende93", - "bifan", - "ZhQb", - "maoyumaoxun", - "LuoYun", - "yuansuye", - "syhxczy", - "zhangchen", - "bozh", - "lociver", - "vividlai", - "vincenting", - "choury", - "wenmin92", - "_da", - "zhaoge26", - "chenpeiguang", - "codetaro", - "Gohikin", - "sgr", - "bigzhao", - "imDemo", - "klutzCoder", - "cinside", - "chuanyidai", - "eddy8", - "kavon", - "victor0801x", - "ngtmuzi", - "xoyoz", - "RachelChen", - "zenzzy", - "wumouse", - "Toweave", - "wenxiangmao", - "mpchina", - "z_p_p", - "997404959", - "Frantic1048", - "teoli", - "LieGroup", - "sevens", - "john_li", - "carl_zhu", - "ziyunfei" - ] - }, - "Web/JavaScript/Guide/Functions": { - "modified": "2020-09-16T04:44:03.700Z", - "contributors": [ - "springwq", - "johnao", - "YooHoeh", - "narutojian", - "chrisdavidmills", - "yulongjing", - "white-more", - "Jzhuonan", - "vainl", - "putongxiaozhu", - "yuansuye", - "Phoenix13", - "SphinxKnight", - "NotDead-NotPerish", - "zhangchen", - "ian.zhang", - "xgqfrms-GitHub", - "wenmin92", - "codetaro", - "appie963", - "caicaicai", - "Darkoe", - "victor0801x", - "helloguangxue", - "tangolivesky", - "wumouse", - "Ende93", - "SamuraiMe", - "duckisaac", - "ziyunfei", - "Cjavaer", - "snowsolf", - "lvjs", - "smartkid", - "teoli", - "sunorry", - "iwo" - ] - }, - "Web/JavaScript/Guide/Grammar_and_types": { - "modified": "2020-10-01T04:36:59.031Z", - "contributors": [ - "dva2019ksy", - "junhaoim", - "SirnoChan", - "Meow-z", - "catlair", - "WoodCube", - "lorry0508", - "ronesam", - "inlym", - "AlphaGo88", - "strandjun", - "hgbj0001", - "vainl", - "goodqd", - "yuansuye", - "zxsunrise", - "hiyoushu", - "zhumengyua", - "runyul", - "shelleyIstar", - "superkuang", - "BlasphemerAzog", - "Timer", - "tjyas", - "xgqfrms-GitHub", - "zxsky1", - "cdz", - "Taisetsuz", - "Arthur.CHANG", - "Seattle", - "faremax", - "fengma", - "xdsnet", - "codetaro", - "VdoG", - "tylerxue", - "Ende93", - "zurl", - "Moressette", - "dsb123dsb", - "kangkai0124", - "koalaxiaot", - "eforegist", - "GoForWill", - "m4jing", - "gknpezgssb", - "evolighting", - "TruthBean", - "kavon", - "victor0801x", - "PoppinL", - "louwuxin", - "xioZquan", - "zhaozhb", - "zouyonghao", - "ziyunfei", - "amIurs", - "gabrielwu", - "kacoro", - "tiansh", - "ReyCG_sub", - "teoli", - "LieGroup", - "evantre", - "iwo" - ] - }, - "Web/JavaScript/Guide/Indexed_collections": { - "modified": "2020-06-29T06:11:51.519Z", - "contributors": [ - "MaZheng", - "amzrk2", - "keys", - "ruoxianbaby", - "aimishan", - "BUnnY25", - "LeoSpark", - "hpcherry", - "niccoming", - "xdsnet", - "kiyonlin", - "codetaro", - "caoruiy", - "suxiesumiao", - "victor0801x", - "zhulinpinyu", - "456wyc", - "gaigeshen", - "VincentLiu0314" - ] - }, - "Web/JavaScript/Guide/Introduction": { - "modified": "2020-07-30T09:11:33.207Z", - "contributors": [ - "Kirin", - "RainSlide", - "agulleung", - "inlym", - "daxiazilong", - "a358003542", - "ElliottZheng", - "runyul", - "123456zzz", - "wushengde", - "zhuangyin", - "lsbrucelincoln", - "seaHeater", - "_da", - "xdsnet", - "VdoG", - "xiaoyusilen", - "eforegist", - "Mosan", - "Joilence", - "LeoMobileDeveloper", - "m4jing", - "dunizb", - "solome", - "zhanglei1995", - "zhe13", - "Rambone", - "Ende93", - "majunbao", - "MurphyL", - "zouyonghao", - "zhengshi", - "fissh", - "pixiu", - "ssbunny", - "PhenixGhost", - "MrH2S", - "HopeCoder", - "ziyunfei", - "hackerZhang" - ] - }, - "Web/JavaScript/Guide/Iterators_and_Generators": { - "modified": "2020-04-19T03:41:05.778Z", - "contributors": [ - "Russell", - "johnao", - "NieLamu", - "SageX", - "Yayure", - "ErChuan", - "RainSlide", - "jupiterben", - "xgqfrms", - "Wuqichao", - "BingerWeb", - "yueshuiniao", - "zhangjiawei0", - "zhangchen", - "azoth1991", - "ezirmusitua", - "xgqfrms-GitHub", - "DarwinniwraD", - "kiyonlin", - "Howard.Chen", - "ianfung1998", - "liadbiz", - "snandy", - "teoli", - "ziyunfei", - "AriesDevil", - "Joyce" - ] - }, - "Web/JavaScript/Guide/JavaScript_Overview": { - "modified": "2019-03-23T23:36:14.828Z", - "contributors": [ - "MrMario", - "ReyCG_sub", - "teoli", - "LieGroup", - "rogersuen" - ] - }, - "Web/JavaScript/Guide/Keyed_collections": { - "modified": "2020-03-12T19:41:31.376Z", - "contributors": [ - "haoye999", - "Jiasm", - "zhangchen", - "jiahui", - "indux", - "supermanmsc", - "fengzhongye" - ] - }, - "Web/JavaScript/Guide/Loops_and_iteration": { - "modified": "2020-03-12T19:42:07.957Z", - "contributors": [ - "koor", - "narutojian", - "RainSlide", - "Wuqichao", - "SphinxKnight", - "zero_zero_zero", - "zhuangyin", - "Zheng7426", - "Bob_young", - "xiaowei.yang", - "johncido", - "xgqfrms-GitHub", - "xdsnet", - "codetaro", - "suxiesumiao", - "AcJoker", - "kavon", - "lushunming", - "MurphyL", - "wumouse", - "intuitionfly" - ] - }, - "Web/JavaScript/Guide/Meta_programming": { - "modified": "2020-10-06T11:58:28.618Z", - "contributors": [ - "SeekerGAO", - "suvyme", - "RainSlide", - "OStoneO", - "rikochyou", - "zhangchen", - "123456zzz", - "pamikel", - "xgqfrms-GitHub", - "hpcherry", - "zyMacro", - "cughudson_1", - "acekingke", - "binhex", - "FredWe" - ] - }, - "Web/JavaScript/Guide/Modules": { - "modified": "2020-10-15T22:19:12.670Z", - "contributors": [ - "ran", - "PPFei5Zhou", - "bkuke", - "StorytellerF", - "Yayure", - "narutojian", - "RainSlide", - "hotbaby" - ] - }, - "Web/JavaScript/Guide/Numbers_and_dates": { - "modified": "2020-10-07T06:12:34.217Z", - "contributors": [ - "antield", - "symant233", - "迷子碳", - "qazsweet", - "canyi1942", - "fenyu", - "adasqg", - "zms1995", - "trionfo1993", - "ShaderWind", - "vividlai", - "yonglezhou", - "DaiZhiTao", - "jitingsun", - "niccoming", - "xiaokk06", - "sgr", - "suxiesumiao", - "victor0801x", - "zhulinpinyu", - "williamchu123", - "ShiJianwen", - "zhe13", - "Toweave", - "Serifx", - "456wyc", - "wenxiangmao" - ] - }, - "Web/JavaScript/Guide/Regular_Expressions": { - "modified": "2020-11-07T12:19:15.360Z", - "contributors": [ - "hensonxu", - "imbriansun", - "Alibuibui", - "srq18211", - "symant233", - "MikeLeon23", - "antield", - "zytjs", - "jingkaimori", - "aliasliao", - "Clara-hy", - "yasen-wolf", - "cody343960591", - "PoppinL", - "cy234", - "RainSlide", - "pzjzeason", - "millionssss", - "iamwwc", - "Yayure", - "Checkson", - "crow-n", - "yadex", - "OlingCat", - "Fungzhe", - "ts0307", - "jianglinghao", - "SphinxKnight", - "AlexStacker", - "zhuangyin", - "Ahhaha233", - "yinsang", - "fengma", - "chenym1992", - "ataotao", - "lixingdecai", - "bmxklYzj", - "Frantic1048", - "hysunny", - "xgqfrms-GitHub", - "Ckc", - "Jeff-Kook", - "ljy", - "maoxiaoke", - "falltodis", - "codetaro", - "simongfxu", - "fanyj1994", - "huaxiabuluo", - "lvhao96", - "luobotang", - "yisibl", - "ngtmuzi", - "chen_wang", - "Ende93", - "sunshineMaria", - "snowsolf", - "sleep", - "Shimo", - "Guanjinke", - "teoli", - "sablib", - "thesadboy", - "devqin", - "jpuncle", - "xiaoxiong", - "ziyunfei" - ] - }, - "Web/JavaScript/Guide/Regular_Expressions/Assertions": { - "modified": "2020-11-07T12:07:11.701Z", - "contributors": [ - "hensonxu", - "srq18211", - "oxyg3n", - "zytjs", - "fish-inu", - "Dev_ljp", - "Xu-Angel", - "liuhao088" - ] - }, - "Web/JavaScript/Guide/Regular_Expressions/Boundaries": { - "modified": "2020-10-30T11:36:06.394Z", - "contributors": [ - "phone-burner" - ] - }, - "Web/JavaScript/Guide/Regular_Expressions/Character_Classes": { - "modified": "2020-06-28T13:35:45.679Z", - "contributors": [ - "srq18211" - ] - }, - "Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges": { - "modified": "2020-08-21T07:28:58.610Z", - "contributors": [ - "srq18211" - ] - }, - "Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes": { - "modified": "2020-07-11T06:10:35.787Z", - "contributors": [ - "zkmbdbbdd" - ] - }, - "Web/JavaScript/Guide/Regular_Expressions/量词": { - "modified": "2020-06-28T13:50:25.946Z", - "contributors": [ - "srq18211" - ] - }, - "Web/JavaScript/Guide/Text_formatting": { - "modified": "2020-07-13T05:48:34.741Z", - "contributors": [ - "laampui", - "zhangchen", - "niccoming", - "evolighting", - "i-PeterZhang", - "456wyc", - "redman9", - "guangxiyu" - ] - }, - "Web/JavaScript/Guide/Using_promises": { - "modified": "2020-09-28T05:37:42.938Z", - "contributors": [ - "Radix10", - "xuquentinyang", - "HashiKudo", - "brizer", - "iEmcc", - "johnao", - "abellong", - "SAM.L", - "RainSlide", - "VickyJin", - "jessica1990", - "TeabugCC", - "zhuangyin", - "ujsxn", - "huixisheng", - "yulongjing", - "rxliuli", - "yonoel", - "DevOps", - "brandonhyc", - "eeeecw", - "zotille", - "xuziang111", - "NN708", - "xuxun", - "zhangchen", - "Evoque", - "Pythonofsdc", - "vanishcode", - "winjeysong", - "cwc7233", - "TimmyKingFree" - ] - }, - "Web/JavaScript/Guide/Working_with_Objects": { - "modified": "2020-03-21T00:54:40.101Z", - "contributors": [ - "johnao", - "fish-inu", - "ngtmuzi", - "Pomelo1213", - "ywjco", - "kramon", - "kgojiwong", - "xgqfrms-GitHub", - "heliangb46", - "Grizzly-Eric", - "zhanglianxin", - "coderfee", - "kiyonlin", - "IrisZhang", - "xwartz", - "Darkoe", - "XueSeason", - "jigs12", - "ReyCG_sub", - "smartkid", - "teoli", - "koala", - "ziyunfei" - ] - }, - "Web/JavaScript/Inheritance_and_the_prototype_chain": { - "modified": "2020-10-20T00:17:44.610Z", - "contributors": [ - "jack_chen", - "Nirvana-zsy", - "PiersZhang", - "YTInMyHeart", - "熊英明", - "AaronZzz", - "hydra-zim", - "demongodYY", - "c932828964", - "maozhenyu123", - "NicholasKong", - "Huangyilin19", - "MonkingStand", - "RainSlide", - "xulinggege", - "Rayyh", - "glud123", - "HuangXiZhou", - "Ieeebruce", - "Snailight", - "yonoel", - "lllbahol", - "ssttii", - "xgqfrms", - "DPJune1", - "MQpeng", - "yangzi", - "zhuangyin", - "anglli", - "Akiq2016", - "jeasonstudio", - "Sevenskey", - "LiXin", - "qiu_han", - "zhangchen", - "keifergu", - "jiangzhenggeng", - "DendiSe7enGitHub", - "zenith7ryu", - "feiyuabc", - "KngZhi", - "xgqfrms-GitHub", - "efeencheung", - "TwinkleLeon", - "jyjz2008", - "Mrzouning", - "craney", - "Ende93", - "nanflower", - "Ares_Xu", - "RenzHoly", - "xiaokk06", - "Musan", - "Downpooooour", - "maicss", - "iplus26", - "gavinjs", - "ziyunfei", - "hbkdsm", - "hipop", - "860136", - "Tranch", - "ReyCG", - "teoli", - "hutuxu" - ] - }, - "Web/JavaScript/Introduction_to_Object-Oriented_JavaScript": { - "modified": "2020-03-12T19:38:08.916Z", - "contributors": [ - "huijing", - "SAM.L", - "NarK", - "umiyevol", - "daix6", - "ashjs", - "sabrinaluo", - "xanarry", - "fskuok", - "hackerZhang", - "hipop", - "jamesliuhk", - "awp0011", - "ryanouyang", - "yiding_he", - "teoli", - "yimity", - "shiyutang", - "xcffl" - ] - }, - "Web/JavaScript/Introduction_to_using_XPath_in_JavaScript": { - "modified": "2019-03-23T23:53:50.408Z", - "contributors": [ - "chrisdavidmills", - "zhanglianxin", - "zengguanming", - "fscholz", - "ziyunfei", - "Cuimingda" - ] - }, - "Web/JavaScript/JavaScript_technologies_overview": { - "modified": "2020-03-12T19:38:44.101Z", - "contributors": [ - "RainSlide", - "zhanglianxin", - "lunix01", - "Musan", - "ReyCG_sub", - "teoli", - "YuQiang.Yuan" - ] - }, - "Web/JavaScript/Language_Resources": { - "modified": "2020-03-12T19:37:56.380Z", - "contributors": [ - "lunix01", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Memory_Management": { - "modified": "2020-03-12T19:38:33.297Z", - "contributors": [ - "y00rb", - "xueliang", - "leavesster", - "quding0308", - "liujuntao123", - "JuneDeng2014", - "ilexwg", - "DarrenMan", - "zhangchen", - "micooz", - "sunnylost", - "Ende93", - "wth", - "timwangdev", - "jackyKin", - "horizon0514", - "knightf", - "Bosn", - "teoli", - "Samoay", - "tank", - "jnoodle", - "Joe_Zhao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference": { - "modified": "2020-09-20T23:15:37.162Z", - "contributors": [ - "laampui", - "seanhuai", - "wwj402", - "RainSlide", - "ssttii", - "causal", - "zhangchen", - "Ende93", - "lunix01", - "ziyunfei", - "teoli", - "CHiENiUS", - "kovchou" - ] - }, - "Web/JavaScript/Reference/About": { - "modified": "2020-03-12T19:40:27.168Z", - "contributors": [ - "Jack-Q", - "lunix01", - "qlxiao520", - "ziyunfei", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Classes": { - "modified": "2020-11-21T07:35:29.331Z", - "contributors": [ - "xiaoxiao1024", - "xgqfrms", - "niices", - "showad", - "xuyimingwork", - "zytjs", - "brizer", - "johnao", - "PeanutQAQ", - "HermitSun", - "narutojian", - "JackDing1208", - "willerhehehe", - "zhangchen", - "llyo", - "LiXin", - "xgqfrms-GitHub", - "LouisaNikita", - "winjeysong", - "PhilTheAir", - "XiongAmao", - "kylezhang", - "tarma", - "Jeane", - "Ende93", - "miuchan", - "slientomorrr", - "ziyunfei", - "eric183", - "sartrey", - "snandy", - "bumaociyuan" - ] - }, - "Web/JavaScript/Reference/Classes/Class_elements": { - "modified": "2020-10-15T22:22:33.437Z", - "contributors": [ - "Fogwind", - "wxyads" - ] - }, - "Web/JavaScript/Reference/Classes/Private_class_fields": { - "modified": "2020-10-15T22:30:12.129Z", - "contributors": [ - "zhuangyin", - "symant233", - "wizard-intraining" - ] - }, - "Web/JavaScript/Reference/Classes/constructor": { - "modified": "2020-10-15T21:36:30.986Z", - "contributors": [ - "zhangchen", - "CJackYang", - "jiangseventeen", - "xgqfrms-GitHub", - "Ende93", - "destinyCherry", - "MarxJiao", - "chaooo", - "Lellansin" - ] - }, - "Web/JavaScript/Reference/Classes/extends": { - "modified": "2020-10-15T21:37:25.638Z", - "contributors": [ - "zhangchen", - "thinkershare", - "liuwj", - "xgqfrms-GitHub", - "MoYahoo", - "Ende93", - "xiaoweb", - "ziyunfei", - "TinyJiang", - "pixiu" - ] - }, - "Web/JavaScript/Reference/Classes/static": { - "modified": "2020-10-15T21:37:45.068Z", - "contributors": [ - "daijie", - "luna666", - "zhuangyin", - "xgqfrms-GitHub", - "zhangchen", - "hijiangtao", - "MrCuriosity", - "kameii", - "solome", - "ngtmuzi", - "willwong", - "knightf", - "lunix01" - ] - }, - "Web/JavaScript/Reference/Deprecated_and_obsolete_features": { - "modified": "2020-03-30T11:15:40.777Z", - "contributors": [ - "RainSlide", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Deprecated_and_obsolete_features/The_legacy_Iterator_protocol": { - "modified": "2020-03-12T19:44:37.222Z", - "contributors": [ - "wwj402", - "jwhitlock", - "lsvih" - ] - }, - "Web/JavaScript/Reference/Errors": { - "modified": "2020-03-12T19:43:37.546Z", - "contributors": [ - "Ende93", - "Jack-Q", - "sabertazimi" - ] - }, - "Web/JavaScript/Reference/Errors/Already_has_pragma": { - "modified": "2020-03-12T19:45:25.142Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Errors/Array_sort_argument": { - "modified": "2020-03-12T19:45:22.429Z", - "contributors": [ - "hui1993", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Bad_octal": { - "modified": "2020-03-12T19:45:19.888Z", - "contributors": [ - "WayneCui", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Bad_radix": { - "modified": "2020-03-12T19:44:42.812Z", - "contributors": [ - "xiaokk06" - ] - }, - "Web/JavaScript/Reference/Errors/Bad_regexp_flag": { - "modified": "2020-03-12T19:46:18.624Z", - "contributors": [ - "lazyboywu" - ] - }, - "Web/JavaScript/Reference/Errors/Bad_return_or_yield": { - "modified": "2020-03-12T19:44:37.026Z", - "contributors": [ - "wangmengjun", - "Cattla" - ] - }, - "Web/JavaScript/Reference/Errors/Called_on_incompatible_type": { - "modified": "2020-03-12T19:46:49.645Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init": { - "modified": "2020-03-12T19:46:25.675Z", - "contributors": [ - "kilodleif", - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Cant_access_property": { - "modified": "2020-03-12T19:48:25.216Z", - "contributors": [ - "zangguodong" - ] - }, - "Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible": { - "modified": "2020-03-12T19:46:26.772Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Cant_delete": { - "modified": "2020-03-12T19:45:31.865Z", - "contributors": [ - "lihx_hit", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Errors/Cant_redefine_property": { - "modified": "2020-03-12T19:46:26.214Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Cyclic_object_value": { - "modified": "2020-07-13T11:27:10.484Z", - "contributors": [ - "Mrdapeng", - "540692039", - "nansanhao", - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Dead_object": { - "modified": "2020-03-12T19:46:28.473Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Delete_in_strict_mode": { - "modified": "2020-03-12T19:46:25.179Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Deprecated_String_generics": { - "modified": "2020-03-12T19:46:39.182Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Deprecated_caller_or_arguments_usage": { - "modified": "2020-03-12T19:45:21.241Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Deprecated_expression_closures": { - "modified": "2020-03-12T19:46:34.964Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Deprecated_octal": { - "modified": "2020-03-12T19:46:39.086Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Deprecated_source_map_pragma": { - "modified": "2020-03-12T19:45:31.617Z", - "contributors": [ - "Kaede_Shinoda", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Deprecated_toLocaleFormat": { - "modified": "2020-03-12T19:46:45.691Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Equal_as_assign": { - "modified": "2020-03-12T19:44:21.268Z", - "contributors": [ - "niaodan2b" - ] - }, - "Web/JavaScript/Reference/Errors/For-each-in_loops_are_deprecated": { - "modified": "2020-03-12T19:45:01.286Z", - "contributors": [ - "_da" - ] - }, - "Web/JavaScript/Reference/Errors/Getter_only": { - "modified": "2020-03-12T19:46:35.397Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Identifier_after_number": { - "modified": "2020-03-12T19:46:01.632Z", - "contributors": [ - "AlanStewart6", - "fanxiaobin1992" - ] - }, - "Web/JavaScript/Reference/Errors/Illegal_character": { - "modified": "2020-03-12T19:46:25.974Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Invalid_array_length": { - "modified": "2020-03-12T19:44:25.874Z", - "contributors": [ - "xiaokk06", - "Hitomichan" - ] - }, - "Web/JavaScript/Reference/Errors/Invalid_assignment_left-hand_side": { - "modified": "2020-03-12T19:44:25.285Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Invalid_const_assignment": { - "modified": "2020-03-12T19:46:37.514Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Invalid_date": { - "modified": "2020-03-12T19:46:02.926Z", - "contributors": [ - "xiaokk06", - "kilodleif", - "dudusky" - ] - }, - "Web/JavaScript/Reference/Errors/Invalid_for-in_initializer": { - "modified": "2020-03-12T19:46:25.733Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Invalid_for-of_initializer": { - "modified": "2020-03-12T19:46:25.653Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/JSON_bad_parse": { - "modified": "2020-03-12T19:44:41.664Z", - "contributors": [ - "Ende93", - "imhaohao" - ] - }, - "Web/JavaScript/Reference/Errors/Malformed_URI": { - "modified": "2020-03-12T19:46:27.676Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Malformed_formal_parameter": { - "modified": "2020-03-12T19:45:20.875Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_bracket_after_list": { - "modified": "2020-03-12T19:45:17.108Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_colon_after_property_id": { - "modified": "2020-03-12T19:46:24.903Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_curly_after_function_body": { - "modified": "2020-03-12T19:46:26.744Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_curly_after_property_list": { - "modified": "2020-03-12T19:45:22.931Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_formal_parameter": { - "modified": "2020-03-12T19:46:22.522Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_initializer_in_const": { - "modified": "2020-03-12T19:46:26.113Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_name_after_dot_operator": { - "modified": "2020-03-12T19:46:26.813Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list": { - "modified": "2020-03-12T19:44:53.187Z", - "contributors": [ - "Idealist_EZ", - "VanLeon" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_parenthesis_after_condition": { - "modified": "2020-03-12T19:46:25.852Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Missing_semicolon_before_statement": { - "modified": "2020-03-12T19:44:58.615Z", - "contributors": [ - "Davont", - "jitingsun" - ] - }, - "Web/JavaScript/Reference/Errors/More_arguments_needed": { - "modified": "2020-03-12T19:45:18.099Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Negative_repetition_count": { - "modified": "2020-03-12T19:45:19.235Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/No_non-null_object": { - "modified": "2020-03-12T19:46:21.638Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/No_properties": { - "modified": "2020-03-12T19:45:01.030Z", - "contributors": [ - "lisniuse", - "jitingsun" - ] - }, - "Web/JavaScript/Reference/Errors/No_variable_name": { - "modified": "2020-03-12T19:46:26.272Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Non_configurable_array_element": { - "modified": "2020-03-12T19:46:26.810Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Not_a_codepoint": { - "modified": "2020-03-12T19:44:36.705Z", - "contributors": [ - "YYYxt", - "Cattla" - ] - }, - "Web/JavaScript/Reference/Errors/Not_a_constructor": { - "modified": "2020-03-12T19:45:22.496Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Not_a_function": { - "modified": "2020-06-13T05:01:42.941Z", - "contributors": [ - "kagurakana", - "Ende93", - "lisniuse" - ] - }, - "Web/JavaScript/Reference/Errors/Not_defined": { - "modified": "2020-06-19T20:36:57.807Z", - "contributors": [ - "oyyunttt", - "Veneno", - "yenshen", - "Zappa451", - "Hitomichan" - ] - }, - "Web/JavaScript/Reference/Errors/Precision_range": { - "modified": "2020-03-12T19:44:41.579Z", - "contributors": [ - "xiaokk06", - "Desmond", - "ihuguowei" - ] - }, - "Web/JavaScript/Reference/Errors/Property_access_denied": { - "modified": "2020-03-12T19:44:01.141Z", - "contributors": [ - "neal1991", - "Jack-Q" - ] - }, - "Web/JavaScript/Reference/Errors/Read-only": { - "modified": "2020-03-12T19:45:06.128Z", - "contributors": [ - "_da" - ] - }, - "Web/JavaScript/Reference/Errors/Redeclared_parameter": { - "modified": "2020-03-12T19:45:19.623Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Reduce_of_empty_array_with_no_initial_value": { - "modified": "2020-03-12T19:47:48.693Z", - "contributors": [ - "RainSlide", - "DarrenZhang01" - ] - }, - "Web/JavaScript/Reference/Errors/Reserved_identifier": { - "modified": "2020-03-12T19:46:21.461Z", - "contributors": [ - "123456zzz", - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Resulting_string_too_large": { - "modified": "2020-03-12T19:45:20.911Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Stmt_after_return": { - "modified": "2020-03-12T19:44:03.324Z", - "contributors": [ - "Jack-Q" - ] - }, - "Web/JavaScript/Reference/Errors/Strict_Non_Simple_Params": { - "modified": "2020-03-12T19:45:16.824Z", - "contributors": [ - "xgqfrms-GitHub", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Too_much_recursion": { - "modified": "2020-03-12T19:43:57.558Z", - "contributors": [ - "Jack-Q" - ] - }, - "Web/JavaScript/Reference/Errors/Typed_array_invalid_arguments": { - "modified": "2020-03-12T19:46:27.376Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Undeclared_var": { - "modified": "2020-03-12T19:45:21.644Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Undefined_prop": { - "modified": "2020-03-12T19:45:16.927Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Unexpected_token": { - "modified": "2020-03-12T19:45:18.592Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Errors/Unexpected_type": { - "modified": "2020-03-12T19:44:27.931Z", - "contributors": [ - "yenshen", - "niaodan2b" - ] - }, - "Web/JavaScript/Reference/Errors/Unnamed_function_statement": { - "modified": "2020-03-12T19:46:23.117Z", - "contributors": [ - "Lxio", - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Unterminated_string_literal": { - "modified": "2020-03-12T19:45:03.493Z", - "contributors": [ - "Ende93", - "luckyG0429" - ] - }, - "Web/JavaScript/Reference/Errors/Var_hides_argument": { - "modified": "2020-03-12T19:45:33.390Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Errors/in_operator_no_object": { - "modified": "2020-03-12T19:46:27.485Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/invalid_right_hand_side_instanceof_operand": { - "modified": "2020-03-12T19:47:39.673Z", - "contributors": [ - "JodieShi" - ] - }, - "Web/JavaScript/Reference/Errors/is_not_iterable": { - "modified": "2020-03-12T19:48:06.104Z", - "contributors": [ - "JsirForGit", - "rockSandy" - ] - }, - "Web/JavaScript/Reference/Errors/不能添加属性": { - "modified": "2020-03-12T19:49:02.016Z", - "contributors": [ - "mysteriousfather" - ] - }, - "Web/JavaScript/Reference/Functions": { - "modified": "2020-10-15T21:02:46.649Z", - "contributors": [ - "meng-Macbook", - "zhangchen", - "LiXin", - "righttoe", - "KngZhi", - "xgqfrms-GitHub", - "appie963", - "Jianming", - "Ende93", - "ChristopherMa2012", - "ziyunfei", - "teoli", - "lijunchengbeyond", - "byronhe", - "iwo" - ] - }, - "Web/JavaScript/Reference/Functions/Arrow_functions": { - "modified": "2020-10-15T21:22:15.274Z", - "contributors": [ - "symant233", - "zhonghuajiadezhuizhongyu", - "woshiqiang1", - "YangYihui", - "kingsley2036", - "Monkey-D-Pixel", - "Himself65", - "Frederick-S", - "jianchao_xue", - "ZeroWhiteSmile", - "wangbangkun", - "ColinJinag", - "zjjgsc", - "Harleywww", - "huangll", - "LeoQuote", - "jjc", - "ywjco", - "Warden", - "xgqfrms-GitHub", - "zhangchen", - "anjia", - "StevenYuysy", - "ZZES_REN", - "tjyas", - "Gary-c", - "linzhihuan", - "guonanci", - "shifengchen", - "unliar", - "MichelleGuan", - "slimeball", - "LangDonHJJ", - "zhangzju", - "Aisi", - "muzhen", - "Meteormatt", - "Ende93", - "Ovilia", - "solome", - "zilong-thu", - "jy1989", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Functions/Default_parameters": { - "modified": "2020-10-15T21:19:13.746Z", - "contributors": [ - "zhuangyin", - "zhangchen", - "xgqfrms-GitHub", - "Carlmac", - "xiaorang", - "Inokinoki", - "thomasyimgit", - "harryhao", - "lunix01", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Functions/Method_definitions": { - "modified": "2020-10-15T21:34:33.682Z", - "contributors": [ - "narutojian", - "by73", - "Harpes", - "fscholz", - "SphinxKnight", - "zhangchen", - "teoli", - "fskuok" - ] - }, - "Web/JavaScript/Reference/Functions/Rest_parameters": { - "modified": "2020-10-15T21:18:39.925Z", - "contributors": [ - "Yayure", - "gqbre", - "codevvvv9", - "fscholz", - "Jhongwun", - "Warden", - "zhangchen", - "Ts799498164", - "Hanx", - "xgqfrms-GitHub", - "Ende93", - "helloguangxue", - "sabrinaluo", - "teoli", - "fskuok", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Functions/arguments": { - "modified": "2020-10-15T21:02:42.108Z", - "contributors": [ - "xgqfrms", - "s1min", - "zx06", - "gqbre", - "jianchao_xue", - "ywjco", - "yeziningmeng", - "DragonHou", - "szengtal", - "zhangchen", - "renyuns", - "xgqfrms-GitHub", - "yyyyu", - "yatace", - "jihonghai", - "Ende93", - "yswang0927", - "teoli", - "asdzxcqwe", - "Fadeoc", - "brandonzhu", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Functions/arguments/@@iterator": { - "modified": "2020-10-15T21:48:23.032Z", - "contributors": [ - "fscholz", - "wizardforcel", - "wohugb" - ] - }, - "Web/JavaScript/Reference/Functions/arguments/callee": { - "modified": "2020-10-15T21:29:14.342Z", - "contributors": [ - "18boys", - "ssttii", - "fscholz", - "NoroHime", - "yangyichen", - "jyjsjd", - "xgqfrms-GitHub", - "Ende93", - "jonkee", - "teoli", - "gemstone" - ] - }, - "Web/JavaScript/Reference/Functions/arguments/length": { - "modified": "2020-10-15T21:21:10.516Z", - "contributors": [ - "fscholz", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Functions/get": { - "modified": "2020-10-15T21:32:24.408Z", - "contributors": [ - "wallena3", - "fscholz", - "LiXin", - "lijinglin", - "zhangchen", - "xgqfrms-GitHub", - "teoli", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Functions/set": { - "modified": "2020-10-15T21:31:33.512Z", - "contributors": [ - "wallena3", - "fscholz", - "Austaras", - "zhangchen", - "xgqfrms-GitHub", - "Go7hic", - "teoli", - "nyx2014", - "LinusYu" - ] - }, - "Web/JavaScript/Reference/Global_Objects": { - "modified": "2020-10-15T01:05:17.510Z", - "contributors": [ - "Neo42", - "Ende93", - "laampui", - "wallena3", - "RainSlide", - "Frederick-S", - "SageX", - "liushengxin", - "Terry.Qiao", - "xgqfrms-GitHub", - "ZQH", - "zhangchen", - "mwc", - "Jiang-Xuan", - "SamuraiMe", - "highkay", - "lunix01", - "JoshuaGhost", - "ziyunfei", - "SphinxKnight", - "yiding_he", - "Fantasy_shao", - "AlexChao", - "teoli", - "OoOoOoOo" - ] - }, - "Web/JavaScript/Reference/Global_Objects/AggregateError": { - "modified": "2020-10-15T22:27:42.765Z", - "contributors": [ - "叶扬", - "MaDeLu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array": { - "modified": "2020-10-15T21:11:20.773Z", - "contributors": [ - "SphinxKnight", - "fantasy090633", - "Frederick-S", - "Willian.G", - "gqbre", - "luluyiluchangtong", - "liuchao0704", - "zxsunrise", - "fisker", - "runyul", - "Terry.Qiao", - "ywjco", - "b2ns", - "kevinfszu", - "shaojingchao", - "zhuangyin", - "xinleibird", - "xgqfrms-GitHub", - "Chocomoon", - "habc0807", - "kdex", - "amnsss", - "pigflymoon", - "xiaojunjor", - "zhiquan_yu", - "lanezhao", - "ttjkst", - "aximario", - "Ende93", - "ObooChin", - "frontzhm", - "kinuxroot", - "VIPArcher", - "ziyunfei", - "TinyJiang", - "FredWe", - "Cattla", - "Gaohaoyang", - "paddingme", - "Yaty", - "tingxinCY", - "Harvesty", - "Guanjinke", - "dancancer", - "teoli", - "WenbingZheng", - "Mickeyboy", - "Oatn", - "Kebing", - "Lanyu", - "Acefeel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/@@iterator": { - "modified": "2020-10-15T21:48:08.478Z", - "contributors": [ - "GlowMonster", - "RainSlide", - "ifredom", - "Ende93", - "OshotOkill" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/@@species": { - "modified": "2020-10-15T21:47:50.737Z", - "contributors": [ - "RainSlide", - "Fire1nRain", - "fscholz", - "hongxu.Wei", - "looch5" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/@@unscopables": { - "modified": "2020-10-15T21:48:00.162Z", - "contributors": [ - "RainSlide", - "Ende93", - "OshotOkill" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/Reduce": { - "modified": "2020-10-15T21:26:38.795Z", - "contributors": [ - "zhuangyin", - "zangbianxuegu", - "cracdic", - "tanpopo", - "SageX", - "good1uck", - "zheng1013757145", - "MrGaoGang", - "daolanfler", - "superadmin", - "jaredhan418", - "polunzh", - "haylorhu", - "yinsang", - "BingerWeb", - "linqunxun", - "weiqinl", - "danchaotaiyang", - "fscholz", - "fisker", - "ysyfff", - "wjuan960407", - "zhangchen", - "dblate", - "Go7hic", - "maximus1992", - "conniejing", - "keyood", - "righttoe", - "xgqfrms-GitHub", - "leeseean", - "micheal-death", - "coolguy", - "iugo", - "seaHeater", - "yanxiaowu", - "collhector", - "Cattla", - "vcfvct", - "teoli", - "AlexChao", - "ziyunfei", - "fishenal" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/ReduceRight": { - "modified": "2020-10-23T11:37:43.387Z", - "contributors": [ - "zhuangyin", - "RainSlide", - "SageX", - "C-boyi", - "fscholz", - "xgqfrms-GitHub", - "micheal-death", - "Menq", - "teoli", - "AlexChao", - "wilsoncook" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/concat": { - "modified": "2020-10-15T21:07:00.501Z", - "contributors": [ - "likev", - "SageX", - "qiannianchong25", - "zhangchen", - "fscholz", - "lijinwenhg", - "web-gm", - "fisker", - "badfl", - "xgqfrms-GitHub", - "Ende93", - "Aralic", - "borishuai", - "ziyunfei", - "teoli", - "Chajn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/copyWithin": { - "modified": "2020-10-15T21:17:18.640Z", - "contributors": [ - "yayaxueyu", - "ZL1019", - "RainSlide", - "fscholz", - "futurefeeling", - "hongxu.Wei", - "fisker", - "Non-professionalIFE", - "xgqfrms-GitHub", - "micheal-death", - "gaoupon", - "Andself", - "Ende93", - "chendatony31", - "crowphy", - "teoli", - "ziyunfei", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/entries": { - "modified": "2020-10-15T21:07:50.512Z", - "contributors": [ - "Harry-Zhao", - "fscholz", - "futurefeeling", - "ywjco", - "xgqfrms-GitHub", - "AlexChao", - "teoli", - "ziyunfei", - "yanhaijing1234" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/every": { - "modified": "2020-10-15T21:17:20.643Z", - "contributors": [ - "qianmo", - "c1er", - "RainSlide", - "genezx", - "DYERPH", - "fscholz", - "futurefeeling", - "banli17", - "zhang-hongwei", - "janason.yang", - "ziyunfei", - "LYF-MIHO", - "AlexChao", - "teoli", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/fill": { - "modified": "2020-10-15T21:26:52.543Z", - "contributors": [ - "fanerge", - "zhangchen", - "fisker", - "linzx1993", - "tiansh", - "xhlsrj", - "micheal-death", - "sqchenxiyuan", - "xgqfrms-GitHub", - "Ende93", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/filter": { - "modified": "2020-10-15T21:17:27.613Z", - "contributors": [ - "alexzedheng", - "Martin-Shao", - "RainSlide", - "zhangchen", - "badfl", - "zhuangyin", - "futurefeeling", - "ywjco", - "RGSS3", - "yuyongjun123", - "zhanglongdream", - "xgqfrms-GitHub", - "mooyxu", - "Gauch", - "Si-Monster", - "sartrey", - "AlexChao", - "ziyunfei", - "teoli", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/find": { - "modified": "2020-10-15T21:17:19.858Z", - "contributors": [ - "canyi1942", - "Harry-Zhao", - "zhangchen", - "Spaghet-Ti", - "futurefeeling", - "Vevlins", - "banli17", - "jiankian", - "hughfenghen", - "graysongs", - "Ende93", - "zhuangyin", - "xiaojunjor", - "xgqfrms-GitHub", - "iNahoo", - "Kennytian", - "OmniP", - "ngtmuzi", - "kkzhang", - "teoli", - "huyue", - "ziyunfei", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/findIndex": { - "modified": "2020-10-15T21:25:37.656Z", - "contributors": [ - "frankfang1990", - "simonzhao", - "fscholz", - "jiankian", - "big-dinner", - "18820486093", - "zhangchen", - "xiaojunjor", - "xgqfrms-GitHub", - "DearZui", - "ngtmuzi", - "SakuraNeko", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/flat": { - "modified": "2020-11-23T21:40:15.634Z", - "contributors": [ - "RolkerMan", - "zhuangyin", - "yadongxie150", - "0uzu0", - "youcanping", - "andycao", - "SageX", - "lovefengruoqing", - "RainSlide", - "hillterry", - "Kemper-Diao", - "dr2009", - "fscholz", - "fisker", - "Braised-Cakes" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/flatMap": { - "modified": "2020-11-30T01:43:38.078Z", - "contributors": [ - "zyq", - "BadmasterY", - "SageX", - "ZzqiZQute", - "a81965689", - "RainSlide", - "rxliuli", - "LiuYuan", - "Channely", - "zhixudong666", - "baylin87" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/forEach": { - "modified": "2020-10-15T21:07:41.999Z", - "contributors": [ - "inlym", - "RainSlide", - "SageX", - "yuwei", - "HermitSun", - "zhangchen", - "hhxxhg", - "fscholz", - "futurefeeling", - "LinLshare", - "gossling", - "bibi941", - "xgqfrms-GitHub", - "lssbq", - "voidzhou", - "kameii", - "Liyunsheng", - "TomIsion", - "helloguangxue", - "Ende93", - "Harvesty", - "AlexChao", - "ziyunfei", - "teoli", - "yanhaijing1234" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/from": { - "modified": "2020-10-15T21:27:52.328Z", - "contributors": [ - "cellinlab", - "RainSlide", - "WhiteMind", - "SageX", - "tc_dreamer", - "EmmaYXY", - "zppro", - "smallbag", - "fscholz", - "hongxu.Wei", - "banli17", - "ywjco", - "Jat", - "xgqfrms-GitHub", - "jessie-zly", - "spicyboiledfish", - "Ende93", - "kdex", - "micheal-death", - "xiaokk06", - "helloguangxue", - "jiraiya", - "LinusYu", - "ngtmuzi", - "yenshen", - "ziyunfei", - "tiansh" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/includes": { - "modified": "2020-10-15T21:30:09.625Z", - "contributors": [ - "FrankYuanhao", - "hjxtclm", - "zheng1013757145", - "vaynewang", - "RainSlide", - "Warden", - "NiroDu", - "fscholz", - "futurefeeling", - "hongxu.Wei", - "badfl", - "hua03", - "kdex", - "xgqfrms-GitHub", - "kameii", - "lizhongyi", - "Ende93", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/indexOf": { - "modified": "2020-10-15T21:26:12.959Z", - "contributors": [ - "SageX", - "Xmader", - "fscholz", - "futurefeeling", - "jiankian", - "big-dinner", - "xgqfrms-GitHub", - "lanezhao", - "keqingrong", - "Ende93", - "paddingme", - "AlexChao", - "ziyunfei", - "focus", - "teoli", - "eric.yuan" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/isArray": { - "modified": "2020-10-15T21:02:37.096Z", - "contributors": [ - "SageX", - "Frederick-S", - "fscholz", - "zhangsenhua", - "yenshen", - "xgqfrms-GitHub", - "ToWorkit", - "Dcfm", - "xiaokk06", - "Ende93", - "ziyunfei", - "teoli", - "paddingme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/join": { - "modified": "2020-10-15T21:05:15.988Z", - "contributors": [ - "SageX", - "Heaan", - "zhangchen", - "fscholz", - "futurefeeling", - "xgqfrms-GitHub", - "badfl", - "helloguangxue", - "yenshen", - "saintwinkle", - "AlexChao", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/keys": { - "modified": "2020-10-15T21:32:21.834Z", - "contributors": [ - "zhangchen", - "fscholz", - "futurefeeling", - "LemonGirl", - "micheal-death", - "xgqfrms-GitHub", - "ziyunfei", - "200OK" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf": { - "modified": "2020-10-15T21:29:02.691Z", - "contributors": [ - "SageX", - "fscholz", - "futurefeeling", - "badfl", - "ywjco", - "AlexChao", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/length": { - "modified": "2020-10-15T21:21:14.308Z", - "contributors": [ - "binarization", - "fscholz", - "fisker", - "jeneser", - "shaodahong", - "The-End-Hero", - "yenshen", - "AlexChao", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/map": { - "modified": "2020-10-15T21:07:20.691Z", - "contributors": [ - "fscholz", - "Zzc19970910", - "Slartbartfast1", - "Jayly", - "ooo1l", - "petrewoo", - "SageX", - "old2sun", - "BingerWeb", - "zhangchen", - "ssttii", - "fengkx", - "xgqfrms-GitHub", - "W4n9Hu1", - "hooozen", - "Ts799498164", - "zhuangyin", - "righttoe", - "notmaster", - "Ende93", - "niices", - "JinxiuLee", - "ziyunfei", - "helinjiang", - "Young-Wang", - "xiaomingming", - "AlexChao", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/of": { - "modified": "2020-10-15T21:17:21.107Z", - "contributors": [ - "chunfeng08", - "fscholz", - "mingttong", - "FunnyZ", - "micheal-death", - "enem", - "xgqfrms-GitHub", - "Ende93", - "yenshen", - "ziyunfei", - "teoli", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/pop": { - "modified": "2020-10-15T21:21:08.570Z", - "contributors": [ - "fscholz", - "Spaghet-Ti", - "ndNovaDev", - "micheal-death", - "xgqfrms-GitHub", - "ysneo", - "AlexChao", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/prototype": { - "modified": "2020-10-15T21:25:06.780Z", - "contributors": [ - "TonyYu2015", - "fscholz", - "abc45628", - "xgqfrms-GitHub", - "micheal-death", - "ziyunfei", - "WangXiZhu", - "zhen", - "pd4d10", - "teoli", - "charlie", - "andy12530", - "sleepholic" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/push": { - "modified": "2020-10-15T21:17:19.272Z", - "contributors": [ - "Huauauaa", - "L9m", - "fscholz", - "lizhonggang", - "Spikef", - "shery", - "micheal-death", - "xgqfrms-GitHub", - "Ende93", - "yenshen", - "AlexChao", - "ziyunfei", - "teoli", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/reverse": { - "modified": "2020-10-15T21:17:25.177Z", - "contributors": [ - "jingchaocheng", - "SageX", - "huxinsen", - "ifredom", - "fscholz", - "futurefeeling", - "xgqfrms-GitHub", - "Ende93", - "AlexChao", - "ziyunfei", - "teoli", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/shift": { - "modified": "2020-10-15T21:26:52.357Z", - "contributors": [ - "SageX", - "jinger7281", - "fscholz", - "badfl", - "LemonGirl", - "micheal-death", - "xgqfrms-GitHub", - "Ende93", - "pd4d10", - "teoli", - "AlexChao", - "ziyunfei", - "endlesswind" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/slice": { - "modified": "2020-11-30T04:00:58.912Z", - "contributors": [ - "shery", - "Zzt-G", - "RainSlide", - "Fire1nRain", - "Mrdapeng", - "MoYuLing", - "Jiang-Xuan", - "524119574", - "xgqfrms-GitHub", - "zhuangyin", - "yiyaxueyu", - "k644606347", - "lihx_hit", - "MechanicianW", - "FlowingRiver", - "GTyexing", - "Ende93", - "aximario", - "helloguangxue", - "AlexChao", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/some": { - "modified": "2020-10-15T21:26:00.318Z", - "contributors": [ - "SageX", - "simonzhao", - "Zohar727", - "Kuroo", - "lzszone", - "gqbre", - "lmislm", - "KangKai-fe", - "zhangchen", - "xgqfrms-GitHub", - "AlexChao", - "ziyunfei", - "teoli", - "yanhaijing1234" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/sort": { - "modified": "2020-10-15T21:17:18.762Z", - "contributors": [ - "810307015", - "xgqfrms", - "zhangchen", - "kaojistream", - "fscholz", - "ywjco", - "Mr-Li-admin", - "NuclearBlast", - "righttoe", - "JackFeng", - "MeCKodo", - "micheal-death", - "Feel-Joy", - "houbx", - "xgqfrms-GitHub", - "ziyunfei", - "stonewen", - "wuzhenquan", - "helloguangxue", - "Ende93", - "helinjiang", - "dameinliu", - "XingxianLI", - "tiansh", - "teoli", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/splice": { - "modified": "2020-10-15T21:28:59.144Z", - "contributors": [ - "ThornWu", - "ttxs69", - "DouglasRyan", - "oopsguy", - "RainSlide", - "ifredom", - "zhuangyin", - "SphinxKnight", - "VinciXie", - "daijie", - "yonoel", - "dpwwwq", - "shibomeng", - "fscholz", - "Jiang-Xuan", - "zhipeng001", - "lemonboy233", - "ywjco", - "badfl", - "hawtim", - "Lemon-jie", - "KMKNKK", - "frankfang1990", - "FlySnails", - "xgqfrms-GitHub", - "NNNaix", - "Lemon-c", - "HUxiaoAlinNG", - "Rising_sun", - "w-halo", - "FlowingRiver", - "me-code", - "Ende93", - "Qin", - "huyue" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/toLocaleString": { - "modified": "2020-10-15T21:29:06.488Z", - "contributors": [ - "fscholz", - "zhangchen", - "badfl", - "zxhycxq", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/toSource": { - "modified": "2020-10-15T21:21:06.880Z", - "contributors": [ - "fscholz", - "badfl", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/toString": { - "modified": "2020-10-15T21:29:03.089Z", - "contributors": [ - "zhangchen", - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/unshift": { - "modified": "2020-10-15T21:23:36.187Z", - "contributors": [ - "benngai123", - "No_risk_atpresent", - "jinger7281", - "heeronchang", - "RainSlide", - "L9m", - "zhangchen", - "fscholz", - "xgqfrms-GitHub", - "AlexChao", - "ziyunfei", - "teoli", - "xfeng" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Array/values": { - "modified": "2020-10-15T21:37:23.141Z", - "contributors": [ - "Agcaiyun", - "johnao", - "RainSlide", - "SageX", - "fscholz", - "ywjco", - "redoc", - "xgqfrms-GitHub", - "Ende93", - "AlexChao", - "KingMario" - ] - }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer": { - "modified": "2020-10-15T21:27:45.114Z", - "contributors": [ - "woshiqiang1", - "wallena3", - "Jiang-Xuan", - "Terry.Qiao", - "xgqfrms-GitHub", - "kameii", - "liyongleihf2006", - "maicss", - "teoli", - "Jijie.Chen", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/@@species": { - "modified": "2020-10-15T21:52:04.532Z", - "contributors": [ - "fscholz", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength": { - "modified": "2020-10-15T21:37:49.462Z", - "contributors": [ - "fscholz", - "kameii", - "fred4444source" - ] - }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView": { - "modified": "2020-10-15T21:37:49.247Z", - "contributors": [ - "Dyon", - "knightyun", - "fscholz", - "yunl819", - "fred4444source" - ] - }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype": { - "modified": "2020-10-15T21:37:49.333Z", - "contributors": [ - "fscholz", - "kameii", - "liyongleihf2006", - "fred4444source" - ] - }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice": { - "modified": "2020-10-15T21:51:34.058Z", - "contributors": [ - "fscholz", - "kameii" - ] - }, - "Web/JavaScript/Reference/Global_Objects/AsyncFunction": { - "modified": "2020-10-15T21:50:47.192Z", - "contributors": [ - "Terry.Qiao", - "xgqfrms-GitHub", - "Ende93", - "_da" - ] - }, - "Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype": { - "modified": "2020-10-15T21:51:59.203Z", - "contributors": [ - "daijie", - "fscholz", - "wizardforcel", - "xygcxy" - ] - }, - "Web/JavaScript/Reference/Global_Objects/AsyncIterator": { - "modified": "2020-10-15T22:28:09.380Z", - "contributors": [ - "lxuewu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics": { - "modified": "2020-10-15T21:47:39.816Z", - "contributors": [ - "xgqfrms", - "zhangchen", - "Terry.Qiao", - "LawrenceChenPro", - "JianrongYu", - "Ende93", - "Hearmen", - "weishuaikun", - "Spring_Winter_Wine" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/add": { - "modified": "2020-10-15T21:52:07.041Z", - "contributors": [ - "fscholz", - "RoXoM", - "JianrongYu", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/and": { - "modified": "2020-10-15T21:52:05.452Z", - "contributors": [ - "fscholz", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/compareExchange": { - "modified": "2020-10-15T21:52:07.140Z", - "contributors": [ - "fscholz", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/exchange": { - "modified": "2020-10-15T21:52:04.443Z", - "contributors": [ - "fscholz", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/isLockFree": { - "modified": "2020-10-15T21:52:17.441Z", - "contributors": [ - "fscholz", - "eyfor", - "Mocuishle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/load": { - "modified": "2020-10-15T21:58:11.479Z", - "contributors": [ - "fscholz", - "Mukti" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/notify": { - "modified": "2020-10-15T22:21:48.950Z", - "contributors": [ - "lizhongzhen11", - "lifankohome" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/or": { - "modified": "2020-10-15T22:21:50.539Z", - "contributors": [ - "lifankohome" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/store": { - "modified": "2020-10-15T21:57:10.970Z", - "contributors": [ - "fscholz", - "zouyang1230", - "shenrongliu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/sub": { - "modified": "2020-10-15T22:24:45.287Z", - "contributors": [ - "BadmasterY" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/wait": { - "modified": "2020-10-15T22:21:34.534Z", - "contributors": [ - "hanalice", - "Jinyingyi" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Atomics/xor": { - "modified": "2020-10-15T22:24:45.064Z", - "contributors": [ - "BadmasterY" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigInt": { - "modified": "2020-10-15T22:12:07.852Z", - "contributors": [ - "YouHeng", - "BadmasterY", - "dstyxy", - "fefe982", - "ddztomcat", - "c412216887", - "lovue" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigInt/BigInt": { - "modified": "2020-10-15T22:25:55.480Z", - "contributors": [ - "wallena3" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigInt/asIntN": { - "modified": "2020-10-15T22:24:46.833Z", - "contributors": [ - "BadmasterY" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigInt/asUintN": { - "modified": "2020-10-15T22:24:47.578Z", - "contributors": [ - "BadmasterY" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString": { - "modified": "2020-10-15T22:24:47.615Z", - "contributors": [ - "BadmasterY" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigInt/toString": { - "modified": "2020-10-15T22:24:48.189Z", - "contributors": [ - "BadmasterY" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigInt/valueOf": { - "modified": "2020-10-15T22:24:48.266Z", - "contributors": [ - "BadmasterY" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigInt64Array": { - "modified": "2020-10-15T22:17:01.806Z", - "contributors": [ - "vent", - "SDUTWSL" - ] - }, - "Web/JavaScript/Reference/Global_Objects/BigUint64Array": { - "modified": "2020-10-15T22:20:32.429Z", - "contributors": [ - "liruiqi" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Boolean": { - "modified": "2020-11-05T03:24:53.922Z", - "contributors": [ - "SphinxKnight", - "184289542", - "Yayure", - "snail-xx", - "zeyongTsai", - "Terry.Qiao", - "comyn", - "zhangchen", - "SmluVFpI", - "righttoe", - "Hugh", - "xgqfrms-GitHub", - "Folgore", - "emctoo", - "slientomorrr", - "yenshen", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Boolean/prototype": { - "modified": "2020-10-15T21:06:58.693Z", - "contributors": [ - "zhangchen", - "keller0", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Boolean/toSource": { - "modified": "2020-10-15T21:51:59.093Z", - "contributors": [ - "fscholz", - "Grizzly-Eric" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Boolean/toString": { - "modified": "2020-10-15T21:28:54.689Z", - "contributors": [ - "fscholz", - "zhangchen", - "yenshen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Boolean/valueOf": { - "modified": "2020-10-15T21:28:53.640Z", - "contributors": [ - "fscholz", - "zhangchen", - "yenshen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView": { - "modified": "2020-10-15T21:34:38.297Z", - "contributors": [ - "wenshui2008", - "RainSlide", - "jason-grimm", - "Jiang-Xuan", - "Terry.Qiao", - "liyongleihf2006", - "Taoja", - "xiaokk06", - "Ende93", - "NIGHTEAGLE" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/buffer": { - "modified": "2020-10-15T21:52:04.673Z", - "contributors": [ - "fscholz", - "wizardforcel", - "holynewbie" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/byteLength": { - "modified": "2020-10-15T21:52:04.538Z", - "contributors": [ - "fscholz", - "wizardforcel", - "holynewbie" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/byteOffset": { - "modified": "2020-10-15T21:52:05.195Z", - "contributors": [ - "fscholz", - "wizardforcel", - "holynewbie" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getBigInt64": { - "modified": "2020-10-15T22:21:33.559Z", - "contributors": [ - "fade-vivida", - "SilverTime" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getBigUint64": { - "modified": "2020-10-15T22:22:15.035Z", - "contributors": [ - "jinger7281" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getFloat32": { - "modified": "2020-10-15T21:49:48.544Z", - "contributors": [ - "wenshui2008", - "758915145", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getFloat64": { - "modified": "2020-10-15T21:49:48.242Z", - "contributors": [ - "758915145", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getInt16": { - "modified": "2020-10-15T21:49:47.595Z", - "contributors": [ - "knightyun", - "758915145", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getInt32": { - "modified": "2020-10-15T21:49:48.330Z", - "contributors": [ - "758915145", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getInt8": { - "modified": "2020-10-15T21:44:13.950Z", - "contributors": [ - "758915145", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getUint16": { - "modified": "2020-10-15T21:49:47.729Z", - "contributors": [ - "758915145", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getUint32": { - "modified": "2020-10-15T21:49:47.551Z", - "contributors": [ - "758915145", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/getUint8": { - "modified": "2020-10-15T21:44:16.655Z", - "contributors": [ - "758915145", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/prototype": { - "modified": "2020-10-15T21:38:02.121Z", - "contributors": [ - "fscholz", - "liyongleihf2006", - "Taoja", - "mzhejiayu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setBigInt64": { - "modified": "2020-10-15T22:24:55.568Z", - "contributors": [ - "wenshui2008" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setBigUint64": { - "modified": "2020-10-15T22:24:53.419Z", - "contributors": [ - "wenshui2008" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setFloat32": { - "modified": "2020-10-15T21:49:50.076Z", - "contributors": [ - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setFloat64": { - "modified": "2020-10-15T21:49:50.505Z", - "contributors": [ - "farteryhr", - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setInt16": { - "modified": "2020-10-15T21:49:50.736Z", - "contributors": [ - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setInt32": { - "modified": "2020-10-15T21:49:50.027Z", - "contributors": [ - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setInt8": { - "modified": "2020-10-15T21:37:32.797Z", - "contributors": [ - "fscholz", - "Taoja", - "mzhejiayu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setUint16": { - "modified": "2020-10-15T21:49:49.541Z", - "contributors": [ - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setUint32": { - "modified": "2020-10-15T21:49:50.144Z", - "contributors": [ - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/DataView/setUint8": { - "modified": "2020-10-15T21:49:48.203Z", - "contributors": [ - "fscholz", - "Taoja" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date": { - "modified": "2020-10-19T08:07:05.768Z", - "contributors": [ - "SphinxKnight", - "songzeng2016", - "ZhangXianWei", - "johnao", - "oujielong", - "striveyan", - "fefe982", - "Mr_z", - "litmonw", - "RainSlide", - "jackylz", - "fscholz", - "VAN666", - "liuzeyafzy", - "whinc", - "sharp-c", - "distums", - "helloguangxue", - "zhang384579631", - "yenshen", - "fuchao2012", - "hikarievo", - "teoli", - "littleVege", - "AlexChao", - "ziyunfei", - "liminjun", - "confusedwu", - "Mickeyboy", - "Mgjbot" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/@@toPrimitive": { - "modified": "2020-10-15T22:06:53.986Z", - "contributors": [ - "pea3nut" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/Date": { - "modified": "2020-10-15T22:28:18.123Z", - "contributors": [ - "lztom2046" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/UTC": { - "modified": "2020-10-15T21:28:25.934Z", - "contributors": [ - "tclzcja", - "fscholz", - "Hugh", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getDate": { - "modified": "2020-10-15T21:03:50.488Z", - "contributors": [ - "hsqin", - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getDay": { - "modified": "2020-10-15T21:03:58.429Z", - "contributors": [ - "HFatBird", - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getFullYear": { - "modified": "2020-10-15T21:03:49.040Z", - "contributors": [ - "fscholz", - "zhangchen", - "xqin", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getHours": { - "modified": "2020-10-15T21:03:54.198Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds": { - "modified": "2020-10-15T21:03:36.395Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getMinutes": { - "modified": "2020-10-15T21:03:39.835Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getMonth": { - "modified": "2020-10-15T21:03:43.325Z", - "contributors": [ - "fscholz", - "viko16", - "Ende93", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getSeconds": { - "modified": "2020-10-15T21:03:45.760Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getTime": { - "modified": "2020-10-15T21:28:11.731Z", - "contributors": [ - "YISHI", - "fscholz", - "Ende93", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset": { - "modified": "2020-10-15T21:28:12.331Z", - "contributors": [ - "daix6", - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCDate": { - "modified": "2020-10-15T21:33:57.569Z", - "contributors": [ - "fscholz", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCDay": { - "modified": "2020-10-15T21:33:56.103Z", - "contributors": [ - "fscholz", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear": { - "modified": "2020-10-15T21:33:57.710Z", - "contributors": [ - "fscholz", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCHours": { - "modified": "2020-10-15T21:34:04.488Z", - "contributors": [ - "fscholz", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds": { - "modified": "2020-10-15T21:34:05.550Z", - "contributors": [ - "fscholz", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes": { - "modified": "2020-10-15T21:34:04.468Z", - "contributors": [ - "fscholz", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth": { - "modified": "2020-10-15T21:34:04.629Z", - "contributors": [ - "fscholz", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds": { - "modified": "2020-10-15T21:34:04.630Z", - "contributors": [ - "fscholz", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/getYear": { - "modified": "2020-10-15T21:28:12.583Z", - "contributors": [ - "fscholz", - "Edith_Ren", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/now": { - "modified": "2020-10-15T21:21:13.943Z", - "contributors": [ - "RainSlide", - "fscholz", - "Ende93", - "AlexChao", - "ziyunfei", - "teoli", - "StuPig" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/parse": { - "modified": "2020-10-15T21:28:30.337Z", - "contributors": [ - "lyh2668", - "fscholz", - "Tao-Quixote", - "hkuclion", - "distums", - "gqqnbig", - "yeliex", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/prototype": { - "modified": "2020-10-15T21:28:32.786Z", - "contributors": [ - "zhangchen", - "imgss", - "fscholz", - "regiondavid", - "mage3k", - "Cattla", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setDate": { - "modified": "2020-10-15T21:28:14.248Z", - "contributors": [ - "jinger7281", - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setFullYear": { - "modified": "2020-10-15T21:28:11.404Z", - "contributors": [ - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setHours": { - "modified": "2020-10-15T21:28:14.385Z", - "contributors": [ - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setMilliseconds": { - "modified": "2020-10-15T21:28:19.563Z", - "contributors": [ - "fscholz", - "htitme", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setMinutes": { - "modified": "2020-10-15T21:28:16.896Z", - "contributors": [ - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setMonth": { - "modified": "2020-10-15T21:28:14.760Z", - "contributors": [ - "ZZES_REN", - "fscholz", - "luyouxin84", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setSeconds": { - "modified": "2020-10-15T21:28:14.577Z", - "contributors": [ - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setTime": { - "modified": "2020-10-15T21:28:10.430Z", - "contributors": [ - "dylanyg", - "fscholz", - "ziyunfei", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCDate": { - "modified": "2020-10-15T21:34:46.724Z", - "contributors": [ - "fscholz", - "rubyisapm" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear": { - "modified": "2020-10-15T21:48:19.613Z", - "contributors": [ - "fscholz", - "zachary05" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCHours": { - "modified": "2020-10-15T21:53:04.641Z", - "contributors": [ - "fscholz", - "haijianyang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds": { - "modified": "2020-10-15T21:55:54.800Z", - "contributors": [ - "fscholz", - "yys" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes": { - "modified": "2020-10-15T22:00:10.646Z", - "contributors": [ - "fscholz", - "LiuYuan" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth": { - "modified": "2020-10-15T21:51:40.559Z", - "contributors": [ - "fscholz", - "wizardforcel", - "Jabinzou" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds": { - "modified": "2020-10-15T21:49:40.074Z", - "contributors": [ - "fscholz", - "wizardforcel", - "petrelselina" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/setYear": { - "modified": "2020-10-15T22:29:46.049Z", - "contributors": [ - "SDUTWSL" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toDateString": { - "modified": "2020-10-15T21:28:24.093Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toGMTString": { - "modified": "2020-10-15T21:28:14.066Z", - "contributors": [ - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toISOString": { - "modified": "2020-10-15T21:28:16.900Z", - "contributors": [ - "fscholz", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toJSON": { - "modified": "2020-10-15T21:28:08.978Z", - "contributors": [ - "fscholz", - "KMKNKK", - "Cattla", - "helloguangxue", - "yenshen", - "Yaty", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString": { - "modified": "2020-10-15T21:28:17.098Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toLocaleString": { - "modified": "2020-10-15T21:28:25.398Z", - "contributors": [ - "fscholz", - "wangerniu", - "liyongleihf2006", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString": { - "modified": "2020-10-15T21:28:22.937Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toSource": { - "modified": "2020-10-15T22:00:19.218Z", - "contributors": [ - "fscholz", - "haipeng.liang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toString": { - "modified": "2020-10-15T21:28:13.694Z", - "contributors": [ - "yunxu1019", - "fscholz", - "yenshen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toTimeString": { - "modified": "2020-10-15T21:28:22.895Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toUTCString": { - "modified": "2020-10-15T21:28:16.518Z", - "contributors": [ - "fscholz", - "chesterchenn", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/valueOf": { - "modified": "2020-10-15T21:28:12.574Z", - "contributors": [ - "fscholz", - "Ende93", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error": { - "modified": "2020-10-15T21:21:49.758Z", - "contributors": [ - "GuYue", - "IreneByron", - "zhangchen", - "ZhishengZhao", - "xgqfrms-GitHub", - "ngtmuzi", - "calidion", - "teoli", - "yenshen", - "Maple-Jan", - "evilpie" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/Stack": { - "modified": "2020-10-15T22:05:59.371Z", - "contributors": [ - "Zoeooo", - "gentlelynn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/columnNumber": { - "modified": "2019-04-02T14:34:45.679Z", - "contributors": [ - "teoli", - "buckarooch" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/fileName": { - "modified": "2019-04-02T14:35:07.280Z", - "contributors": [ - "teoli", - "buckarooch" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/lineNumber": { - "modified": "2020-10-15T22:00:20.126Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/message": { - "modified": "2019-04-02T14:35:10.524Z", - "contributors": [ - "yenshen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/name": { - "modified": "2019-07-05T00:02:19.372Z", - "contributors": [ - "yenshen", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/prototype": { - "modified": "2019-04-02T14:33:04.306Z", - "contributors": [ - "ngtmuzi", - "shajiquan" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/toSource": { - "modified": "2020-10-15T22:04:46.786Z", - "contributors": [ - "zxsunrise", - "yuchaoWu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Error/toString": { - "modified": "2019-04-02T14:43:23.068Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/EvalError": { - "modified": "2020-10-15T21:15:06.730Z", - "contributors": [ - "Tao-Quixote", - "Debugger-D", - "buckarooch", - "slientomorrr", - "teoli", - "Mickeyboy" - ] - }, - "Web/JavaScript/Reference/Global_Objects/EvalError/prototype": { - "modified": "2020-10-15T21:59:36.134Z", - "contributors": [ - "hwj" - ] - }, - "Web/JavaScript/Reference/Global_Objects/FinalizationRegistry": { - "modified": "2020-10-15T22:33:55.419Z", - "contributors": [ - "LydiaYuan", - "xgqfrms" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Float32Array": { - "modified": "2019-03-23T22:55:04.546Z", - "contributors": [ - "lsvih", - "luojia", - "AlixWang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Float64Array": { - "modified": "2019-03-23T22:27:51.833Z", - "contributors": [ - "lsvih" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function": { - "modified": "2020-10-15T21:07:16.185Z", - "contributors": [ - "johnao", - "RainSlide", - "Bjkb", - "xuyewen288", - "ywjco", - "Jiang-Xuan", - "xgqfrms-GitHub", - "Ende93", - "webery", - "FredWe", - "teoli", - "chbdetta", - "chyee", - "ziyunfei", - "iwo" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/apply": { - "modified": "2020-10-15T21:21:35.017Z", - "contributors": [ - "leafwingstar", - "熊英明", - "zhanjunhao", - "wisecamle", - "zhangchen", - "Plortinus", - "MoYuLing", - "tangj1206", - "Humyang", - "Leivy", - "xgqfrms-GitHub", - "Ende93", - "JJPandari", - "hbkdsm", - "paddingme", - "onetree", - "AlexChao", - "ziyunfei", - "Nebu1aX", - "teoli", - "endlesswind" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/arguments": { - "modified": "2019-08-06T06:43:10.243Z", - "contributors": [ - "omz-one", - "ziyunfei", - "WangXiZhu", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/bind": { - "modified": "2020-10-15T21:07:21.219Z", - "contributors": [ - "xx1124961758", - "oxyg3n", - "lzfee0227", - "FeiJian984", - "TMM-eng", - "C2015", - "RainSlide", - "StuPig", - "williantian", - "hansnow", - "bananafishM", - "z1yuan", - "Arichy", - "Maiko", - "wisecamle", - "zhangchen", - "zjffun", - "AllanJian", - "kuleyu", - "LiXin", - "baidufe.hc", - "yuwanlin", - "yangyh1911", - "gwiron", - "lclscofield", - "xgqfrms-GitHub", - "zhengkai2001", - "Katherina-Miao", - "jyjsjd", - "Jiavan", - "riversYeHaha", - "xie-qianyue", - "sensui7", - "Ende93", - "manfredHu", - "cqzhao", - "prawn", - "iplus26", - "teoli", - "paddingme", - "TooBug", - "SDLyu", - "bin", - "ziyunfei", - "stylechen" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/call": { - "modified": "2020-10-15T21:07:14.576Z", - "contributors": [ - "Blackie", - "dcyu007", - "zzykillu", - "RainSlide", - "Maiko", - "Sally-he", - "whidy", - "Jiang-Xuan", - "fanerge", - "voidzhou", - "xgqfrms-GitHub", - "micheal-death", - "windluo", - "azhi09", - "ChemiCoder", - "Ende93", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/caller": { - "modified": "2019-08-06T03:21:58.429Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/displayName": { - "modified": "2019-05-15T23:11:48.055Z", - "contributors": [ - "liuchuzhang", - "lilng", - "teoli", - "minstrel1977", - "webery" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/length": { - "modified": "2020-10-15T21:02:07.304Z", - "contributors": [ - "zhangchen", - "gqbre", - "chudu", - "Ende93", - "guosimin", - "yenshen", - "teoli", - "ziyunfei", - "tiansh" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/name": { - "modified": "2020-10-15T21:02:08.194Z", - "contributors": [ - "zhangchen", - "inickel", - "minstrel1977", - "xgqfrms-GitHub", - "Marco_dev", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/prototype": { - "modified": "2019-09-11T09:25:06.080Z", - "contributors": [ - "Ende93", - "FrankElean", - "xiaowtz", - "DevinHe", - "teoli", - "ziyunfei", - "Oatn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/toSource": { - "modified": "2019-03-23T23:36:01.366Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/toString": { - "modified": "2020-10-15T21:21:30.188Z", - "contributors": [ - "zhangchen", - "Maiko", - "xmoyKing", - "laampui", - "AlexChao", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Generator": { - "modified": "2020-10-15T21:34:46.129Z", - "contributors": [ - "Ende93", - "xgqfrms", - "xuxiaokang", - "kdex", - "xgqfrms-GitHub", - "Yelmor", - "lanezhao", - "panhezeng", - "ziyunfei", - "Javascipt", - "lukywong", - "jpmedley" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Generator/next": { - "modified": "2019-08-17T06:59:14.528Z", - "contributors": [ - "Yayure", - "miyoosan", - "ywjco", - "Ende93", - "lukywong", - "jcouyang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Generator/return": { - "modified": "2020-10-15T21:37:31.281Z", - "contributors": [ - "SevenDreamYang", - "Ende93", - "ljxy", - "lukywong" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Generator/throw": { - "modified": "2019-08-12T05:52:42.406Z", - "contributors": [ - "Ende93", - "lukywong" - ] - }, - "Web/JavaScript/Reference/Global_Objects/GeneratorFunction": { - "modified": "2020-10-15T21:39:23.129Z", - "contributors": [ - "fscholz", - "zhangchen", - "lanezhao", - "webery", - "Cendy" - ] - }, - "Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype": { - "modified": "2020-10-15T21:40:51.679Z", - "contributors": [ - "fscholz", - "shinexyt", - "zhangchen", - "webery" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Infinity": { - "modified": "2020-10-19T00:56:56.707Z", - "contributors": [ - "DarkWing", - "lizhongzhen11", - "wallena3", - "Jiang-Xuan", - "yenshen", - "tiansh", - "SphinxKnight", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Int16Array": { - "modified": "2019-03-23T22:35:54.313Z", - "contributors": [ - "kdex", - "zilong-thu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Int32Array": { - "modified": "2019-06-02T03:31:50.287Z", - "contributors": [ - "wuqinqiang", - "xclhs", - "langjun" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Int8Array": { - "modified": "2019-03-18T20:48:04.246Z", - "contributors": [ - "xgqfrms-GitHub", - "ObooChin" - ] - }, - "Web/JavaScript/Reference/Global_Objects/InternalError": { - "modified": "2019-03-23T22:32:14.689Z", - "contributors": [ - "teoli", - "maicss", - "Jack-Q" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl": { - "modified": "2020-10-15T21:41:37.430Z", - "contributors": [ - "RainSlide", - "zhangchen", - "teabyii" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/Collator": { - "modified": "2020-10-15T21:52:01.061Z", - "contributors": [ - "fscholz", - "hiyangguo" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat": { - "modified": "2020-04-21T09:01:11.408Z", - "contributors": [ - "fscholz", - "TianchiLi", - "zxsunrise", - "liyongleihf2006" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype": { - "modified": "2020-04-21T09:01:11.304Z", - "contributors": [ - "fscholz", - "liyongleihf2006" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames": { - "modified": "2020-04-21T09:19:23.285Z", - "contributors": [ - "fscholz", - "hulucode" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/ListFormat": { - "modified": "2020-10-15T22:16:21.221Z", - "contributors": [ - "fscholz", - "Spengh" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/Locale": { - "modified": "2020-10-15T22:19:16.260Z", - "contributors": [ - "weibangtuo", - "fscholz", - "shuvidora", - "lovedebug" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat": { - "modified": "2020-10-15T21:50:51.219Z", - "contributors": [ - "fscholz", - "RoXoM", - "Sivan", - "lisniuse", - "liyongleihf2006" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format": { - "modified": "2020-10-15T22:04:10.022Z", - "contributors": [ - "fscholz", - "zxsunrise", - "Evansy" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/PluralRules": { - "modified": "2020-10-15T22:05:26.837Z", - "contributors": [ - "fscholz", - "JimmyBenKlieve", - "DeanNode" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat": { - "modified": "2020-10-15T22:21:27.890Z", - "contributors": [ - "SandBoat", - "Mongkii", - "fscholz", - "AchooLuv", - "xrr2016", - "SphinxKnight", - "qiufeihong2018" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales": { - "modified": "2020-10-15T22:09:15.623Z", - "contributors": [ - "pea3nut" - ] - }, - "Web/JavaScript/Reference/Global_Objects/JSON": { - "modified": "2020-10-15T21:06:55.773Z", - "contributors": [ - "recursion", - "renfufei", - "codevvvv9", - "zhangchen", - "luojia", - "righttoe", - "xgqfrms-GitHub", - "Freed", - "huguangju", - "liyongleihf2006", - "Ende93", - "yenshen", - "teoli", - "Yaty", - "fscholz", - "AlexChao", - "Wladimir_Palant", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/JSON/parse": { - "modified": "2020-10-15T21:28:05.508Z", - "contributors": [ - "hikigaya58", - "RainSlide", - "renfufei", - "zhuangyin", - "mySoul", - "rambo-panda", - "zhaoqize", - "DejectedBird", - "ZDeborah", - "xgqfrms-GitHub", - "zhoupenghui", - "frankfang1990", - "LiYang982", - "sszsfan", - "xgqfrms", - "TomIsion", - "qiao4", - "Ende93", - "yenshen", - "Yaty", - "ziyunfei", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/JSON/stringify": { - "modified": "2020-10-27T03:21:45.041Z", - "contributors": [ - "anan824", - "JaCoder", - "zhangchen", - "Ocean-ZH", - "huxinsen", - "fwmh", - "szengtal", - "superfighter", - "zhaoqize", - "Demo_Hu", - "xgqfrms-GitHub", - "xiuzhihuan", - "leouncle", - "zhoupenghui", - "LiYang982", - "zachary05", - "ziyunfei", - "byr-gdp", - "paddingme", - "AlexChao", - "teoli", - "Lovesueee" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map": { - "modified": "2020-10-15T21:06:49.701Z", - "contributors": [ - "laampui", - "wallena3", - "KaySama", - "Turner", - "YaoZeyuan", - "Mr_Big", - "maoyumaoxun", - "hong007", - "zhangchen", - "Amio", - "tsejx", - "thegatheringstorm", - "buckarooch", - "xgqfrms-GitHub", - "kameii", - "Cattla", - "huguangju", - "YangyuhaoBit", - "luneice", - "git123hub", - "Ende93", - "sqqihao", - "fskuok", - "teoli", - "ziyunfei", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/@@iterator": { - "modified": "2020-10-15T21:56:27.573Z", - "contributors": [ - "Ende93", - "DuLinRain" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/@@species": { - "modified": "2020-10-15T21:57:35.566Z", - "contributors": [ - "vanishcode" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/@@toStringTag": { - "modified": "2019-04-05T14:04:42.613Z", - "contributors": [ - "DuLinRain" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/Map": { - "modified": "2020-10-15T22:29:02.199Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/clear": { - "modified": "2020-10-15T21:41:32.043Z", - "contributors": [ - "zhangchen", - "SphinxKnight", - "HsuanLee", - "youth7" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/delete": { - "modified": "2020-10-15T21:46:05.144Z", - "contributors": [ - "zhangchen", - "royl8", - "Hushabyme", - "webery" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/entries": { - "modified": "2020-10-15T21:39:28.129Z", - "contributors": [ - "Louis-7", - "SphinxKnight", - "ngtmuzi", - "HsuanLee", - "Zhiyu_Wang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/forEach": { - "modified": "2020-10-15T21:39:26.824Z", - "contributors": [ - "Mr_kaze", - "niices", - "liu7654", - "SimonYang", - "SphinxKnight", - "ziyunfei", - "Zhiyu_Wang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/get": { - "modified": "2020-10-15T21:39:27.794Z", - "contributors": [ - "RainSlide", - "SphinxKnight", - "ziyunfei", - "Zhiyu_Wang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/has": { - "modified": "2019-10-04T10:03:31.075Z", - "contributors": [ - "Cyberhan123", - "SphinxKnight", - "DirtyPP" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/keys": { - "modified": "2020-10-15T21:48:38.432Z", - "contributors": [ - "Davidyanlong", - "RainSlide", - "zachary05" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/prototype": { - "modified": "2019-12-28T23:13:19.788Z", - "contributors": [ - "wallena3", - "YaoZeyuan", - "kameii", - "chaosdog", - "webery" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/set": { - "modified": "2020-10-15T21:48:37.587Z", - "contributors": [ - "CascEco", - "ts0307", - "RainSlide", - "MaZheng", - "Hushabyme", - "zachary05" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/size": { - "modified": "2019-09-06T04:35:48.843Z", - "contributors": [ - "boyue", - "wenshin" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Map/values": { - "modified": "2019-10-04T09:57:38.527Z", - "contributors": [ - "killsos", - "mingzhaov" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math": { - "modified": "2020-10-15T21:21:09.889Z", - "contributors": [ - "RainSlide", - "Zhenger", - "tzmf", - "levinweb", - "xzmshiji", - "LiXin", - "xgqfrms-GitHub", - "Ende93", - "lwxyfer", - "FredWe", - "yenshen", - "baiya", - "AlexChao", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/E": { - "modified": "2019-03-23T23:12:59.627Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/LN10": { - "modified": "2019-03-23T22:26:33.778Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/LN2": { - "modified": "2019-03-23T23:12:59.485Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/LOG10E": { - "modified": "2019-03-23T23:12:57.229Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/LOG2E": { - "modified": "2019-03-23T23:12:57.389Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/PI": { - "modified": "2019-10-10T16:56:22.011Z", - "contributors": [ - "helloguangxue", - "yenshen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/SQRT1_2": { - "modified": "2019-03-23T23:12:56.404Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/SQRT2": { - "modified": "2019-03-23T23:34:50.958Z", - "contributors": [ - "AlexChao", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/abs": { - "modified": "2019-04-05T14:44:14.817Z", - "contributors": [ - "FlowingRiver", - "tiansh", - "AlexChao", - "teoli", - "ndon" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/acos": { - "modified": "2019-04-05T14:44:29.427Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/asin": { - "modified": "2019-08-17T06:23:48.692Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/asinh": { - "modified": "2020-10-15T22:29:13.098Z", - "contributors": [ - "vampire624" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/atan": { - "modified": "2019-03-23T23:12:33.623Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/atan2": { - "modified": "2019-10-29T04:38:29.778Z", - "contributors": [ - "412799755", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/atanh": { - "modified": "2019-03-23T22:30:24.385Z", - "contributors": [ - "timqian92" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/cbrt": { - "modified": "2019-11-08T10:40:00.500Z", - "contributors": [ - "hellorayza", - "hhxxhg", - "SphinxKnight", - "wangyukai04", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/ceil": { - "modified": "2020-10-15T21:28:51.015Z", - "contributors": [ - "RainSlide", - "xgqfrms-GitHub", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/clz32": { - "modified": "2020-10-15T21:26:57.620Z", - "contributors": [ - "Lucilor", - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/cos": { - "modified": "2019-03-23T23:12:55.982Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/cosh": { - "modified": "2019-03-23T22:45:35.592Z", - "contributors": [ - "SphinxKnight", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/exp": { - "modified": "2019-04-05T14:46:00.450Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/expm1": { - "modified": "2019-03-23T23:24:29.516Z", - "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/floor": { - "modified": "2020-12-01T02:48:28.851Z", - "contributors": [ - "OmniP", - "wangyukai04", - "xgqfrms-GitHub", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/fround": { - "modified": "2019-04-05T14:46:26.026Z", - "contributors": [ - "SphinxKnight", - "zxsunrise", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/hypot": { - "modified": "2020-10-15T21:25:13.114Z", - "contributors": [ - "Dorence", - "hellorayza", - "plutonji", - "SphinxKnight", - "tiansh", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/imul": { - "modified": "2020-01-20T10:35:52.662Z", - "contributors": [ - "徐鹏跃", - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/log": { - "modified": "2019-03-23T23:34:08.078Z", - "contributors": [ - "kyriejoshua", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/log10": { - "modified": "2019-03-23T23:24:22.200Z", - "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/log1p": { - "modified": "2019-03-23T23:24:22.369Z", - "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/log2": { - "modified": "2019-03-27T00:02:26.543Z", - "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/max": { - "modified": "2020-10-15T21:28:51.161Z", - "contributors": [ - "zhangchen", - "zzykillu", - "littleRice", - "FlowingRiver", - "Gohikin", - "helloguangxue", - "tiansh", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/min": { - "modified": "2019-10-10T16:47:54.897Z", - "contributors": [ - "FlowingRiver", - "Ende93", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/pow": { - "modified": "2020-10-15T21:28:50.816Z", - "contributors": [ - "zhangchen", - "bestlbw", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/random": { - "modified": "2020-10-15T21:25:37.360Z", - "contributors": [ - "Ende93", - "Jing1107", - "Soyaine", - "wutiande", - "hhxxhg", - "meng-Macbook", - "ywjco", - "ZZES_REN", - "Daniel_Liu", - "xgqfrms-GitHub", - "AlexChao", - "teoli", - "ndon" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/round": { - "modified": "2019-09-15T15:07:27.927Z", - "contributors": [ - "shelter9824", - "zxsunrise", - "pazingaa", - "xgqfrms-GitHub", - "teoli", - "ziyunfei", - "AlexChao", - "princetoad@gmail.com" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/sign": { - "modified": "2019-08-31T06:02:13.833Z", - "contributors": [ - "xgqfrms-GitHub", - "tiansh", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/sin": { - "modified": "2020-11-11T08:27:43.469Z", - "contributors": [ - "luisleee", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/sinh": { - "modified": "2020-08-20T08:15:43.793Z", - "contributors": [ - "635153226", - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/sqrt": { - "modified": "2020-10-15T21:28:52.595Z", - "contributors": [ - "zhangchen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/tan": { - "modified": "2019-08-31T06:01:37.228Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/tanh": { - "modified": "2020-10-15T21:49:09.190Z", - "contributors": [ - "Dorence", - "Yunme", - "Gohikin", - "lsvih" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/trunc": { - "modified": "2020-10-15T21:25:16.193Z", - "contributors": [ - "zxsunrise", - "Ende93", - "ziyunfei", - "tiansh", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Math/反双曲余弦值": { - "modified": "2020-10-15T21:50:09.940Z", - "contributors": [ - "Dorence", - "wizardforcel", - "LiuYuan" - ] - }, - "Web/JavaScript/Reference/Global_Objects/NaN": { - "modified": "2020-10-15T21:21:08.233Z", - "contributors": [ - "wallena3", - "HuangXin", - "caofei6", - "zxsunrise", - "EthanOrange", - "Jiang-Xuan", - "Ende93", - "yenshen", - "SphinxKnight", - "ziyunfei", - "AlexChao", - "teoli", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number": { - "modified": "2020-10-15T21:21:06.513Z", - "contributors": [ - "SageX", - "Mookiepiece", - "huxinsen", - "hhxxhg", - "shevche24", - "re09", - "righttoe", - "yurielZhang", - "liudeyuan", - "liuzeyafzy", - "Ende93", - "teoli", - "xuxiaodong", - "ethertank" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/EPSILON": { - "modified": "2019-10-14T12:34:30.960Z", - "contributors": [ - "SageX", - "Fire1nRain", - "Liugq5713", - "AlexChao", - "jokeviner" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER": { - "modified": "2019-11-10T23:49:14.665Z", - "contributors": [ - "zotille", - "AlexChao", - "jokeviner" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE": { - "modified": "2019-03-18T20:54:24.017Z", - "contributors": [ - "dsgygb", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER": { - "modified": "2020-10-15T21:48:36.767Z", - "contributors": [ - "SphinxKnight", - "User670", - "suxiesumiao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE": { - "modified": "2019-03-23T23:13:08.431Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY": { - "modified": "2019-03-23T23:13:05.395Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/NaN": { - "modified": "2019-04-06T03:20:31.087Z", - "contributors": [ - "AlexChao", - "teoli", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/Number": { - "modified": "2020-10-15T22:32:37.356Z", - "contributors": [ - "爬上神坛的猫" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY": { - "modified": "2019-03-23T23:12:58.979Z", - "contributors": [ - "helinjiang", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/isFinite": { - "modified": "2020-10-15T21:24:17.461Z", - "contributors": [ - "zhangchen", - "AlexChao", - "teoli", - "ziyunfei", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/isInteger": { - "modified": "2020-10-15T21:24:18.300Z", - "contributors": [ - "yanhaijing1234", - "daihaoxin", - "oldmtn", - "Ende93", - "teoli", - "ziyunfei", - "tiansh", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/isNaN": { - "modified": "2020-10-15T21:19:55.509Z", - "contributors": [ - "RainSlide", - "polunzh", - "daihaoxin", - "xgqfrms-GitHub", - "AlexChao", - "yenshen", - "teoli", - "yufeng", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger": { - "modified": "2020-10-15T21:27:54.542Z", - "contributors": [ - "yanhaijing1234", - "hellorayza", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/parseFloat": { - "modified": "2019-11-08T10:17:37.826Z", - "contributors": [ - "hellorayza", - "Youzi", - "SphinxKnight", - "AlexChao", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/parseInt": { - "modified": "2020-10-15T21:32:59.587Z", - "contributors": [ - "hellorayza", - "SageX", - "edward870505", - "NiLinli", - "iugo", - "ziyunfei", - "tiansh" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/prototype": { - "modified": "2019-03-23T22:12:02.199Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/toExponential": { - "modified": "2019-04-06T03:30:46.772Z", - "contributors": [ - "zhazhjie", - "yunl819", - "helloguangxue", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/toFixed": { - "modified": "2020-10-15T21:28:32.902Z", - "contributors": [ - "zeroxie", - "liuruiqi1993", - "Xiaoming666", - "rulanfenghua", - "PageYe", - "yenshen", - "Jinjiang", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/toLocaleString": { - "modified": "2020-10-15T21:28:46.243Z", - "contributors": [ - "RoXoM", - "dongchaoge", - "Sivan", - "Hugh", - "anchengjian", - "shuding", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/toPrecision": { - "modified": "2019-09-09T23:08:23.767Z", - "contributors": [ - "helloguangxue", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/toSource": { - "modified": "2019-04-06T03:53:43.075Z", - "contributors": [ - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/toString": { - "modified": "2019-07-09T06:38:38.264Z", - "contributors": [ - "LeoSpark", - "ywjco", - "xgqfrms-GitHub", - "righttoe", - "YoungChen", - "yenshen", - "AlexChao", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Number/valueOf": { - "modified": "2019-04-06T04:03:18.487Z", - "contributors": [ - "weiqinl", - "ziyunfei", - "yenshen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object": { - "modified": "2020-10-15T21:07:58.316Z", - "contributors": [ - "VictoriaChou", - "oldguan", - "oxyg3n", - "sunshine8752", - "yzh196", - "CelestialPhineas", - "RainSlide", - "zhangchen", - "lee-joe", - "xgqfrms-GitHub", - "kangaoxiaoshi", - "Hugh", - "tomoat", - "hxlhxl", - "Ende93", - "scscms", - "charlie", - "ziyunfei", - "paddingme", - "AlexChao", - "teoli", - "iwo" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf": { - "modified": "2020-10-15T21:07:55.199Z", - "contributors": [ - "futurefeeling", - "ywjco", - "zhangchen", - "xgqfrms-GitHub", - "teoli", - "AlexChao", - "paddingme", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/Object": { - "modified": "2020-10-15T22:29:02.706Z", - "contributors": [ - "jiyiwohanxing" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__": { - "modified": "2019-03-23T23:05:45.020Z", - "contributors": [ - "ziyunfei", - "LinusYu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/__defineSetter__": { - "modified": "2019-03-23T23:05:56.544Z", - "contributors": [ - "ziyunfei", - "LinusYu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/__lookupGetter__": { - "modified": "2019-03-23T23:14:35.158Z", - "contributors": [ - "MurphyL", - "ziyunfei", - "lutaoact" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/__lookupSetter__": { - "modified": "2019-03-23T22:21:56.129Z", - "contributors": [ - "winjeysong", - "lisniuse" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/assign": { - "modified": "2020-10-21T06:50:11.039Z", - "contributors": [ - "srq18211", - "xgqfrms", - "sjnho", - "SphinxKnight", - "YF05105814", - "zac_ma", - "shery", - "shutong", - "HJava", - "Jiang-Xuan", - "zhangchen", - "xgqfrms-GitHub", - "micheal-death", - "kiyonlin", - "Wayme", - "glgjssy", - "Ende93", - "Y____C", - "zhangking", - "calmcarry", - "iamchenxin", - "ziyunfei", - "rebornix" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/constructor": { - "modified": "2020-10-15T21:22:02.873Z", - "contributors": [ - "Lan1967", - "zhangchen", - "icyzeroice", - "luoxzhg", - "Hugh", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/create": { - "modified": "2020-11-17T22:40:03.747Z", - "contributors": [ - "zhuangyin", - "kaiyuan-c", - "yukyao", - "Aster.", - "symant233", - "zhanghao-zhoushan", - "Ahhaha233", - "name-dingding", - "Lan1967", - "wangzherlf", - "LuckyJoker", - "zhangchen", - "evan_Yuanzh", - "luoxzhg", - "ywjco", - "cuji", - "Tuoe", - "foreverwang", - "HuazzTsai", - "Cribug8080", - "Ende93", - "xgqfrms-GitHub", - "runighcat", - "ouonet", - "Hopcraft", - "luojia", - "AlexChao", - "teoli", - "ziyunfei", - "Chajn", - "georgewing", - "nightire", - "bingjie2680", - "fscholz", - "raymoth", - "Mgjbot", - "Kaixin110", - "Cnmahj", - "Mhoudg", - "Andyyard", - "Carrie zhxj", - "Mickeyboy", - "Verruckt", - "Taken", - "Ahong" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/defineProperties": { - "modified": "2020-10-15T21:04:47.093Z", - "contributors": [ - "zhangchen", - "xgqfrms-GitHub", - "microTT", - "ziyunfei", - "AlexChao", - "teoli", - "OoOoOoOo", - "leeli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/defineProperty": { - "modified": "2020-12-03T03:27:16.867Z", - "contributors": [ - "daniel_tsai", - "liushuaimaya", - "symant233", - "lijinwenhg", - "RainSlide", - "sunw", - "mingzhang6", - "liuliuLiu161", - "walwimp", - "leavesster", - "onedaywen", - "junyuli1992", - "Xmader", - "zhanghy7", - "Josnk", - "lmislm", - "weidapao", - "CaptainInPHW", - "zotille", - "LeoSpark", - "i850", - "Mrdapeng", - "yuyongjun123", - "buptsky", - "ywjco", - "Wutang", - "Black-Hole", - "zhangchen", - "xiiiAtCn", - "C_Kite", - "MrITzhongzi", - "usernameisMan", - "zilong", - "ziyunfei", - "dttx123", - "win5do", - "Ende93", - "righttoe", - "hicrow", - "xgqfrms-GitHub", - "maxmeng", - "whwei", - "xuemengfei", - "riversYeHaha", - "harttle", - "coolguy", - "KingMario", - "helinjiang", - "Lenville", - "teoli", - "TimothyZhang", - "AlexChao", - "aaron4512", - "jiraiya", - "yanhaijing", - "StuPig", - "OoOoOoOo" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/entries": { - "modified": "2020-10-15T21:47:29.698Z", - "contributors": [ - "symant233", - "versionlin7", - "zhangchen", - "spiritree", - "xgqfrms-GitHub", - "OshotOkill" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/freeze": { - "modified": "2020-10-15T21:04:51.609Z", - "contributors": [ - "Frederick-S", - "lejsure", - "mingttong", - "zhangchen", - "ywjco", - "sqliang", - "zhouyuanhao", - "Ende93", - "AlexChao", - "teoli", - "ziyunfei", - "undercooled" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/fromEntries": { - "modified": "2020-10-15T22:09:07.388Z", - "contributors": [ - "zhangchen", - "qiudongwei", - "iugo", - "xiaopingzhang0207", - "kohai", - "Bayes" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor": { - "modified": "2020-10-15T21:04:53.010Z", - "contributors": [ - "Damoness", - "274659281", - "RoXoM", - "liuyangjoker", - "usernameisMan", - "Ende93", - "teoli", - "AlexChao", - "ArthasTree", - "ziyunfei", - "nightire" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors": { - "modified": "2020-10-15T21:47:29.156Z", - "contributors": [ - "Aaron-Bird", - "RoXoM", - "kdex", - "Hushabyme", - "delkaka", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames": { - "modified": "2020-10-15T21:04:50.666Z", - "contributors": [ - "woyaohaohaoxuexi", - "ywjco", - "zhangchen", - "C_Kite", - "kdex", - "Ende93", - "RandyOu", - "ChrisCindy", - "helinjiang", - "teoli", - "AlexChao", - "ziyunfei", - "Arenwisdom" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols": { - "modified": "2020-10-15T21:28:24.757Z", - "contributors": [ - "zhangchen", - "limichange", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty": { - "modified": "2020-11-12T05:23:35.945Z", - "contributors": [ - "haichao0817", - "Harry-Zhao", - "RainSlide", - "liuzhengdong", - "ShirleyM", - "xgqfrms-GitHub", - "Ende93", - "ziyunfei", - "yyj" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/is": { - "modified": "2020-10-15T21:22:02.169Z", - "contributors": [ - "jaredhan418", - "Mirefire", - "ngulee", - "RainSlide", - "42", - "zhangchen", - "shaojingchao", - "xgqfrms-GitHub", - "Ende93", - "ziyunfei", - "snandy", - "teoli", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/isExtensible": { - "modified": "2019-03-24T12:06:06.825Z", - "contributors": [ - "fanerge", - "helinjiang", - "AlexChao", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/isFrozen": { - "modified": "2020-10-15T21:04:51.362Z", - "contributors": [ - "XiongAmao", - "zhangchen", - "xgqfrms-GitHub", - "micheal-death", - "WangXiao", - "helinjiang", - "AlexChao", - "teoli", - "ziyunfei", - "undercooled" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf": { - "modified": "2019-07-25T07:55:33.320Z", - "contributors": [ - "xhlsrj", - "xgqfrms-GitHub", - "Ende93", - "helloguangxue", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/isSealed": { - "modified": "2020-10-15T21:04:48.021Z", - "contributors": [ - "yuyeqianxun", - "zhangchen", - "xgqfrms-GitHub", - "Ende93", - "helinjiang", - "AlexChao", - "teoli", - "ziyunfei", - "undercooled" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/keys": { - "modified": "2020-10-15T21:06:49.993Z", - "contributors": [ - "fbfatboy", - "Cuixote", - "liuzhengdong", - "SphinxKnight", - "Vike50", - "zhuangyin", - "dc165015", - "zhangchen", - "ywjco", - "xgqfrms-GitHub", - "Ende93", - "Lynn0108", - "kdex", - "micheal-death", - "zaxlct", - "WhiteMind", - "qdxt", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/preventExtensions": { - "modified": "2020-10-15T21:04:47.741Z", - "contributors": [ - "Astroleander", - "zhangchen", - "recursion", - "AlexChao", - "teoli", - "ziyunfei", - "undercooled" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable": { - "modified": "2020-10-15T21:21:12.490Z", - "contributors": [ - "RainSlide", - "zhangchen", - "TiaossuP", - "helloguangxue", - "Gresic", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/proto": { - "modified": "2020-10-15T21:20:42.886Z", - "contributors": [ - "milyyy", - "Ende93", - "rjdangcc", - "HIKALU-Z", - "Btista", - "trotyl", - "wolyshaw", - "xgqfrms-GitHub", - "eeeeeeeason", - "Howard.Chen", - "Wayme", - "lisniuse", - "redcool007", - "Leslie2014", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/prototype": { - "modified": "2020-10-15T21:21:47.231Z", - "contributors": [ - "SphinxKnight", - "daihaoxin", - "zhangchen", - "wwy2018", - "Linjing", - "WizardAlice", - "ywjco", - "xgqfrms-GitHub", - "Cattla", - "scscms", - "webery", - "luoway", - "ziyunfei", - "LinusYu", - "teoli", - "iwo" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/seal": { - "modified": "2020-10-15T21:04:46.777Z", - "contributors": [ - "1997Liusheng", - "acejerry", - "zhangchen", - "cwwjie", - "toBeTheLight", - "zixiangTang", - "AlexChao", - "teoli", - "ziyunfei", - "monthev" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf": { - "modified": "2020-10-15T21:23:41.066Z", - "contributors": [ - "zhuguibiao", - "fengma", - "xgqfrms-GitHub", - "kameii", - "inJs", - "xuzhijun", - "helm", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/toLocaleString": { - "modified": "2020-10-15T21:28:39.035Z", - "contributors": [ - "ShirleyM", - "Humyang", - "zhangchen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/toSource": { - "modified": "2020-10-15T21:21:01.572Z", - "contributors": [ - "qiu_han", - "zhangchen", - "xgqfrms-GitHub", - "keller0", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/toString": { - "modified": "2020-10-15T21:22:00.834Z", - "contributors": [ - "RainSlide", - "jbbjs", - "johnlin0207", - "zhangchen", - "xgqfrms-GitHub", - "wizardforcel", - "Hugh", - "sabrinaluo", - "AlexChao", - "ziyunfei", - "ZhouMengkang", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/valueOf": { - "modified": "2020-10-15T21:19:19.149Z", - "contributors": [ - "microJ", - "ywjco", - "zhangchen", - "zilong-thu", - "jimwmg", - "Ende93", - "helloguangxue", - "paddingme", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Object/values": { - "modified": "2020-10-15T21:42:31.053Z", - "contributors": [ - "Bayes", - "RoXoM", - "ywjco", - "zhangchen", - "spiritree", - "percy507", - "maicss", - "xgqfrms-GitHub", - "Hushabyme", - "webery" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise": { - "modified": "2020-11-09T05:18:40.533Z", - "contributors": [ - "13126767772", - "Neo42", - "NickH", - "jackyKin", - "SandBoat", - "xgqfrms", - "woniuxingdong", - "ourai", - "w1687021088", - "xianghui-ma", - "42", - "SterileSummer", - "ZhechenLi", - "kyriejoshua", - "DHclly", - "Jiang-Xuan", - "filosfino", - "dandanbu3", - "suwu150", - "YISHI", - "Debugger-D", - "winjeysong", - "sjz2259696", - "NoroHime", - "SunApriloy", - "xutao", - "_da", - "wYhooo", - "tangHanSan", - "ThaddeusJiang", - "lindaxiao-hust", - "xgqfrms-GitHub", - "HenryYong", - "Ende93", - "liujun121533", - "pot-code", - "lihx_hit", - "sensui7", - "udoless", - "dingxu", - "AnnAngela", - "excosy", - "billcz", - "Yidada", - "hipop", - "dear-lizhihua", - "xuanxiao2013", - "fskuok", - "mountainmoon", - "Fantasy_shao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/Promise": { - "modified": "2020-10-15T22:27:28.549Z", - "contributors": [ - "GYN" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/all": { - "modified": "2020-10-15T21:34:13.137Z", - "contributors": [ - "xgqfrms", - "Debugger-D", - "moldray", - "kite-js", - "gemmi", - "Jiang-Xuan", - "BearZ", - "higrw", - "xgqfrms-GitHub", - "rollinhup", - "Hushabyme", - "iugo", - "billcz", - "zilong-thu", - "fskuok" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/allSettled": { - "modified": "2020-11-21T01:58:43.408Z", - "contributors": [ - "xgqfrms", - "wowoqu", - "mountainmoon", - "chrisdavidmills", - "zhangchen", - "bangbang93", - "RoXoM", - "youngboy", - "SphinxKnight", - "jiaqunying" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/any": { - "modified": "2020-10-27T03:51:15.177Z", - "contributors": [ - "SphinxKnight", - "mashuiquan", - "damengzhang", - "laampui", - "XLCYun", - "zhangchen", - "yinguangyao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/catch": { - "modified": "2020-10-15T21:31:34.215Z", - "contributors": [ - "oldmtn", - "xycd", - "banli17", - "zhishaofei3", - "SheltonDong", - "Yevvb", - "HsuanLee", - "xgqfrms-GitHub", - "Hushabyme", - "fskuok", - "mountainmoon" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/finally": { - "modified": "2020-10-15T22:01:56.341Z", - "contributors": [ - "WangLeto", - "zhangchen", - "Pada", - "ZQ-jhon", - "sudoor", - "ziclee", - "zhengzongyi", - "hoshino111" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/prototype": { - "modified": "2019-06-27T05:04:40.773Z", - "contributors": [ - "SphinxKnight", - "cyancity", - "Bryannnnnnn", - "HenryYong", - "mountainmoon" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/race": { - "modified": "2020-10-15T21:34:18.502Z", - "contributors": [ - "Cuixote", - "lastnigtic", - "zhangchen", - "Jiang-Xuan", - "xgqfrms-GitHub", - "zhang-quan-yi", - "Hushabyme", - "fskuok" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/reject": { - "modified": "2020-10-15T21:34:10.841Z", - "contributors": [ - "zhangchen", - "ChauMing", - "Flcwl", - "SphinxKnight", - "fskuok" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/resolve": { - "modified": "2020-10-15T21:36:39.943Z", - "contributors": [ - "inlym", - "ly023", - "zhangchen", - "xiaoxiyao", - "rockedpanda", - "cyancity", - "Jiang-Xuan", - "fscholz", - "nineSean", - "purple_force", - "Zhangjd", - "ylc395" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Promise/then": { - "modified": "2020-10-15T21:31:32.284Z", - "contributors": [ - "BadmasterY", - "RainSlide", - "zrefrain", - "triboby", - "litbear", - "love999262", - "Jiang-Xuan", - "LiXin", - "WenWu92", - "Kylin.this", - "HsuanLee", - "xgqfrms-GitHub", - "Ende93", - "Hushabyme", - "RandyLoop", - "hipop", - "liuyiqian", - "fskuok", - "mountainmoon" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy": { - "modified": "2020-11-29T05:45:07.225Z", - "contributors": [ - "saifeiLee", - "VicterSun", - "RainSlide", - "Hilshire", - "liuguanyu", - "xgqfrms-GitHub", - "zhangchen", - "Lave", - "gaoupon", - "kdex", - "gaopeng", - "07akioni", - "wzx", - "Go7hic", - "WarriorWu", - "Katherina-Miao", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy": { - "modified": "2020-10-15T22:33:06.804Z", - "contributors": [ - "zhanghaoxu0128" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler": { - "modified": "2020-10-15T21:32:21.161Z", - "contributors": [ - "stack_vim", - "RainSlide", - "wallena3", - "daxiazilong", - "Bayes", - "SphinxKnight", - "myl0204", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply": { - "modified": "2020-10-15T21:46:28.417Z", - "contributors": [ - "ngtmuzi", - "wtZZx" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct": { - "modified": "2020-10-15T21:56:26.489Z", - "contributors": [ - "dickenslian", - "DuLinRain" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty": { - "modified": "2019-07-17T00:09:33.026Z", - "contributors": [ - "accountwind", - "Illyrix" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty": { - "modified": "2019-03-23T22:18:37.010Z", - "contributors": [ - "Illyrix" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/get": { - "modified": "2019-03-23T22:32:42.643Z", - "contributors": [ - "Shigma", - "ngtmuzi" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor": { - "modified": "2019-07-28T23:51:58.213Z", - "contributors": [ - "darkmirrors", - "EPSON-LEE", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf": { - "modified": "2020-10-15T21:32:20.694Z", - "contributors": [ - "RainSlide", - "OStoneO", - "SphinxKnight", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/has": { - "modified": "2019-08-25T22:51:33.932Z", - "contributors": [ - "wonschangge", - "EPSON-LEE", - "Hearmen" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible": { - "modified": "2020-10-15T21:59:04.944Z", - "contributors": [ - "wonschangge", - "cxftj" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys": { - "modified": "2019-08-25T23:12:08.688Z", - "contributors": [ - "wonschangge", - "daiqingyun", - "DuLinRain" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions": { - "modified": "2020-10-15T21:59:08.645Z", - "contributors": [ - "jinwanmian", - "wonschangge", - "zxh19890103", - "RoXoM", - "varcat" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/set": { - "modified": "2020-10-15T21:46:38.211Z", - "contributors": [ - "RainSlide", - "wonschangge", - "wtZZx", - "ngtmuzi" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf": { - "modified": "2020-10-15T21:59:05.778Z", - "contributors": [ - "varcat" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Proxy/revocable": { - "modified": "2020-10-15T21:32:15.521Z", - "contributors": [ - "RainSlide", - "SphinxKnight", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RangeError": { - "modified": "2019-03-23T22:27:07.051Z", - "contributors": [ - "wizardforcel", - "MurphyL", - "yatace" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RangeError/prototype": { - "modified": "2020-10-15T22:06:54.468Z", - "contributors": [ - "pea3nut" - ] - }, - "Web/JavaScript/Reference/Global_Objects/ReferenceError": { - "modified": "2019-03-23T22:52:45.441Z", - "contributors": [ - "funroller", - "Tienyz" - ] - }, - "Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype": { - "modified": "2020-10-15T22:04:38.794Z", - "contributors": [ - "Mal_akh" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect": { - "modified": "2020-10-15T21:38:03.417Z", - "contributors": [ - "tita0x00", - "LeonDWong", - "z1948296027", - "ZhangWei-KUMO", - "Akenokoru", - "Ende93", - "AlixWang", - "tanggd", - "Tommy-White", - "linzx1993", - "RoXoM", - "zhangchen", - "xgqfrms-GitHub", - "mo-n", - "wzx", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/apply": { - "modified": "2020-10-15T21:46:16.764Z", - "contributors": [ - "Ende93", - "IAIAE" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/construct": { - "modified": "2020-07-16T14:15:43.959Z", - "contributors": [ - "oxyg3n", - "caolvchong", - "xiaoxionganna", - "tornoda", - "sqqihao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty": { - "modified": "2020-10-15T21:51:24.597Z", - "contributors": [ - "laampui", - "tornoda", - "charlesthink", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty": { - "modified": "2019-07-05T03:12:53.100Z", - "contributors": [ - "tornoda", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/get": { - "modified": "2020-10-15T21:51:21.601Z", - "contributors": [ - "stupidsongshu", - "tornoda", - "AozakiOrenji", - "Hushabyme", - "EpsilonYi" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor": { - "modified": "2019-03-23T22:20:49.977Z", - "contributors": [ - "RoXoM", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf": { - "modified": "2020-10-15T21:51:25.998Z", - "contributors": [ - "徐鹏跃", - "RoXoM", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/has": { - "modified": "2019-03-18T21:00:09.070Z", - "contributors": [ - "sjpeter", - "IAIAE" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible": { - "modified": "2019-03-23T22:20:41.186Z", - "contributors": [ - "cxftj", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys": { - "modified": "2020-10-15T21:51:25.621Z", - "contributors": [ - "zhangchen", - "liuy1994", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions": { - "modified": "2020-10-15T21:51:26.999Z", - "contributors": [ - "Astroleander", - "RoXoM", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/set": { - "modified": "2020-10-15T21:51:25.331Z", - "contributors": [ - "zero7u", - "AozakiOrenji", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf": { - "modified": "2020-10-15T21:51:25.701Z", - "contributors": [ - "徐鹏跃", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Reflect/比较_Reflect_和_Object_方法": { - "modified": "2020-09-02T03:21:36.745Z", - "contributors": [ - "tita0x00" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp": { - "modified": "2020-10-15T21:04:56.799Z", - "contributors": [ - "jingkaimori", - "空杉心雨后", - "ll009366", - "Ende93", - "fanerge", - "daijie", - "wbamberg", - "zhuangyin", - "YoungChen", - "myl0204", - "xgqfrms-GitHub", - "kiling", - "biaocy", - "fuchao2012", - "shuata", - "xgqfrms", - "KingMario", - "vbnjfhty", - "y8n", - "tabooc", - "jamesxu", - "teoli", - "AlexChao", - "chyee", - "Darrel.Hsu", - "photino", - "ziyunfei", - "fishenal", - "akawhy", - "shi_zheng", - "GreatHan", - "Hans huang", - "Mickeyboy" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@match": { - "modified": "2020-10-15T21:49:08.862Z", - "contributors": [ - "Ende93", - "wizardforcel", - "boatlet" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@matchAll": { - "modified": "2020-10-15T22:16:46.561Z", - "contributors": [ - "c1er" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@replace": { - "modified": "2020-10-15T21:54:34.957Z", - "contributors": [ - "javenl", - "LeoQuote", - "876843240", - "fanyer" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@search": { - "modified": "2019-03-23T22:11:28.976Z", - "contributors": [ - "fanyer" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@species": { - "modified": "2019-03-23T22:18:27.389Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@split": { - "modified": "2019-08-22T23:28:14.164Z", - "contributors": [ - "fangyulovechina", - "fanyer" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/RegExp": { - "modified": "2020-10-15T22:33:53.145Z", - "contributors": [ - "jingkaimori" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/compile": { - "modified": "2019-03-23T22:22:52.399Z", - "contributors": [ - "kameii" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/dotAll": { - "modified": "2020-10-15T22:16:46.676Z", - "contributors": [ - "c1er" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/exec": { - "modified": "2020-10-15T21:26:53.403Z", - "contributors": [ - "CarrotB", - "dear-lizhihua", - "PageYe", - "righttoe", - "shiddong", - "ibufu", - "nandayaduo", - "Marco_dev", - "xgqfrms-GitHub", - "hangyangws", - "LiiiiittleRain", - "paddingme", - "baiya", - "teoli", - "AlexChao", - "ziyunfei", - "LinusYu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/flags": { - "modified": "2019-07-04T23:57:57.114Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/global": { - "modified": "2019-07-04T23:58:07.262Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase": { - "modified": "2019-07-04T23:54:43.220Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/input": { - "modified": "2019-04-16T05:59:34.644Z", - "contributors": [ - "gh1031", - "teoli", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex": { - "modified": "2019-07-04T23:55:43.642Z", - "contributors": [ - "teoli", - "AlexChao", - "ziyunfei", - "Wjsl" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch": { - "modified": "2019-03-23T22:18:26.965Z", - "contributors": [ - "teoli", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/lastParen": { - "modified": "2019-03-23T22:18:27.095Z", - "contributors": [ - "teoli", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/leftContext": { - "modified": "2019-03-23T22:18:24.587Z", - "contributors": [ - "teoli", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/multiline": { - "modified": "2019-07-04T23:59:21.859Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/n": { - "modified": "2019-07-12T00:53:55.955Z", - "contributors": [ - "teoli", - "fengma", - "xgqfrms-GitHub", - "AlixWang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/prototype": { - "modified": "2019-07-08T23:50:51.861Z", - "contributors": [ - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/rightContext": { - "modified": "2019-03-23T22:18:24.457Z", - "contributors": [ - "teoli", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/source": { - "modified": "2019-07-04T23:56:46.237Z", - "contributors": [ - "ziyunfei", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/sticky": { - "modified": "2020-10-15T21:51:29.415Z", - "contributors": [ - "Ende93", - "Ahhaha233", - "wenmin92" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/test": { - "modified": "2020-11-19T10:20:16.081Z", - "contributors": [ - "zhuangyin", - "ReedSun", - "symant233", - "ridiculousjam", - "zqyue", - "xgqfrms-GitHub", - "kameii", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/toSource": { - "modified": "2019-07-04T23:42:36.181Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/toString": { - "modified": "2019-07-04T23:42:41.541Z", - "contributors": [ - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/RegExp/unicode": { - "modified": "2019-07-04T23:59:38.859Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set": { - "modified": "2020-11-10T03:33:00.037Z", - "contributors": [ - "SphinxKnight", - "Ongve", - "Ende93", - "wallena3", - "woshiqiang1", - "houzp", - "MYWProgram", - "zhuangyin", - "zhangchen", - "Jiang-Xuan", - "buckarooch", - "xgqfrms-GitHub", - "CoCooCo", - "JJPandari", - "tang45", - "xdsnet", - "dingxu", - "tngan", - "ziyunfei", - "fskuok", - "tiansh", - "teoli", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/@@iterator": { - "modified": "2020-10-15T22:31:10.470Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/@@species": { - "modified": "2020-10-15T22:05:00.184Z", - "contributors": [ - "Ende93", - "susan007", - "helloyong" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/Set": { - "modified": "2020-10-15T22:31:09.443Z", - "contributors": [ - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/add": { - "modified": "2020-10-15T21:28:25.102Z", - "contributors": [ - "Mr_kaze", - "zhuangyin", - "fscholz", - "MaZheng", - "Ende93", - "Skyang", - "yenshen", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/clear": { - "modified": "2019-03-23T23:13:23.536Z", - "contributors": [ - "MaZheng", - "Ende93", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/delete": { - "modified": "2019-07-08T00:12:51.875Z", - "contributors": [ - "adonWong", - "Ende93", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/entries": { - "modified": "2019-03-23T22:25:08.761Z", - "contributors": [ - "Lunaticf", - "timlee1128" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/forEach": { - "modified": "2019-08-05T06:54:27.458Z", - "contributors": [ - "tzmf", - "Jonnypeng", - "SphinxKnight", - "myl0204", - "tommyzqfeng", - "timlee1128", - "201341", - "gaigeshen" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/has": { - "modified": "2019-07-08T00:21:03.715Z", - "contributors": [ - "marsgt", - "MaZheng", - "SphinxKnight", - "Nonlone" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/size": { - "modified": "2020-10-15T21:41:25.836Z", - "contributors": [ - "zhangchen", - "SphinxKnight", - "springuper", - "OmniP" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Set/values": { - "modified": "2020-10-15T21:48:24.054Z", - "contributors": [ - "Mr_kaze", - "qiudongwei", - "marsgt", - "holynewbie" - ] - }, - "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer": { - "modified": "2020-10-15T21:52:10.163Z", - "contributors": [ - "wallena3", - "szengtal", - "RoXoM", - "AnnAngela", - "xgqfrms-GitHub", - "winjeysong" - ] - }, - "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/byteLength": { - "modified": "2020-10-15T21:58:35.573Z", - "contributors": [ - "wallena3", - "xgqfrms-GitHub" - ] - }, - "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype": { - "modified": "2020-10-15T21:58:38.272Z", - "contributors": [ - "wallena3", - "xgqfrms-GitHub" - ] - }, - "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/slice": { - "modified": "2020-10-15T21:58:38.787Z", - "contributors": [ - "wallena3", - "xgqfrms-GitHub" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String": { - "modified": "2020-05-13T00:15:31.329Z", - "contributors": [ - "canyi1942", - "RainSlide", - "Ejgwg0629", - "transping", - "zhangsenhua", - "frankfang1990", - "huangbom", - "xgqfrms-GitHub", - "ezirmusitua", - "sevenqi", - "ouzz413", - "MrBeike", - "msmailcode", - "git123hub", - "Soy", - "webpansy", - "liurenxingyu", - "lunix01", - "FredWe", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/@@iterator": { - "modified": "2019-10-14T06:47:30.493Z", - "contributors": [ - "SageX", - "Dewey." - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/Trim": { - "modified": "2020-10-15T21:07:55.641Z", - "contributors": [ - "brizer", - "RainSlide", - "SageX", - "xgqfrms-GitHub", - "Ende93", - "helloguangxue", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/TrimLeft": { - "modified": "2020-10-15T21:07:56.369Z", - "contributors": [ - "RainSlide", - "SageX", - "zhangchen", - "xgqfrms-GitHub", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/TrimRight": { - "modified": "2020-10-15T21:07:55.509Z", - "contributors": [ - "SageX", - "zhangchen", - "teoli", - "Ende93", - "xgqfrms-GitHub", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/anchor": { - "modified": "2019-10-13T02:57:05.433Z", - "contributors": [ - "SageX", - "xgl", - "wwzText", - "Noly1990", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/big": { - "modified": "2019-08-30T00:30:39.502Z", - "contributors": [ - "wizardforcel", - "Valora", - "JokerPrince" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/blink": { - "modified": "2019-08-30T00:33:08.296Z", - "contributors": [ - "wizardforcel", - "JokerPrince" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/bold": { - "modified": "2019-08-30T00:38:46.883Z", - "contributors": [ - "Ende93", - "Agp12010" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/charAt": { - "modified": "2019-08-30T00:20:40.323Z", - "contributors": [ - "Noly1990", - "xgqfrms-GitHub", - "Hugh", - "MarianZhang", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/charCodeAt": { - "modified": "2020-10-15T21:28:56.069Z", - "contributors": [ - "laampui", - "ChenNing02", - "RainSlide", - "lordisback", - "JuFoFu", - "KMKNKK", - "wizardforcel", - "xgqfrms-GitHub", - "baishusama", - "VmanXu", - "NotFinally", - "MarianZhang", - "Bigbigbig", - "greatbug", - "BeHappyF", - "LittleJake", - "Meteormatt", - "sweetliu", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/codePointAt": { - "modified": "2019-03-18T20:48:31.110Z", - "contributors": [ - "transping", - "xdsnet", - "anchengjian" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/concat": { - "modified": "2020-10-15T21:07:52.015Z", - "contributors": [ - "laampui", - "Skyang", - "yenshen", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/endsWith": { - "modified": "2020-10-15T21:21:07.320Z", - "contributors": [ - "laampui", - "RainSlide", - "Veneno", - "LasyIsLazy", - "hongxu.Wei", - "terasum", - "SphinxKnight", - "percy507", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/fixed": { - "modified": "2019-03-23T22:39:09.482Z", - "contributors": [ - "Ende93", - "chengxc" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/fontcolor": { - "modified": "2019-03-23T22:20:59.919Z", - "contributors": [ - "Jiang-Xuan", - "jieouba" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/fontsize": { - "modified": "2019-03-23T22:22:45.888Z", - "contributors": [ - "JokerPrince" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/fromCharCode": { - "modified": "2020-10-15T21:28:54.977Z", - "contributors": [ - "叶扬", - "laampui", - "weiqinl", - "Jiang-Xuan", - "xgqfrms-GitHub", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/fromCodePoint": { - "modified": "2020-10-15T21:44:06.995Z", - "contributors": [ - "RainSlide", - "varcat", - "transping", - "xiayefeng", - "Hushabyme", - "Cattla", - "lastjune" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/includes": { - "modified": "2020-10-15T21:20:32.653Z", - "contributors": [ - "laampui", - "1v9", - "hongxu.Wei", - "xgqfrms-GitHub", - "Zertu", - "JokerPrince", - "zilong-thu", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/indexOf": { - "modified": "2020-10-15T21:28:57.881Z", - "contributors": [ - "sunchengpeng", - "LaiTaoGDUT", - "inlym", - "Heaan", - "kingsley2036", - "RainSlide", - "a-x", - "xgqfrms-GitHub", - "Ende93", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/italics": { - "modified": "2019-03-23T22:39:41.518Z", - "contributors": [ - "ssruoyan" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/lastIndexOf": { - "modified": "2019-10-13T05:19:10.386Z", - "contributors": [ - "SageX", - "ts0307", - "Heaan", - "GavinMoreYoung", - "yenshen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/length": { - "modified": "2019-03-18T20:48:34.436Z", - "contributors": [ - "yenshen", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/link": { - "modified": "2020-10-15T21:28:55.868Z", - "contributors": [ - "RainSlide", - "teoli", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/localeCompare": { - "modified": "2020-10-15T21:40:52.842Z", - "contributors": [ - "weibangtuo", - "xuqighub", - "Ninja-Xu", - "Lookkkk", - "lcysgsg", - "xgqfrms-GitHub", - "zilong-thu", - "Yuxuan_Jiang", - "helloguangxue", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/match": { - "modified": "2020-11-19T10:33:22.045Z", - "contributors": [ - "zhuangyin", - "GGliushi", - "zhangming8691", - "SageX", - "meng-Macbook", - "Nick_Arron", - "YISHI", - "Freed", - "xgqfrms-GitHub", - "kameii", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/matchAll": { - "modified": "2020-10-15T22:16:17.159Z", - "contributors": [ - "oxyg3n", - "symant233", - "Tangel", - "zytjs", - "BadmasterY", - "SageX", - "Marcia_gm" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/normalize": { - "modified": "2020-10-15T21:26:59.570Z", - "contributors": [ - "RainSlide", - "SageX", - "xgl", - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/padEnd": { - "modified": "2020-10-15T21:44:49.353Z", - "contributors": [ - "zhuangyin", - "calabash519", - "Iwouldliketobeapig", - "comehope", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/padStart": { - "modified": "2020-10-15T21:44:45.823Z", - "contributors": [ - "zhuangyin", - "FredYing", - "dblate", - "Iwouldliketobeapig", - "kdex", - "xgqfrms-GitHub", - "Jiang-Xuan", - "comehope", - "tjyas", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/prototype": { - "modified": "2020-10-15T21:27:29.084Z", - "contributors": [ - "gqbre", - "pabloyshi", - "zhazhjie", - "zqyue", - "Ende93", - "midare", - "Yuxuan_Jiang", - "micheal-death", - "xgqfrms-GitHub", - "Hugh", - "terrycafe520", - "qianjiahao", - "paddingme", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/raw": { - "modified": "2020-10-15T21:29:34.006Z", - "contributors": [ - "SageX", - "Jamsdfn", - "HDUCC", - "OhIAmFine", - "RainSlide", - "RoXoM", - "SphinxKnight", - "joy-yu", - "ShupingLiu", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/repeat": { - "modified": "2020-10-15T21:23:38.769Z", - "contributors": [ - "laampui", - "xgqfrms-GitHub", - "git123hub", - "Ende93", - "OmniP", - "teoli", - "tiansh", - "ziyunfei", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/replace": { - "modified": "2020-11-27T21:45:38.567Z", - "contributors": [ - "lastVigo", - "ZouYj", - "zhangming8691", - "RainSlide", - "SageX", - "zhengwengang", - "bigbird231", - "lwjcjmx123", - "glntlq", - "Ende93", - "qiubo1992", - "dingziqi", - "xgqfrms-GitHub", - "Leeoric", - "benymor", - "imwangpan", - "Zegendary", - "billcz", - "snowsolf", - "S-iscoming", - "lunix01", - "FredWe", - "MoltBoy", - "xinshangshangxin", - "paddingme", - "fannie-z", - "teoli", - "AlexChao", - "robert.yin", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/replaceAll": { - "modified": "2020-10-15T22:30:27.485Z", - "contributors": [ - "Damoness", - "laampui", - "xgqfrms" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/search": { - "modified": "2020-10-15T21:29:01.821Z", - "contributors": [ - "laampui", - "Fleeting198", - "RainSlide", - "xgqfrms-GitHub", - "rockedpanda", - "AlexChao", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/slice": { - "modified": "2020-10-15T21:04:29.173Z", - "contributors": [ - "RainSlide", - "Jemory", - "MinimalistYing", - "zhangchen", - "xgqfrms-GitHub", - "towerzju", - "Meteormatt", - "helloguangxue", - "FredWe", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/small": { - "modified": "2019-03-23T22:22:44.927Z", - "contributors": [ - "wizardforcel", - "JokerPrince" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/split": { - "modified": "2020-10-15T21:28:59.434Z", - "contributors": [ - "real-Row", - "SageX", - "WindLo", - "gentlecoder", - "42", - "hongxu.Wei", - "laampui", - "Jiang-Xuan", - "YISHI", - "JuFoFu", - "ZQH", - "xgqfrms-GitHub", - "Bitzo", - "uestcNaldo", - "zhuangyin", - "mooyxu", - "Hugh", - "auroraeffect", - "azhi09", - "helloguangxue", - "horizon0514", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/startsWith": { - "modified": "2020-10-15T21:21:10.667Z", - "contributors": [ - "zhangchen", - "YouMoeYi", - "RainSlide", - "SimonLeeee", - "SphinxKnight", - "Meteormatt", - "ziyunfei", - "teoli", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/strike": { - "modified": "2019-03-23T22:19:16.420Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/sub": { - "modified": "2019-03-23T22:19:14.417Z", - "contributors": [ - "xgqfrms-GitHub", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/substr": { - "modified": "2019-09-27T00:05:56.009Z", - "contributors": [ - "wingtao", - "xybin1990", - "zhaoboxiang", - "xgqfrms-GitHub", - "helloguangxue", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/substring": { - "modified": "2020-06-10T02:59:54.363Z", - "contributors": [ - "HCSkatana", - "SageX", - "libaixu", - "zhuangyin", - "hexianzhi", - "xgqfrms-GitHub", - "qujingyouyachu", - "helloguangxue", - "bailnl", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/sup": { - "modified": "2019-03-23T22:19:11.494Z", - "contributors": [ - "xgqfrms-GitHub", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase": { - "modified": "2019-10-14T05:00:05.180Z", - "contributors": [ - "SageX", - "853419196", - "wizardforcel", - "xgqfrms-GitHub", - "fighting0710" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase": { - "modified": "2020-10-15T22:29:43.372Z", - "contributors": [ - "konnga" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/toLowerCase": { - "modified": "2020-08-21T17:39:11.325Z", - "contributors": [ - "LCLx", - "SageX", - "xgqfrms-GitHub", - "helloguangxue", - "yenshen", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/toSource": { - "modified": "2019-03-18T20:48:25.704Z", - "contributors": [ - "teoli", - "AlixWang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/toString": { - "modified": "2019-10-14T05:25:34.591Z", - "contributors": [ - "SageX", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/toUpperCase": { - "modified": "2020-10-15T22:30:43.287Z", - "contributors": [ - "LCLx", - "Originalee", - "ahbiao", - "Jabin_Lee" - ] - }, - "Web/JavaScript/Reference/Global_Objects/String/valueOf": { - "modified": "2020-10-15T22:31:18.217Z", - "contributors": [ - "zhangming8691", - "ahbiao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol": { - "modified": "2020-10-19T10:05:29.655Z", - "contributors": [ - "Alendia", - "polunzh", - "JohnhanLiu", - "Coink", - "haoXu-web", - "Revonia", - "zhangchen", - "huge", - "Bitzo", - "winjeysong", - "shaojingchao", - "xgqfrms-GitHub", - "lfkid", - "syhxczy", - "wdpm", - "helloguangxue", - "MapleGu", - "Ende93", - "X-Cracker", - "fscholz" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/@@toPrimitive": { - "modified": "2020-10-15T21:51:10.533Z", - "contributors": [ - "zhangchen", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator": { - "modified": "2020-10-15T22:20:07.992Z", - "contributors": [ - "zhangchen", - "lzfcc" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/description": { - "modified": "2020-10-15T22:12:44.560Z", - "contributors": [ - "Maiko" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/for": { - "modified": "2019-04-22T09:08:37.458Z", - "contributors": [ - "Ende93", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance": { - "modified": "2020-10-15T21:49:33.542Z", - "contributors": [ - "vent", - "zhangchen", - "AlexChao", - "Hushabyme", - "zhouytforever", - "zhengwei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable": { - "modified": "2020-10-15T21:49:33.460Z", - "contributors": [ - "Ende93", - "zhengwei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/iterator": { - "modified": "2020-10-15T21:36:42.166Z", - "contributors": [ - "zhangchen", - "Ende93", - "ziyunfei", - "Jacksunwei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/keyFor": { - "modified": "2020-10-16T06:56:40.936Z", - "contributors": [ - "le-phq", - "zh244135370", - "SphinxKnight", - "purple_force", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/match": { - "modified": "2020-10-15T21:49:57.252Z", - "contributors": [ - "RainSlide", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/matchAll": { - "modified": "2020-10-15T22:18:46.613Z", - "contributors": [ - "Nodiff" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/prototype": { - "modified": "2020-10-15T21:42:54.702Z", - "contributors": [ - "zhangchen", - "purple_force" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/replace": { - "modified": "2020-10-15T21:56:21.976Z", - "contributors": [ - "Ende93", - "cuji" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/search": { - "modified": "2020-11-17T03:44:46.302Z", - "contributors": [ - "KaiserZh", - "ufolux" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/species": { - "modified": "2020-10-15T21:51:11.135Z", - "contributors": [ - "Ende93", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/split": { - "modified": "2020-08-29T01:24:33.903Z", - "contributors": [ - "vent", - "Hushabyme", - "_da" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive": { - "modified": "2020-10-15T21:51:09.142Z", - "contributors": [ - "baooab", - "Mactaivsh", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/toSource": { - "modified": "2019-09-06T06:31:54.610Z", - "contributors": [ - "teoli", - "purple_force" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/toString": { - "modified": "2019-03-23T23:13:48.406Z", - "contributors": [ - "SphinxKnight", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag": { - "modified": "2019-04-22T09:04:43.680Z", - "contributors": [ - "ziyunfei", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/unscopables": { - "modified": "2020-10-15T21:51:10.976Z", - "contributors": [ - "Ende93", - "ywjco", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Symbol/valueOf": { - "modified": "2019-03-23T23:13:43.496Z", - "contributors": [ - "SphinxKnight", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/SyntaxError": { - "modified": "2019-08-07T05:20:14.990Z", - "contributors": [ - "Ende93", - "yenshen", - "Mingun" - ] - }, - "Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype": { - "modified": "2019-03-23T23:03:07.644Z", - "contributors": [ - "Ende93", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypeError": { - "modified": "2020-10-15T21:34:35.462Z", - "contributors": [ - "Tao-Quixote", - "Ende93", - "shajiquan" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypeError/prototype": { - "modified": "2020-10-15T21:39:50.956Z", - "contributors": [ - "Tao-Quixote", - "coolfireWang", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray": { - "modified": "2020-10-15T21:25:05.655Z", - "contributors": [ - "knightyun", - "9-lives", - "tangtangtangtangtang", - "taoyouh", - "Jiang-Xuan", - "Gintoki", - "xgqfrms-GitHub", - "chenyang", - "liyongleihf2006", - "Ende93", - "teoli", - "David_Li" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/@@iterator": { - "modified": "2019-03-23T22:19:18.717Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/@@species": { - "modified": "2019-03-23T22:19:06.809Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT": { - "modified": "2019-03-23T22:52:00.851Z", - "contributors": [ - "iFish" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/buffer": { - "modified": "2019-03-23T22:19:06.244Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/byteLength": { - "modified": "2019-03-23T22:19:10.941Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/byteOffset": { - "modified": "2019-03-23T22:19:08.934Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin": { - "modified": "2020-03-06T04:49:17.530Z", - "contributors": [ - "knightyun", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/entries": { - "modified": "2019-03-23T22:19:07.170Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/every": { - "modified": "2019-03-23T22:19:10.485Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/fill": { - "modified": "2019-03-23T22:11:01.372Z", - "contributors": [ - "benpigchu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/filter": { - "modified": "2019-03-23T22:19:16.643Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/find": { - "modified": "2019-03-23T22:19:12.001Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/findIndex": { - "modified": "2019-03-23T22:19:14.644Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/forEach": { - "modified": "2020-10-15T21:51:57.505Z", - "contributors": [ - "laampui", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/from": { - "modified": "2020-10-15T21:57:11.137Z", - "contributors": [ - "knightyun", - "nekronhuang", - "pasturn" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/includes": { - "modified": "2019-03-23T22:19:11.643Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/indexOf": { - "modified": "2019-03-23T22:20:08.080Z", - "contributors": [ - "xgqfrms-GitHub", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/join": { - "modified": "2019-03-23T22:19:12.294Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/keys": { - "modified": "2019-03-23T22:19:18.105Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/lastIndexOf": { - "modified": "2019-03-23T22:19:04.259Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/length": { - "modified": "2019-03-23T22:19:16.206Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/map": { - "modified": "2019-03-23T22:19:16.989Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/name": { - "modified": "2019-03-23T22:27:51.557Z", - "contributors": [ - "lsvih" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/of": { - "modified": "2019-03-23T22:20:06.649Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/prototype": { - "modified": "2019-03-23T22:21:58.417Z", - "contributors": [ - "wizardforcel", - "liyongleihf2006" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/reduce": { - "modified": "2019-03-23T22:22:18.240Z", - "contributors": [ - "wizardforcel", - "zurl" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/reduceRight": { - "modified": "2019-03-23T22:19:12.473Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/reverse": { - "modified": "2019-03-23T22:19:12.148Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/set": { - "modified": "2020-10-11T08:53:21.212Z", - "contributors": [ - "xyzingh", - "knightyun", - "Kylin.this" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/slice": { - "modified": "2020-10-15T21:59:28.967Z", - "contributors": [ - "luojia", - "lvyue" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/some": { - "modified": "2020-10-15T22:06:36.897Z", - "contributors": [ - "rockSandy" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/sort": { - "modified": "2019-03-23T22:19:06.667Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/subarray": { - "modified": "2020-10-15T22:06:55.665Z", - "contributors": [ - "pea3nut" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/toLocaleString": { - "modified": "2020-10-15T22:07:03.779Z", - "contributors": [ - "taoyouh" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/toString": { - "modified": "2019-03-23T22:20:22.038Z", - "contributors": [ - "kameii" - ] - }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/values": { - "modified": "2019-03-23T22:19:17.373Z", - "contributors": [ - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/Global_Objects/URIError": { - "modified": "2020-10-15T21:58:35.369Z", - "contributors": [ - "Mal_akh", - "Tao-Quixote", - "HCH.no1" - ] - }, - "Web/JavaScript/Reference/Global_Objects/URIError/prototype": { - "modified": "2020-10-15T22:03:36.123Z", - "contributors": [ - "Tao-Quixote" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Uint16Array": { - "modified": "2020-10-15T22:30:29.389Z", - "contributors": [ - "elfpower" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Uint32Array": { - "modified": "2020-10-15T21:30:53.115Z", - "contributors": [ - "Dorence", - "icepro", - "liyongleihf2006", - "chyee" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Uint8Array": { - "modified": "2020-10-15T21:36:50.602Z", - "contributors": [ - "Maiko", - "wizardforcel", - "WhiteMind", - "Meteormatt", - "linus_ding" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray": { - "modified": "2020-08-30T01:01:24.154Z", - "contributors": [ - "vent", - "xhlsrj" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakMap": { - "modified": "2020-10-15T21:06:55.119Z", - "contributors": [ - "Venus14", - "wallena3", - "Ende93", - "WangLeto", - "BingerWeb", - "lizheming", - "hhxxhg", - "xgqfrms-GitHub", - "kameii", - "lvjs", - "Cattla", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/clear": { - "modified": "2019-03-23T22:23:38.007Z", - "contributors": [ - "teoli", - "xgqfrms-GitHub", - "xx1124961758", - "xdsnet" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/delete": { - "modified": "2019-03-23T23:13:54.509Z", - "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/get": { - "modified": "2019-03-23T22:30:00.497Z", - "contributors": [ - "Hushabyme", - "Cattla", - "legend80s" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/has": { - "modified": "2019-03-23T22:23:27.973Z", - "contributors": [ - "xdsnet" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/prototype": { - "modified": "2019-03-23T22:23:35.449Z", - "contributors": [ - "hhxxhg", - "xdsnet" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/set": { - "modified": "2020-10-15T21:50:40.762Z", - "contributors": [ - "Ende93", - "xdsnet" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakRef": { - "modified": "2020-11-04T03:38:15.371Z", - "contributors": [ - "moniang", - "DIFFICULTTOGIVE" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakRef/deref": { - "modified": "2020-11-04T03:35:50.870Z", - "contributors": [ - "moniang" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakSet": { - "modified": "2020-10-15T21:26:50.454Z", - "contributors": [ - "wallena3", - "earlymeme", - "xgqfrms-GitHub", - "Go7hic", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/add": { - "modified": "2019-03-23T22:20:53.399Z", - "contributors": [ - "marsgt", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/clear": { - "modified": "2019-03-23T22:18:46.466Z", - "contributors": [ - "teoli", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/delete": { - "modified": "2020-03-17T12:14:42.437Z", - "contributors": [ - "zhenzhenChange", - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/has": { - "modified": "2019-03-23T22:21:07.252Z", - "contributors": [ - "Hushabyme" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/prototype": { - "modified": "2019-10-09T00:35:58.794Z", - "contributors": [ - "sky-gg", - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly": { - "modified": "2020-10-15T21:53:08.592Z", - "contributors": [ - "wallena3", - "Chesn", - "Gaohaoyang", - "zhangchen", - "chyingp", - "JianrongYu" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError": { - "modified": "2020-10-15T22:26:35.137Z", - "contributors": [ - "wallena3" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Global": { - "modified": "2020-11-13T02:45:14.451Z", - "contributors": [ - "yujiaao", - "yxwsbobo" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance": { - "modified": "2020-10-23T07:01:43.345Z", - "contributors": [ - "liguorain", - "yxwsbobo", - "SphinxKnight" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory": { - "modified": "2020-10-15T22:06:20.710Z", - "contributors": [ - "Zhang-Junzhi", - "sunwanxin213" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Module": { - "modified": "2020-10-15T22:00:19.792Z", - "contributors": [ - "dondevi" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError": { - "modified": "2020-10-15T22:26:27.221Z", - "contributors": [ - "wallena3" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Table": { - "modified": "2020-11-04T03:44:08.051Z", - "contributors": [ - "moniang", - "hurrytospring" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/compile": { - "modified": "2020-10-15T21:58:44.128Z", - "contributors": [ - "kungfucode-rex" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming": { - "modified": "2020-10-15T22:15:30.451Z", - "contributors": [ - "Cyandev" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate": { - "modified": "2020-10-15T21:57:59.458Z", - "contributors": [ - "wallena3", - "Hedgehog", - "airt", - "kungfucode-rex" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming": { - "modified": "2020-10-15T22:11:30.410Z", - "contributors": [ - "Xiaoming666" - ] - }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/validate": { - "modified": "2020-10-15T22:15:29.365Z", - "contributors": [ - "Cyandev" - ] - }, - "Web/JavaScript/Reference/Global_Objects/decodeURI": { - "modified": "2020-10-15T21:22:04.033Z", - "contributors": [ - "Mookiepiece", - "IreneByron", - "laampui", - "xgqfrms-GitHub", - "PoppinL", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/decodeURIComponent": { - "modified": "2020-03-12T19:39:38.099Z", - "contributors": [ - "c1er", - "laampui", - "xgqfrms-GitHub", - "PoppinL", - "maicss", - "Ende93", - "SphinxKnight", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/encodeURI": { - "modified": "2020-03-12T19:39:40.462Z", - "contributors": [ - "xgqfrms-GitHub", - "HelloFun", - "PoppinL", - "leedorian", - "baiya", - "FredWe", - "SphinxKnight", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/encodeURIComponent": { - "modified": "2020-10-15T21:29:33.137Z", - "contributors": [ - "zhangchen", - "oscarwang913", - "inlym", - "maiff", - "HelloFun", - "PoppinL", - "Roland_Reed", - "fortime", - "SphinxKnight", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/escape": { - "modified": "2020-03-12T19:40:29.669Z", - "contributors": [ - "1renhaO", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Global_Objects/eval": { - "modified": "2020-10-15T21:15:16.670Z", - "contributors": [ - "amzrk2", - "mrzhouxu", - "chrislung", - "laampui", - "yasen-wolf", - "RainSlide", - "jinhuiWong", - "Akiq2016", - "extending", - "icepro", - "eeeeeeeason", - "JX-Zhuang", - "yanpengxiang", - "SiberianMark", - "Jiang-Xuan", - "Hugh", - "Binly42", - "ziyunfei", - "fscholz", - "qianjiahao", - "teoli", - "huguowei", - "Mgjbot", - "Laser" - ] - }, - "Web/JavaScript/Reference/Global_Objects/globalThis": { - "modified": "2020-10-15T22:10:51.438Z", - "contributors": [ - "MinimalistYing", - "RainSlide", - "wallena3", - "kangkai0124", - "SphinxKnight", - "LEORChn", - "fscholz", - "Jack.Works" - ] - }, - "Web/JavaScript/Reference/Global_Objects/isFinite": { - "modified": "2020-10-15T21:24:26.397Z", - "contributors": [ - "rulanfenghua", - "littcc", - "Jiang-Xuan", - "golegen", - "SphinxKnight", - "AlexChao", - "teoli", - "zhangyaochun1987" - ] - }, - "Web/JavaScript/Reference/Global_Objects/isNaN": { - "modified": "2020-10-15T21:28:42.019Z", - "contributors": [ - "Ende93", - "ubuntugx", - "bluetata", - "INCHMAN", - "xgqfrms-GitHub", - "mt001mt", - "Hugh", - "cekingLu", - "wanghaoran", - "Skyang", - "yenshen", - "yufeng", - "SphinxKnight", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/null": { - "modified": "2020-10-15T21:21:19.908Z", - "contributors": [ - "wallena3", - "RainSlide", - "GreedyPig", - "zxsunrise", - "zhuangyin", - "Jiang-Xuan", - "SphinxKnight", - "ziyunfei", - "AlexChao", - "teoli" - ] - }, - "Web/JavaScript/Reference/Global_Objects/parseFloat": { - "modified": "2020-10-15T21:21:34.049Z", - "contributors": [ - "laampui", - "rulanfenghua", - "maoyumaoxun", - "ywjco", - "xgqfrms-GitHub", - "huguangju", - "xuzhijun", - "yenshen", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/parseInt": { - "modified": "2020-12-04T02:14:06.997Z", - "contributors": [ - "熊英明", - "liuy666", - "zhuguibiao", - "SAYHISAYHI", - "jjc", - "frankfang1990", - "pantao", - "liuzhengdong", - "lmislm", - "Roland_Reed", - "Eurkidu", - "Mars687", - "cyancity", - "BrightLD", - "hua03", - "ywjco", - "lcxmaple", - "weicaiyue", - "righttoe", - "xgqfrms-GitHub", - "xiaohangJose", - "PengyuanJiang", - "xuzhijun", - "du0m0", - "XingxianLI", - "teoli", - "AlexChao", - "Mickeyboy" - ] - }, - "Web/JavaScript/Reference/Global_Objects/undefined": { - "modified": "2020-10-15T21:21:19.165Z", - "contributors": [ - "wallena3", - "lizhongzhen11", - "ywjco", - "fzhw88", - "zhuangyin", - "WJ941", - "ervinewell", - "kameii", - "Jiang-Xuan", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/unescape": { - "modified": "2020-10-15T21:39:43.532Z", - "contributors": [ - "zhangchen", - "ZivHe", - "Jiang-Xuan", - "Ende93" - ] - }, - "Web/JavaScript/Reference/Global_Objects/uneval": { - "modified": "2020-10-15T21:40:49.845Z", - "contributors": [ - "zhangchen", - "imnodb", - "codert", - "Vincent.Yu" - ] - }, - "Web/JavaScript/Reference/Iteration_protocols": { - "modified": "2020-11-16T00:41:30.233Z", - "contributors": [ - "wubaodong", - "Mr_kaze", - "Clarkkkk", - "DengZhihao", - "RainSlide", - "wangxiujuni", - "houzp", - "edward12699", - "luohe", - "Shigma", - "yueshuiniao", - "isLishude", - "xgqfrms-GitHub", - "kdex", - "bnerDY", - "xgqfrms", - "m31271n.", - "jiraiya", - "harttle", - "holajiawei", - "zbinlin", - "panhezeng", - "Qcui", - "Ende93", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Lexical_grammar": { - "modified": "2020-10-15T21:37:37.250Z", - "contributors": [ - "wwj402", - "RainSlide", - "jiangxin123", - "mistoken", - "DrndwX", - "VdoG", - "eforegist", - "Hitomichan", - "jiahui", - "lunix01" - ] - }, - "Web/JavaScript/Reference/Operators": { - "modified": "2020-11-11T01:18:14.844Z", - "contributors": [ - "Liugq5713", - "Ende93", - "ourai", - "zhangchen", - "zxsunrise", - "ZTFtrue", - "yangzx", - "xgqfrms-GitHub", - "imhaohao", - "Meteormatt", - "tim.liu", - "lunix01", - "Go7hic", - "yenshen", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Operators/Addition_assignment": { - "modified": "2020-10-15T22:32:22.325Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/JavaScript/Reference/Operators/Arithmetic_Operators": { - "modified": "2020-10-15T21:31:37.464Z", - "contributors": [ - "srq18211", - "RainSlide", - "lmislm", - "Braveheartforyou", - "zhangchen", - "xixigeek", - "XHMM", - "ZhengAu", - "aimiy", - "xhlwill", - "xgqfrms-GitHub", - "yayayhoo", - "xiaofengling", - "git123hub", - "AnnAngela", - "tiansh", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Operators/Assignment": { - "modified": "2020-10-15T22:32:28.366Z", - "contributors": [ - "longfangsong", - "hellorayza", - "yemao", - "Linuocc" - ] - }, - "Web/JavaScript/Reference/Operators/Assignment_Operators": { - "modified": "2020-10-15T21:29:35.850Z", - "contributors": [ - "AchooLuv", - "wbamberg", - "cuixiping", - "adoreCherish", - "yofine", - "AlexChao", - "SphinxKnight" - ] - }, - "Web/JavaScript/Reference/Operators/Bitwise_AND_assignment": { - "modified": "2020-10-15T22:34:19.309Z", - "contributors": [ - "Eric_lc", - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Bitwise_NOT": { - "modified": "2020-10-15T22:34:23.865Z", - "contributors": [ - "Eric_lc", - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Bitwise_OR": { - "modified": "2020-10-15T22:34:22.155Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Bitwise_OR_assignment": { - "modified": "2020-10-15T22:34:21.154Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Bitwise_Operators": { - "modified": "2020-03-12T19:40:23.030Z", - "contributors": [ - "xmasuhai", - "GreedyPig", - "parabolazz", - "ywjco", - "xgqfrms-GitHub", - "clcy1243", - "tiansh", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Operators/Bitwise_XOR": { - "modified": "2020-10-15T22:34:22.385Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment": { - "modified": "2020-10-15T22:34:23.846Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Comma_Operator": { - "modified": "2020-10-15T21:32:06.908Z", - "contributors": [ - "zhangchen", - "xgqfrms-GitHub", - "ontheway1215", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Operators/Comparison_Operators": { - "modified": "2020-03-12T19:41:27.611Z", - "contributors": [ - "ch4zzzzz", - "ubuntugx", - "GreedyPig", - "gongzhibin", - "choukin", - "blue0125", - "Ende93", - "beiweiqiang", - "qianjiahao" - ] - }, - "Web/JavaScript/Reference/Operators/Conditional_Operator": { - "modified": "2020-10-15T21:37:34.292Z", - "contributors": [ - "wendy260310", - "dadan", - "KnightYin", - "pluwen", - "zhangchen", - "ziyunfei", - "Ende93", - "lunix01" - ] - }, - "Web/JavaScript/Reference/Operators/Destructuring_assignment": { - "modified": "2020-10-15T21:34:33.159Z", - "contributors": [ - "fanerge", - "kidonng", - "Aaron-Bird", - "zhuziyi", - "ZeroWhiteSmile", - "RainSlide", - "zhangchen", - "tosmaller", - "a-pple", - "FideoJ", - "xgqfrms-GitHub", - "XHMM", - "kdex", - "Jiasm", - "jerryni", - "LeoEatle", - "donyaw", - "starriv", - "TiaossuP", - "WeRDyin", - "panhezeng", - "jiahui", - "pjsong", - "zilong-thu", - "lunix01", - "ziyunfei", - "fskuok" - ] - }, - "Web/JavaScript/Reference/Operators/Division": { - "modified": "2020-10-18T03:29:08.158Z", - "contributors": [ - "MapMaths", - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Division_assignment": { - "modified": "2020-10-15T22:34:21.674Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Exponentiation": { - "modified": "2020-10-18T04:06:14.289Z", - "contributors": [ - "MapMaths", - "xeunglay", - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Exponentiation_assignment": { - "modified": "2020-10-15T22:34:25.557Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Greater_than": { - "modified": "2020-10-15T22:32:32.486Z", - "contributors": [ - "jarirliu" - ] - }, - "Web/JavaScript/Reference/Operators/Greater_than_or_equal": { - "modified": "2020-10-15T22:32:26.171Z", - "contributors": [ - "ziyunfei", - "shishana" - ] - }, - "Web/JavaScript/Reference/Operators/Grouping": { - "modified": "2020-10-15T21:32:23.898Z", - "contributors": [ - "RainSlide", - "Idealist_EZ", - "zhangchen", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Operators/Increment": { - "modified": "2020-11-14T04:00:24.472Z", - "contributors": [ - "seanhuai", - "xgqfrms" - ] - }, - "Web/JavaScript/Reference/Operators/Inequality": { - "modified": "2020-10-18T04:16:16.608Z", - "contributors": [ - "MapMaths", - "YeahPotato" - ] - }, - "Web/JavaScript/Reference/Operators/Left_shift": { - "modified": "2020-10-15T22:34:24.967Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Left_shift_assignment": { - "modified": "2020-10-15T22:34:28.331Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Less_than": { - "modified": "2020-10-15T22:34:22.220Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Less_than_or_equal": { - "modified": "2020-10-15T22:32:26.501Z", - "contributors": [ - "shishana" - ] - }, - "Web/JavaScript/Reference/Operators/Logical_AND_assignment": { - "modified": "2020-10-15T22:34:22.943Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Logical_NOT": { - "modified": "2020-10-15T22:34:26.449Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Logical_OR": { - "modified": "2020-10-15T22:34:22.730Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Logical_OR_assignment": { - "modified": "2020-10-15T22:34:21.861Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Logical_Operators": { - "modified": "2020-10-15T21:22:11.681Z", - "contributors": [ - "HermitSun", - "git710", - "RainSlide", - "withoutmelv", - "SphinxKnight", - "Kaijun", - "fphonor", - "zhangchen", - "YoungChen", - "zhuangyin", - "yenshen", - "teoli", - "MoltBoy" - ] - }, - "Web/JavaScript/Reference/Operators/Logical_nullish_assignment": { - "modified": "2020-10-15T22:33:59.629Z", - "contributors": [ - "JoshOY" - ] - }, - "Web/JavaScript/Reference/Operators/Multiplication": { - "modified": "2020-10-15T22:34:23.887Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Multiplication_assignment": { - "modified": "2020-10-15T22:34:26.770Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Nullish_coalescing_operator": { - "modified": "2020-10-15T22:25:14.991Z", - "contributors": [ - "xgqfrms", - "RainSlide", - "Coink", - "ran" - ] - }, - "Web/JavaScript/Reference/Operators/Object_initializer": { - "modified": "2020-10-15T21:37:33.998Z", - "contributors": [ - "lengjingify", - "zhangchen", - "xgqfrms-GitHub", - "slimeball", - "williamchu123", - "hitme" - ] - }, - "Web/JavaScript/Reference/Operators/Operator_Precedence": { - "modified": "2020-09-26T23:18:03.052Z", - "contributors": [ - "taichiyi", - "Linuocc", - "Yang-yibu", - "zsirfs", - "zhangchen", - "ZQH", - "QinZhiNian", - "jianglinjie", - "xhlwill", - "maicss", - "czyin", - "Ende93", - "AlexChao", - "yenshen", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Operators/Property_Accessors": { - "modified": "2020-10-15T21:37:38.990Z", - "contributors": [ - "RainSlide", - "zhangchen", - "isLishude", - "xiaojunzhou", - "lunix01" - ] - }, - "Web/JavaScript/Reference/Operators/Remainder_assignment": { - "modified": "2020-10-15T22:34:27.144Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Right_shift": { - "modified": "2020-11-02T06:18:13.407Z", - "contributors": [ - "Boswell", - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Right_shift_assignment": { - "modified": "2020-10-15T22:34:28.606Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Spread_syntax": { - "modified": "2020-11-26T05:06:49.056Z", - "contributors": [ - "superchow", - "NorthWind", - "renfufei", - "fanjieqi", - "kczjczhYue", - "zhangchen", - "maoguojun" - ] - }, - "Web/JavaScript/Reference/Operators/Strict_equality": { - "modified": "2020-10-15T22:34:20.707Z", - "contributors": [ - "LydiaYuan" - ] - }, - "Web/JavaScript/Reference/Operators/Strict_inequality": { - "modified": "2020-10-15T22:31:52.866Z", - "contributors": [ - "yemao", - "milulelele" - ] - }, - "Web/JavaScript/Reference/Operators/Subtraction": { - "modified": "2020-10-15T22:34:24.192Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Subtraction_assignment": { - "modified": "2020-10-15T22:34:27.258Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Unary_negation": { - "modified": "2020-10-15T22:34:23.921Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Unary_plus": { - "modified": "2020-10-15T22:34:22.724Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Unsigned_right_shift": { - "modified": "2020-10-15T22:34:23.607Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment": { - "modified": "2020-10-15T22:34:24.975Z", - "contributors": [ - "laampui" - ] - }, - "Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数": { - "modified": "2020-10-15T21:51:08.469Z", - "contributors": [ - "Terry.Qiao", - "fphonor", - "xgqfrms-GitHub", - "x-cold", - "Rusion-Wayne" - ] - }, - "Web/JavaScript/Reference/Operators/await": { - "modified": "2020-08-15T05:29:31.365Z", - "contributors": [ - "zzzimaple", - "shifenjiandan", - "Syclover-u2400", - "chang-shuai", - "i850", - "shhider", - "xgqfrms-GitHub", - "chenlexing", - "x-cold", - "liuqipeng417" - ] - }, - "Web/JavaScript/Reference/Operators/class": { - "modified": "2020-10-15T21:37:37.172Z", - "contributors": [ - "Peidong_Xie", - "fscholz", - "xgqfrms-GitHub", - "zyq930501", - "ziyunfei", - "sartrey", - "lunix01" - ] - }, - "Web/JavaScript/Reference/Operators/delete": { - "modified": "2020-10-15T21:07:30.470Z", - "contributors": [ - "zcdll", - "wallena3", - "zhangchen", - "wendy260310", - "yaksha", - "pyz1989", - "Vincent-yz", - "ucev", - "jamesfancy", - "ZackBee", - "lazybusy", - "Ende93", - "xgqfrms-GitHub", - "xwartz", - "AlexChao", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Operators/function": { - "modified": "2020-03-12T19:39:30.038Z", - "contributors": [ - "inlics", - "LJJ1996", - "ucev", - "zhuangyin", - "ryanlid", - "xgqfrms-GitHub", - "Ende93", - "AlexChao", - "SphinxKnight", - "nightire" - ] - }, - "Web/JavaScript/Reference/Operators/function*": { - "modified": "2020-10-15T21:37:40.102Z", - "contributors": [ - "HCSkatana", - "zhangchen", - "chenyeah", - "ShupingLiu", - "ooops", - "lunix01" - ] - }, - "Web/JavaScript/Reference/Operators/in": { - "modified": "2020-10-15T21:21:37.099Z", - "contributors": [ - "zhuangyin", - "zhangchen", - "lemonsWen", - "kameii", - "zachary05", - "AlexChao", - "SphinxKnight", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Operators/instanceof": { - "modified": "2020-10-15T21:07:55.878Z", - "contributors": [ - "Lsnsh", - "kidonng", - "chenzhh", - "helloyong", - "zhangchen", - "LJJ1996", - "Minhow.liu", - "zhuangyin", - "xgqfrms-GitHub", - "ReedSun", - "liudanning", - "xgqfrms", - "SamuraiMe", - "jonkee", - "suffering", - "Ende93", - "jetzhliu", - "floraLam", - "tiansh", - "AlexChao", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Operators/new": { - "modified": "2020-10-15T21:30:30.354Z", - "contributors": [ - "HermitSun", - "lmx-Hexagram", - "wuwensheng1992", - "RainSlide", - "toyflivver", - "nanyang24", - "Akiq2016", - "zhangchen", - "btea", - "zhuangyin", - "TroyMa1990", - "xgqfrms-GitHub", - "pokka", - "ruiM92", - "Ke.shidong", - "yangzi", - "yenshen", - "fskuok", - "jiacai2050", - "fphonor", - "SphinxKnight", - "TomWan" - ] - }, - "Web/JavaScript/Reference/Operators/new.target": { - "modified": "2020-10-15T21:39:57.852Z", - "contributors": [ - "RoXoM", - "jafck", - "zhangchen", - "sunhengzhe", - "ngtmuzi", - "ccnuzindex" - ] - }, - "Web/JavaScript/Reference/Operators/super": { - "modified": "2020-10-15T21:34:14.337Z", - "contributors": [ - "jackyqin", - "t.ccydlj", - "woshiqiang1", - "hikigaya58", - "KennyWho", - "Yayure", - "wangmiJM", - "zhangchen", - "xgqfrms-GitHub", - "lvjs", - "saintwinkle" - ] - }, - "Web/JavaScript/Reference/Operators/this": { - "modified": "2020-10-15T21:24:16.968Z", - "contributors": [ - "Clarkkkk", - "imbant", - "laampui", - "ldsyzjb", - "aaaxiu", - "frankchia", - "usernameisMan", - "Xuemuyang", - "luoxzhg", - "Akiq2016", - "secretmadonna", - "zhangchen", - "jasonwithjs", - "rollinhup", - "anderson_liu", - "KngZhi", - "xgqfrms-GitHub", - "JJPandari", - "07akioni", - "Cmen", - "bodii", - "Ende93", - "eric183", - "floraLam", - "teoli", - "haodut", - "zhanglun", - "jaka", - "JinZheng", - "DaoG" - ] - }, - "Web/JavaScript/Reference/Operators/typeof": { - "modified": "2020-11-25T06:03:35.454Z", - "contributors": [ - "zhuangyin", - "AidanDai", - "kidonng", - "levo2165", - "zhangchen", - "huangtt", - "Crazycheng", - "DarkYeahs", - "Bitzo", - "bengfor", - "xgqfrms", - "zachary05", - "auver", - "yufeng", - "AlexChao", - "teoli", - "ziyunfei", - "ethertank" - ] - }, - "Web/JavaScript/Reference/Operators/void": { - "modified": "2020-10-15T21:30:34.673Z", - "contributors": [ - "seiry", - "Yidada", - "zhangchen", - "xycd", - "xgqfrms-GitHub", - "Ende93", - "lunix01", - "yenshen", - "ziyunfei", - "AlexChao", - "SphinxKnight", - "parano" - ] - }, - "Web/JavaScript/Reference/Operators/yield": { - "modified": "2020-10-15T21:26:10.731Z", - "contributors": [ - "RedemptioM", - "Yongest", - "Usey95", - "zhangchen", - "lfy55", - "xgqfrms-GitHub", - "AlexChao", - "mountainmoon", - "teoli", - "lpy" - ] - }, - "Web/JavaScript/Reference/Operators/yield*": { - "modified": "2020-10-15T21:32:40.952Z", - "contributors": [ - "zhangchen", - "xgqfrms-GitHub", - "ccn1010", - "ziyunfei", - "Liyunsheng" - ] - }, - "Web/JavaScript/Reference/Operators/取余": { - "modified": "2020-10-15T22:30:57.453Z", - "contributors": [ - "parabolazz" - ] - }, - "Web/JavaScript/Reference/Operators/可选链": { - "modified": "2020-11-05T00:32:59.486Z", - "contributors": [ - "MinimalistYing", - "xgqfrms", - "RainSlide", - "zhangchen", - "Coink", - "daolanfler", - "lmislm", - "Ende93", - "wsv587" - ] - }, - "Web/JavaScript/Reference/Operators/按位与": { - "modified": "2020-10-15T22:33:57.582Z", - "contributors": [ - "hellorayza" - ] - }, - "Web/JavaScript/Reference/Operators/相加": { - "modified": "2020-10-15T22:31:36.619Z", - "contributors": [ - "lws123321", - "Spengh" - ] - }, - "Web/JavaScript/Reference/Operators/相等": { - "modified": "2020-10-28T03:33:52.196Z", - "contributors": [ - "SphinxKnight", - "thefirst-ma", - "zhangchen", - "lujing2", - "milulelele" - ] - }, - "Web/JavaScript/Reference/Operators/管道操作符": { - "modified": "2020-10-15T21:59:15.552Z", - "contributors": [ - "RainSlide", - "fsy0718", - "zhangchen", - "qdlaoyao", - "fphonor" - ] - }, - "Web/JavaScript/Reference/Operators/自减": { - "modified": "2020-10-15T22:33:30.374Z", - "contributors": [ - "helsmy" - ] - }, - "Web/JavaScript/Reference/Operators/逻辑和": { - "modified": "2020-10-15T22:32:55.133Z", - "contributors": [ - "matsongajapan" - ] - }, - "Web/JavaScript/Reference/Reserved_words": { - "modified": "2019-03-23T23:46:04.954Z", - "contributors": [ - "fangnanjun", - "Haichao", - "teoli", - "Mickeyboy" - ] - }, - "Web/JavaScript/Reference/Statements": { - "modified": "2020-11-19T11:54:21.852Z", - "contributors": [ - "xgqfrms", - "wwj402", - "RainSlide", - "victor0801x", - "yenshen", - "Ende93", - "webery", - "ziyunfei", - "teoli" - ] - }, - "Web/JavaScript/Reference/Statements/Empty": { - "modified": "2020-10-15T21:32:25.866Z", - "contributors": [ - "zhangchen", - "Hugh", - "git123hub", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Statements/async_function": { - "modified": "2020-11-26T06:15:48.712Z", - "contributors": [ - "superchow", - "Neo42", - "zhangxingeng", - "Irisa", - "brizer", - "icethawless", - "rockan007", - "AppleTenlp", - "gqbre", - "elkfn", - "Hew007", - "Ende93", - "YKG", - "42", - "murphywuwu", - "ntnyq", - "jaredhan418", - "TriStone", - "lmislm", - "toyflivver", - "dudueasy", - "NiroDu", - "awmleer", - "mysmlz", - "Bill0412", - "Jessy.D.", - "zxsunrise", - "pujiaxun", - "biggersun", - "Jiang-Xuan", - "pot-code", - "ofatbird", - "shhider", - "zhangchen", - "xgqfrms-GitHub", - "_da", - "Katherina-Miao" - ] - }, - "Web/JavaScript/Reference/Statements/block": { - "modified": "2020-11-26T06:25:49.649Z", - "contributors": [ - "cikelichu", - "daxiazilong", - "ywjco", - "zhangchen", - "icepro", - "Canaan", - "frankfang1990", - "Cattla", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Statements/break": { - "modified": "2020-11-26T22:14:31.749Z", - "contributors": [ - "superchow", - "zhangchen", - "git123hub", - "Poisonloc", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Statements/class": { - "modified": "2020-10-15T21:40:52.749Z", - "contributors": [ - "zhangchen", - "LiXin", - "xgqfrms-GitHub", - "AimLuo", - "makebanana", - "ryanlid", - "kdex", - "lixuguang", - "ouonet", - "MrLyp", - "jooyoon", - "webery" - ] - }, - "Web/JavaScript/Reference/Statements/const": { - "modified": "2020-11-20T09:29:05.867Z", - "contributors": [ - "zhuangyin", - "Snailight", - "niices", - "RainSlide", - "Jat", - "zhangchen", - "winjeysong", - "myl0204", - "xgqfrms-GitHub", - "shifengchen", - "Go7hic", - "zhe13", - "webery", - "lunix01", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Statements/continue": { - "modified": "2020-10-15T21:22:29.579Z", - "contributors": [ - "zhangchen", - "tiansh", - "teoli", - "sunorry" - ] - }, - "Web/JavaScript/Reference/Statements/debugger": { - "modified": "2020-10-15T21:19:13.851Z", - "contributors": [ - "zhangchen", - "yenshen", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Statements/default": { - "modified": "2020-10-15T21:40:53.796Z", - "contributors": [ - "hellokidder", - "zhangchen", - "binguanghe", - "Lukas-LiuYi", - "fscholz" - ] - }, - "Web/JavaScript/Reference/Statements/do...while": { - "modified": "2020-10-15T21:32:25.936Z", - "contributors": [ - "zhangchen", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Statements/export": { - "modified": "2020-10-31T21:18:02.310Z", - "contributors": [ - "wenxiayili", - "panzhh", - "brizer", - "Casseil-1996", - "zhouxyy", - "symant233", - "Asuka109", - "hanalice", - "narutojian", - "ThisIszas", - "GentleGong", - "woniuxingdong", - "TeabugCC", - "yinpeng123", - "RainSlide", - "xgqfrms", - "wossig", - "zarvin", - "TimmyKingFree", - "zhangchen", - "xgqfrms-GitHub", - "Jiang-Xuan", - "Suixinlei", - "nolanlee", - "sartrey", - "jianyi1995" - ] - }, - "Web/JavaScript/Reference/Statements/for": { - "modified": "2020-10-15T21:38:44.431Z", - "contributors": [ - "RainSlide", - "yy7054wyq5", - "zhangchen", - "IShinji", - "yenshen", - "oscar1980", - "gaigeshen" - ] - }, - "Web/JavaScript/Reference/Statements/for-await...of": { - "modified": "2020-11-19T13:54:59.528Z", - "contributors": [ - "xgqfrms", - "jingkaimori", - "AozakiOrenji", - "Ende93", - "SphinxKnight", - "mrdulin", - "WangXiaoyu", - "thereAnana" - ] - }, - "Web/JavaScript/Reference/Statements/for...in": { - "modified": "2020-10-15T21:07:57.911Z", - "contributors": [ - "lmislm", - "毛毛_", - "name-dingding", - "raoenhui", - "412799755", - "Hourann", - "XiangHongAi", - "jiladahe1997", - "zhangchen", - "WPH2017", - "xgqfrms-GitHub", - "jdk137", - "yatace", - "helloguangxue", - "Ende93", - "wonyun", - "denghongcai", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Statements/for...of": { - "modified": "2020-10-15T21:07:54.800Z", - "contributors": [ - "sendudu", - "mouming", - "houzp", - "zgj233", - "osramywj", - "Joker09", - "Jiang-Xuan", - "charliex2", - "zhangchen", - "killsos", - "xgqfrms-GitHub", - "zhuangyin", - "yihuan", - "yanlee26", - "dingxu", - "lsvih", - "imnodb", - "Ende93", - "iamchenxin", - "teoli", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Statements/function": { - "modified": "2020-12-02T02:36:07.313Z", - "contributors": [ - "zhuangyin", - "frankfang1990", - "maicss", - "xgqfrms-GitHub", - "helloguangxue", - "yenshen", - "teoli", - "ielgnaw" - ] - }, - "Web/JavaScript/Reference/Statements/function*": { - "modified": "2020-10-15T21:27:24.673Z", - "contributors": [ - "HCSkatana", - "kingsley2036", - "RoXoM", - "Jiang-Xuan", - "ywjco", - "picc-lu", - "pot-code", - "righttoe", - "kdex", - "xgqfrms-GitHub", - "ShupingLiu", - "lunix01", - "simongfxu", - "ziyunfei", - "fskuok", - "teoli" - ] - }, - "Web/JavaScript/Reference/Statements/if...else": { - "modified": "2020-10-15T21:32:24.204Z", - "contributors": [ - "maoyumaoxun", - "zhangchen", - "jjc", - "TimmyKingFree", - "Hugh", - "connie77", - "yenshen" - ] - }, - "Web/JavaScript/Reference/Statements/import": { - "modified": "2020-10-15T21:36:46.597Z", - "contributors": [ - "SunnyDayLily", - "laampui", - "brizer", - "TeabugCC", - "RainSlide", - "daihaoxin", - "jason-grimm", - "jjyyxx", - "Ende93", - "zhangchen", - "xgqfrms-GitHub", - "xiaomingming", - "Jiang-Xuan", - "houbx", - "taokd", - "Skyang", - "larntin", - "bambooom", - "ziyunfei", - "wengeezhang", - "sartrey", - "WangZishi" - ] - }, - "Web/JavaScript/Reference/Statements/import.meta": { - "modified": "2020-10-15T22:07:59.455Z", - "contributors": [ - "gitHber", - "JonathanLee-LX" - ] - }, - "Web/JavaScript/Reference/Statements/label": { - "modified": "2020-10-15T21:31:44.464Z", - "contributors": [ - "xgqfrms", - "RainSlide", - "zhangchen", - "delkaka", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Statements/let": { - "modified": "2020-10-15T21:07:01.000Z", - "contributors": [ - "Snailight", - "卡尔维斯特", - "JameMoriarty", - "yangnaiyue", - "Zhang-Junzhi", - "wongxiao", - "Ende93", - "jzz2649", - "SphinxKnight", - "Lan1967", - "Freezer", - "alexzaolin", - "JunjieCai", - "ilyp", - "ssttii", - "jcguang", - "mathxlee", - "ywjco", - "zhangchen", - "yingying", - "frankfang1990", - "swfbarhr", - "xgqfrms-GitHub", - "mr.code", - "artificial", - "leafdog", - "yangzongjie", - "ZhiRui", - "ZhanghaoH", - "ChuckZhang", - "Go7hic", - "highsea", - "panhezeng", - "kemchenj", - "lunix01", - "dondevi", - "hang", - "Rococolate", - "ouonet", - "ziyunfei", - "WangZishi", - "Junjie_Wei", - "teoli", - "nightire", - "ted423" - ] - }, - "Web/JavaScript/Reference/Statements/return": { - "modified": "2020-10-15T21:32:16.829Z", - "contributors": [ - "xianshenglu", - "zhangchen", - "Ende93", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Statements/switch": { - "modified": "2020-10-15T21:31:42.513Z", - "contributors": [ - "rianma", - "jfw10973", - "RainSlide", - "ywjco", - "zhangchen", - "PaperFlu", - "FAOfao931013", - "xgqfrms-GitHub", - "AlexChao", - "xin" - ] - }, - "Web/JavaScript/Reference/Statements/throw": { - "modified": "2020-10-15T21:17:26.144Z", - "contributors": [ - "koalaxiaot", - "zhangchen", - "xgqfrms-GitHub", - "fanpaa", - "soulxy", - "onetwogoo", - "iFish", - "teoli", - "Mickeyboy" - ] - }, - "Web/JavaScript/Reference/Statements/try...catch": { - "modified": "2020-10-15T21:35:35.752Z", - "contributors": [ - "zhangchen", - "Lan1967", - "cddsgtc", - "Xheldon", - "gooqiao", - "llwanghong", - "YouHeng", - "xgqfrms-GitHub", - "Hugh", - "helloguangxue", - "TUKOMI", - "ziyunfei", - "licop" - ] - }, - "Web/JavaScript/Reference/Statements/var": { - "modified": "2020-10-15T21:29:22.023Z", - "contributors": [ - "FloydTsai", - "RainSlide", - "zhangchen", - "AymaxLi", - "xgqfrms-GitHub", - "The-End-Hero", - "loddit", - "lunix01", - "AlexChao", - "SphinxKnight", - "Fify" - ] - }, - "Web/JavaScript/Reference/Statements/while": { - "modified": "2020-10-15T21:31:43.063Z", - "contributors": [ - "RainSlide", - "zhangchen", - "ziyunfei", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Statements/with": { - "modified": "2020-10-15T21:29:35.662Z", - "contributors": [ - "SadWood", - "yangtoude", - "zhangchen", - "abc45628", - "xgqfrms-GitHub", - "kiling", - "wizardforcel", - "YFM-getA", - "jonkee", - "SphinxKnight", - "front" - ] - }, - "Web/JavaScript/Reference/Strict_mode": { - "modified": "2020-03-12T19:35:37.779Z", - "contributors": [ - "xrkffgg", - "gaoyia", - "qiufeihong2018", - "Opelar", - "hmsz", - "amandameng", - "zhangchen", - "recursion", - "JuFoFu", - "qiu_han", - "tsejx", - "righttoe", - "xgqfrms-GitHub", - "holynewbie", - "nanflower", - "weimengxi", - "xuzicn", - "Qcui", - "Toweave", - "zilong-thu", - "anitawho", - "laoxubuer", - "knightf", - "Jack.Works", - "Dijason", - "ziyunfei", - "yaway", - "iahu", - "mountainmoon", - "Frantic1048", - "Darrel.Hsu", - "ReyCG", - "teoli", - "endlesswind" - ] - }, - "Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode": { - "modified": "2020-03-12T19:38:14.564Z", - "contributors": [ - "vincentdd", - "weimengxi", - "gavinjs", - "zjjott", - "ziyunfei", - "yenshen", - "teoli" - ] - }, - "Web/JavaScript/Reference/Trailing_commas": { - "modified": "2020-10-15T21:52:12.920Z", - "contributors": [ - "RainSlide", - "zhangchen", - "wizardforcel" - ] - }, - "Web/JavaScript/Reference/template_strings": { - "modified": "2020-10-15T21:37:03.468Z", - "contributors": [ - "SphinxKnight", - "fanky-huang", - "崮生", - "zhangchen", - "zouyang1230", - "aimishan", - "pujiaxun", - "ZQH", - "LNY", - "ywjco", - "winjeysong", - "xgqfrms-GitHub", - "lihx_hit", - "donyaw", - "Ende93", - "lukywong", - "FredWe" - ] - }, - "Web/JavaScript/Shells": { - "modified": "2020-09-04T03:12:55.502Z", - "contributors": [ - "a1157116165", - "StorytellerF", - "pluwen", - "sonymoon", - "pelligit", - "maicss" - ] - }, - "Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation": { - "modified": "2020-03-12T19:49:00.824Z", - "contributors": [ - "Rominez", - "suhan" - ] - }, - "Web/JavaScript/Typed_arrays": { - "modified": "2020-10-15T21:26:17.964Z", - "contributors": [ - "norton-lee", - "ThomasWhyne", - "nkliyc", - "AngeloZ", - "zhangchen", - "wblovezqy", - "jing-y", - "lvsiyuan", - "xgqfrms-GitHub", - "JoyZF", - "jianzhou", - "lon", - "ngtmuzi", - "Amme", - "troywith77", - "ipy", - "teoli", - "zekai.zheng" - ] - }, - "Web/JavaScript/javascript(起步)": { - "modified": "2019-03-23T22:54:49.824Z", - "contributors": [ - "Rupengkun" - ] - }, - "Web/Localization": { - "modified": "2020-05-28T07:36:01.726Z", - "contributors": [ - "RoyZ", - "faliye" - ] - }, - "Web/Manifest": { - "modified": "2019-10-29T05:08:14.882Z", - "contributors": [ - "7NZ", - "mySoul", - "flyingsouthwind", - "varcat", - "_da", - "xgqfrms-GitHub" - ] - }, - "Web/Manifest/background_color": { - "modified": "2020-10-15T22:31:53.672Z", - "contributors": [ - "wobuhuisuanmin", - "wr20060926" - ] - }, - "Web/MathML": { - "modified": "2020-10-15T21:25:04.339Z", - "contributors": [ - "RainSlide", - "Anonymous86x69ashe", - "pluwen", - "linmx0130", - "lunix01", - "fred.wang", - "fscholz" - ] - }, - "Web/MathML/Attribute": { - "modified": "2019-03-23T22:52:18.616Z", - "contributors": [ - "luneice", - "FredWe" - ] - }, - "Web/MathML/Authoring": { - "modified": "2019-10-27T00:08:11.337Z", - "contributors": [ - "RainSlide", - "fanxiaojie", - "FredWe" - ] - }, - "Web/MathML/Element": { - "modified": "2020-03-31T12:28:08.721Z", - "contributors": [ - "RainSlide", - "qson", - "ziyunfei", - "a.stone" - ] - }, - "Web/MathML/Element/maction": { - "modified": "2019-03-18T21:42:16.631Z", - "contributors": [ - "LiuYuan" - ] - }, - "Web/MathML/Element/math": { - "modified": "2019-03-23T22:48:38.735Z", - "contributors": [ - "linmx0130" - ] - }, - "Web/MathML/Element/mroot": { - "modified": "2019-03-18T21:42:14.503Z", - "contributors": [ - "LiuYuan" - ] - }, - "Web/MathML/Element/mrow": { - "modified": "2020-10-15T22:25:33.815Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/MathML/Element/mspace": { - "modified": "2019-03-18T21:42:15.461Z", - "contributors": [ - "LiuYuan" - ] - }, - "Web/MathML/Element/msqrt": { - "modified": "2019-03-18T21:42:14.783Z", - "contributors": [ - "LiuYuan" - ] - }, - "Web/MathML/Element/msub": { - "modified": "2019-03-18T21:42:15.091Z", - "contributors": [ - "LiuYuan" - ] - }, - "Web/MathML/Element/msubsup": { - "modified": "2020-10-15T22:28:42.346Z", - "contributors": [ - "RainSlide" - ] - }, - "Web/MathML/Element/msup": { - "modified": "2020-10-15T22:01:09.939Z", - "contributors": [ - "RainSlide", - "LiuYuan" - ] - }, - "Web/MathML/Examples": { - "modified": "2019-10-26T23:25:14.524Z", - "contributors": [ - "RainSlide", - "Anonymous86x69ashe", - "Seattle", - "abc3660170", - "FredWe" - ] - }, - "Web/MathML/Examples/Deriving_the_Quadratic_Formula": { - "modified": "2019-10-27T00:00:27.008Z", - "contributors": [ - "RainSlide", - "luneice" - ] - }, - "Web/MathML/Examples/MathML_Pythagorean_Theorem": { - "modified": "2019-10-26T23:28:44.470Z", - "contributors": [ - "RainSlide", - "Anonymous86x69ashe", - "Seattle" - ] - }, - "Web/Media/Formats": { - "modified": "2019-10-28T06:26:59.997Z", - "contributors": [ - "jswisher" - ] - }, - "Web/Media/Formats/Containers": { - "modified": "2020-11-01T10:00:22.590Z", - "contributors": [ - "happyxxj" - ] - }, - "Web/Media/Formats/Image_types": { - "modified": "2020-10-28T06:58:07.754Z", - "contributors": [ - "hylashyla", - "RainSlide" - ] - }, - "Web/Media/Formats/视频编解码器": { - "modified": "2019-10-29T00:53:07.418Z", - "contributors": [ - "zxhaha" - ] - }, - "Web/Performance": { - "modified": "2020-07-21T05:10:44.104Z", - "contributors": [ - "lvbaiying", - "FE_pangxing", - "biqing", - "RainSlide", - "maoyougan", - "sqd123", - "chrisdavidmills", - "iceytea" - ] - }, - "Web/Performance/CSS_JavaScript_animation_performance": { - "modified": "2020-07-29T00:36:34.087Z", - "contributors": [ - "deping_chen", - "sunfeel", - "liangbus" - ] - }, - "Web/Performance/Critical_rendering_path": { - "modified": "2020-10-13T09:41:03.369Z", - "contributors": [ - "xgqfrms", - "HouGiser", - "HuiyingShen96", - "chafel" - ] - }, - "Web/Performance/Lazy_loading": { - "modified": "2020-10-13T09:10:51.078Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/Performance/Optimizing_startup_performance": { - "modified": "2019-03-23T22:00:17.334Z", - "contributors": [ - "chrisdavidmills", - "codeofjackie" - ] - }, - "Web/Performance/Rum-vs-Synthetic": { - "modified": "2020-10-13T09:51:23.567Z", - "contributors": [ - "xgqfrms" - ] - }, - "Web/Performance/dns-prefetch": { - "modified": "2020-10-13T10:51:56.349Z", - "contributors": [ - "xgqfrms", - "chrisdavidmills", - "caoweiju" - ] - }, - "Web/Performance/浏览器渲染页面的工作原理": { - "modified": "2020-04-02T13:24:16.615Z", - "contributors": [ - "Galaxy" - ] - }, - "Web/Progressive_web_apps": { - "modified": "2020-03-14T09:56:33.733Z", - "contributors": [ - "Miahui", - "kkocdko", - "chrisdavidmills", - "sijimi", - "xgqfrms-GitHub", - "xgqfrms" - ] - }, - "Web/Progressive_web_apps/App_structure": { - "modified": "2020-05-31T18:38:01.454Z", - "contributors": [ - "jin_wang", - "Miahui", - "xiao11lang", - "Mosan", - "githubxiaominge", - "liminjun", - "zjffun", - "alfred_chao95", - "chrisdavidmills", - "eightHundreds" - ] - }, - "Web/Progressive_web_apps/Installable_PWAs": { - "modified": "2020-08-03T23:25:28.976Z", - "contributors": [ - "SDUTWSL", - "nurob", - "Dht", - "Miahui", - "HDUCC", - "deping_chen" - ] - }, - "Web/Progressive_web_apps/Introduction": { - "modified": "2019-08-21T09:58:46.102Z", - "contributors": [ - "jackupdown", - "zjffun", - "chrisdavidmills", - "eightHundreds", - "yijie_sun" - ] - }, - "Web/Progressive_web_apps/Network_independent": { - "modified": "2019-03-18T20:52:05.037Z", - "contributors": [ - "chrisdavidmills", - "liminjun", - "xgqfrms-GitHub" - ] - }, - "Web/Progressive_web_apps/Offline_Service_workers": { - "modified": "2020-07-02T16:41:37.440Z", - "contributors": [ - "showad", - "nurob", - "githubxiaominge", - "zjffun" - ] - }, - "Web/Progressive_web_apps/Re-engageable": { - "modified": "2019-03-18T20:52:04.596Z", - "contributors": [ - "chrisdavidmills", - "liminjun" - ] - }, - "Web/Progressive_web_apps/Re-engageable_Notifications_Push": { - "modified": "2020-05-31T18:38:17.693Z", - "contributors": [ - "nurob", - "githubxiaominge" - ] - }, - "Web/Progressive_web_apps/Responsive": { - "modified": "2019-03-18T20:52:04.806Z", - "contributors": [ - "chrisdavidmills", - "liminjun" - ] - }, - "Web/Progressive_web_apps/Responsive/responsive_design_building_blocks": { - "modified": "2020-11-17T04:04:41.165Z", - "contributors": [ - "DingGuangbo" - ] - }, - "Web/Progressive_web_apps/优势": { - "modified": "2019-04-18T12:23:20.526Z", - "contributors": [ - "chenronghui" - ] - }, - "Web/Progressive_web_apps/加载": { - "modified": "2019-08-31T10:29:37.985Z", - "contributors": [ - "githubxiaominge" - ] - }, - "Web/Progressive_web_apps/添加到主屏幕": { - "modified": "2019-11-13T02:27:54.714Z", - "contributors": [ - "JC-Ge" - ] - }, - "Web/Reference": { - "modified": "2019-03-18T21:10:51.690Z", - "contributors": [ - "SphinxKnight", - "acuptea", - "rguanghui", - "huasheng", - "yangchengjian", - "liuwentianwtu", - "jack7758", - "ValkyrieLawliet", - "ZhangKaiqiang", - "colin-zhou", - "ziyunfei", - "Sheppy" - ] - }, - "Web/Reference/API": { - "modified": "2020-02-06T00:29:14.463Z", - "contributors": [ - "RainSlide", - "yongxiaodu", - "micblo", - "kevinfszu", - "yfdyh000", - "zmh_w", - "tangxiaobaobao", - "ziyunfei", - "noscripter", - "hutuxu" - ] - }, - "Web/SVG": { - "modified": "2020-05-25T07:08:22.112Z", - "contributors": [ - "Adrian-Yan", - "RainSlide", - "pluwen", - "LalaChu", - "simongfxu", - "fanxiaojie", - "Metalooze", - "lunix01", - "charlie", - "johncido", - "cuixiping", - "huguowei", - "teoli", - "xcffl", - "LIXer" - ] - }, - "Web/SVG/Applying_SVG_effects_to_HTML_content": { - "modified": "2020-10-21T05:14:10.197Z", - "contributors": [ - "Chellyyy", - "Kylexii", - "almond", - "AaronYehf", - "swingcat", - "SphinxKnight", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute": { - "modified": "2020-06-11T11:15:23.661Z", - "contributors": [ - "chanvin", - "RainSlide", - "fanxiaojie", - "slientomorrr", - "stevenvachon" - ] - }, - "Web/SVG/Attribute/From": { - "modified": "2019-03-23T22:07:46.163Z", - "contributors": [ - "876843240" - ] - }, - "Web/SVG/Attribute/Presentation": { - "modified": "2020-10-15T22:23:08.667Z", - "contributors": [ - "gogoend" - ] - }, - "Web/SVG/Attribute/accent-height": { - "modified": "2019-07-05T08:35:14.107Z", - "contributors": [ - "yvonneit" - ] - }, - "Web/SVG/Attribute/accumulate": { - "modified": "2019-03-23T22:32:55.125Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/alignment-baseline": { - "modified": "2019-07-05T08:35:05.656Z", - "contributors": [ - "liyongleihf2006", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/attributeName": { - "modified": "2019-03-23T22:46:42.034Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/attributeType": { - "modified": "2019-03-23T22:46:39.534Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/baseProfile": { - "modified": "2019-07-05T08:35:43.566Z", - "contributors": [ - "leighcc" - ] - }, - "Web/SVG/Attribute/baseline-shift": { - "modified": "2019-03-23T22:46:48.235Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/begin": { - "modified": "2019-03-23T22:46:49.938Z", - "contributors": [ - "wbamberg", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/calcMode": { - "modified": "2019-03-23T22:10:34.986Z", - "contributors": [ - "leedut" - ] - }, - "Web/SVG/Attribute/clip": { - "modified": "2020-10-15T21:39:26.851Z", - "contributors": [ - "RainSlide", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/clip-path": { - "modified": "2020-10-15T22:28:50.040Z", - "contributors": [ - "jhchen6" - ] - }, - "Web/SVG/Attribute/color": { - "modified": "2020-10-15T21:39:18.231Z", - "contributors": [ - "RainSlide", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/cx": { - "modified": "2019-03-23T22:18:03.024Z", - "contributors": [ - "realstephenzhao", - "huainanhai" - ] - }, - "Web/SVG/Attribute/cy": { - "modified": "2019-03-18T21:22:46.371Z", - "contributors": [ - "realstephenzhao" - ] - }, - "Web/SVG/Attribute/d": { - "modified": "2019-03-23T22:55:44.323Z", - "contributors": [ - "msyfls123", - "fanxiaojie", - "creamidea", - "charlie" - ] - }, - "Web/SVG/Attribute/display": { - "modified": "2020-11-17T10:08:32.937Z", - "contributors": [ - "292514467", - "misakisaysyes", - "radial-hks" - ] - }, - "Web/SVG/Attribute/dominant-baseline": { - "modified": "2019-03-23T22:09:53.226Z", - "contributors": [ - "xinjianheyi" - ] - }, - "Web/SVG/Attribute/dur": { - "modified": "2019-03-23T22:46:40.065Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/dx": { - "modified": "2020-08-25T05:37:26.030Z", - "contributors": [ - "danceash", - "jiahui" - ] - }, - "Web/SVG/Attribute/edgeMode": { - "modified": "2019-03-23T22:46:21.766Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/enable-background": { - "modified": "2020-10-15T22:34:25.447Z", - "contributors": [ - "SphinxKnight", - "SoMuchTo" - ] - }, - "Web/SVG/Attribute/end": { - "modified": "2019-03-23T22:46:42.288Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/fill": { - "modified": "2019-03-23T22:46:42.182Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/fill-opacity": { - "modified": "2019-03-23T22:46:42.402Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/fill-rule": { - "modified": "2020-10-15T21:39:20.776Z", - "contributors": [ - "skywalker_z", - "kapokkopak", - "Ambar", - "ZhengYinBo", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/filter": { - "modified": "2019-03-23T22:46:38.982Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/filterUnits": { - "modified": "2019-03-23T22:14:03.688Z", - "contributors": [ - "liyongleihf2006" - ] - }, - "Web/SVG/Attribute/font-family": { - "modified": "2019-03-23T23:04:59.299Z", - "contributors": [ - "charlie" - ] - }, - "Web/SVG/Attribute/fr": { - "modified": "2019-03-18T21:22:49.932Z", - "contributors": [ - "realstephenzhao" - ] - }, - "Web/SVG/Attribute/fx": { - "modified": "2019-03-18T21:28:55.964Z", - "contributors": [ - "realstephenzhao", - "longfeihouhouhou" - ] - }, - "Web/SVG/Attribute/fy": { - "modified": "2019-03-18T21:22:47.918Z", - "contributors": [ - "realstephenzhao" - ] - }, - "Web/SVG/Attribute/height": { - "modified": "2019-03-23T22:46:48.815Z", - "contributors": [ - "Ende93", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/id": { - "modified": "2020-10-15T22:25:42.877Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/SVG/Attribute/image-rendering": { - "modified": "2019-03-23T23:10:41.035Z", - "contributors": [ - "ReyCG_sub" - ] - }, - "Web/SVG/Attribute/in": { - "modified": "2019-03-23T22:13:50.542Z", - "contributors": [ - "liyongleihf2006" - ] - }, - "Web/SVG/Attribute/kernelMatrix": { - "modified": "2019-03-23T22:14:02.784Z", - "contributors": [ - "liyongleihf2006" - ] - }, - "Web/SVG/Attribute/keyTimes": { - "modified": "2019-03-18T21:30:15.598Z", - "contributors": [ - "ZhenhuaChen" - ] - }, - "Web/SVG/Attribute/letter-spacing": { - "modified": "2020-10-15T22:23:39.628Z", - "contributors": [ - "vvv-7911" - ] - }, - "Web/SVG/Attribute/marker-end": { - "modified": "2020-10-15T22:18:07.958Z", - "contributors": [ - "ciki6" - ] - }, - "Web/SVG/Attribute/marker-start": { - "modified": "2020-10-15T22:35:06.368Z", - "contributors": [ - "ciki6" - ] - }, - "Web/SVG/Attribute/mask": { - "modified": "2019-03-23T22:46:32.037Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/max": { - "modified": "2020-10-15T22:26:09.162Z", - "contributors": [ - "bompoo" - ] - }, - "Web/SVG/Attribute/media": { - "modified": "2020-10-15T22:28:22.473Z", - "contributors": [ - "Firefox_mozilla" - ] - }, - "Web/SVG/Attribute/opacity": { - "modified": "2019-03-23T22:46:17.591Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/order": { - "modified": "2019-03-23T22:14:09.913Z", - "contributors": [ - "liyongleihf2006" - ] - }, - "Web/SVG/Attribute/origin": { - "modified": "2020-09-21T09:25:39.365Z", - "contributors": [ - "SphinxKnight", - "a420980938" - ] - }, - "Web/SVG/Attribute/overflow": { - "modified": "2020-10-15T22:09:03.459Z", - "contributors": [ - "SphinxKnight", - "888aaa" - ] - }, - "Web/SVG/Attribute/path": { - "modified": "2019-01-17T01:11:59.482Z", - "contributors": [ - "dfEric" - ] - }, - "Web/SVG/Attribute/pathLength": { - "modified": "2019-03-18T21:24:01.815Z", - "contributors": [ - "EXSVAMP" - ] - }, - "Web/SVG/Attribute/patternUnits": { - "modified": "2019-03-18T21:15:24.501Z", - "contributors": [ - "Chesn" - ] - }, - "Web/SVG/Attribute/pointer-events": { - "modified": "2020-10-15T22:18:55.261Z", - "contributors": [ - "WebsonLeo" - ] - }, - "Web/SVG/Attribute/points": { - "modified": "2019-03-23T22:46:24.044Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/preserveAlpha": { - "modified": "2019-03-18T21:30:40.693Z", - "contributors": [ - "hy512" - ] - }, - "Web/SVG/Attribute/preserveAspectRatio": { - "modified": "2019-03-23T22:02:41.003Z", - "contributors": [ - "codepandy", - "ciki6", - "yuyx91", - "webtuotuo2017" - ] - }, - "Web/SVG/Attribute/primitiveUnits": { - "modified": "2019-03-23T22:14:03.826Z", - "contributors": [ - "liyongleihf2006" - ] - }, - "Web/SVG/Attribute/r": { - "modified": "2019-03-18T21:22:40.271Z", - "contributors": [ - "realstephenzhao" - ] - }, - "Web/SVG/Attribute/radius": { - "modified": "2019-03-23T22:46:18.311Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/repeatCount": { - "modified": "2019-03-23T22:18:01.687Z", - "contributors": [ - "876843240", - "huainanhai" - ] - }, - "Web/SVG/Attribute/result": { - "modified": "2019-01-16T21:31:09.328Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/rx": { - "modified": "2019-03-18T21:00:24.171Z", - "contributors": [ - "RainSlide", - "BowenSun" - ] - }, - "Web/SVG/Attribute/scale": { - "modified": "2019-03-23T22:46:29.331Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/seed": { - "modified": "2019-03-23T22:46:25.651Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/shape-rendering": { - "modified": "2019-03-23T22:41:44.530Z", - "contributors": [ - "maicss" - ] - }, - "Web/SVG/Attribute/stdDeviation": { - "modified": "2019-03-18T21:23:00.621Z", - "contributors": [ - "realstephenzhao" - ] - }, - "Web/SVG/Attribute/string": { - "modified": "2020-10-15T22:28:09.817Z", - "contributors": [ - "Tjhxzd" - ] - }, - "Web/SVG/Attribute/stroke": { - "modified": "2019-03-23T22:47:39.759Z", - "contributors": [ - "fanxiaojie", - "slientomorrr" - ] - }, - "Web/SVG/Attribute/stroke-dasharray": { - "modified": "2019-08-08T05:38:03.197Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/stroke-dashoffset": { - "modified": "2019-10-10T16:56:45.450Z", - "contributors": [ - "ZhengYinBo", - "yanagao" - ] - }, - "Web/SVG/Attribute/stroke-linecap": { - "modified": "2019-03-23T22:21:59.850Z", - "contributors": [ - "ZhengYinBo" - ] - }, - "Web/SVG/Attribute/stroke-linejoin": { - "modified": "2020-10-15T21:52:22.702Z", - "contributors": [ - "cuixiping", - "IridescentMia" - ] - }, - "Web/SVG/Attribute/stroke-miterlimit": { - "modified": "2019-03-23T22:46:40.182Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/stroke-opacity": { - "modified": "2019-03-23T22:46:37.761Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/stroke-width": { - "modified": "2019-03-23T22:46:41.922Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/style": { - "modified": "2019-10-09T03:46:30.272Z", - "contributors": [ - "xianshenglu", - "xgqfrms-GitHub", - "monjer" - ] - }, - "Web/SVG/Attribute/target": { - "modified": "2020-10-15T22:27:15.767Z", - "contributors": [ - "fzhyzamt", - "boli14" - ] - }, - "Web/SVG/Attribute/text-decoration": { - "modified": "2020-09-26T20:27:21.690Z", - "contributors": [ - "xuhaooo", - "qingpingy" - ] - }, - "Web/SVG/Attribute/transform": { - "modified": "2019-10-17T10:24:00.177Z", - "contributors": [ - "qq240814476" - ] - }, - "Web/SVG/Attribute/type": { - "modified": "2019-09-27T11:12:53.094Z", - "contributors": [ - "Huang2019023239" - ] - }, - "Web/SVG/Attribute/units-per-em": { - "modified": "2020-10-15T22:25:05.021Z", - "contributors": [ - "pandahara" - ] - }, - "Web/SVG/Attribute/values": { - "modified": "2020-08-19T04:16:48.441Z", - "contributors": [ - "keyline-1" - ] - }, - "Web/SVG/Attribute/vector-effect": { - "modified": "2020-10-15T22:25:39.831Z", - "contributors": [ - "cuixiping" - ] - }, - "Web/SVG/Attribute/version": { - "modified": "2019-08-03T10:57:47.255Z", - "contributors": [ - "monkeycf", - "LiKunWillShine" - ] - }, - "Web/SVG/Attribute/viewBox": { - "modified": "2019-08-01T23:50:11.252Z", - "contributors": [ - "lovefengruoqing", - "act262" - ] - }, - "Web/SVG/Attribute/visibility": { - "modified": "2019-03-23T22:46:34.860Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/width": { - "modified": "2019-03-23T22:46:51.950Z", - "contributors": [ - "Ende93", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/x": { - "modified": "2019-03-23T22:46:48.086Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/y": { - "modified": "2019-03-23T22:46:47.078Z", - "contributors": [ - "jiereal", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/文本锚点": { - "modified": "2019-03-23T22:22:02.773Z", - "contributors": [ - "AozakiOrenji", - "yashuer" - ] - }, - "Web/SVG/Attribute/样式": { - "modified": "2020-10-15T22:10:48.584Z", - "contributors": [ - "liu3329" - ] - }, - "Web/SVG/Content_type": { - "modified": "2019-03-23T22:46:41.769Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Element": { - "modified": "2020-03-13T06:26:33.332Z", - "contributors": [ - "Dorence", - "RainSlide", - "fanxiaojie", - "lunix01", - "cungen", - "teoli", - "ethertank" - ] - }, - "Web/SVG/Element/a": { - "modified": "2019-06-15T03:14:27.907Z", - "contributors": [ - "lnh", - "sqchenxiyuan", - "Sebastianz", - "fanxiaojie", - "teoli", - "techird" - ] - }, - "Web/SVG/Element/altGlyph": { - "modified": "2019-06-15T03:14:19.322Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/altGlyphDef": { - "modified": "2019-03-23T22:46:38.701Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/altGlyphItem": { - "modified": "2019-03-23T22:46:33.665Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/animate": { - "modified": "2020-05-04T23:05:51.292Z", - "contributors": [ - "knightyun", - "oujielong", - "Ende93", - "luojia", - "Sebastianz", - "fanxiaojie", - "329530588", - "lunix01" - ] - }, - "Web/SVG/Element/animateColor": { - "modified": "2019-03-23T22:46:35.027Z", - "contributors": [ - "xgqfrms-GitHub", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/animateMotion": { - "modified": "2020-10-15T21:39:29.124Z", - "contributors": [ - "knightyun", - "wbamberg", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/animateTransform": { - "modified": "2019-03-23T22:46:37.058Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/circle": { - "modified": "2019-03-23T21:45:42.756Z", - "contributors": [ - "wbamberg", - "xgqfrms-GitHub", - "Sebastianz", - "loofahsf", - "fanxiaojie", - "ziyunfei", - "cungen" - ] - }, - "Web/SVG/Element/clipPath": { - "modified": "2020-10-15T21:32:57.569Z", - "contributors": [ - "jhchen6", - "RainSlide", - "Sebastianz", - "fanxiaojie", - "huyue" - ] - }, - "Web/SVG/Element/color-profile": { - "modified": "2019-03-23T22:46:33.322Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/cursor": { - "modified": "2020-10-15T21:39:22.908Z", - "contributors": [ - "knightyun", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/defs": { - "modified": "2019-03-23T23:05:33.636Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "charlie", - "baiya" - ] - }, - "Web/SVG/Element/desc": { - "modified": "2019-03-23T22:46:43.461Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/ellipse": { - "modified": "2019-03-23T22:54:08.203Z", - "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "FredWe" - ] - }, - "Web/SVG/Element/feBlend": { - "modified": "2019-03-23T22:46:45.814Z", - "contributors": [ - "liyongleihf2006", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feColorMatrix": { - "modified": "2019-03-23T23:25:05.534Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "teoli", - "daniel.tian" - ] - }, - "Web/SVG/Element/feComponentTransfer": { - "modified": "2019-03-23T22:46:30.620Z", - "contributors": [ - "liyongleihf2006", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feComposite": { - "modified": "2019-03-23T22:46:29.887Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feConvolveMatrix": { - "modified": "2019-08-01T01:30:07.081Z", - "contributors": [ - "liyongleihf2006", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feDiffuseLighting": { - "modified": "2019-03-23T22:46:38.862Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feDisplacementMap": { - "modified": "2019-03-23T22:46:34.138Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feDistantLight": { - "modified": "2019-03-23T22:46:37.517Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feFlood": { - "modified": "2019-03-23T22:46:31.627Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feFuncA": { - "modified": "2020-10-15T21:39:23.537Z", - "contributors": [ - "RainSlide", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feFuncB": { - "modified": "2019-03-23T22:46:38.185Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feFuncG": { - "modified": "2019-03-23T22:46:32.939Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feFuncR": { - "modified": "2019-03-23T22:46:31.912Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feGaussianBlur": { - "modified": "2019-03-23T22:46:35.725Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feImage": { - "modified": "2019-03-23T22:46:35.585Z", - "contributors": [ - "AaronYehf", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feMerge": { - "modified": "2019-03-23T22:46:36.019Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feMergeNode": { - "modified": "2019-03-23T22:46:29.748Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feMorphology": { - "modified": "2019-03-23T22:51:21.184Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "foolof41" - ] - }, - "Web/SVG/Element/feOffset": { - "modified": "2019-03-23T22:46:37.362Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/fePointLight": { - "modified": "2019-03-23T22:46:33.171Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feSpecularLighting": { - "modified": "2019-03-23T22:46:21.088Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feSpotLight": { - "modified": "2019-03-23T22:46:30.010Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feTile": { - "modified": "2019-03-23T22:46:20.383Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/feTurbulence": { - "modified": "2019-03-23T22:46:22.298Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/filter": { - "modified": "2020-07-14T05:46:35.376Z", - "contributors": [ - "Yang_Gia", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/font": { - "modified": "2019-03-23T22:43:54.105Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "charlie" - ] - }, - "Web/SVG/Element/font-face": { - "modified": "2019-03-23T23:04:56.439Z", - "contributors": [ - "Sebastianz", - "charlie" - ] - }, - "Web/SVG/Element/font-face-format": { - "modified": "2019-03-23T22:46:32.676Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/font-face-name": { - "modified": "2019-03-23T22:46:33.056Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/font-face-src": { - "modified": "2019-03-18T20:41:42.540Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/font-face-uri": { - "modified": "2019-03-23T22:46:38.431Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/foreignObject": { - "modified": "2020-10-15T21:39:29.342Z", - "contributors": [ - "hanjc1993", - "cnhekai", - "zhangchen", - "kamilic", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/g": { - "modified": "2019-03-23T22:55:45.907Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "monjer" - ] - }, - "Web/SVG/Element/glyph": { - "modified": "2019-03-23T22:55:52.238Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "charlie" - ] - }, - "Web/SVG/Element/glyphRef": { - "modified": "2019-03-23T22:46:32.815Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/hkern": { - "modified": "2019-03-23T22:46:35.411Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/image": { - "modified": "2019-03-23T23:07:18.007Z", - "contributors": [ - "tjyas", - "Sebastianz", - "fanxiaojie", - "lrz8745", - "cuixiping" - ] - }, - "Web/SVG/Element/line": { - "modified": "2019-07-31T04:23:35.374Z", - "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/linearGradient": { - "modified": "2019-07-01T05:50:18.527Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "ziyunfei", - "xile611" - ] - }, - "Web/SVG/Element/marker": { - "modified": "2019-03-23T23:03:51.340Z", - "contributors": [ - "wbamberg", - "liyongleihf2006", - "Sebastianz", - "fanxiaojie", - "fonglezen" - ] - }, - "Web/SVG/Element/mask": { - "modified": "2019-03-23T23:03:51.605Z", - "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "fonglezen" - ] - }, - "Web/SVG/Element/metadata": { - "modified": "2019-03-23T22:46:43.887Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/missing-glyph": { - "modified": "2019-03-23T23:04:57.001Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "fonglezen", - "charlie" - ] - }, - "Web/SVG/Element/mpath": { - "modified": "2019-03-23T22:46:38.309Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/path": { - "modified": "2019-03-23T23:07:18.417Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "cuixiping" - ] - }, - "Web/SVG/Element/pattern": { - "modified": "2019-03-23T23:03:50.981Z", - "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "fonglezen" - ] - }, - "Web/SVG/Element/polygon": { - "modified": "2019-03-23T23:13:30.746Z", - "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "ziyunfei", - "fly-bird" - ] - }, - "Web/SVG/Element/polyline": { - "modified": "2019-03-23T22:57:44.713Z", - "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "e26h" - ] - }, - "Web/SVG/Element/radialGradient": { - "modified": "2020-10-15T21:39:21.881Z", - "contributors": [ - "realstephenzhao", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/rect": { - "modified": "2019-03-23T22:57:44.926Z", - "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "e26h" - ] - }, - "Web/SVG/Element/script": { - "modified": "2019-03-23T22:46:33.996Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/set": { - "modified": "2019-08-05T06:51:54.590Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "baiya" - ] - }, - "Web/SVG/Element/stop": { - "modified": "2019-03-23T22:46:37.919Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/style": { - "modified": "2019-03-23T22:46:35.874Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/svg": { - "modified": "2019-03-23T23:03:45.347Z", - "contributors": [ - "alphabet007", - "liyongleihf2006", - "Sebastianz", - "fanxiaojie", - "charlie", - "fonglezen" - ] - }, - "Web/SVG/Element/switch": { - "modified": "2019-03-23T23:03:50.332Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "fonglezen" - ] - }, - "Web/SVG/Element/symbol": { - "modified": "2019-03-23T23:05:34.325Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "baiya" - ] - }, - "Web/SVG/Element/text": { - "modified": "2019-03-23T23:05:43.568Z", - "contributors": [ - "Sebastianz", - "jyy12", - "fanxiaojie", - "charlie", - "baiya" - ] - }, - "Web/SVG/Element/textPath": { - "modified": "2019-03-23T23:05:43.375Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "baiya" - ] - }, - "Web/SVG/Element/title": { - "modified": "2019-03-23T22:46:43.066Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/tref": { - "modified": "2019-03-23T23:05:44.122Z", - "contributors": [ - "Sebastianz", - "fanxiaojie", - "baiya" - ] - }, - "Web/SVG/Element/tspan": { - "modified": "2019-03-23T23:29:30.380Z", - "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "teoli", - "flyonok" - ] - }, - "Web/SVG/Element/use": { - "modified": "2019-03-23T22:46:45.349Z", - "contributors": [ - "Sebastianz", - "ObooChin", - "fanxiaojie" - ] - }, - "Web/SVG/Element/view": { - "modified": "2019-06-15T03:14:56.821Z", - "contributors": [ - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Element/vkern": { - "modified": "2020-10-15T21:39:26.145Z", - "contributors": [ - "RainSlide", - "Sebastianz", - "fanxiaojie" - ] - }, - "Web/SVG/Linking": { - "modified": "2019-11-28T05:35:16.253Z", - "contributors": [ - "tangguolong" - ] - }, - "Web/SVG/Namespaces_Crash_Course": { - "modified": "2019-10-11T20:02:55.677Z", - "contributors": [ - "pacexy", - "cyemeng", - "876843240", - "RongMine", - "Ljrou", - "charlie" - ] - }, - "Web/SVG/SVG_1.1_Support_in_Firefox": { - "modified": "2019-03-23T22:52:10.546Z", - "contributors": [ - "Kylexii", - "sunxiang", - "ziyunfei", - "lunix01" - ] - }, - "Web/SVG/SVG_animation_with_SMIL": { - "modified": "2019-03-23T22:46:05.864Z", - "contributors": [ - "WindStormrage", - "fscholz", - "Jackandjohn", - "fanxiaojie" - ] - }, - "Web/SVG/SVG_as_an_Image": { - "modified": "2019-03-23T22:46:05.004Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Tutorial": { - "modified": "2019-08-15T22:27:47.736Z", - "contributors": [ - "AngelName", - "Pehfan", - "simongfxu", - "xgqfrms", - "fanxiaojie", - "charlie", - "teoli", - "ziyunfei", - "Dx.Yang" - ] - }, - "Web/SVG/Tutorial/Basic_Shapes": { - "modified": "2020-05-17T23:40:20.747Z", - "contributors": [ - "nyz123", - "0229xiang", - "851091009", - "VicYu", - "fanxiaojie", - "zldream1106", - "act262" - ] - }, - "Web/SVG/Tutorial/Basic_Transformations": { - "modified": "2019-03-23T22:46:26.560Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Tutorial/Clipping_and_masking": { - "modified": "2020-05-16T12:44:05.454Z", - "contributors": [ - "Yayure", - "hebby", - "chenronghui", - "zhangyifan", - "fanxiaojie" - ] - }, - "Web/SVG/Tutorial/Fills_and_Strokes": { - "modified": "2019-07-02T00:36:20.256Z", - "contributors": [ - "0229xiang", - "ZhengYinBo", - "fanxiaojie", - "act262" - ] - }, - "Web/SVG/Tutorial/Filter_effects": { - "modified": "2020-05-16T13:46:25.008Z", - "contributors": [ - "Yayure", - "knightyun", - "ZeroJsus", - "fanxiaojie" - ] - }, - "Web/SVG/Tutorial/Getting_Started": { - "modified": "2020-02-19T07:42:57.768Z", - "contributors": [ - "Jamie0327", - "qinggge", - "SallyOne", - "maozhenhua2", - "shuihuo", - "SparrowLiu", - "fanxiaojie", - "dolphinX" - ] - }, - "Web/SVG/Tutorial/Gradients": { - "modified": "2019-03-23T22:50:18.555Z", - "contributors": [ - "fanxiaojie", - "ziyunfei", - "zldream1106" - ] - }, - "Web/SVG/Tutorial/Introduction": { - "modified": "2020-06-30T12:46:55.614Z", - "contributors": [ - "antimonyGu", - "Jamie0327", - "daGaiGuanYu", - "XHMM", - "ZeroJsus", - "shuihuo", - "ezirmusitua", - "xgqfrms", - "fanxiaojie", - "charlie", - "teoli", - "ziyunfei", - "Dx.Yang" - ] - }, - "Web/SVG/Tutorial/Other_content_in_SVG": { - "modified": "2020-05-16T13:02:06.652Z", - "contributors": [ - "Yayure", - "fanxiaojie" - ] - }, - "Web/SVG/Tutorial/Paths": { - "modified": "2020-10-26T07:22:08.293Z", - "contributors": [ - "WindStormrage", - "esc", - "xgqfrms", - "chenyang", - "hebby", - "mochase", - "xianshenglu", - "vlaw", - "fanxiaojie", - "AnnGing", - "teoli", - "ziyunfei" - ] - }, - "Web/SVG/Tutorial/Patterns": { - "modified": "2020-05-04T00:26:06.468Z", - "contributors": [ - "knightyun", - "fanxiaojie", - "zldream1106" - ] - }, - "Web/SVG/Tutorial/Positions": { - "modified": "2019-06-07T11:18:02.352Z", - "contributors": [ - "ymjrcc", - "fanxiaojie", - "BlackGlory", - "jiraiya", - "teoli", - "ziyunfei" - ] - }, - "Web/SVG/Tutorial/SVG_Image_Tag": { - "modified": "2019-03-23T22:46:20.960Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Tutorial/SVG_In_HTML_Introduction": { - "modified": "2019-10-30T00:49:48.215Z", - "contributors": [ - "donley828", - "crazy_rat", - "chrisdavidmills", - "zldream1106", - "lunix01" - ] - }, - "Web/SVG/Tutorial/SVG_fonts": { - "modified": "2019-03-23T22:46:23.842Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/SVG/Tutorial/Texts": { - "modified": "2020-07-06T07:25:02.894Z", - "contributors": [ - "zch233", - "fsx950223", - "fanxiaojie", - "FEbyland" - ] - }, - "Web/SVG/Tutorial/Tools_for_SVG": { - "modified": "2019-03-23T22:46:28.488Z", - "contributors": [ - "fanxiaojie" - ] - }, - "Web/Security": { - "modified": "2019-09-10T16:49:46.462Z", - "contributors": [ - "SphinxKnight", - "cooldrivez", - "zhangppbb", - "RainSlide", - "msforest", - "Vivi-wu", - "ziyunfei", - "Breezewish", - "Freeopen" - ] - }, - "Web/Security/CSP": { - "modified": "2019-08-30T07:28:26.257Z", - "contributors": [ - "ziyunfei", - "Breezewish", - "zhangzipeng", - "R00tgrok" - ] - }, - "Web/Security/CSP/Introducing_Content_Security_Policy": { - "modified": "2019-08-30T07:28:05.612Z", - "contributors": [ - "LeonDWong", - "lcxfs1991", - "Breezewish", - "ziyunfei" - ] - }, - "Web/Security/CSP/Using_CSP_violation_reports": { - "modified": "2019-03-23T23:03:20.586Z", - "contributors": [ - "ziyunfei", - "zhangzipeng" - ] - }, - "Web/Security/Information_Security_Basics": { - "modified": "2020-04-29T06:01:25.213Z", - "contributors": [ - "shellway", - "fanyj1994", - "ivydom", - "wth" - ] - }, - "Web/Security/Same-origin_policy": { - "modified": "2020-04-07T00:07:57.795Z", - "contributors": [ - "H3lloTom", - "dingziqi", - "769344359", - "AOYE", - "LvChengbin", - "Jerry4013", - "Syclover-u2400", - "iceytea", - "moyamoyarua", - "LeezQ", - "Akiq2016", - "zhuangyin", - "heekei", - "sqchenxiyuan", - "firedent", - "orangle", - "xgqfrms-GitHub", - "Ende93", - "Jim_Chen", - "lyhper", - "linzhixiong", - "J22Melody", - "codinglion", - "ziyunfei", - "Taro", - "mr3", - "teoli", - "monjer", - "kusamba", - "Ghostheaven" - ] - }, - "Web/Security/Secure_Contexts": { - "modified": "2020-09-16T05:44:30.532Z", - "contributors": [ - "gjc9620" - ] - }, - "Web/Security/Securing_your_site": { - "modified": "2019-05-30T06:18:16.799Z", - "contributors": [ - "Qos", - "Roscoe93", - "keep2zero", - "xgqfrms-GitHub", - "hashedhyphen" - ] - }, - "Web/Security/Securing_your_site/Configuring_server_MIME_types": { - "modified": "2020-07-16T22:36:04.639Z", - "contributors": [ - "wangxu1144", - "Roscoe93", - "651291702" - ] - }, - "Web/Security/Securing_your_site/Turning_off_form_autocompletion": { - "modified": "2020-06-26T14:51:08.712Z", - "contributors": [ - "Clarkkkk", - "zhangchen", - "nick-ChenZe", - "tsejx", - "1010Tech", - "xgqfrms-GitHub" - ] - }, - "Web/Security/传输层安全协议": { - "modified": "2020-05-16T23:45:09.100Z", - "contributors": [ - "Unequaled804", - "msforest" - ] - }, - "Web/Security/子资源完整性": { - "modified": "2020-06-01T06:08:59.407Z", - "contributors": [ - "asmoker", - "chenqingyue", - "maicss", - "kingcc", - "Roland_Reed", - "xgqfrms-GitHub" - ] - }, - "Web/Tutorials": { - "modified": "2020-09-27T10:44:48.931Z", - "contributors": [ - "GKilyar", - "StorytellerF", - "yzweb2018", - "shengoo", - "yangzi", - "wumouse", - "185-5162-9169", - "Ende93", - "SamuraiMe", - "cehnjing", - "shengyouxiao", - "ziyunfei" - ] - }, - "Web/WebDriver": { - "modified": "2020-10-15T22:20:19.059Z", - "contributors": [ - "lvbaiying", - "ZQ-jhon" - ] - }, - "Web/Web_Components": { - "modified": "2020-05-14T03:39:38.306Z", - "contributors": [ - "lc15011977647", - "RequireSun", - "ujsxn", - "zjffun", - "YellowPure", - "FlyingPig", - "FarmerZhou", - "siwei_null", - "zilong-thu", - "jscgq", - "EliYao", - "zhangchen", - "xgqfrms-GitHub", - "little-tomorrow", - "chaosdog", - "xiaokk06", - "jchnxu", - "Fantasy_shao" - ] - }, - "Web/Web_Components/HTML导入": { - "modified": "2020-10-15T21:47:50.577Z", - "contributors": [ - "2A5F", - "xgqfrms-GitHub", - "jchnxu" - ] - }, - "Web/Web_Components/Status_in_Firefox": { - "modified": "2019-03-23T22:21:10.569Z", - "contributors": [ - "mx601595686" - ] - }, - "Web/Web_Components/Using_custom_elements": { - "modified": "2020-08-13T09:13:52.060Z", - "contributors": [ - "justaverygoodboy", - "ytxmobile", - "LemonTency", - "Xiaoming666", - "bei6", - "YellowPure", - "rianma", - "fu1252", - "olivewind", - "zhang-quan-yi" - ] - }, - "Web/Web_Components/Using_shadow_DOM": { - "modified": "2020-06-08T05:35:09.239Z", - "contributors": [ - "Junezm", - "RainSlide", - "Louis-7", - "haoliangwu", - "zhang-quan-yi" - ] - }, - "Web/Web_Components/Using_templates_and_slots": { - "modified": "2020-11-09T10:43:35.619Z", - "contributors": [ - "luzhenqian", - "jingkaimori", - "Yayure", - "whuhyw", - "sjpeter", - "Czzzx", - "JasonKee", - "xgqfrms", - "xrr2016", - "zxk7516" - ] - }, - "Web/Web_Components/影子_DOM": { - "modified": "2019-03-23T22:29:42.834Z", - "contributors": [ - "xgqfrms-GitHub", - "fsx950223", - "floraluo", - "jchnxu" - ] - }, - "Web/XML": { - "modified": "2019-09-25T00:01:50.050Z", - "contributors": [ - "amalia77", - "ExE-Boss" - ] - }, - "Web/XML/XML_Introduction": { - "modified": "2020-03-04T03:08:47.854Z", - "contributors": [ - "Whitetea00", - "Joria0414", - "fish-inu", - "ExE-Boss", - "DarrenZhang01", - "pluwen", - "xgqfrms-GitHub", - "Y001", - "Mgjbot", - "Gelihui", - "Kakurady", - "Dbseti" - ] - }, - "Web/XPath": { - "modified": "2019-03-18T20:43:12.282Z", - "contributors": [ - "RainSlide", - "Ke.shidong", - "ziyunfei", - "cattail2012@gmail.com" - ] - }, - "Web/XPath/Axes": { - "modified": "2019-03-18T20:43:12.087Z", - "contributors": [ - "ziyunfei", - "Cuimingda" - ] - }, - "Web/XSLT": { - "modified": "2019-03-23T23:52:51.686Z", - "contributors": [ - "Gingercat", - "ziyunfei", - "Freeopen", - "Lycvip" - ] - }, - "Web/XSLT/Elements": { - "modified": "2019-03-24T00:03:10.744Z", - "contributors": [ - "ziyunfei", - "fscholz", - "Freeopen" - ] - }, - "Web/XSLT/Transforming_XML_with_XSLT": { - "modified": "2019-03-23T23:52:45.330Z", - "contributors": [ - "chrisdavidmills", - "ziyunfei", - "Freeopen" - ] - }, - "Web/媒体": { - "modified": "2019-08-30T07:28:45.901Z", - "contributors": [ - "Jwenee", - "Forbidden" - ] - }, - "Web/媒体/Autoplay_guide": { - "modified": "2020-11-19T04:43:44.047Z", - "contributors": [ - "avrinfly", - "baijingfeng" - ] - }, - "Web/演示说明": { - "modified": "2019-09-04T03:32:34.828Z", - "contributors": [ - "RainSlide", - "yzweb2018", - "nanflower", - "Vevlins", - "wth", - "awesomeric" - ] - }, - "WebAPI": { - "modified": "2019-03-18T20:42:39.198Z", - "contributors": [ - "wbamberg", - "fscholz", - "jiahui", - "zhenhua32", - "Meteormatt" - ] - }, - "WebAssembly": { - "modified": "2020-10-15T21:52:52.867Z", - "contributors": [ - "callmeDAY", - "zhangchen", - "ldwformat", - "zhuangyin", - "kingysu", - "xgqfrms-GitHub", - "disoul" - ] - }, - "WebAssembly/C_to_wasm": { - "modified": "2020-11-17T22:59:58.305Z", - "contributors": [ - "CGerAJ", - "zhanyuzhang", - "xinghuolei", - "rui-space", - "jinliming2", - "johncido", - "eeve", - "kingysu", - "hungtcs", - "AdrianDuan", - "disoul" - ] - }, - "WebAssembly/Caching_modules": { - "modified": "2019-03-25T04:00:16.303Z", - "contributors": [ - "Seasonley", - "rui-space", - "kingysu" - ] - }, - "WebAssembly/Concepts": { - "modified": "2019-03-18T20:54:48.847Z", - "contributors": [ - "xiongcong", - "rui-space", - "ziyunfei", - "kingysu" - ] - }, - "WebAssembly/Exported_functions": { - "modified": "2019-07-23T04:14:30.673Z", - "contributors": [ - "imechZhangLY", - "rui-space", - "kingysu" - ] - }, - "WebAssembly/Loading_and_running": { - "modified": "2019-03-18T20:54:50.799Z", - "contributors": [ - "kingysu", - "xgqfrms-GitHub" - ] - }, - "WebAssembly/Rust_to_wasm": { - "modified": "2020-11-12T06:21:14.353Z", - "contributors": [ - "longfangsong", - "linghucq1", - "yanchongwen101", - "Syaki", - "SphinxKnight", - "SToneX", - "wymm0008" - ] - }, - "WebAssembly/Text_format_to_wasm": { - "modified": "2020-01-27T02:12:13.951Z", - "contributors": [ - "coderzh", - "acelan86", - "xgqfrms-GitHub", - "kingysu" - ] - }, - "WebAssembly/Understanding_the_text_format": { - "modified": "2019-03-23T22:12:45.612Z", - "contributors": [ - "yangdonglai", - "rui-space", - "aaron_li", - "Rexli", - "rockfire", - "acelan86", - "kingysu", - "chyingp", - "itminus" - ] - }, - "WebAssembly/Using_the_JavaScript_API": { - "modified": "2020-08-18T06:38:27.755Z", - "contributors": [ - "jealyn", - "xgqfrms", - "coderzh", - "billkang", - "huangjj27", - "kingysu", - "skyfore", - "xgqfrms-GitHub" - ] - }, - "WebGuide/API/File_System": { - "modified": "2019-03-23T23:17:06.579Z", - "contributors": [ - "ziyunfei" - ] - }, - "WebGuide/API/File_System/Introduction": { - "modified": "2019-03-23T23:31:18.012Z", - "contributors": [ - "JobbyM", - "ziyunfei", - "james.li" - ] - }, - "WebRTC": { - "modified": "2019-03-23T23:36:50.162Z", - "contributors": [ - "lxyion", - "acgeeker", - "alayasix" - ] - }, - "WebRTC/介绍": { - "modified": "2019-07-15T23:54:09.891Z", - "contributors": [ - "qs3673132", - "Xiaosha61", - "Move", - "acgeeker" - ] - }, - "Web_Development": { - "modified": "2019-03-24T00:05:29.399Z", - "contributors": [ - "xuxun", - "xcffl", - "superwulei", - "Marcossp", - "fantasticfears", - "limomo", - "Cnmahj" - ] - }, - "Web_Development/Introduction_to_Web_development": { - "modified": "2019-03-24T00:00:33.366Z", - "contributors": [ - "ziyunfei", - "fantasticfears" - ] - }, - "Web_Development/Mobile": { - "modified": "2019-03-23T23:32:37.535Z", - "contributors": [ - "xuxun", - "wbamberg" - ] - }, - "Web_Development/Mobile/Responsive_design": { - "modified": "2019-03-23T23:32:36.317Z", - "contributors": [ - "cagen53070830", - "ziyunfei", - "goodboy" - ] - }, - "XHTML": { - "modified": "2019-03-23T23:53:05.465Z", - "contributors": [ - "SQibang", - "ziyunfei", - "Jiangyuanmil", - "Jiao7zhe8", - "Unest" - ] - }, - "XMLSerializer": { - "modified": "2020-10-15T21:14:45.671Z", - "contributors": [ - "leeleee", - "zhangchen", - "ziyunfei", - "teoli", - "zchong1022" - ] - }, - "learn": { - "modified": "2020-07-16T22:43:49.854Z", - "contributors": [ - "Roy-Tian", - "SirnoChan", - "mrg123", - "wangfangping", - "chentao106", - "916106840510", - "wushengde", - "MingdaHIT", - "JiaHua", - "Aslemonssss", - "SurfingFish", - "svarlamov", - "RanceLotusLee", - "miye", - "xmcgcg", - "codeofjackie", - "xixilog", - "Forbidden", - "Bearies", - "varcat", - "2526chen", - "zs808", - "gao5252", - "xcffl", - "sefer", - "xgqfrms-GitHub", - "fan19900404", - "WavinFlag", - "Simcookies", - "m4jing", - "liminjun", - "sunxiang", - "Ende93", - "Meteormatt", - "lunix01", - "27", - "chenhui7373", - "teoli", - "ziyunfei" - ] - }, - "learn/Accessibility": { - "modified": "2020-07-16T22:40:01.477Z", - "contributors": [ - "shinexyt", - "pixang", - "yatarphae", - "guaner", - "chenghaihua" - ] - }, - "learn/Accessibility/Accessibility_troubleshooting": { - "modified": "2020-07-16T22:40:37.212Z", - "contributors": [ - "wsj0124", - "kuldahar", - "zeng-zhi-yong" - ] - }, - "learn/Accessibility/CSS和JavaScript": { - "modified": "2020-11-03T05:18:13.954Z", - "contributors": [ - "No.5972", - "yawei", - "grape", - "wangfangping", - "wsj0124", - "cani1see", - "hmfight" - ] - }, - "learn/Accessibility/HTML:为可访问性提供一个良好的基础": { - "modified": "2020-07-16T22:40:15.418Z", - "contributors": [ - "grape", - "kuldahar", - "ChuckZhang", - "zxsunrise", - "xiwusheng", - "zouyang1230", - "Junx" - ] - }, - "learn/Accessibility/Mobile": { - "modified": "2020-07-16T22:40:33.086Z", - "contributors": [ - "yuyx91", - "shenshaohui1991" - ] - }, - "learn/Accessibility/WAI-ARIA_basics": { - "modified": "2020-07-16T22:40:24.388Z", - "contributors": [ - "grape", - "Madao-3", - "DavidDavidx" - ] - }, - "learn/Accessibility/多媒体": { - "modified": "2020-07-16T22:40:28.501Z", - "contributors": [ - "wangfangping", - "xiwusheng" - ] - }, - "learn/Front-end_web_developer": { - "modified": "2020-07-16T22:40:48.018Z", - "contributors": [ - "Ende93", - "ex90rts" - ] - }, - "learn/HTML": { - "modified": "2020-07-16T22:22:25.734Z", - "contributors": [ - "anguiao", - "xmcgcg", - "codeofjackie", - "myfreeer", - "xp44mm", - "xgqfrms-GitHub", - "BigLiao", - "leenlyCFFC", - "Mac_zhang", - "aimiy", - "chenxingyu350128", - "Yongest", - "funnyChinese", - "pkjy", - "sunxiang", - "Metalooze" - ] - }, - "learn/HTML/Forms_and_buttons": { - "modified": "2020-02-28T22:25:38.433Z", - "contributors": [ - "Dev-Liangjian" - ] - }, - "learn/HTML/Howto": { - "modified": "2020-07-16T22:22:31.131Z", - "contributors": [ - "xmcgcg", - "coderfee", - "WooHooDai", - "sallyllas", - "sour-toilet-seat", - "webber007", - "pengtikui", - "skylakecore", - "qixi" - ] - }, - "learn/HTML/Howto/Add_a_hit_map_on_top_of_an_image": { - "modified": "2020-07-16T22:22:43.732Z", - "contributors": [ - "hebby" - ] - }, - "learn/HTML/Introduction_to_HTML": { - "modified": "2020-07-16T22:22:54.800Z", - "contributors": [ - "zixuan945", - "mkckr0", - "Sphish", - "xmcgcg", - "imba-tjd", - "HolaForce", - "codeofjackie", - "zihengCat", - "lihaoyuan", - "chenos", - "Melvin.", - "xixilog", - "SeanZHU", - "funnyChinese", - "ZhiRui" - ] - }, - "learn/HTML/Introduction_to_HTML/Advanced_text_formatting": { - "modified": "2020-10-29T09:47:28.341Z", - "contributors": [ - "kuailekai", - "Chell", - "Roy-Tian", - "MorrisLi", - "CesarChang", - "kenneth55555", - "cetewhale", - "xq20160912", - "monkey-king", - "imba-tjd", - "kaka4NERV", - "HolaForce", - "codeofjackie", - "jwhitlock", - "anlien", - "eelord", - "lihaoyuan", - "superkuang", - "zhaoqize", - "023Sparrow", - "yydzxz", - "dirringx", - "HashubWang", - "xiaofei86", - "luwudang", - "weikunzz" - ] - }, - "learn/HTML/Introduction_to_HTML/Debugging_HTML": { - "modified": "2020-09-22T12:30:11.535Z", - "contributors": [ - "Roy-Tian", - "aaazz47", - "Yang_Hanlin", - "huaouo", - "HolaForce", - "lihaoyuan", - "zhaoqize", - "littledust", - "Zeng", - "huixiaomu" - ] - }, - "learn/HTML/Introduction_to_HTML/Getting_started": { - "modified": "2020-07-16T22:23:09.709Z", - "contributors": [ - "lucida959595", - "Roy-Tian", - "dlnb526", - "LINYI", - "Sphish", - "h4091", - "WoodCube", - "eagle1949", - "imba-tjd", - "gadflysu", - "WimZhai", - "jwhitlock", - "HolaForce", - "byeyear", - "Planet6174", - "codeofjackie", - "pachinko", - "Willian.G", - "alonelyer", - "xp44mm", - "shinexyt", - "zhaoqize", - "Jeffrey_Yang", - "lyxy", - "SilverLeaves", - "skylakecore", - "jiahaifeng", - "workttt", - "HashubWang", - "b2ns", - "songbinghui", - "mhengrui", - "PhilipDing", - "RevolverOcelotA", - "hawm", - "3359260180", - "goingon", - "MinimalistYing", - "funnyChinese" - ] - }, - "learn/HTML/Introduction_to_HTML/HTML_text_fundamentals": { - "modified": "2020-11-16T00:17:59.659Z", - "contributors": [ - "sinochen123", - "Roy-Tian", - "aaazz47", - "ZeroAurora", - "youngquan", - "MorrisLi", - "SirnoChan", - "Sphish", - "liangmuyang", - "tryhard", - "sf-think", - "baijingfeng", - "WindLo", - "HolaForce", - "web-xx", - "CaTmmao", - "shiyubo", - "zhaoqize", - "fengkx", - "HashubWang", - "skylakecore", - "876843240", - "DZW314", - "danlanxiaohei", - "c0ldian", - "funnyChinese" - ] - }, - "learn/HTML/Introduction_to_HTML/Marking_up_a_letter": { - "modified": "2020-07-16T22:23:14.761Z", - "contributors": [ - "Roy-Tian", - "ToJunYu", - "ZhiiChong", - "chrisdavidmills", - "SirnoChan", - "FantasqueX", - "imba-tjd", - "ChairMao", - "kongkong1", - "HolaForce", - "Lohoyo", - "phiwyc", - "lihaoyuan", - "zhaoqize", - "gitpyc", - "Boot95" - ] - }, - "learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content": { - "modified": "2020-07-16T22:24:21.297Z", - "contributors": [ - "Roy-Tian", - "MorrisLi", - "HolaForce", - "codeofjackie", - "lihaoyuan", - "zhaoqize", - "littledust", - "ChenLyu01" - ] - }, - "learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML": { - "modified": "2020-12-06T06:59:19.723Z", - "contributors": [ - "zrzjohn", - "wayne_lau", - "Roy-Tian", - "Sphish", - "PYGC", - "WoodCube", - "fangfangfanga", - "eagle1949", - "Metaloe", - "HolaForce", - "qinruiy", - "codeofjackie", - "CaTmmao", - "yevivid", - "Willian.G", - "Milktea", - "anan0v0", - "zhaoqize", - "fengkx", - "oldpotter", - "littledust", - "hjb912", - "tianhu288", - "Mac_zhang", - "BarryLiu1995", - "HashubWang", - "littermark", - "igigi", - "876843240", - "mhengrui", - "Daryl.L", - "chinazhaghai", - "sisyphus-zhou" - ] - }, - "learn/HTML/Introduction_to_HTML/文件和网站结构": { - "modified": "2020-09-22T12:28:50.229Z", - "contributors": [ - "Roy-Tian", - "aaazz47", - "chenduone", - "MorrisLi", - "SirnoChan", - "wangfangping", - "FantasqueX", - "imba-tjd", - "HolaForce", - "HeYuansong", - "web-xx", - "codeofjackie", - "chaosdog", - "phiwyc", - "eelord", - "lihaoyuan", - "zhaoqize", - "nbhaohao", - "dirringx", - "HashubWang", - "skylakecore", - "BarryLiu1995", - "luwudang", - "JX-Master", - "danlanxiaohei", - "c0ldian" - ] - }, - "learn/How_the_Internet_works": { - "modified": "2020-07-16T22:35:39.172Z", - "contributors": [ - "simon.woo", - "grape", - "W-YaoLing", - "ZhuZhuDrinkMilk", - "TaskForce86", - "ShirleyM", - "yydzxz", - "Jeffrey_Yang", - "StarryForce", - "ArcherGrey", - "wth", - "boredivan", - "RyanZhang", - "TanJrJie" - ] - }, - "learn/How_to_contribute": { - "modified": "2020-07-16T22:33:47.665Z", - "contributors": [ - "SphinxKnight", - "Simcookies", - "Forbidden", - "WavinFlag" - ] - }, - "learn/JavaScript": { - "modified": "2020-07-16T22:29:46.300Z", - "contributors": [ - "oceanMIH", - "yummy_song", - "scyhm", - "YehaiChen", - "WavinFlag", - "xgqfrms-GitHub", - "noiron", - "houcheng", - "Maze", - "Metalooze" - ] - }, - "learn/JavaScript/Building_blocks": { - "modified": "2020-07-16T22:31:11.083Z", - "contributors": [ - "Drizzt-Yu", - "NiceGG", - "JiLiangLai", - "xiaobin123", - "xp44mm", - "yzweb2018", - "sonymoon", - "nlln", - "ztytotoro", - "okotta1", - "backli", - "lvyue", - "ByWhy", - "Marslin92", - "chinatomhuang", - "GKilyar", - "iProgramme" - ] - }, - "learn/JavaScript/Building_blocks/Build_your_own_function": { - "modified": "2020-08-01T05:11:26.919Z", - "contributors": [ - "driftingdream", - "Hermedius", - "WindLo", - "qiubite-name", - "codeofjackie", - "Undecyce", - "hygSup", - "gitpyc", - "Ray-Eldath", - "Hecdi", - "ppphp" - ] - }, - "learn/JavaScript/Building_blocks/Functions": { - "modified": "2020-08-27T11:13:47.934Z", - "contributors": [ - "shawn20111416", - "driftingdream", - "jsl1079322620", - "Hermedius", - "jinsth", - "hyjalxl", - "agnoCJY", - "BusyToDie", - "LuoYun", - "codeofjackie", - "zhilu1", - "caifx", - "luoxzhg", - "NicholasCao", - "Pipapa", - "GKilyar", - "caojinguo", - "fyzzy1943", - "minmino" - ] - }, - "learn/JavaScript/Building_blocks/Looping_code": { - "modified": "2020-07-16T22:31:22.467Z", - "contributors": [ - "agnoCJY", - "Yayure", - "jianbinfu", - "LittleMang", - "LuoYun", - "lscnet", - "codeofjackie", - "WhiteYin", - "tuneura", - "DaduCC", - "Ray-Eldath", - "NicholasCao", - "Ende93", - "wanqing19954", - "Marslin92" - ] - }, - "learn/JavaScript/Building_blocks/Return_values": { - "modified": "2020-11-24T04:05:07.114Z", - "contributors": [ - "Anser0111", - "jsl1079322620", - "Hermedius", - "FantasqueX", - "LuoYun", - "larrychen", - "Gloriazdh", - "codeofjackie", - "DaduCC", - "BadRonmance", - "yj21world", - "minmino" - ] - }, - "learn/JavaScript/Building_blocks/conditionals": { - "modified": "2020-07-16T22:31:16.388Z", - "contributors": [ - "SirnoChan", - "qiubite-name", - "Undecyce", - "Ray-Eldath", - "DaduCC", - "NicholasCao", - "ideal.Li", - "lyllll000", - "finegao", - "INFINITSY", - "HashubWang" - ] - }, - "learn/JavaScript/Building_blocks/相片走廊": { - "modified": "2020-07-16T22:31:44.958Z", - "contributors": [ - "lucida959595", - "Roy-Tian", - "LittleMang", - "Park-ma", - "codeofjackie", - "lihaoyuan", - "yeslogin2", - "Zeng" - ] - }, - "learn/JavaScript/Howto": { - "modified": "2020-07-16T22:33:11.775Z", - "contributors": [ - "wangwenhao", - "yuyx91" - ] - }, - "learn/JavaScript/异步": { - "modified": "2020-07-16T22:33:15.541Z", - "contributors": [ - "yuqing521", - "alice201601", - "oceanMIH" - ] - }, - "learn/JavaScript/异步/Async_await": { - "modified": "2020-07-16T22:33:27.360Z", - "contributors": [ - "woniuxingdong", - "qwei", - "plainnany", - "jakio6", - "awarmy", - "cochn", - "wangfangping" - ] - }, - "learn/JavaScript/异步/Choosing_the_right_approach": { - "modified": "2020-10-15T22:20:44.814Z", - "contributors": [ - "icetea_cover", - "rubyKC", - "shangruitong", - "PYGC", - "wangfangping", - "tjls" - ] - }, - "learn/JavaScript/异步/Promises语法": { - "modified": "2020-12-07T14:31:25.365Z", - "contributors": [ - "byrde", - "You2er", - "hidoos", - "mizhon", - "haoawen", - "PYGC", - "masterZSH", - "wangfangping", - "kafm", - "zijieee" - ] - }, - "learn/JavaScript/异步/概念": { - "modified": "2020-07-16T22:33:29.726Z", - "contributors": [ - "alice201601", - "grape", - "HermitSun", - "oceanMIH" - ] - }, - "learn/JavaScript/异步/简介": { - "modified": "2020-07-16T22:33:19.077Z", - "contributors": [ - "iroywang", - "hidoos", - "Hermedius", - "Xugen-Ma", - "alice201601", - "grape", - "Kavelaa", - "gqbre", - "oceanMIH" - ] - }, - "learn/JavaScript/异步/超时和间隔": { - "modified": "2020-08-14T06:09:20.310Z", - "contributors": [ - "Pada", - "You2er", - "WinterCicada", - "zhangbig0", - "mizhon", - "yuqing521", - "Alendia", - "grape", - "wangfangping", - "puddlejumper26", - "oceanMIH" - ] - }, - "learn/Learning_and_getting_help": { - "modified": "2020-12-06T05:06:52.891Z", - "contributors": [ - "3143875691" - ] - }, - "learn/Performance": { - "modified": "2020-12-05T12:01:04.505Z", - "contributors": [ - "mayerpan", - "liguanzeng", - "Bayes", - "yangchongduo" - ] - }, - "learn/Performance/Web_Performance_Basics": { - "modified": "2020-07-16T22:40:42.886Z", - "contributors": [ - "shuiRong", - "creative_fish" - ] - }, - "learn/Performance/感知性能": { - "modified": "2020-07-16T22:40:43.760Z", - "contributors": [ - "biqing" - ] - }, - "learn/Server-side": { - "modified": "2020-07-16T22:36:03.668Z", - "contributors": [ - "ZuoRight", - "xixilog", - "JamesZhange", - "Munch_TZB", - "GHLgh" - ] - }, - "learn/Server-side/Django": { - "modified": "2020-07-16T22:36:36.546Z", - "contributors": [ - "diyigechipangxie", - "xixilog", - "chinanf-boy", - "hstaoqian", - "Zhaoyu" - ] - }, - "learn/Server-side/Django/Authentication": { - "modified": "2020-07-16T22:37:25.161Z", - "contributors": [ - "floodwater", - "edgar-chen", - "xixilog" - ] - }, - "learn/Server-side/Django/Deployment": { - "modified": "2020-11-23T18:29:57.524Z", - "contributors": [ - "keetack", - "edgar-chen", - "yan-jin", - "xixilog" - ] - }, - "learn/Server-side/Django/Forms": { - "modified": "2020-07-16T22:37:34.229Z", - "contributors": [ - "buttre", - "edgar-chen", - "xixilog" - ] - }, - "learn/Server-side/Django/Generic_views": { - "modified": "2020-07-16T22:37:19.625Z", - "contributors": [ - "edgar-chen", - "xixilog", - "SphinxKnight" - ] - }, - "learn/Server-side/Django/Introduction": { - "modified": "2020-07-16T22:36:42.459Z", - "contributors": [ - "khalim", - "Nel", - "ShuangFarmer", - "xiezhedaima9591", - "chinanf-boy" - ] - }, - "learn/Server-side/Django/Models": { - "modified": "2020-07-16T22:37:00.935Z", - "contributors": [ - "shawPLUSroot", - "senghongchong7", - "phdgogogo", - "colin3dmax", - "AIIEOIBD", - "zphj1987", - "cashlu", - "xixilog", - "szlh", - "chinanf-boy" - ] - }, - "learn/Server-side/Django/Sessions": { - "modified": "2020-07-16T22:37:28.578Z", - "contributors": [ - "buttre", - "edgar-chen", - "xixilog" - ] - }, - "learn/Server-side/Django/Testing": { - "modified": "2020-07-16T22:37:39.373Z", - "contributors": [ - "edgar-chen", - "xixilog" - ] - }, - "learn/Server-side/Django/Tutorial_local_library_website": { - "modified": "2020-07-16T22:36:50.644Z", - "contributors": [ - "zengqi", - "ddtyjmyjm", - "hstaoqian" - ] - }, - "learn/Server-side/Django/django_assessment_blog": { - "modified": "2020-07-16T22:37:49.691Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Django/skeleton_website": { - "modified": "2020-07-16T22:36:55.364Z", - "contributors": [ - "Nel", - "xixilog", - "ddtyjmyjm", - "MengLingqin", - "chinanf-boy", - "hstaoqian" - ] - }, - "learn/Server-side/Django/web_application_security": { - "modified": "2020-07-16T22:37:47.216Z", - "contributors": [ - "knktc", - "edgar-chen", - "xixilog" - ] - }, - "learn/Server-side/Django/主页构建": { - "modified": "2020-07-16T22:37:11.997Z", - "contributors": [ - "feko", - "mojiangyuan", - "colin3dmax", - "floodwater", - "xixilog", - "chinanf-boy" - ] - }, - "learn/Server-side/Django/开发环境": { - "modified": "2020-10-06T10:08:45.805Z", - "contributors": [ - "kuailekai", - "silentpanda97", - "Adrian-Yan", - "q2937711", - "xixilog", - "chinanf-boy" - ] - }, - "learn/Server-side/Django/管理站点": { - "modified": "2020-07-16T22:37:06.131Z", - "contributors": [ - "Jeffxzj", - "wangfangping", - "colin3dmax", - "indv-zhu", - "chinanf-boy" - ] - }, - "learn/Server-side/Express_Nodejs": { - "modified": "2020-07-16T22:37:56.406Z", - "contributors": [ - "hellorayza", - "百里笙歌", - "Frederick-S", - "yatace", - "edgar-chen", - "Ran_Lyu", - "longzhengxiong", - "sp900409", - "chenlexing", - "ant0x00" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data": { - "modified": "2020-10-27T00:17:29.715Z", - "contributors": [ - "Megrax", - "socovo", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page": { - "modified": "2020-07-16T22:38:39.461Z", - "contributors": [ - "woshiqiang1", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/Author_list_page": { - "modified": "2020-07-16T22:38:38.246Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_detail_page_and_challenge": { - "modified": "2020-07-16T22:38:39.803Z", - "contributors": [ - "staticfire", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_list_page": { - "modified": "2020-07-16T22:38:37.044Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/Book_detail_page": { - "modified": "2020-07-16T22:38:39.148Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/Book_list_page": { - "modified": "2020-07-16T22:38:36.367Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/Date_formatting_using_moment": { - "modified": "2020-07-16T22:38:37.610Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/Genre_detail_page": { - "modified": "2020-07-16T22:38:38.748Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/Home_page": { - "modified": "2020-07-16T22:38:35.735Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/LocalLibrary_base_template": { - "modified": "2020-10-27T06:26:13.607Z", - "contributors": [ - "Megrax", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/Template_primer": { - "modified": "2020-07-16T22:38:34.671Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async": { - "modified": "2020-07-16T22:38:33.746Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Installing_on_PWS_Cloud_Foundry": { - "modified": "2020-09-24T11:45:05.090Z", - "contributors": [ - "Mdreame", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/Introduction": { - "modified": "2020-07-16T22:38:13.912Z", - "contributors": [ - "Roy-Tian", - "hehe1111", - "sun603", - "janyin", - "biblade", - "outman", - "congrongdeyu", - "codeofjackie", - "edgar-chen", - "bybiuhappy", - "ShirleyM", - "lofayo", - "chengzhibing" - ] - }, - "learn/Server-side/Express_Nodejs/Tutorial_local_library_website": { - "modified": "2020-07-16T22:38:17.531Z", - "contributors": [ - "Roy-Tian", - "chudongsong", - "janyin", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/deployment": { - "modified": "2020-07-16T22:38:50.827Z", - "contributors": [ - "edgar-chen", - "codeofjackie" - ] - }, - "learn/Server-side/Express_Nodejs/development_environment": { - "modified": "2020-07-16T22:38:02.448Z", - "contributors": [ - "snaildarter", - "phili-p", - "Roy-Tian", - "sun603", - "yijie_sun", - "yaoqtan", - "jianchao_xue", - "edgar-chen", - "BarryLiu1995" - ] - }, - "learn/Server-side/Express_Nodejs/forms": { - "modified": "2020-08-07T05:55:45.402Z", - "contributors": [ - "yunxiaomeng", - "grape", - "hdh296", - "socovo", - "edgar-chen", - "zhangyu911013" - ] - }, - "learn/Server-side/Express_Nodejs/forms/Create_BookInstance_form": { - "modified": "2020-07-16T22:38:46.101Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/forms/Create_author_form": { - "modified": "2020-07-16T22:38:44.657Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/forms/Create_book_form": { - "modified": "2020-07-16T22:38:45.191Z", - "contributors": [ - "SphinxKnight", - "UPUP", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/forms/Create_genre_form": { - "modified": "2020-07-16T22:38:43.645Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/forms/Delete_author_form": { - "modified": "2020-07-16T22:38:46.761Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/forms/Update_Book_form": { - "modified": "2020-07-16T22:38:48.713Z", - "contributors": [ - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/mongoose": { - "modified": "2020-08-12T09:45:03.710Z", - "contributors": [ - "Dazhuzhu-github", - "vpstarter", - "百里笙歌", - "socovo", - "Roy-Tian", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/routes": { - "modified": "2020-10-23T08:33:36.699Z", - "contributors": [ - "Hawaii_zzapi", - "百里笙歌", - "Roy-Tian", - "jianchao_xue", - "edgar-chen" - ] - }, - "learn/Server-side/Express_Nodejs/skeleton_website": { - "modified": "2020-08-26T10:22:11.122Z", - "contributors": [ - "Tiny-Wei", - "Roy-Tian", - "edgar-chen" - ] - }, - "learn/Server-side/First_steps": { - "modified": "2020-07-16T22:36:11.413Z", - "contributors": [ - "DaniellaAngel", - "edgar-chen", - "ArcherGrey", - "chf007", - "tinyCucumber", - "07akioni" - ] - }, - "learn/Server-side/First_steps/Client-Server_overview": { - "modified": "2020-07-16T22:36:22.601Z", - "contributors": [ - "DaniellaAngel", - "JuleHenriHu", - "WindLo", - "yijie_sun", - "ZhuZhuDrinkMilk", - "edgar-chen", - "ShuangFarmer", - "whocare", - "BarryLiu1995", - "yuantongkang", - "liminjun", - "zhuangyin", - "old2sun", - "ziyouwa", - "Zeng" - ] - }, - "learn/Server-side/First_steps/Introduction": { - "modified": "2020-09-13T05:53:31.575Z", - "contributors": [ - "dake0805", - "vicco", - "yijie_sun", - "zhangchen", - "Nothosaurs", - "lonelee", - "diaotai", - "old2sun", - "ziyouwa", - "Zeng" - ] - }, - "learn/Server-side/First_steps/Web_frameworks": { - "modified": "2020-07-16T22:36:26.173Z", - "contributors": [ - "mojiangyuan", - "DaniellaAngel", - "hikigaya58", - "tongwenwu", - "zhuzhangliang", - "edgar-chen", - "JamesZhange", - "ddtyjmyjm", - "Phoenixkaze", - "Jhongwun", - "Stevenhwang", - "yinzhuoya", - "old2sun", - "Zeng" - ] - }, - "learn/Server-side/First_steps/Website_security": { - "modified": "2020-10-20T04:30:22.097Z", - "contributors": [ - "Megrax", - "mayhjx", - "yi2sun", - "ZhuZhuDrinkMilk", - "goat91", - "Zeng" - ] - }, - "learn/Web_Mechanics": { - "modified": "2020-07-16T22:22:13.542Z", - "contributors": [ - "jdk137", - "Ende93", - "yfdyh000", - "yanbinlucy" - ] - }, - "使用Javascript和DOM_Interfaces来处理HTML": { - "modified": "2020-10-08T06:13:28.865Z", - "contributors": [ - "ruiyang0012", - "crowphy", - "newued", - "helloguangxue", - "Jcrjia", - "Transfan", - "Laser", - "Carrie zhxj", - "Mgjbot", - "Surfchen", - "Kakurady", - "Heagle" - ] - } -} \ No newline at end of file diff --git a/files/zh-cn/adding_extensions_using_the_windows_registry/index.html b/files/zh-cn/adding_extensions_using_the_windows_registry/index.html deleted file mode 100644 index 24d2bf7477..0000000000 --- a/files/zh-cn/adding_extensions_using_the_windows_registry/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Adding Extensions using the Windows Registry -slug: Adding_Extensions_using_the_Windows_Registry -tags: - - Extensions -translation_of: >- - https://extensionworkshop.com/documentation/publish/signing-and-distribution-overview/ ---- -

Introduction 简介

-

This document explains how to "install" Firefox and Thunderbird extensions using the Windows Registry. This mechanism is designed to make it easier for third-party installers to register extensions with Firefox and Thunderbird.
-本文说明如何使用Windows注意表"安装"Firefox/Thunderbird extensions. 此机制用以方便第三方为Firefox/Thunderbird注意extensions. -

Note The mechanism described in this document requires Firefox/Thunderbird 1.5 or later.
-注意 此机制要求Firefox/Thunderbird 1.5或者更高版本. -

-

Installation 安装

-

Installation is performed by writing a Registry entry under one of the following keys:
-在下列注册表键(或其中之一)下加入注册表项来完成安装: -

-
HKEY_CURRENT_USER\Software\Vendor\Name\Extensions
-HKEY_LOCAL_MACHINE\Software\Vendor\Name\Extensions
-
-

Where Vendor and Name are the values returned from the corresponding properties of nsIXULAppInfo. In Mozilla products, Vendor is "Mozilla", and Name is the short name of the product, e.g.:
-VendorName的值可由相对应的nsIXULAppInfo属性得到. 在Mozilla产品中, Vendor的值为"Mozilla", Name为产品的短名称, 例如: -

-
HKEY_CURRENT_USER\Software\Mozilla\Firefox\Extensions
-HKEY_CURRENT_USER\Software\Mozilla\Thunderbird\Extensions
-
-

The ID of the extension must be used as the name of the Registry entry. The Registry entry must have a type of REG_SZ, and its value must be an absolute path to the folder containing the extension (i.e., the location of the unpacked XPI). For example, to install the extension described in the Building an Extension article, create a Registry entry with name equal to sample@foo.net and value equal to c:\extensions\myExtension.
-Extension的ID必须作为注册项的名字. 注册项的类型必须为REG_SZ, 值必须是包含extension的文件夹的绝对路径. 例如, 要安装Building an Extension文章中的extension, 创建名为sample@foo.net的注册项, 设定其值为c:\extensions\myExtension. -

After the Registry entry is created, Firefox/Thunderbird will notice the change the next time it is launched. It is safe to modify the Registry keys while Firefox/Thunderbird is running.
-注册项创建完成后, 在下一次启动时Firefox/Thunderbird将会注意到变化. 在Firefox/Thunderbird运行期间也可以安全地修改注册项. -

If the same extension appears under both HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE, then the instance under HKEY_CURRENT_USER will be used. If the same extension appears in the user's profile directory (via manual install), then it will take precedence over any instances found in the Registry.
-如果HKEY_CURRENT_USERHKEY_LOCAL_MACHINE下有相同的extension, 那么HKEY_CURRENT_USER将被先行使用. 如果用户目录下有相同extension, 那么它将优先于任何注册项. -

-

Uninstallation 卸载

-

Extensions installed using the Windows Registry may be uninstalled by simply removing their corresponding Registry entry. After the Registry entry is removed, Firefox/Thunderbird will notice the change the next time it is launched. It is safe to modify the Registry keys while Firefox/Thunderbird is running.
-由Windows注册表安装的extensions可简单的进行相应注册项的删除完成卸载. 注册项删除后, 在下一次启动时Firefox/Thunderbird将会注意到变化. Firefox/Thunderbird运行期间也可安全的修改注册表. -

-

See also 参见

-

打包extension -

-
-
-{{ languages( { "en": "en/Adding_Extensions_using_the_Windows_Registry", "ja": "ja/Adding_Extensions_using_the_Windows_Registry", "zh-tw": "zh_tw/\u4ee5_Windows_\u767b\u9304\u78bc\u5b89\u88dd\u64f4\u5145\u5957\u4ef6" } ) }} diff --git a/files/zh-cn/aggregating_the_in-memory_datasource/index.html b/files/zh-cn/aggregating_the_in-memory_datasource/index.html deleted file mode 100644 index 6ecf148dff..0000000000 --- a/files/zh-cn/aggregating_the_in-memory_datasource/index.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: 收集 In-Memory 数据源 -slug: Aggregating_the_In-Memory_Datasource -tags: - - RDF -translation_of: Mozilla/Tech/XPCOM/Aggregating_the_In-Memory_Datasource ---- -

 

-

Introduction

-

You can use XPCOM aggregation1 with the in-memory datasource. Why would you want to do this? Say you were writing a datasource2, and the way you chose to implement it was to "wrap" the in-memory datasource; i.e.,

-
MyClass : public nsIMyInterface, public nsIRDFDataSource {
-private:
-    nsCOMPtr<nsIRDFDataSource> mInner;
-
-public:
-    // nsIRDFDataSource methods
-    NS_IMETHOD Init(const char* aURI) {
-        return mInner->Init(aURI);
-    }
-
-    NS_IMETHOD GetURI(char* *aURI) {
-        return mInner->GetURI(aURI);
-    }
-
-    // etc., for each method in nsIRDFDataSource!
-};
-
-

Very painful, prone to errors, and fragile as the interfaces are still in flux (a wee bit). Aggregation to the rescue! Here are the gory details on how.

-

When It Won't Work

-

Although this magic is terribly convenient to use, it won't work in the case that you want to "override" some of the in-memory datasource's methods. For example, while writing the bookmarks datasource, I wanted to be able to trap Assert() to enforce the bookmarks datasource would only accept "bookmarks related" assertions. If I'd just delegated to the in-memory datasource, Assert() would've taken any old random garbage. Similarly, I wanted to trap Flush() so that I could write the bookmarks.html file back to disk.

-

In short, the only case where this technique is useful is when you're implementing a datasource to get "read-only reflection". That is, you want to reflect the contents of something as an RDF graph (presumably so that it can be aggregated with other information or displayed as styled content).

-

Technical Details

-

As before, have an nsCOMPtr as your delegate, but this time around, - - don't - derive from nsIRDFDataSource. Also, instead of keeping an nsCOMPtr<nsIRDFDataSource>, you'll just want an nsCOMPtr<nsISupports>:

-
class MyClass : public nsIMyInterface {
-    ...
-private:
-    nsCOMPtr<nsISupports> mInner;
-};
-
-

Construct the datasource delegate when your object is constructed (or, at worst, when somebody QI's for it):

-
rv = nsComponentManager::CreateInstance(
-        kRDFInMemoryDataSourceCID,
-        this, /* the "outer" */
-        nsCOMTypeInfo<nsISupports>::GetIID(),
-        getter_AddRefs(mInner));
-
-

Note passing this as the "outer" parameter.

-

Now, if the in-memory datasource's implementation of QueryInterface() fails because it doesn't support the requested interface, it will - - forward - the query interface to its "outer" (which is "us"). This preserves the symmetrical property of QueryInterface().

-

For us to preserve symmetry, our QueryInterface() implementation needs to forward nsIRDFDataSource to the delegate3:

-
NS_IMETHODIMP
-MyClass::QueryInterface(REFNSIID aIID, void** aResult)
-{
-  NS_PRECONDITION(aResult != nsnull, "null ptr");
-  if (! aResult)
-    return NS_ERROR_NULL_POINTER;
-
-  if (aIID.Equals(nsCOMTypeInfo<nsIMyInterface>::GetIID()) ||
-      aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
-    *aResult = NS_STATIC_CAST(nsIGlobalHistory*, this);
-  }
-  else if (aIID.Equals(nsCOMTypeInfo<nsIRDFDataSource>::GetIID())) {
-    return mInner->QueryInterface(aIID, aResult);
-  }
-  else {
-    *aResult = nsnull;
-    return NS_NOINTERFACE;
-  }
-
-  NS_ADDREF(NS_STATIC_CAST(nsISupports*, aResult));
-  return NS_OK;
-}
-
-

The only other thing that you'll need to be aware of is that you'll need to QueryInterface() from nsISupports to nsIRDFDataSource before you can actually do anything useful with the datasource from within your object. For example:

-
NS_IMETHODIMP
-MyClass::DoSomething()
-{
-  nsCOMPtr<nsIRDFDataSopurce> ds = do_QueryInterface(mInner);
-
-  rv = ds->Assert(/* something useful here */);
-
-  // etc...
-
-  return NS_OK;
-}
-
-

It may be tempting to keep a pointer to the aggregate's nsIRDFDataSource in a member variable, but - - you can't do that - . Why? Because if you did, you'd hold a circular reference that would never unwind.

-

Notes

-
    -
  1. Describing all of the vagaries of XPCOM aggregation is beyond the scope of this document. The basic idea is to overload QueryInterface(), allowing it to return a - - delegate - object that supports the interface. There is some trickery involved on the delegate's part to ensure that reference counting is done sanely, and that the reflexive, symmetric, and transitive properties of QueryInterface() are preserved. If you're really interested, I'd recommend reading about it in a COM book.
  2. -
  3. For more information on writing a datasource, see the RDF Datasource How-To document.
  4. -
  5. You could also forward other interfaces to the mInner that you - - know - it can support; however, this is extremely risky. It's risky because another implementation of the same object might - - not - support those interfaces. Then the QueryInterface() will be forwarded back to you, and we'll recurse off to infinity (and beyond!...)
  6. -
-

Interwiki Language Links

-

diff --git a/files/zh-cn/archive/add-ons/developing_add-ons/index.html b/files/zh-cn/archive/add-ons/developing_add-ons/index.html deleted file mode 100644 index 80eaac8ffc..0000000000 --- a/files/zh-cn/archive/add-ons/developing_add-ons/index.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Developing add-ons -slug: Archive/Add-ons/Developing_add-ons -translation_of: Archive/Add-ons/Developing_add-ons ---- -

基于Mozilla的软件通常是通过加载项来实现扩展. 有三种基本类型的加载项: 扩展, 插件和主题. 本页将指导你为Firefox, Thunderbird或其它基于Mozilla的软件创建组件时你所需要的信息, 以及如何发布你的加载项.

- -

Add-ons topics

Submitting an add-on to AMO 提交加载项到AMO
为加载项开发人员提供有用的信息以帮助他们正确的打包并提供他们的加载项. 这包含关于addons.mozilla.org及Mozilla's加载项发布Web地点的信息.
Extensions 扩展
扩展增加新的功能给像Firefox, SeaMonkey和Thunderbird这类Mozilla应用. 它可以增加任何功能, 包括从工具栏按钮到完整新特性.
Plug-ins 插件
Information about how to create plug-ins, which are binary components that let Mozilla based software display content they can't handle natively.
有关如何创建插件, 让基于Mozill二进制组件
Themes 主题
Themes let users customize the appearance of the user interface presented by Mozilla-based applications.
用户可以使用扩展来改变基于Mozilla的应用程序的外观。
Search engine plug-ins 搜索引擎插件
Firefox supports search engine plug-ins, which enable the search box to support different search engines.
The Mozilla platform Mozilla 平台
Information about the Mozilla platform, including all of its APIs and technologies, as well as how to use them in your own projects.
diff --git a/files/zh-cn/archive/add-ons/downloading_json_and_javascript_in_extensions/index.html b/files/zh-cn/archive/add-ons/downloading_json_and_javascript_in_extensions/index.html deleted file mode 100644 index 3760e02fae..0000000000 --- a/files/zh-cn/archive/add-ons/downloading_json_and_javascript_in_extensions/index.html +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 在扩展中下载JSON和JavaScript -slug: Archive/Add-ons/Downloading_JSON_and_JavaScript_in_extensions -tags: - - Extensions -translation_of: Archive/Add-ons/Downloading_JSON_and_JavaScript_in_extensions ---- -


- 在很多扩展中常见的用法是使用XMLHttpRequest(或者其他机制)从一个远程的网站下载 JavaScript 或者JSON(这两者是不同的!)一旦内容下载完成,扩展的作者就会使用 eval() 继续进行解码的工作,把字串内容转换成 JavaScript 对象。这样的做法是非常危险的,并且,实际上不会通过AMO的审核。所以这样的扩展将不会被允许离开AMO的砂箱。

- -

这种做法是危险的是因为解码后的 JavaScript 具有全部的 chrom 权限并且可以执行一些很恶劣的动作.一个扩展下载下来的JavaScript如何能执行恶劣的动作?如果承载 JavaScript 的网络服务器被劫持了或者被攻陷了,那就很容易了。这种情况是有可能发生的。AMO很认真地看待这种危险。

- -

好消息是我们有很多方法来绕开这个问题。

- -

下载 JSON

- -

如果扩展是需要下载JSON,那么开发人员应该使用在这里讨论过的某种JSON解码方法,而千万不要使用eval() 。JSON是有关状态的,并不允许解码函数。扩展开发人员可用的JSON解码方法保护了扩展免于受到恶意的JSON和JavaScrip的侵害。从远端的服务器通过JSON下载状态变得日益流行。使用JSON解码器,而不是eval()

- -

下载 JavaScript

- -

当然了,有时候也有扩展中下载并插入 JavaScript 代码模块的时候。发生这些事情主要是因为扩展试图保持它的部分代码是干净和动态的,而扩展的作者又不想为每次脚本的变化发布一个新版本。在这种场合下,我们应该使用 JavaScript 的砂箱来把下载下来的JavaScript代码和扩展的其它代码部分以及宿主的应用给隔离开。

- -

砂箱是通过使用Components.utils.evalInSandbox()实现的。JavaScript 代码会被和任何JavaScript需要交互的"安全"的对象一起添加到砂箱里。砂箱自己也不是完全没有危险,开发者应该仔细阅读砂箱的文档页面,以确保不可信的代码不会从砂箱中泄露出来。

- -

diff --git a/files/zh-cn/archive/add-ons/index.html b/files/zh-cn/archive/add-ons/index.html deleted file mode 100644 index 7c4b16bc57..0000000000 --- a/files/zh-cn/archive/add-ons/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Add-ons -slug: Archive/Add-ons -tags: - - Add-ons - - Archive - - Extensions - - 存档 - - 拓展 -translation_of: Archive/Add-ons ---- -
{{AddonSidebar}}
- -

存档的旧式拓展开发文档。

- -
-
Add-on SDK
-
Using the Add-on SDK, you can create Firefox add-ons. You can use various standard Web technologies: JavaScript, HTML, and CSS, to create the add-ons. The SDK includes JavaScript APIs, which you can use to create add-ons and tools for creating, running, testing, and packaging add-ons.
-
bookmarks.export()
-
将书签导出为 HTML 书签文件。
-
bookmarks.import()
-
从 HTML 书签文件导入书签。
-
Bootstrapped extensions
-
browser.bookmarks.export( function() {...} // optional function )
-
Code snippets
-
-
Creating custom Firefox extensions with the Mozilla build system
-
There is a wealth of material on creating extensions for Firefox. All of these documents currently assume, however, that you are developing your extension using XUL and JavaScript only. For complex extensions, it may be necessary to create components in C++ that provide additional functionality. Reasons why you might want to include C++ components in your extension include:
-
Embedded WebExtension
-
Starting in Firefox 51, you can embed a WebExtension in a classic bootstrapped extension or an Add-on SDK add-on. The embedded WebExtension's files are packaged inside the legacy add-on. The embedded WebExtension doesn't directly share its scope with the embedding legacy add-on, but they can exchange messages using the messaging functions defined in the runtime API.
-
Extension Etiquette
-
This article describes best practices when making extensions, including how to be kind to your users. It assumes that you are already familiar with Building an Extension.
-
Extension Packaging
-
By the end of 2017 WebExtensions will be the only supported add-on type in Firefox. To learn how to install a WebExtension for testing purposes, see Temporary Installation in Firefox. To learn how to package a WebExtension for distribution, see Publishing your WebExtension.
-
Extensions support in SeaMonkey 2
-
Starting with SeaMonkey 2 Alpha 1 SeaMonkey supports toolkit/-style extensions. These type of extensions have many advantages for both users and developers compared to the old xpinstall/-style extensions.
-
Firefox addons developer guide
-
The original document is in Japanese and distributed via the xuldev.org website. So there may be still some reference to the xuldev website (we want to host source code on MDC, not on xuldev), and to Japanese things (like some specific locales, which have been translated to French since non-latin characters are not well supported).
-
Hotfix Extension
-
This document has been moved to the Add-ons wiki.
-
How to convert an overlay extension to restartless
-
First off, what kind of add-on are we talking about here? Well, XUL overlays and windows, JSM files, chrome & resource mappings with localization, default preferences, but no XPCOM components of your own. Some of that will have to be replaced and the rest will need to be loaded differently.
-
Inline options
-
Firefox 7 supports a new syntax for defining extensions' preferences for both bootstrapped and traditional extensions. The user interface for the preferences defined with this new syntax appears in the extension's detail view in the Add-on Manager. This functionality originally appeared in Firefox mobile and is now available in Firefox on the desktop as well.
-
Install Manifests
-
An Install Manifest is the file an Add-on Manager-enabled XUL application (e.g. Firefox or Thunderbird) uses to determine information about an add-on as it is being installed. It contains metadata identifying the add-on, providing information about who created it, where more information can be found about it, which versions of what applications it is compatible with, how it should be updated, and so on.
-
Interaction between privileged and non-privileged pages
-
An easy way to send data from a web page to an extension is by using custom DOM events. In your extension's browser.xul overlay, write code which listens for a custom DOM event. Here we call the event MyExtensionEvent.
-
Legacy Add-ons
-
This section contains links to documentation for legacy technology for add-on development, including:
-
Legacy extensions for Firefox for Android
-
Add-ons that work with desktop Firefox do not automatically work in Firefox for Android:
-
Overlay extensions
-
This page contains links to documentation for the approach to developing extensions for Gecko-based applications which uses:
-
Performance best practices in extensions
-
One of Firefox's great advantages is its extreme extensibility. Extensions can do almost anything. There is a down side to this: poorly written extensions can have a severe impact on the browsing experience, including on the overall performance of Firefox itself. This article offers some best practices and suggestions that can not only improve the performance and speed of your extension, but also of Firefox itself.
-
Security best practices in extensions
-
This document is intended as a guide for developers to promote best practices in securing your extension. Your goal is to keep your users safe. Some items mentioned are strict guidelines, meaning that if you don't follow them then your add-on will not be approved on Mozilla add-ons. Other items are recommendations. The difference will be clearly flagged.
-
Setting up an extension development environment
-
This article provides suggestions for how to set up your Mozilla application for extension development. These details apply to Firefox, Thunderbird, and SeaMonkey (version 2.0 and above).
-
Tabbed browser
-
Here you should find a set of useful code snippets to help you work with Firefox's tabbed browser. The comments normally mark where you should be inserting your own code.
-
Techniques
-
-
Working with multiprocess Firefox
-
In older versions of Firefox, chrome code (including code inserted by extensions) and content run in the same operating system process. So extensions can access content directly:
-
diff --git a/files/zh-cn/archive/add-ons/installing_extensions_and_themes_from_web_pages/index.html b/files/zh-cn/archive/add-ons/installing_extensions_and_themes_from_web_pages/index.html deleted file mode 100644 index ffc2c7240b..0000000000 --- a/files/zh-cn/archive/add-ons/installing_extensions_and_themes_from_web_pages/index.html +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Installing_Extensions_and_Themes_From_Web_Pages(从网页安装扩展和主题) -slug: Archive/Add-ons/Installing_Extensions_and_Themes_From_Web_Pages -translation_of: Archive/Add-ons/Installing_Extensions_and_Themes_From_Web_Pages ---- -

There are a variety of ways you can install extensions and themes from web pages, including direct linking to the XPI files and using the InstallTrigger object.(译:要通过网页来安装扩展和主题,有多种方法可供选择,包括直接链接到XPI文件和使用InstallTrigger对象。)

-

Extension and web authors are encouraged to use the method described below to install XPIs, as it provides the best experience to users.(译:鼓励扩展和网页的开发者使用如下描述的方法来安装XPI文件,这将会给使用者最好的体验。)

-

Web Script Example

-
<script type="application/x-javascript">
-<!--
-function install (aEvent)
-{
-  var params = {
-    "Foo": { URL: aEvent.target.href,
-             IconURL: aEvent.target.getAttribute("iconURL"),
-             Hash: aEvent.target.getAttribute("hash"),
-             toString: function () { return this.URL; }
-    }
-  };
-  InstallTrigger.install(params);
-
-  return false;
-}
--->
-</script>
-
-<a href="http://www.example.com/foo.xpi"
-  iconURL="http://www.example.com/foo.png"
-  hash="sha1:28857e60d043447c5f4550853f2d40770b326a13"
-  onclick="return install(event);">Install Extension!</a>
-
-

Let's go through this piece by piece. The HTML <a> is the install link. The href attribute contains a direct link to the extension XPI file, this is what will show in the location bar when the link is moused over. Users can save the XPI file to disk easily by right clicking on the link and choosing "Save Link As..."[译:让我们一点一点地看这些代码。HTML标签<a>是用来安装的链接。href属性包含了一个到扩展XPI文件的连接,当鼠标经过时这个连接就会在地址栏中显示出来。使用者可以简单地通过点击右键选“另存为...”来保存该XPI文件到本地磁盘。]

-

When the link is clicked it calls the function install passing the event object as the parameter.[译:当这个链接被点击时,install函数会被调用,并传递一个事件对象作为参数。]

-

The install first creates a parameter block:[译:安装过程首先会创建一个如下的参数块:]

-
var params = {
-  "Foo": { URL: aEvent.target.href,
-           IconURL: aEvent.target.getAttribute("iconURL"),
-           Hash: aEvent.target.getAttribute("hash"),
-           toString: function () { return this.URL; }
-};
-
-

This specifies the display name (Foo) for use in the confirmation dialog, the URL to the extension (which is the link href, recall), the Icon URL to display in the confirmation dialog, a hash of the xpi file contents (to protect against corrupted downloads), and a toString function which will allow this code to work with versions of Firefox 0.8 and earlier. You could also use the old style parameter block ({ "Foo": aEvent.target.href }) if you wanted - and didn't have an Icon to use for the confirmation dialog.[译:它指定了在确认对话框上的显示名字(Foo),到扩展的URL(连接的href属性),显示在确认对话框上的图标的URL,xpi文件的hash值(防止下载过程中的错误),和一个用来让该能在Firefox0.8及以前版本上工作的toString函数。如果愿意的话,你可以使用旧的编码风格来写这个参数块({ "Foo": aEvent.target.href }),你也可以不指定显示在确认对话框上的图标。]

-

InstallTrigger.install is then called to install the item with the parameter block. [译:接下来InstallTrigger.install会被调用,它使用刚才的参数块来安装项目。]

-
return false;
-
-

This last part is the most important - the install function must return false so that when the link is clicked, only the script is run, and the link href is not navigated to. If you omit this step, the user may see two installation dialogs—since you've effectively invoked two install requests, one from the InstallTrigger, one from trying to load the XPI file directly.[译:最后一部分是最重要的,install函数必须返回false,这样当链接被点击时只有脚本被运行了,而并未导航到连接的地址。如果你忽略该步,使用者将看到两个安装对话框--因为你成功的调用了两次安装请求,一次来自于InstallTrigger,另一次来自于直接下载XPI文件。]

-

Available Parameters for the install object(install对象可使用的参数)

-

The InstallTrigger.install method accepts a JavaScript object as a parameter, with several properties on that object used to affect the install.[译:InstallTrigger.install 方法接收一个JavaScript对象作为参数,该参数对象中有一些属性来影响安装。]

-

URL

-

The URL property specifies the URL of the XPI to install. This property is required.[URL属性指定了将被安装的XPI文件的URL.该属性是必须的。]

-

IconURL

-

The IconURL property specifies an icon to be displayed in the installation dialog. This property is optional. If you do not specify an icon, the default icon will be used, usually a green puzzle piece. The icon can be any image format supported by Firefox, and should be 32x32 pixels in size.[译:IconURL属性指定一个显示在安装对话框上的图标。如果不指定图标,一个默认的图标就会被使用,通常是一个绿色的拼图块。图标可以是任意被Firefox支持的格式,但大小应是32x32像素的。]

-

Hash

-

The Hash property specifies a cryptographic hash of the XPI file contents. This is used to verify the downloaded file, to protect against a corrupted file being served by a mirror download server, for example. You can use any hash function supported by nsICryptoHash. The hash is specified as hash function:hash value, for example, sha1:28857e60d043447c5f4550853f2d40770b326a13.[译:Hash属性用于指定XPI文件内容的加密hash值。这被用来验证下载文件,例如,可以防止一个错误的XPI文件被放在镜像服务器上被下载。可以使用被nsICryptoHash支持的hash函数。该hash值的格式为 hash函数:hash值,例如:sha1:28857e60d043447c5f4550853f2d40770b326a13。]

-

toString()

-

The toString() property should return the XPI URL, for compatibility with Firefox browsers older than version 1.0, and other applications such as Seamonkey.[译:toString()属性应当返回XPI 的URL,主要是为了兼容早于1.0版本的浏览器和其它程序如Seamonkey。]

-

Themes

-

Pretty much everything I've described applies to themes too, except you'll use the installChrome function. Because so many sites installed extensions by direct-linking the XPI file and relying on content handling to invoke the confirmation UI, many sites are (incorrectly) doing so for theme JAR files too and wondering why they aren't auto-detected and installed. Well, XPI is a Mozilla-specific extension and so we can have special handling for it, but JAR is not - not all .jar files are Firefox themes, so if you click on a .jar link you'll be shown the Save As decision dialog. For this reason you should always use the InstallTrigger API to install themes.

-

A Note on updateEnabled()

-

InstallTrigger exposes a function called updateEnabled that some of you may be calling before you call InstallTrigger.install. This is not necessary as install calls updateEnabled itself internally. Furthermore, calling updateEnabled may lead to problems if your distribution site is not in the user's whitelist, because Firefox only displays the "Installation Blocked" message when install or installChrome are called, or when a XPI file is loaded. So, if you have code that looks like this:

-
if (InstallTrigger.updateEnabled())
-  InstallTrigger.install({"Foo": "foo.xpi"});
-
-

... and your site is not in the whitelist, when the user invokes that code, updateEnabled will return false because your site isn't whitelisted, and since it was updateEnabled that discovered this, not a call to install, there will be no notification to the user.

-

Thus you should only use updateEnabled to display content in the page to alert the user that software installation is disabled, or your site is not in the whitelist—do not place it in the install code path.

-

(* by all means don't let this stop you from developing more ambitious install systems, I am providing this documentation only as a guide that I hope most extension distributors will use since it handles most cases well)

diff --git a/files/zh-cn/archive/add-ons/jetpack_processes/index.html b/files/zh-cn/archive/add-ons/jetpack_processes/index.html deleted file mode 100644 index f03acfe8f9..0000000000 --- a/files/zh-cn/archive/add-ons/jetpack_processes/index.html +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Jetpack Processes -slug: Archive/Add-ons/Jetpack_Processes -translation_of: Archive/Add-ons/Jetpack_Processes ---- -

Jetpack processes are created by components that implement the nsIJetpackService interface, and their parent chrome process communicates with them via the nsIJetpack interface.

-
Note: The Jetpack service, provided by nsIJetpackService, is not included by default in Firefox 4. Prior to Firefox 12, it could be included in custom builds by using ENABLE_JETPACK_SERVICE at compile time. However, the service has been removed entirely as of Firefox 12.
-

These processes are relatively lightweight, do not have access to XPCOM, and can innately do little other than compute. Messaging facilities that allow them to communicate with their parent chrome process are the only means by which they can be endowed with any real power.

-
Note: The above statement is not currently true, as js-ctypes is now provided to Jetpack processes as of bug 588563. A mechanism to optionally disable this feature has been proposed in bug 614351.
-

Privileged APIs

-

When script is evaluated in a Jetpack process via a call to nsIJetpack.evalScript(), the script's global scope is endowed with the following privileged APIs:

-
sendMessage(aMessageName [, v1 [, v2 [, ...]]])
Similar to nsIJetpack.sendMessage(), this function asynchronously sends a message to the chrome process.
callMessage(aMessageName [, v1 [, v2 [, ...]]])
This function is like sendMessage() but sends the message synchronously. It returns an Array whose elements are the return values of each receiver in the chrome process that was triggered by the message.
registerReceiver(aMessageName, aReceiver)
Similar to nsIJetpack.registerReceiver(), this function registers a callback that is triggered when the chrome process sends a message with the given name.
unregisterReceiver(aMessageName, aReceiver)
Similar to nsIJetpack.unregisterReceiver(), this function unregisters a callback previously registered with registerReceiver().
unregisterReceivers(aMessageName)
Similar to nsIJetpack.unregisterReceivers(), this function unregisters all callbacks for the given message name.
createHandle()
Similar to nsIJetpack.createHandle(), this function creates a new handle and returns it.
createSandbox()
This creates a new JavaScript sandbox and returns its global scope. This global scope does not contain privileged APIs, or any non-standard JavaScript objects for that matter, though new globals can be endowed by simply attaching them to the global scope as properties.
evalInSandbox(aSandbox, aScript)
Evaluates the given script contents in the given sandbox's global scope. At minimum, JavaScript 1.8.1 is used. Individual lines of the form //@line 1 "foo.js" can be used to specify filename and line number information for debugging purposes.
gc()
Synchronously performs garbage collection.
-
-

Handles

-

Messages that communicate between the browser and jetpack process may contain only serializable (JSON) data and handles. A handle can be used to provide context for messages. Either the browser or the jetpack implementation may create one.

-

A handle keeps any arbitrary properties attached to it alive, but those properties are not transmitted across the process boundary. These arbitrary properties are the primary means through which context can be provided for messages; for instance, if the handle is meant to represent a network request, an XMLHttpRequest instance can be attached to the handle on the chrome process.

-

Because a handle's existence crosses process boundaries and cross-process garbage collection does not exist, the lifetime of a handle needs to be controlled manually by code. By default, a handle is rooted in the JavaScript interpreter's garbage collector, meaning that even if a process throws it away, it will not be garbage collected unless the other process explicitly does something to indicate that it is no longer needed. If that other process does not do something explicit and simply removes all references to it, the handle remains rooted yet unreachable in both processes and a memory leak is created.

-

To prevent such memory leaks, a process can either invalidate a handle, immediately preventing it from being passed as a message argument, or it can unroot the handle, allowing it to be passed as a message argument until all references to it are removed, at which point it is garbage collected.

-

Handles have the following native methods and properties:

-
invalidate()
Invalidates the handle. Either process may invalidate a handle when it is no longer useful.
createHandle()
Creates a child handle which becomes invalid when its parent does. This is useful for associating handles to the lifetime of a particular window, context menu, or other element, and helping ensure that they do not leak.
parent
The parent handle of the object, if any. Read-only.
isValid
Whether the handle is still valid or not. Read-only.
isRooted
Whether the handle is GC rooted or not. Read-write.
onInvalidate
A callback to call when the handle is garbage collected, either through an explicit call to invalidate() or being unrooted and then unreachable. The callback is only called from the process that the handle was not garbage collected in. Read-write.
-
-

Special Messages

-
core:process-error(context)
When the jetpack process crashes, this message is sent to the parent. If a crash report minidump is available, the context.dumpID property will list the minidump ID of the crash report that was collected.
core:exception(error)
When an exception occurs in a Jetpack script and is not caught, this message is sent to the parent. The error object contains the following properties: fileName, lineNumber, and message.
-
-

History

-

See bug 556846 and bug 578821 for details.

-

Sample Code

-

For example code, check out the unit tests.

-

See also

- diff --git a/files/zh-cn/archive/add-ons/multiple_item_packaging/index.html b/files/zh-cn/archive/add-ons/multiple_item_packaging/index.html deleted file mode 100644 index baf4f245ce..0000000000 --- a/files/zh-cn/archive/add-ons/multiple_item_packaging/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Multiple Item Package -slug: Archive/Add-ons/Multiple_Item_Packaging -tags: - - Extensions - - Toolkit API -translation_of: Archive/Add-ons/Multiple_Item_Packaging ---- -

A Multiple Item Package provides the ability to package multiple Installable Bundles which can then be downloaded and installed by a user, or provided pre-packaged with an application or by an external program. Every Multiple Item Package must provide an install.rdf file (not old-style install.js!) and has the same requirements as an Extension except as noted below.

-

There is currently no facility to prevent or warn the user when installing a previous version of an extension.

-

 

-

Multiple Item Package File Layout

-

The Multiple Item Package file layout is a simplified form of an Installable Bundle and requires a file extension of <tt>xpi</tt>. A Multiple Item Package may contain both extensions (e.g. <tt>xpi</tt> file extension) and themes (e.g. <tt>jar</tt> file extension). The basic structure is shown below:

-
/install.rdfInstall Manifest
-/extension1.xpiExtension
-/extension2.xpiExtension
-/theme1.jarTheme
-/theme2.jarTheme
-...
-
-

The Extension Manager will read the <tt>install.rdf</tt> Install Manifest to determine if this is a Multiple Item Package and then start the installation of the individual packages it contains automatically. No other files besides the install.rdf Install Manifest and the files with a <tt>jar</tt> and <tt>xpi</tt> file extension will be extracted or utilized.

-

install.rdf

-

A Multiple Item Package does not have the same requirements as an Extension for its install.rdf. The only required items are <tt>em:id</tt>, <tt>em:targetApplication</tt>, and <tt>em:type</tt>.

-

For the Firefox and Thunderbird 1.5 Extension Manager to determine that this package is a Multiple Item Package the <tt>em:type</tt> specified in your install.rdf must be <tt>32</tt> and specified as <tt><em:type NC:parseType="Integer">32</em:type></tt>. The XML namespace <tt>xmlns:NC="http://home.netscape.com/NC-rdf#"</tt> must also be declared in your install.rdf as shown below.

-
...
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:NC="http://home.netscape.com/NC-rdf#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <!-- nsIUpdateItem type for a Multiple Item Package -->
-    <em:type NC:parseType="Integer">32</em:type>
-...
-

For the Firefox and Thunderbird 2.0 Extension Manager you can use the previous syntax or <tt><em:type>32</em:type></tt> as shown below.

-
...
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <!-- nsIUpdateItem type for a Multiple Item Package -->
-    <em:type>32</em:type>
-...
-

When specifying <tt>em:targetApplication</tt> the <tt>minVersion</tt> specified should be the highest <tt>minVersion</tt> and the <tt>maxVersion</tt> specified should be the lowest <tt>maxVersion</tt> from all of the Installable Bundles contained by the Multiple Item Package for the <tt>em:targetApplication</tt>. If this is not done then any items that are not compatible will not be installed unless a compatibility check discovers updated compatibility information that makes it compatible.

-

Installation

-

Installation can be performed using any of the existing methods used for installing extensions / themes and the same user interface is used for installing a Multiple Item Package (the individual packages contained in the Multiple Item Package will not be listed). This also allows displaying of signing information for the Multiple Item Package.

-

If a manager (e.g. Extension / Theme Manager) is displayed then after the download of the Multiple Item Package completes the manager will display the individual items contained by the Multiple Item Package in the same manner that it would if the user had chosen to install multiple items simultaneously. The manager will not display the Multiple Item Package in the list of items after the download of the Multiple Item Package has completed.

-

Official References for Toolkit API

-

Official References. Do not add to this list without contacting Benjamin Smedberg. Note that this page is included from the pages listed below. So: Don't Add Breadcrumbs! -

-

diff --git a/files/zh-cn/archive/add-ons/signing_an_xpi/index.html b/files/zh-cn/archive/add-ons/signing_an_xpi/index.html deleted file mode 100644 index e017c540b7..0000000000 --- a/files/zh-cn/archive/add-ons/signing_an_xpi/index.html +++ /dev/null @@ -1,378 +0,0 @@ ---- -title: Signing a XPI -slug: Archive/Add-ons/Signing_an_XPI -translation_of: Archive/Add-ons/Signing_an_XPI ---- -
注意:这些说明已经过时了。扩展的签名工作是通过Mozilla而不是作者。请查看  签名和发布你的 add-on
- -
Note: These instructions are for how to test with a self-signed certificate. See Signing an extension for a practical guide.
- -

Introduction

- -

This article describes how to sign your own Firefox extensions with a code-signing certificate on a Windows platform. It was developed from the linux article So you want to sign your XPI package? by MozDev Group's Pete Collins.

- -

This article is a mirror of the original, with minor reformatting, some new info and all links updated in March 2010.

- -

Get network security services

- -

1. Download the latest Network Security Services (NSS) package from the Mozilla FTP site at ftp://ftp.mozilla.org/pub/mozilla.or.../nss/releases/. For Windows, you'll want the nss-3.11.4.zip package in the NSS_3_11_4_RTM/msvc6.0/WINNT5.0_OPT.OBJ/ folder - it is by 2010 the only one with the right binaries.

- -

2. Extract the contents of the archive file to a local folder. In my case it's C:\Apps\nss-3.11.4\

- -

Get Netscape Portable Runtime

- -

1. Download the latest Netscape Portable Runtime from the Mozilla FTP site: http://ftp.mozilla.org/pub/mozilla.org/nspr/releases/. For Windows you'll want the nspr-4.6.zip package in the v4.6/WINNT5.0_OPT.OBJ/ folder.

- -

2. Extract the contents of the archive file to a local folder. In my case it's C:\Apps\nspr-4.6\

- -

Add path

- -

Add the NSS tools bin/ and lib/, and the NSPR lib/ directories to the system path. You can either set this permanently via Control Panel->System Properties->Advanced->Environment Variables->System Variables or do it each time you run the tools from the command-line (preferably using a batch file). Windows contains its own version of some of these files (e.g. certutil.exe) in the system directory (\Windows\system32\) so ensure the new paths are first in the PATH search list.

- -
C:\> set PATH=C:\Apps\nss-3.11.4\bin\;C:\Apps\nss-3.11.4\lib\;C:\Apps\nspr-4.6\lib\;%PATH%
-
- -

An easier way is to copy everything from your new directories C:\Apps\nss-3.11.4\ and C:\Apps\nspr-4.6\ including sub directories to the same directory - fx C:\Apps\CodeSigning\ - and then run every command from that.

- -

Initialize the certificate database

- -

Decide which folder to create the certificate database in. Use this command to create it (note the trailing dot is required).

- -
C:\Projects\CodeSigning\> certutil -N -d .
-
- -

The dot will cause the database to be created in the current directory.

- -

You will be prompted for the NSS Certificate database password - don't forget it!

- -
C:\Projects\CodeSigning\> certutil -N -d .
-Enter a password which will be used to encrypt your keys.
-The password should be at least 8 characters long,
-and should contain at least one non-alphabetic character.
-
-Enter new password:
-Re-enter password:
-
- -

Create a test certificate

- -

Create a test certificate, using the -p option to set a password for the new certificate

- -
C:\Projects\CodeSigning\> signtool -G myTestCert -d . -p"password"
-using certificate directory: .
-
-WARNING: Performing this operation while the browser is running could cause
-corruption of your security databases. If the browser is currently running,
-you should exit the browser before continuing this operation. Enter
-"y" to continue, or anything else to abort: y
-
-
-Enter certificate information.  All fields are optional. Acceptable
-characters are numbers, letters, spaces, and apostrophes.
-certificate common name: XPI Test
-organization: TJworld
-organization unit: Software
-state or province: Nottingham
-country (must be exactly 2 characters): GB
-username: tj
-email address: certificates@lan.tjworld.net
-generated public/private key pair
-certificate request generated
-certificate has been signed
-certificate "myTestCert" added to database
-Exported certificate to x509.raw and x509.cacert.
-
- -

x509.cacert will be used to sign your XPI package. Check that it exists on the file system and in the certificate database:

- -
C:\Projects\CodeSigning\> dir x509*
-
-14/12/2005  15:13             1,031 x509.cacert
-14/12/2005  15:13               798 x509.raw
-
-C:\Projects\CodeSigning\> certutil -d . -L
-myTestCert                                                   u,u,Cu
-
- -

Prepare XPI file for signing

- -

Create a new folder just for signing, copy your existing XPI into it, unzip* it (maintaining paths), delete the XPI and return to the certificate-database folder.

- -

*Assumes you have a zip utility available on your system path. This example is using the CygWin bin/zip.exe tool. You can use a graphical Zip tool provided it manages the internal sub-directory structure properly. An alternative is to use WinRar.

- -
The 7-Zip tool doesn't work when creating Mozilla XPI signed archives because it sorts the directory entries alphabetically, and Mozilla requires the first entry to be META-INF/zigbert.rsa.
- -
C:\Projects\CodeSigning\> md signed
-
-C:\Projects\CodeSigning\> copy C:\Projects\fsb\fsb.xpi signed
-        1 file(s) copied.
-
-C:\Projects\CodeSigning\> cd signed
-
-C:\Projects\CodeSigning\signed> unzip fsb.xpi
-Archive:  fsb.xpi
-   creating: chrome/
-  inflating: chrome.manifest
-  inflating: chrome/fsb.jar
-  inflating: install.rdf
-
-C:\Projects\CodeSigning\signed> del fsb.xpi
-
-C:\Projects\CodeSigning\signed> cd ..
-
- -

Sign XPI

- -
C:\Projects\CodeSigning\> signtool -d . -k myTestCert -p "password" signed/
-using certificate directory: .
-Generating signed//META-INF/manifest.mf file..
---> chrome/fsb.jar
---> chrome.manifest
---> install.rdf
-Generating zigbert.sf file..
-tree "signed/" signed successfully
-
- -

Re-package XPI

- -

Change to the signed/ folder, create a new zip with the META-INF/zigbert.rsa file listed first, then add the remaining files.

- -
C:\Projects\Certs\> cd signed
-
-C:\Projects\CodeSigning\signed\> zip fsb.xpi META-INF/zigbert.rsa
-  adding: META-INF/zigbert.rsa (deflated 35%)
-
-C:\Projects\CodeSigning\signed> zip -r -D fsb.xpi * -x META-INF/zigbert.rsa
-  adding: META-INF/manifest.mf (deflated 37%)
-  adding: META-INF/zigbert.sf (deflated 40%)
-  adding: chrome/fsb.jar (deflated 74%)
-  adding: chrome.manifest (deflated 69%)
-  adding: install.rdf (deflated 62%)
-
- -

Test your certificate

- -

To test your certificate, install it into your browser, and attempt to load the signed extension by following these steps:

- -

1. Temporarily install the Test Certificate Authority into your Mozilla browser

- -

Rename the x509.cacert file generated earlier to x509.cert

- -

Import it into Mozilla Firefox as a Software Developer Certificate Authority.

- -
Don't forget to delete the certificate from Mozilla Firefox once you've finished testing
- -

Firefox 1.5: From the Tools menu choose Options->Advanced->Security->View Certificates->Authorities

- -

Firefox 1.0: From the Tools menu choose Options->Advanced->Certificates->Manage Certificates->Authorities

- -

Press the Import button.

- -

Navigate to the folder containing x509.cert and choose it.

- -

In the Downloading Certificate dialog, tick Trust this CA to identify software developers. and press the View button if you wish to examine the certificate more closely.

- -

Press the OK button and you'll see your new certificate in the list of Authorities.

- -

2. Attempt to install the signed extension

- -

Either drag and drop or browse to and download the signed XPI. When the Mozilla Firefox Software Installation dialog appears the organisation name of the certificate will appear where Firefox usually displays unsigned.

- -

image

- -

Obtaining a valid software developer code-signing certificate

- -

 

- -
Warning: Currently Firefox expects XPI files to be signed with certificates that conform to the older Object Signing convention, rather than the newer Code Signing convention. This means that Firefox will refuse to install code signed via an intermediate certificate authority such as Certum Level I unless the user installs that intermediate CA certificate into Firefox first. Installing the intermediate CA certificate causes Firefox to mark the intermediate Code Signing CA certificate as a valid Object Signing CA certificate, which makes it all work. bug 321156 has been filed to request a way to obviate the installation of intermediate Code Signing CA certs into Firefox.
- -

Now you know it all works, you need to add a real software developer's certificate to the NSS certificate database, and use that to sign the XPI. There are several issuers of software developer certificates, with the three key differentials: availability, cost and identity verification.

- -

Many issuers will not provide a software developer certificate to individuals (how ridiculous) so you may have to search hard to find one that will, and who also has a CA root Authority installed in Mozilla Firefox. Without the certificate-issuers CA root certificate Mozilla Firefox will not confirm the validity of your certificate to users who want to install your extension. Ideally you want a certificate that has a root CA installed in all major platforms (Microsoft Windows, Sun Java, Mozilla/Netscape Firefox/Navigator, Opera) so you only use one certificate for signing all your software, no matter which platform it is for.

- -

The cheapest universally supported (Mozilla, Java, Microsoft) certificate seems to be the Comodo Instant-SSL offering. You can get a free certificate for open-source developers from Unizeto Certum, in 2010 it is a Certum Level III CA.

- -

Here are some current issuers:

- - - -

You will need to apply for a Code Signing Certificate and satisfy the Issuer's identity verification procedures. They will then issue a signed certificate. When you receive the signed certificate it must be imported into the certificate database.

- -
Your browser will generate a new private key and Code Signing Request (CSR) in the background without you necessarily realising it. The CSR will be uploaded to the Issuer. Later, you must use the same browser when installing the new certificate because the key and certificate pair must be together.
- -

Hint: When applying for a certificate ensure that the Organisation (O) contains your name and not the Issuer's default text, because this is what is displayed to users.

- -

For this guide I applied for a free certificate from Unizeto Certum. After completing the application process where I entered my details into the online application, I received an automated email requesting documentary evidence of my ID in the form of a photo-ID or similar. I have hi-resolution scanned images of my passport and drivers license for these situations so I placed them on my web-server temporarily in a hidden location and emailed Unizeto Certum with the details and location of the files. Within a few hours I received a confirmation email from a human accepting the ID images and giving me a hyperlink to the certifcate download area.

- -

Install the certificate into Mozilla Firefox (which goes with the private key created earlier), and copy/paste the displayed certificate text into a new file called C:\Projects\CodeSigning\Certum Code Signing.cer.

- -

Installing real certificate

- -

There are two steps required to install the new certificate in the Code Signing NSS certificate database.

- -
 1. Install the Issuer's Certificate Authority Root
- 2. Install your key and certificate
-
- -

The root CA establishes the trust of your certificate. Many issuer's have multiple root CAs for different levels of trust. find out which one was used for your certificate and download it. You can view the details of your certificate in Mozilla Firefox and get this information from the Issued By Common Name (Unizeto Certum's free certificate CA is Certum Level III CA).

- -

Download the Root CA and any intermediate certificates used to sign your certificate from the Issuer; their web site will have a link somewhere to their root CAs and public certificates. (Certum public key page). I downloaded the Certum Root CA and Certum Level III CA Digital ID for web and SSL/TLS Servers, copied the text and saved them to the files C:\Projects\CodeSigning\Certum Root CA.cer and C:\Projects\CodeSigning\Certum Level III CA.cer.

- -

Open a command prompt (ensure the paths to the NSS tools are set as described above) in the CodeSigning folder, install the Issuer CA certificates, and check they have been added correctly.

- -
C:\Projects\CodeSigning> certutil -A -n "Certum Root CA" -t "TC,TC,TC" -d . -i "Certum Root CA.cer"
-
-C:\Projects\CodeSigning> certutil -A -n "Certum Level III CA" -t "c,c,C" -d . -i "Certum Level III CA.cer"
-
-C:\Projects\CodeSigning> certutil -L -d .
-myTestCert                                                   u,u,Cu
-Certum Root CA                                               CT,C,C
-Certum Level III CA                                          CT,C,C
-
- -

The name given to the newly issued certificate in the Mozilla Firefox keystore is not the easiest key alias in the world to remember, so I've added an additional step here that lets you rename it (its not just a simple rename operation, unfortunately).

- -

To find the name, in Mozilla Firefox navigate to the Certificate Manager (described in Step 11), choose Your Certificates, select the new certificate, press View, choose Details and look at the first entry in the Certificate Fields tree-view.

- -

My Unizeto Certum certificate is named "TJ's Unizeto Sp. z o.o. ID" but I want it to be called "Code Signing (Certum)".

- -

The trick is to install the certificate (without the key) first and give your chosen nickname at that point. When the key/certificate pair is imported from Mozilla Firefox afterwards, the private key will be added but the certificate name will remain the same.

- -
C:\Projects\CodeSigning> certutil -A -n "Code Signing (Certum)" -t "u,u,u" -d . -i "Certum Code Signing.cer"
-
-C:\Projects\CodeSigning> certutil -L -d .
-myTestCert                                                   u,u,Cu
-Certum Root CA                                               CT,C,C
-Certum Level III CA                                          CT,C,C
-Code Signing (Certum)                                        ,,
-
-C:\Projects\CodeSigning> signtool -l -d .
-using certificate directory: .
-
-Object signing certificates
----------------------------------------
-myTestCert
-    Issued by: myTestCert (XPI Test)
-    Expires: Tue Mar 14, 2006
-Code Signing (Certum)
-    Issued by: Certum Level III CA (Certum Level III CA)
-    Expires: Tue Mar 14, 2006
----------------------------------------
-For a list including CA's, use "signtool -L"
-
- -

Now you must export the new key/certificate pair from the Mozilla Firefox certificate database and into the NSS certificate database.

- -

The hardest part is locating Mozilla's key database. It consists of two files named key3.db and cert8.db. They usually live in the Mozilla Firefox user profile folder. I found mine in C:\Documents and Settings\TJ\Application Data\Mozilla\Firefox\Profiles\xxxxxxxx.default\ where xxxxxxxx is a random string of characters.

- -
This procedure assumes you installed the new certificate into Mozilla Firefox
- -

Here's the commands required to export it to a file, import it to the Code Signing database, and verify the signing attributes (u,u,u). Ensure you use the nickname of your certificate in place of mine, and the directory where your Mozilla Firefox key database files are:

- -
C:\Projects\CodeSigning> pk12util -o "Certum Code Signing.pkcs12" -n "TJ's Unizeto Sp. z o.o. ID" -d "C:\Documents and Settings\TJ\Application Data\Mozilla\Firefox\Profiles\xxxxxxxx.default"
-Enter password for PKCS12 file:
-Re-enter password:
-pk12util: PKCS12 EXPORT SUCCESSFUL
-
-C:\Projects\CodeSigning> pk12util -i "Certum Code Signing.pkcs12" -d .
-Enter Password or Pin for "NSS Certificate DB":
-Enter password for PKCS12 file:
-pk12util: PKCS12 IMPORT SUCCESSFUL
-
-C:\Projects\CodeSigning> certutil -L -d .
-myTestCert                                                   u,u,Cu
-Certum Root CA                                               CT,C,C
-Certum Level III CA                                          c,c,C
-Code Signing (Certum)                                        u,u,u
-
- -

You should notice that the existing certificate has been updated.

- -

Sign extension with real certificate

- -

This is a repeat of the earlier steps using the real certificate's details. Here's the output on a test directory:

- -
C:\Projects\CodeSigning>signtool -d . -k "Code Signing (Certum)" -p ******* test
-using certificate directory: .
-Generating test/META-INF/manifest.mf file..
---> test.txt
-Generating zigbert.sf file..
-tree "test" signed successfully
- -

Incorporating signing into your build process

- -

You may want to incorporate these steps into your existing build process. I have a build.bat file that automates the creation of the jar and xpi files. This example is using the CygWin bin/zip.exe tool.

- -

build.bat is placed in the extension's root folder. E.g.

- -

/dev/fsb/build.bat /dev/fsb/install.rdf /dev/fsb/chrome.manifest /dev/fsb/chrome/ /dev/fsb/chrome/content/ /dev/fsb/chrome/locale/ /dev/fsb/chrome/skin/

- -

Here it is with the code-signing steps included:

- -

 

- -
@echo off
-set x=%cd%
-
-echo Building %x%.xpi ...
-echo Started at %DATE% %TIME% > %x%\build.log
-
-md build\chrome
-
-cd chrome
-
-zip  -r -0 "%x%.jar" * >> %x%\build.log
-
-move "%x%.jar" ..\build\chrome >> %x%\build.log
-
-cd ..
-
-copy install.rdf build >> %x%\build.log
-
-copy chrome.manifest build >>%x%\build.log
-
-signtool.exe -d C:\Projects\CodeSigning -k "Code Signing (Certum)" -p "password" build/ >> %x%\build.log
-
-cd build
-
-zip "%x%.xpi" META-INF/zigbert.rsa >> %x%\build.log
-
-zip -r -D "%x%.xpi" * -x META-INF/zigbert.rsa >> %x%\build.log
-
-rem copy "%x%.xpi" ..\..\..\http\fsb.xpi >> %x%\build.log
-
-move "%x%.xpi" ..\ >> %x%\build.log
-
-cd ..
-
-rd build /s/q
-
-echo Done.
- -

Make sure to replace password with your NSS Certificate database password.

- -

Alternatives to NSS/signtool

- -

There are several alternatives to using signtool that might suit your needs better, however please note that these alternatives are unofficial third party products.

- - - -

References

- - - -

diff --git a/files/zh-cn/archive/apps/advanced_topics/index.html b/files/zh-cn/archive/apps/advanced_topics/index.html deleted file mode 100644 index 33d3c00fa5..0000000000 --- a/files/zh-cn/archive/apps/advanced_topics/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Advanced topics -slug: Archive/Apps/Advanced_topics -tags: - - 应用 - - 火狐OS - - 移动 -translation_of: Archive/Apps/Advanced_topics ---- -

这篇文章提供了关于高级开放网络应用话题的额外信息。

- -
-
-

应用构建文档

- -
-
网络应用构建
-
网络应用设计与实践背后的构建过程概览。
-
特定平台的应用安装细节
-
在不同的支持开放网络应用的平台上,应用的安装存在细节上的不同, 这篇文章将帮助你理解它们。
-
针对安卓的开放网络应用
-
关于在安卓设备上安装并测试开放网络应用的信息。
-
应用运行时的发行说明
-
针对不同平台的应用运行时发行说明。
-
- -

其它文档

- -
-
创建你自己的市场
-
如果你希望自己构建一个用于销售和分发开放网络应用的市场,这篇文章里面的信息可能对你有帮助。
-
- -

查看所有...

-
- -
-

面向应用开发者的工具
- -
技术参考文档
- -
从社区获取帮助
-

如果您还不确定该做的事,欢迎随时加入讨论。

- -

别忘记网络礼仪...

-
-
- -

 

diff --git a/files/zh-cn/archive/apps/icon_implementation_for_apps/index.html b/files/zh-cn/archive/apps/icon_implementation_for_apps/index.html deleted file mode 100644 index 2d15366474..0000000000 --- a/files/zh-cn/archive/apps/icon_implementation_for_apps/index.html +++ /dev/null @@ -1,178 +0,0 @@ ---- -title: 应用程序图标的实现 -slug: Archive/Apps/Icon_implementation_for_apps -translation_of: Archive/Apps/Icon_implementation_for_apps ---- -
-
-
-

在不同的平台上实现应用程序的图标是一种痛苦,这甚至是没有考虑设计的图标和图形。不同的平台有不同的应用方式和大小,所以你需要有很多要考虑,如果你想让你的应用支持多个平台。本文提供了有用的提示,用来实现应用程序的图标,包括不同的大小和不同的平台(如:浏览器的操作系统),以及实施细节。我们不会提供图标图形设计信息,但我们将为每个平台链接到合适的资源。

-
-
-
- -

Web应用程序的通用图标

- -

TBD

- -

Firefox OS

- -

谋智的Firefox OS  平台是一个最简单的从图标的支持。这部分从细节上解释了为什么这些大小是需要的,并提供了一个表来表明具体图标大小与相关发布的手机出货量。

- -
-

Note: For more information on the actual design of Firefox OS icons, read the Firefox OS app icon design guidelines. They can be square or round, as stated in the guidelines.

-
- -

Icon format

- -

Firefox OS icons need to be in PNG format.

- -

Icon sizes

- -

Required icon sizes

- -
-
128 x 128
-
For display on the Firefox Marketplace and device.
-
- - - -
-
128 x 128
-
For display on the Firefox Marketplace and pre-Firefox OS 2.0 devices.
-
512 x 512
-
From Firefox 2.0 onwards, larger icons are needed for crisp display on all the different possible combinations of Phone and tablet screen sizes, screen resolutions, and 3 and 4-column layouts. We accept a 512 x 512 icon, which is then scaled for all the different uses across devices. This size is also useful for display on other platforms apps can be installed across, such as Android.
-
- -

Other icon sizes that might be useful

- -
-
60 x 60
-
For the exact on-device icon size on older Firefox OS versions.
-
16 x 16, 32 x 32, 48 x 48, 64 x 64, 90 x 90, 128 x 128 and 256 x 256
-
These icon sizes are used on various other platforms your app can be installed on, such as Windows, Mac OS X and Android.
-
- -

Icon size explanations

- -

512 icon for device display

- -

For older Firefox OS device (pre-2.0), the recommendation was a 60 x 60 icon, to use on the homescreen of your device. It was simple back then, as the devices generally had a similar screen size and resolution, and the layout didn't vary much. However, more recently, a number of factors have proven this to be less than ideal:

- - - -

These factors resulted in icons started to look pixelated on some devices. The Firefox OS UX team considered many different options to resolve this, including SVG icons, multiple device icon requirements, and a number of different single icon sizes, but in the end the best solution was a single 512 x 512 icon that can be resized as needed for different uses across devices. This is the best solution:

- - - -

With the 2.0 homescreen design, we wanted to move to larger app icons as one of the tenets of the 2.0 visual refresh is to make things feel more spacious and comfortable to use. As such, we decided to ship a 3 column, large icon version of the homescreen, but still provide users with an option to switch back to the 4 column, small icon layout from Settings.

- -

The icon sizes starting with the 2.0 release across different devices are as follows:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Icon sizes across Firefox OS devices from 2.0 onwards
Device namePhysical screen specificationsScreen resolutionScale factorLarge (3 column homescreen) icon sizeSmall (4 column homescreen) icon size
Most in-market devices320x480   HVGA  3.5”165ppi1x84px64px
Helix (Huawei) or ZTE Open C480x800   WVGA  4.0”233ppi1.5x126px96px
Flame reference device480x854   FWVGA 4.5”218ppi1.5x126px96px
4.5" @ qHD540x960   qHD   4.5”245ppi2x142px108px
4.7" @ 720p720x1280  720p  4.7”312ppi2.25x189px144px
5.0" @ 1080p1080x1920 1080p 5”440ppi3.375x284px216px
- -

For the 320 x 480 screen, the base sizes of 84 x 84 for 3 column mode, and 64 x 64 for 4 column mode were chosen to maximize icon size while balancing the icon density and wallpaper visibility needs. Icon sizes for all other screens are calculated by multiplying by the relevant scale factor.  For example, on Flame it is 1.5 (scale factor) x 84 = 126 (large icons) and 1.5 (scale factor) x 64 = 96 (small icons).

- -

128 icon for marketplace

- -

The Firefox Marketplace still requires a 128 x 128 icon, for display on app marketplace listing pages.

- -

Including the icon in your app

- -

You specify the path to the icons in the icon field of the app manifest, and multiple icons can be pointed to like this:

- -
"icons": {
- "512": "/img/icon-512.png",
- "128": "/img/icon-128.png"
-}
- -

You can also use a 64 bit encoded Data URI directly in the manifest file to provide the icon and cut down on HTTP requests:

- -
"icons": {
- "512": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC ... "
-}
- -

We have cut the above example down for the sake of brevity.

- -

Adding more specific icon sizes

- -

Note that you don't need to just include 512 x 512 and 128 x 128 with your app: you can happily include further specific icon sizes if you want to provide a tailored look for each different required size — you can simply include more icon lines in the manifest icon field shown above.

- -

Icons in other app ecosystems

- -

Android, iOS, Windows, Tizen, etc.

- -

It would be good to cover icon requirements for different ecosystems.

- -

 

diff --git a/files/zh-cn/archive/apps/index.html b/files/zh-cn/archive/apps/index.html deleted file mode 100644 index c1517d6372..0000000000 --- a/files/zh-cn/archive/apps/index.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Apps -slug: Archive/Apps -tags: - - Apps - - Firefox OS - - NeedsTranslation - - TopicStub - - Web -translation_of: Archive/Apps ---- -

This page includes archived content for Apps, including obsolete web app content, Firefox OS app-related content, etc.

- -

Tools and frameworks

diff --git a/files/zh-cn/archive/apps/tools_and_frameworks/app_templates/index.html b/files/zh-cn/archive/apps/tools_and_frameworks/app_templates/index.html deleted file mode 100644 index 742f6c19ae..0000000000 --- a/files/zh-cn/archive/apps/tools_and_frameworks/app_templates/index.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: 使用应用程式模板 -slug: Archive/Apps/Tools_and_frameworks/App_templates -tags: - - 使用应用程式模板 -translation_of: Archive/Apps/Tools_and_frameworks/App_templates ---- -
-

为了帮助您快速开始编写Web应用程序,我们提供了一些已经设置好的模板。 每个模板都是一个静态Web项目,其中包含有助于构建和部署的工具。

-
- -

What you get:

- - - -

You can view all of the available templates in the mortar repo. The following are available:

- - - -

Starting with the App Stub Template

- -

You could simply use git to get the template from this repo:

- -
git clone https://github.com/mozilla/mortar-app-stub.git myapp
- -

Using volo is recommended, however. volo is a tool for automating projects, and you'll be able to use it with good effect with this template, so go ahead and install it. You first need node.js, which you can download from here. Once you have node, install volo (you might need to prefix the command with sudo if it fails due to insufficient permissions):

- -
npm install -g volo
-
- -

Now you can just use the volo create command, followed a name for the folder you want your app created in, then mozilla/ followed by the name of the mortar template you want to use:

- -
volo create myapp mozilla/mortar-app-stub
- -

When future templates are available, you can use the same create command with different template URLs.

- -

What Now?

- -

All your HTML, CSS, and JavaScript are under the www directory, so start coding! You'll see a bunch of stuff in there, but feel free to remove anything you don't need.

- -

The template uses require.js to manage JavaScript. If you look in www/js/app.js you'll see that it defines the main module and loads a few libraries like zepto. The Marketplace JavaScript library is also included, which enables in-app payments and receipt verification. You don't need this if you're a free app without in-app payments.

- -

Below that, you'll see the line:

- -
define(function(require) {
- -

That defines the main module for your app, and you should start coding within the function. You can use require to load in other modules, the same way zepto is loaded. Check out the require.js API to learn more about modules.

- -
-

Note: By default, modules are loaded from www/js/lib. If you want to load something from www/js, which is your working directory, use the syntax require('./mylib') instead of just require('mylib')

-
- -

You can edit CSS in www/css/app.css. Typically you should @import additional CSS files at the top of this file instead of using the <link> tag to include them. This allows the volo optimizer to inline all the CSS when building for deploying.

- -

Finally, volo provides several helpful commands that you can use:

- -
$ volo serve         # Fire up a local development server
-$ volo add <library> # Add the JavaScript library
-$ volo build         # Build an optimized version of the app into www-built
-$ volo ghdeploy      # Deploy the built version to github (need to build first)
-
- -

All of these must be run at the root of your project. There are a few other commands and you can view the full list by simply typing volo.

- -
-

Note: volo itself only has a few built-in commands. The app template provides the serve, build, ghdeploy, and other commands.

-
- -

Tutorial

- -

For more information about this template, see the Weather App Tutorial which shows you step-by-step how to build a weather app with this template. It dives into the volo commands more specifically and explains the template in more detail.

diff --git a/files/zh-cn/archive/apps/tools_and_frameworks/index.html b/files/zh-cn/archive/apps/tools_and_frameworks/index.html deleted file mode 100644 index 49231f75ef..0000000000 --- a/files/zh-cn/archive/apps/tools_and_frameworks/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Tools and frameworks -slug: Archive/Apps/Tools_and_frameworks -tags: - - Apps - - Firefox OS - - Frameworks - - Libraries - - NeedsTranslation - - Tools - - TopicStub - - Workflows -translation_of: Archive/Apps/Tools_and_frameworks ---- -
-

This part of the App Center provides guides to using tools, frameworks and libraries to speed up Open Web App development — Brick, app templates, X-Tag, and Firefox OS Cordova support.

-
- -
-
-

Components and templates

- -
-
Web components and Mozilla Brick
-
Mozilla Brick is a Web component library, based on the X-Tag library, which allows easy usage of custom elements.
-
Using app templates
-
To help you get going with app development as quickly as possible, there are some template apps you can use as a basis for your own apps. This guide provides information on those templates, how to get them, and how to work with them.
-
X-Tag
-
X-Tag and the Web components specification family provide a means for us to define custom elements that will dealt with as first class citizens by the browser, rather than as an inefficient afterthought. This guide explains how they work.
-
Custom elements
-
This article describes some of the most useful custom elements available inside Mozilla's X-Tag library.
-
-
- -
-

Cross-platform apps and build tools

- -
-
Cordova support for Firefox OS
-
This article provides a basic introduction to Apache Cordova and explains how to use it to generate an Open Web App for installation on Firefox OS.
-
Cordova Firefox OS plugin reference
-
Reference showing sample code and examples for the Cordova plugins that currently support Firefox OS.
-
-
-
- -

 

diff --git a/files/zh-cn/archive/b2g_os/api/alarm_api/index.html b/files/zh-cn/archive/b2g_os/api/alarm_api/index.html deleted file mode 100644 index bc686238e2..0000000000 --- a/files/zh-cn/archive/b2g_os/api/alarm_api/index.html +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: Alarm API -slug: Archive/B2G_OS/API/Alarm_API -tags: - - API - - Firefox OS - - 警报 -translation_of: Archive/B2G_OS/API/Alarm_API ---- -

{{DefaultAPISidebar("Alarm API")}}{{Non-standard_Header}}

- -

Alarm API允许应用程序设定将来运行的操作。例如,一些应用程序(如闹钟、日历或自动更新)可能需要使用Alarm API在指定的时间点触发特定的设备行为。

- -

Alarm API本身只允许调度警报。Alarm 通过系统消息API发送到应用程序,因此希望对警报作出响应的应用程序必须将自己注册到Alarm 消息中。

- -

Alarm 使用 {{DOMxRef("Navigator.mozAlarms")}}对象设置,该对象是{{DOMxRef("MozAlarmsManager")}}接口的一个实例。

- -
-

注: 这里的‘“闹钟 ”(Alarm API)并不同于闹铃App。Alarm API 唤醒应用程序, 闹钟叫醒人. 闹钟 使用 Alarm API 设置通知,用来在正确的时间叫醒人。(译者注:疑问脸)

-
- -

设置闹铃

- -

使用闹铃时要做的第一件事是设置闹铃。根据时区的不同,有两种警报。在这两种情况下,它都是使用{{DOMxRef("MozAlarmsManager.add()")}}方法完成的。

- -
-

Note: 如果警报不是针对特定应用程序的,系统会将所有警报发送给所有监听警报的应用程序。

-
- -
-

Note: 您需要使用相同的URL来设置和接收警报。例如,如果在foo.html或index.html?foo=bar上调用navigator.mozAlarms.add(),但在清单消息字段中有{ "alarm": "/index.html" },您将永远不会收到警报。

-
- -

Alarms 忽略时区

- -

这类警报是根据设备的本地时间发出的。如果设备用户更改了时区,将根据新的时区发出警报。例如,如果用户在巴黎,设置了一个应该在CET(中欧时间)下午12点发出的警报,而该用户前往旧金山,那么该警报将在PDT(太平洋夏令时)下午12点发出。

- -
// 设定闹钟的日期
-var myDate  = new Date("May 15, 2012 16:20:00");
-
-// 传递给警报的任意数据
-var data    = {
-  foo: "bar"
-}
-
-// 使警报忽略"ignoreTimezone"
-var request = navigator.mozAlarms.add(myDate, "ignoreTimezone", data);
-
-request.onsuccess = function () {
-  console.log("The alarm has been scheduled");
-};
-
-request.onerror = function () {
-  console.log("An error occurred: " + this.error.name);
-};
- -

时区警报

- -

这些类型的警报是根据定义警报计划时间的时区中的时间发出的。如果由于某种原因,设备的用户更改了时区,将根据原始时区发出警报。例如,如果用户在巴黎,并设置一个闹钟,该闹钟应该在CET(中欧时间)下午12点发出,如果该用户前往旧金山,该闹钟将在太平洋夏令时凌晨3点发出。

- -
// This the date to schedule the alarm
-var myDate  = new Date("May 15, 2012 16:20:00");
-
-// This is arbitrary data pass to the alarm
-var data    = {
-  foo: "bar"
-}
-
-// The "honorTimezone" string is what make the alarm honoring it
-var request = navigator.mozAlarms.add(myDate, "honorTimezone", data);
-
-request.onsuccess = function () {
-  console.log("The alarm has been scheduled");
-};
-
-request.onerror = function () {
-  console.log("An error occurred: " + this.error.name);
-};
- -

管理警报

- -

 

- -

设定警报后,仍然可以管理它。

- -

方法将返回应用程序当前调度的警报的完整列表。这个列表是一个{{anch("mozAlarm")}}对象数组。

- -

 

- -

 

- -

mozAlarm

- -

 

- -

匿名JavaScript对象,具有以下属性:

- -

 

- -

id

- -

表示警报id

- -

date

- -

表示警报的预定时间的日期对象

- -

respectTimezone

- -

一个字符串,指示警报是否必须尊重或忽略date对象的时区信息。它的值可以是ignoreTimezonehonorTimezone

- -

data

- -

一个JavaScript对象,包含警报存储的所有数据

- -

 

- -
var request = navigator.mozAlarms.getAll();
-
-request.onsuccess = function () {
-  this.result.forEach(function (alarm) {
-    console.log('Id: ' + alarm.id);
-    console.log('date: ' + alarm.date);
-    console.log('respectTimezone: ' + alarm.respectTimezone);
-    console.log('data: ' + JSON.stringify(alarm.data));
-  });
-};
-
-request.onerror = function () {
-  console.log("An error occurred: " + this.error.name);
-};
- -

{{DOMxRef("MozAlarmsManager.remove")}} 用于取消现有警报的调度。

- -
var alarmId;
-
-// Set an alarm and store it's id
-var request = navigator.mozAlarms.add(new Date("May 15, 2012 16:20:00"), "honorTimezone");
-
-request.onsuccess = function () {
-  alarmId = this.result;
-}
-
-// ...
-
-// Later on, removing the alarm if it exists
-if (alarmId) {
-  navigator.mozAlarms.remove(alarmId);
-}
- -

处理警报

- -

 

- -

当系统发出警报时,任何应用程序都可以作出反应。为了能够处理任何警报,应用程序必须将自己注册为警报处理程序。这是通过系统消息API分两个步骤完成的:

- -

首先,应用程序必须将alarm包含到其应用程序清单的messages属性中,并提供到文档的URL,文档注册在发出警报时使用的回调函数。

- -
"messages": [
-  { "alarm": "/index.html" }
-]
- -

其次,应用程序必须将回调函数与警报消息绑定。这是使用{{DOMxRef("Navigator.mozSetMessageHandler()")}}方法完成的。这个回调函数将接收一个{{Anch("mozAlarm")}}对象,其中包含附加到警报的数据。

- -
navigator.mozSetMessageHandler("alarm", function (mozAlarm) {
-  alert("alarm fired: " + JSON.stringify(mozAlarm.data));
-});
- -

如果应用程序想知道系统级别上是否存在挂起的警报,可以使用下面的方法。

- -
navigator.mozHasPendingMessage("alarm"); 
- -

权限 Alarm API

- -

请注意,虽然警报API没有特权或认证,但您仍然应该在清单中包含权限消息条目。当包含在可安装的打开的Web应用程序中的manifest.webapp文件。

- -
{
-  "permissions": {
-    "alarms": {
-      "description": "Required to schedule alarms"
-    }
-  },
-  "messages": [
-    { "alarm": "/index.html" }
-  ]
-}
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("Alarm API")}}{{Spec2("Alarm API")}}Initial specification.
- -

浏览器兼容性

- -

Supported in Firefox OS 1.0.1.

- -

另请参阅

- - diff --git a/files/zh-cn/archive/b2g_os/api/bluetoothstatuschangedevent/index.html b/files/zh-cn/archive/b2g_os/api/bluetoothstatuschangedevent/index.html deleted file mode 100644 index 8003a4414b..0000000000 --- a/files/zh-cn/archive/b2g_os/api/bluetoothstatuschangedevent/index.html +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: 蓝牙状态更改事件 -slug: Archive/B2G_OS/API/BluetoothStatusChangedEvent -translation_of: Archive/B2G_OS/API/BluetoothStatusChangedEvent ---- -

概要

- -

BluetoothStatusChangedEvent API可以访问有关蓝牙设备状态的任何更改的信息。

- -

当触发以下某个事件时,会发生状态更改:

- - - -

接口概述

- -
interface BluetoothStatusChangedEvent: Event
-{
-  readonly attribute DOMString address;
-  readonly attribute boolean status;
-};
- -

属性

- -
-
{{domxref("BluetoothStatusChangedEvent.address")}} {{readonlyinline}}
-
表示蓝牙微网中状态发生变化的设备地址的字符串。.
-
{{domxref("BluetoothStatusChangedEvent.status")}} {{readonlyinline}}
-
表示连接当前状态的布尔值。它可以被启用(true)或禁用(false)。
-
-
- -

方法

- -

目前没有。

- -

规范

- -

还不是任何规范的一部分。它应该作为W3C's System Applications Working Group的一部分进行讨论。

- -

也可以看看

- - diff --git a/files/zh-cn/archive/b2g_os/api/domrequest/index.html b/files/zh-cn/archive/b2g_os/api/domrequest/index.html deleted file mode 100644 index 0f4502fac7..0000000000 --- a/files/zh-cn/archive/b2g_os/api/domrequest/index.html +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: DOMRequest -slug: Archive/B2G_OS/API/DOMRequest -tags: - - API - - DOM - - 回调 -translation_of: Archive/B2G_OS/API/DOMRequest ---- -
- -

DOMRequest对象表示正在进行的操作。 它提供在操作完成时调用的回调,以及对操作结果的引用。 启动一个进行中的操作,DOM方法会返回一个DOMRequest对象,您可以使用该对象来监视该操作的进度。

- -

Note: 此特性在 Web Worker 中可用。

- -

属性

- -
-
DOMRequest.onsuccess
-
当由DOMRequest表示的操作完成时调用的回调处理程序。
-
DOMRequest.onerror
-
当处理操作发生错误时调用的回调处理程序。
-
DOMRequest.readyState
-
表示操作是否已完成运行的字符串。 其值为“done”或“pending”。
-
DOMRequest.result
-
操作的结果。
-
DOMRequest.error
-
错误信息(如果有)。
-
- -

方法

- -

无.

- -

例子

- -

使用DOMRequest对象的onsuccess,onerror,result和error属性的一个示例。

- -
var pending = navigator.mozApps.install(manifestUrl);
-
-pending.onsuccess = function () {
-  // Save the App object that is returned
-  var appRecord = this.result;
-  alert('Installation successful!');
-};
-pending.onerror = function () {
-  // Display the name of the error
-  alert('Install failed, error: ' + this.error.name);
-};
- -

规范

- -

目前不是任何规范的一部分。

- -

浏览器支持

- -

We're converting our compatibility data into a machine-readable JSON format. - This compatibility table still uses the old format, - because we haven't yet converted the data it contains. - Find out how you can help!

- -
- - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support?13.0 (13.0)???
Available in workers?41.0 (41.0)???
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support??13.0 (13.0)???
Available in workers??41.0 (41.0)???
-
- -

另见

- - diff --git a/files/zh-cn/archive/b2g_os/api/index.html b/files/zh-cn/archive/b2g_os/api/index.html deleted file mode 100644 index 6748c09ac8..0000000000 --- a/files/zh-cn/archive/b2g_os/api/index.html +++ /dev/null @@ -1,833 +0,0 @@ ---- -title: B2G OS APIs -slug: Archive/B2G_OS/API -tags: - - API - - B2G API - - NeedsTranslation - - TopicStub - - b2g os api's -translation_of: Archive/B2G_OS/API ---- -

B2G OS uses standard Web API's

- -

-A -B -C -D -E -F -G -H -I - - -K -L -M -N -O -P - - -R -S -T -U -V -W -X - - - - - -

diff --git a/files/zh-cn/archive/b2g_os/api/navigator/index.html b/files/zh-cn/archive/b2g_os/api/navigator/index.html deleted file mode 100644 index c66a781c5f..0000000000 --- a/files/zh-cn/archive/b2g_os/api/navigator/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Navigator (Firefox OS extensions) -slug: Archive/B2G_OS/API/Navigator -translation_of: Archive/B2G_OS/API/Navigator ---- -

(zh-CN translation)

- -

The Navigator interface represents the state and the identity of the user agent. It allows scripts to query it and to register themselves to carry on some activities. This page represents the list of properties and methods added to Navigator on Firefox OS devices. For the list of properties and methods available to any Web sites, consult Navigator.

- -

A Navigator object can be retrieved using the read-only Window.navigator property.

- -

Navigator.mozHasPendingMessage()
该方法用来用于判定一个给定类型(type)是否存在未决消息(待处理的消息),返回类型为是(true)或非(false)。
Navigator.mozSetMessageHandler()
该方法用来允许应用为系统消息注册处理程序,对消息作出反应。
Navigator.mozTelephony
返回一个你可以用来从浏览器启动和控制电话呼叫的Telephony对象。

diff --git a/files/zh-cn/archive/b2g_os/api/navigator/mozhaspendingmessage/index.html b/files/zh-cn/archive/b2g_os/api/navigator/mozhaspendingmessage/index.html deleted file mode 100644 index ea7a00d867..0000000000 --- a/files/zh-cn/archive/b2g_os/api/navigator/mozhaspendingmessage/index.html +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: Navigator.mozHasPendingMessage() -slug: Archive/B2G_OS/API/Navigator/mozHasPendingMessage -translation_of: Archive/B2G_OS/API/Navigator/mozHasPendingMessage ---- -

-

此 API 在 Firefox OS网页内容或高权限的应用程序上可用。

-

- -

概要

- -

该方法用来用于判定一个给定类型(type)是否存在未决消息(待处理的消息),返回类型为是(true)或非(false)。

- -

navigator.mozSetMessageHandler() 用于设定一种类型的句柄时,待处理的消息会以异步的方式的传输给应用。 

- -

语法

- -
navigator.mozHasPendingMessage(type);
- -

参数

- -
-
type
-
类型是字符串,用于表示一个应用注册的处理函数要处理的消息。要获得有效type的完整列表,请参考navigator.mozSetMessageHandler().
-
- -

返回值

- -

布尔类型。

- -

规范

- - - - - - - - - - - - - - -
规范状态注解
UnknownUnknown定义了系统消息的接口
- -

浏览器兼容性

- -

We're converting our compatibility data into a machine-readable JSON format. - This compatibility table still uses the old format, - because we haven't yet converted the data it contains. - Find out how you can help!

- -
- - -

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support未实现未实现未实现未实现未实现
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox OSFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support未实现1.0未实现未实现未实现未实现
-
- -

参见

- - diff --git a/files/zh-cn/archive/b2g_os/api/navigator/mozsetmessagehandler/index.html b/files/zh-cn/archive/b2g_os/api/navigator/mozsetmessagehandler/index.html deleted file mode 100644 index 9418c598cc..0000000000 --- a/files/zh-cn/archive/b2g_os/api/navigator/mozsetmessagehandler/index.html +++ /dev/null @@ -1,252 +0,0 @@ ---- -title: Navigator.mozSetMessageHandler() -slug: Archive/B2G_OS/API/Navigator/mozSetMessageHandler -translation_of: Archive/B2G_OS/API/Navigator/mozSetMessageHandler ---- -

-

此 API 在 Firefox OS网页内容或高权限的应用程序上可用。

-

- -

概要

- -

该方法用来允许应用为系统消息注册处理程序,对消息作出反应。

- -

任何应用都允许注册到任何消息,但一些消息仅仅可以被送到有对应接收权限的应用。不同于DOM事件,如果应用没有针对系统消息的处理程序,它们将留在队列里。如果有排队消息,可以传入一个type参数调用navigator.mozHasPendingMessage()查看,当一个处理程序被设置,待处理消息将异步的地发送到应用。

- -

语法

- -
navigator.mozSetMessageHandler(type, handler);
- -

参数

- -
-
 
-
type
-
type是一个字符串,表示要为其注册处理函数的一类消息。
-
handler
-
当系统发送消息时,该处理函数被调用,其接收参数由消息类型来确定。
-
- -

消息类型

- -

目前Firefox OS允许注册以下消息 :

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message nameHandler signaturePermission
activityf( MozActivityRequestHandler request ) 
alarmf( object unknown )alarms
bluetooth-cancelf( object unknown )bluetooth
bluetooth-dialer-commandf( object unknown )bluetooth
bluetooth-hfp-status-changedf( object unknown )bluetooth
bluetooth-opp-transfer-startf( object unknown )bluetooth
bluetooth-opp-transfer-completef( object unknown )bluetooth
bluetooth-opp-receiving-file-confirmationf( object unknown )bluetooth
bluetooth-opp-update-progressf( object unknown )bluetooth
bluetooth-pairedstatuschangedf( object unknown )bluetooth
bluetooth-requestconfirmationf( object unknown )bluetooth
bluetooth-requestpincodef( object unknown )bluetooth
bluetooth-requestpasskeyf( object unknown )bluetooth
headset-buttonf( object unknown ) 
icc-stkcommandf( object command )settings
notificationf( object unknown ) 
pushf( object registration )push
push-registerf (  )push
sms-receivedf( SmsMessage sms )sms
sms-sentf( SmsMessage sms )sms
telephony-call-endedf( object call )telephony
telephony-new-callf( )telephony
ussd-receivedf( object ussd )mobileconnection
wappush-receivedf( object wappush )wappush
- -

规范说明

- - - - - - - - - - - - - - -
SpecificationStatusComment
UnknownUnknownDefines the system messaging interfaces.
- -

浏览器兼容性

- -

We're converting our compatibility data into a machine-readable JSON format. - This compatibility table still uses the old format, - because we haven't yet converted the data it contains. - Find out how you can help!

- -
- - -

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support未实现未实现未实现未实现未实现
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox OSFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support未实现1.0未实现未实现未实现未实现
-
- -

参见

- - diff --git a/files/zh-cn/archive/b2g_os/api/navigator/moztelephony/index.html b/files/zh-cn/archive/b2g_os/api/navigator/moztelephony/index.html deleted file mode 100644 index 9161c818ba..0000000000 --- a/files/zh-cn/archive/b2g_os/api/navigator/moztelephony/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Navigator.mozTelephony -slug: Archive/B2G_OS/API/Navigator/MozTelephony -translation_of: Archive/B2G_OS/API/Navigator/MozTelephony ---- -

- -

-

非标准
- 该特性是非标准的,请尽量不要在生产环境中使用它!

-

- -

-

此 API 仅在 Firefox OS内部应用程序中可用。

-

- -

概要

- -

返回一个你可以用来从浏览器启动和控制电话呼叫的Telephony对象。

- -

语法

- -
var phone = window.navigator.mozTelephony;
-
- -

- -

navigator.mozTelephony是一个可以用来控制浏览器正在运行的设备上电话功能的Telephony对象

- -

详述

- -

这是一个非标准实现,但正在作为系统应用工作组的一部分被W3C讨论。

- - - - - - - - - - - - - - - - -
详述状态内容
Web TelephonyDraftEditor Draft (WIP).
- -

浏览器适应性

- -

由于诸多原因, 其主要的支持预期在手机浏览器上。

- -
- - - - - - - - - - - - - - - - - - - -
功能AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持未实现12.0 (12.0)未实现未实现未实现
-
- -

参见

- - diff --git a/files/zh-cn/archive/b2g_os/api/permissions_api/index.html b/files/zh-cn/archive/b2g_os/api/permissions_api/index.html deleted file mode 100644 index 0459a9c438..0000000000 --- a/files/zh-cn/archive/b2g_os/api/permissions_api/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: Permissions API (Firefox OS) -slug: Archive/B2G_OS/API/Permissions_API -translation_of: Archive/B2G_OS/API/Permissions_API ---- -

-

非标准
- 该特性是非标准的,请尽量不要在生产环境中使用它!

-

- -

-

此 API 仅在 Firefox OS内部应用程序中可用。

-

- -

 

- -

Permissions API 用于显示应用权限以及让用户管理所有app的使用权限。有了这个API,一个应用可以读取到另一个应用的权限,并且还可以管理其权限范围。 

- -

权限管理器可以通过navigator.mozPermissionSettings属性访问,该属性是 PermissionSettings 的实例.

- -

已安装的应用程序权限

- -


- 每个应用程序通过其应用清单请求一些权限。 每次应用程序尝试使用需要显式权限的API时,系统都会提示用户授予或拒绝该权限。 如果他选择不再提示,则用户无法改变主意。 使用此API,可以为用户提供一个界面来管理他为任何应用程序提供的所有权限。

- -

可以通过使用 PermissionSettings.get(), set(), 和isExplicit() 等方法。

- -

读取权限

- -

要了解给定权限的当前状态,可以使用PermissionSettings.get() 方法.  方法返回一个字符串,给出特定应用程序权限的当前状态。 可能的值是:

- -
-
允许
-
该权限已被授予,不需要任何进一步的用户交互。
-
拒绝
-
无论是系统还是用户,权限都被拒绝。
-
提示
-
在需要时,将通过提示明确询问用户。
-
未知
-
应用程序没有要求此权限,甚至无法提示用户获取此权限。
-
- -
// 检查所有已安装的应用
-var apps = navigator.mozApps.mgmt.getAll();
-
-apps.onsuccess = function () {
-  var permission = navigator.mozPermissionSettings;
-
-  // 检查每个应用的权限
-  apps.result.forEach(function (app) {
-    var request, appName = app.manifest.name;
-
-    for (request in app.manifest.permissions) {
-      // 获取应用程序的每个权限请求的当前权限
-      var p = permission.get(request, app.manifestURL, app.origin, false);
-
-      console.log(appName + ' asked for "' + request + '" permission, which is "' + p + '"')
-    }
-  });
-}
-
- -

设置权限

- -

要设置权限,只需使用PermissionSettings.set() 方法。它的值可能与通过get方法检索的值相同。

- -
-

注意: 根据应用程序的privileges,某些权限是隐式的。 如果由于某种原因应用程序尝试更改隐式的权限,则会引发错误。 为了避免此类错误,可以使用PermissionSettings.isExplicit() 方法.

-
- -
// 检查所有已安装的应用
-var apps = navigator.mozApps.mgmt.getAll();
-
-apps.onsuccess = function () {
-  var permission = navigator.mozPermissionSettings;
-
-  // 检查每个应用的权限
-  apps.result.forEach(function (app) {
-    var request, appName = app.manifest.name;
-
-    for (request in app.manifest.permissions) {
-      // 如果权限不明确
-      if (!permission.isExplicit(request, app.manifestURL, app.origin, false) {
-        // 询问用户应用程序请求的所有权限
-        permission.set(request, 'prompt', app.manifestURL, app.origin, false);
-      }
-    }
-  });
-}
- -

规范

- -

暂无

- -

再看看

- - diff --git a/files/zh-cn/archive/b2g_os/api/settingslock/index.html b/files/zh-cn/archive/b2g_os/api/settingslock/index.html deleted file mode 100644 index 50f05a7966..0000000000 --- a/files/zh-cn/archive/b2g_os/api/settingslock/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: SettingsLock -slug: Archive/B2G_OS/API/SettingsLock -tags: - - API - - B2G - - Firefox OS - - NeedsTranslation - - Non-standard - - Settings - - TopicStub -translation_of: Archive/B2G_OS/API/SettingsLock ---- - - -
-

This API is available on Firefox OS for internal applications only.

-
- -

The SettingsLock interface represents a lock on settings. it allows a script to modify settings asynchronously, but in a safe way: ordering is guaranteed and the no other script will modify the settings until the modification are done (the next lock objects will start processing after it has been closed).

- -

Each call to SettingsManager.createLock() create a new SettingsLock object.

- -

All SettingsLock objects are kept in a queue of active locks. When a SettingsLock object is created it's placed at the end of the queue. Calls to get/set places a request against the lock on which it's called. Requests run asynchronously and in the order they are placed against a lock. When the last request for a lock is run, and  the success/error event against it has been fired, the lock is removed from the queue and the next lock start to be processed.

- -

Properties

- -
-
SettingsLock.closed
-
Indicates if the lock is no longer the active lock (true) or if it's still the active lock (false)
-
- -

Methods

- -
-
SettingsLock.set()
-
Allows to change the values of a set of settings. This method is asychronous and return a DOMRequest object.
-
SettingsLock.get()
-
Allows to retrieve the value of a given setting. This method is asychronous and return a DOMRequest object.
-
SettingsLock.clear()
-
Clears any action that have not been done yet (remember that get and set are asynchronous). This method is added for testing and it deletes the whole settings DB!
-
- -

Specification

- -

Not part of any specification yet; however, this API will be discuss at W3C as part of the System Applications Working Group.

- -

See also

- - diff --git a/files/zh-cn/archive/b2g_os/api/settingslock/set/index.html b/files/zh-cn/archive/b2g_os/api/settingslock/set/index.html deleted file mode 100644 index 2203fc1169..0000000000 --- a/files/zh-cn/archive/b2g_os/api/settingslock/set/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: SettingsLock.set() -slug: Archive/B2G_OS/API/SettingsLock/set -translation_of: Archive/B2G_OS/API/SettingsLock/set ---- - - - - - - -
-

此API在 Firefox OS 上仅可供 内部程序  使用.

-
- - - -

摘要

- -

这个方法用来更改一或多个已提供的设置的值。

- -

此方法是异步的,返回一个 DOMRequest 对象,用于检测更改何时完成(或是否发生错误),并在更改完成后根据需要执行操作。

- -

语法

- -
SettingsLock.set(settings);
- -

参数

- -
-
settings
-
一个包含了一组键值对的对象,其中每个键表示给定的设置的字符串名称。可能的字符串的确切列表取决于设备。每个Gaia构建可以有自己的设置列表,有关这些字符串的最新列表,请查看 the Gaia source code.
-
- -

示例

- -

这个示例用来打开设备的WIFI。

- -
var lock = navigator.mozSettings.createLock();
-var result = lock.set({
-  'wifi.enabled': true
-});
-
-result.onsuccess = function () {
-  console.log("The setting has been changed");
-}
-
-result.onerror = function () {
-  console.log("An error occure, the setting remain unchanged");
-}
-
- -

规范

- -

这目前还不是任何规范的一部分; 然而, 此 API 将会作为 System Applications Working Group 的一部分参与W3C的讨论。

- -

其他

- - diff --git a/files/zh-cn/archive/b2g_os/api/settingsmanager/index.html b/files/zh-cn/archive/b2g_os/api/settingsmanager/index.html deleted file mode 100644 index 946c05f3d6..0000000000 --- a/files/zh-cn/archive/b2g_os/api/settingsmanager/index.html +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: SettingsManager -slug: Archive/B2G_OS/API/SettingsManager -tags: - - API - - B2G - - Firefox OS - - Settings -translation_of: Archive/B2G_OS/API/SettingsManager ---- -
- - -
-

此API在 Firefox OS 上仅适用于 内部程序 

-
-
- -

提供对设备设置的访问。

- -

属性

- -
-
SettingsManager.onsettingchange
-
引用处理程序来管理设置的更改状态。
-
- -

方法

- -
-
SettingsManager.createLock()
-
返回一个异步的安全访问设置的 SettingsLock 对象。
-
SettingsManager.addObserver()
-
允许绑定一个函数来对给定的设置进行任意的更改。
-
SettingsManager.removeObserver()
-
允许取消绑定之前使用 addObserver 绑定的处理程序。
-
- -

标准

- -

目前还没有成为任何标准的一部分,然而,此API将会作为 System Applications Working Group 的一部分参与W3C的讨论。

- -

其他

- - diff --git a/files/zh-cn/archive/b2g_os/api/tpc_socket_api/index.html b/files/zh-cn/archive/b2g_os/api/tpc_socket_api/index.html deleted file mode 100644 index b2ce9fe405..0000000000 --- a/files/zh-cn/archive/b2g_os/api/tpc_socket_api/index.html +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: TCP Socket API -slug: Archive/B2G_OS/API/TPC_Socket_API -tags: - - API - - Firefox OS - - TCP套接字 - - WebAPI - - 指导 - - 非标准 -translation_of: Archive/B2G_OS/API/TPC_Socket_API ---- - - -
-

非标准
- 这个特性不在当前的W3C标准上,但在Firefox OS平台上受支持. 尽管实现方式可能会在将来发生变化,并且不受浏览器的广泛支持, 它适合在专用于Firefox OS应用程序的代码中使用。

-
- -
-

该API可用于 Firefox OS 上仅适用于 privileged or certified applications.

-
- -

摘要

- -

TCPSocket API提供了一个完整的API,用于打开和使用TCP连接。 这使应用程序制造商可以实施TCP之上可用的任何协议,例如IMAP,IRC,POP,HTTP等,甚至可以构建自己的协议来满足他们可能拥有的任何特定需求。

- -

权限

- -

为了使用该API,对于所有特权API,都需要在 app manifest 中请求权限。

- -
"permissions" : {
-  "tcp-socket" : {
-    "description" : "创建TCP套接字并通过它们进行通信。"
-  }
-}
- -

总览

- -

This API is available through the Navigator.mozTCPSocket property which is itself a TCPSocket object.

- -

Opening a socket

- -

Opening a socket is done with the TCPSocket.open() method. This method expects up to three parameters:

- -
    -
  1. A string representing the hostname of the server to connect to (it can also be its raw IP address).
  2. -
  3. A number representing the TCP port to be used by the socket (some protocols have a standard port, for example 80 for HTTP, 447 for SSL, 25 for SMTP, etc. Port numbers beyond 1024 are not assigned to any specific protocol and can be used for any purpose.)
  4. -
  5. A optional object containing up to two options: a boolean named useSecureTransport is the socket needed to use SSL, false by default; and a string named binaryType allows to state the type of data retrieved by the application through the data event, with the expected values string or arraybuffer. By default, it is string.
  6. -
- -
var socket = navigator.mozTCPSocket.open('localhost', 80);
- -
-

Note: Only certified apps can use a port below 1024.

-
- -

Listening for connections

- -

Listening for connections is done with the TCPSocket.listen() Requires FirefoxOS 1.2 method. This method expects up to three parameters:

- -
    -
  1. A number representing the TCP port to be used to listen for connections.
  2. -
  3. An optional object specifying the details of the socket. This object expects a property called binaryType, which is a string that can have two possible values: "string" or "arraybuffer". If the value is "arraybuffer" then the TCPSocket.send() will use ArrayBuffers and the data received from the remote connection will also be available in that format.
  4. -
  5. A number representing the maximum length that the pending connections queue can grow.
  6. -
- -
var socket = navigator.mozTCPSocket.listen(8080);
- -
-

Note: Only certified apps can listen on a port below 1024.

-
- -

Sending data

- -

Sending data is done using the TCPSocket.send() method. The data sent can be either a string or a Uint8Array object; however, remember that a TCP socket always deals with binary data. For that reason, it's a lot safer to use Uint8Array instead of a string when sending data.

- -

As per the TCP protocol, it's a good optimization to send a maximum of 64kb of data at the same time. As long as less than 64kb has been buffered, a call to the send method returns true. Once the buffer is full, the method will return false which indicates the application should make a pause to flush the buffer. Each time the buffer is flushed, a drain event is fired and the application can use it to resume data sending.

- -

It's possible to know exactly the current amount of data buffered with the TCPSocket.bufferedAmount property.

- -
function getData() {
-  var data;
-
-  // do stuff that will retrieve data
-
-  return data;
-}
-
-function pushData() {
-  var data;
-
-  do {
-    data = getData();
-  } while (data != null && socket.send(data));
-}
-
-// Each time the buffer is flushed
-// we try to send data again.
-socket.ondrain = pushData;
-
-// Start sending data.
-pushData();
-
- -

Getting data

- -

Each time the socket gets some data from the host, it fires a data event. This event will give access to the data from the socket. The type of the data depends on the option set when the socket was opened (see above).

- -
socket.ondata = function (event) {
-  if (typeof event.data === 'string') {
-    console.log('Get a string: ' + event.data);
-  } else {
-    console.log('Get a Uint8Array');
-  }
-}
- -

As the data event is fired as much as needed, it can sometimes be necessary to pause the flow of incoming data. To that end, calling the TCPSocket.suspend() method will pause reading incoming data and stop firing the data. It's possible to start reading data and firing events again by calling the TCPSocket.resume() method.

- -

Closing a socket

- -

Closing a socket is simply done using TCPSocket.close().

- -

Standard

- -

Not part of any specification yet; however, this API is discussed at W3C as part of the System Applications Working Group under the Raw Sockets proposal.

- -

See also

- - diff --git a/files/zh-cn/archive/b2g_os/apps/index.html b/files/zh-cn/archive/b2g_os/apps/index.html deleted file mode 100644 index 1fc5f11e62..0000000000 --- a/files/zh-cn/archive/b2g_os/apps/index.html +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: 制作Firefox OS应用程序 -slug: Archive/B2G_OS/Apps -translation_of: Web/Apps/Fundamentals ---- -

在Firefox OS设备上运行的应用程序其实就是一个Web应用程序,这样的应用程序完全是由开放的Web技术编写的,比如JavaScript,HTML,以及CSS.我们的网站上几乎包含了你所需要的所有知识和文档,下面仅列出一些只针对Firefox OS的技术文档.

-
-
-

文档和教程

-
-
- 为Firefox OS编写一个应用程序
-
- 本篇教程可以让你制作出你的第一个Firefox OS应用程序.
-
- 提示和技巧
-
- 我们的开发工程师为你提供的各种提示和技巧(还有问题的解决办法)!
-
-

查看更多...

-
-
-

在社区中寻求帮助

-

如果你在开发应用程序的过程中遇到了问题,而且在文档中无法找到解决办法,那么:

- -

不要忘了"提问的艺术"...

-

工具

- -

查看更多...

- - -
-
-

 

diff --git a/files/zh-cn/archive/b2g_os/apps/writing_a_web_app_for_firefox_os/index.html b/files/zh-cn/archive/b2g_os/apps/writing_a_web_app_for_firefox_os/index.html deleted file mode 100644 index 87fe8d36c7..0000000000 --- a/files/zh-cn/archive/b2g_os/apps/writing_a_web_app_for_firefox_os/index.html +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: 为Firefox OS写一个web app -slug: Archive/B2G_OS/Apps/Writing_a_web_app_for_Firefox_OS -translation_of: Web/Apps/Fundamentals/Quickstart ---- -

B2G应用是一个使用HTML,CSS以及JavaScript写成的网络应用(Web Apps)。就像你发布网站一样,你把它们发布在网络上。为了让这个网站可以像一个网络应用一样被安装在你的移动设备上,你不得不给他们加一个标识 (manifest)和一个链接的安装按钮,下面会解释。

-

下面的主题被推荐为起点:

- -

当然,你也可以无拘无束的沉浸在Open Web Apps的深处!

-

安装网络应用(Web app)

-

 

-

当你把应用和标识(manifest)发布到网上,你必须要让Gecko意识到它。在安装时,Gecko会检查标识文件(manifest)并且把其中的重要记录添加到主屏幕(home screen)和其他地方。

-

在安装应用时,调用navigator.mozApps.installAPI。下面是一个安装按钮的例子,你可以把他们嵌入到你的应用中:

-

 

-
<button id="install">
-  安装这个给力的应用在你的主屏幕上
-</button>
-
-<script>
-(function(){
-  function install(ev) {
-    ev.preventDefault();
-    // 定义标识文件的网址(define the manifest URL)
-    var manifest_url = "http://my.webapp.com/manifest.webapp";
-    // 安装这个应用(install the app)
-    var myapp = navigator.mozApps.install(manifest_url);
-    myapp.onsuccess = function(data) {
-      // 应用已经被安装,移出按钮(App is installed, remove button)
-      this.parentNode.removeChild(this);
-    };
-    myapp.onerror = function() {
-      // 应用不能被安装(App wasn't installed, info is in)
-      // installapp.error.name
-     };
-  };
-  //获得按钮的信息并且在按钮被点击的时候调用install()(install() get a reference to the button and call install() on click)
-  var button = document.getElementById('install');
-  button.addEventListener('click', install, false);
-})();
-</script>
-
-

注意:这个安装按钮也可以被放在应用市场(app market)中,比如Firefox Marketplace,但是你也可以在你网站的首页放一个非常方便的“安装应用”的按钮

-

现在使用B2G浏览器app浏览你的网站并且点选安装按钮把。

diff --git a/files/zh-cn/archive/b2g_os/automated_testing/gaia_performance_tests/index.html b/files/zh-cn/archive/b2g_os/automated_testing/gaia_performance_tests/index.html deleted file mode 100644 index 12c0633e43..0000000000 --- a/files/zh-cn/archive/b2g_os/automated_testing/gaia_performance_tests/index.html +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: Gaia 性能测试 -slug: Archive/B2G_OS/Automated_testing/Gaia_performance_tests -translation_of: Archive/B2G_OS/Automated_testing/Gaia_performance_tests ---- -
-

本文主要讲述了有关在 Gaia 上运行性能测试以及如何创建新的测试。

-
-

运行测试

-

The tests are run on a regular basis on Datazilla; however, you can also run them yourself. To do so, you'll need an engineer build with Marionette enabled and remote debugging disabled. See Gaia Build System Primer, Customizing the preferences for more information on how doing this.

-

测试需求

-

Since bug 915156 landed on December 6th 2013, make test-perf requires Node.js on the host to run the tests. The relevant modules should be installed automatically with npm.

-

Prior to running the test, you need to configure a runner host. The runner host is a module that will either run the test in B2G desktop or on a device (real or virtual — like an emulator). By default it runs in B2G desktop, which is not very relevant for performance. To configure the runner just edit the file local.mk in the Gaia top level directory (create it if it doesn't already exist) and put the following line:

-
MARIONETTE_RUNNER_HOST=marionette-device-host
-

This will use the device host runner. The default value is marionette-b2gdesktop-host.

-

The alternative to this is to do:

-
MARIONETTE_RUNNER_HOST=marionette-device-host make test-perf 
-
-

Note: only one device at a time is supported, either an emulator or real device. Make sure you have an up-to-date Gaia version running on it.

-
-

输出

-

By default the test output the data in JSON format. By default it is output to stdout and might be mixed with error message from other commands like npm. This is not a very good idea for automation. So you can redirect this JSON output to a file. Just define MOZPERFOUT for the host runner, either on the command line as an option or in the local.mk file as shown above.

-
MOZPERFOUT=myfile.json
-

There is a "spec" reporter that allow reporting the output in a more human readable format. To use it, set the environment as follow:

-
REPORTER=ConsoleMozPerf
-

This will make the test output something easier to read. Not easier to parse. There is no real syntax.

-

For now, any other value will use the JSON reporter.

-
-

Note: MOZPERFOUT will be honoured whichever reporter you select.

-
-

对所有 app 运行测试

-

In general you can run these test on 1.4 and up from Gaia master. 1.3 might no longer be able to have the tests runs. There is an exception for 1.3t (Tarako). since bug 1006064 landed, if you want to run the tests against Tarako (1.3t), you should run it from the Gaia 1.3t.

-

From 2.0 and onwards, we consider that you should run the test from the same Gaia tree.

-
make test-perf
-

对指定的 app 运行测试

-
APP=browser make test-perf
-

对多个 app 运行测试

-
APPS="browser communications/contacts" make test-perf
-

Setting the number of runs

-

By default, each test is run five times. You can change that by setting the value of RUNS before running the tests. For example, to run each test three times you'd use this option:

-
RUNS=3 make test-perf
-

已知问题

-

When running test on Buri/Hamachi (Alcatel one touch fire), you get:

-
Not enough fields given the number of keys.
-

You can safely ignore the warning. It is just that b2g-info on the device is too old as it comes from 1.2 and we only change Gecko and Gaia on these.

-

Writing new tests

-

With the details of running the test suite out the way, let's now look at how you can write your own performance tests for Gaia.

-

Startup event tests

-

We have setup a standard for app startup events. If you want to test the app startup, please follow the responsiveness guidelines. The startup_event_test.js test will drive it. Make sure to whitelist your app in /tests/performance/startup_events_test.js, by adding it to the list specified by whitelistedApps. Also as a transition measure, you should add it to  whitelistedUnifiedApps which list the apps that use that new method. Once all the apps will be migrated, then we this will disappear - if you can't find it that mean it is not needed anymore.

-
-

Note: this is only implemented in 2.0 and later. If you code use startup-path-done events then it is using the old style and should be updated.

-
-

If you want to measure intermediate launch stages that are not part of the reponsiveness standard, you can dispatch these using the method described below. Dispatching performance events is all you need, they will be collected automatically.

-

其他的 event 基础测试

-

Now if you want to test specific features in your app you can do so by sending events. The test will be in two part. The instrumentation part that lives in the app itself, and the control part that will use marionette to control the app to perform actions.

-

Instrumentation

-

To record the events, all you have to do is dispatch them.

-

First, include our helper in your app:

-
<script defer src='/shared/js/performance_testing_helper.js'></script>
-
-
-

Note: If you use a module loader like RequireJS or Alameda, you might prefer to use that, which is perfectly fine.

-
-

You need to be cautious and make sure you adjust the unit tests so that the PerformaceTestingHelper is either loaded or shimmed. A simple shim is to put this in the unit test source file:

-
var PerformanceTestingHelper = {
-  dispatch: function() { }
-};
-
-

The Travis CI jobs we run out of Github will error if you don't do that properly.

-

Having done that, you can use the helper to dispatch events when it seems appropriate to do so. First you should dispatch a start event. It is important as the 'start' event is sent when we register the listeners, so for your feature you likely want to do this much later. So choose where the feature start and add the proper event dispatch.

-
PerformanceTestingHelper.dispatch('my-feature-start');
-
-

When you're ready to stop collecting data and to report the numbers, you need to send the my-feature-done event, also called the last event, to tell the helper to finish:

-
PerformanceTestingHelper.dispatch('my-feature-done');
-

Also you might want to send intermediate events as appropriate.

-
-

Note: Here we use "my-feature-" as a prefix for the performance event. This is just an example. Please use an obvious name and try to use it consistently.

-
-

Controlling the app

-

The second part is writing a JavaScript to the test framework to perform the test. The filename must end with _test.js and live in apps/<myapp>/test/performance/.

-

It is a lot like a marionette integration test (based on mocha), but with a few twists: in the setup() function you must inject the helper atom that is being used to collect the performance events.

-
PerformanceHelper.injectHelperAtom(client);
-

You must pass a lastEvent parameter to the PerformanceHelper constructor. This will be the last event on which to wait to test your feature.

-

When calling performanceHelper.reportRunDurations() toward the end you must pass the name of the start event you dispatched, otherwise the measurement will be from the start, ie when we inject the helper atom. An easy to figure out the error is if you see the start event in the results. And in that case you'll the the startup events as well as these will be dispatched too.

-
-

Note: you may want to look at existing test to get a better idea.

-
-

Collecting memory statistics

-

You can collect the memory usage for both the b2g process and the current app. Just do

-
var memUsage = performanceHelper.getMemoryUsage(app);
-

app is the application object. memusage will contain several objects enumerating the memory statistics.

-

Running tests from a non-engineering device

-

If you don't have an engineering build on your phone you'll have to do some additional steps:

-
    -
  1. Clone B2G, and build with ./config.sh DEVICE-NAME (e.g. ./config.sh keon)
  2. -
  3. Build the Gecko part via ./build.sh gecko
  4. -
  5. Connect the phone and flash gecko via ./flash.sh gecko
  6. -
  7. Clone Gaia, and create a file build/custom-prefs.js with content user_pref("marionette.defaultPrefs.enabled", true);
  8. -
  9. Enable Remote Debugging on the phone and run make reset-gaia to reset the phone (or make install-gaia if you trust yourself)
  10. -
  11. Disable Remote Debugging and verify that everything is OK by running adb devices. The device should show up.
  12. -
  13. Now running a perf test should work. Verify via RUNS=1 APP=browser make test-perf
  14. -
-

提交 bug

-

Please file bugs in Bugzilla, product "Firefox OS", component "Gaia::PerformanceTest".

-

参考

- diff --git a/files/zh-cn/archive/b2g_os/automated_testing/gaia_unit_tests/index.html b/files/zh-cn/archive/b2g_os/automated_testing/gaia_unit_tests/index.html deleted file mode 100644 index f5d1fb609c..0000000000 --- a/files/zh-cn/archive/b2g_os/automated_testing/gaia_unit_tests/index.html +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Gaia 单元测试 -slug: Archive/B2G_OS/Automated_testing/Gaia_unit_tests -tags: - - B2G - - Firefox OS - - Gaia - - Mobile - - tests - - 单元测试 - - 构建文档 - - 自动化 -translation_of: Archive/B2G_OS/Automated_testing/Gaia_unit_tests ---- -
-

作为 Gaia/B2G 源码的一部分,我们已经创建了多个可运行的单元测试,来测试 Gaia 和 B2G 的不同方面。本文则讲述了如何来访问它们。

-
-
-

注意: 本文假设您已经完全理解 Gaia 和 B2G 是如何工作的。可参考 Hacking Gaia 来开始学习 Gaia。

-
-

运行单元测试

-

您可以在  B2G desktop 或 Firefox Nightly 上运行单元测试。您也需要最新的 Gaia 仓库。为了能够执行绝大部分功能,您必须要安装 Node.js 和 NPM

-
-

注意: 当在安装 test-agent 依赖时,如果下面的命令会因为一种神秘的错误而失败,可能是由于您的 Node.js/NPM 版本太老了。请阅读 通过包管理器来安装 Node.js 以安装最新的版本,并且将 /tools/test-agent/node_modules 文件夹删掉。

-
-

在 Gaia 仓库中有一个 bin/gaia-test 脚本文件, 可以帮助我们以简单的方式运行测试。

-
-

小心: this script will generate a profile suited for unit tests in profile-debug. If you already have another profile in this directory it will be overwritten. Bug 980496 aims to make this configurable.

-
-

在 Firefox 中启动 test runner

-

This will run the test server and launch your default Firefox as found in the path:

-
bin/gaia-test
-

选择 Firefox 二进制

-

You can export the FIREFOX environment variable to your firefox binary. For example, on MacOS X:

-
export FIREFOX=/Applications/FirefoxNightly.app/Contents/MacOS/firefox
-

Alternatively, you can pass it as argument to bin/gaia-test:

-
bin/gaia-test <gaia directory> <firefox path>
-

使用 B2G Desktop 启动 test runner

-

This will download and launch B2G Desktop:

-
bin/gaia-test -d
-

Run the tests from the Web Interface

-

You can simply click on specific tests and then the Execute button.

-

Run the tests from the command line

-

With the WebSocket server running, and the Test Agent app running in B2G Desktop/Firefox Nightly, run the following command:

-
make test-agent-test
-
-

If you only want to run one app's tests you can specify which via the APP env variable:

-
make test-agent-test APP=calendar
-
-

You can also optionally provide a reporter to format the test output:

-
make REPORTER=List test-agent-test
-
-
- Note: Not all reporters work, since we currently do not support Doc.
-

Run the tests as you save

-

When the server is running, the tests for a file are run automatically when a file is saved or even just touched:

- -
-

Note: It watches only existing files so if you create a new file, you have to restart the agent.

-
-

Running tests like TBPL does

-

Gaia unit tests in TBPL are run using a separate runner; this explains how to use it.  Please consult the virtualenv docs if you're not familiar with using a Python virtualenv.

-
virtualenv venv
-source venv/bin/activate
-cd $GAIA/tests/python/gaia-unit-tests
-python setup.py develop
-cd gaia_unit_test
-python main.py --binary /path/to/b2g/desktop/build --profile /path/to/gaia/profile
-
-
-

Note: When specifying the path to the B2G desktop build, you should specify the path to b2g-bin, if it exists, otherwise use b2g.

-
-

The Gaia profile must be made using the following:

-
NO_LOCK_SCREEN=1 DEBUG=1 DESKTOP=0 make
-

By default, this profile will be generated in $GAIA/profile-debug. bin/gaia-test generates the same profile so you don't need to regenerate it if you already run gaia-test.

-

Disabling a gaia unit test in TBPL

-

TBPL uses a blacklist to exclude certain gaia unit tests from being run.  To prevent a test from running in TBPL, add its path to https://github.com/mozilla-b2g/gaia/blob/master/tests/python/gaia-unit-tests/gaia_unit_test/disabled.json.

-

设置您的 Gaia 应用

-

Although this guide should help make things easier, the best way to learn how to write, set up, and run tests is currently still to look at the source code; in particular, take a look at the gallery tests.

-

Using mocks

-

TBD

-

进阶: 脚本在做什么?

-

产生一个 profile

-

You need a profile that is generated by this command:

-
NO_LOCK_SCREEN=1 DEBUG=1 DESKTOP=0 make
-
-

This generates a debug profile in gaia/profile-debug, overriding a previous profile if you already have one.

- -

启动 WebSocket 服务器

-

Test agent (the test runner) ships with a built in WebSocket server that lets you remotely message the browser or device to queue a test run. Often you will want to develop with time saving features like a file watcher that will run your tests when a test file or implementation changes. To take advantage of these features you need to start the server:

-
make test-agent-server
-
-

Using the WebSocket server provides other tools such as a command line reporter for test results (watch the terminal you ran the command from), a Growl reporter, syntax error notifications, and more.

-

The agent also watches for modifications in files, and automatically runs the associated tests. It runs when you save the test or if you save the tested file (we use the convention where the test filename is the tested filename with _test appended, see below for more examples). It watches only existing files so if you create a new file, you have to restart the agent.

-

在 Firefox OS Nightly 运行单元测试

-

You can launch Gaia in Firefox Nightly with the following commands:

-
cd <path to gaia>
-<path to nightly>/firefox --no-remote -profile <path to gaia>/profile-debug/ http://test-agent.gaiamobile.org:8080/
-
-

Note: In Mac OSX, The profile path should be absolute path

-
-

You can use Firebug or the integrated debugger to debug the tests; use the debugger keyword to break in the debugger.

-

使用 B2G Desktop 运行单元测试

-

Launch Gaia and start the "Test Agent" app. From the Test gent app you can select tests to run from the UI.

-

进阶: test-agent 如何工作?

-

The Test Agent lives in its own Github repository. You can have look there to understand how it works under the hood.

diff --git a/files/zh-cn/archive/b2g_os/automated_testing/index.html b/files/zh-cn/archive/b2g_os/automated_testing/index.html deleted file mode 100644 index a5c2c58f11..0000000000 --- a/files/zh-cn/archive/b2g_os/automated_testing/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: Firefox OS 自动化测试 -slug: Archive/B2G_OS/Automated_testing -tags: - - B2G - - QA - - 测试 - - 自动化测试 -translation_of: Archive/B2G_OS/Automated_testing ---- -

-
-

Firefox OS 仍然处在开发中,在可预见的未来中则会对新的硬件加以支持,如何对其进行测试则显得非常重要。 该页面提供的文档主要是对 Firefox OS 多方面进行测试的信息,包括运行不同的测试,自动化,获取报告以及跟踪等。 

-
-

入门

-
-
- Firefox OS 中运行测试: 开发者指南
-
- 这是一个运行测试时入门级的快速开发指南。如果您对 Mozilla 测试和自动化系统没有什么接触,则需要从此处开始。有经验者,则可能对如何运行及怎么运行感兴趣,可以跳过该指南,去学习下面更具体的细节知识。
-
-

Gaia 测试

-

这些文章涵盖了主要的 Gaia 测试套件。

-
-
- Gaia UI 测试
-
- 主要针对 Gaia UI 交互和特性的 Python 测试。
-
- Gaia 集成测试
-
-  基于 Marionette, 针对 Gaia 的 JavaScript 的集成测试。
-
- Gaia 单元测试
-
- 无 UI 交互的 Gaia 单元测试; 使用 JavaScript 实现,并不基于Marionette。
-
- Gaia 性能测试
-
- 基于内部仪器来测量 Gaia app 性能,是树状的测试框架。
-
-

B2G 测试

-

下面的指南涵盖了多个不同的测试框架,用于测试 B2G 功能的各个方面。

-
-
- Mochitests
-
- Gecko 功能和API 测试;基于 HTML & JS。没有与 Gaia 交互。
-
- Reftests
-
- Gecko 渲染正确性测试。
-
- WebAPI tests
-
- Gecko 基于 JS WebAPI 测试;绝大多数需要一个模拟器。
-
- xpcshell tests
-
- Gecko XPCOM APIs 无头绪测试
-
- B2GPerf
-
- 基于内部仪器来测量 Gaia app 性能。
-
- Eideticker
-
- 提供了基于视频捕捉的 Firefox OS 性能测量。
-
- 耐久性测试
-
- 长期运行的重复性测试,用于发现内存泄漏和稳定性问题。
-
- MTBF 测试
-
- 这是一个基于 non-restart gaia-ui-test 的测试框架。它会试图找到阻碍长时间运行测试的各种问题点。(当前,它由台湾团队来完成,仍然是一个开发中的测试框架)
-
- 内存测试 — 即将推出
-
- Repetitive tests run per-commit to mozilla-central, reporting to https://areweslimyet.com/, designed to find problems with memory usage.
-
-

辅助文档

-

This section provides links to some of the supporting technologies that underpin Mozilla's tests, which you may want to find more information about.

-
-
- Marionette
-
- 基于 Selenium WebDriver 的远程测试驱动程序。
-
- Marionette JavaScript tests
-
- A node.js-based runner for Marionette.
-
- Marionette Python tests
-
- A Python runner for Marionette.
-
-
-

Note: If you want to run Marionette against a production build (to run gaia integration tests, gaia-ui-tests, etc.), you can install Marionette as an extension (this currently only works for 1.3 builds, but more support will be added soon.)

-
-

持续性集成测试和结果报告

-

The following articles cover the continuous integration and result reporting mechanisms Mozilla uses to store and intepret test data.

-
-
- TBPL
-
- Understand the tests and builds that run on TBPL.
-
- Jenkins
-
- Understand the tests that are run on real devices via Jenkins.
-
- Datazilla
-
- Understand which performance tests are reporting to the Datazilla dashboard, and what those tests measure.
-
- Test execution chart
-
- A chart showing which tests are being run — on what devices and where — and which platforms are supported for each test.
-
-
-
-  
-
diff --git a/files/zh-cn/archive/b2g_os/building/index.html b/files/zh-cn/archive/b2g_os/building/index.html deleted file mode 100644 index 838fe7c56f..0000000000 --- a/files/zh-cn/archive/b2g_os/building/index.html +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: 构建B2G -slug: Archive/B2G_OS/Building -translation_of: Archive/B2G_OS/Building ---- -
-
-
-

一旦建立B2G的构建系统与完成代码的初始化提取和配置,你就可以生成B2G系统了。

-
-

更新代码

-

在生成B2G系统前,如果这不是你第一次构建B2G, 你也许想要获取最新的代码。要实现这一点,你应该使用下面两个命令更新B2G工具和依赖项:

-
git pull
-./repo sync
-
-

You can update a specific make target's repository by specifying its name:

-
./repo sync gaia
-
-

The repo command has other options available that might be interesting; repo help will give you a lot of information.

-

编译

-
-

Note: Before building, you may want to set up a .userconfig file to customize the build. See Customization with the .userconfig file for details.

-
-

To build Boot to Gecko, simply use the build.sh tool:

-
cd B2G
-./build.sh
-
-

Time for another coffee break, or possibly a nap (especially if this is your first build).

-

编译具体的模块

-

If you want to build just a particular module, such as Gecko, you can specify it by name:

-
./build.sh gecko
-
-

To get a list of the modules you can build, you can do:

-
./build.sh modules
-
-

设置所使用的处理器的核心数

-

By default, the B2G build scripts use the number of cores your system has plus two as the number of parallel tasks to run. You can change this by specifying the -j parameter when running build.sh. This can be handy if you're using your system for other things while building in the background and need to reduce CPU load a bit. It's also handy when you're having build problems, as it can make reading error output from the build process easier if you have just one task going at a time!

-

For example, to build using just two parallel tasks:

-
./build.sh -j2
-
-

The most common use case for this, however, is to prevent builds from running in parallel at all. This makes the output of the process much easier to read, making it easier to sort out build problems. To do this:

-
./build.sh -j1
-
-

若你的编译系统在运行测试的时候出了差错

-

Sometimes (especially after build tool or operating system updates) you'll get weird errors like this when the build system runs its post-build tests:

-
Generating permissions.sqlite...
-test -d profile || mkdir -p profile
-run-js-command  permissions
-WARNING: permission unknown:offline-app
-WARNING: permission unknown:indexedDB-unlimited
-build/permissions.js:122: NS_ERROR_UNEXPECTED: Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIPermissionManager.add]
-make[1]: *** [permissions] Error 3
-make: *** [gaia/profile.tar.gz] Error 2
-

In this situation, try deleting the gaia/xulrunner-sdk directory and re-pulling the code:

-
rm -r gaia/xulrunner-sdk
-
-

This deletes the downloaded, precompiled copy of XULRunner that the build system retrieves automatically; on your next build, a new copy of XULRunner will be automatically retrieved.

-

已知错误

-

“构建错误!”("Build failed!")

-

如果你得到一个普通的“构建错误”信息,你应该尝试重新连接你的手机到电脑上;有时手机可能会因为各种原因被卸载。

-
-

注意不能在Mac上为Keon配置和构建B2G. 你需要使用Linux来为它构建系统。

-
-

美洲狮(Mountain Lion)特定错误

-
-

1.如果你正在OS X 10.8 “美洲狮”(Xcode 4.4.1或更新)上构建并发生了如下错误:

-
external/qemu/android/skin/trackball.c:130:25: error: 'M_PI' undeclared (first use in this function)
- 编辑文件: B2G/external/qemu/Makefile.android 并在第78行加上:
-
MY_CFLAGS += -DM_PI=3.14159265358979323846264338327950288   #/* B2G_fix: not finding M_PI constant */
-
-
- 2. If you are on Mountain Lion and you receive an error during ./build.sh like:
-
-
/System/Library/Frameworks/IOKit.framework/Headers/usb/USB.h:797:9: error: too many #pragma options align=reset
-

Replace all instances of '#pragma options align=reset' with '#pragma pack()' inside /System/Library/Frameworks/IOKit.framework/Headers/usb/USB.h

-
-

未定义符号(Undefined symbols )"_sqlite3_androidopt_handle_pragma" 和 "_sqlite3_androidopt_open"

-

这个错误会在你在OS X 10.7 及更新系统上使用 Xcode 4.5 及更新构建使出现,为解决这个问题,请在external/sqlite/dist/Android.mk文件上应用补丁https://groups.google.com/forum/#!msg/android-building/yAfPyUqCsiQ/7zvICk4GWjYJ

-

KeyedVector.h:193:31: error: indexOfKey was not declared in this scope

-

这个错误在你使用较新的gcc版本时出现,安装gcc/g++/g++-multilib 4.6.x版本。详见使用.userconfig文件自定应.

-
-

社区友情提示: 稍微的修改一下B2G的代码(gcc会告诉你如何改),使用gcc 4.7.x也是可能的,但是这并没有任何的帮助,无论是对于修改的代码还是你会遇到的bug来说。

-
-

arm-linux-androideabi-g++: Internal error: Killed (program cc1plus)

-

如果你见到了这样的信息,很有可能是内存不足造成的,在执行./build.sh之前确保你有足够的可用内存,如果你的系统有4GB RAM应该就可以正常运行。

-

"...is referenced by DSO" error

-

如果在构建模拟器时你得到了这样的信息: /usr/bin/ld: out/host/linux-x86/obj/EXECUTABLES/triangleCM_intermediates/triangleCM: hidden symbol `_XGetRequest' in out/host/linux-x86/obj/STATIC_LIBRARIES/libSDL_intermediates/libSDL.a(SDL_x11dyn.o) is referenced by DSO.

-

你可以通过各种版本的二进制包工具获得,如果你使用Debian Stable,你可以通过安装binutils-gold包来使用gold连接器,注意,binutils已经安装了gold连接器,但是并没有默认使用;binutils-gold就是来做这件事的(让它默认使用)。

-

如果你在编译系统运行测试时遇到编译错误

-

有时,特别是编译工具或操作系统升级之后,在编译系统运行编译后测试时,你会遇到一些奇怪的错误。

-
Generating permissions.sqlite...
-test -d profile || mkdir -p profile
-run-js-command  permissions
-WARNING: permission unknown:offline-app
-WARNING: permission unknown:indexedDB-unlimited
-build/permissions.js:122: NS_ERROR_UNEXPECTED: Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIPermissionManager.add]
-make[1]: *** [permissions] Error 3
-make: *** [gaia/profile.tar.gz] Error 2
-

在这种情况下,尝试删除 gaia/xulrunner-sdk 目录并从重新拷贝一份代码:

-
rm -r gaia/xulrunner-sdk
-

这会删除编译系统自动恢复的已下载的XULRunner的预编译副本,在你下一次编译时,系统会自动恢复一个新的副本。

-

(无法获取)Cannot fetch platform/libcore

-

如果你尝试为Nexus S编译B2G(./config.sh nexus-s)并遇到了libcore相关的错误,那是我们使用开源项目git的缘故,为了解决这个问题,像下面这样检出B2G manifest:

-
git clone https://github.com/mozilla-b2g/b2g-manifest.git
-

在这个仓库中编辑文件 nexus-s.xml, 用一个aosp的入口引用来替换开源git的入口,像下面这个样子:

-
<default revision="refs/tags/android-4.0.4_r1.2"
-              remote="aosp"
-              sync-j="4" />
-

提交这些改变并改变B2G主仓库主分支中的config.sh文件,使你的检出指向你本地修改过的manifest而不是Mozilla提供的:

-
GITREPO=${GITREPO:-"file:///home/path/to/my/b2g-manifest"}
-

clang errors when building with Xcode 5 on Mac

-

If you are building on Mac OS X 10.8 with Xcode 5, you will likely see errors like the following:

-
clang: error: argument unused during compilation: '-include system/core/include/arch/darwin-x86/AndroidConfig.h'
-clang: error: argument unused during compilation: '-U DEBUG'
-clang: error: argument unused during compilation: '-U DEBUG'
-clang: error: argument unused during compilation: '-MF out/host/darwin-x86/obj/EXECUTABLES/obbtool_intermediates/Main.d'
-make: *** [out/host/darwin-x86/obj/EXECUTABLES/obbtool_intermediates/Main.o] Error 1
-

This is because Xcode 5 changes the g++ compiler in /usr/bin, which breaks the build process if you try to use it to compile. In order to work around the problem, edit the following line in build/core/combo/HOST_darwin-x86.mk:

-
HOST_CXX := g++
-

to

-
HOST_CXX := g++-4.6
-ifeq (,$(wildcard /usr/local/bin/g++-4.6))
- HOST_CXX := g++
-endif
-

Next, you'll want to uninstall gcc, using brew (this assumes you've run the Mac OS bootstrap script — if not, you'll need to complete that step before continuing):

-
brew uninstall gcc-4.6
-

Now reinstall gcc with multilib and c++ support:

-
brew install --enable-cxx https://gist.github.com/artlogic/6988658/raw/aeb9d1ea098274ad3f3fe2637b9df7f308a8a120/gcc-4.6.rb
-

Make sure /usr/local/bin is on your PATH. You can do this temporarily by typing the following into the command prompt:

-
export PATH=/usr/local/bin:$PATH
-

You can make the above change permanent by adding it to the .bash_profile file in your home directory.

-

After you've set your PATH, make sure you can run both of the following commands:

-
gcc-4.6 -v
-
-g++-4.6 -v
-

If either of these commands fail, you may need to relink your gcc using brew with the following command:

-
brew link --overwrite gcc-4.6
-

It's also possible that /usr/bin/c++ is not pointing at clang++ as it should be with Xcode 5 installed. You can determine if it is by typing the following:

-
ls -l /usr/bin/c++
-

It should return something that looks like this:

-
lrwxr-xr-x 1 root admin 7 Sep 19 11:40 /usr/bin/c++ -> clang++
-

If c++ is pointing at something other than clang++, update it with the following commands:

-
sudo rm /usr/bin/c++
-
-sudo ln -s /usr/bin/clang++ /usr/bin/c++
-

Cannot pull files from backup directory

-

This could happen when the USB connection is broken while the script pulls data from device to computer.

-

When you run the script again, you'll probably get the following (the example is for the Peak device):

-
Pulling files from ../../../backup-peak
-cat: ../../../backup-peak/system/build.prop: No such file or directory
-Found firmware with build ID
-Pulling "libaudioeq.so"
-cp: cannot stat `../../../backup-peak/system/lib/libaudioeq.so': No such file or directory
-Failed to pull libaudioeq.so. Giving up.
-
-> Build failed! <
-
-Build with |./build.sh -j1| for better messages
-If all else fails, use |rm -rf objdir-gecko| to clobber gecko and |rm -rf out| to clobber everything else.
-

To solve this, it is not necessary to remove the whole objdir-gecko or out directories. Just remove the backup directory, like this (for the example above):

-
$rm -rf backup-peak
-

Emulator build issues

-

If you are making an emulator build, you need to pay attention to these issues:

-
-

First, note that you shouldn't use the x86 emulator — it is hard to install and not well supported.

-
-

Next, the build-system for the emulator builds both 32bit and 64bit versions of the emulator. As the emulator depends on OpenGL, this means that you need to have both 32bit and 64bit versions of OpenGL libraries installed on your system. See the discussion in bug 897727.

-

There are two ways that you can solve this problem:

- -

If your linux distro has multilib packages for OpenGL libraries, you can attempt installing them. You might then have to manually create some symlinks.

-

For example, here is the situation on Ubuntu 12.04 LTS x86-64. On this distribution, the libgl1-mesa-dev package cannot be installed simultaneously in x86-64 and i386 versions, but you can have the following combination of packages simultaneously installed:

-
sudo apt-get install libgl1-mesa-dev libglapi-mesa:i386 libgl1-mesa-glx:i386
-

After having run this command, you will still have to manually create some symlinks for the emulator build to succeed:

-
sudo ln -s /usr/lib/i386-linux-gnu/libX11.so.6 /usr/lib/i386-linux-gnu/libX11.so
-sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
-

Solution #2: just patch the emulator so it only builds 64bit

-

Just apply this patch to the sdk/ git repository under the B2G repo. This will cause the B2G emulator to only attempt to build the 64bit emulator if you're on a 64bit system, thus avoiding any multilib issues. The 32bit emulator is unused anyway on a 64bit system. This is the simplest solution, until this patch eventually bit-rots.

-

下一步

-

After building, your next step depends on whether you built Boot to Gecko for the emulator or for a real mobile device; see the following articles for details:

- diff --git a/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/b2g_os_update_packages/index.html b/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/b2g_os_update_packages/index.html deleted file mode 100644 index f1198f2f1f..0000000000 --- a/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/b2g_os_update_packages/index.html +++ /dev/null @@ -1,477 +0,0 @@ ---- -title: 创建及获取B2G OS更新包 -slug: Archive/B2G_OS/Building_and_installing_Firefox_OS/B2G_OS_update_packages -translation_of: Archive/B2G_OS/Building_and_installing_B2G_OS/B2G_OS_update_packages ---- -
-

待我慢慢来翻译吧。20190416

- -

 

- -

你若想让 B2G OS用户很容易地就能在其设备上进行系统更新,你需要给他们创建一个更新包。

- -

If you want to allow B2G OS users to easily update the version of the system code on their devices, you need to create an update package for them to use. This article goes through the different types of update package available and covers building the package, hosting the updates (and how the system polls for available updates), and applying and verifying those updates.

-
- -

Creating and applying an update is split into four steps:

- -
    -
  1. Building incremental update packages from old version(s) to a new version on a build host.
  2. -
  3. Finding the right update package to download on the client.
  4. -
  5. Downloading the update.
  6. -
  7. Applying the update to existing files on the device.
  8. -
- -

Each of these steps are covered below.

- -
-

Note: There are a number of useful tools for building and testing Firefox OS system updates, available at b2g/tools/update-tools.

-
- -

Prerequisites

- -

To build and apply updates you must ensure that your build has the updater and associated update tools enabled. By default those are enabled only in userdebug and user variants. You can however force building them by adding the following line to your .userconfig file:

- -
export B2G_UPDATER=1
- -

To sign update packages you will need a Java runtime environment (JRE) or Java software development kit (JDK) installed and the java command available in the default path.

- -

Types of update

- -

There are two types of updates to know about: FOTA (Firmware Over-The-Air) and Gecko/Gaia OTA (Over-The-Air). Let's look at the differences between them.

- -

FOTA updates

- -

We can update the entire B2G OS system through FOTA updates, the technology behind which is shared with the Android project. The locations on the phone's hard drive that can be changed using FOTA updates include the system partition, kernel, modem baseband, recovery image used for updating, or any other file on the device.

- -

B2G OS does not depend on a particular FOTA client; the interface is abstracted through an API we call librecovery. However, we recommend using the GOTA recovery client (see below for more details), and the discussion here assumes GOTA is being used.

- -

FOTA update packages mainly consist of a file called update.zip. This package consists of

- - - -

This format and set of files are the same as those used in normal Android updates, except that B2G OS additionally wraps the update.zip package in a mar wrapper (MAR stands for Mozilla ARchive). This mar wrapper allows an additional level of verification, which is explained below.

- -

Gecko/Gaia OTA updates

- -

Alteratively we can update just the Gecko and Gaia files on a B2G OS device, through a mechanism we call Gecko/Gaia OTA updates. All of the Gecko and Gaia files — comprising the core Gecko runtime and the device's user interface — are in the /system/b2g directory on the device. This is the only directory that OTA updates can make changes to.

- -

Gecko/Gaia OTA updates use the same technology that's used to update the Firefox desktop web browser. Much like the FOTA update.zip packages discussed above, OTA updates consist of a MAR file containing a set of binary diffs and new files needed to update the client to a newer software version.

- -

The Gecko client verifies the integrity of MARs that it downloads, and MARs can be signed by multiple parties.

- -

Why have two update technologies?

- -

OTA updates are not as comprehensive as FOTA updates, but they are a lot more user friendly and easy to apply, and will often be fine for what you need to update:

- - - -

Of course, if you need to update files outside Gecko/Gaia, you will have to go for the full FOTA package route.

- -

Let's move on and examine the package building process.

- -

Building update packages

- -

Building updates is the process of generating the files needed to update B2G OS clients from version X of the software to a newer version Y. The update package that's needed to update the client depends on what files have changed between version X and version Y.

- - - -

To generate an incremental update package (for both FOTA and Gecko/Gaia OTA updates), our tools require full builds of both version X and version Y. Full build means that the package includes all the files that are needed to Flash a client. When we produce a full build for version X, we don't know which future versions we will be updating to from versionX . Because of that, we build both full FOTA packages and Gecko/Gaia packages for each version. This allows us to generate either a Gecko/Gaia OTA incremental update, or a FOTA incremental update if needed, between version X and all future versions.

- -

At a high level, the process of building an update looks like this:

- -
    -
  1. With software version X - -
      -
    • Generate a complete Gecko/Gaia OTA MAR for the contents of /system/b2g.
    • -
    • Generate a complete FOTA target files zip, optionally signing it, for the device partitions. The target files zip is referenced below as DEVICE-target_files-$VARIANT.$USER.zip, and is a zip containing the files to update the phone directories, including SYSTEM/, BOOT/, etc. A full FOTA update.zip can be generated from the target files zip.
    • -
    -
  2. -
  3. With software version Y -
      -
    • Generate a complete Gecko/Gaia OTA MAR for the contents of /system/b2g.
    • -
    • Generate a complete FOTA target files zip, optionally signing it, for the device partitions. The target files zip is referenced below as DEVICE-target_files-$VARIANT.$USER.zip, and is a zip containing the files to update the phone directories, including SYSTEM/, BOOT/, etc. A full FOTA update.zip can be generated from the target files zip.
    • -
    -
  4. -
  5. If only files in /system/b2g have changed, generate an incremental Gecko/Gaia OTA update MAR from version X to version Y.
  6. -
  7. Otherwise, generate an incremental FOTA update.zip from version X to version Y. Wrap the incremental FOTA update.zip in a MAR for delivery to the B2G client.
  8. -
  9. Sign the packages as required by delivery agreements.
  10. -
- -

The subsections below describe how to use B2G's tools to implement each of these steps.

- -
-

Note: the steps below assume that you have already set up a b2g build environment at the location $b2g. The commands below reference the $b2g/build.sh helper script, but make can also be used.

-
- -

Generating a complete Gecko/Gaia OTA update MAR

- -

To generate a complete OTA update MAR from the last successful b2g build (e.g. that you built yourself), you need to invoke the gecko-update-full target. To place the MAR at $b2g/objdir-gecko/dist/b2g-update/b2g-gecko-update.mar, use the following commands:

- -
$ cd $b2g
-$ ./build.sh gecko-update-full
-$ cp objdir-gecko/dist/b2g-update/b2g-gecko-update.mar <destination>
-
- -

Generating a full FOTA update MAR

- -

To generate a full FOTA update MAR from the last successful b2g build (e.g. that you built yourself), you need to invoke the gecko-update-fota-full target. This includes the contents of the entire /system partition. Here are the commands you need:

- -
$ cd $b2g
-$ ./build.sh gecko-update-fota-full
-
- -

This will generate a ZIP file ($PRODUCT_OUT/fota/full/update.zip) and a MAR file ($PRODUCT_OUT/fota-$TARGET_DEVICE-update-full.mar). The ZIP file can be directly used with adb sideload, while the MAR is intended for distribution in the same manner as any other update package.

- -

Generating a FOTA update MAR plus recovery package

- -

As of Firefox OS 2.2 (mid April and beyond) we added a new make target, which can be invoked as follows:

- -
$ cd $b2g
-$ ./build.sh gecko-update-fota-fullimg
- -

This is used to produce a recovery package that will dump a set of partitions images. The default set is controlled by the variable B2G_FOTA_FULLIMG_PARTS, defined in gonk-misc/Android.mk (along with most of the other new features seen below.) It's a space-separated string of mountpoint:image instances to include. The default value is "/boot:boot.img /system:system.img /recovery:recovery.img /cache:cache.img".

- -

Along with this we have also introduced some new environment variables to control the production of the two other make targets — gecko-update-fota and gecko-update-fota-full:

- - - -
-

Note: All of these new features heavily rely on having a proper recovery.fstab file provided for the device in question.

-
- -

Generating a partial Gecko/Gaia FOTA update MAR

- -

A partial FOTA update uses the same mechanism as a full FOTA update, but by default only includes Gecko/Gaia updates like a regular OTA update. Additional files outside of Gecko/Gaia (such as fonts) can also be included.

- -

The rationale for generating a partial FOTA update package is mainly related to licensing issues: when building a complete FOTA update package, the whole system partition (at least) will be included. This may include blobs that you don't have the authorization to redistribute. However, since MAR distribution is useful and Gecko/Gaia themselves are free software, there is no reason we should not be able to distribute them in this manner. A partial FOTA allows you to only update a subset of the system. An OTA update could be used instead in this scenario but it does come at a cost: OTA updates require enough space on the system partition to hold both the existing Gecko/Gaia files as well as the unpacked update files. A partial FOTA update does not suffer from this limitation as it can overwrite the existing files with the updated ones.

- -

To create a partial FOTA update from the last successful b2g build (e.g. that you built yourself), Invoke the gecko-update-fota target with the following commands:

- -
$ cd $b2g
-$ ./build.sh gecko-update-fota
-
- -

This will generate a ZIP file ($PRODUCT_OUT/fota/partial/update.zip) and a MAR file ($PRODUCT_OUT/fota-$TARGET_DEVICE-update.mar). The ZIP file can be directly used with adb sideload, while the MAR is intended for distribution in the same manner as any other update package.

- -

The construction can be controlled with a couple of environment variables, the most useful of which are documented below:

- - - - - - - - - - - - - - - - - - - - - - -
VariableMeaning
$B2G_FOTA_DIRSSpace-separated list of directories to include in the update. Defaults to system/b2g.
$TARGET_UPDATE_BINARYBinary used to execute the Edify script inside the package. When none is provided, a pre-built updater binary from ICS is used.
$FOTA_FINGERPRINTSComma-separated list of Android fingerprints to check against. The use case is to be able to distribute Gecko/Gaia update packages on top of a controlled Gonk base system that we cannot legally distribute. For example, Open C community builds are using this.
- -
-

Note: A complete set of these variables is defined in the Android.mk file of the gonk-misc repository; note that $FOTA_FINGERPRINTS is used in our update_tools.py tool.

-
- -

Generating a complete FOTA target files zip

- -

Invoke the target-files-package target to build a target files zip that can be used to generate both incremental and full FOTA update packages. The target files zip can also be signed by custom keys to ensure that only FOTA updates from known sources can be installed. After signing target files, all images and updates (also OTA) need to be generated again to catch the inserted keys.

- -
-

Note: The target files zip is generated in the location out/target/product/$DEVICE/obj/PACKAGING/target_files_intermediates/$DEVICE-target_files-$VARIANT.$USER.zip

-
- -

The following commands will carry out this step:

- -
$ cd $b2g
-$ ./build.sh target-files-package
-$ cp out/target/product/$DEVICE/obj/PACKAGING/target_files_intermediates/$DEVICE-target_files-$VARIANT.$USER.zip <destination>
-
- -

The variable values in the commands listed above should be filled in as follows:

- - - - - - - - - - - - - - - - - - - - - - -
VariableMeaning
$DEVICEDevice name for the AOSP product
$VARIANTeng, user, or userdebug
$USERThe build username
- -

Signing a complete FOTA target files zip

- -

Proper releases should typically be signed by custom release keys only known to the vendor. Having such keys will prevent FOTA updates where the source is unknown from being installed, hence introducing an extra security layer. For this to work, the images flashed to a device need to include public keys while the updates need to be signed by the corresponding private key. 

- -

The first step is to generate custom keys and store them in a safe place. The Android Open Source Project has a script for generating these keys. For full compatibility, get this script from the branch corresponding to the Gonk version of the device in question. Here is the master branch version.

- -

A couple of keys are needed — create them with the following commands. releasekey is the key to use for signing FOTA update packages.

- -
$ development/tools/make_key releasekey '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
-$ development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
-$ development/tools/make_key shared '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
-$ development/tools/make_key media '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
-
- -

With keys present, the target files zip can be signed using the following commands. This will insert the public keys and modify build properties to reflect the fact that it has been signed.

- -
$ cd $b2g
-$ ./build/tools/releasetools/sign_target_files_apks \
-  --default_key_mappings $RELEASEKEY_FOLDER \
-  --replace_ota_keys \
-  --signapk_path prebuilts/sdk/tools/lib/signapk.jar \
-  $UNSIGNED_TARGET_FILES_ZIP \
-  $SIGNED_TARGET_FILES_ZIP
- -

The variable values in the commands listed above should be filled in as follows:

- - - - - - - - - - - - - - - - - - - - - - -
VariableMeaning
$RELEASEKEY_FOLDERThe path to the folder containing the custom keys
$UNSIGNED_TARGET_FILES_ZIPThe FOTA target files zip to sign.
$SIGNED_TARGET_FILES_ZIPThe signed FOTA target files zip to be generated
- -

Generating an incremental OTA update MAR

- -

In this example, we're assuming that we're generating an update from software version X to version Y. The location of the full Gecko/Gaia OTA MAR built from software version X using the instructions above will be called $MAR_X below. This might be a path on a build server like /home/build/b2g/versions/X/update.mar. Similarly, the location of the full MAR built from version Y will be called $MAR_Y.

- -

The tool build-gecko-mar.py will generate an incremental Gecko/Gaia OTA update MAR using $MAR_X and $MAR_Y. We'll call the destination of the generated file $GENERATED_INCREMENTAL_MAR_X_Y. Use the following commands for this step:

- -
$ cd $b2g
-$ ./tools/update-tools/build-gecko-mar.py --from $MAR_X --to $MAR_Y $GENERATED_INCREMENTAL_MAR_X_Y
-
- -

Generating an incremental FOTA update zip

- -

In this example, we're assuming that we're generating an update from software version X to version Y. The location of the full FOTA target zip built from software version X using the instructions above will be called $TARGET_FILES_X below. This might be a path on a build server like /home/build/b2g/versions/X/target_files.zip. Similarly, the location of the full FOTA target zip built from version Y will be called $TARGET_FILES_Y.

- -

The tool build/tools/releasetools/ota_from_target_files will generate an incremental FOTA update.zip using $TARGET_FILES_X and $TARGET_FILES_Y. We'll call the destination of this intermediate file $INTERMEDIATE_FOTA_UPDATE_FOTA_X_Y.

- -

After this update.zip is generated, the last step is to wrap it in a MAR for delivery to the B2G client. The tool tools/update-tools/build-fota-mar.p does this step. We'll call the destination of this generated file $GENERATED_INCREMENTAL_FOTA_X_Y.

- -

Use the following commands to complete this step:

- -
$ cd $b2g
-$ ./build/tools/releasetools/ota_from_target_files -v \
-    --incremental_from $TARGET_FILES_X \
-    --signapk_path prebuilts/sdk/tools/lib/signapk.jar \
-    --package_key $FOTA_SIGNING_KEY \
-    $TARGET_FILES_Y \
-    $INTERMEDIATE_FOTA_UPDATE_FOTA_X_Y
-$ ./tools/update-tools/build-fota-mar.py $INTERMEDIATE_FOTA_UPDATE_FOTA_X_Y --output=$GENERATED_INCREMENTAL_FOTA_X_Y
-
- -

The variable values in the commands listed above should be filled in as follows:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VariableMeaning
$TARGET_FILES_XThe FOTA target files zip for version X
$TARGET_FILES_YThe FOTA target files zip for version Y
$INTERMEDIATE_FOTA_UPDATE_FOTA_X_YA temporary update.zip to generate a MAR from
$GENERATED_INCREMENTAL_FOTA_X_YThe destination incremental update zip wrapped in a MAR for delivery to clients
$FOTA_SIGNING_KEYPath to the prefix for a private key and public cert for signing the update zip. $FOTA_SIGNING_ZIP.pk8 and $FOTA_SIGNING_ZIP.x509.pem should both exist on the file system. If $TARGET_FILES_X is not signed this option can be omitted; the default testkey will still be picked up. In case $TARGET_FILES_X is a custom release key, refer to the target files zip signing section on how to create it, and don't forget to sign $TARGET_FILES_Y.
- -

Hosting updates and polling for updates on the client side

- -

B2G OS clients poll for updates by fetching and parsing an update manifest: update.xml. B2G OS clients are configured to poll for updates on specific servers — they query a specially-constructed path on the server. HTTPS is the recommended protocol that the client uses to query the server, however HTTP is also supported. The server and path polled by clients can be changed by shipping an update to existing clients that changes the polling code.

- -

In the examples below, we'll assume that updates are hosted on the server updates.b2g.com.

- -

The URL polled by the client commonly contains the following parameters:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterExplanation
PRODUCT_MODELThe name of the device model. This is the ro.product.model value in the B2G property database.
CHANNELThe update "channel". This is useful for testing: servers can be configured to host, for example, "nightly", "beta", and "release" channels.
VERSIONThe client's software version. For example, "18.0.2".
BUILD_IDA unique ID such as a timestamp, configured for a particular build.
- -

The Firefox client uses the value of its configured update host and these values to construct a URL to poll at runtime. The structure is as follows:

- -
https://aus4.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%PRODUCT_DEVICE%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml
- -

A real example of such a URL is as follows:

- -
https://aus4.mozilla.org/update/3/B2G/37.0a1/20141214040212/flame/en-US/nightly-b2g37/Boot2Gecko%202.2.0.0-prerelease%20%28SDK%2019%29/default/default/update.xml?force=1
- -

If the server returns a "404 Not Found" in response to the client's request, then there is no update available. If the server returns a "200" and a manifest file, then there may be an update available. The manifest describes the newly available build; that is, the build the client would update to. An example manifest is:

- -
<?xml version="1.0"?>
-<updates>
-  <update type="major" appVersion="19.0" version="19.0" extensionVersion="19.0" buildID="20121210123456"
-          licenseURL="http://www.mozilla.com/test/sample-eula.html"
-          detailsURL="http://www.mozilla.com/test/sample-details.html"
-          isOSUpdate="true">
-    <patch type="partial" URL="https://updates.b2g.com/release/unagi1/18.0/20121203123456/update.mar"
-           hashFunction="SHA512" hashValue="5111e033875752b7d9b32b4795152dea5ef954cb8a9d4a602dd19a923b464c43521287dcb5781faf3af76e6dc5e8a3dd9c13edea18c1f2c8f3bd89e17d103d6f"
-           size="41901319"/>
-  </update>
-</updates>
-
- -

This follows the same schema as the B2G build manifest (see updates.xml Format for more details). The fields in the manifest describe:

- - - -
-

Note: There is a useful update script available at build-update-xml.py, which given a MAR file, builds a B2G OS update.xml for testing.

-
- -
-

Note: The client device or the user may wish to decline an update.

-
- -
-

Note:  isOSUpdate="true" is needed for FOTA updates but not for OTA updates.

-
- -

Using the mechanisms described above, servers can host update packages to update any old client version to the newest version. Or they may host only a "linear update history" in which clients must upgrade through a single path.

- -

The details of the interaction between build servers and the update host is currently beyond the scope of this document. It is highly dependent on the production environment. You can find some more details on our Software Update wiki page.

- -

Verifying and applying updates

- -

After a B2G OS client has successfully polled for an update (handled from within the system), downloaded it, and verified the integrity of the downloaded update package, the final step is to apply the update.

- -

The first step in applying an update is to verify the signatures embedded in the MAR packages (see Generating an incremental FOTA update zip for how these are created). This is done by the B2G OS client itself after checking the integrity of the downloaded package. The code used for this is the same for both FOTA and Gecko/Gaia OTA updates.

- -
-

Note: It is not the MAR file that gets signed: it's the FOTA zip file that gets bundled into the MAR that's signed by build/tools/releasetools/ota_from_target_file. The signing of the FOTA update works the same as it does on Android; if you just run the script without specifying the key, it will use the developer key at build/target/product/security/testkeys.*. This is ok for testing but when you create a real update you need a secure key — i.e. one that no-one else knows about. The device will also verify that signature before applying the patch, so a device's initial images will need to contain the key as well.

-
- -
-

Note: The keys referred to above are found in the Android build systems; we've forked it in our platform_build repo.

-
- -

After signatures are verified, the process of applying an update diverges between Gecko/Gaia OTA updates and FOTA updates. Let's look at the differences between the two at this point.

- -

Applying Gecko/Gaia OTA updates

- -

The B2G OS client applies these using the updater binary. This is part of the Gecko distribution and is the same code used to apply updates to desktop Firefox. As described above, the update is applied while the B2G OS client continues to run normally. Users are able to make and receive calls, run apps, browse the web, etc. while updates are being applied.

- -

The specific details of the updater binary are beyond the scope of this document, but it works approximately like so:

- - - -

After the b2g process finishes restarting, the user will be running the new version of the B2G client software.

- -

Applying FOTA updates

- -

The FOTA client applies these. The Gecko client "hands off" the update to be applied by calling into the librecovery API. What happens after this step is specific to each FOTA client.

- -

In the implementation of librecovery used for the GOTA client, the downloaded update package is staged to be applied and special commands are enqueued for the recovery client. librecovery then reboots the device into recovery mode. The recovery client then runs the update script in the update.zip to update files and partitions as needed. The recovery client may need to reboot multiple times in order to update all files.

- -

After the final reboot, the device will be running the new version of the B2G OS client software.

diff --git a/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/firefox_os_build_overview/index.html b/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/firefox_os_build_overview/index.html deleted file mode 100644 index 7e27a80e43..0000000000 --- a/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/firefox_os_build_overview/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Firefox OS 的编译综述 -slug: Archive/B2G_OS/Building_and_installing_Firefox_OS/Firefox_OS_build_overview -translation_of: Archive/B2G_OS/Building_and_installing_B2G_OS/B2G_OS_build_process_summary ---- -
-

构建和安装Firefox OS火狐操作系统需要消耗大量的时间,网络带宽,和计算机硬件配置。不幸的是,编译过程中很容易发生错误。本文档大致描述了构建过程及步骤来帮助用户们了解概况。每个步骤的详细信息会在相应的链接页面中给出。

-
-
-

注意: 在Firefox OS火狐操作系统的构建过程中会多次引用到“B2G”或“Boot2Gecko”这个词。 “Boot2Gecko”是Firefox OS项目的始称。

-
-

构建的目标:四个“映像”文件

-

构建过程的总体目的是构建四个可以复制到Firefox OS设备的文件。

- - - - - - - - - - - - - - - - - - - -
boot.img(启动映像)包含Linux内核和一个主文件系统映像,后者提供一套精简可用的Unix工具。
system.img(系统映像)包含Firefox OS火狐操作系统的核心,包括了Gonk的一部分,Gecko的接口以及B2G的可执行文件。
userdata.img(用户数据映像)包含Gecko的概要界面和设备上的Gaia风格的web应用程序。
recovery.img(还原映像)包含一个Linux内核和一个主文件系统映像,后者附带一个能够让用户修复错误安装的简单工具。
- -

一旦创建了这四个映像文件,就可以将它们转移到设备里了。

-

Firefox OS 火狐操作系统是建立在Android开源项目(AOSP)的基础之上的。AOSP 的工具—— adbfastboot (快速启动工具)提供了强大的方式来访问和操作设备。很显然,比如,命令行指令 adb reboot-bootloadr 能够使得被控设备重启并停留在bootloader(引导程序)的前期,此时再通过命令行指令 fastboot flash $partition $image 可以把映像文件复制到设备中。

-

启动映像

-

启动映像(boot.img)是由 Linux 内核和一个包含了核心软件和初始化脚本的根分区组成。后者将被复制到设备内存中以便设备的调用,因此被称为“虚拟内存盘”(或者是RAM盘,译者注)。启动映像将被复制到设备的“boot”分区,而设备的文件系统运行时,可以通过工具在根目录下访问RAM盘的内容,比如使用 adb shell访问

-

启动映像还将在根目录的 default.prop 文件中建立超级用户(root user)的权限。

-

启动映像是可以进行修改的——通过检查该文件,再把文件拆分为内核部分和虚拟内存盘映像,提取、修改原先的虚拟内存盘映像中的内容并重新组合为一个能运行的 boot.img 文件。看看这个例子: Alcatel One Touch Fire Hacking (Mini) Guide (无中文)。

-

在被刷入设备之前,可以通过“旁加载”的方法来测试启动映像;启动设备,并停留在bootloadr引导加载程序阶段,然后使用命令fastboot boot /some/path/to/boot.img从启动映像中加载启动并进行测试,这样就不需要安装这个启动映像来进行测试了。

-

系统映像

-

系统映像 (system.img) 提供了 Firefox OS 火狐操作系统的核心:

- -
-

请参阅 the Firefox OS platform 指南以获得更多关于平台体系结构详细信息。

-
-

系统映像将会被复制到设备的 system(系统分区上,并在设备运行时存取到文件系统上的 /system/ 目录中。

-
-

注意: 系统映像也同样提供了设备所需要的二进制文件,最常见的就是手机无线电模块的 RIL (无线电接口

-
-

用户数据映像

-

用户数据映像(userdata.img提供了设备运行时加载的Gaia应用。

-

用户数据映像将被复制到设备的 userdata 分区上,并在设备运行时存取到文件系统上的 /data/ 目录中。很显然,在 /data/b2g/ 目录中包含了用户设备的 Mozilla Gecko 配置。而 /data/local/webapps/ 目录里包含了真实的给用户使用的网络应用程序

-

还原映像

-

还原映像 (recovery.img含有一个一模一样的内核和一个与当前启动映像类似的虚拟内存盘。可是还原映像使用了一个不同的初始化脚本,当用户使用设备上的硬件按钮时,这个脚本将触发一系列还原命令。

-

还原映像将被复制到设备的 recovery 分区上,这是个文件系统在正常启动时不会被挂载的分区。

-

构建的步骤:准备、配置、构建、安装

-

Firefox OS 的整个编译安装过程分为四个步骤:

- - - - - - - - - - - - - - - - - - - -
准备获取所有编译过程中用到的工具和程序,比如说合适的编译器和库文件。
配置下载源代码,并创建.configure 文件,这个文件用于定义与编译相关的环境变量 ,包括定义路径和变量
构建构建用户的 Gecko 配置文件和设备的 Gaia 网络应用程序。
安装在设备上安装文件
- -

 

-

准备

-

最初的准备必须做好,以确保在编译时能够备齐所需的全部软件,比如编译器和编译工具。

-

这个步骤可以手动操作或者使用脚本自动执行。详细请参考 Firefox OS build prerequisites (未翻译)页面。

-
-

注意: 在 Unix 系统或者 类 Unix 系统的机子上,所需的软件可以把它们的程序名作为指令参数使用 unix 的命令行的  which 命令来查找得知。

-
-

配置

-

真正编译始于获取 Firefox OS (或者 B2G)的副本,可以通过在Git上克隆(clone)B2G项目完成。构建配置的过程既包括获取所有构建所需的源代码副本的过程;也包括创建 .config 文件的过程。

-

这需要运行一个 config.sh 脚本。详细请参考 Preparing for your first B2G build (未翻译)页面。

-

配置脚本需要指定构建设备的类型参数,构建名字是指与CPU的架构相关的代号(code names)而不是特定的设备,并且暂时无法指定某个构建过程与具体某个物理设备相对应。可用的代号列表见这里(未翻译)。

-

在配置过程中还会用到AOSP项目的repo工具,用于下载或更新构建过程中所需代码的副本。不同版本的副本会保存在.repo/projects目录下。配置过程将下载大量数据,这需要花费很长的时间。

-

构建

-

构建这一步骤将编译所有源文件,并生成映像文件。

-

这需要运行 build.sh脚本。详细请参考 Building Firefox OS 页面。

-

默认情况下,工具会对所有代码进行尝试构建,从AOSP项目工具到Linux内核,再到Gaia层的网络应用程序。因为这个构建过程是一个整体过程,所以有时当编译失败后,会不知道失败在哪一步。

-

当然为了避免上述情况的发生,也可以只构建整个代码某一特定的部分。比如,Gecko系统部分只在调用有 gecko 参数的构建脚本时才被构建。同样对于Gaia部分也是如此。后面的章节将解释如何在分开编译完成后再安装这些部分到设备上去。

-

同样也可以构建本章在第一部分所提到的几个映像文件。比如说,可以通过命令  ./build.sh out/platform/$target/system.img,构建系统映像system.img,这里 $target 参数要和配置过程中保持一致。

-

安装

-

通过运行脚本 flash.sh将最新编译的代码安装到设备上。

-

独立分开构建的部分可以通过在脚本中添加相应参数进行安装。比如,可以通过指令./flash.sh gaia.只安装Gaia部分的网络应用程序。

diff --git a/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/index.html b/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/index.html deleted file mode 100644 index 5adf2904fe..0000000000 --- a/files/zh-cn/archive/b2g_os/building_and_installing_firefox_os/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: 编译及安装Firefox OS火狐操作系统 -slug: Archive/B2G_OS/Building_and_installing_Firefox_OS -translation_of: Archive/B2G_OS/Building_and_installing_B2G_OS ---- -
-

Firefox OS火狐操作系统正在紧张地开发之中,目前还未正式发布(2013年2月底已向媒体展示实体手机样机),因而保证你能有最新安装版的最优方法,是搭建并安装一个你自己的版本。本页列出的文章将指导你怎样在仿真器或兼容设备上构建和安装Firefox OS,以及火狐浏览器的Gaia用户界面。

-
- - - - - - - -
-

获取和构建 Firefox OS

-
-
- Firefox OS 的构建综述
-
- 构建和安装Firefox OS火狐操作系统需要消耗大量的时间,网络带宽,和计算机硬件配置。此部分将大致描述构建的过程、步骤以及目标,帮助用户自行进行构建。
-
- 构建 Firefox OS 之前
-
- 第一次构建 Firefox OS 之前所需要了解和准备的工作。
-
- 构建 Firefox OS 的准备
-
- 构建 Firefox OS,你需要获取源代码并配置构建过程所需要的参数。本篇文章将告诉你该怎么做。
-
- 构建 Firefox OS
-
- 如何构建Firefox OS。
-
- 移植 Firefox OS
-
- 关于如何移植 Firefox OS 到新的设备中。
-
-

全部内容...

-
-

安装 Firefox OS 或者 Gaia

-
-
- 选择如何运行 Gaia 或 Firefox OS
-
- 你可以在火狐浏览器中使用 Gaia ,可以在手机上的 Firefox OS 中,也可以在桌面模拟器上。本篇文章将帮助你做出选择。
-
- 在 Firefox 中使用 Gaia
-
- 如何在桌面火狐浏览器中使用Gaia。
-
- 使用 Firefox OS 桌面客户端
-
- 本篇文章指导你使用桌面客户端版本的Firefox OS;桌面客户端将 Gaia 环境模拟成一个桌面应用程序。这个模拟比在火狐浏览器中使用Gaia要真实,但没有使用模拟器的效果好。
-
- 使用 Firefox OS 模拟器
-
- 本篇文章将指导你构建和使用Firefox OS模拟器,以及选择不同的模拟器。
-
- 在移动设备上安装 Firefox OS
-
- 如何在手机设备上安装 Firefox OS。
-
- 在 SGS2 上 实现 Firefox OS 和 Android 双系统引导
-
- 在三星 Galaxy S2上如何设置Firefox OS和Android双系统启动环境。
-
-
-

 

diff --git a/files/zh-cn/archive/b2g_os/building_the_b2g_desktop_client/index.html b/files/zh-cn/archive/b2g_os/building_the_b2g_desktop_client/index.html deleted file mode 100644 index 89b2385295..0000000000 --- a/files/zh-cn/archive/b2g_os/building_the_b2g_desktop_client/index.html +++ /dev/null @@ -1,262 +0,0 @@ ---- -title: Building the B2G desktop client -slug: Archive/B2G_OS/Building_the_B2G_desktop_client -translation_of: Archive/B2G_OS/Building_the_B2G_OS_simulator ---- -
-

The B2G OS simulator lets you run Gaia and Web apps in a Gecko-based environment somewhat similar to an actual device. It doesn't emulate device hardware, so it's not adequate for testing device APIs, and isn't a replacement for testing on actual hardware. However, it does have several APIs enabled that aren't available on Firefox such as the Contacts and Settings APIs. It can therefore be useful during the development of your application, or while working on the Gaia user interface itself. This article covers downloading or building the Firefox OS simulator, as well as how to use it.

-
- -
-

Note: The easiest way to use the Firefox OS desktop client is to use the Firefox OS Simulator add-on via WebIDE. It does not require you to build the simulator yourself.

-
- -

Download nightly builds

- -

Just like Firefox Nightlies, the B2G OS simulator desktop client (identified by b2g-) is automatically built every day from the latest source code. The latest build is available from the Mozilla FTP server. Be sure to pick the latest version and the right archive for your operating system. This lets you bypass having to build it yourself. In addition, you don't have to download Gaia on your own either.

- -

Be sure to install the application in a writeable location; the application needs to be able to update the included Gaia profile.

- -

You can now skip ahead to Running the simulator, unless you actually want to build it for yourself. This is necessary if you want to make and test changes to the codebase.

- -

Building the simulator

- -

The first thing you need to do is set up a standard Mozilla build environment. Once you have that, you can pull down the code you'll need and configure it to build the Firefox OS desktop client.

- -

Downloading the code for the first time

- -

In a directory where you'd like the source code to go, clone the mozilla-central repository that contains all of Gecko:

- -
 hg clone http://hg.mozilla.org/mozilla-central
- -

Alternatively, you can download the same code from Github:

- -
 git clone https://github.com/mozilla/gecko-dev
- -

Updating the code

- -

When you do subsequent builds, you should make sure to pull in the latest changes:

- -
cd mozilla-central
-hg pull -u
-
- -

or

- -
cd gecko-dev
-git pull
-
- -

Create a mozconfig

- -

Next, you need to create a file called .mozconfig in the mozilla-central directory to configure the build system to build the Boot to Gecko client instead of Firefox. This file should contain the following:

- -
. "$topsrcdir/b2g/config/mozconfigs/common"
-
-mk_add_options MOZ_OBJDIR=../build # This line should be commented if you use gecko-dev or mozilla-central
-mk_add_options MOZ_MAKE_FLAGS="-j9 -s"
-
-ac_add_options --enable-application=b2g
-ac_add_options --disable-libjpeg-turbo
-
-# This option is required if you want to be able to run Gaia's tests
-ac_add_options --enable-tests
-
-# turn on mozTelephony/mozSms interfaces
-# Only turn this line on if you actually have a dev phone
-# you want to forward to. If you get crashes at startup,
-# make sure this line is commented.
-#ac_add_options --enable-b2g-ril
- -

You also need to include the line ENABLE_MARIONETTE=1 in the file if you want to run Mochitests in the B2G desktop client (either mochitest-b2g-desktop or mochitest-plain) or if you want to run Gaia unit tests.

- -

Building

- -

Now you can build the desktop client with the following command (run this from inside the mozilla-central directory):

- -
./mach build
-
- -

The built client will be placed in the objdir/dist/bin directory (based on the value you specify for MOZ_OBJDIR in the mozconfig file).

- -
-

Note: If you have any trouble first check the dependencies.

-
- -

Downloading Gaia

- -

By default the simulator desktop client will show an empty screen because it doesn't know which web app to load initially as the system app. The collection of system apps and default apps that come with Firefox OS — Gaia — needs to be downloaded.

- -

To download Gaia for the first time, clone the source code repository on GitHub:

- -
git clone https://github.com/mozilla-b2g/gaia
-cd gaia
- -

To update an already existing clone of Gaia, you can pull in the latest changes from GitHub:

- -
cd gaia
-git pull
-
- -

Creating a custom-settings.json

- -

If you know what you're doing and you want to set various config options you can create the file gaia/build/config/custom-settings.json and add them there, for example:

- -
{
-  "lockscreen.enabled": false,
-  "lockscreen.locked": false,
-  "devtools.debugger.remote-enabled": true
-}
- -

This example is useful for bypassing the lockscreen, which is otherwise impossible to bypass on desktop because it can't be unlocked using a mouse or trackpad.

- -

Generating a profile

- -

Next we need to set up Gaia's apps for the desktop simulator. This includes packaging the Gaia apps in the same way as they would be installed on the device, as well as setting up the permissions for the privileged system apps. We do this by generating a profile. The following command (run in the downloaded gaia directory) will take care of that:

- -
make DESKTOP_SHIMS=1 NOFTU=1 DEBUG=1
-
- -

This should create a profile-debug directory below the gaia directory. The new profile contains a customized extension and other configuration details needed to make B2G run properly.

- -
-

Note: There is currently a bug (bug 1180103) that causes Gaia debug profiles to render with an empty homescreen when run through the Firefox OS Simulator (through WebIDE, or whatever.) This can be worked around by building with DEBUG=1 DESKTOP=0 make instead of DEBUG=1.

-
- -

Running the simulator

- -

Once you've built the client (or downloaded and installed the nightly desktop application) and downloaded Gaia , you're ready to fire up the simulator.

- -

Running on Linux

- -

To run the simulator on Linux using the embedded Gaia profile, just run the b2g executable. The binary is in the archive you downloaded earlier or in the objdir/dist/bin directory if you built the client yourself.

- -
b2g -profile gaia/profile-debug
-
- -

You may experience annoying rendering problems. To avoid them, add the following line to your gaia/profile/user.js file:

- -
user_pref("layers.acceleration.disabled", true);
-
- -

Running on Mac

- -

If you downloaded the Nightly build, you can simply launch it from the Finder as usual. Any console output is visible by running the standard Console utility program included with your Mac.

- -

If you want to specify a different Gaia profile (such as your separate download Gaia from above), you need to bypass the b2g wrapper program and run the b2g binary. The command line is slightly more complicated due to the location of the b2g binary and the need for absolute paths when specifying the profile directory:

- -
.../B2G.app/Contents/MacOS/b2g-bin -profile /full/path/to/gaia/profile-debug
-
- -

Running on Windows

- -

Running the Nightly build on Windows is as simple as launching b2g.exe. If you want to customize the execution, you can do so by running the b2g.exe executable instead; this bypasses the wrapper program that automatically uses the bundled Gaia.

- -

Command line options

- -

There are a number of command line options you can use to adjust the runtime experience while using the desktop simulator. You can get a list by using the -help option. This section covers some of the particularly interesting ones.

- -

Specifying the screen size

- -

You can specify the screen size of the device you want to simulate using the -screen option:

- -
b2g -screen <width>x<height>@<dpi>
- -

Where <width>, <height>, and <dpi> are fairly self-explanatory parameters: the width and height of the device's screen in pixels and the device resolution in DPI. Here's some real examples:

- -
b2g -screen 320x480
-b2g -screen 320x480@160
-
- -

Optionally, you can specify certain devices by name to simulate their screen size and resolution:

- - - -

These preset devices are defined in screen.js.

- -

In order to select different screen you probably have to specify the profile path as follow:

- -
-

./b2g-bin --profile ./gaia/profile/ --screen=galaxy_tab

-
- -

Opening the JavaScript console

- -

You can open the JavaScript console when launching the desktop simulator by launching it from the command line with the -jsconsole flag. After building, just do:

- -
.../b2g -jsconsole -profile /path/to/your/profile
- -

If you've installed the Nightly build on a Mac, you can do the following:

- -
/Applications/B2G.app/Contents/MacOS/b2g -jsconsole -profile /path/to/your/profile-debug
- -
-

Note: On production builds of Firefox OS, console logging (for example console.log()) is disabled by default. In order to enable it, open the Developer settings and enable the Console Enabled preference.

-
- -

Launching a specific application at startup

- -

You can specify an application to be launched automatically when b2g starts up in the simulator. This is done as soon as the rest of the system is done loading up. To do this, just use the -runapp option, which takes as a parameter the name of the application to run. For example:

- -
 .../b2g -profile /path/to/your/gaia/profile-debug -runapp email
- -
-

Note: The specified name is normalized by converting it to all lower case and removing all dashes and spaces. This normalized name is then compared to similarly normalized names from the manifests of available apps' manifests. For example, the name of the email app is currently "E-mail", but -runapp email will work because of this normalization.

-
- -

If you specify the -runapp option without an argument, or with an empty argument, the simulator will output to your terminal a list of the known applications as well as a brief usage message.

- -
-

Note: Using the -runapp option disables the lock screen as a side effect and does not re-enable it. It's assumed that you won't use this command on a profile on which you will be testing the lock screen, or you will turn it back on manually using Settings > Screen Lock. Feel free to contribute a patch to change this behavior if it's a problem.

-
- -

Usage tips

- -

This section provides a few helpful tips to using the B2G desktop client.

- - - -

Troubleshooting: A blank screen when the simulator starts

- -

When you start b2g using b2g -profile gaia/path/to/gaia/profile a blank screen may show up along with an error "Cannot reach app://system.gaiamobile.org". To fix this there are a couple of things you can check:

- - - -

Next steps

- -

Now that you have a simulated build of Boot to Gecko running, you can do testing, development, and other work in it:

- - - -

- -

diff --git a/files/zh-cn/archive/b2g_os/customization_with_the_.userconfig_file/index.html b/files/zh-cn/archive/b2g_os/customization_with_the_.userconfig_file/index.html deleted file mode 100644 index 0cfc69ac0b..0000000000 --- a/files/zh-cn/archive/b2g_os/customization_with_the_.userconfig_file/index.html +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: 定制 .userconfig 文件 -slug: Archive/B2G_OS/Customization_with_the_.userconfig_file -tags: - - B2G - - Firefox OS - - build - - userconfig -translation_of: Archive/B2G_OS/Customization_with_the_.userconfig_file ---- -
-

通过将一些 bash 代码放在 B2G 源码 .userconfig 文件中, 您能够对编译过程的一些方面进行定制。 本文将对修改能达到的效果及如何修改进行介绍。

-
-

 .userconfig 文件并没有被源代码控制,因此当您更新源码树时,您的更改不会被覆盖。它需要在   B2G 根目录下被创建; 也就是和 flash.sh, build.sh, 等在一个目录下。在运行您的配置和编译步骤时,需要添加该文件。

-

The .userconfig file, if it exists, is sourced by the load-config.sh script, which is in turn sourced by these scripts: flash.sh, build.sh (through setup.sh), run-gdb.sh, run-emulator.sh and tools/mach_b2g_bootstrap.py. The run-*.sh scripts use it to determine where Gecko is for your build. The mach_b2g_boostrap.py script is used by every B2G related mach command.

-
-

重要: 您的 .userconfig 文件应该在 B2G 源码根目录下,而不是您的 home 目录!

-
-

Changing the Gecko source tree

-

By default, the build uses the gecko tree, which is cloned from a tree in github. Some people like to use mozilla-inbound, or mozilla-central. To do this create your clone whereever you like and add a line to your .userconfig which sets GECKO_PATH, for example:

-
export B2G_DIR=${B2G_DIR:-$(cd $(dirname $0); pwd)}
-echo "B2G_DIR = ${B2G_DIR}"
-
-export GECKO_PATH=${B2G_DIR}/mozilla-inbound
-echo "GECKO_PATH = ${GECKO_PATH}"
-
-
-

Note: if building against a custom Gecko in Mac OS X, the mozilla-central directory must be in a case sensitive file system or else GECKO_PATH will be ignored. You can check whether the file system is case sensitive by running this in a Terminal window:

-
echo -n This file system is case->tmp; echo -n in>>TMP; echo sensitive>>tmp; cat tmp
-

Getting B2G_DIR the way it is above allows your .userconfig to work without having hard-coded paths.

-
-

Changing Gaia settings

-

Sometimes, you'd like to be able to change gaia settings. For example, enabling adb in a user build. The gaia Makefile passes in --override build/custom-settings.json when calling build/settings.py, so we can write some bash which will write {"devtools.debugger.remote-enabled": true} into the custom-settings.json file. We try to avoid changing custom-settings.json if we don't need to, so we actually write into custom-settings.json.new and if the contents differ from custom-settings.json then we'll replace it.

-
export GAIA_PATH=${GAIA_PATH:-$(cd gaia; pwd)}
-export CUSTOM_SETTINGS="${GAIA_PATH}/build/config/custom-settings.json"
-cat > "${CUSTOM_SETTINGS}.new" <<EOF
-{"devtools.debugger.remote-enabled": true}
-EOF
-if [[ -f ${CUSTOM_SETTINGS} ]] && cmp "${CUSTOM_SETTINGS}" "${CUSTOM_SETTINGS}.new" >& /dev/null; then
-  rm "${CUSTOM_SETTINGS}.new"
-else
-  mv "${CUSTOM_SETTINGS}.new" "${CUSTOM_SETTINGS}"
-fi
-
-

Another easier way is to configure a build/config/custom-prefs.js file in the Gaia working directory, so that means in gaia/build/config/custom-prefs.js if you're in the B2G directory. See Gaia Build System Primer, Customizing the preferences.

-
-

Note:  Currently the build is not smart enough to look in a different directory based on GAIA_PATH.  This is different from how GECKO_PATH behaves.  If you wish to use a separate Gaia clone you can manually run make from that directory.

-
-

Create a debug build

-

To build a debug build, put the following line in your .userconfig file:

-
export B2G_DEBUG=1
-

Profiling build

-

To enable profiling (for best results with the built-in (SPS) platform profiler), add the following to your .userconfig file then rebuild:

-
export MOZ_PROFILING=1
-
-

Do NOT pair with B2G_NOOPT. The results will be meaningless!

-
-

Disable the optimizer

-

To disable the optimizer (which may create builds that are easier to debug), add the following to your .userconfig file then rebuild:

-
export B2G_NOOPT=1
-

Disable First Time User experience

-

If you build and reflash a lot, going through the First Time User experience constantly can be annoying. You can disable this by adding the following to your .userconfig:

-
export NOFTU=1
-

Enable gaia developer mode

-

If you plan to develop apps or hack gaia, you can automatically set various usefull settings and preferences to ease working with the device. For example, it will automatically enable the remote debugging feature and disable the prompt when an incoming debugging connection starts.

-

What you need is the following export added to your .userconfig:

-
export DEVICE_DEBUG=1
-

Enable valgrind

-

Valgrind is useful for debugging memory or threading issues with your application. For more information on running valgrind, see Debugging B2G using valgrind [en-US].

-

To use valgrind under B2G, add the following to your .userconfig:

-
export B2G_VALGRIND=1
-

Changing the default host compiler

-

On some recent distributions which use GCC 4.7 as the default compiler you will need to specify an older version in order to be able to build, to do so add two lines to your .userconfig file setting the CC and CXX variables to set the alternate C and C++ compilers respectively. For example to set the GCC 4.6 compiler on Ubuntu 12.10 use:

-
export CC=gcc-4.6
-export CXX=g++-4.6
-
-

Or if you're using a version built from sources provide the full path to the exectuables:

-
export CC=/opt/gcc-4.6.4/bin/gcc
-export CXX=/opt/gcc-4.6.4/bin/g++
-
-

Specify a custom Gecko object tree location

-

Once you start changing gecko source trees and other build options, you may want to also modify where your objects get stored (so, for example, all of your debug objects go into a different tree from your non-debug objects). So you might do something like:

-
export GECKO_OBJDIR=${GECKO_PATH}/objdir-gonk-debug
-
-

Using ${GECKO_PATH} makes it easy to switch between different gecko trees (eg: central, beta, aurora, etc).

-

Keeping both debug and non-debug objects

-

You can use your .userconfig file to switch back and forth between debug and release builds without having to rebuild everything each time!

-
-
-
export B2G_DIR=${B2G_DIR:-$(cd $(dirname $0); pwd)}
-echo "B2G_DIR = ${B2G_DIR}"
-
-export GECKO_PATH=${B2G_DIR}/mozilla-inbound
-echo "GECKO_PATH = ${GECKO_PATH}"
-
-export B2G_DEBUG=1
-echo "B2G_DEBUG = ${B2G_DEBUG}"
-
-export GECKO_OBJDIR=${GECKO_PATH}/objdir-gonk
-if [[ "${B2G_DEBUG}" != "0" ]]; then
-  export GECKO_OBJDIR=${GECKO_OBJDIR}-debug
-fi
-if [[ "${GECKO_PATH/*mozilla-inbound*/mozilla-inbound}" == "mozilla-inbound" ]]; then
-  export GECKO_OBJDIR=${GECKO_OBJDIR}-m-i
-fi
-echo "GECKO_OBJDIR = ${GECKO_OBJDIR}"
-

The echo commands help remind you what your current settings are. To switch between debug and release builds, simply change the value of B2G_DEBUG on line 7.

diff --git a/files/zh-cn/archive/b2g_os/debugging/debugging_b2g_using_gdb/index.html b/files/zh-cn/archive/b2g_os/debugging/debugging_b2g_using_gdb/index.html deleted file mode 100644 index b4939ee2f8..0000000000 --- a/files/zh-cn/archive/b2g_os/debugging/debugging_b2g_using_gdb/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: 使用 gdb 及相关工具调试 B2G -slug: Archive/B2G_OS/Debugging/Debugging_B2G_using_gdb -tags: - - B2G - - Firefox OS - - Mobile - - 调试 -translation_of: Archive/B2G_OS/Debugging/Debugging_B2G_using_gdb ---- -
-

gdb 是一个命令行调试器,提供了许多有用的选项,可以用来调试 Firefox OS 应用程序。其他相关的工具也是同样有效的,比如  b2g-ps, 它是对标准 ps 工具的封装,会显示 B2G 实例中运行的每个进程的名称。本文则描述了如何使用这些工具来执行 Fiefox OS 调试工作。

-
-

在单进程模式下启动调试器

-
-

注意: 在运行调试器前,你可能想要建立一个  .userconfig 文件来自定义一些配置。请查看 Customization with the .userconfig file 获取更多信息。

-
-

要重启 Firefox OS 并在 gdb 控制下运行,只需要简单的运行 run-gdb.sh 脚本就可以了:

-
./run-gdb.sh
-
-
-

注意: 如果你想要在模拟器上调试,请确保并没有连接手机;否则可能会与模拟器上调试 gdb 相冲突。

-
-

如果 Firefox OS 已经在运行,你想要在不重启的情况下附加在上面,也可以这样做:

-
./run-gdb.sh attach
-
-

调试 out-of-process 任务

-

Because of the threaded nature of Firefox OS, 你可能需要掉时除了主 B2G 任务之外的任务。最简单的方式就是使用 b2g-ps 命令来找出你需要调试的进程的 PID:

-
$ adb shell b2g-ps
-b2g              root      106   1     189828 56956 ffffffff 40101330 S /system/b2g/b2g
-Browser          app_0     4308  106   52688  16188 ffffffff 400db330 S /system/b2g/plugin-container
-
-

此处, Browser 是一个子进程用作 browser 应用的 "content process" 。因此如果在本例中,你想要调试  content process, 可以这么做:

-
$ ./run-gdb.sh attach 4308
-

有时候,如果有任何子进程被创建就立刻通知是非常有用的。我们可以在启动  run-gdb.sh  时添加  MOZ_DEBUG_CHILD_PROCESS 环境变量来实现:

-
MOZ_DEBUG_CHILD_PROCESS=1 ./run-gdb.sh
-

运行上面命令后,在 Firefox OS 中启动一个 OOP 应用时,就会输出新任务 plugin-container  的 PID。Having done this, launching an OOP application on Firefox OS will output the PID of the plugin-container for the new task, and will sleep for 30 seconds, enough time for you to run the attach command we saw above:

-
$ ./run-gdb.sh attach 4308
-

If you are trying to debug something that occurs during boot, you have to launch the debugger instance for the new application fairly quickly. Once the new debugger is launched, you should immediately press "c" to continue running the new task.

-

支持

-

What level of functionality to expect

-

The following debugging features at least should definitely work. If they don't, it's likely that a simple tweak to your setup will make them work:

- -

The following debugging features are not supported. Don't try to use them.

- -

Troubleshooting

-

Here are a few things to try first whenever GDB is not working as described above.

-

Ensure that your B2G clone is up-to-date

-

Always keep in mind to that to update your B2G clone you must run these two commands:

-
git pull
-./repo sync
-

Forgetting the git pull there is a typical reason why you'd end up with an old run-gdb.sh and not benefit from recent improvements.

-

确保你已经附着在了正确的进程上

-

Attaching to the wrong process (e.g. main B2G process versus Browser process) would explain why your breakpoints don't get hit.

-

Ensure that symbols are correctly read

-
    -
  1. In gdb, use info shared to check that symbols are correctly read: -
    (gdb) info shared
    -From        To          Syms Read   Shared Object Library
    -0xb0001000  0xb0006928  Yes         out/target/product/otoro/symbols/system/bin/linker
    -0x40051100  0x4007ed74  Yes         /hack/b2g/B2G/out/target/product/otoro/symbols/system/lib/libc.so
    -0x401ab934  0x401aba2c  Yes         /hack/b2g/B2G/out/target/product/otoro/symbols/system/lib/libstdc++.so
    -...
    -
  2. -
  3. The Syms Read column should say Yes everywhere. Maybe on some android phone you would see Yes (*) for some system libraries or drivers; that would be OK. You should not see any No.
  4. -
  5. If you do see a No, that is your first problem and you must solve it before looking at anything else.
  6. -
  7. Look for any error messages in the terminal output just after you typed your run-gdb.sh command.
  8. -
  9. Also check in that terminal output that the GDB command is sane. In particular, its last command line argument should be the path to your b2g executable. Here is a sane example: -
    prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-gdb -x /tmp/b2g.gdbinit.bjacob /hack/b2g/B2G/objdir-gecko/dist/bin/b2g
    -
  10. -
  11. Check the value of these GDB variables: solib-search-path and solib-absolute-prefix: -
    (gdb) show solib-search-path
    -The search path for loading non-absolute shared library symbol files is /hack/b2g/B2G/objdir-gecko/dist/bin:out/target/product/otoro/symbols/system/lib:out/target/product/otoro/symbols/system/lib/hw:out/target/product/otoro/symbols/system/lib/egl:out/target/product/otoro/symbols/system/bin:out/target/product/otoro/system/lib:out/target/product/otoro/system/lib/egl:out/target/product/otoro/system/lib/hw:out/target/product/otoro/system/vendor/lib:out/target/product/otoro/system/vendor/lib/hw:out/target/product/otoro/system/vendor/lib/egl.
    -(gdb) show solib-absolute-prefix
    -The current system root is "out/target/product/otoro/symbols".
    -
  12. -
-
-

Note: If you need more help, try the #b2g IRC channel. If you think you found a bug, report it on the B2G issue tracker.

-
-

 

diff --git a/files/zh-cn/archive/b2g_os/debugging/debugging_ooms/index.html b/files/zh-cn/archive/b2g_os/debugging/debugging_ooms/index.html deleted file mode 100644 index 2b6b511092..0000000000 --- a/files/zh-cn/archive/b2g_os/debugging/debugging_ooms/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: 调试 Firefox OS 的内存溢出错误 -slug: Archive/B2G_OS/Debugging/Debugging_OOMs -translation_of: Archive/B2G_OS/Debugging/Debugging_OOMs ---- -
-

当 Firefox OS 设备内存溢出时,低内存管理器以及低内存消息系统就会 kill 掉一些进程,从而保持 OS 运行。 当 kernel 选择 kill 掉前台进程时, 就会看到你正在使用的 app 有一个明显的 crash 现象。 本文主要描述了如何理解和调试 OOM crash 问题。

-
-
-

注意: 如果你并不了解内存条件在 Firefox OS 上是如何管理的,请在阅读本文前参考 Out of memory management on Firefox OS

-
-

调试  OOM crash

-

假设你已经复现了你认为是由于手机内存溢出所导致的 crash 问题。下面的步骤可以帮助我们理解这些错误是如何产生的。 

-

步骤 1: 验证确实是 OOM 

-

首先,我们需要检查下是否 crash 是否确实是由于内存溢出所导致的。运行命令  adb shell dmesg 可以查看。如果 app 确实是由于 OOM 被 kill 掉的, 你就会看到下面类似的语句输出:

-
<4>[06-18 07:40:25.291] [2897: Notes+]send sigkill to 2897 (Notes+), adj 2, size 30625
-

这一行表示手机的低内存管理器 kill 掉了  Notes+ app (进程 id 2897), 当被 kill 时,其 oom_adj 2 。size 是以 pages 为单位的,每个 page 表示 4kb。因此,在此情况下,   Notes+ app 使用了 30625 * 4kb = 120mb 的内存。

-

题外话: 如果不是 OOM 

-

如果你在 dmesg 输出中没有看到类似的信息,你的 crash 可能就不是 OOM。下面的步骤就是将  crash 的进程附加在  gdb 上进行调试,并获取 backtrace,就像下面代码所示:

-
$ cd path/to/B2G/checkout
-$ adb shell b2g-ps
-# Note pid of the app that you're going to crash
-$ ./run-gdb.sh attach <pid>
-(gdb) continue
-# crash the app
-(gdb) bt
-

当报出 bug 时, 关注上述命令的输出,同时伴随这  adb logcat 的输出。如果你的 crash  是由于 OOM 导致的,   gdb backtrace 就没有什么用了。 因为 OOM crash 是由发送到 kernel 的信号所触发的,而不是进程中错误代码执行时所导致的。

-

步骤 2: 收集内存报告

-

在您已经验证您的 crash 确实是由于 OOM 导致的,下面要做的就是在 app crash 前收集关于手机的内存报告。内存报告会帮助我们理解内存都在哪些方面被使用了。 这个步骤有点困难, 因为一旦 app 出现 crash, 就没有办法从那个进程获取到内存报告。当然也没有办法在 kernel 试图去 kill 一个进程时,才来出发内存报告,那就太晚了。

-

要从手机上获取内存报告, 首先要更新你的构建树,才能获取到最新版本的相关工具。 repo sync 是不能实现这个要求的;你必须执行  git fetch && git mergegit pull 命令才可以:

-
$ cd path/to/B2G/checkout
-$ git fetch origin
-$ git merge --ff-only origin
-

现在你就可以运行使用下面命令来运行内存报告工具了:

-
$ tools/get_about_memory.py
-

一旦获取了你所想要的内存报告,就可以将问题的目录(名称为  about-memory-N)压缩,并附加在相关的 bug 上。但是,只有在你运行这些命令时,你所关注的 app 还活着,并且耗费了大量的内存时,才是管用的。此时也有一些选项。

-

Step 2, 选项 1: 获取不同的设备Get a different device

-

一般最简单的方式就是使用包含更多 RAM 的设备。从步骤 1 中获知当产生 crashed 时,进程会使用多少内存,因此你可以简单的等待,直到进程使用了那么多的内存时,就获取内存报告。 b2g-info 工具就会显示出不同的 B2G 进程使用了多少内存。你可以使用下面的命令循环的运行这个工具:

-
$ adb shell 'while true; do b2g-info; sleep 1; done'
-

如果在设备上无法获取 b2g-info ,你就可以使用  b2g-procrank 来替代。

-

Step 2, option 2: Fastest finger

-

如果无法获得包含更多 RAM 的设备,就可已尝试着去在 app crash 前运行  get_about_memory.py 。 你也可以向上节一样循环运行 b2g-info 来计算何时运行  get_about_memory.py. 运行内存报告时会将手机上的所有进程冻结一段时间,因此在进程 OOM 之前抓取内存报告并不困难。

-

Step 2, option 3: Use a smaller testcase

-

We often hit OOMs when doing something like "loading a file of at least size X in the app."

-

If the app crashes very quickly with a testcase of size X, you could try running a similar but smaller testcase (say, size X/2) and capturing a memory report after that succeeds.  The memory report generated this way often gives us good insights into the OOM crash that we ultimately care about.

-

Step 2, option 4: Run B2G on your desktop

-

If the worst comes to the worst, you can run B2G on your desktop, which probably has much more RAM than your FxOS phone.  This is tricky because B2G running on a desktop machine is a different in some key ways from B2G running on a phone.

-

In particular, B2G on desktop machines has multiprocess disabled by default.  It doesn't really work 100% correctly anywhere, but it works most accurately on Linux and Mac.  (Follow Bug 923961, Bug 914584, Bug 891882)  You can test on your desktop without multiprocess enabled, but in my experience a lot of our high memory usage issues are caused by our interprocess communication code, so that won't necessarily trigger the bug you're seeing.

-

It's also not as convenient to take memory reports from a B2G desktop process.  On Linux, you can send signal 34 to the main B2G process and it'll write memory-report-*.gz files out to /tmp.
-
- One advantage to using B2G desktop builds is that you can use your favorite desktop debugging tools, such as Instruments on Mac OSX.  We've had a lot of success with this in the past. To collect a memory report using Instruments on OS X, choose "New -> Mac OS X -> Allocations". Start b2g-desktop and you should see multiple "plugin-container" processes in the activity monitor. You will need 2 Instruments activities: 1 to trace the allocations on the main b2g process and another to trace the allocations on the app you wish to analyze. Attach the instrument activities and execute your test case.

-

To analyze how much memory your app is using, analyze call trees. Check the "Invert Call Tree" tick, and sort by bytes used. This will show you which part of your app is using lots of memory. Below is a screenshot of a sample analysis of memory usage for an app:

-

Screen shot of instruments.
-
- For more information on setting up B2G desktop builds, read our Hacking Gaia page.

-

步骤 3: 分析内存报告 

-

当运行 get_about_memory.py 时,它就会打开 Firefox 中的内存报告。这个文件包含系统上所有进程的内存使用信息。  Note that you can hover over any leaf node to get a description of what that node describes. 你真正要寻找的是在  crashing 进程中 ”异常变大“ 的事物。此处的 "unusually large" means by capturing a memory report of your app when it's not using a ton of memory and comparing that to the errant memory report.

-

阅读内存报告需要一些实践,因此请在需要的时候就发问吧。这个领域的专家在 #memshrink on IRC.

-

步骤 4: 必要时使用  DMD 重新构建

-

One common line item to stick out in memory reports captured before apps crash is heap-unclassifiedheap-unclassified counts memory allocated by the process that isn't covered by any other memory reporter.  If you have high heap-unclassified, the memory report can't tell you anything else about what that memory belongs to. Our tool for digging into heap-unclassified is called DMD.  This works on B2G, but you must build B2G yourself in order for it to work because DMD requires local symbols that are only kept on the build machine.

-

To find out more information on running DMD and interpreting its output, read the Mozilla Wiki DMD page.
-  

diff --git a/files/zh-cn/archive/b2g_os/debugging/developer_settings/index.html b/files/zh-cn/archive/b2g_os/debugging/developer_settings/index.html deleted file mode 100644 index 0b59d842f7..0000000000 --- a/files/zh-cn/archive/b2g_os/debugging/developer_settings/index.html +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: Firefox OS 开发者设置 -slug: Archive/B2G_OS/Debugging/Developer_settings -translation_of: Archive/B2G_OS/Debugging/Developer_settings ---- -
-

在 Firefox OS Settings 应用中有一个开发者面板。这个面板提供了许多选项可以使您在 Firefox OS 上调试 open web app 更简单。本文则对有效的选项和如何使用进行了介绍。

-
-

开发者选项的设置面板故意将路径设置的不太好找,这是为了避免不需要这些选项的终端用户无意中打开该选项,从而使设备变得更慢或者在界面中显示出特殊的效果。该面板与下图类似 (下图是一个运行 Firefox OS 2.0 2014 四月版本的 Geeksphone keon ):

-

-

可以通过下面路径找到开发者面板:

- -

下面的章节则对开发者面板中的每个选项进行了介绍,包括它们是做什么的以及为何有效。

-

开发者工具设置

-

通过 USB 调试

-

“远程调试” 选项会在 Firefox OS 设备上对 远程调试功能 进行使能。同时也使能了 ADB 命令用法。在  Firefox <1.4 版本,只是一个复选框;在 Firefox 1.4  中是一个下拉选框,其中有三个有效的选项:

- -

开发者 HUD

-

Firefox OS 1.4+ 版本中, 点击该部分会进入开发者 HUD 选择视图。

-

-

在显示开发者信息的 FIrefox OS UI 的顶部,有一个复选框可涌来使能或禁用开发者 HUD 全部的功能,下面有 5 个复选框可以用来启用或禁用:

- -

每秒帧数(Frames per second)

-

启用该选项会使 Firefox OS 显示界面左上角显示 3 个数字; 这个数字表示的是在滑动窗口中近期的平均值,指瞬时数据,但又是相当精确的。实际上,所有的数字都是推测出来的:

- -

A screenshot of Firefox OS, showing three numbers in the top left hand corner that are measurements of app framerate.

-

装载时间

-

Firefox OS 也有一个工具可以帮助测量启动时间,尤其是“初次绘制“ 时间。 由工具所显示的值 — 位于 Firefox OS 界面右上角 — 是指从距今最近的应用的启动时间到应用第一次绘制自己 UI 估计值 之间的时间间隔,间隔以毫秒为单位。 这个数字只是接近“第一次真正画界面”的时间,一般会比实际值要小。 然而, 降低这以数值一般与改善真正的启动时间有直接关系, 因此它可以用来快速的测量优化问题。

-

A screenshot of Firefox OS, showing a number in the top right hand corner that is a measurement of the current app startup time, in milliseconds.

-

App 内存

-

它会显示有关 app 所使用内存的信息, 并且允许您启用或禁用使用内存的不同条目以显示当前 app 所使用的内存。 例如,下面的截图显示了只有 App 内存 和 Js 对象勾选了,就会在界面右下角提示 Settings app 中 Js 对象使用了 414.77KB 内存。

-

-

Flash 重绘区域

-

In this mode, every time a region of the screen is painted by Gecko, Gecko blits a random translucent color over the painted region. Ideally, only parts of the screen that visually change between frames will "flash" with a new color. But sometimes more area than is needed is repainted, causing large areas to "flash". This symptom may indicate that application code is forcing too much of its scene to update. It may also indicate bugs in Gecko itself.

-

A screenshot of Firefox OS with a number of transparent overlays, showing the parts of the screen repainted with each new animation frame.

-

Graphics settings

-

Enable APZ for all content (was Async Pan/Zoom)

-

When enabled, the Async Pan/Zoom module allows panning and zooming to be performed on asynchronously, on another thread, with some noticeable differences to rendering behaviour. To find out more, read the MozillaWiki APZ article.

-

Tiling (was Layers: Enable tiles)

-

Introduced in Firefox OS 1.4, this feature enables the painting of content to the screen in smaller chunks ("tiles") rather than painting the whole screen at once. This is mainly useful for platform QA work involving reducing checkerboarding and finding regression windows.

-

Simple tiling (was Layers: Simple tiles)

-

This flips between the two different content painting implementations described in the section above.

-

Hardware composer (was Enable hardware compositing)

-

When enabled, this setting causes the device to use its Hardware Composer to composite visual elements (surfaces) to the screen.

-

Draw tile borders (was Layers: Draw tile borders)

-

This is very similar to the Draw layer borders option, the difference being that it also draws the borders for individual tiles as well as the borders around layers.

-

Draw layer borders

-

When this setting is enabled, a brightly colored border is added around all the different layers painted to the display — great for diagnosing layout issues.

-

A screenshot from Firefox OS showing an opened select form with the draw layers borders option enabled, resulting in colored borders being drawn on all the different rendered layers.

-

Dump layers tree

-

This option causes a copy of the compositor's layer tree to be dumped to logcat on every frame composited to the screen; this is mainly useful for platform graphics performance work, rather than regular web development.

-

Cards View: Screenshots

-

When enabled, this specifies that app screenshots will be taken when the open apps are displayed in card view. If disabled, app icons are shown in the center of blank cards for the card view instead.

-

窗口管理设置

-

Software home button

-

Enabling this option creates a software home button that can provide the same functionality as the equivalent hardware button if it is not available. This is intended for future use on devices that are likely to not have hardware home buttons, like tablets.

-

Home gesture

-

Enabling this option allows you to swipe upwards towards the center from outside the screen to bring up the homescreen. Again, this can provide the same functionality as the equivalent hardware button if it is not available, and is intended for future use on devices that are likely to not have hardware home buttons, like tablets.

-

Edges gesture

-

Enabling this option allows you to swipe left and right from outside the screen towards the center, to navigate to the next and previous sheets (either web pages in the browser, or views inside another app.) This basically works like the browser navigator bar in Firefox.

-

Continuous transition

-

This setting allows you to decide whether app keyboards open immediately or continuously (with a  transition). Disabling such transition effects are useful on low end devices, when they cause performance to suffer.

-

App transition

-

Turn this on and then off again and you will disable all app closing/opening transitions: all apps will now just show immediately, without the smooth animation, and keyboards will also open/close without animation. Like "Continuous transition enabled", this is meant for improving performance on low end devices, but it has more of an effect.

-

App suspending

-

If enabled, this specifies that when an app is killed in the background, it will be kept in history and reopened when you open it from homescreen/card view. If disabled, such apps are not kept in history/card view.

-

Debug settings

-

Log slow animations

-

This tool tries to help developers understand why animations are not offloaded to the compositor to be run efficiently as possible. It reports "bugs" like trying to animate elements that are too large, or trying to animate CSS properties that can't be offloaded. The messages you'll get on the device will look like the following:

-
I/Gecko   ( 5644): Performance warning: Async animation disabled because frame size (1280, 410) is bigger than the viewport (360, 518) [div with id 'views']
-
-

Wi-Fi output in adb

-

Enabling this option adds information about Wi-Fi to the adb logs (error logs from the console can be accessed using adb logcat | grep "Error" in the Terminal.)

-

Bluetooth output in adb

-

Enabling this option adds information about Bluetooth to the adb logs (error logs from the console can be accessed using adb logcat | grep "Error" in the Terminal.)

-

Console enabled

-

When enabled, this option lets you use the Web Console in Firefox to remotely access the console output on the device; without this option enabled, the console.log() function does nothing.

-

Gaia debug traces

-

Enabling this directly enables DEBUG traces in Gaia; see bug 881672 for more details.

-
-

Note: Unfortunately, not every app supports this mechanism to print their debug log. Instead, they control a "DEBUG" flag in code directly, so enabling this flag does NOT ensure that you'll see all debug logs.

-
-

Show accessibility settings

-

This enables the accessibility settings menu, subsequently found at Settings > Accessibility. The options contained within the accessibility settings are as follows:

-

Screen reader

-

Enabling this option turns on Firefox OS's screen reader. This is technology that allows a blind person to use a Firefox OS device. Currently at a very early stage, it changes the way the standard touch events work. When the screen reader is on, you must interact with the screen as follows:

- -
-

Note: If you have turned the screen reader on and wish to disable it again, you must navigate back to the setting via these new gestures and double-tap the checkbox once it is highlighted to turn it off again. That will restore the touch screen functionality to its default behaviour.

-
-

Note: In Firefox 1.4 and above, there is a quick toggle for the screen reader. Press volume up, then down, three times (up, down, up, down, up, down). The screen reader will instruct you to perform this same action again (volume up, down, up, down, up, down) to turn it on if it is not running, or to turn it off if it is already running. If you do not want to change the current toggle state, simply do something else. That way, you can turn it on and off at will to test your web application for accessibility without having to navigate the accessibility settings menu each time.

-

Speech volume

-

A slider that controls how loud the speech is delivered.

-

Speech rate

-

A slider that controls how fast the speech is delivered.

-

Launch first time use

-

The "Launch first time use" button runs the first-time startup program; this lets you go through the initial setup and tutorial process, and is useful when trying to debug that process, or if you want to re-configure your device from scratch.

-

Obsolete settings

-

This section lists settings that are no longer provided, or no longer exist in the same state, but might still be interesting if you are running an older version of Firefox OS.

-

Accessibility

-

In versions of Firefox earlier than newer 1.4 versions, this controls the accessibility settings, as explained in the Show_accessibility_settings section above.

-

Grid

-

The "Grid" option, when enabled, causes the Firefox OS display to be overlaid with a grid pattern to help you gauge positioning and alignment of items. For example, below we see the Browser app running with the Grid option enabled:

-

-

The grid's heavier lines are 32 pixels apart, both horizontally and vertically.

-

Show frames per second

-

In Firefox OS versions older than newer 1.4, enabling this displays frames per second, as explained in the Frames_per_second section above.

-

Show time to load

-

In Firefox OS versions older than newer 1.4, enabling this displays time to load information, as explained in the Time_to_load section above.

-

Rocketbar enabled

-

In Firefox OS versions older than newer 1.4, this option enables the new Firefox Rocketbar on your device, which provides a useful new way to switch between apps, search, and more. When enabled, you'll find a search icon at the top left of the device, and the RocketBar can be brought up by swiping from the top left of the device towards the bottom left.

-
-

Note: In newer versions of Firefox OS, Rocketbar is enabled automatically and cannot be turned off.

-
-

Contacts debugging output in adb

-

Enabling this option adds debugging information about contacts to the adb logs (error logs from the console can be accessed using adb logcat | grep "Error" in the Terminal.)

-

Progressive paint (was Layers: Progressive paint)

-

This was introduced to help with debugging of the Async Panning/Zoom module (APZ) during its implementation. Now APZ implementation is complete, this option is deprecated, and will be removed from future versions (see bug 1003228).

-

Displayport Heuristics

- -

These options were introduced to help with debugging of the Async Panning/Zoom module (APZ) during its implementation, specifically to allow QA to experiment with different repainting heuristics to see which resulted in the least amount of checkboarding.. Now APZ implementation is complete, these options are deprecated, and will be removed from future versions (see bug 1003228).

-

Keyboard layouts

-

In addition to the developer-specific options listed above, Firefox OS < 1.4's developer settings featured keyboard layout options. These let you toggle on and off the then-experimental Chinese input methods:

-

-

As of Firefox 1.4, these options have been removed. This is because the Chinese keyboard layout implementations (zhuyin and pinyin) have now been completed.

-
-

Note: For other keyboard layouts still under development, such as Japanese, we now have a build-time config to opt them in.

-
-

 

diff --git a/files/zh-cn/archive/b2g_os/debugging/index.html b/files/zh-cn/archive/b2g_os/debugging/index.html deleted file mode 100644 index a83bb6ae67..0000000000 --- a/files/zh-cn/archive/b2g_os/debugging/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Debugging on Firefox OS -slug: Archive/B2G_OS/Debugging -tags: - - B2G - - Debugging - - Firefox OS - - NeedsTranslation - - QA - - Testing - - TopicStub -translation_of: Archive/B2G_OS/Debugging ---- -
-

There are two main types of debugging you'll want to with Firefox OS: debugging apps, and debugging other aspects of the system. This section of the site provides articles covering the different tools at your disposal to debug your Firefox OS code.

-
-

Debugging apps

-

When debugging your web apps, the best tool at your disposal is Mozilla's powerful App Manager, which allows you to run your apps directly on a real device or simulator, update any changes instantly, and debug them directly on the device using Mozilla's excellent developer tools. This should be your first choice, especially for app/Gaia debugging.

-
-
- Using the App Manager
-
- The App Manager is a new tool available in Firefox for Desktop, which provides a number of useful tools to help you test, deploy and debug HTML5 web apps on Firefox OS phones and the Firefox OS Simulator, directly from your browser.
-
- Debugging out of memory errors on Firefox OS
-
- This article describes how B2G's multiprocess architecture affects what the phone does when we run out of memory, and how to understand and debug OOM crashes.
-
-

Debugging Gaia/B2G

-

If you want to debug code from the Gaia apps suite or B2G itself, the following tools will be of use to you.

-
-
- Debugging using the desktop B2G client
-
- You can use the dedicated B2G desktop application (and associated tools) to debug multiple aspects of B2G and Gaia.
-
- Quickstart guide to Gaia development
-
- This guide provides a very quick easy guide to developing and debugging Gaia apps, including running Gaia inside desktop Firefox, and debugging Gaia with App Manager.
-
- Debugging B2G using gdb
-
- The popular gdb debugger can be used to debug Firefox OS and web apps running on a device, or on an emulator. This guide will show you how it's done.
-
- Debugging B2G using Valgrind
-
- Valgrind gives developers access to information about memory allocations, threads, and other information important to performance. This guide shows how to run Valgrind either on desktop B2G or select phone hardware.
-
- Getting NSPR logs in B2G
-
- You can use NSPR logs to record HTTP and other networking.
-
- Debugging OpenGL
-
- How to debug OpenGL code on Firefox OS.
-
-

General setup and information

-

The following articles provide information on individual aspects of setup for Firefox OS development. The chances are that you won't need these, especially if you are just debugging apps using the App Manager. But we have made them available here in case you do.

-
-
- Developer settings for Firefox OS
-
- There are a number of settings options available for developers on Firefox OS. This guide explains what they do and how to take advantage of them.
-
- Installing and using ADB
-
- Many aspects of Firefox OS development require installation of adb, the Android Debug Bridge. This article explains how to do that, and shares some common useful ADB commands.
-
- On-device console logging
-
- How to log to console on a Firefox OS device, and how to access the resulting logs for review on your computer.
-
- Connecting a Firefox OS device to the desktop
-
- This short guide explains how to set up your Firefox OS device and your desktop so that the desktop can communicate with the device over USB.
-
- Setting up to debug Firefox OS code
-
- Before you can begin using most of the tools integrated into Firefox for debugging code running under Firefox OS, you need to do a little configuration work. This article explains what you need to do.
-
diff --git a/files/zh-cn/archive/b2g_os/debugging/taking_screenshots/index.html b/files/zh-cn/archive/b2g_os/debugging/taking_screenshots/index.html deleted file mode 100644 index a1ca14b2aa..0000000000 --- a/files/zh-cn/archive/b2g_os/debugging/taking_screenshots/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: 截屏 -slug: Archive/B2G_OS/Debugging/taking_screenshots -tags: - - Firefox OS - - 截屏 - - 调试 -translation_of: Archive/B2G_OS/Debugging/taking_screenshots ---- -
-

在许多场合下截屏都是非常有用的,例如将你的工作展示给客户端或者在 Marketplace 中发布应用。本文则对在 Firefox OS 手机中如何截屏进行了说明。

-
-
-

Note: Android 会觉得非常熟悉。这些步骤都是类似的。

-
-

准备你的手机

-
    -
  1. 在手机上到 Developer Settings  查看远程调试和终端是否使能
  2. -
  3. 确保你的手机已经  ADB installed 并且正常工作
  4. -
  5. 通过 USB 将手机连接到电脑
  6. -
-

截屏

-

你当前可以有 4 种方式可以实现: 使用终端,在 Eclipse 中使用 DDMS, 在手机上使用手机上的组合按键,或者使用 App Manager。

-

终端

-

打开一个终端窗口,依次输入下面 3 个命令:

-
    -
  1. 使用下面的命令截屏(如果你想要称之为其他的名称,可以修改 screenshot.png
    - adb shell screencap -p /sdcard/screenshot.png
  2. -
  3. 从电脑中获取图片:
    - adb pull /sdcard/screenshot.png
  4. -
  5. 在设备中删除截屏图片
    - adb shell rm /sdcard/screenshot.png
  6. -
-

Alternatively, you can use ffmpeg:

-
    -
  1. Make sure you have ffmpeg installed: -
      -
    1. On Mac, if you use MacPorts, you can do this with sudo port install ffmpeg. For homebrew, do brew install ffmpeg.
    2. -
    3. On Linux (Ubuntu/Debian), use sudo apt-get install ffmpeg.
    4. -
    -
  2. -
  3. cd into the B2G/gaia directory.
  4. -
  5. Use the make screenshot command to take a screenshot.
  6. -
  7. You now have a screenshot called screenshot.png.
  8. -
-

DDMS

-

Open Eclipse.

-
    -
  1. Open DDMS: Window > Open Perspective > Other > DDMS.
  2. -
  3. On the left side panel, in the Devices tab, click the Screen capture button.
  4. -
  5. A new window appears with several options; click on Save button to save your screenshot.
  6. -
-
-

Note: To learn more about DDMS, have a look at the DDMS documentation .

-
-

Phone button combination

-
    -
  1. On Firefox OS versions up to 2.0, simultaneously hold down the Home and Power buttons for a few seconds.
  2. -
  3. On Firefox OS version 2.1 and beyond, simultaneously hold down the Volume Down and Power buttons for a few seconds.
  4. -
-

This takes a screenshot, which is saved in your Gallery. You can now copy the picture from your SDCard to your computer using whatever method suits you best.

-
-

Note: The button combination change was made because many people feel that Home and Power is more difficult to do that it should be, especially with one hand, plus devices with no hardware Home button are not very well supported (you can't use a software Home button in many places in Gaia, such as the lock screen.)

-
-

App Manager/Simulator

-
    -
  1. Go to the App Manager, connect to your phone, and navigate to the Device tab on the left.
  2. -
  3. Click on the Screenshot button at the bottom of the page (is at the same place that you startes the simulator).
  4. -
diff --git a/files/zh-cn/archive/b2g_os/developing_firefox_os/customizing_the_b2g.sh_script/index.html b/files/zh-cn/archive/b2g_os/developing_firefox_os/customizing_the_b2g.sh_script/index.html deleted file mode 100644 index 0406de37db..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_firefox_os/customizing_the_b2g.sh_script/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: 定制 b2g.sh 脚本 -slug: Archive/B2G_OS/Developing_Firefox_OS/Customizing_the_b2g.sh_script -translation_of: Archive/B2G_OS/Developing_Firefox_OS/Customizing_the_b2g.sh_script ---- -
-

在手机上,  b2g 应用程序 (它提供了 Firefox OS API 以及其他的东西)是通过 /system/bin/b2g.sh 脚本启动的。你可以对这个脚本进行定制,以修改 Firefox OS 的行为,本文则是介绍了这些内容。

-
-

设定环境变量

-

如果你仅仅是想要对单个运行的 B2G 设定环境变量,可以执行下面命令:

-
adb shell stop b2g
-adb shell "export ENV_VAR=value && /system/bin/b2g.sh"
-
-

如果你想要在任何时候都使用相同的环境能够变量,可以向下节描述中对 b2g.sh 进行编辑。

-

编辑 b2g.sh

-

For debugging, you may want to set environment variables to get logging information or to otherwise affect how the b2g program runs. You can do this by editing the b2g.sh script. There aren't any tools included on the phone to edit the file in place, so you'll need to copy it to your computer first.

-
    -
  1. Connect the phone to your computer, open a terminal window, and execute the following command to edit the script: -
    adb pull /system/bin/b2g.sh
    -
  2. -
  3. Edit the script to make the changes you want. For example, suppose you'd like to see some logging output (which requires a debug build), then you might add something like: -
    export NSPR_LOG_FILE=/data/local/tmp/mylog.txt
    -export NSPR_LOG_MODULES=Layers:5
    -
    -
  4. -
  5. Run the following commands to save your updated b2g.sh script to the phone and restart b2g: -
    adb shell stop b2g
    -adb remount
    -adb push b2g.sh /system/bin
    -adb shell chmod 0755 /system/bin/b2g.sh
    -adb shell start b2g
    -
    -
  6. -
-
-

Note: /data/local/tmp is the only place on the filesystem which is writable by content processes.

-
-

参考

- -

 

diff --git a/files/zh-cn/archive/b2g_os/developing_firefox_os/filing_bugs_against_firefox_os/index.html b/files/zh-cn/archive/b2g_os/developing_firefox_os/filing_bugs_against_firefox_os/index.html deleted file mode 100644 index 2e5eb4050c..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_firefox_os/filing_bugs_against_firefox_os/index.html +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: 为 Firefox OS 提交 Bug -slug: Archive/B2G_OS/Developing_Firefox_OS/Filing_bugs_against_Firefox_OS -translation_of: Archive/B2G_OS/Developing_Firefox_OS/Filing_bugs_against_Firefox_OS ---- -
-

本文是对 Firefox OS 项目提交 Bug 的指南, 包括 Gaia 和 B2G。

-
- -

Bugzilla

- -

与 Mozilla 中的大多数项目一样,我们用 Bugzilla 作为软件缺陷的追踪管理。当你发现程序错误时,你可以向 bugzilla 中的 Firefox OS 产品提交 bug 报告,其中包含 GaiaGonk 以及 Firefox OS Gecko 等组件。你可以从这里报告关于Firefox OS、B2G、Gaia 等组件的 bug。

- -
-

注意: The Mozilla B2G QA Wiki page also has some useful resources on handling Firefox OS bugs; the most useful pages are Bugzilla Usage and Incoming bug triage for Firefox OS.

-
- -

提交 Bug 

- -

你可以依照 bug 报告撰写指南中的内容来报告优秀的 bug,你也可以在下面发现更多的细节。

- -

强制和可选字段

- -

在报告新 bug 时,有一些必填域:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
字段描述
类别选择这个bug所属的类型,如果你不清楚这个问题所属的类型,你可以将它放到"常规"问题当中。
概要简要描述这个bug的概要。
描述 -

清楚地描述情况,一个好的bug报告应该包含有:1.重现的步骤(STR), 2.预期结果(程序本应该出现的结果)和实际结果(因为bug产生的结果), 3.顺便说明出现bug的频率(即:您多次重复这样的步骤后这个bug出现次数)。

-
版本信息进入 设置>设备信息>更多信息 并且将下列信息与bug一并提交:操作系统版本,内部版本号,平台版本,构建标识,更新方式。(如果你有一台带安装了adb功能的运行Mac或者Linux的电脑,你可以直接运行这个脚本,并且黏贴这个脚本的输出结果到bug报告中)。
截图请抓取一个截图方便我们分析这个bug。(在Flame设备上,可以同时按住电源键和音量下键两秒直至设备显示截屏通知,然后通过USB线传输到电脑上以便提交)。
录制视频如果这个bug的截图不方便传输或者难以通过截图来捕获,请录制一段关于这个bug的视频,你可以将视频文件上传作为bug报告的附件,也可以上传至YouTube网站并且复制视频链接至报告中。
ADB 运行日志如果你的电脑安装了ADB工具,请将你的设备连接到电脑并且在ADB中运行以下命令|adb logcat|。请将这个命令的输出信息复制到一个文本文档中并且附到bug报告中。
- -

以下是可选域:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
字段描述
依赖/块列出多个bug之间的联系。
关键词为bugzilla列出关键词. 特殊的团队将用它们来追踪。
白板包含标签,为追踪bug添加标签,你不能未经许可就擦除其他的标签。
看点别的有时候,两个问题是相互有关联的,你可以指定它们。
旗子用于追踪的旗子; the most used flag in Firefox OS bugs is blocking-b2g. If a bug is set as blocking-b2g, it means we should pay more attention to it as it threatens to block a release.
SecurityIf a bug is related to personal data security, loss of earnings, and other such issues, you should check the checkbox and it will only be visiable to involved employees.
- -

To find more information on bugzilla fields, you can view the Bugzilla Fields page on Bugzilla.

- -

常见关键字

- -

下面的表格提供了你将在 Firefox OS 的 bug 报告中经常见到的关键字。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
关键字描述
metaIndicates that the bug is a status tracking bug. Mozilla uses this tag to tracking multiple bug or user story implementation statuses. Once marked like this, developers should not land patches on top of such bugs. Please be reminded that project managers and QA staff will use meta bugs for tracking.
qablockerUse this keyword for bugs that are blocking testing (manual or automated testing of a feature) and need to be fixed by the next Beta or RC milestone.
qawantedUse this keyword for bugs that need more info, require reproducing or testcasing, or are duplicates (but you can't find the original bug being duplicated). Required QA work progress is recorded in the whiteboard; you should remove this keyword when the required QA work has been completed.
regressionThis keyword means that the problem was fixed, but then it came back (regressed) and the bug in question is a new bug, filed to track the regression. It can also refer to problems outside those identified in pre-check in and smoke tests, which were found in current builds and that were known to be working in previous builds. Tracking these bugs helps us to identify areas that are fragile, prone to breakage and are good candidates for adding to smoke and pre-check in tests.
regressionwindow-wantedIndicates that the bug is a regression, and would strongly benefit from someone identifying the time period in which it happened, ideally to a specific check in.
steps-wantedHighlights a bug that would greatly benefit from someone identifying the steps to reproduce it.
verifymeMeans that this bug is ok to verify with the latest B2G build by someone other than the QA Contact indicated. The bug has specific machine configuration details indicated for verifying the fix. You should try to reproduce the failure, and, if you agree that the resolution of Fixed is correct, mark the Status as Verified.
-
- You should always indicate the build/OS/platform(s) used to verify the bug in the bug comments, before you change the Status to Verified. If the bug is reported on all three platforms and you only have one platform to verify the fix on, go ahead and do so and note it in the bug, but do not mark the bug as Verified. All platforms must be checked before moving Status to Verified.
-
- Finally, if other bugs have been marked as a duplicate of the bug you're verifying, be sure to check and mention those as well. Often developers mark related — but not identical — bugs as duplicates, and these can be overlooked if not checked.
- -
-

注意:有关 Gaia 开发中对 bug 的处理的更多信息,请见向 Gaia 提交补丁

-
- -

 

diff --git a/files/zh-cn/archive/b2g_os/developing_firefox_os/index.html b/files/zh-cn/archive/b2g_os/developing_firefox_os/index.html deleted file mode 100644 index 888de98cc8..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_firefox_os/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Firefox OS 开发 -slug: Archive/B2G_OS/Developing_Firefox_OS -tags: - - NeedsTranslation - - TopicStub -translation_of: Archive/B2G_OS/Developing_Firefox_OS ---- -
-

本部分提供了许多有用的文档,主要包括在编译和写应用时对Firefox OS修改和定制的不同方式以及您如何能够帮助我们对平台进行开发。

-
-
-
- Gaia开发快速入门
-
- Gaia是指web应用的集合,并由这些应用共同组成了 Firefox OS 的前端。在Firefox OS  屏幕上显示的内容都使用了开放web技术,其中包括主屏幕和所有的原生应用 。本指南主要对如何快速使用和修改Gaia层应用进行了简单介绍。
-
- 系统编译入门
-
- 文章介绍了Gaia编译系统是如何工作的,包括Makefile文件,编译过程,环境变量以及隐含的自定义配置等。
-
- Hacking Gaia
-
- 文章提供了开发和修改Gaia的详细指南。
-
-  Market customizations guide
-
- Market customizations allow you to specify build-time customization instructions (for example, which apps should be included in your build) in separate directories, without modifying the core Gaia repo. You can include your own customizations in distinct directories, or use the preexisting directories that come with the source. These customizations are specified with build options. In this article we look in detail at how to create and use these customizations.
-
- Modifying the hosts file
-
- A guide to what can be achieved by modifying the Firefox OS hosts file.
-
- Customization with the .userconfig file
-
- How to customize the build and execution of Firefox OS by changing the .userconfig file.
-
- Customizing the keyboard in Firefox OS apps
-
- This guide shows how to customize the keyboard in your Firefox OS apps.
-
- Firefox OS 本地化
-
- A guide to localising the Firefox OS platform, making it available in your preferred languages.
-
diff --git a/files/zh-cn/archive/b2g_os/developing_firefox_os/market_customizations_guide/index.html b/files/zh-cn/archive/b2g_os/developing_firefox_os/market_customizations_guide/index.html deleted file mode 100644 index 91fc8d5aab..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_firefox_os/market_customizations_guide/index.html +++ /dev/null @@ -1,979 +0,0 @@ ---- -title: 市场自定义指南 -slug: Archive/B2G_OS/Developing_Firefox_OS/Market_customizations_guide -translation_of: Archive/B2G_OS/Developing_Gaia/Market_customizations_guide ---- -
-

市场定制允许您在独立的文件夹指定构建时定制指令(例如,在构建时哪个app应被包括其中)而不必修改核心的Gaia仓库。您能够将自己的定制项放在不同的目录或使用代码中已存在的目录。这些定制是由 build 选项指定的。本文会对如何创建和使用这些定制项进行深入探讨。

-
- -

定制概览

- -

从 1.0.1 开始, Firefox OS 所采用的定制机制都是相同的。
-
- We have created a full-featured Gaia distribution customization sample as part of the gaia repo: study this to learn first-hand what can be done with build-time customization. It will also be referenced in the article below.

- -
-

注意: send a pull request to the above referenced Github repo if you have any suggestions for improving the customization sample, or see something that has been changed in this article but not  updated in the code.

-
- -

Below is the tree structure for the customization sample:

- -
  customize-sample
-  ├── power
-  │   ├── carrier_power_on.png
-  │   └── carrier_power_off.png
-  ├── ringtones
-  │   ├── list.json
-  │   └── ringer_dream_theme.ogg
-  ├── wallpapers
-  │   ├── customize.png
-  │   └── list.json
-  ├── browser.json
-  ├── calendar.json
-  ├── contacts.json
-  ├── costcontrol.json
-  ├── homescreens.json
-  ├── network.json
-  ├── sensors.json
-  ├── settings.json
-  ├── sms-blacklist.json
-  ├── support.json
-  ├── wapuaprof.json
-  └── apps.list
- -
-

注意: 所有的文件都是可选的。如果您没有提供这个文件,就会使用系统的默认配置。

-
- -

We will discuss all these optional customizations in the sections that follow, but first let's see how to apply the customization to Gaia.

- -

定制步骤

- -

要将定制样例应用在 Gaia:

- -
    -
  1. 从 https://github.com/mozilla-b2g/gaia 地址 Clone Gaia 源码
  2. -
  3. 你可以将  gaia/customization/ 文件夹拷贝到新的文件夹来进行你自己的本地化,或者是编辑  gaia/customization/ 文件夹本身。这个路径就是指下面所讲的  <DISTRIBUTION_PATH>; 将该目录更改为你自己的文件路径。
  4. -
  5. 通过 USB 附加在 Firefox OS 设备上,并检查是否它是否可以通过 USB  辨认
  6. -
  7. 构建 Gaia, 使用  GAIA_DISTRIBUTION_DIR 环境变量指定定制样例的位置,如下所示: -
    GAIA_DISTRIBUTION_DIR=<DISTRIBUTION_PATH> make production
    -
  8. -
  9. 现在就应该在你的 Firefox OS 设备上应用了你的定制的修改。
  10. -
- -

如果你将定制样例文件夹拷贝到了 gaia/distribution/, 就可以在没有指定环境变量运行 make 命令:

- -
make production
- -
-

Note: 可通过 Gaia 构建脚本进行定制。 请参考 make options reference 获取构建脚本定制的信息。

-
- -
-

Note: SIM card-specific customizations are included at build time, but applied at runtime during the First Time Usage experience.

-
- -

构建时定制

- -

Let's now go through the different options available in the sample.

- -

power/

- -

Custom power on/off animations (or static images) are included here. Files can be MP4 for animations or PNG for static images.

- -

Valid file names are:

- - - -

ringtones/

- -

Custom ringtones are included here. list.json should contain the filenames of the ringtones, like this:

- -
  {
-    "ringer_classic_courier.opus": "",
-    "ringer_dream_theme.ogg": "",
-    "ringer_loud_windchimes.opus": "",
-    "ringer_bitbounce.opus": ""
-  }
- -

Custom ringtones are selectable in the Firefox OS settings app through Sound > Ringer. The default ringtone must be set in settings.json, using DataURI, you can use datauri command which is available on node/npm, install it by npm install datauri -g and convert file to DataURI by datauri <FILE>

- -

wallpapers/

- -

Custom wallpapers (PNG files) should be included here and listed in list.json, after which they can be selected in the Firefox OS settings app through Display > Wallpaper.

- -

The default wallpaper must be set in settings.json, using the following line:

- -
"wallpaper.image": "image location"
- -
-

Note: The image can be specified as a file path, or a Base 64 encoded data URI.

-
- -

browser.json

- -

This file allows you to add customizations into the actual Browser app, such as bookmarks and default search engine. See the section Browser bookmarks & default search engine for more details on what to put in this file.

- -

calendar.json

- -

This file allows you to use your own custom calendars in the Firefox OS Calendar app. You'll need to specify your own Google Oauth credentials.  In addition, calendar CalDav API access is needed: To  generate the required API key and secret, you need to apply at Google's creating your client ID page; follow these instructions:

- -
    -
  1. Open the API console.
  2. -
  3. Create a project and enable Calendar CalDav API in APIs & auth > APIs.
  4. -
  5. Click on Credentials.
  6. -
  7. Click on Create new client ID
  8. -
  9. Set the Application type to Installed application, and Installed application type to Other, then press Create Client ID. This should give you a Client ID and Client secret.
  10. -
  11. Open the calendar.json file, change the client_id and client_secret to the Client ID and Client secret you got from the Google API console, and save and close.
  12. -
- -
-

Note: API usage is limited to 1,000,000 requests/day

-
- -

camera.json (Gallery and Camera app image sizes)

- -
-
{
-  "maxImagePixelSize": 6000000,
-  "maxSnapshotPixelSize": 4000000,
-  "requiredEXIFPreviewSize": {
-    "width": 1200,
-    "height": 1222
-  }
-}
-
- -

maxImagePixelSize and maxSnapshotPixelSize are maximum pixel sizes of an image Gallery and Camera is allowed to view. Default to 5 mega-pixels (5*220 pixels; 5mp).

- -

Optionally, you can also define variables to specify the minimum EXIF preview size that will be displayed as a full-screen preview by adding requiredEXIFPreviewSize property. If you do not specify this property then EXIF previews will only be used if they are big enough to fill the screen in either width or height in both landscape and portrait mode.

- -

contacts.json

- -

Contacts listed here will be included in the phone's contacts database as soon as Gaia is built.

- -

Here's an example contacts.json file:

- -
[
-   {
-     "name": ["John Doe"],
-     "givenName": ["John"],
-     "familyName": ["Doe"],
-     "nickname": ["Johnny"],
-     "category": ["Work", "Racing Team"],
-     "email": [
-       {
-         "type": ["personal"],
-         "value": "john.doe@example.org",
-         "pref": true
-       },
-       {
-         "type": ["work"],
-         "value": "jdoe@example.com"
-       }
-     ],
-     "adr": [
-       {
-         "type": ["personal"],
-         "streetAddress": "123 Foopy St.",
-         "locality": "San Francisco",
-         "region": "Downtown",
-         "postalCode": "94030",
-         "countryName": "US"
-       }
-     ]
-   },
-   {
-     "name": ["CarrierX"],
-     "email": [
-       {
-         "type": ["work"],
-         "value": "support@carrierx.com"
-       }
-     ],
-     "url": [
-       {
-         "type": ["work"],
-         "value": "https://www.carrierx.com"
-       }
-     ]
-   }
- ]
- -
-

Note: See the Contacts API page for details on the layout of Contacts objects.

-
- -
-

Note: For SIM-card dependent customizations, see the Browser bookmarks and default search engine section.

-
- -

homescreens.json

- -

homescreens.json defines what apps to show in the Firefox OS dock and homescreen, and in which order. By default the file looks like this:

- -
{"homescreens": [
-   [
-     ["apps", "communications", "dialer"],
-     ["apps", "sms"],
-     ["apps", "browser"],
-     ["apps", "camera"]
-   ]
- ]}
- -

This causes the four described apps to appear in the dock. If we added another array, that set of apps would appear on page 1 of the homescreen, the next set on page 2, etc.

- -
{"homescreens": [
-   [ // We're in the dock!
-     ["apps", "communications", "dialer"],
-     ["apps", "sms"],
-     ["apps", "browser"],
-     ["apps", "camera"]
-   ],
-   [ // We're on Page 1 of the homescreen
-     ["apps", "email"],
-     ["apps", "settings"],
-     ["apps", "clock"],
-     ["apps", "calendar"]
-   ],
-   [ // We're on Page 2 of the homescreen
-     ["external-apps", "customapp1"],
-     ["external-apps", "customapp2"],
-     ["external-apps", "customapp3"],
-     ["external-apps", "customapp4"]
-   ]
- ]}
- -

The first item inside each sub-array is the folder the app appears inside; the second is the app directory name.

- -

Collections

- -

Collections are groups of apps that have their own icon that appears on the homescreen. When this icon is tapped, a new screen appears containing all the icons for the apps in the collection. Have a look at the collections directory in the source code to get more of an idea of how these work.

- -

By default, four Collections are prefilled on the first page of the Gaia homescreen: Social, Games, Music, and Entertainment. In homescreens.json it's possible to define what collections to load, what pages they should appear in and in what order. For example, if we wanted to specify these four default collections to appear, we would write this:

- -
{"homescreens": [
-   [
-     ["apps/homescreen/collections", "social"],
-     ["apps/homescreen/collections", "games"],
-     ["apps/homescreen/collections", "music"],
-     ["apps/homescreen/collections", "showbiz"]
-   ], [
-     ["apps", "communications", "dialer"],
-     ["apps", "sms"],
-     ["apps", "browser"],
-     ["apps", "camera"]
-   ]
- ]}
- -

Each top level array position refers to a page of the homescreen. Here, the collections would appear in the dock, and the individual apps would appear on page 1 of the homescreen.

- -
-

Note: Collection names are written in lowercase.

-
- -

Collections can be chosen from the following list:

- - - -
-

Note: As of Firefox OS 1.3, you can define your own custom collections. You simply create them inside the collections directory as explained below, and point to them inside collections.json as shown above.

-
- -

What collections contain

- -

Collections are composed of two types of app.
-
- Local apps are defined at build time by means of manifest files, located at /apps/homescreen/collections/<collectionName>/manifest.collection. The local apps contained within each collection are defined in the mainfest file. For example, the social collection (contains dialer, sms, contacts and email apps) manifest looks like so:

- -
{
-  "name": "Social",
-  "role": "collection",
-  "provider_id": "289", // adaptive search identifier
-  "apps": [
-    ["apps", "communications", "dialer"],
-    ["apps", "sms"],
-    ["apps", "communications", "contacts"],
-    ["apps", "email"]
-  ],
-  "default_locale": "en-US",
-  "icons": {
-    "60": "/collections/social/icon.png",
-    "90": "/collections/social/icon@1.5x.png",
-    "120": "/collections/social/icon@2x.png"
-  }
- }
- -

Remote apps are supplied by the adaptive search provider at runtimee, when the device is online.

- -

How to translate collections

- -

Collection translations have to be defined in locale files in within the homescreen app, in the apps/homescreen/locales/. directory. Each different locale file has a name structure looking like collections.<langCode>.properties — where <langCode> is for example fr for French — and contains simple lines containing the default English string and translated version. An example from the French locale file follows:

- -
# Add bookmark to homescreen
-add-to-home-screen=Ajouter à l’écran d’accueil
-add-to-home-screen-header=Ajouter un lien
-website-name=Nom du site web
-address=Adresse
-added-to-home-screen=Ajouté à l’écran d’accueil
- -

network.json (not in customization folder)

- -
-

Important: This is no longer supported in Firefox OS 1.4.

-
- -

In Firefox OS < 1.4, this file can be created in gaia/apps/settings/resources, and it allows you to set the network types supported by the device. Firefox OS supports the following types:

- - - -

An example is as follows:

- -
{
-  "types":  [
-    "cdma/evdo",
-    "cdma", "evdo"
-  ]
-}
- -

sensors.json

- -

Defines the sensor capabilities of the device. By default it contains:

- -
{ "ambientLight": true }
- -

You can set the value to false if you want to disable device sensor capabilities.

- -

settings.json

- -

This file allows you to set default wallpaper/ringtones, lockscreen enable/disable, bluetooth on/off, etc. You can consult build/config/common-settings.json to find out what settings can be set in settings.json;  for example you can set "wifi.enabled": false to disable wifi by default.

- -

Customize default Homescreen APP

- -

homescreen.appName allows you to set specific APP as default Homescreen APP.

- -
-
{ "homescreen.appName": "homescreen-stingray" }
-
- -

sms-blacklist.json

- -

This file contains a custom SMS blacklist: numbers specified in this file can't have SMS message sent to them. This list will overwrite blacklist.json file in the SMS app. The numbers are specified in an array, like so:

- -
["11223344", "55667788"]
- -

cellbroadcast

- -

Listening Channels:

- - - -

Disable event reporting:

- - - -
-

Note: Default settings are available in operator_variant.xml.

-
- -

support.json

- -

This file contains support contacts, including online support & telephone support. When included, this file will overwrite support.json in the Settings app. Since these customizations will overwrite the default settings, if you want to keep default settings and add some extra resources you should copy those settings from the built-in apps and add your own customization onto them.

- -

Here's an example of what the JSON should look like:

- -
{
-   "onlinesupport": {
-     "href": "http://support.mozilla.org/",
-     "title": "Mozilla Support"
-   },
-   "callsupport": [
-     {
-       "href": "tel:12345678",
-       "title": "Call Support 1"
-     },
-     {
-       "href": "tel:87654321",
-       "title": "Call Support 2"
-     }
-   ]
- }
- -

WAP user agent profile (wapuaprof.json)

- -

The WAP user agent profile overrides the user agent information when sending WAP packets. If you want to override the default WAP user agent profile based on MCC/MNC, you can use this one to do it  (further explained in runtime customization).

- -

apps.list

- -

This allows you to specify which apps you want to load up at runtime (in a similar manner to variant.json, as explained in the Applications section below.) The applications are specified like so:

- -
apps/*
-external-apps/*
-outoftree_apps/*
- -

You can specify individual apps rather than whole folders of apps, like this:

- -
apps/email
-apps/settings
- -
-

Note: If you want to include custom external apps as part of your Gaia build, you need to build them in a specific way, and then place them into the gaia/external-apps/ folder. Read Building Prebundled web apps to find out how.

-
- -
-

Important: Apps that you add as part of a customized Firefox OS build need to be added in agreement with Mozilla's Distribution Agreement.

-
- -

Other customization options

- -

There are many other customizations that can be made, which we should explore more. Let's look at them now.

- -
-

Note: The build script used in many of the below sections can be found in gaia/build/applications-data.js. This gets copied into an init.json file in the browser app directory at build time.

-
- -

Browser bookmarks and default search engine

- -

The default bookmarks and default search engine can be customised at build time, with different variants for each country and network in a single build. The customised data is inserted into the browser app the first time it is run, based on the MCC and MNC codes of the SIM card present in the device at the time.

- -
-

Note: Bookmarks can be customised in Firefox OS 1.0.1+; default search engines can be customised in Firefox OS 1.2+.

-
- -

The example below (browser.json) shows a configuration for Vivo in Brazil (724006, where 724 is Brazil and 006 is Vivo according to the MCC and MNC codes), along with a default fallback (000000) in case a non-matching SIM card or no SIM card is present.

- -
content = {
-   '000000': {
-     'bookmarks': [
-       { 'title': 'Mozilla',
-         'uri': 'http://mozilla.org',
-         'iconUri':
-           'data:image/png;base64,AAABAAIAEBAAAAEAIABo[truncated]'
-       },
-       { 'title': 'Firefox OS',
-         'uri': 'http://mozilla.org/firefoxos',
-         'iconUri':
-           'data:image/png;base64,AAABAAIAEBAAAAEA[truncated]'
-       }
-     ],
-     'searchEngines' : [
-        {
-          'title': 'Google',
-          'uri': 'http://www.google.com/search?q={searchTerms}',
-          'iconUri':
-            'data:image/png;base64,AAABAAIAEBAAAAEAIABoBAA[truncated]'
-        }
-      ],
-      'settings' : {
-        'defaultSearchEngine': 'http://www.google.com/search?q={searchTerms}'
-      }
-   },
-
-   '724006': {
-     "bookmarks": [
-       { "title": "Vivo Busca",
-         "uri": "http://www.google.com.br/m/search",
-         "iconUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC[truncated]"
-       },
-       { "title": "Serviços e Downloads",
-         "uri": "http://vds.vivo.com.br",
-         "iconUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACA[truncated]"
-       },
-       {
-         "title": "Site Vivo",
-         "uri": "http://www.vivo.com.br/conteudosmartphone",
-         "iconUri": "data:image/jpg;base64,/9j/4AAQSkZJRg[truncated]"
-       }
-     ],
-     'searchEngines' : [
-        {
-          'title': 'Yahoo',
-          'uri': 'http://search.yahoo.com/search?q={searchTerms}',
-          'iconUri':
-            'data:image/png;base64,AAABAAIAEBAAAAEAIABoBAA[truncated]'
-        }
-      ],
-      'settings' : {
-        'defaultSearchEngine': 'http://search.yahoo.com/search?q={searchTerms}'
-      }
-   }
- };
- -

In the example, if a Vivo SIM card from Brazil is entered on first run the user will see Vivo bookmarks and Yahoo as the default search engine. If another SIM card or no SIM card is entered on first run the user will see Mozilla bookmarks and Google as the default search engine. There are a few important parts to note:

- - - -
-

Note: The browser application will show bookmarks in reverse order, the first bookmark in the json will be shown the last one and so on.

-
- -

Data and messaging settings

- -

Device data and messaging settings are runtime customizable.

- -

To apply specific settings, change gaia/shared/resources/apn/apns_conf_local.xml, simply adding or editing carrier blocks as required:

- -
 <apn carrier="Test Network"
-      mcc="001"
-      mnc="01"
-      apn="internet"
-      user="user"
-      password="password"
-      proxy="127.0.0.1"
-      port="8080"
-      mmsc="http://127.0.0.1"
-      mmsproxy="127.0.0.1"
-      mmsport="8080"
-      authtype="0"
-      type="default,supl,mms"
-  />
- -

Voicemail and cell broadcast settings

- -

To apply specific voicemail and cell broadcast settings, change gaia/shared/resources/apn/operator_variant.xml. Add or edit a carrier block, changing attributes as needed:

- -
   <operator carrier="Test Network with Operator Variant Settings"
-       mcc="001"
-       mnc="01"
-       cellBroadcastSearchList="0,1,2,3"
-       voicemail="999999"
-   />
- -

WAP user agent profile

- -

The WAP user agent profile is another app that supports runtime customization. It overrides the user agent information when sending WAP packets, based on MCC/MNC. The profile overriding has url and tagname parts, but we only support url in our current implementation.

- -

The WAP user agent profile uses the same coding style for its key as the browser app, although "000000" is used as the default profile. An example follows:

- -
   {
-     "000000": {
-       "url": "http://example.url/default.xml"
-     },
-     "123001": {
-       "url": "http://example.url/custom123001.xml"
-     }
-   }
- -

In this example, the url of the default profile is http://example.url/default.xml; for mcc = 123 and mnc = 001, the url is http://example.url/custom123001.xml. If there was another ic card with mcc = 123 and mnc=100, its url would be http://example.url/default.xml.

- -

If the 000000 is removed from this example, like so:

- -
  {
-     "123001": {
-       "url": "http://example.url/custom123001.xml"
-     }
-   }
- -

the url of UA profile of ic card with mcc = 123, mnc = 001 is now overridden as http://example.url/custom123001.xml. No others will be overridden.

- -

If we have the "000000" as before, but we also have a "123001" case with no url inside it, like so:

- -
   {
-     "000000": {
-       "url": "http://example.url/default.xml"
-     },
-     "123001": {}
-   }
- -

All UA profile urls are now overridden as http://example.url/default.xml

- -

Applications

- -

Applications installed in Firefox OS can be customized at runtime, in a number of ways (see also Customizing the build-time apps). Perhaps the most powerful way is to edit the variant.json configuration file, which allows apps to be selectively installed and placed in the desired position in the homescreen, depending on the MCC/MNC. The customized applications will be added to the standard applications list.

- -

The relevant part of the variant.json file typically looks like so.

- -
   {
-     "apps": {
-       "puzzle":
-         {
-           "manifestURL": "https://owd.tid.es/store/packages/fe8e4a866c518a42db9d2041568684c1.webapp"
-         },
-       "store":
-         {
-           "manifestURL": "https://owd.tid.es/store/manifest.webapp",
-           "installOrigin": "https://www.openwebdevice.com"
-         }
-     },
-     "operators": [
-       {
-         "id": "movistar-co",
-         "mcc-mnc": [
-           "214-01",
-           "214-02"
-         ],
-         "apps": [
-           {
-             "id": "store",
-             "screen": 0,
-             "location": 2
-           }
-         ]
-       },
-       {
-         "id": "movistar-mx",
-         "mcc-mnc": [
-           "215-23"
-         ],
-         "apps": [
-           {
-             "id": "store",
-             "screen": 0,
-             "location": 2
-           },
-           {
-             "id": "puzzle"
-           }
-         ]
-       }
-     ]
-   }
- - - -

Support contacts, default contacts, wallpaper & ringtone

- -

The same file variant.json file — used to configure applications at runtime depending on the MCC/MNC — also allows you to configure specific resources by adding some attributes under each operator object. Thus, an operator can have the following settings:

- -
   { apps: ...
-     "operators": [
-       {
-         "id": "movistar-co",
-           "mcc-mnc": [
-             "214-01",
-             "214-02"
-           ],
-         "apps": [
-           {
-             "id": "store",
-             "screen": 0,
-             "location": 2
-           }
-         ],
-         "support_contacts": "resources/support_contacts_movistar.json",
-         "default_contacts": "resources/contacts_movistar.json",
-         "ringtone": {
-           "path": "resources/Movistar_Mid_ABR_128kbps.ogg",
-           "name": "Tono Movistar"
-         },
-         "wallpaper": "resources/customize.jpg"
-       },
-       ...
-   }
- -

For each operator:

- -
    -
  1. support_contacts specifies a path to a file containing contacts to be shown on the help screen (Settings > Help), offering the same functionality as support.json. The file format is: - -
       {
    -     "onlinesupport": {
    -       "title": "Mozilla Support",
    -       "href": "http://test.mozilla.org/support"
    -     },
    -     "callsupport1": {
    -       "title": "Call Support (Primary)",
    -       "href": "tel:14155550001"
    -     },
    -     "callsupport2": {
    -       "title": "Call Support (Secondary)",
    -       "href": "tel:14155550002"
    -     }
    -   }
    -
  2. -
  3. default_contacts contains the path to a file containing contacts that will be preloaded to the Contacts application, depending on the MCC/MNC pair present at run time. The section names are the MCC/MNC pair, and section contents should be an array of contacts following the same format as contacts.json. For example: -
        {
    -        "123123":
    -        [
    -            {name: ["John Doe"]},
    -            // etc
    -        ],
    -    }
    -
    -
  4. -
  5. ringtone sets the default ringtone and contains two attributes, both mandatory: -
      -
    • path: The path to the ringtone audio file.
    • -
    • name: The name to display when the ringtone is shown in settings.
    • -
    -
  6. -
  7. wallpaper contains the path to the image file (PNG) that will be set as a default wallpaper.
  8. -
- -

Building Prebundled web apps

- -

Earlier on, we discussed the apps.list file, and how this can be used to add built-in apps to your build. These apps need to be built in a certain way, then added to the gaia/external-apps directory.
-
- To build Prebundled web apps, you can utilize our gaia-preload-app script, which builds a prebundled webapp from a given .webapp URL. It can accept hosted web app manifests, or packaged app mini-manifests.

- -

To bundle a single web app

- -

Find a .webapp URL that want to bundle, and run the command to bundle it, as follows:

- -
python preload.py http://<webapp url>
- -

This will generate a directory with the same name as the target webapp's name, e.g. accuweather.

- -

Batch process to bundle multiple web apps

- -

You can create a file called list, containing all the app names and .webapp locations you want to bundle all together in a batch. The format is:

- -
    myFirstApp,https://www.firstapp.com/manifest.webapp
-    mySecondApp,https://www.secondapp.com/manifest.webapp
-    etc.
- -

You need to save this list file in the same directory as our preload.py script, then run the following command:

- -
    $ python preload.py
- -

The preload.py script will parse the list file and do the batch conversion for you.

- -

Prebundled web app metadata.json

- -

Every Prebundled webapp should have a metadata.json file contained within its root directory. The Firefox Marketplace counts on this metadata.json file for auto-updating. This file is auto-generated by the preload.py script.
-
- For a hosted webapp, the properties of metadata.json are:

- - - -

For a packaged webapp, the properties of metadata.json are:

- - - -

Packaged web app update.webapp format

- -

Packaged webapps have an update.webapp file, which is used for auto-updates. The format is similar to manifest.webapp, but you have to include additional attributes:

- - - -
  {
-    "name": "Game Pack",
-    "icons": {"60": "/icon-60.png", "128": "/icon-128.png"},
-    "version": "1.1.2",
-    "package_path": "/application.zip",
-    "developer": {"url": "http://abc.com", "name": "abc Inc."},
-    "release_notes": "2nd release",
-    "locales": {"es": {"launch_path": "/index-es.html", "description": "show me customization."}},
-    "size": 5460141
-  }
- -

Pre-bundled web app AppCache format

- -

If your web app's manifest.webapp has an appcache_path included in it, the preload.py script will fetch the AppCache file  pointed to, and pre-fetch all the resources described in the AppCache file. The Pre-bundled webapp AppCache is a bit different, as Gecko recognizes a different format, but this is auto generated by the preload.py script.

- -

The translated file structure is:

- -
    <app name>
-       ├── manifest.webapp
-       └── cache
-             ├── manifest.appcache
-             └── <resources>
-
- -
-

Note: If a different name is given to the AppCache file in the appcache_path, it needs to be renamed to manifest.appcache and saved in the cache folder.

-
- -

FAQ

- -

The following is a list of common questions about market customizations, and their answers.

- -

What can be customized?

- - - -

How and where do you define a customized app grid layout?

- -

This is currently defined in gaia/apps/homescreen/js/init.json. customize.py takes care of building this in the correct format.

- -

Is it possible to define whether an app is removable in the homescreen configuration?

- -

No. All apps in /system/b2g are non removable, those in /data are removable. Since all preloaded apps come from /system, we need to move them to /data if we want them to be removable.

- -

How do you add a preloaded packaged or hosted app to the build?

- -

These should both be added to gaia/external-apps. customize.py will allow entry of the URL to a packaged app or a hosted app manifest, and will download it into the correct place and create metadata.json. This will serve as the "build step".

- -

We have different metadata for packaged and hosted apps to distinguish them.

- -

See Building Prebundled web apps for more details.

- -

How do you prepare a preloaded hosted app for initial offline support?

- -

You need to provide all the files to cache in the directory external-apps/MY_APP/cache, along with the AppCache manifest.

- -

Again, see Building Prebundled web apps for more details.

- -

What Marketplace Customizations Are Possible?

- - - -

There are many other considerations when adding a region or carrier.  See Adding Regions and Carriers for more details.

- -

How do I package and store per-market customization changes?

- -

Store only the files changed; currently these are in various locations in the filesystem. In B2G v2, we are considering consolidating these into a single location, similar to the branding directories we have for Gecko.

- -

How do you build the product with a specific market's configuration?

- -

Copy your changed files into a checkout of Gaia, and build using that modified Gaia. customize.py will provide a UI for setting relevant switches, create the appropriate files in the appropriate places in the gaia checkout, and then build the profile from that gaia.

- -

How to customize power on / off animation?

- - diff --git a/files/zh-cn/archive/b2g_os/developing_firefox_os/modifying_hosts_file/index.html b/files/zh-cn/archive/b2g_os/developing_firefox_os/modifying_hosts_file/index.html deleted file mode 100644 index 569bd5b114..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_firefox_os/modifying_hosts_file/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: 修改 hosts 文件 -slug: Archive/B2G_OS/Developing_Firefox_OS/modifying_hosts_file -tags: - - Android - - B2G - - Firefox OS - - hosts -translation_of: Archive/B2G_OS/Developing_Firefox_OS/modifying_hosts_file ---- -
-

由于遭受攻击,阻止不希望的连接,将请求重定向到一个特定 IP 等原因,有时您需要对机器上的 hosts 文件进行编辑。本文则阐述了如何修改您 Fiefox OS 手机上的 hosts 文件。 在 Linux 系统下,它位于 /system/etc 目录下,而在 Mac OSX 系统下,位于 /etc 目录下。

-
-

准备您的手机

-

打开手机,进入开发者设置面板Developer settings panel 检查一下:

- -

将手机插入您的电脑上。

-

下面,修改 hosts 文件的步骤就与 Android 相同了。 Android开发者则能够快速的进行设置。

-

终端中的步骤

-
    -
  1. 打开终端窗口
  2. -
  3. 重新装载设备上的 /system 分区,以获得读-写 权限。 -
    adb remount
    -
  4. -
  5. 在电脑上获取 hosts 文件 -
    adb pull /system/etc/hosts /tmp
    -
  6. -
  7. 按照所需修改 /tmp/hosts 文件并保存。例如 : -
    127.0.0.1         localhost
    -ip.to.re.direct   hostName
    -
  8. -
  9. 将修改的 hosts 文件推送到设备 -
    adb push /tmp/hosts /system/etc/hosts
    -
  10. -
-

这样就完成啦,您的 hosts 文件现在就应更新啦。

-
-

注意: 要了解更多关于 ADB 的内容,请参考 ADB 文档

-
-

 

diff --git a/files/zh-cn/archive/b2g_os/developing_firefox_os/quickstart_guide_to_gaia_development/index.html b/files/zh-cn/archive/b2g_os/developing_firefox_os/quickstart_guide_to_gaia_development/index.html deleted file mode 100644 index 6000b95c7d..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_firefox_os/quickstart_guide_to_gaia_development/index.html +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: Gaia 开发快速入门 -slug: Archive/B2G_OS/Developing_Firefox_OS/Quickstart_guide_to_Gaia_development -translation_of: Firefox_OS/Developing_Gaia ---- -
-

本指南提供了关于Gaia apps调试和开发的快速入门步骤,内容包括在桌面版Firefox中运行Gaia和Firefox OS App Manager中运行Gaia。 在阅读指南之前,您需要具备如下条件: 了解HTML5技术,熟悉MVC设计模式并且对Firefox OS 有着强烈的兴趣。在学习完成本指南后,您能够掌握如下知识: Gaia app的基本架构,修改Gaia apps的基本工作流程以及如何对apps进行测试。

-
- -

您需要什么?

- -

有两种方式对Gaia/B2G的开发环境进行配置,分别是配置本地的环境或者使用 FoxBox 编译环境. 下面就让我们分别通过这两种方式来运行Gaia吧!

- -

配置本地环境

- -
    -
  1. 首先,您要完成对Git的安装.如果您更喜欢在可视化环境下工作,可以考虑安装下Github客户端 (GitHub for Mac / GitHub for Windows).Git可以更新代码,对更改进行提示以及观察其他开发者的工作,因此十分有必要来熟练掌握它。
  2. -
  3. 然后就是在本地机器上要获得一份Moziila Gaia的仓库: https://github.com/mozilla-b2g/gaia. 最好的方式就是fork这份仓库,并且通过使用命令git clone https://github.com/<your github name>/gaia.git.将您fork的仓库clone到本机的电脑上。由于仓库相当大,大约在700M左右,可能需要花费一些时间。
  4. -
  5. 完成上面的步骤,您就可以在终端中进入仓库 (cd gaia) 并且运行 DEBUG=1 make 命令编译以及配置调试模式下的Gaia仓库。命令运行中会下载 XULRunner -- 我们可以使用它对Mozilla运行时的包进行安装,更新和卸载,还可以使用它执行所需的编译步骤。 -
    Note:如果您想要了解更多,可参考Gaia Make options
    -
  6. -
  7. 在完成工作区的配置后, 就需要来安装Firefox Nightly 版本
  8. -
  9. 在Nightly版本中, 可以选择是使用火狐仿真器扩展插件还是App Manager插件,这主要取决于您到底喜欢哪种工作流程.如果身边没有可用的物理设备,但选择使用APP Manager的方式,虽然 The App Manager 扩展插件已经预安装在nightly 版本中,但是您仍然需要安装 Firefox OS simulator
  10. -
  11. 安装 ADB helper 来调试手机等远程设备。
  12. -
  13. 您可能想要获得一部 Firefox OS 手机. 在手机上可以获取到诸如应用程序的启动事件,帧速率等各种使用信息。同样,一旦能够在设备上运行真实的操作系统,您也可以轻松的对所有支持的设备APIs进行测试。
  14. -
- -

配置FoxBox虚拟环境

- -

FoxBox是指包含在VM(虚拟机)中的Firefox OS编译环境,由 Vagrant 和 VirtualBox提供。它有许多优点,最主要的就是在可以为您完成大量的配置工作,从而使您能够专心的进行开发工作。要了解它的完整的内容,可以阅读  FoxBox GitHub repo README.

- -

现在您已经完成了基本工作区的配置,让我们下面一起向应用进发吧!

- -

Firefox OS  原生应用

- -

Gaia 源码中提供的原生的HTML5应用如下所示:

- - - -

当手机开机时,第一个启动的应用是系统应用(System app)。该应用主要是负责打开和管理主屏幕。在主屏幕界面则可以启动其他的应用以执行以执行各种功能。例如,当用户点击手机图标时,则会从主屏幕启动拨号盘应用 。当用户在拨号时想要查看联系人列表时,又可以启动联系人应用。

- -

一起来探索下一些应用的结构

- -

原生应用都存放在 gaia/apps/ 文件夹下. 每个 Gaia 应用的文件夹下都包含下面的组件:

- - - -

有一些应用还可能有下面的组件:

- - - -
-

重要: 除了上面列举的文件外,还可能会存在一些额外的文件,比如LazyLoaders以及定制的模板引擎和其他一些关于应用的优化。你也可能会注意到,在不同的应用或者 .js 文件中使用的模式也不尽相同。 记住,这是一个开源的app/OS, 它是由很多人编码而成的,因此这些应用也是使用不同的模式和编程风格而完成的。

-
- -
-

注意:本节是对Gaia应用总体布局的介绍。您自己在创建web应用时,当前必须要创建的文件只有  manifest.webapp文件;其他的文件都是可选的。

-
- -

我相信,如果您有关于web开发的经验,就会尽其所能的对一些app进行修改,从而使它们不断得到完善。

- -

我们一起来启动一些应用吧

- -

在对这些应用进行修改后,如果想立刻看到修改后带来的变化,可以通过下面的几种方式来实现:在  Firefox Nightly中运行,将应用推送到物理设备端,或者通过Firefox OS 应用管理器(可以在模拟器上或者真实设备上)运行。

- -

运行在Firefox Nightly中

- -

要在Firefox Nightly中运行Gaia以及查看应用 , 需要使用下面的结构来运行命令:

- -
/path/to/firefoxnightly -profile /path/to/B2G/gaia/profile-debug -no-remote
- -

例如在Mac OS X中,可以运行下面的命令:

- -
/Applications/FirefoxNightly.app/Contents/MacOS/firefox -profile /Users/bob/git/gaia/profile-debug -no-remote
- -
-

Note: -no-remote 是用来阻止使用已存在的Firefox实例,从而创建一个新的Firfox应用来运行定制的Gaia配置文件。 profile-debug 是指运行Gaia调试模式下的配置文件,该文件是使用之前步骤中的 DEBUG=1  make command 命令生成。

-
- -

在启动时会耗费一些时间,但是最终Gaia实例以及许多控制选项会在一个新的浏览器窗口中运行。

- -

A UI screen showing the Gaia user interface running in Firefox nightly: a phone screen and number of tool bar controls.

- -

另外如果您只想在浏览器中运行一个应用,一个更加快速的方法就是在浏览器中通过file://URL的格式简单的输入应用的根HTML文件(例如在浏览器中打开index.html)。然后可以使用 Responsive Design View 工具观察在小屏幕分辨率的效果. 如果想要做一些快速UI开发/调试的工作,这是一个非常有用的方法,而且在实例装载方面也有许多优势。此时,火狐开发者工具也是十分有用的,例如测试CSS调整的效果。

- -
-

注意: 由于该方法并不能对硬件设备进行访问,因此有许多功能都无法工作,再加上你无法看到app启动的过程,在主屏幕看到图标等弊端,比较而言,运行在物理设备上还是最好的办法,这在下面章节中有介绍。

-
- -

运行在物理设备上

- -

要将更改后的Gaia推送到物理Firefox OS 设备,您需要:

- -
    -
  1. 已完成对 adb 的安装或者安装了前面描述的l ADB helper .
  2. -
  3. 在终端中输入adb devices命令来检查您的手机是否和电脑通过 adb 命令建立了成功的连接。
  4. -
  5. 在Gaia目录下输入make reset-gaia 命令从而通adb推送到手机
  6. -
- -

这种方式会耗费些时间,如果使用App manager则会更快一些。

- -

在 App Manager中运行

- -

只要您的Firefox 版本在1.2以上,就可以在App Manager中运行更改后的app,在下节会对该部分内容进行介绍。

- -

使用 App Manager来调试

- -

在完成对应用的更改后(或者创建新的应用 ),就可以在App Manager来调试它们。

- -

在调试之前,需要具备下面的条件: App Manager和设备之间能够正常通信,如果没有物理设备可以使用 Firefox OS 仿真器。这些条件在使用App Manager 有详细阐述。

- -

下面就是选择想要调试的应用了 — 在 App Manager中添加包应用控制,并选择要调试的应用的文件夹。首次操作应用时,需要点击“Start”按钮将应用安装在 设备端/模拟器端并启动它。之后就可以点击“Update”按钮将更新推送到设备/模拟器端,而且使用Mozilla的开发工具在设备端对应用直接调试。

- -

例如,下面就是在App Manager中运行 Contacts 应用的图示。

- -

A card showing details of the Gaia contacts app: a simple contacts application.

- -

同时也可以去尝试下调试的一些功能,例如,运行一些终端命令或者对更改CSS特性。

- -

A screenshot of the Mozilla App Manager

- -

为项目贡献代码

- -

只要您对自己在Gaia仓库中的更改感到满意,就可以向GitHub上的代码库提交pull请求。如果您不知道怎么做,可以去参考GitHub 帮助页面的 Using Pull Requests

- -

实际上,您的pull请求如果没有经过Gaia开发团队的讨论和认可是不会被接受的。 您可以在 dev-gaia@lists.mozilla.org 邮件列表, 或者是在 Mozilla IRC.的 #gaia IRC 通道与Gaia 开发团队进行联系。

- -

另外一个课程就是如何在Mozilla Bugzilla 系统中提交Bug。在提交Bug时,要使用  Firefox OS project bug form (选择 Gai或者一个合适的子集作为component). 但在提交Bug前,首先要在Bugzilla 中搜寻下问题是否已经被其他人提过。 如果没有,就需要考虑下面两点:

- - - -
-

注意:如果您不知道到底该怎么提bug,就是想要寻找一些相关的bug进行处理, 可以寻求 Josh Matthews' Bugs Ahoy 应用来帮忙。

-
- -

常见问题

- -

下面的内容是对在桌面上使用Gaia调试应用的一些常见问题的答案。

- -
-

Note: 多参考 Hacking gaia 中关于可以设置的make选项对调试Gaia是非常有帮助的。

-
- -

我能够在火狐桌面版浏览器中对高分辨率的设备进行仿真吗?

- -

必须的!

- -
    -
  1. 首先可以运行下面命令来确保在qHD和WVGA设备上图片是不失真的 -
    GAIA_DEV_PIXELS_PER_PX=1.5 DEBUG=1 make
    -
  2. -
  3. 然后,在火狐中打开 about:config页面,通过将layout.css.devPixelsPerPx 标志位变为1.5来更改浏览器的密度。
  4. -
  5. 最后,可以使用 Responsive Design View 变为320 x 533 px (这种设置与设备上 CSS  480 x 800 像素的效果是等价的 .)
  6. -
diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/customizing_build-time_apps/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/customizing_build-time_apps/index.html deleted file mode 100644 index 573e3ac09a..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/customizing_build-time_apps/index.html +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: 定制构建时 apps -slug: Archive/B2G_OS/Developing_Gaia/Customizing_build-time_apps -tags: - - Apps - - B2G - - Firefox OS - - Gaia - - 'l10n:priority' - - 定制 - - 指南 -translation_of: Archive/B2G_OS/Developing_Gaia/Customizing_build-time_apps ---- -
-

作为一个开发者或设备厂商,您可能由于各种原因想要对 Friefox OS 首次启动时的 app 进行定制。本文则说明了完成该需求的不同机制。

-
- -

Gaia 中的 App 存放位置

- -

运行在 Firefox OS 中的 app 都位于 Gaia 源码树下,共有两个存储位置:

- - - -

如果您想要在编译 Gaia/B2G 时忽略或添加这些 app, 有下面几种方式可以实现:

- -

野蛮的定制方法

- -

所谓“野蛮”的方法是指在编译前, 将不想要参与编译的 app 直接删除即可。

- -

编辑配置列表

- -

相比而言,更优雅的方法则是编辑 apps-*.list 文件 (位于不同的设备目录下,在  gaia/build/config/ 内部,如 phone/tablet/) ,将需要编译的 app 路径包括进去。例如,   gaia/build/config/phone/apps-production.list 格式如下所示:

- -
apps/bluetooth
-apps/bookmark
-apps/browser
-apps/calendar
-apps/callscreen
-etc.
- -

注意,您也可以使用如下代码指定目录下的所有 app:

- -
apps/*
- -

至于在编译时,具体选择哪个  apps-*.list 文件的代码在 gaia/Makefile 文件中指定来,其形式如下所示:

- -
GAIA_DEVICE_TYPE?=phone
-  ...
-GAIA_APP_TARGET?=engineering
-  ...
-ifeq ($(MAKECMDGOALS), demo)
-GAIA_DOMAIN=thisdomaindoesnotexist.org
-GAIA_APP_TARGET=demo
-else ifeq ($(MAKECMDGOALS), dogfood)
-DOGFOOD=1
-else ifeq ($(MAKECMDGOALS), production)
-PRODUCTION=1
-endif
-  ...
-ifeq ($(PRODUCTION), 1)
-GAIA_OPTIMIZE=1
-GAIA_APP_TARGET=production
-endif
-
-ifeq ($(DOGFOOD), 1)
-GAIA_APP_TARGET=dogfood
-endif
-  ...
-ifndef GAIA_APP_CONFIG
-GAIA_APP_CONFIG=build$(SEP)config$(SEP)apps-$(GAIA_APP_TARGET).list
-endif
- -

最初, GAIA_APP_TARGET 变2量被设置为 engineeringGAIA_DEVICE_TYPE 变量被设置成  phone, 因此默认情况下编译 Gaia 时会使用 gaia/config/phone/app-engineering.list (其中包括所有的测试,deomo 等)。

- -

要指定其他应用程序列表的用法,请在运行make命令时指定不同的选项。比如用 gaia/build/config/phone/apps-production.list 进行构建, 比如,你要使用:

- -
PRODUCTION=1 make
- -

如果你专门指定DEMO=1进行构建, 那么它将使用apps-demo.list. 如果你专门指定DOGFOOD=1进行构建, 则它将会使用apps-dogfood.list.

- -

你可以完全覆盖该决定通过编辑 GAIA_APP_CONFIG 文件在 gaia/Makefile目录中, 并提供你自己的 apps-*.list 文件.

- -

gaia/Android.mk 包括下面命令:

- -
ifneq ($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)
-GAIA_MAKE_FLAGS += PRODUCTION=1
-B2G_SYSTEM_APPS := 1
-endif
- -

当你构建的时候, 如果 VARIANT=user 或者 VARIANT=userdebug 被设定 (这些将会在 TARGET_BUILD_VARIANT 变量中反映), PRODUCTION=1 在构建Gaia时会自动设置.

- -
-

注意: 要了解其他有效的 make 选项,请参考 make options 参考文档

-
- -

使用市场化定制

- -

第三种也是最完善(但最复杂)的方法是使用自定义方式.这将允许您在单独的目录中指定构建时的自定义说明,而无需修改Gaia的核心存储库。 您可以再不同的目录中包括自己的自定义项,或者使用源附带的目录。

- -

例如,使用GAIA_DISTRIBUTION_DIR 这个环境变量来指定自定义示例的位置, 像这样:

- -
GAIA_DISTRIBUTION_DIR=<DISTRIBUTION_PATH> make production
- -

更多有关分发机制的自定义实例请参考以下网页https://github.com/mozilla-b2g/gaia/tree/master/customization

- -

定制完全属于您的个人主题,要了解更多信息,欢迎访问我们的市场定制指南Market Customizations guide.

- -
-

注意: 如果您希望在 Gaia 编译时包含一些自定义的外部 app, 则需要以指定的方式编译它们,并且将它们放在  gaia/dev-apps/ 文件夹中。请参考 Building Prebundled web apps  获取更多内容。

-
- -
-

重要: 如果您是创建自定义B2G/Gaia 版本进行分发的设备供应商,则需要满足一些条件才能将firefox marketplace应用程序包含在手机/平板电脑等设备中。有关更多详细信息,欢迎联系Mozilla!

-
diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/customizing_the_keyboard/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/customizing_the_keyboard/index.html deleted file mode 100644 index 64b9152bc5..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/customizing_the_keyboard/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: 在 Firefox OS 中定制键盘 -slug: Archive/B2G_OS/Developing_Gaia/Customizing_the_keyboard -translation_of: Archive/B2G_OS/Developing_Gaia/Customizing_the_keyboard ---- -
-

This document explains how to add custom keyboard layouts containing their own languages/scripts to Firefox OS v1.2 and up.

-
-

Gaia 内置键盘 app 状态 & system 架构

-

Two major features have been implemented in Firefox OS, as of October 2013.

- -

To come up with a new keyboard layout, you can put a layout file in Gaia, build the keyboard app using a build config, or come up with your own keyboard app and install it on the phone.

-

如何生成一个键盘应用 (keyboard app)

-

You can use Gaia's built-in keyboard app as a template, or fork it. The basic ideas are:

- -

After that, you can install your keyboard, and it will show up on the bottom half of the screen whenever the user is focused to an input field. The space issues that arise from this can be dealt with by:

- -
-

TBD: provide sample code and/or a small template app

-
-

How to add a custom layout to your template in the Gaia keyboard app

-
    -
  1. See the keyboard CONFIGURE details for more information. Depending on the language you might want to add a dictionary, or include an interactive IME (for Asian languages).
  2. -
  3. If you add layouts for a newly supported language, you may want to add them as default layouts for that language in build/config/keyboard-layouts.json.
  4. -
-

Spell check / word suggestion dictionary

-
-

TBD

-
-

Asian IME

-

East Asian languages (Chinese, Japanese, and Korean) use a fairly complex script that involves thousands of characters. As there is no way to put thousands of keys on a hardware or software keyboard, users rely on an indexing program called input method, or IME for short, to convert a series of symbols into selections of characters.
-
- How symbols should be converted and how "smart" the IME should be depends on the method chosen, implementation itself, and often NLP science, which is outside the scope of this document. Note that it is highly recommended to put the database part into IndexedDB, in order to conserve memory on a mobile device.

-

IM Engine interface in Gaia keyboard app

-

Assuming you have an IME library readily available for converting symbols into characters (''IM Engine'' in our terminology), you would need to use the defined interface within the Gaia Keyboard app to receive symbols from the layout and output the characters. The current API is documented on Github.

-

We invite implementations in order to further refine this API within Gaia.

-

Make your IM engine work with your layout

-

To get your IM engine working with your keyboard layout:

-
    -
  1. Put a new layout in layout.js as described in the previous section.
  2. -
  3. Reference the IM engine with the imEngine property. When your layout is enabled, the keyboard app will start loading the script located at keyboard/js/imes/<imEngine>/<imEngine>.js.
  4. -
  5. Set up the APIs to receive and send the keys/characters when the script is loaded and init'd.
  6. -
  7. Do whatever you want in response to the user input. When the user taps any keys on the keyboard, it would typically get sent to the IM engine.
  8. -
-

Known implementations

- -

讨论和问答

-

Please come to the dev-gaia mailing list or the #gaia channel on irc.mozilla.org. #mozilla-taiwan is the de-facto Chinese-language channel for this topic.
-
-  

diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/different_ways_to_run_gaia/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/different_ways_to_run_gaia/index.html deleted file mode 100644 index c77e27efea..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/different_ways_to_run_gaia/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: 运行 Gaia 的不同方式 -slug: Archive/B2G_OS/Developing_Gaia/Different_ways_to_run_Gaia -translation_of: Archive/B2G_OS/Developing_Gaia/Different_ways_to_run_Gaia ---- -
-

您可以通过 App Manager中,在 Desktop Firefox 中直接运行,作为专用桌面版本(Desktop B2G), 在仿真器中, 或在可兼容的移动设备中运行 Gaia。本文则对上述每个方式如何实现的进行总结,以及链接到更深的内容。

-
-

它与真实的东西有多接近?

-

Some of the solutions for running Gaia detailed in this article are closer to the experience on a real device than others. The order of ease for running is as follows:

-
    -
  1. Gaia in simulator
  2. -
  3. Gaia in Desktop Firefox
  4. -
  5. Gaia in B2G Desktop
  6. -
  7. Gaia in Emulator
  8. -
  9. Gaia flashed on phone
  10. -
  11. Gaia+Gecko flashed on phone
  12. -
-

The order of “how close it is to the shipped product” is exactly the opposite of this. Depending on the feature you’re working on, you’ll have to find the environment that suits the problem.

-

在 App Manager/Firefox OS simulator 中使用 Gaia

-

The quickest way to try Gaia is via the Firefox App Manager.
-
- App Manager is a developer tool available in Firefox for Desktop. It provides a number of useful tools to help you test, deploy and debug HTML5 web apps on Firefox OS phones and the Firefox OS Simulator, directly from your browser.
-
- In desktop Firefox Browser 26+, open the App Manager using Tools > Web Developer > App Manager. Tap Start Simulator (once you've installed it) and you are ready to experience Firefox OS.

-

B2G Desktop

-

B2G Desktop is a desktop build of the app runtime used on Firefox OS devices which you can use to run Gaia on your desktop computer.

-

You can download a nightly build of B2G desktop from the Firefox Nightly site. Depending on what version you are targeting, you may want a specific version of latest-mozilla-b2g18. There are builds for Linux (32 bit and 64 bit), Mac OS X and Windows.

-

Nightly builds come packaged with a recent version of gaia. Once you've downloaded the archive, all you need to do is extract it to a folder and run the b2g binary from the extracted folder.

-
$ cd b2g
-$ ./b2g
-

To run B2G with your own version of Gaia for development purposes you first need to build a profile from your clone:

-
$ cd /path/to/gaia
-$ DEBUG=1 DESKTOP=0 make
-

This will generate a directory in your gaia directory called profile. The DEBUG part runs Gaia as hosted apps on a built-in web server, rather than the default packaged apps which have to be re-packaged after every change. You can find the path to the profile directory by taking a look at last line of output after running the above command, which should look like:

-
Profile Ready: please run [b2g|firefox] -profile /path/to/gaia/profile
-

You can then run B2G Desktop with your generated profile like so:

-
$ ./b2g /path/to/gaia/profile
-

If you want to you can build your own B2G desktop from source.

-
-

Note: On Mac OS X, the b2g binary will be inside B2G.app. To run B2G Desktop on this platform you will need the following command:
- ./B2G.app/Contents/MacOS/b2g /path/to/gaia/profile

-
-

在 Desktop Firefox 中使用 Gaia

-

It's also possible to run Gaia inside of Firefox. This gives you the advantages of having a rapid development cycle, as well as standard web development tools and debuggers. See Running the Gaia codebase for details on how to do this.

-
-

Note: FoxBox is a Firefox OS build environment contained in a VM (Virtual Machine), powered by Vagrant and VirtualBox. This has many advantages, but the main one is that it does a lot of configuration for you, leaving you to get on with development work. For full instructions, read the FoxBox GitHub repo README.

-
-

在真实设备中烧写 Gaia

-

要在真实设备上烧写新版本的 Gaia 需要下列步骤:

-
    -
  1. 首先请确认您本地的电脑上有 Gaia 仓库,并且 ADB 已安装。
  2. -
  3. 确认您已经使能  Debugging via USB 选项。
  4. -
  5. 通过 USB 将您的设备连接到电脑上。
  6. -
  7. 如果您有一个连接的设备,可以继续下面的命令。或者您( Windows 或 Linux 系统的用户)可能需要检查下 OEM USB 驱动页面来对您电脑中的 USB 驱动进行正确配置。
  8. -
  9. 在 Gaia 仓库中运行下面命令以对手机进行复位以及更新您的 Gaia 源码: -
    $ make reset-gaia
    -
  10. -
  11. 要测试非 System app, 您可以在不重启设备情况下运行下面命令来安装: -
    $ make install-gaia
    -
  12. -
  13. 如果您只是想安装一个指定的 app, 可以通过 APP 变量来完成, 就如下面的命令: -
    $ make install-gaia APP=browser
    -
  14. -
-

要检查您的设备是否已正确的通过 USB 连接, 可以键入下面命令:

-
$ adb devices
-

您应该获取到如下类似的结果:

-
List of devices attached
-emulator-5554  device
-

编译 Gecko 和 Gaia 并在仿真器或真实设备中使用

-

如果您有一个可兼容的移动设备,则可以 编译和安装您自己的 Firefox OS 版本 并且将其运行在仿真器或推送到实际设备上。

diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/index.html deleted file mode 100644 index ea781858de..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/index.html +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Gaia 开发 -slug: Archive/B2G_OS/Developing_Gaia -translation_of: Archive/B2G_OS/Developing_Gaia ---- -
-

Gaia 是 Firefox OS 用户界面及一套原生app:它包括 lock screen, home screen, dialer, 以及其他应用。简而言之,Gaia是运行在Firefox OS 平台的一个复杂的web应用集合 。这组文档会涵盖为Gaia工程贡献代码所需要的所有知识。

-
-

在本指南中,我们会带您为 Gaia 贡献代码的有效的工作流程—此处的贡献是指为 Gaia 代码库添加新的功能以及为 Gaia 工程解决bug。第一组文档是需要顺序阅读的,但如果您需要更新下您在特定步骤的知识,也可以阅读指定的章节。

-

后面,我们就会提供包括额外主题的参考资料和信息。

-

-

基础

-
    -
  1. 运行 Gaia 代码库
  2. -
  3. 理解 Gaia 代码库
  4. -
  5. 修改 Gaia 代码
  6. -
  7. 测试 Gaia 变化的代码
  8. -
  9. 提交 Gaia patch
  10. -
-

Gaia 构建参考

- -

参考

- -

- -
-

加入 Gaia 社区

-
-
请选择你喜欢的方式加入我们:
- -
-
- -
-
-

diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/localizing_firefox_os/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/localizing_firefox_os/index.html deleted file mode 100644 index dfd446cac6..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/localizing_firefox_os/index.html +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: Firefox OS 本地化 -slug: Archive/B2G_OS/Developing_Gaia/Localizing_Firefox_OS -translation_of: Archive/B2G_OS/Developing_Gaia/Localizing_B2G_OS ---- -
-

在本指南中,我们会告诉您如何简单的对 Firefox OS 进行本地化,尤其是 Gaia 接口和 apps。我们会从帮助您从配置电脑开始,继而描述如何本地化 Gaia 字符串, 最后介绍如何在您的工作中执行 l10n 测试。

-
-

准备您的工具

-

为了能获得 Gaia 的源码并在您的电脑中测试本地化字符串, 您需要确保在电脑中已安装了下面的工具和语言:

-
-
- GNU make
-
- make 是一个有用的小工具,用来从源码中创建构建操作。当您准备好在电脑上进行 l10n 测试时,它就会排上用场。下载和安装 make 工具是非常简单的,可以直接借助 GNU 网站完成。 如果您在使用 Mac OSX, 则需要从  App Store 中安装 XCode 和 XCode's 命令行工具。
-
- git
-
- git 是一个版本控制系统,用来存储正在积极开发的 Gaia 源代码。下载和安装 git 是非常简单的,能够直接借助它们的网站来完成。
-
- Python
-
- Python 是一种编程语言,将帮助您创建对 l10n 测试的 Firefox OS 构建过程。 下载和安装 Python 是非常简单的,可以直接通过它们的网站来完成。
-
- Mercurial (hg)
-
- Mercurial (hg) 也是一个版本控制系统, 会收藏稳定的 Gaia版本以用于 l10n, 本地仓库也是一样。 下载和安装 Mercurial 是非常简单的,能够直接通过 直接通过它们的网站来完成
-
- compare-locales
-
- compare-locales 是一个 Python 脚本,可以帮助本地化工作者评估它们的工作并将需要本地化的内容与已经本地化的内容分离(称之为 diff) 。 下载和安装 compare-locales 是非常简单的,可以  done 直接通过 compare-locales wiki 页面完成。请注意,如果您仅仅使用命令行或文本编辑器,该工具是必须的。如果您使用 pootel, Tansifex 或 Pontoon 等工具,则不需要使用它。
-
-

配置本地化仓库

-

在您确认已经完成对上面软件列表的下载和安装后,就可以在您的电脑中获取源码并本地化字符串了。

-
    -
  1. 请在命令行下,进入您存储 Gaia 代码和本地化字符串的目录
  2. -
  3. 使用 hg,  将 en-US 仓库 clone 到本地, 请使用下面的命令完成。
    -
    hg clone https://hg.mozilla.org/gaia-l10n/en-US
    -
    -
  4. -
  5. 现在,使用带有下面结构的命令 clone 您的本地化仓库。下面例子中,第二行命令则是指将繁体中文 clone 到对应的文件夹中。 
    -
    hg clone https://hg.mozilla.org/gaia-l10n/your-locale-code
    -hg clone https://hg.mozilla.org/gaia-l10n/zh-TW/ B2G/gaia/locales/zh-TW
    -
  6. -
  7. 现在运行下面的命令:
    -
    LOCALE_BASEDIR=locales/ LOCALES_FILE=locales/languages_mine.json make
    -
  8. -
-

本地化文件会在 languages_mine.json 文件中列出,其结构如下所示:

-
{
-  "en-US" : "English (US)",
-  "fr" : "Français (fr)"
-}
-

在此文件中,您应该有一个列表的字符串去翻译!请注意, 如果您开始对 Friefox OS 新的语言进行本地化,则不需要创建一个 diff, 因为所有的字符串都是新字串,都需要我们来翻译。

-
-

注意: 在本地构建自动化脚本时,请参考  这个要点 gist

-
-

 

-

翻译 Gaia 字符串

-

The workflow for translating Gaia strings largely depends upon the tools you're using to translate. This part of the process is similar to the regular translation phase for other Mozilla products. The Translation Phase page of the Localization Quick Start Guide contains a list of all the tools used to translate strings within Mozilla products along with tutorials on how to translate with those tools. This page will be useful to you whether you're part of a l10n team trying to decide what tool to use to translate Gaia strings or you're looking for the right tutorial for the tool your team currently uses.

-

Firefox OS L10n 测试

-

There are two main methods for performing l10n testing on Firefox OS: desktop builds and mobile builds. Currently, the desktop method is the most widely used method for l10n testing.

-

Desktop l10n testing

-
    -
  1. Download and install the latest boot2gecko nightly desktop build by visiting http://ftp.mozilla.org/pub/mozilla.org/b2g/nightly/latest-mozilla-b2g18/and downloading the package that corresponds to your operating system. Look for the packages that contain the word localizer in them. This indicates that the build has all of the locales listed on languages-all.json enabled.
  2. -
  3. Clone the latest version of Gaia by navigating to the directory on your desktop where you would like it to download and entering this command in the command line utility: git clone git://github.com/mozilla-b2g/gaia.git
  4. -
  5. If your team is localizing Firefox OS for the first time, you'll need to enable your locale. If not, grab yourself a drink while everyone else enables their locale. -
      -
    1. While in the command line, navigate inside your gaia clone and run this command to clone your locale's repo: hg clone ssh://hg.mozilla.org/gaia-l10n/your-locale-code
    2. -
    3. Open the languages.json file located in the shared/resources directory in the gaia repository you just cloned.
    4. -
    5. Add your locale information according to this format: "en-US" : "English (US)", and save the file.
    6. -
    7. Finally, run the command: make multilocale This enables your locale on your desktop build.
    8. -
    -
  6. -
  7. Create your Gaia profile by running this command: DEBUG=1 make -C gaia profile
  8. -
  9. Finally, you can run Firefox OS with your locale profile and begin testing. Do this by entering this command: b2g/b2g -profile gaia/profile. If you're using Mac OS X, run this command: /Applications/B2G.app/Contents/MacOS/b2g -profile gaia/profile
  10. -
  11. To update your desktop builds, simply navigate to your Gaia repo clone and enter this command: git pull
  12. -
-

Mobile l10n testing

-

- - This section will grow as more devices that support Firefox OS become available to localizers. -

-

What to look for when l10n testing

-

Localization testing for a mobile operating system has some similarites to localization testing for a desktop application. Here are some guidelines on what to look for when performing localization testing on your work:

-
    -
  1. See if your translations fit inside UI text elements.
  2. -
  3. Ensure that the tone, style, and terminology are consistant throughout the entire product.
  4. -
  5. Look for untranslated English strings in the UI. These may be hard-coded into Gaia or they may caused by element ID errors.
  6. -
  7. Make sure that time and dates display according your regions standards.
  8. -
-

发现本地化相关 bugs

-

Here are some links to bugzilla in order to give you examples of bugs that have been encountered while using the phones. This will give you an idea of where to look at for bugs as well as an example in filing these kinds of bugs.

- -

General rules when filing a Localization bug:

- -

For those of you who use Moztrap, looking at the existing test cases under the FirefoxOS "localization" tags and seeing if you can pass the tests on your device is also a good way to test Firefox OS localizations.

-

下面要做的

-

Now you're ready to start localizing! So open up your favorite l10n tool and go for it! As always, if you have questions that are not covered in this document, please send them to the mozilla.dev.l10n newsgroup.

diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/make_options_reference/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/make_options_reference/index.html deleted file mode 100644 index 19e5b61e40..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/make_options_reference/index.html +++ /dev/null @@ -1,186 +0,0 @@ ---- -title: make 选项参考 -slug: Archive/B2G_OS/Developing_Gaia/make_options_reference -translation_of: Archive/B2G_OS/Developing_Gaia/make_options_reference ---- -
-

在Gaia仓库下的执行make命令会创建一个Gaia配置文件,继而装载到您的设备端或运行在 B2G Desktop 中。本文会对make不同的选项详细探究。

-
-
-

注意: 在Makefile文件中有许多环境变量,不要太依赖它们,因为在将来可能会去掉。

-
-

创建的配置文件一般存放在gaia的根目录下,例如 /gaia/profile 文件夹,其中包括下面的条目: 

- -
-

注意: 当您已经生成了一个配置文件而且想要构建一个新的文件,就必须在构建新的配置文件前,将原有的删除。

-
-

默认命令

-
make
-

该命令只是给您一个非调试下的默认编译。 对于一个带有品牌的构建,您需要使用Official Mozilla branding make命令; 对于调试构建,您需要使用 Debug make命令。

-

推送到设备端

-
make install-gaia
-
-make reset-gaia
-
-

使用 ADB (Android Debug Bridge) 安装工具,上面的make命令会将Gaia推送到设备端。  install-gaia 会将Gaia更新从您工作的文件夹推送到设备端。 reset-gaia 在将Gaia推送到手机前会清除所有现存的配置,配置文件,web 应用以及数据库信息。

-

编译特定的应用

-
APP=system make
-
-APP=system make install-gaia
-

当一个配置文件已存在时, APP 参数允许您指定特定的app重新打包,而不是对所有的Gaia应用重新打包和重新发布。

-

指定自定义的profile文件夹

-

您可以指定一个自定义的文件夹来构建您的profile文件。例如使用 PROFILE_FOLDER:

-
PROFILE_FOLDER=profile-b2g-desktop make
-

不同设备的编译

-

下面几个 make 选项是不同的设备进行编译,其用途也会不同。

-

创建Gaia的手机端编译

-
GAIA_DEVICE_TYPE=phone make
-

此次编译是从 /gaia/build/config/phone/apps-engineering.list 文件获取app的。

-

创建Gaia的平板端编译

-
GAIA_DEVICE_TYPE=tablet make
-

此次编译是从 /gaia/build/config/tablet/apps-engineering.list 文件获取app的。

-

不同的编译类型

-

有些选项可以创建出不同的编译类型,其目的也有所不同。

-

Production make

-
PRODUCTION=1 make
-

它会创建 Gaia 的生产型编译版本

- -
-

注意: 您也可以使用  make production 替换该命令。

-
-

Debug make

-
DEBUG=1 make
-

The DEBUG variable runs Gaia as hosted apps on a built-in web server on a specific GAIA_PORT, rather than the default of packaged apps which have to be re-packaged after every change; this makes things easier to test. Launching the profile with the latest Firefox Nightly will also give you nice B2G specific panels on the Firefox Developer Tools.

-

In addition:

- -

Device debug make

-
DEVICE_DEBUG=1 make
-

它可以禁用设备的锁屏, 并且启用 ADB 工具,因此在设备调试时是非常有用的。

-

在 Firefox OS version > 1.2 以上版本,当想要使用 App Manager 调试 Firefox OS webapps 时指定这个参数。

-

Debug desktop make

-
DEBUG=1 DESKTOP=0 make
-

这个选项可以创建一个 desktop 调试版本, 在 B2G desktop 中运行。

-

官方 Mozilla 分支 make

-
MOZILLA_OFFICIAL=1 make
-

Use this to make an official Mozilla-branded build.

-

Dogfood make

-
DOGFOOD=1 make
-

Dogfooding options and utilities are turned on, for example the Feedback app, which allows doog fooders to easily submit feedback on the OS.

-

System apps make

-
B2G_SYSTEM_APPS=1 make
-

这个环境变量能将 app 推送到 /system/b2g 而不是 /data/local。当进行 user 编译时应使用这个命令。 当运行  make production 这个命令会自动设置。可用作install-gaia 或 reset-gaia

-

发布和市场化定制编译

-
GAIA_DISTRIBUTION_DIR=./dir
-
-

注意: Read Market Customizations for more details.

-
-

开发者/调试选项

-

There are also make options for adding/removing features or changing settings, for debugging purposes.

-

使能远程调试

-
REMOTE_DEBUGGER=1
-

This enables remote debugging on the device, the same as using the option in the developer settings.

-

JavaScript 优化 make

-
GAIA_OPTIMIZE=1 make
-

This triggers an optimization pass on Gaia's JavaScript, concatenating/compressing the files. This is automatically set when running make production. This can be used for install-gaia or reset-gaia too.

-

高分辨率图片资源

-
GAIA_DEV_PIXELS_PER_PX=1.5 make
-

When packaging the app, this option replaces images with their *@1.5x.(gif|jpg|png) equivalents if such images exist. You need to use the above option as part of a standard make command, for example:

-
GAIA_DEV_PIXELS_PER_PX=1.5 make reset-gaia
-
-GAIA_DEV_PIXELS_PER_PX=1.5 make install-gaia
-

Gaia is currently targetting the following screen resolutions:

- -

use GAIA_DEV_PIXELS_PER_PX to make sure the images looks sharp on qHD and WVGA devices. see A pixel is not a pixel for more information about device pixels per css pixels.

-

低内存 profile 编译

-
GAIA_MEMORY_PROFILE=low make
-

This variable generates a low memory profile version of Gaia, aimed at low memory devices like the Tarako.

-

Haida features

-
HAIDA=1 make reset-gaia
-

This build enables the Haida feature set, which is currently limited to rocketbar and edge gestures, but will likely include other features in the near future.

-

禁用初次用户体验 (FTU)

-
NOFTU=1
-
-

使用这个环境变量可以禁用 FTU。

-

禁用锁屏

-

您可以使用 NO_LOCK_SCREEN 选项禁用 Firefox OS 的锁屏功能,例如:

-
NO_LOCK_SCREEN=1 make
-

参考工作负载 Reference Workloads

-

参考工作负载(Reference workloads)能够使开发者在一些应用中快速装载大量的数据,尤其是对新烧的机器。 

-

在 Gaia 目录下可执行下面命令:

-
make reference-workload-light
- -
make reference-workload-medium
- -
make reference-workload-heavy
- -
make reference-workload-x-heavy
- -

这些命令可以接受 APP 环境变量或者是 APPS 环境变量(需要使用空格将各 app 名称分开)。例如:

-
APP=sms make reference-workload-light
-APPS="sms communications/contacts" make reference-workload-heavy
-
-

The apps available are:

-
APPS="gallery music video communications/contacts sms communications/dialer"
-

为了能够使用参考工作负载 (reference workloads), 必须安装 mid3v2 工具。 这个工具可以使用下面命令安装: 

-
sudo apt-get install python-mutagen
-

如果您使用的是 Fedora 或 RHEL 操作系统,请使用下面命令:

-
sudo yum install python-mutagen
-

make 文档

-

Gaia 文档可以通过 jsdoc3 进行编译。要产生文档,可以使用下面的命令:

-
make docs
-

启用 IME 布局和词典

-

要启用键盘 IME 布局和词典, 请使用下面的命令结构:

-
GAIA_KEYBOARD_LAYOUTS=en,zh-Hant-Zhuyin,el,de,fr,zh-Hans-Pinyin make
diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/making_gaia_code_changes/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/making_gaia_code_changes/index.html deleted file mode 100644 index 48f28d2bb8..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/making_gaia_code_changes/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: 修改 Gaia 代码 -slug: Archive/B2G_OS/Developing_Gaia/Making_Gaia_code_changes -translation_of: Archive/B2G_OS/Developing_Gaia/Making_Gaia_code_changes ---- -
-

现在您已经在桌面上运行 Gaia, 并且对源代码的工作方式有了一定程度的理解,下一步就应该准备好为项目做贡献了。本文则描述了如何修改代码以及如何在代码中找到 bug 出现的位置。 

-
-

Git 最佳实践

-
    -
  1. 当对 Gaia 修改时, 首先需要从 master 上获取最新的代码: -
    cd path/to/gaia
    -git checkout master
    -git pull 
    -
  2. -
  3. 下面切换到您解决问题的分支: -
    git checkout -b my-code-fix
    -
  4. -
  5. 最后,到 gaia/apps 目录下,可以修改对应的文件了。
  6. -
-
-

注意: 在 gaia/profile-debug/ 目录下,您会找到  webapps/, 但其中只包含需要运行的 app 的manifest 文件,而 app 是存在于  gaia/apps/ 目录下的。

-
-

简单的代码修改示例

-

您可以按照需求对代码作出修改,保存修改,在 Firefox 桌面中运行 Gaia 并刷新 tab 页以查看效果。  Let's do something simple like change the text colour of the clock on the lock screen:

-

Gaia lockscreen showing the clock display in white text

-
    -
  1. The best way to find how this style is set is to use the developer tools. Ctrl/right + click on the clock in Firefox Desktop and select Inspect Element from the context menu.
  2. -
  3. You can then work out which CSS file to edit — gaia/apps/system/style/lockscreen.css in this case — and then make your changes in the CSS styles on the right hand side of the display to get it to the state you want.
  4. -
  5. When you are happy with the change, go and make the change in the file directly.
  6. -
  7. Next, refresh the tab (or use the Reload application button) and the HTTP server serves the changes instantly:
  8. -
-

Gaia lockscreen showing the clock display modified from white to red text
-
-
- Limitations of Gaia Desktop Firefox rendering:

- -

发现 bug 出现的地方

-

The best way to find Firefox OS bugs to work on is to consult Josh Matthews' Bugs Ahoy app — this pulls in bugs directly from Mozilla's Bugzilla and displays them in an easy to search and browse way. One you have found a bug that you want to work on, go to its Bugzilla page, enter yourself in the "assigned to" field, and start work, as indicated above.

-

有用的提示

- -

https://bugzilla.mozilla.org/buglist.cgi?columnlist=product%2Ccf_blocking_b2g%2Cbug_status%2Cresolution%2Cshort_desc&resolution=---&query_based_on=CLOCK&query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Gaia%3A%3AClock&product=Boot2Gecko&known_name=CLOCK&list_id=9776392

-

参考

- diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/running_the_gaia_codebase/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/running_the_gaia_codebase/index.html deleted file mode 100644 index 30fc71b5f9..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/running_the_gaia_codebase/index.html +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: 运行 Gaia 代码 -slug: Archive/B2G_OS/Developing_Gaia/Running_the_Gaia_codebase -translation_of: Archive/B2G_OS/Developing_Gaia/Running_the_Gaia_codebase ---- -
-

本文对如何在本地运行 Gaia 代码以及在设置过程中的有效工具进行了深入讲解。

-
- -

首先,我们应该指出,在操作Gaia 时,您并不需要编译 Gecko 或 B2G。您只需要将 Gaia 源代码下载到本地,以一定的方式运行和编辑它。

- -


- 共有下面几种方式来运行 Gaia:

- - - -

你能在我们的 用多种方法运行Gaia 页面找到关于以多种方法运行Gaia的简略信息以及到更详细信息的链接。一般来说,这些信息是由从复杂问题(最常需要的信息)到简单问题(最少需要的信息)排序的。

- -

在这篇文章里,我们会使用Firefox Mulet或WebIDE来运行Gaia -- 对于大部分你想对于Gaia代码库进行的更改,它们提供了最快捷的调试你的更新的方式。但显然,为了使用一些功能(如调试设备API或者与手机硬件进行交互等),你需要一个真正的设备。

- -
-

注意: 如需得到更深入的帮助, 最好的地方就是 #gaia IRC 频道 (参见 Mozilla IRC 以获取更多信息) 以及 Gaia开发邮件单

-
- -

运行 Gaia 

- -
    -
  1. 首先,fork我们在Github上的主项目存档库 Gaia.
  2. -
  3. 然后,在本地clone它: -
    git clone https://github.com/your-username/gaia.git
    -
  4. -
  5. 之后,再加入一个像这样的upstream: -
    cd gaia
    -git remote add upstream https://github.com/mozilla-b2g/gaia
    -
  6. -
  7. 最后, 在你的系统上安装 Fira Sans 字体:这是在真实设备上Gaia使用的字体, 所以在桌面上运行 Gaia 时也使用它是十分有用的,尤其是当你测试有关重叠或字体大小的功能时。
  8. -
  9. -

    现在你需要为Gaia创建一个调试档案。 在你的Gaia存档库文件夹内运行DEBUG=1 make指令就会在profile-debug目录下创建一个档案(profile),这个档案是为了做到最优调试而创建的。它会创建未压缩(即主机调试版本)的Gaia应用,可以通过Firefox桌面版内置的扩展HTTPD服务器直接进行调试。当你对你的应用做了一个改变时,你只需要刷新你的浏览器窗口就可以看到结果,而不用再进行重新编译文件、重新推送到设备等等繁杂的过程。这对于快速的CSS/JS/HTMl修改尤其有用。

    -
  10. -
  11. With your debug profile built, run it in your desktop Firefox build (we'd recommend you use Firefox Nightly) from the command line, using a command with the following structure: -
    /path/to/firefoxnightly -profile /path/to/B2G/gaia/profile-debug -no-remote
    - For example, on Mac OS X, we ran the following command: - -
    /Applications/FirefoxNightly.app/Contents/MacOS/firefox -profile /Users/bob/git/gaia/profile-debug -no-remote
    -
  12. -
- -

This should load up your Gaia profile running in a desktop Firefox tab, like so (you'll notice that the URL is http://system.gaiamobile.org:8080/):

- -

A screenshot of Firefox OS Gaia being run inside a desktop Firefox nightly build.

- -
-

Note: If you open a tab in the Firefox desktop window Gaia is running in, enter about:config, and search for "gaia", you'll find a number of extensions.gaia.* prefs — which the httpd.js extension is using. You'll also be able to find the network.dns.localDomains pref, which is the trick that makes http://system.gaiamobile.org:8080 connect on your localhost.

-
- -
-

Note: The make command is run inside the Gaia directory to create a profile (including apps, setting, etc.) that can be loaded on a phone, run inside an emulator, etc. The make command has a number of options to create different kinds of build. Just running make creates a standard production profile inside gaia/make, with packaged apps, which is not set up for optimum modification and debugging.

-
- -

有效的工具

- -

You'll see that this view has a number of different tools available, including:

- - diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/testing_gaia_code_changes/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/testing_gaia_code_changes/index.html deleted file mode 100644 index 3f2aa1a408..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/testing_gaia_code_changes/index.html +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: 测试 Gaia 代码修改 -slug: Archive/B2G_OS/Developing_Gaia/Testing_Gaia_code_changes -tags: - - B2G - - Firefox OS - - Gaia - - UI - - 'l10n:priority' - - 指南 - - 测试 - - 贡献 - - 集成 -translation_of: Archive/B2G_OS/Developing_Gaia/Testing_Gaia_code_changes ---- -
-

当您完成对 Gaia 代码库的修改并且结果看起来正常时, 下面的步骤就是通过测试程序的验证,从而确保在将 patch 提交到工程之前,您的修改可以真正的工作— 也就是对其他的 Gaia 代码也是有效的。本文所讲的就是这些内容。

-
-

测试步骤一般包括:

- -

下面让我们来对这两部分进行分析:

-

标准调试

-

如果您是一位有经验的 web 开发者,那么对调试 Gaia 代码的步骤也不会陌生。 我们已经讨论了如何在桌面 Firefox 中运行Gaia,以及如何做 基本的修改。要获取更复杂的代码库添加的知识,则需要在桌面 Firefox 中对 Firefox 调试工具多多使用才好。

-
-

注意: 要获取更多使用工具方面的指令,请参考我们的 Tools zone.

-
-

自动化测试

-

在提交 patch 前,您同样应该在 Gaia 中运行标准测试套件,以保证您的代码更改不会对现有的手机功能造成影响。需要运行的测试包括:

- -

在提交 patch 前,我们一般会要求运行测试;如果这是您第一次为 gaia 做贡献,可以在提交前不经过测试的环节,但后续则必须要进行测试。在运行测试前,为保证您的代码是最新的,需要更新 Gaia 仓库。 

-
-

注意: 要获取更多有关测试的内容,请参考 Firefox OS 自动化测试页面

-
-
-

注意: 如果可能的话,您需要考虑下运行在真实设备上运行每一项测试 (一些功能/硬件在仿真器上并不支持),否则就在 B2G 桌面仿真器或 Firefox Nightly 中运行。

-
-

单元测试

-

单元测试是指在大型应用中测试对每个独立的代码单元进行测试 — 对 Gaia 而言,就是指单独的 app。Gaia 使用:

- -

您可以运行下面的命令来下载,安装和作为一个单元测试服务器(运行该命令需要一些时间,不妨先喝杯茶休息一下):

-
make test-agent-server
-

下面,打开一个新的终端窗口,在 Nightly 中将  test-agent app 装载进去

-
    -
  1. 运行下面命令:
    -
    make DEBUG=1
    -/Applications/FirefoxNightly.app/Contents/MacOS/firefox -profile /Users/bob/git/gaia/profile-debug -no-remote
    -
  2. -
  3. 点击 homescreen 上的 Test Aagent app
  4. -
-

使用下面命令来运行所有测试

-
make test-agent-test
-
-

注意: 由于要运行很多测试,可能要花费一个小时或更多的时间,因此您可能只想要对您所修改的 app 进行测试。此时,就可以将 APP=<app folder name>  添加在命令后面来实现,如  APP=settings.

-
-
-

注意: 您也可以阅读 Gaia Unit Tests 获取更多单元测试的信息。

-
-

集成测试

-

Integration testing involves testing different units of code together in a group to see how well they work together, and is the logical next step after unit testing. Gaia Integration tests are driven by a marionette script written in JavaScript and a python-based server. It can communicate with Gecko so it’s possible to control both the browser and Firefox OS device, and get them interacting with each other.

-

You can run the following command to trigger the integration tests:

-
make test-integration
-
-

Note: As with the unit tests, running the whole integration test suite can be very time consuming, so you can append APP=<app folder name> onto the above command to test a single app, for example APP=calendar.

-
-

性能测试

-

Gaia 性能测试会触发 B2G 桌面,多次启动 apps, 并且计算平均 app 装载时间。在运行测试后,性能框架会也会收集 app 和 系统进程(b2g) 的内存使用情况。

-

要运行这个测试,需要安装上 B2G Desktop, 并运行下面命令

-
make test-perf
-
-

注意: 当涉及到其他的测试类型时,你可以在上面命令后添加 APP=<app folder name> 来测试单个 app, 例如 APP=settings.

-
-

整体的平均值会在 mozPerfDurationsAverage 中表示:

-
"mozPerfDurationsAverage": 225.5
-

这是以毫秒为单位的平均 app 装载时间。为了优化用户体验,你应该将目标设为 1 s 一下。 性能测试同样会返回一些详细的内存使用值:

-
{
-  "app": {
-    "name": "Settings",
-    "uss": 16.6,
-    "pss": 19.5,
-    "rss": 32.9,
-    "vsize": 73.3
-  },
-  "system": {
-    "name": "b2g",
-    "uss": 50.1,
-    "pss": 53.2,
-    "rss": 67,
-    "vsize": 148.1
-  }
-},
-

test-pref 的整体原则是 ”数值越低越好“, 上面的这些值分别表示:

- -

Generally vsize >= rss >= pss >= uss . vsize and rss don’t accurately reflect a process’s usage of pages shared with other processes. So the two numbers you want to watch are the pss and uss.
-
- uss 是指进程所独自完整占用的内存。如果应用程序当前终止的话,这些内存都可以被释放掉。这是用来评价的关键指标。
-
- pss 是进程共享库按比例所分享的大小。如果进程终止,这些内存也不能释放。
-  

-
-

注意: 要获取更多性能测试的信息,请参考 Gaia performance tests.

-
-

 

diff --git a/files/zh-cn/archive/b2g_os/developing_gaia/understanding_the_gaia_codebase/index.html b/files/zh-cn/archive/b2g_os/developing_gaia/understanding_the_gaia_codebase/index.html deleted file mode 100644 index 8a0695b970..0000000000 --- a/files/zh-cn/archive/b2g_os/developing_gaia/understanding_the_gaia_codebase/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: 理解 Gaia 代码库 -slug: Archive/B2G_OS/Developing_Gaia/Understanding_the_Gaia_codebase -tags: - - B2G - - Code - - Firefox OS - - Gaia - - Guide - - JavaScript - - contribution -translation_of: Archive/B2G_OS/Developing_Gaia/Understanding_the_Gaia_codebase ---- -
-

在对 Gaia codebase作出您自己的修改之前,您需要理解下Gaia 的基本构成以及使用的编码规则。本文则涵盖了这些这些方面。

-
-

Gaia 代码库结构

-

下面的部分则概述了 Gaia 代码库最重要的部分。

-

apps/

-

此目录包括所有的主 Gaia apps, 在 homescreen 中显示的 app(如 calendar 和 camera)和底层 app(如 system, homescreen 和 keyboard ) 。
-
- app 工作方式略有不同,但有许多公共的特点,包括:

- -
-

注意: 在 Gaia 应用指南 一文中可获得更多关于 app 工作的内容。

-
-

build/

-

包含编译脚本。

-

dev_apps/

-

文件夹中包含自定义的一些应用。例如,您可以包含一些自定义的 app。

-
-

注意: 要获取更多关于 Gaia 自定义项的知识,请参考  Market customizations guide.

-
-

keyboard/

-

 keyboard 文件夹包含了 keyboard 词典以及不同语言的布局。

-

locales/

-

包含一个 JSON 文件,languages_all.json,  该文件定义了 Gaia 所支持的语言。要更深入的了解 apps 是如何本地化的,请参考  Getting started with app localization.

-

shared/

-

此目录包含了多个应用使用的大量的资源文件;其中最重要的部分为:

- -

tools/

-

tools 目录包含编译脚本和测试的工具。

-

Gaia 编码风格

-

Gaia 遵循 Google JavaScript coding style.

-

背景知识:

- -

具体规则

-
    -
  1. 确保 HTML 文件都带有 <!DOCTYPE html>  声明(也就是 HTML5 文档)。如果您不这么做, Internet Explorer 9 以及后续的版本会以兼容模式来装载它们。
  2. -
  3. 包含 "use strict"; 这个语句(就像刚才写的一样,包含双引号)放在 Js 文件头部,会使 js 进入 strict 模式。
  4. -
  5. 使用两个空格来缩进,而不是使用 tabs。
  6. -
  7. 请使用换行符来分隔代码逻辑!
  8. -
  9. 多单词的文件名称应该使用下划线字符来分隔单词,如like_this.js
  10. -
  11. 使用单引号而不是双引号来表示字符串。
  12. -
  13. 使用扩展的条件结构: -
    Bad
    -if (expression) doSomething();
    -
    -Correct
    -if (expression) {
    -  doSomething();
    -}
    -
  14. -
  15. 如果您修改 System app,请阅读  guidance listed here.
  16. -
-

每笔提交编码风格检查

-

在每个 commit 之前,通过调用  git pre-commit hook, Gaia 会使用  jshint 工具会自动对JS 编码风格进行检查。一旦您提交了对 Gaia 仓库的 Pull Request,  Travis (Github Continuous Integration) 服务器会运行这个工具来重复检查样式是否正确。

-

 precommit hook 脚本在gaia/tools/pre-commit 下,一旦  make 命令执行就会复制到 .git/hooks 文件夹 下。

-
-

注意: 我们以前会使用  gjslint 来检查编码风格,但已将其弃用;而是使用 jshint 来产生更严格和更好的效果。从 Firefox OS 1.4 开始就一直使用 JSHint,  gjslint 只被用来检查一些还没有使用 JSHint 的旧文件。

-
-

通过 Gaia 来手动运行 linting 检查

-

在提交 path 前我们推荐您在 patch 上手动运行 JSHint 来检查是否有任何样式上的错误。
-
- 您应该在 gaia/build/jshint 目录下获取更多关于 Gaia 中 jshint 的细节;Gaia 为您提供了一个构建脚本,您可运行:

-
$ make lint
-

来自动进行 gjshint 和 jshint 样式的检查。 或者您运行

-
$ make hint
-

只运行 jshint 样式检查。

-
-

注意: 如果您想要在不是用 Gaia 的情况下,自己安装 Jshint,可运行如下命令:

-
npm install jshint -g
-jshint myfile.js
-
-
-

 

diff --git a/files/zh-cn/archive/b2g_os/events/disabled/index.html b/files/zh-cn/archive/b2g_os/events/disabled/index.html deleted file mode 100644 index 0a6370bcfb..0000000000 --- a/files/zh-cn/archive/b2g_os/events/disabled/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: disabled -slug: Archive/B2G_OS/Events/disabled -translation_of: Archive/B2G_OS/Events/disabled ---- -

禁用时,无线网络连接的设备上禁用事件引发的。

- -

基本信息

- -
-
规范
-
Wifi(特定于Firefox OS)WifiDirect(特定于Firefox OS)
-
接口
-
事件
-
泡泡
-
没有
-
可取消
-
没有
-
目标
-
WifiManager和MozWifiP2pManager
-
默认动作
-
没有
-
- -

物产

- -

未知

- -

- -
navigator.mozWifiManager.ondisabled = function(){
-  console.log("Wifi已被禁用");
-};
-
- -

相关活动

- - diff --git a/files/zh-cn/archive/b2g_os/events/index.html b/files/zh-cn/archive/b2g_os/events/index.html deleted file mode 100644 index 6805ee5749..0000000000 --- a/files/zh-cn/archive/b2g_os/events/index.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: B2G OS events -slug: Archive/B2G_OS/Events -tags: - - Archive - - B2G - - NeedsTranslation - - TopicStub - - events -translation_of: Archive/B2G_OS/Events ---- -

Archived event pages related to B2G OS.

- -
connected
The connected event callback is executed when a call has been connected.
connectioninfoupdate
The connectionInfoUpdate handler is executed when information about the signal strength and the link speed have been updated.
contactchange
The contactchange event is fired each time a contact is added, updated or removed from the device's contact database.
disabled
The disabled event is raised when WiFi is disabled on the device.
enabled
The enabled handler is executed when Wifi is enabled on the device.
localized
The localized event is triggered after the webL10n library has finished localizing the document and detecting language.
message
The message handler is executed when data is received from a child (i)frame or parent window.
diff --git a/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/1.x/index.html b/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/1.x/index.html deleted file mode 100644 index e872f21b11..0000000000 --- a/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/1.x/index.html +++ /dev/null @@ -1,534 +0,0 @@ ---- -title: Firefox OS 1.x building blocks -slug: Archive/B2G_OS/Firefox_OS_apps/Building_blocks/1.x -tags: - - Apps - - B2G - - Firefox OS - - Firefox OS UX - - NeedsTranslation - - TopicStub - - UX -translation_of: Archive/B2G_OS/Firefox_OS_apps/Building_blocks/1.x ---- -
-

Important: The descriptions on this page and its subpages are old descriptions written around the first few versions of Firefox OS (1.0.1–1.3), so are out of date. You'll only find these useful if you are writing an app specifically aimed at an old version of Firefox OS, or fixing a bug on an old branch of Gaia. If you want to find more up to date building block information, go to our main Firefox OS building blocks landing page.

-
- -
-

This page provides links to the Firefox OS 1.x building blocks.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Action menu

-
-


-  Details
- Coding guide

-
-

An action menu presents a list of actions, related to the app's content, from which the user may make a selection. See the Coding guide for details on how to implement an action menu in your app.

- -

 

- -

Characteristics

- -
    -
  • Opened from buttons within app content; these buttons are often inside toolbars (for example, the Browser app's "Share" button).
  • -
  • Action menus contain one or more items.
  • -
  • These menus expand in height to accomodate their items, to a maximum of the screen's height. Once that maximum height is reached, the content becomes scrollable vertically. Generally, the best practice is to try to include no more than five items plus a menu title.
  • -
  • The title string is optional.
  • -
  • The menu is closed by one of: -
      -
    • Selecting one of the actions.
    • -
    • Tapping the "Cancel" button.
    • -
    -
  • -
- -

 

-
-

Button

-
-

- -

Details
- Coding guide

-
-

Performs an action when tapped by the user. These are highly flexible user interface objects that have a wide variety of styles. See the Coding guide for information on how to implement buttons that look like those described here.

- -

 

- -

Characteristics

- -
    -
  • Buttons have two components: a visual target and a hit target. The hit target is always larger, in order to reduce targeting errors by making the button easier to tap.
  • -
  • Buttons have two states: normal and pressed.
  • -
  • Buttons can also be disabled, which means they can't be activated by the user, and are displayed dimmed to indicate that they're disabled.
  • -
- -

There are several types of buttons:

- -
-
Action buttons
-
Used when there are only a few actions and a list isn't needed. The main action button uses a special highlight color to indicate that it's the primary option.
-
List buttons
-
Used when displaying a list of actions, or to trigger the display of a value selector.
-
Input field buttons
-
Used to perform actions with input fields.
-
Special/custom buttons
-
These are used to provide specific actions including recording, dialing, and the like.
-
- -

 

-
-

Confirmation

-
-

- -

Details
- Coding guide
-  

-
-

A confirmation prompt asks the user to take or confirm an action, such as responding to a system event such as asking the user to restart the device after swapping SIM cards, or to ask the user to grant or deny permission to perform a task. See the Coding guide for information about how to implement these prompts in your app.

- -

 

- -

Characteristics

- -
    -
  • Confirmation prompts are modal; they occupy the entire screen, and require user input to close them.
  • -
  • Confirmation prompts consist of: -
      -
    • Title (optional)
    • -
    • Body
    • -
    • Icon (optional)
    • -
    • A Confirmation input button, whose label can be customized
    • -
    • An optional Cancel input button, whose label can be customized
    • -
    -
  • -
- -

 

-
-

Filter

-
-

- -

Details

-
-

Filters can be used for two purposes: data filtering, in which the user can view a single set of data in different ways (for example, the Calendar app uses filters to select the time scale to use when viewing data (that is, by day, week, or month); and secondary navigation (presenting a second set of tabs when tabs are already present in your user interface).

- -

 

- -

Characteristics

- -
    -
  • Filters are presented as a horizontal sequence of buttons.
  • -
  • Only one button is focused at a time.
  • -
  • The best practice is to place filters within toolbars, so that they don't flow with content.
  • -
  • Left, middle, and right buttons can be styled uniquely. This lets you make, for example, the left and right ends of your bar take on a "sheen," or to make the bar rounded on the ends.
  • -
  • Filter buttons' widths vary depending on the number of filters in a single set.
  • -
  • You must have at least two and no more than five filters in a set.
  • -
  • A given set of filters may be labeled with either text or icons, but not both. Because filters' heights are relatively small compared to tabs, text is typically the best practice.
  • -
- -

 

-
- -
-

- -

Details
- Coding guide

-
-

A header labels the active view. In addition, it can contain top-level navigation and inputs for the active view. See the Coding guide for information on implementing headers in your apps.

- -

 

- -

Characteristics

- -
    -
  • A header is a horizontal bar the full width of the screen, which appears at the top of the screen in most apps.
  • -
  • Headers float above content, with the option of flowing with content in special instances, such as in the Browser app.
  • -
  • The heading's text provides the name of the current view.
  • -
  • The heading may optionally include additional text; for example, in an email app, the number of unread messages may be displayed.
  • -
  • Headers may include inputs for navigating and manipulating the current view.
  • -
  • Most apps (full-screen games being an obvious exception) have a header.
  • -
- -

 

-
-

Input area

-
-

- -

Details

-
-

An input area is a data entry field. There are many variations on what an input area can look like; they can be as simple as a text entry field, and as complex as a multi-part entry field with text entry, value selectors, and buttons.

- -

Details coming soon.

-
-

List

-
-

- -

Details

-
-

Lists are used to display a set of consecutive items, such as a list of contacts or a list of messages.

- -

 

- -

Characteristics

- -
    -
  • List items may vary in height (from one to three rows in a single item).
  • -
  • List items may be as simple as just a text string, to including images, text, and buttons.
  • -
  • Lists are comprised of rows, with optional section headers.
  • -
- -

There are several types of list rows:

- -
-
Action row
-
An action row is one in which a tap anywhere in the row triggers the row.
-
Status indicator row
-
Need details.
-
Button row
-
Need details.
-
Link row
-
Need details.
-
- -

 

-
-

Object menu

-
-

- -

Details

-
-

 

- -

An object menu is a menu that lets the user directly manipulate objects without having to open them and navigate deeper into a view hierarchy.

- -
    -
  • Deleting a photo by selecting its thumbnail, instead of by opening the full image first.
  • -
  • Flagging an email by selecting its preview instead of by first opening the email.
  • -
  • Calling a contact by selecting their name, instead of by opening their detailed contact information then pressing a "Call" button.
  • -
- -

Object menus are currently implemented as a special case of action menu; this will evolve over time. For now, see the action menu coding guide for information on how to implement an object menu.

- -

 

- -

Characteristics

- -
    -
  • Object menus are accessed using a "press-and-hold" gesture on a selectable object, such as a list row, phone number, URL, or the like.
  • -
  • An object menu contains one or more items.
  • -
  • Object menus expand in height to accomodate their contents, to a maximum of the height of the screen; at that point, the contents of the menu scroll. As a rule of thumb, you should try to avoid having more than five items in the menu.
  • -
  • Unlike action menus, object menus do not have titles.
  • -
  • You implement object menus using the same code and style as for action menus.
  • -
- -

 

- -

 

-
-

Progress and activity indicator

-
-

- -

Details

-
-

Progress and activity indicators are used to provide visual feedback that a process is active.

- -

 

- -

Characteristics

- -
    -
  • May include an animated visual element, a text label, or both.
  • -
  • Progress and activity indicators may be used in modal windows, or inline either with content or adjacent to content.
  • -
  • An activity indicator is used to show that an activity is ongoing without indicating how long the task is expected to take; these can be "barberpole" style indicators, or spinners.
  • -
  • A progress indicator is used to show how much out of 100% of an activity has been completed.
  • -
- -

 

-
-

Scrolling

-
-

- -

Details

-
-

Scrolling areas are used to let the user move text and/or images across the device's display.

- -

 

- -

Characteristics

- -

There are two types of scrolling areas: scrollbars and index scrolling.

- -

 

-
-

Seek bar

-
-

- -

Details

-
-

Seek bars have a draggable thumb the user can touch and drag back and forth to scroll through content (such as to set playback position in a media file) or to set a new value for a given control, such as sound volume or display brightness.

- -

 

- -

Characteristics

- -
    -
  • A seek bar consists of a track with a knob that indicates the current playback position.
  • -
  • The knob has both normal and "pressed" states.
  • -
  • The values for the ends of the seek bar can be specified as either text or images.
  • -
  • Seek bars may be oriented either horizontally or vertically.
  • -
- -

 

-
-

Status

-
-


- Details
- Coding guide

-
-

Relays information to the user in a transitory fashion, typically to confirm a user action or to alert the user to a system event. See the Coding guide for details on how to implement a status bar. Sometimes status bars are referred to as "banners."

- -

 

- -

Characteristics

- -
    -
  • Examples include deleting multiple photos in Gallery, or deleting or moving multiple emails.
  • -
  • Positioned at the bottom of the screen, covering underlying content.
  • -
  • Closing: Status bars automatically disappear, typically after a few seconds for short messages. This can be longer, though, depending on the message and context.
  • -
  • Can include an input, such as an "Undo" option; this is optional.
  • -
  • Can optionally include an image.
  • -
  • Can either be part of an app (such as a "Photos deleted" banner in the Gallery app) or in the System (such as a "Low battery" alert).
  • -
  • Avoid displaying more than one status bar at the same time. If two status bars appear at the same time, the newer status bar replaces the older one.
  • -
- -

 

-
-

Switch

-
-

- -

Details
- Coding guide

-
-

A switch is any control which presents two mutually exclusive options or states. Switches are also used to select items within lists. See the Coding guide for details on implementing switches in your apps.

- -

 

- -

Characteristics

- -
    -
  • A switch presents two mutually exclusive choices or states.
  • -
  • There are three types of switch: -
      -
    • On/Off toggle switches
    • -
    • Checkboxes
    • -
    • Radio buttons
    • -
    -
  • -
- -

 

-
-

Tabs

-
-

- -

Details
- Coding guide

-
-

Tabs are used as a navigational widget that let the user switch among sets of views. This way, a window may contain multiple views. See the Coding guide for details on how to implement tabs in your apps.

- -

 

- -

Characteristics

- -
    -
  • Tab bars always fill the full horizontal width of the screen.
  • -
  • You may have up to (but no more than) five tabs in a tab bar.
  • -
  • Tab bars should be positioned at the very bottom of the screen, unless doing so would result in excessive clutter due to multiple bars of controls at the bottom of the screen.
  • -
  • Tabs can contain a variety of elements, such as buttons, filters, indicators, and the like.
  • -
  • Tabs' labels may be text, text with an icon, or just an icon.
  • -
- -

 

-
-

Toolbar

-
-

- -

Details
- Coding guide

-
-

Toolbars contain actions, indicators, and navigation elements associated with the current view. These may include things such as buttons to delete the currently selected items, a filter to enter edit mode, or a filter to show only "favorite" contacts. See the Coding guide for details on how to implement toolbars in your apps.

- -

 

- -

Characteristics

- -
    -
  • Toolbars are always the full width of the screen, and are always the same height.
  • -
  • Toolbars never scroll with content; instead, they float above content.
  • -
  • Toolbars should always be positioned at the very bottom edge of the screen unless tabs are also present, in which case the toolbar is positioned at the top of the screen instead.
  • -
  • Toolbars may contain a wide variety of elements, including buttons, filters, progress/activity indicators, and so forth.
  • -
- -

 

-
-

Value selector

-
-

- -

Details
- Coding Guide

-
-

Value selectors let the user choose one of a number of possible values, and are typically used from a form interface. For example, value selectors could be used to choose the month or day for a calendar event. These are presented automatically for the values of the <input> element's type attribute.

- -

 

- -

Characteristics

- -
    -
  • Value selectors may have an optional title.
  • -
  • The following types of value selectors are provided: -
      -
    • Date
    • -
    • Time
    • -
    • SIngle-select list
    • -
    • Multiple-select list
    • -
    -
  • -
- -

 

-
- -

 

diff --git "a/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/1.x/\346\214\211\351\222\256/index.html" "b/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/1.x/\346\214\211\351\222\256/index.html" deleted file mode 100644 index 76a4f69227..0000000000 --- "a/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/1.x/\346\214\211\351\222\256/index.html" +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: 按钮 -slug: Archive/B2G_OS/Firefox_OS_apps/Building_blocks/1.x/按钮 -translation_of: Archive/B2G_OS/Firefox_OS_apps/Building_blocks/1.x/Button ---- -

当用户点击时执行操作。这些是高度灵活的用户界面对象,具有多种样式。有关如何实现类似于此处描述的按钮的信息,请参见编码指南

- -

特点

- - - -

有几种类型的按钮:

- -
-
动作按钮
-
仅在执行少量操作且不需要列表时使用。主操作按钮使用特殊的突出显示颜色来指示它是主要选项。
-
列表按钮
-
在显示操作列表或触发值选择器显示时使用。
-
输入栏按钮
-
用于对输入字段执行操作。
-
特殊/自定义按钮
-
这些用于提供特定的操作,包括记录、拨号等。
-
- -

Visuals

- -

Here are some visual examples of what buttons should look like. Don't forget that you can use the style sheet and image resources provided in the Coding guide to implement these.

- -

Action buttons

- -

Action buttons are used when there are only a few actions and you don't need a full list. The main action button uses a special highlight color to indicate that it's the primary action.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Primary actionSecondary actionDelete
Normal
Pressed
Disabled
- -

On a dark background, disabled buttons have a special appearance, as seen below.

- - - - - - - - - - - - - - - - -
Primary actionSecondary action
Disabled
- -

List buttons

- -

List buttons are used to display a list of actions, to trigger the display of a value selector.

- -

Triggering actions

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Trigger an action in the current viewTrigger an action in a new viewDisplay a value selector
Normal
Pressed
Disabled
- -

Value selectors

- -

Once a value selector has been opened, you will need at least one button on the value selector panel to dismiss the value selector. These buttons should look like the following:

- - - - - - - - - - - - - - - - -
NormalPressedDisabled
- -

Input field buttons

- -

Input field buttons are buttons associated with an input field, which when pressed perform an action related to that input field.

- - - - - - - - - - - - - - - - -
NormalPressedDisabled
- -

Special buttons

- -

The special buttons are visual icon-style buttons used for special purposes, such as operating the device's camera, answering and hanging up the phone, and activating the keypad dialer. You may of course find other uses for this style of button.

- -

Camera buttons

- -

These buttons don't have a disabled state; you simply don't display them if the ability to take photos isn't available.

- - - - - - - - - - - - - - - - - - - - - - - - -
Record videoStop recording videoCapture photo
Normal
Pressed
- -

Phone buttons

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Pick upHang upHide keypad
Normal
Pressed
Disabled
- -

Custom buttons

- -

These are examples of custom buttons; in this case, for adding a contact.

- - - - - - - - - - - - - - - - -
Normal
Pressed
Disabled
- -

See also

- - diff --git a/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/index.html b/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/index.html deleted file mode 100644 index 0b20e0c329..0000000000 --- a/files/zh-cn/archive/b2g_os/firefox_os_apps/building_blocks/index.html +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: Firefox OS Building Blocks -slug: Archive/B2G_OS/Firefox_OS_apps/Building_blocks -tags: - - Design - - Design patterns - - Firefox OS - - NeedsTranslation - - TopicStub - - UI - - building blocks -translation_of: Archive/B2G_OS/Firefox_OS_apps/Building_blocks ---- - - -
-

The Firefox OS Building Blocks are reusable UI components (also called 'common controls') that reflect OS-wide design patterns. Building Blocks are used to create the interfaces of all Gaia default apps. You are free to make use of these components in your own Firefox OS apps, or general Web apps.

-
- -

Using the Firefox OS Building Blocks

- -

The code for the Firefox OS Building Blocks can be found in the Gaia Github repo under shared/style. Here, you can find a CSS file that contains the CSS for that particular Building Block, and a sub directory containing the HTML fragments and image assets. If you are creating your own standalone Web app, you can simply copy the CSS, HTML and image asset files across into your own project; if your app is intended to be installed on Firefox OS only (or you want to use these features only when the app is being used on Firefox OS), then you can link to the versions available inside Gaia.

- -

The pages for the individual Building Block implementations can be found under the pages for each building block — see next section. These contain instructions on how to implement each one.

- -
-

Note: The version 2.0 building block code is used in Firefox OS releases 2.0 through 2.2. Version 2.3 sees an update, with the building blocks being reimplemented using Web components — these provide the same functionality, but implemented in a much more powerful, flexible way. You'll see 2.3 pages appear underneath the main building block pages covering these Web components as soon as the information is available.

-
- -
-

Note: We also have an old guide covering the v1.x building blocks used in older versions of Firefox OS. This is mainly for legacy information.

-
- -

Web components preliminary setup

- -

This section details the preliminary setup needed to use Gaia Web components.

- -

Web components browser support

- -

To use Gaia Web components at all, you need to run them using a browser that supports Web components. The state of support is as follows:

- - - -

Web components are supported in Firefox OS from v2.1 onwards, although most of them weren't actually implemented until v2.3. Be aware also that currently Web components won't work for Firefox OS apps below internal (certified) level. This restriction should be lessened in the future.

- -
-

Note: If your app is certified, the components will just work. You don't need to set a specific manifest permission.

-
- -

Web components installation notes

- -

Gaia Web components are installed in your app using the Bower package manager. To install this, you first need Node.js/npm and Git installed. Once they are installed you can install Bower with

- -
npm install -g bower
- -

At this point you could also install the Gaia Fira Sans font that Firefox OS uses in your app , with the following command:

- -
bower install gaia-components/gaia-fonts
- -

You can then make use of the font by including the following in your head (along with a font-family of FiraSans):

- -
<link rel="stylesheet" type="text/css" href="bower_components/gaia-fonts/style.css"></link>
- -

Firefox OS Building Blocks

- -
-
-
-
Action menu
-
An action menu presents a list of actions, related to the app's content, from which the user may make a selection.
-
Banners
-
Banners (Status, in older versions of Firefox OS) provide information to the user in a transitory fashion, typically to confirm an action or to alert the user to a system event.
-
Buttons
-
Buttons are used to perform explicit actions. Buttons may be text or images.
-
Context menu
-
Accessed via a tap and hold gesture (sometimes called a long press), the Context Menu (called the Object Menu in older versions of Firefox OS) allows users to perform actions on objects without having to leave their current view.
-
Dialog
-
A Dialog (Confirm, in older versions of Firefox OS) provides the user with some important information, asks the user to take or confirm an action, or allows the user to make a choice or enter some information.
-
Drawer
-
The drawer is a scalable way for users to navigate between views or filter views. The drawer can also include links to app settings or other tools.
-
Header
-
A header is a dedicated space at the top of the screen, most often used to display the view title. It can also include navigation, action buttons and other controls.
-
Input area
-
An input area is a data entry field, and can be as simple as a text only entry field, or as complex as a multipart entry field with text entry, value selections, and buttons.
-
Layout
-
The Layout utility will help you to create common layout structures for your Firefox OS apps. Note that Layout is only available in Firefox OS 2.1 and above.
-
List items
-
List items are typically used to navigate to a new screen, or to display information or controls.
-
-
- -
-
-
Picker
-
The Picker is designed to select a group of items as attachments for messaging and email.
-
Progress and activity
-
Progress and activity indicators provide the user with visual feedback that a process (such as a resource loading) is active.
-
Scrolling
-
Scrolling areas allow the user to move text and/or images across the device's display.
-
Search
-
Search is used to filter a list or find context-specific content.
-
Slider
-
A Slider (which was called Seekbar in older Firefox OS versions) is used to select a value from a continuous or discrete range of values by dragging the handle.
-
Select mode
-
Select Mode (which was called Edit Mode in older Firefox OS versions) is designed to select and perform actions on items.
-
Subheader
-
Subheaders are used to describe a subsection of content.
-
Switches
-
Switches (such as checkboxes, etc.) allow users to activate and deactivate items. Switches are also used to select items within a list.
-
Tab/Filter
-
A Tab/Filter gives the user a way to easily switch between views or to filter a set of data.
-
Toolbars
-
Toolbars contain actions, indicators and navigation elements associated with the current view.
-
Value selector
-
Value Selectors let the user choose from among a list of possible values.
-
-
-
- -
-

Note: For a detailed guide to the design pattern followed by the building blocks when the Arabic locale (bidirectional) is selected, read Firefox OS in Arabic.

-
- -

Cross browser CSS

- -

Arnau March wrote a CSS file called cross browser CSS, containing rules to allow Firefox 2.0 building blocks to render properly across different browsers (ie 9, Firefox 18, Chrome 24, Safari 5.1.) If you want to write hosted apps that look ok across different browsers, include this CSS in your project.

- -

Browse Firefox OS Building Block implementations by version

- -

The pages below list links to pages covering the Firefox OS Building Block implementations as they appear in different versions of Firefox OS.

- - diff --git a/files/zh-cn/archive/b2g_os/firefox_os_apps/index.html b/files/zh-cn/archive/b2g_os/firefox_os_apps/index.html deleted file mode 100644 index 370236dd14..0000000000 --- a/files/zh-cn/archive/b2g_os/firefox_os_apps/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Firefox OS apps -slug: Archive/B2G_OS/Firefox_OS_apps -tags: - - Apps - - Building - - Components - - Firefox OS - - Installing - - NeedsTranslation - - TopicStub - - device APIs -translation_of: Archive/B2G_OS/Firefox_OS_apps ---- -

This section of the Firefox OS docs covers the specific techniques required — and available tools — for building Firefox OS apps. You'll find a number of details below, from Firefox OS building blocks/web components, to device APIs and App installation.

- -

Building Firefox OS apps

- -
-
Building apps for Firefox OS
-
Firefox OS/Firefox platform app specifics, including App installation and management APIs, manifest files, packaged and hosted apps, handling API permissions.
-
Localization
-
This set of articles provides information for developers wishing to provide localized versions of their apps.
-
Performance
-
This page lists performance-related topics specific to Firefox OS.
-
Firefox Accounts on Firefox OS
-
This article provides an overview of using Firefox Accounts in Firefox OS.
-
Reference apps
-
This page lists a number of sample apps we've put together for you to download, install, play with and learn from. Have fun!
-
Screencast series: App Basics for Firefox OS
-
In this collection of short videos, developers from Mozilla and Telenor explain in a few steps how you can get started with building applications for Firefox OS.
-
- -

Building blocks

- -
-
Building Blocks
-
The Firefox OS Building Blocks are reusable UI components (also called 'common controls') that reflect OS-wide design patterns. Building Blocks are used to create the interfaces of all Gaia default apps. You are free to make use of these components in your own Firefox OS apps, or general Web apps.
-
- -

Styleguides

- -
-
Firefox OS Visual styleguide
-
Our style guide for Firefox OS visual design, covering colours, typeface, backgrounds, app icons, and the design of specific UI elements.
-
Firefox OS Copy styleguide
-
This guide outlines the rules we follow for writing Firefox OS app copy, but can be used as a general guide to writing good copy for any app interfaces.
-
Firefox OS in Arabic
-
A guide to the specific UX design implementation Firefox OS has in place for dealing with Arabic (and other RTL languages.)
-
- -

Assets

- -
-
Firefox OS design asset library
-
In this section you'll find design assets, artwork, graphic templates, fonts and other materials that will be helpful as you design Firefox OS/Gaia apps.
-
Firefox OS icon font
-
Firefox OS has its own icon font set available: this article explains how to use it in your own apps.
-
Firefox OS transitions
-
A reference to some of the transitions used in Firefox OS to move between different states in apps, including animated GIFs demonstrating the animations used, plus code samples to show the CSS animation code needed to implement these animations.
-
- -

References

- -
-
Firefox OS device APIs
-
This article provides a list of pages covering those APIs, as well as the app manifest permissions for each one.
-
Firefox OS app tools
-
This page provides a list of useful tools, libraries, examples, etc. that are useful for Firefox OS app developers, whether you want a code template to copy, or need help with adding a specific feature to your Firefox OS app.
-
- -

Other app topics

- -
-
Porting Chrome apps to Firefox OS Apps
-
This article discusses the differences between Chrome apps and Firefox OS Apps, and how you can convert between the two.
-
App development FAQ
-
This FAQ is a compilation of answers to common app development questions.
-
- -

See also

- - diff --git a/files/zh-cn/archive/b2g_os/firefox_os_build_prerequisites/index.html b/files/zh-cn/archive/b2g_os/firefox_os_build_prerequisites/index.html deleted file mode 100644 index 8cca33fd04..0000000000 --- a/files/zh-cn/archive/b2g_os/firefox_os_build_prerequisites/index.html +++ /dev/null @@ -1,267 +0,0 @@ ---- -title: 编译Firefox OS的系统需求 -slug: Archive/B2G_OS/Firefox_OS_build_prerequisites -translation_of: Archive/B2G_OS/B2G_OS_build_prerequisites ---- -

在获取用于编译Firefox OS的代码之前,你需要设置好所需的编译环境。目前可在64位Linux或Mac OS X下编译Firefox OS。

-

注意:要构建firefox OS到手机上,开始时不要把你的手机连接到电脑上,当需要连接的时候我们会告诉你把手机插入到电脑上。

-

使用兼容的硬件或使用模拟器

-

尽管我们支持一些手机,其中一些还有多种变体产品,但我们当前支持一些特定的产品而且有些设备比其他的有更好的支持:

-

等级 1

-

等级1设备表示用于开发的主要设备,而且常常会是最先收到漏洞修复和功能更新。

-
-
- Unagi
-
- Unagi是被用来作为中低端智能手机测试和开发平台的一个手机,许多核心Firefox OS开发者都使用Unagi。
-
- Otoro
-
- Otoro是被用来作为中低端智能手机测试和开发平台的一个手机,许多核心Firefox OS开发者都使用Otoro。
-
- 开发平台Pandaboard
-
- Pandaboard是一个基于OMAP(开放式多媒体应用平台,Open Multimedia Application Platform)4架构的开发用电路板,用于移动平台上的开发工作。
-
- 模拟器(ARM和x86)Emulator (ARM and x86)
-
- 有两种可用的模拟器:一个模拟ARM代码(指令集),而另一个运行在x86代码(指令集)上。
-
- 桌面
-
- 你也可以构建Firefox OS的桌面版本;这种方式在XULRunner应用中运行Gecko,接着你就可以在其中使用Gaia用户界面了。
-
-

当然,你也可以构建桌面客户端或者使用模拟器

-

等级2

-

等级2设备为一般功能性设备,许多开发者(特别是应用开发者)都是用这样的设备,所以他们往往在之后选择更新。

-
-
- Samsung Nexus S
-
- 已知的Nexus S设备中可用的产品型号为GT-I9020A和GT-I9023,其他型号也许可以用。
-
- Samsung Nexus S 4G
-
- SPH-D720作为等级2设备支持。
-
-

等级3

-

Firefox OS可以在这些设备上构建,但是他们并不是核心开发者积极工作的基础设备。他们的可靠性和功能设置可能会明显的落后于等级1设备甚至于等级2设备。

-
-
- Samsung Galaxy S2
-
- 唯一可用的产品型号是i9100;没有其他的同类型变体具有官方兼容性。(i9100P可能可用,因为它唯一的改变是增加了一个NFC芯片)
-
- Samsung Galaxy Nexus
-
- 现在所知的没有任何变体产品可以兼容。
-
-
- 重点: 仅支持至少运行Android 4(又称Ice Cream Sandwich)的设备,如果你的设备在上面列出来了,但是运行的是低版本的安卓系统,请先升级在进行操作。
-

Linux系统需求

-

在Linux系统下构建Firefox OS,要求如下:

-

To build on Linux, you'll need to have a system configured with:

- -

This is more than the bare minimum, but sometimes building fails just because it's missing resources.【这已经超过最低限度,但是有时构建失败只是因为缺少资源】

-

It's possible to use other distributions, but we recommend Ubuntu 12.04 since it's the most common system people use successfully. Distributions that might not work: 32 bit distros and recent distros ( Ubuntu 12.10, Fedora 17/18, Arch Linux because of gcc 4.7).【可以使用其他发行版本,但是我们建议使用Ubuntu 12.04,因为他是人们成功使用最常用的。可能无法正常工作的发行版有:32位和最近发型版本(Ubuntu 12.10,Fedora 17/18,因为linux分支gcc 4.7-可能版本过高吧)】

-

You will also need the following tools installed:

-

【你还需要安装一下工具:】

- -

64 bit install examples:

-

Ubuntu 12.04 / Linux Mint 13 / Debian 6

-
$ sudo apt-get install autoconf2.13 bison bzip2 ccache curl flex gawk gcc g++ g++-multilib git ia32-libs lib32ncurses5-dev lib32z1-dev libgl1-mesa-dev libx11-dev make zip
-

When building on 64-bit Ubuntu, you may find that you need to add symlinks for the 32-bit versions of libX11.so and libGL.so:

-
$ sudo ln -s /usr/lib/i386-linux-gnu/libX11.so.6 /usr/lib/i386-linux-gnu/libX11.so
-$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
-

Ubuntu 12.10

-
$ sudo apt-get install autoconf2.13 bison bzip2 ccache curl flex gawk gcc g++ g++-multilib gcc-4.6 g++-4.6 g++-4.6-multilib git ia32-libs lib32ncurses5-dev lib32z1-dev libgl1-mesa-dev libx11-dev make zip
-

In addition to the steps above needed to fix issues with the 32-bit versions of the libX11.so and libGL.so libraries, you will need to specify GCC 4.6 as the default host compiler before building. After having retrieved the sources, see here how to do it.

-

In a fresh Ubuntu 12.10 install, you'll get an error about unmet dependenceis for ia32-libs. The following steps fix it.

-
sudo dpkg --add-architecture i386
-sudo apt-get update
-sudo apt-get install ia32-libs
-

Fedora 16:

-
$ sudo yum install autoconf213 bison bzip2 ccache curl flex gawk gcc-c++ git glibc-devel glibc-static libstdc++-static libX11-devel make mesa-libGL-devel ncurses-devel patch zlib-devel ncurses-devel.i686 readline-devel.i686 zlib-devel.i686 libX11-devel.i686 mesa-libGL-devel.i686 glibc-devel.i686 libstdc++.i686 libXrandr.i686 zip
-

Fedora 17/18:

-
$ sudo yum install autoconf213 bison bzip2 ccache curl flex gawk gcc-c++ git glibc-devel glibc-static libstdc++-static libX11-devel make mesa-libGL-devel ncurses-devel patch zlib-devel ncurses-devel.i686 readline-devel.i686 zlib-devel.i686 libX11-devel.i686 mesa-libGL-devel.i686 glibc-devel.i686 libstdc++.i686 libXrandr.i686 zip perl-Digest-SHA
-

In addition to the above you will need GCC 4.4 in order to compile the project. You can find a pre-compiled version here. Download it and install it to /opt with the following command:

-
$ wget http://people.mozilla.org/~gsvelto/gcc-4.4.7-bin.tar.xz
-$ sudo tar -x -a -C /opt -f gcc-4.4.7-bin.tar.xz
-
-

You will need to specify this compiler as the default host compiler before building. After having retrieved the sources, see here how to do it.

-

 

-

Arch Linux (not functional yet):

-
$ sudo pacman -S --needed alsa-lib autoconf2.13 bison ccache curl firefox flex gcc-multilib git gperf libnotify libxt libx11 mesa multilib-devel wireless_tools yasm lib32-mesa lib32-ncurses lib32-readline lib32-zlib
-

By default, Arch Linux uses Python3. You'll have to force it to use the old python2:

-
$ cd /usr/bin
-
-$ sudo ln -fs python2 python
-

Mac OS X系统需求

-

To build Firefox OS on Mac OS X, you need to install Xcode's Command Line Utilities.

-

You can download just the Command Line Utilities from Apple's developer downloads page for your particular version of OS X.

-

However, if you would like the entire Xcode suite of applications, you can install Xcode through the Mac App Store. 

-

Install Command Line Utilities via XCode 4.3.1 and newer

-

Xcode 4.3.1 (OS X 10.7 "Lion") and other newer versions such as 4.4.1+ (that is, Mac OS X10.8 "Mountain Lion"), won't necessarily include the required Command Line Utilities. When you install Xcode, make sure to go into Preferences, then the Downloads panel, and install the Command Line Utilities. In addition, make sure you have at least 20 GB of free disk space.

-

Screenshot of Xcode Downloads Command Line Tools

-
- Note: The Firefox OS emulator requires a Core 2 Duo processor or later; that is, a system that is compatible with Mac OS X 10.7 "Lion." You do not actually have to be running Lion, you just have to be compatible with it. You can, however, build any Firefox OS build on many older Macs.
-

Firefox OS Mac Bootstrap

-

Open a terminal and run the following command:

-
curl -fsSL https://raw.github.com/mozilla-b2g/B2G/master/scripts/bootstrap-mac.sh | bash
-

It will pull and run a bootstrap script that makes sure you have all the prerequisites met to build the emulator. It will also prompt you for permission to install anything you're missing. The script will check for and install the following items:

- -
-

Xcode

-

If you have already upgraded to Xcode 4.4+ and get the message that Xcode is outdated, check the Xcode path with:

-
xcode-select -print-path
- If it still points to /Developer you can update the path with: -
sudo xcode-select -switch /Applications/Xcode.app
- Next to that be sure that you have the Mac OS X 10.6 SDK available at: -
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
-

If it cannot be found there you will need to extract and copy it from the Xcode 4.3 DMG file which is available at the Apple Developer portal. You can use the utility Pacifist to extract the 10.6 SDK. Be sure to add a symlink to it to the /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ directory. (We can drop the 10.6 SDK requirement after bug 784227 has been fixed, and our version of platform_build has been updated.)

-

Mountain Lion

-
-

If you are building on OS X 10.8 "Mountain Lion" (Xcode 4.4.1 or later) and encounter the following error:

-
external/qemu/android/skin/trackball.c:130:25: error: 'M_PI' undeclared (first use in this function)
- Edit the file: B2G/external/qemu/Makefile.android and add in line 78:
-
MY_CFLAGS += -DM_PI=3.14159265358979323846264338327950288   #/* B2G_fix: not finding M_PI constant */
-
-
- If you are on Mountain Lion and you receive an error during the installation of the dependencies via homebrew, such as:
-
-
-
-
clang: error: unable to execute command: Segmentation fault: 11
- ... try reinstalling the dependency manually adding the --use-gcc flag, for example: -
brew install mpfr --use-gcc
-
-

Samsung Galaxy S2

-

If you plan to build for the Samsung Galaxy S2, you will also need to install heimdall. See Installing heimdall for details. This is not done for you by the bootstrap script!

-
- Note: If you have installed the Samsung Kies tool, which is used to manage the contents of many Samsung phones, you will have to remove it before you can flash Firefox OS onto your device. You can use the standard application removal process on Windows; on Mac, the Kies install disk image has a utility to fully remove Kies from your system. Flashing will not work if you have Kies installed. If you forget to remove Kies, the build system will detect it and remind you to uninstall it. Note also that the uninstall tool does not correctly remove the folder ~/Library/Application Support/.FUS, and leaves a reference to a utility there in your user startup items list. You will want to remove these manually.
-
- Note: Mac OS X uses a case insensitive filesystem by default, which will prevent you from building Firefox OS down the road (EDITOR'S NOTE: I have never had a problem with this).  You should create a case sensitive sparse disk image work from within that directory.  To buld the case sensitive disk image:
-
hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/firefoxos.dmg
-

Mount the drive with:

-
open ~/firefoxos.dmg
-

Change into the mouted drive with:

-
cd /Volumes/untitled/
-

Fix libmpc dependency if broken

-

gcc 4.6 was built with libmpc 0.9; if you then use homebrew to update packages, libmpc gets updated to version 1.0, but homebrew doesn't rebuild gcc 4.6 after the library version changes. So you need to create a symlink to make things work again, like this:

-
cd /usr/local/lib/
-ln -s libmpc.3.dylib libmpc.2.dylib
-

Optional: Install HAX

-

Intel provides a special driver that lets the B2G emulator run its code natively on your Mac instead of being emulated, when you're using the x86 emulator. If you wish to use this, you can download and install it. It's not required, but it can improve emulation performance and stability.

-

安装adb

-

在构建B2G之前,需要从手机的安卓安装上拷贝下来二进制对象(当然,除非你要构建模拟器)。为此,你需要安装adb,安卓调试桥(Android Debug Bridge)。安装adb这篇文件中讲解了如何安装adb。

-
-

在你将来使用adb时请注意:为了调试你的手机,adb需要手机的锁屏处于解锁状态(至少在最新的Firefox OS中是这样的)。你最好禁用锁屏(我们在以后的构建指导中说明如何来做)。

-
-

安装heimdall

-

Heimdall is a utility for flashing the Samsung Galaxy S2. It's used by the Boot to Gecko flash utility to replace the contents of the phone with Firefox OS, as well as to flash updated versions of B2G and Gaia onto the device. You'll need it if you want to install Firefox OS on a Galaxy S2; it is not needed for any other device. For other devices, we build and use the fastboot utility instead.

-
- Note: Again, it's important to note that this is only required for installing Firefox OS on the Samsung Galaxy S2.
-

There are two ways to install heimdall:

- -
-

Note: Building the latest Heimdall from source currently produces errors. It is better to instead use the 64bit packaged version from the Ubuntu 14.04 repos. i.e. don't use heimdall-flash:i386 if you can avoid it.

-
-

配置 ccache

-

B2G构建过程使用ccache,ccache的默认缓存大小是1GB,但是B2G构建很容易就会占满这个缓存;建议把缓存调整到10G左右。你可以通过在终端中运行下面这个命令来配置你的缓存:

-
ccache --max-size 10GB
-

针对Linux:为你的手机配置udev 规则

-
-

注意: 这一节是针对Linux用户;OS X用户已经安装了必要的设备权限。

-
-

接下来,你需要为你的手机配置udev规则。

-

你可以通过运行lsusb来获得你插入的手机的 USB供应商编号(USB vendor ID) ,通常是Google 18d1, Samsung 04e8, ZTE 19d2, Geeksphone/Qualcomm 05c6。

-

在文件/etc/udev/rules.d/android.rules中加上这一行(使用你的设备供应商ID替换XXXX):

-
SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", MODE="0666", GROUP="plugdev"
-

以中兴手机作为例子,android.rules的内容如下:

-
SUBSYSTEM=="usb", ATTR{idVendor}=="19d2", MODE="0666", GROUP="plugdev"
-

对于Firefox Flame,内容如下:

-
SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", MODE="0666", GROUP="plugdev"
-

请注意fastboot设备(flash时使用)可能有一个不同的供应商ID(vendor ID),故你需要为它添加一条规则。例如Firefox Flame也需要谷歌的供应商ID

-
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev"
-
-

如果文件不存在则创建,通常,rules.d目录默认为只读,所以你可能要使用chmod来使目录、文件或两者可写。

-
-

一旦你保存了文件就关闭它,让文件可读:

-
sudo chmod a+r /etc/udev/rules.d/android.rules
-

由于udev规则更新了,重启udev守护进程。

-

Ubuntu

-
sudo service udev restart
-

Fedora 20

-
sudo systemctl restart systemd-udevd.service
-

ARCH

-
sudo udevadm control --reload-rules
-
-

注意: 这也许需要稍长的时间,取决于你的发行版本,类似于:
-
- sudo vi /etc/udev/rules.d/android.rules
- sudo service udev restart
- sudo /etc/init.d/udev restart
- sudo reload udev
- sudo udevadm trigger

-
-

最后,拔掉USB接口但是不要重新插上,因为我们要先启动手机上的远程调试。

-

启动远程调试

-

在你把你的手机插回USB端口上之前,让其处于USB开发者模式,这允许你调试并更新(flash)你的手机,在你的手机上启动开发者设置 中的 远程调试(在老版本中称为开发者模式)来启动开发者模式。一旦勾选了这个选项,远程调试即启动,然后你就可以继续了。

-

现在,通过USB连接你的手机和电脑(如果你在之前创建了一个udev规则,这将会触发udev检测你的手机并创建相应权限的设备节点)。现在你可以检查你是否可以通过adb devices命令来列出你的设备(谨记adb只可以在你的手机处于解锁时看到它)。如果一切OK,你应该可以看到类似于下面的输出(下面这个是对于一个极客手机Keon来说):

-
$ adb devices
-List of devices attached
-full_keon       device
-

如果设备没有列出来,检查文件名称和脚本是否正确(详见之前的小节),然后重启电脑并重新输入命令,还要注意你的设备是否使用fastboot,引导程序可能会识别为一个不同的供应商ID而不是你正常用设备引导看到的那个。

-

备份手机system分区

-
-

注意: 如果你没有已存在的系统备份,在构建系统之前你必须做这一步,因为在构建期间有许多库会被引用,这些库可能是专有的以至于我们不能在基础代码中提供他们。

-
-

建议你备份手机上的整个安卓系统分区。

-

你可以使用这份安卓二进制对象副本,以防后面你会删除你的B2G树,运行:

-
adb pull /system <backup target dir>/system
-

 你可能还需要拷贝出/data 和/或 /vendor目录,不过这取决于手机:

-
adb pull /data <backup target dir>/data
-adb pull /vendor <backup target dir>/vendor
-

如果pull命令因“权限不足”而失败,尝试下面的步骤:

- -

On to the next step

-

At this point, you should be ready to fetch the Firefox OS code!

diff --git a/files/zh-cn/archive/b2g_os/firefox_os_faq/index.html b/files/zh-cn/archive/b2g_os/firefox_os_faq/index.html deleted file mode 100644 index 079c31f3fa..0000000000 --- a/files/zh-cn/archive/b2g_os/firefox_os_faq/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Firefox OS FAQ -slug: Archive/B2G_OS/Firefox_OS_FAQ -tags: - - B2G - - FAQ - - Firefox OS -translation_of: Archive/B2G_OS/Introduction ---- -
-
- 我如何能获取到一个开发者预览版的Firefox OS手机?
-
- 它们即将在Geeksphone网站上首发。
-
- 如果我不想买一个新的手机,我还能为Firefox OS手机开发一个App吗?
-
- 当然可以!你可以在你的Android手机上测试你的App(配合Marketplace for Firefox)或者在电脑上使用Firefox OS模拟器.
-
- 预览版和最终版的手机会有什么区别?
-
- 关于该手机何时进入普通消费市场,我们正在和其他几个合作伙伴进行沟通.这些手机的硬件配置如何,我们到时候再讨论.
-
- 我从哪里可以下载到Firefox OS?
-
- https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS/Building_and_installing_Firefox_OS
-
- 如何测试我的Firefox OS App?
-
- 使用Android或Firefox OS模拟器.
-
- 什么是Firefox OS?
-
- 它是一个全新的手机操作系统,采用了完全开放的Web标准实现.即使是用HTML5开发的Web App,页能使用到设备的每个基础功能(比如打电话,发短信,浏览本地文件等),而其他手机操作系统下,只有原生App能实现这些需求.
-
- 哪里有一个完整的Web API列表?准备把这些API进行标准化吗?
-
- Firefox OS的最初版本将会实现大量的Web API.完成的列表可以在这里找到:https://wiki.mozilla.org/WebAPI#APIs.标准化工作也正在进行中.
-
- 这些Web API标准化之后可以跨平台使用吗?
-
- 是的,这些API是在我们和其他几个合作伙伴以及经销商的共同合作下产生的,其中一些API已经应用在了其他的平台上.如何能让Web App访问到最终用户的硬件,这几乎是所有的技术公司都在面临的问题,我们正是做了一个好的开始.
-
diff --git a/files/zh-cn/archive/b2g_os/index.html b/files/zh-cn/archive/b2g_os/index.html deleted file mode 100644 index 850f1933e0..0000000000 --- a/files/zh-cn/archive/b2g_os/index.html +++ /dev/null @@ -1,243 +0,0 @@ ---- -title: B2G OS -slug: Archive/B2G_OS -tags: - - B2G - - Firefox OS - - Gaia - - NeedsTranslation - - TopicStub - - 火狐OS -translation_of: Archive/B2G_OS ---- -
-

Firefox OS 是由 Mozilla 打造的全新移动操作系统,基于 Linux 系统和驱动火狐浏览器的强大 Gecko 渲染引擎开发。

-
- -
-

Firefox OS 是完全开源的,因而避免了专有技术。她能为应用开发人员提供有力的支持以创造优秀的产品。此外,这款灵活的操作系统能够创造优异的用户体验。

- -

对 web 开发者而言,最重要的部分莫过于理解 Firefox OS 的整个用户界面就是一个 web 应用,而且这个 web 应用具有启动并展现其他 web 应用的能力。尽管提高了对移动设备硬件和服务的访问,但是您对用户界面的改动和您开发的任何在 Firefox OS 上运行的 web 应用使用的都是 HTML、CSS 和 JavaScript。

- -

从产品的角度看,Firefox OS 是 Mozilla 公司(以及其 OEM 合作伙伴)的品牌,它基于 Boot to Gecko (B2G),Boot to Gecko 是 Firefox OS 操作系统的工程代号,它是由 Mozilla 内部的一组工程师团队和 Mozilla 开源社区的众多外部贡献人员共同开发的。

-
- -
-

开发 Firefox OS 应用

- -

访问我们的应用中心,获取开发 Firefox OS 应用所需要的各种信息!

-
- -
-
-

平台指南

- -

为平台开发者提供的指南,主要讲述了FIrefox OS 平台的不同组件是如何组合在一起并工作的。

- - -
- -
-

构建与安装

- -

在模拟器,兼容设备或桌面模拟器上编译及安装 Firefox OS 的指南。

- - -
- -
-

开发者手机

- -

针对开发者手机的相关信息,如微调、更新、恢复和购买。

- - -
-
- -
-
-

Firefox OS 书籍

-有若干涵盖 Firefox 开发各方面的书籍已经出版或正在编写中。要想详细了解,请访问 Firefox OS Books
- - -
- -
-

注:如果您想要为 Firefox OS 中文文档做贡献,请查看 Firefox OS 文档翻译进度

-
- -

- -
-

加入 Firefox OS 社区

-
-
请选择你喜欢的方式加入我们:
- -
-
- -
-
-

- - - -
    -
  1. 介绍
  2. -
  3. 平台指南 -
      -
    1. 平台指南概述
    2. -
    3. 架构概述
    4. -
    5. 应用架构
    6. -
    7. Gonk
    8. -
    9. Gecko
    10. -
    11. Gaia
    12. -
    13. Gaia 应用指南
    14. -
    15. 安全 -
        -
      1. Firefox OS 安全模型
      2. -
      3. 系统安全
      4. -
      5. Firefox OS 中的应用程序安全
      6. -
      7. 安全地安装和更新应用程序
      8. -
      -
    16. -
    17. Firefox OS 上的内存溢出管理
    18. -
    19. 特性支持统计表
    20. -
    21. 设置列表
    22. -
    -
  4. -
  5. 构建和安装 -
      -
    1. 构建和安装概述
    2. -
    3. Firefox OS 构建概述
    4. -
    5. 构建依赖
    6. -
    7. 首次构建前的准备
    8. -
    9. 构建 Firefox OS
    10. -
    11. 移植 Firefox OS
    12. -
    13. 用哪种方式运行 Gaia 和 Firefox OS
    14. -
    15. 使用 Firefox OS 桌面客户端
    16. -
    17. 使用 Firefox OS 模拟器
    18. -
    19. 安装 Firefox OS 到移动设备端
    20. -
    21. 创建和应用 Firefox OS 更新包
    22. -
    23. 运行时工具
    24. -
    -
  6. -
  7. Firefox OS 开发 -
      -
    1. Firefox OS 开发概述
    2. -
    3. 提交 Firefox OS 相关 bug
    4. -
    5. 修改 hosts 文件
    6. -
    7. 定制 .userconfig 文件
    8. -
    9. 定制 b2g.sh 脚本
    10. -
    -
  8. -
  9. Gaia 开发 -
      -
    1. Gaia 开发概述
    2. -
    3. 运行 Gaia 代码库
    4. -
    5. 理解 Gaia 代码库
    6. -
    7. 修改 Gaia 代码
    8. -
    9. 测试 Gaia 代码修改
    10. -
    11. 为 Gaia 提交 patch
    12. -
    13. Gaia 构建系统入门
    14. -
    15. 定制 build-time 应用
    16. -
    17. 市场定制指南 
    18. -
    19. 在 Firefox OS 应用中定制键盘
    20. -
    21. Firefox OS 本地化
    22. -
    23. Make 选项参考文档
    24. -
    25. Gaia 工具参考
    26. -
    -
  10. -
  11. Firefox OS 设备指南 -
      -
    1. 开发者手机指南概述
    2. -
    3. 手机和设备规格
    4. -
    5. Geeksphone
    6. -
    7. ZTE OPEN
    8. -
    9. ZTE OPEN C
    10. -
    11. Flame
    12. -
    13. 一般设备特性
    14. -
    15. 疑难解答
    16. -
    17. 开放参考设备最佳实践
    18. -
    -
  12. -
  13. Firefox OS 发行记录 -
      -
    1. Firefox OS 发行记录概览
    2. -
    3. Firefox OS 2.1 for developers
    4. -
    5. Firefox OS 2.0 for developers
    6. -
    7. Firefox OS 1.4 for developers
    8. -
    9. Firefox OS 1.3 for developers
    10. -
    11. Firefox OS 1.2 for developers
    12. -
    13. Firefox OS 1.1 for developers
    14. -
    15. Firefox OS 1.0.1 for developers
    16. -
    -
  14. -
  15. 自动化测试 -
      -
    1. Firefox OS 测试概述
    2. -
    3. 在 Firefox OS 上进行测试:开发者指南
    4. -
    5. Gaia UI 测试
    6. -
    7. Gaia 集成测试
    8. -
    9. Gaia 单元测试
    10. -
    11. Gaia 性能测试
    12. -
    13. Mochitests
    14. -
    15. Reftests
    16. -
    17. WebAPI 测试
    18. -
    19. xpcshell 测试
    20. -
    21. 耐久性测试
    22. -
    23. MTBF 测试
    24. -
    25. Marionette
    26. -
    27. TBPL
    28. -
    29. Jenkins
    30. -
    -
  16. -
  17. 调试 -
      -
    1. Firefox OS 调试概述
    2. -
    3. Firefox OS 开发相关设置
    4. -
    5. 连接 Firefox OS 设备到电脑
    6. -
    7. 使用 Firefox 开发者工具调试 Firefox OS
    8. -
    9. 如何在移动设备上打印日志
    10. -
    11. 安装和使用 ADB
    12. -
    13. 截屏
    14. -
    15. 使用 WebIDE
    16. -
    17. 使用 Firefox OS 应用管理器
    18. -
    19. Firefox OS 崩溃报告
    20. -
    21. 调试 Firefox OS 的内存错误
    22. -
    23. 调试并对 Firefox OS 进行安全性测试
    24. -
    25. 使用 gdb 调试 B2G
    26. -
    27. 使用 Valgrind 调试 B2G
    28. -
    -
  18. -
diff --git a/files/zh-cn/archive/b2g_os/installing_on_a_mobile_device/index.html b/files/zh-cn/archive/b2g_os/installing_on_a_mobile_device/index.html deleted file mode 100644 index 390c5e9e73..0000000000 --- a/files/zh-cn/archive/b2g_os/installing_on_a_mobile_device/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: 在移动设备上安装 Firefox OS -slug: Archive/B2G_OS/Installing_on_a_mobile_device -tags: - - Ch -translation_of: Archive/B2G_OS/Installing_on_a_mobile_device ---- -

- -

Once you've built Boot to Gecko for a supported mobile device, you can install it. This article will guide you through the process.

- -
Note: The first time you flash your phone, it must have Android 4 (Ice Cream Sandwich) installed. The process will not work correctly otherwise. Once you've done your first install of B2G, however, you can simply update on top of it.
- -

刷机

- -

To flash everything to your phone, simply connect your phone and type:

- -
./flash.sh
-
- -

That's it. The B2G you've currently got built will flash onto your device.

- -

Configuring the udev rule for your device

- -

On Linux, if you get this,

- -
< waiting for device >
- -

that probably means that you haven't added a udev rule for the fastboot device, which is not the same as the one for adb. You can get the USB vendor ID by running lsusb now, but typically it's Google's: 18d1, so adding this line in your /etc/udev/rules.d/51-android.rules would work:

- -
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev"
- -
Note: If you get a very helpful libusb error "-3" on Linux, it means you need to be root to have the needed access to the USB device. Run the script again using sudo.
- -
Note 2: If you have an Unagi or a Geeksphone Keon phone, you need two lines like this - one for the original phone vendor's ID, and one for Google's.
- -

Special notes for Hamachi, Helix, and Leo devices

- -

If your phone is a hamachi, helix or leo device, the ./flash.sh script will now default to flashing only gecko and gaia.  It is recommended that you flash with the OEM as a base build to get the firmware and the gonk layers and then flash the gecko and gaia on top.  If you want to flash using the images, there is an override flash where you can ./flash.sh -f and it will use the image files to flash your device.

- -

Special notes for the Samsung Galaxy S2

- -

If your phone is a Galaxy S2 and you are using heimdall 1.3.2 (the latest version; use heimdall version to check), you may see an alarming error "FACTORYFS upload failed!" followed by "Heimdall flashing failed" and some additional information. This is actually a success condition, and you can ignore the advice.

- -

To get rid of this strange behavior, grab a source copy of heimdall, downgrading to the 1.3.1 release ("git checkout fbbed42c1e5719cc7a4dceeba098981f19f37c06"), then compile it  according to the README, then install that to make the error go away. However, this isn't strictly necessary.

- -

All versions of heimdall are unable to flash a system.img larger than 100MB. Do:

- -
ls -l ./out/target/product/galaxys2/system.img
-
- -

to see how big yours is. If it's too large, ask in IRC for advice; there are ways to do it in two stages.

- -

Added step for the Samsung Galaxy S2

- -

If you're flashing onto the Galaxy S2, there is an additional step to follow. Gaia does not get flashed automatically by the flash.sh script; you'll need to also do:

- -
./flash.sh gaia
-
- -

Flashing specific partitions to fastboot phones

- -

You can flash specific partitions to fastboot phones (that is, any phone other than the Samsung Galaxy S2). For example:

- -
./flash.sh system
-./flash.sh boot
-./flash.sh user
-
- -

Updating specific modules

- -

You can update specific components of B2G by specifying their names when flashing. For example:

- -
./flash.sh gaia
-./flash.sh gecko
-
- -

In order to update only one application you can use BUILD_APP_NAME environment variable:

- -
BUILD_APP_NAME=calendar ./flash.sh gaia
- -

If your phone is not for developer (you aren't interested on test apps and/or require optimization), you can update gaia using:

- -
VARIANT=user ./flash.sh gaia
- -

Next steps

- -

At this point, your phone should be running Boot to Gecko! It's time to experiment, write some code, test, or do some debugging!

- -
Note: A helpful usage tip: if your build of B2G starts up with the lock screen requesting a pass code to unlock the phone, the default code is 0000.
- -

Troubleshooting

- -

Here are a some tips for what to do if your device doesn't work right after installing B2G, or updating it to a new version

- -

If the UI doesn't start up

- -

If you update your phone and the user interface doesn't start up, you can reset it to clear out out-of-date configuration and the like. This may bring it back to life. Here's how:

- -
cd gaia
-make reset-gaia
-
- -

If you want change from developer to production mode

- -
cd gaia
-make reset-gaia PRODUCTION=1
- -

"image is too large" error message on ./flash.sh execution

- -

It might mean that you phone needs to be rooted first before flashing it. As b2g needs to be written on root partition, your phone needs to be rooted in order to install it.

diff --git a/files/zh-cn/archive/b2g_os/introduction/index.html b/files/zh-cn/archive/b2g_os/introduction/index.html deleted file mode 100644 index 5652a42443..0000000000 --- a/files/zh-cn/archive/b2g_os/introduction/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Firefox OS简介 -slug: Archive/B2G_OS/Introduction -tags: - - B2G - - Firefox OS - - Gaia - - 介绍 - - 社区 -translation_of: Archive/B2G_OS/Introduction ---- -

 

- -
-

Firefox OS 致力于推进关于手机完全运行web的可能性和允许新的手机使用用户完全的在线使用他们的首部智能手机的范围. 它是一个开放源码的基于Linux的移动操作系统, 开放的Web标准和Mozilla的Gecko引擎科技提供的关于对手机移动平台的重新定义. 通过关于WebAPI对硬件调用的能力的介绍和提供用户一个直观的, 简洁并且优雅的智能手机体验, Mozilla相信对开发者来讲Web将会提供巨大的机遇去得到用户的青睐用优秀的Web软件.

-
- -

目标读者

- -

这套文档是针对于那些想要学习知道Firefox OS的工作机制,怎样去开发项目,怎样去编译和安装他们自己开发的软件的web和平台开发者们. 对那些想要创建和发布他们的web应用的开发者来说, App CenterMarketplace Zone是理想的去处. 

- -

Firefox OS 的基本承诺

- -

对于Web/平台开发者来讲, 最重要的部分是理解整个用户调用接口层其实就是一个能够显示和发布其他Web应用的Web应用. 即使对移动设备的硬件和服务可访问性增强了, 但是任何对于用户接口的修改和你在Firfox OS上新建的应用都还是将会引用标准的web技术. 从一个产品的远景来看, Firefox OS是支持用Gecko(操作系统的产品工程研发代号)去启动系统后运行服务的Mozilla平台品牌.  Firefox OS的用户接口层叫做Gaia, 其中包含了系统的默认的应用和系统函数. 想要发现更多关于平台的架构, 请访问 平台指南.  

- -

当前和未来的计划

- -

Firefox 0S 2.0正在开发中, 将要出来1.3/1.4 稳定的编译版本. 在开发者和消费者中有很多各种型号不同的手机. 可以知道的更多通过阅读下面的几点:

- - - -

发布周期

- -

Since Firefox OS 1.2, the Firefox OS release cycle has been aligned as closely as possible with the Gecko and Firefox desktop version release cycle (6 weeks). A new Firefox OS version is released new every three months, so there will be a Firefox OS release for every two Gecko (Firefox browser core) releases.

- -

For example. Gecko 30 is bundled with Firefox 1.4, bypassing Gecko 29, and Gecko 32 is bundled with Firefox 2.0 (was 1.5), bypassing Gecko 31.

- -
-

Note: Check out our rapid release calendar to check the corresponding versions between Firefox OS and Gecko / Desktop Firefox, and read Firefox OS Release Milestones for more information on how our releases are managed.

-
- -

社区

- -

Boot to Gecko and Gaia are developed by teams of engineers inside Mozilla, plus, many external contributors from the wider Mozilla/open source community. If you want to talk to the community about any aspect of Firefox OS or Gaia development, a good place to start is our mailing lists and IRC channels, detailed in the below info box.

- -

- -
-

加入 Firefox OS 社区

-
-
请选择你喜欢的方式加入我们:
- -
-
- -
-
-

- -

To file bugs, use our Bugzilla system, and file bugs against the Firefox OS components. If you are not sure what component to file a bug against, feel free to ask.

- -
-

Note: If you have a question or a point to raise about a specific part of the B2G/Gaia source code (for example, a specific Gaia app), you can find more specific contact details on ourFirefox Modules page.

-
- -

构建一个操作系统

- -

The B2G operating system is based on Mozilla's Gecko rendering engine, and sits on top of a Linux kernel and userspace hardware abstraction layer (HAL) called Gonk. The Gecko talked about here is basically the same Gecko used in Firefox for Android, or Windows, or Mac OS X, etc. Gonk is basically another porting target of Gecko.

- -

To learn how to build and install Firefox OS, consult our guide to Building and installing Firefox OS. You can find the B2G source code on Github.

- -

为 Gaia 做贡献

- -

To contribute to Gaia, you don't need much more than a solid knowledge of web development. To learn about getting Gaia up and running, consult our Quickstart guide to Gaia development.

- -

There are a number of useful tools available to you for debugging Gaia and other web apps running on Firefox OS. To learn about these and much more, consult our guide to Hacking Gaia.

- -

为 Firefox OS 开发 app

- -

Firefox OS apps are built using standard web technologies — HTML, CSS, JavaScript, etc. — so if you are a web developer you will also have most of what you need. There are a few special JavaScript APIs to know about, which allow you to access device hardware and key features (for example camera, gyroscope, light sensor, contacts, system alarms and notifications...), but these are all well documented on our App Center and Web Platform pages.

- -
-

Note: If you are a beginner to building open web/Firefox OS apps, or if you want a concise account of the differences between web apps and traditional web pages, the best place to start is our apps Quickstart guide.

-
- -

支持跨 Firefox OS 版本的应用

- -

Note that when developing apps for Firefox OS, you need to bear in mind what platform versions will be available on the devices your customers will have (see our available phones table for a list.) Remember that it is not as simple to update phone platform software as it is desktop software — users tend to be at the mercy of the network providers. You therefore need to develop apps to support these versions. As an example, multiline Flexbox doesn't work on Firefox OS versions below 1.3, so you may need to use a simpler layout method or provide a fallback for older versions.

- -

This issue should go away soon, as more consumer Firefox OS devices appear, equipped with newer versions of Firefox OS out of the box.

- -
-

The current baseline platform we recommended developing for is Firefox 1.1.

-
- -
-

Note: MDN's web platform reference pages include browser/platform support information, plus you can find support information for more App-specific technologies on our Apps API Reference.

-
- -

 

diff --git a/files/zh-cn/archive/b2g_os/phone_guide/best_practices_open_reference_devices/index.html b/files/zh-cn/archive/b2g_os/phone_guide/best_practices_open_reference_devices/index.html deleted file mode 100644 index 3e92766166..0000000000 --- a/files/zh-cn/archive/b2g_os/phone_guide/best_practices_open_reference_devices/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: 开放参考设备最佳实践 -slug: Archive/B2G_OS/Phone_guide/Best_practices_open_reference_devices -translation_of: Archive/B2G_OS/Phone_guide/Best_practices_open_reference_devices ---- -
-

The following article aims to provide a set of best practices that we believe should come highly recommended for any widely available open reference devices. All of the recent Firefox OS reference devices have followed these practices, including the forthcoming Flame.

-
-

Devices should have:

- -

Easily accessible and installable builds

-

Reference devices are largely aimed at developers and other groups with a greater degree of technical knowledge than average device consumers. But even so, we shouldn't expect users of these devices to compile their own builds if they don't wish to — for many of them this is a complete waste of time.

-

Open reference devices should have a maintained set of unlocked builds for current and future releases that are easy to access and install. This means having multiple tiers of builds available, at least:

- -

They should be made easily available on a dedicated download page, and updated regularly and often. Devices should also have OTA updates made available to them.

-

The OEMs should be responsible for providing these builds since they are the only ones who can legally distribute all the required binaries, etc.

-

It may make sense to follow a similar model to the Firefox browser, where each of the release, stable and nightly channels are based on subsequent versions of the source code.

-

Completely unlocked operating system

-

The device operating system platform should be completely unlocked, so that app and platform developers can have the necessary freedom of control available over their devices to perform any desired tests and development work. This includes:

- -

Worldwide availability

-

If you want your reference devices to be a universal standard, then it follows that you should make them available worldwide. If this is not the case, people in different locales will have to make do with different devices, which may carry different behaviours.

-

Feature support equivalent to consumer phones

-

There is no point in creating a reference device that does not have support for the same technologies and associated features as the consumer devices you will ultimately be distributing Firefox OS builds and open web apps on.

-

These include:

- -

Availability of replacement batteries

-

Replacement batteries can often be really hard to obtain for different devices, and can lead to otherwise useful devices being rendered useless. It is therefore a good idea to make replacement batteries as available as possible.

-

Easily enabled language choices

-

Since these device will be distributed worldwide, it is important to make localised builds available for as many languages as possible,  taking into account availability of resources and most popular target market locales.

-

The most likely solution to this is localised Gaia builds or language packs that can be flashed onto the device separately, and Mozilla is working on a solution to make creation and installation of these as easy as possible.

diff --git a/files/zh-cn/archive/b2g_os/phone_guide/flame/index.html b/files/zh-cn/archive/b2g_os/phone_guide/flame/index.html deleted file mode 100644 index 91947e54fd..0000000000 --- a/files/zh-cn/archive/b2g_os/phone_guide/flame/index.html +++ /dev/null @@ -1,258 +0,0 @@ ---- -title: Flame -slug: Archive/B2G_OS/Phone_guide/Flame -translation_of: Archive/B2G_OS/Phone_guide/Flame ---- -

A picture of the Flame device, showing the Firefox OS homescreen containing several app icons.

- -

Available to order

- -

The Flame developer reference phone is a milestone in Firefox OS device releases. The Flame hardware offers a representative set of specs — including FWVGA display and dual-core processor — to help developers build great content and experiences. A single hardware platform is also good for testers, making it easier to test and address specific software issues without having to worry about device model-specific bugs, etc.

- -

If you have your phone in hand and want to start playing with it, developing and distributing apps, or contributing to the Firefox platform, the following links will get you where you need to go:

- - - -

If you’d like to find out more about updating the operating system, recovering it, pushing apps to it, or phone specs, you’ll find the information you need below.

- -

Purchasing a device

- -

Our device manufacturer partner has made the device available to order on everbuying.com, for US$170 including global shipping (device cost is $145, shipping is $25 and custom fees may still apply, depending on the destination country). The device is bootloader and carrier unlocked, and it utilizes a quad-band GSM+UMTS radio so that it can work with a wide variety of operators/carriers.

- -
-

Note: Another option for getting hold of a Flame is to participate in our Flames for Apps scheme, aimed at experienced HTML5 app developers wishing to port their highly-rated apps onto Firefox OS.

-
- -

Updating your Flame's software

- -

We will have two main "channels" of Firefox OS software version releases for the Flame phone:

- - - -
-

Note: Windows users will need to install a driver to enable USB communication with their phones. See how to do this in the Windows section below. Linux users may need to add a udev rule; see the Linux and Mac section.

-
- -

While our partners are working out a final storage solution for the software builds, you can get recovery files and tools at the following Onedrive storage locations:

- - - -

To install the base image on your device:

- -
    -
  1. Install ADB on your computer.
  2. -
  3. If you are on Windows, install the driver, as explained in the Windows section below.
  4. -
  5. Make sure remote debugging is enabled on your Flame, using the Remote debugging/Debugging via USB option in the device's Developer settings (the option is different, depending on whether you have Firefox 1.3 and under, or Firefox 1.4+ installed).
  6. -
  7. Connect your Flame to your computer via a USB cable. Verify that the computer is connected to the device by running the adb devices command in a terminal.
  8. -
  9. Download and Extract the software appropriate for your system listed above (the .zip in the case of Mac / Linux, the .exe in the case of Windows)
  10. -
  11. Go into the directory you extracted the software into and run it: -
      -
    • On Windows, simply run the executable.
    • -
    • On Linux / OSX, use the terminal to enter the directory, then run the flash.sh script using sudo ./flash.sh (if you don't run it using sudo, the flash script may fail to see your device, and it won't work).
    • -
    -
  12. -
- -
-

Note: You are also welcome to build your own builds to install on the Flame: see Building and installing Firefox OS.

-
- -

Updating your Flame to a nightly build

- -
-

Note: For this current build, Nightly development builds of Firefox OS do not support A-GPS, which may lead to slow performance of GPS functionality. We plan to resolve this in an updated future Nightly channel.

-
- -
    -
  1. Before updating your phone to a nightly build you should flash the latest base image to make sure the underlying systems are up to date. Download a base image and use it to update your device's software, as explained above.
  2. -
  3. Because the above step installs a fresh operating system on your device, you'll need to enable remote debugging on your Flame again, using the Remote debugging option in the device's Developer settings.
  4. -
  5. Next, choose a Nightly build to install. You can find nightly builds on http://ftp.mozilla.org/pub/mozilla.org/b2g/nightly/. You'll want one of the following: - -
  6. -
  7. Pick a version and download both the b2g-XX.XX.en-US.android-arm.tar.gz and gaia.zip files.
  8. -
  9. Download the shallow flash script and save it in a sensible place (such as the same directory as the above two files.)
  10. -
  11. Flash the builds to your phone using the following command: -

    Mac

    - -
    ./shallow_flash.sh -g /path/to/gaia.zip -G /path/to/b2g-XX.XX.en-US.android-arm.tar.gz
    - -

    Linux

    - -
    ./shallow_flash.sh -g/path/to/gaia.zip -G/path/to/b2g-XX.XX.en-US.android-arm.tar.gz
    -
  12. -
- -
-

Note: If you get a "permission denied" error when running the above command, your shell script probably doesn't have the right permissions. Running chmod +x shallow_flash.sh on it should solve this problem.

-
- -
-

Note: A "shallow flash" only updates Gecko and Gaia, as opposed to a full flash, which updates Gecko/Gaia, but also the underlying Gonk layer and associated binaries particular to that device type. This is why it is a good idea to update to the official base image first, as suggested above, then to shallow flash over the top of that, once you've got the Gonk/binary layer right.

-
- -
-

Shallow flash flashes more than just Gecko and Gaia so all the data on the device is lost!

-
- -

Once the install procedure finishes the phone should reboot into the updated build and the first time user workflow.

- -

Font fix

- -

After updating Gecko and Gaia to nightly with the v123 base image, there will be a mismatch between the fonts that Gecko and Gaia expects and what the base image provides. To fix this, download our font update package, extract it, navigate into the directory created by extracting, and run the supplied flash.sh script.

- -

Fastboot mode

- -

If flashing a new build to your phone fails to work, your phone may becomes unresponsive, and the phone may always reboot in recovery mode. The recovery mode allows you a few actions (reboot, update from adb, wipe data, wipe cache, update from sdcard). Unfortunately, selecting update from adb triggers a sideload mode and you cannot use the other adb commands, only adb sideload would work but the various flash scripts rely on other adb commands.

- -

In this case, you can probably force fastboot mode as follows:

- -
    -
  1. power off the phone (which may involve removing the battery in extreme cases...),
  2. -
  3. plug in the USB cable
  4. -
  5. power the phone up again by pressing the Volume Down and Power buttons together.
  6. -
- -

The phone should only display the very first static logo and stay there, without displaying the boot animation. It seems stuck but is not really: it is in fastboot mode and is waiting for something on the USB cable. At this step, a computer on the other side of the USB cable should see the phone when running fastboot devices to list the connected devices. Note that regular adb would not see the device, only fastboot sees it. In this mode, you can use the flash script to install v123 as explained above. As the script does use both adb and fastboot commands, you may see some initial error and warnings from adb, but eventually the device should be flashed properly at the end.

- -

Emergency download mode

- -

If flashing a new build to your phone fails to work, your phone becomes unresponsive, and the phone cannot enter fastboot mode, you can use emergency mode for recovery. A USB cable and the Emergency Download Tool are required to enter emergency download mode. Install this tool and follow the instructions.

- -

Recovery mode

- -

You can enter recovery mode to clear your phone data or manually update the firmware. There are two ways to enter this mode:

- - - -

When in recovery mode, press the Volume up/down keys to move the selection highlight, and the Power key to select. Make sure you have your phone data (Contacts, SMS, etc.) backed up before clearing data, and your upgrade packages downloaded before updating.

- -

Pushing apps to your Flame

- -

The App Manager tool makes it easy to push apps to your phone, for testing, etc. Full instructions are available in the article Using the App Manager.

- -
-

Important: Additional platform-specific instructions are available below. Follow these first before attempting to use the App Manager.

-
- -

Linux and Mac

- -

No additional steps should be required if you are using a Linux or Mac system, although depending on your Linux distro, you might need to add a udev rule for your phone, which will look something like the following:

- -
SUBSYSTEM=="usb", ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="9025", GROUP="users", MODE="0666"
- -

Make sure to --reload-rules, then unplug and replug and your device before continuing.

- -

Windows

- -

To access the Flame device with the App Manager/ADB, a USB driver is required. Follow the steps outlined in the below sections to install it.

- -

Downloading the driver

- -

Download the Windows driver from this location. Once downloaded, extract the contents of the ZIP file to a suitable place on your hard drive.

- -
-

Note: The Android Debug Bridge (ADB) must be already installed.

-
- -

Installing the USB Driver

- -

At this point, connect your Flame device to your computer using a USB cable.

- -

To install the driver, open the Alcatel_USB_Driver_Q_4.0.0_2013_11_11_noinstall directory within the extracted ZIP file and double click on the DriverInstaller.exe executable. You may receive a warning at this point that the executable is from an unknown publisher. If so, select the Yes button and the executable will be launched.

- -

Simple dialog box showing a picture of a phone along with install and uninstall buttons.

- -

Click on the Install button to install the driver.

- -

After the driver installs, you can check that it is working by opening a command line window and typing adb devices. This should list the connected device with an output something like:

- -
List of devices attached
-3561d02a          device
- -

If your device is not showing up here, check in the Windows Device Manager. Your Flame may be showing up as "ACER ADB Interface". You can confirm this by unplugging the device and seeing if it disappears from the device manager. Uninstall the driver software by right-clicking on "ACER ADB Interface" and clicking uninstall.  Be sure to check the box in the dialog to delete the driver software.  Now re-run the installer above. It is advisable to set the screen timeout on your Flame to something high (Settings > Display > Screen timeout) as Windows sometimes appears to reinstall the default drivers when the screen turns off.

- -

RAM adjustment

- -

You can adjust the available RAM capacity to see how apps perform on Firefox OS phones with lower memory footprints.

- -

This is accomplished by entering fastboot mode (install fastboot first, which is available on the same SDK page as ADB) and typing:

- -
adb reboot bootloader
-fastboot oem mem [0|256-1024]
- -

“0” is the memory automatically detected and “256-1024” is the number of megabytes. For example, if you want to adjust device RAM capacity to 512M, enter fastboot oem mem 512.

- -

You'll need to then reboot your device for the settings to take effect. This can be done using:

- -
fastboot reboot
- -

The current memory size can be returned by entering fastboot mode and typing:

- -
fastboot getvar mem
-
- -

Network and Device specs

- -

Network:

- - - -

Hardware: You can find more of the hardware features listed on our Phone and device specs page.

- -

Additional features include:

- - - -

See also

- - - -
- -
- -

 

diff --git a/files/zh-cn/archive/b2g_os/phone_guide/index.html b/files/zh-cn/archive/b2g_os/phone_guide/index.html deleted file mode 100644 index ff0395cc14..0000000000 --- a/files/zh-cn/archive/b2g_os/phone_guide/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Firefox OS 开发者手机指南 -slug: Archive/B2G_OS/Phone_guide -translation_of: Archive/B2G_OS/Phone_guide ---- -
-

本节包含了运行Firefox OS 的指定手机相关的开发者信息。我们已经有关于  Building and installing Firefox OS 和 Hacking Firefox OS  的文章,因此请到那里获取关于编译和安装的信息。 但与特定手机相关的开发人员会发现下面的文档是非常有用的。

-
- -

特定的设备信息

- -
-
Firefox OS phone data
-
在这篇文章中我们列举出了能够得到的Firefox OS手机的信息。比如型号,什么时候能够得到还有一些硬件特性之类的信息都能在这里找到。
-
Flame
-
Information on Mozilla's high-end Firefox OS reference phone, codenamed the Flame, and produced in partnership with T2Mobile.
-
Geeksphone
-
In this article we cover some basic tips on how to keep your Geeksphone up-to-date and how to tweak the system Gaia applications.
-
ZTE OPEN
-
This article contains information on the ZTE OPEN Firefox OS device.
-
ZTE OPEN C
-
The ZTE Open C is an updated ZTE-produced Firefox OS device, with higher end hardware and newer software.
-
 
-
- -

一般的  Firefox OS 信息

- -
-
General device features
-
This page lists typical Firefox OS hardware features and minimum hardware requirements.
-
Troubleshooting
-
This article provides tips for resolving common problems you may have while using Firefox OS.
-
Best practices for open reference devices
-
A set of best practices that we believe should come highly recommended for any widely available open reference devices. All of the recent Firefox OS reference devices have followed these practices.
-
diff --git a/files/zh-cn/archive/b2g_os/phone_guide/phone_specs/index.html b/files/zh-cn/archive/b2g_os/phone_guide/phone_specs/index.html deleted file mode 100644 index 04faf7017e..0000000000 --- a/files/zh-cn/archive/b2g_os/phone_guide/phone_specs/index.html +++ /dev/null @@ -1,439 +0,0 @@ ---- -title: Phone and device data -slug: Archive/B2G_OS/Phone_guide/Phone_specs -translation_of: Archive/B2G_OS/Phone_guide/Phone_specs ---- -
-

这篇文章提供有关Firefox OS设备的信息,包括特定的硬件规格,代号,默认安装Firefox OS的版本等等。

-
- -

可使用的Firefox OS手机

- -

下面的表格列举了可使用的或已经可用的Firefox OS设备模型。

- -
-

注意:关于可使用的商业手机的信息,包括可得到手机的国家和经营者,请查阅我们的发现你附近的Firefox OS网页。

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称/代号释放日期最初版本可否获得备注
-

Alcatel One Touch Fire

- -

hamachi, buri

-
2013年7月12日1.0.1在售 -

在巴西、乌拉圭、意大利、德国、希腊、塞尔维亚、匈牙利和波兰公开发售。

- -

可由eBay上的经销商获得。

-
Alcatel One Touch Fire E2014年7月18日1.3.0在售在捷克、德国、匈牙利、波兰、俄罗斯公开发售。
otoro, unagi, inari   在ZTE Open之前的用于开发的ZTE非定制机。
-

ZTE Open

- -

ikura

-
2013年7月2日1.0.1在售和inari相似,在eBay公开发售。
-

LG Fireweb

- -

leo

-
2013年10月24日1.1在售在巴西公开发售。
-

Geeksphone Keon

- -

keon

-
2013年4月24日1.0.1已脱销专为开发者提供的设备。
-

Geeksphone Peak

- -

peak

-
2013年4月24日1.0.1已脱销过去一段时间的代号为“twist",专为开发者提供的设备。
Geeksphone Peak+  不再发售已被取消
Geeksphone Revolution2014年3月4日1.3pre在售在线发售
-

LG Google Nexus 4

- -

nexus-4

-
   实验性,不再被Google和LG支持,硬件停止开发
-

Flame

- -

"the reference device"

-
2014年4月晚些时候1.3  -

可以预订

- -

在2014年12月售完

-
-

Spreadtrum

- -

tarako

-
2014年第二季度末期 马上销售 
-

ZTE Open C

-
2014年5月13日1.3在售在线发售
Symphony GoFox F152014年9月16日1.4在售仅可通过孟加拉国格莱珉电话公司(Grameenphone)的通道获得。
Intex Cloud Fx 1.3在售仅可由印度的Snapdeal公司获得
Spice Fire One (Mi-FX1) 1.3在售仅可由印度的Snapdeal公司获得
Alcatel OneTouch FireC 4020D2014年10月1日1.3在售Filpkart销售
Zen Fire 1052014年10月16日1.3在售Homeshop18销售
Cherry Mobile Ace2014年11月1.3T在售在菲律宾公开发售
Fx02014年12月2.0在售消费者电话,在日本(KDDI.)公开发售
- -

Firefox OS版本

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
版本特性完成(FC)日期合作伙伴释放日期代号Gecko版本包括的安全补丁释放版标记
1.02012年12月22日2013年2月21日TEFGecko 18Gecko 18 
1.0.12013年1月15日2013年9月6日ShiraGecko 18Gecko 20Developer
- Consumer
1.12013年3月29日2013年10月9日LeoGecko 18+ (new APIs)Gecko 23Developer
- Consumer
1.1.1 TBDHDSame as 1.1.0 with WVGAGecko 23 
1.22013年9月15日2013年12月9日KoiGecko 26Gecko 26Developer
- Consumer
1.32013年12月9日TBD Gecko 28Gecko 28Developer
- Consumer
1.42014年3月17日TBD Gecko 30Gecko 30Developer
- Consumer (TBD)
2.02014年11月TBD Gecko 32Gecko 32Developer
- Consumer (TBD)
- -

设备规格

- -

注意:由于某些原因,有一款即将出现的设备没有被说明,但是我们将分享这些设备的代号和一些性能。不要放额外的设备信息,除非Andreas Gal或者其他同样可以公开说明已公开的信息的人的同意。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameCodenameVersionsResolutionRAMStorage
Alcatel One Touch Firehamachi, buriv1.0.1/v1.1 -

320 x 480
- PX=1

-
256M/data: probably the same as inari; specs say 160MB "end user memory"
- Probably no built-in DeviceStorage, MicroSD card (up to 32GB) required
-  
ZTE Open / variantsikurav1.0.1 (as shipped)320 x 480
- PX=1
256M -

/data: 152M
- No built-in DeviceStorage, MicroSD card required

-
LG Firewebleov1.1320 x 480
- PX=1
  -

/data: 1007.90M
- built-in DeviceStorage: yes, size unsure. possibly 3.7G, but that might be bad math.  (On an unhapy device /sys/devices/platform/msm_sdcc.3/mmc_host/mmc0/mmc0:0001/block/mmcblk0/block is 7733248, and then assuming a 512 byte block size, we get 3.7G)

-
Geeksphone Keonkeon -

v1.0.1 - nightly
- downloads here

-
320 x 480
- PX=1
512M -

/data: 1.5G
- built-in DeviceStorage: 1023.4M

-
Geeksphone Peakpeakv1.0.1 - nightly
- downloads here
540 x 960
- PX=1.5
512Mprobably the same as the keon based on specs.
Nexus 4nexus-4v1.3 - nightly768 x 12802GBeverything exists in one big soup, there is no external (MicroSD) storage.  The size of the soup varies based on what model Nexus 4 you got.
some tablet thingflatfish    
some phone thingfuguv1.2f (branch) per320 x 480256MB 
some 128MB platform thingtarakov1.3 per320 x 480128MB (zram) 
- -

列行解释:

- - diff --git a/files/zh-cn/archive/b2g_os/platform/apps_architecture/index.html b/files/zh-cn/archive/b2g_os/platform/apps_architecture/index.html deleted file mode 100644 index 0960f1d970..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/apps_architecture/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Firefox OS apps 架构 -slug: Archive/B2G_OS/Platform/Apps_architecture -translation_of: Archive/B2G_OS/Platform/Apps_architecture ---- -
-

本文讲述了Firefox OS 应用启动和管理的内部原理。对 Firefox OS 平台开发者和将操作系统移植到硬件的团队是有用的。如果您仅仅是一个应用开发者,则不用了解这些细节,但又何妨一读,因为它是十分有趣的过程。

-
-

app启动过程

-

当用户选择他们想要启动或需要启动的应用时, home screen app会通过App API,获取到一个app的引用,之后会调用 App.launch() 方法启动这个应用。 

-

Gecko 接收到请求后会向携带着 app 详情 向System app发送 mozChromeEvent 事件。 System app 对事件进行处理:向 DOM tree中插入一个新的 <iframe> ,并且在这个新的 <iframe> 中装载 app。 此后 frame 就会是 app 的  home 了,直到 app终止。

-

每个 app都需要一个 manifest文件来对 app进行描述,并且在它的包中有一个特定的文件结构。要了解更多详情,请参阅文章 App manifest

-

与 Gecko 通信

-

Gecko 和 Gaia 系统应用之间的通信是通过 mozChromeEventmozContentEvent 完成的。mozChromeEvent 是从 chrome 到 content 的广播;而   mozContentEvents 是从 content 到  chrome 的广播。 这种通信过程用来控制可信任UI 的创建和关闭,以及为通知和其他工作注入需要的功能,如告诉System app 启动一个 app 。

-
-

注意:  通过阅读  System app documentation 您可以获取到关于这些事件工作的更多的内容。 通过阅读 b2g/chrome/content/shell.js 您也可已获取到更多使用的细节。 

-
-

参见

- diff --git a/files/zh-cn/archive/b2g_os/platform/architecture/index.html b/files/zh-cn/archive/b2g_os/platform/architecture/index.html deleted file mode 100644 index 4b57f44ada..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/architecture/index.html +++ /dev/null @@ -1,1024 +0,0 @@ ---- -title: Firefox OS架构 -slug: Archive/B2G_OS/Platform/Architecture -tags: - - Architecture - - B2G - - Firefox OS - - Guide - - IPC - - IPDL -translation_of: Archive/B2G_OS/Architecture ---- -

 

- -
-

草案
- 本页尚未完工.

-
- -

 

- -

这篇文章是对Firefox OS平台的高度概览,介绍了一些关键的概念以及组件如何交互的过程。

- -
-

Note: Firefox OS 仍然是未发布的产品,这里描述的架构并不是最终版本。

-
- -

Firefox OS 术语

- -

在进一步学习 Firefox OS 文档前,请先了解下面的术语。

- -

架构框图

- -
-
B2G
-
Boot to Gecko 的简称。
-
Boot to Gecko
-
Firefox OS 操作系统的工程代号。 因为在该项目拥有官方名称之前B2G已经使用了很久的原因,它经常用于指代 Firefox OS。
-
Firefox OS
-
FIrefox OS 基本上是指 Mozilla及合作伙伴应用在 B2G上的品牌和服务支持, 最终将创建一个发布的产品。
-
Gaia
-
Firefox OS 平台的用户接口层。屏幕启动时渲染到屏幕上的一切都是Gaia层的产物。Gaia 实现了 lock screen, home screen, 和所有你所期待在智能手机上看到的标准应用。Gaia 完全使用 HTML, CSS, 和 JavaScript实现。Web APIs 是Gaia层到底层系统的唯一入口,Web APIs 是由Gecko 层实现的。第三方应用可以安装在Gaia层。
-
Gecko
-
Firefox OS 应用的运行环境;该层提供了对: HTML, CSS, and JavaScript三个标准的支持,它能确保APIs能够在gecko支持的系统上良好工作。也就是说,它包括了网络栈,图形栈,布局引擎,js虚拟机和端口层。
-
Gonk
-
Gonk 是Firefox OS平台更低层的系统,包括了 Linux kernel (基于 AOSP)和用户空间硬件抽象层 (HAL)。内核和一些用户空间库都是公共的开源项目:linux, libusb, bluez等。其他的一些硬件抽象层部分是与android项目共享的:GPS, camera等。你可以认为 Gonk 是一个非常简单的 Linux 版本。Gonk 是 Gecko 层的端口目标;也就是说 Gecko 层有到 Gonk 的端口,就像Gecko 到 Mac OS X, Windows, 和 Android 一样。因为Firefox OS 对 Gonk 拥有完全的控制权,相比其他操作系统,我们可以释放更多的接口到 Gecko。例如,Gecko 拥有到 Gonk 电话栈和帧缓冲区的直接入口,但在其他操作系统却没有。
-
Jank
-
这个术语经常用在移动app空间的讨论中,主要是指在app中缓慢/低效的代码操作会导致 block UI的更新甚至出现无响应状态。我们的gaia工程师会不惜一切代价使用各种优化技术来避免这一问题。
-
 
-
 
-
Firefox OS Architecture
-
- -

 

- -

Firefox OS 启动步骤

- -

本节主要描述了FIrefox OS 设备启动以及各模块交互的过程。简而言之,整个系统的启动流程是从内核空间的bootloaders开始,继而对native code初始化,到B2G至用户空间的Gecko,最后会到 Gaia 层 system app,window manager,homescreen app。而其他应用都是在它们上面执行的。

- -

Firefox os bootup

- -

自启动过程

- -

当Firefox OS 设备启动时,执行过程从主要的引导装载程序(primary bootloader)开始。此时,会以常用的方式装载主操作系统。在这个链条中,一级级的装载会触发更高层次的迭代。这个过程最终是交由 Linux 内核处理。

- -

关于启动过程,这里有几点需要注意的地方:

- - - -

Linux 内核

- -

Gonk使用的 Linux内核与原生Linux派生出的AOSP是非常相似的。与AOSP (Android Open Source Project )相比,它还有一些小的变化。另外,厂商还可能会对内核进行修改,并将这些变化按照自身的要求来设定。 一般而言, Linux内核是非常相近的。

- -

网络上对 startup process for Linux 有许多详细的介绍,此处不会再赘述。

- -

Linux内核会带动设备的启动并且运行基本的过程。它会先执行 init.rc 中的步骤,继而运行 init.b2g.rc 来启动必须的步骤, 如包含的Gecko内的Firefox OS 基本过程以及 rild (电话相关由不同芯片组相关的进程)— 下面会有更详细的说明。 在过程结束时,正如绝大多数 UNIX-like 操作系统一样, 用户空间 init 进程会被启动。

- -

init 进程启动完成时,Linux内核会处理来自用户空间的系统请求,来自硬件的中断等。许多硬件特性会通过 sysfs 暴露给用户空间。例如这里的 代码片段 就在Gecko中读取电池的状态。

- -
FILE *capacityFile = fopen("/sys/class/power_supply/battery/capacity", "r");
-double capacity = dom::battery::kDefaultLevel * 100;
-if (capacityFile) {
-  fscanf(capacityFile, "%lf", &capacity);
-  fclose(capacityFile);
-}
- -

init 进程

- -

在Gonk中的 init 进程会处理文件系统的加载请求以及派生的系统服务。在此之后,它会作为进程的管理器而存在。这与其他的 UNIX-like操作系统是非常类似的。它会 将init*.rc 脚本文件解释成包含启动各种服务的命令的集合。Firefox OS init.b2g.rc 其实就是在 Android init.rc 文件的基础上添加一些关于启动Firefox OS的命令的文件。

- -

init 进程启动过程中一个关键任务就是启动 b2g 进程,它是 Firefox OS 操作系统的核心所在。

- -

init.b2g.rc 文件中启动b2g进程的命令如下所示:

- -
service b2g /system/bin/b2g.sh
-    class main
-    onrestart restart media
- -

您也可以查看下 init.b2g.rc 文件内容,它是添加在 Android init.rc 文件后用来启动b2g进程的。

- -
-

注意: 对\不同的设备而言init.rc 与 Android 的 对应文件间的差别也是不同的。,init.b2g.rc 只是简单的附加在文件后面的,有时候 patch 文件显得会更重要些。

-
- -

userspace 进程架构

- -

现在如果概览一下Firefox OS的不同组件是如何组合在一起并与其他组件交互的过程是非常有用的。下图则包含了 Firefox OS 主要的 usersapce 进程。

- -

Userspace diagram

- -
-

注意: 我们应当知道,由于 FIrefox OS 正处在活跃开发阶段,这个框图可能会发生变化,不会那么准确。

-
- -

b2g 进程是主要的系统进程。它会以非常高的优先级运行,并且会访问绝大多数的硬件设备。b2g 会和 modem 进行通信, 会在 display framerbuffer上绘图, 与 GPS, Camera 以及其他硬件交互。 b2g 内部运行在Gecko层(由 libxul.so 实现)。查看 Gecko 可以获得 Gecko层如何工作, b2g 与Gecko如何通信的细节。

- -

b2g

- -

b2g 进程可能会反过来孵化一些低优先级的 content processes。 这些进程都是关于 web 应用或其他的 web 内容装载的过程。这些进程会和Gecko server主进程通过 IPDL 消息传送系统进行通信。

- -

rild

- -

rild 进程是 modem 处理器的接口。 rild 是实现 Radio Interface Layer (RIL) 的守护进程。 它是一个专有的代码,由硬件供应商与自己的modem 硬件实现。rild 使客户端代码连接它所绑定的 UNIX域的 socket成为可能。它会由 init 脚本中的如下代码启动:

- -
service ril-daemon /system/bin/rild
-    socket rild stream 660 root radio
- -

rilproxy

- -

在Firefox OS 中, rild 客户端就是 rilproxy 进程。它在 rildb2g 扮演着简单的转发代理服务器的角色。这个代理需要的是实现的细节,可以说,这确实是非常必要的。riproxy 代码可以在Github上找到。

- -

mediaserver

- -

mediaserver 进程控制着音频和视频的播放。Gecko会通过 Android远程过程调用机制(RPC)与 其通信。Gecko可以播放的多媒体(OGG Vorbis 音频, OGG Theora 视频,以及 WebM 视频)都是由 Gecko解码并直接发送给 mediaserver 进程。其他的多媒体文件是由 libstagefright 解码的,它能够访问专用编码器和硬件编码器。

- -
-

注意: mediaserver 进程时一个临时的Firefox OS组件, 对我们初始的开发会有帮助,但最终会离开。然而在 Firefox OS 2.0 之前,可能不会发生。

-
- -

netd

- -

netd 进程用来对网络接口进行配置。

- -

wpa_supplicant

- -

wpa_supplicant 进程是标准的 UNIX样式的守护进程,会处理 WIFI 的连接。

- -

dbus-daemon

- -

dbus-daemon 实现了 D-Bus( DBus 是指Firefox OS 用于蓝牙通信的一种消息总线系统)。

- -

 

- -

Gecko

- -

Gecko,正如之前提到的,是对 web标准( HTML, CSS, andJavaScript)的实现,用于实现用户在Firefox OS 上看到的一切界面。

- -
-

注意: 您可以使用 http://dxr.mozilla.org 来查找Gecko代码库。这个网站非常有趣,并且提供了较好的参照特性,但是代码库的数量有限。或者您可以尝试下传统的 http://mxr.mozilla.org ,其中会包括更多的Mozilla 项目。

-
- -

与Firefox OS 相关的 Gecko 文件

- -

b2g/

- -

b2g 文件夹会包含了一些主要的Firefox OS 相关的功能。.

- -
b2g/chrome/content
- -

包含了在system app 之上运行的 Javascript 文件。

- -
b2g/chrome/content/shell.html
- -

Gaia的入口 — system app的html。 shell.html 会加载 settings.js 和 shell.js:

- -
<script type="application/javascript;version=1.8" src="chrome://browser/content/settings.js"> </script>
-<script type="application/javascript;version=1.8" src="chrome://browser/content/shell.js"> </script>
- -
 
- -
 
- -

settings.js 包含了系统设置的默认参数。

- -
b2g/chrome/content/shell.js
- -

shell.js 是在 Gaia system app中装载的第一个脚本文件。.

- -

shell.js 导入了所有需要的模块,注册键值监听,定义了 sendCustomEvent sendChromeEvent 与Gaia 通信,并且提供了 webapp 的安装助手: indexedDB quota, RemoteDebugger, keyboard helper, 和screenshot 工具。

- -

但是shell.js 最重要的功能就是启动了 Gaia system app, 之后又将整个系统相关的管理工作移交给了 Gaia system app。

- -
let systemAppFrame =
-  document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
-    ...
-  container.appendChild(systemAppFrame);
- -
 
- -
 
- -
 
- -
 
- -
b2g/app/b2g.js
- -

这个脚本中包含了预定义的配置信息,如浏览器中的 about:config, 文件与 Gaia 中的 pref.js 类似。这些配置可以在 Settings app中更改,可以使用Gaia 构建脚本文件 Gaia user.js文件覆写。

- -

dom/{API}

- -

新的 API 实现(post-b2g)放置在 dom/ 文件夹中;而旧的API 的 dom/base 文件夹中,如 navigator.cpp。

- -
dom/apps
- -

.jsm 文件会被加载,是对.js API 的实现,如 webapp.js 等。

- -
dom/apps/src/
- -

所有的权限信息都在 PermissionsTable.jsm 文件中定义。

- -

dom/webidl

- -

WebIDL 是一种用来定义 web APIs 的语言。可查看 WebIDL_bindings 文件来获取它所支持的特性。

- -

hal/gonk

- -

这个文件夹包含了 gonk 接口层的相关文件。

- -

Generated files

- -
module/libpref/src/init/all.js
- -

包含所有的配置文件。

- -
/system/b2g/ omni.ja and omni.js
- -

包含了设备中的资源样式包。

- -

输入事件处理

- -

在Gekco层绝大多数动作都是由用户行为触发的。这些动作是由输入事件所表示的(如按钮点击,触屏设备的触控,等等)。这些事件是通过 nsIAppShellGonk implementation 传入的,这个接口用来表示Gecko 应用的最初入口点。也就是说, 输入设备会调用 nspAppShell对象的方法,来表示 Gecko子系统想要发送事件到用户界面。

- -

例如:

- -
void GeckoInputDispatcher::notifyKey(nsecs_t eventTime,
-                                     int32_t deviceId,
-                                     int32_t source,
-                                     uint32_t policyFlags,
-                                     int32_t action,
-                                     int32_t flags,
-                                     int32_t keyCode,
-                                     int32_t scanCode,
-                                     int32_t metaState,
-                                     nsecs_t downTime) {
-  UserInputData data;
-  data.timeMs = nanosecsToMillisecs(eventTime);
-  data.type = UserInputData::KEY_DATA;
-  data.action = action;
-  data.flags = flags;
-  data.metaState = metaState;
-  data.key.keyCode = keyCode;
-  data.key.scanCode = scanCode;
-  {
-    MutexAutoLock lock(mQueueLock);
-    mEventQueue.push(data);
-  }
-  gAppShell->NotifyNativeEvent();
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

这些事件都来自于标准的Linux input_event 系统。Firefox OS 使用了 light abstraction layer 来覆写它;它也提供了较好的特性如事件过滤机制。 您可以在 widget/gonk/libui/EventHub.cpp 文件的 EventHub::getEvents() 的方法中找到创建输入事件的代码。

- -

当Gecko层接收到事件时,就会通过nsAppShell 分发到DOM中。

- -
static nsEventStatus sendKeyEventWithMsg(uint32_t keyCode,
-                                         uint32_t msg,
-                                         uint64_t timeMs,
-                                         uint32_t flags) {
-    nsKeyEvent event(true, msg, NULL);
-    event.keyCode = keyCode;
-    event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;
-    event.time = timeMs;
-    event.flags |= flags;
-    return nsWindow::DispatchInputEvent(event);
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

此后,事件就会由Gecko本身处理或作为 DOM events 分发到web 应用中进一步处理

- -

图像

- -

在底层, Gecko 会使用 OpenGL ES 2.0 to draw to a GL context that wraps the hardware frame buffers. 这是由 Gonk 层nsWindow 实现的,代码如下:

- -
gNativeWindow = new android::FramebufferNativeWindow();
-sGLContext = GLContextProvider::CreateForWindow(this);
- -
 
- -
 
- -

FramebufferNativeWindow 类是直接 从Android拿过来的,可参考 FramebufferNativeWindow.cpp。为了能够将缓存从帧缓存设备映射到内存中,它使用了 gralloc API 来访问图像驱动。

- -

Gecko 使用了 Layers 系统来将复合后的内容画在屏幕上。总结一些,基本步骤是:

- -
    -
  1. Gecko draws separate regions of pages into memory buffers. Sometimes these buffers are in system memory; other times, they're textures mapped into Gecko's address space, which means that Gecko is drawing directly into video memory. This is typically done in the method BasicThebesLayer::PaintThebes().
  2. -
  3. Gecko then composites all of these textures to the screen using OpenGL commands. This composition occurs in ThebesLayerOGL::RenderTo().
  4. -
- -

The details of how Gecko handles the rendering of web content is outside the scope of this document.

- -

硬件抽象层 (HAL)

- -

The Gecko hardware abstraction layer is one of the porting layers of Gecko. It handles low-level access to system interfaces across multiple platforms using a C++ API that's accessible to the higher levels of Gecko. These APIs are implemented on a per-platform basis inside the Gecko HAL itself. This hardware abstraction layer is not exposed directly to JavaScript code in Gecko.

- -

How the HAL works

- -

Let's consider the Vibration API as an example. The Gecko HAL for this API is defined in hal/Hal.h. In essence (simplifying the method signature for clarity's sake), you have this function:

- -
void Vibrate(const nsTArray<uint32> &pattern);
- -

This is the function called by Gecko code to turn on vibration of the device according to the specified pattern; a corresponding function exists to cancel any ongoing vibration. The Gonk implementation of this method is in hal/gonk/GonkHal.cpp:

- -
void Vibrate(const nsTArray<uint32_t> &pattern) {
-  EnsureVibratorThreadInitialized();
-  sVibratorRunnable->Vibrate(pattern);
-}
- -
 
- -
 
- -
 
- -
 
- -

This code sends the request to start vibrating the device to another thread, which is implemented in VibratorRunnable::Run(). This thread's main loop looks like this:

- -
while (!mShuttingDown) {
-  if (mIndex < mPattern.Length()) {
-    uint32_t duration = mPattern[mIndex];
-    if (mIndex % 2 == 0) {
-      vibrator_on(duration);
-    }
-    mIndex++;
-    mMonitor.Wait(PR_MillisecondsToInterval(duration));
-  }
-  else {
-    mMonitor.Wait();
-  }
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

vibrator_on() is the Gonk HAL API that turns on the vibrator motor. Internally, this method sends a message to the kernel driver by writing a value to a kernel object usingsysfs.

- -

Fallback HAL API implementations

- -

The Gecko HAL APIs are supported across all platforms. When Gecko is built for a platform that doesn't expose an interface to vibration motors (such as a desktop computer), then a fallback implementation of the HAL API is used. For vibration, this is implemented in hal/fallback/FallbackVibration.cpp.

- -
void Vibrate(const nsTArray<uint32_t> &pattern) {
-}
- -
 
- -
 
- -

Sandbox implementations

- -

Because most web content runs in content processes with low privileges, we can't assume those processes have the privileges needed to be able to (for example), turn on and off the vibration motor. In addition, we want to have a central location for handling potential race conditions. In the Gecko HAL, this is done through a "sandbox" implementation of the HAL. This sandbox implementation simply proxies requests made by content processes and forwards them to the "Gecko server" process. The proxy requests are sent using IPDL.

- -

For vibration, this is handled by the Vibrate() function implemented in hal/sandbox/SandboxHal.cpp:

- -
void Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id) {
-  AutoInfallibleTArray<uint32_t, 8> p(pattern);
-
-  WindowIdentifier newID(id);
-  newID.AppendProcessID();
-  Hal()->SendVibrate(p, newID.AsArray(), GetTabChildFrom(newID.GetWindow()));
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

This sends a message defined by the PHal interface, described by IPDL in hal/sandbox/PHal.ipdl. This method is described more or less as follows:

- -
Vibrate(uint32_t[] pattern);
- -

The receiver of this message is the HalParent::RecvVibrate() method in hal/sandbox/SandboxHal.cpp, which looks like this:

- -
virtual bool RecvVibrate(const InfallibleTArray<unsigned int>& pattern,
-            const InfallibleTArray<uint64_t> &id,
-            PBrowserParent *browserParent) MOZ_OVERRIDE {
-
-  hal::Vibrate(pattern, newID);
-  return true;
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

This omits some details that aren't relevant to this discussion; however, it shows how the message progresses from a content process through Gecko to Gonk, then to the Gonk HAL implementation of Vibrate(), and eventually to the Vibration driver.

- -

DOM APIs

- -

DOM interfaces 从本质上说,是指web内容与Gecko的如何通信的。当然此处会涉及到更多的内容,如果您对更多的细节感兴趣,可以参考 about the DOM 。. DOM 接口是使用 IDL 定义的,包括外部功能接口(FFI) 和使用JavaScript 和 C++ 的对象模型(OM)。

- -

震动API是通过IDL接口暴露给web内容的,IDL接口定义在nsIDOMNavigator.idl:

- -
[implicit_jscontext] void mozVibrate(in jsval aPattern);
- -

jsval 参数表示 mozVibrate() (这个未定版的震动规范是以我们的厂商作为前缀实现的)会接受任何输入的JavaScript值。 IDL编译器 xpidl 会产生一个C++接口,这个接口由 定义在 Navigator.cpp 文件中的 Navigator实现。

- -
NS_IMETHODIMP Navigator::MozVibrate(const jsval& aPattern, JSContext* cx) {
-  // ...
-  hal::Vibrate(pattern);
-  return NS_OK;
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -

您在这个方法中看到的源码要比这里要多,但这并非我们此次讨论的目的。关键点在于此处会调用 hal::Vibrate() 将控制行为从DOM层传送到GECKO HAL层。 在那里,我们会进入 在之前一节HAL 实现的讨论,并会一直走到图形驱动层。最重要的是,DOM的实现并不会关心它运行在那个平台 (Gonk, Windows, Mac OS X, 或者其他)。、它也不会关心这些代码时运行在 content 进程或者是 Gecko 服务器进程。这些细节都会由系统底层处理。

- -

震动 API 非常简单, 可以作为一个好的例子来讲解。 SMS API 则比较复杂会使用到自身的“远程”层级连接content 进程到服务器。

- -

Radio Interface Layer (RIL)

- -

The RIL was mentioned in the section The userspace process architecture. This section will examine how the various pieces of this layer interact in a bit more detail.

- -

The main components involved in the RIL are:

- -
-
rild
-
The daemon that talks to the proprietary modem firmware.
-
rilproxy
-
The daemon that proxies messages between rild and Gecko (which is implemented in the b2g process). This overcomes the permission problem that arises when trying to talk to rild directly, since rild can only be communicated with from within the radiogroup.
-
b2g
-
This process, also known as the chrome process, implements Gecko. The portions of it that relate to the Radio Interface Layer are dom/system/gonk/ril_worker.js (which implements a worker thread that talks to rild through rilproxy and implements the radio state machine; and the nsIRadioInterfaceLayer interface, which is the main thread's XPCOMservice that acts primarily as a message exchange between the ril_worker.js thread and various other Gecko components, including the Gecko content process.
-
Gecko's content process
-
Within Gecko's content process, the nsIRILContentHelper interface provides an XPCOM service that lets code implementing parts of the DOM, such as theTelephony and SMS APIs talk to the radio interface, which is in the chrome process.
-
- -

Example: Communicating from rild to the DOM

- -

Let's take a look at an example of how the lower level parts of the system communicate with DOM code. When the modem receives an incoming call, it notifies rild using a proprietary mechanism. rild then prepares a message for its client according to the "open" protocol, which is described in ril.h. In the case of an incoming call, aRIL_UNSOL_RESPONSE_CALL_STATE_CHANGED message is generated and sent by rild torilproxy.

- -

rilproxy, implemented in rilproxy.c, receives this message in its main loop, which polls its connection to rild using code like this:

- -
ret = read(rilproxy_rw, data, 1024);
-
-if(ret > 0) {
-  writeToSocket(rild_rw, data, ret);
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -

Once the message is received from rild, it's then forwarded along to Gecko on the socket that connects rilproxy to Gecko. Gecko receives the forwarded message on its IPC thread:

- -
int ret = read(fd, mIncoming->Data, 1024);
-// ... handle errors ...
-mIncoming->mSize = ret;
-sConsumer->MessageReceived(mIncoming.forget());
- -
 
- -
 
- -
 
- -
 
- -

The consumer of these messages is SystemWorkerManager, which repackages the messages and dispatches them to theril_worker.js thread that implements the RIL state machine; this is done in theRILReceiver::MessageReceived() method:

- -
virtual void MessageReceived(RilRawData *aMessage) {
-  nsRefPtr<DispatchRILEvent> dre(new DispatchRILEvent(aMessage));
-  mDispatcher->PostTask(dre);
-}
- -
 
- -
 
- -
 
- -
 
- -

The task posted to that thread in turn calls the onRILMessage() function, which is implemented in JavaScript. This is done using the JavaScript API functionJS_CallFunctionName():

- -
return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv), argv, argv);
- -

onRILMessage() is implemented in dom/system/gonk/ril_worker.js, which processes the message bytes and chops them into parcels. Each complete parcel is then dispatched to individual handler methods as appropriate:

- -
handleParcel: function handleParcel(request_type, length) {
-  let method = this[request_type];
-  if (typeof method == "function") {
-    if (DEBUG) debug("Handling parcel as " + method.name);
-    method.call(this, length);
-  }
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

This code works by getting the request type from the object, making sure it's defined as a function in the JavaScript code, then calling the method. Since ril_worker.js implements each request type in a method given the same name as the request type, this is very simple.

- -

In our example, RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, the following handler is called:

- -
RIL[UNSOLICITED_RESPONSE_CALL_STATE_CHANGED] = function UNSOLICITED_RESPONSE_CALL_STATE_CHANGED() {
-  this.getCurrentCalls();
-};
- -
 
- -
 
- -
 
- -

As you see in the code above, when notification is received that the call state has changed, the state machine simply fetches the current call state by calling thegetCurrentCall() method:

- -
getCurrentCalls: function getCurrentCalls() {
-  Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS);
-}
- -
 
- -
 
- -
 
- -

This sends a request back to rild to request the state of all currently active calls. The request flows back along a similar path the RIL_UNSOL_RESPONSE_CALL_STATE_CHANGEDmessage followed, but in the opposite direction (that is, from ril_worker.js toSystemWorkerManager to Ril.cpp, then rilproxy and finally to the rild socket). rildthen responds in kind, back along the same path, eventually arriving in ril_worker.js's handler for the REQUEST_GET_CURRENT_CALLS message. And thus bidirectional communication occurs.

- -

The call state is then processed and compared to the previous state; if there's a change of state, ril_worker.js notifies the nsIRadioInterfaceLayer service on the main thread:

- -
_handleChangedCallState: function _handleChangedCallState(changedCall) {
-  let message = {type: "callStateChange",
-                 call: changedCall};
-  this.sendDOMMessage(message);
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -

nsIRadioInterfaceLayer is implemented in dom/system/gonk/RadioInterfaceLayer.js; the message is received by itsonmessage() method:

- -
 onmessage: function onmessage(event) {
-   let message = event.data;
-   debug("Received message from worker: " + JSON.stringify(message));
-   switch (message.type) {
-     case "callStateChange":
-       // This one will handle its own notifications.
-       this.handleCallStateChange(message.call);
-       break;
-   ...
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

All this really does is dispatch the message to the content process using the Parent Process Message Manager (PPMM):

- -
handleCallStateChange: function handleCallStateChange(call) {
-  [some internal state updating]
-  ppmm.sendAsyncMessage("RIL:CallStateChanged", call);
-}
- -
 
- -
 
- -
 
- -
 
- -

In the content process, the message is received by receiveMessage() method in the nsIRILContentHelper service, from the Child Process Message Manager (CPMM):

- -
receiveMessage: function receiveMessage(msg) {
-  let request;
-  debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json));
-  switch (msg.name) {
-    case "RIL:CallStateChanged":
-      this._deliverTelephonyCallback("callStateChanged",
-                                     [msg.json.callIndex, msg.json.state,
-                                     msg.json.number, msg.json.isActive]);
-      break;
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

This, in turn, calls the nsIRILTelephonyCallback.callStateChanged() methods on every registered telephony callback object. Every web application that accesses the window.navigator.mozTelephony API has registered one such callback object that dispatches events to the JavaScript code in the web application, either as a state change of an existing call object or a new incoming call event.

- -
NS_IMETHODIMP Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
-                                          const nsAString& aNumber, bool aIsActive) {
-  [...]
-
-  if (modifiedCall) {
-    // Change state.
-    modifiedCall->ChangeState(aCallState);
-
-    // See if this should replace our current active call.
-    if (aIsActive) {
-      mActiveCall = modifiedCall;
-    }
-
-    return NS_OK;
-  }
-
-  nsRefPtr<TelephonyCall> call =
-          TelephonyCall::Create(this, aNumber, aCallState, aCallIndex);
-  nsRefPtr<CallEvent> event = CallEvent::Create(call);
-  nsresult rv = event->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("incoming"));
-  NS_ENSURE_SUCCESS(rv, rv);
-  return NS_OK;
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

Applications can receive these events and update their user interface and so forth:

- -
handleEvent: function fm_handleEvent(evt) {
-  switch (evt.call.state) {
-    case 'connected':
-      this.connected();
-      break;
-    case 'disconnected':
-      this.disconnected();
-      break;
-    default:
-      break;
-  }
-}
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -
 
- -

Take a look at the implementation of handleEvent() in the Dialer application as an extended example.

- -

3G data

- -

There is a RIL message that initiates a "data call" to the cellular service; this enables data transfer mode in the modem. This data call ends up creating and activating a Point-to-Point Protocol (PPP) interface device in the Linux kernel that can be configured using the usual interfaces.

- -
-

Note: This section needs to be written.

-
- - - -

This section lists DOM APIs that are related to RIL communications:

- - - -

WiFi

- -

Firefox OS 的WIFI后台只是简单的借助 wpa_supplicant 来完成绝大部分工作。也就是说,后台的主要工作就是对 supplicant 的简单管理以及一些初始化的工作,如装载WiFi 驱动和使能或禁止网络接口。后台本质上只是一个跟随supplicant 状态而变化的状态机。

- -
-

注意: 在WIFI中发生的绝大部分事情会取决于 wpa_supplicant 进程状态的变化。

-
- -

WIFI组件的实现可以分成两个文件:

- -
-
dom/wifi/DOMWifiManager.js
-
实现了暴露给web 内容的API,这些API是定义在 nsIWifi.idl中的。
-
dom/wifi/WifiWorker.js
-
实现了关于 supplicant 的状态机和驱动代码。
-
- -

这两个文件之间使用 message manager 通信。消息的后台监听需要特定的动作触发,如 "associate", 当动作执行完成时也会返回一个消息。

- -

对响应方法的DOM侧监听与一些事件消息一样,都表示状态的变化和信息的更新。

- -
-

Note: 任何同步的 DOM APIs 都是通过管道一侧的缓存数据实现的。如果可能的话,要尽量避免使用同步消息。

-
- -

WifiWorker.js

- -

This file implements the main logic behind the WiFi interface. It runs in the chrome process (in multi-process builds) and is instantiated by the SystemWorkerManager. The file is generally broken into two sections: a giant anonymous function and WifiWorker(and its prototype). The anonymous function ends up being the WifiManager by providing a local API, including notifications for events such as connection to the supplicant and scan results being available. In general, it contains little logic and lets its sole consumer control its actions while it simply responds with the requested information and controls the details of the connection with the supplicant.

- -

The WifiWorker object sits between the WifiManager and the DOM. It reacts to events and forwards them to the DOM; in turn, it receives requests from the DOM and performs the appropriate actions on the supplicant. It also maintains state information about the supplicant and what it needs to do next.

- -

DOMWifiManager.js

- -

This implements the DOM API, transmitting messages back and forth between callers and the actual WiFi worker. There's very little logic involved.

- -
-

Note: In order to avoid synchronous messages to the chrome process, the WiFi Manager does need to cache the state based on the received event.

-
- -

There's a single synchronous message, which is sent at the time the DOM API is instantiated, in order to get the current state of the supplicant.

- -

DHCP

- -

DHCP and DNS are handled by dhcpcd, the standard Linux DHCP client. However, it's not able to react when the network connection is lost. Because of this, Firefox OS kills and restarts dhcpcd each time it connects to a given wireless network.

- -

dhcpcd is also responsible for setting the default route; we call into the network manager to tell the kernel about DNS servers.

- -

网络管理器

- -

网络管理器会对由3G数据和WIFI组件打开的网络接口进行配置。

- -
-

注意: 这部分内容需要完善。

-
- -

进程和线程

- -

Firefox OS 操作系统使用 POSIX 线程机制实现所有的应用线程,包括每个应用的主线程,Web workers和辅助线程。优先值是由标准的Linux内核调度程序决定用来表示进程和线程执行时的优先级。根据进程的状态不同,我们设定了不同的优先值。当前共有7个等级:

- -

进程优先级等级

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PriorityNiceUsed for
MASTER0b2g 主进程
FOREGROUND_HIGH0持有 CPU wakelock 的应用
FOREGROUND1前台应用
FOREGROUND_KEYBOARD1键盘应用
BACKGROUND_PERCEIVABLE7播放音乐的后台应用
BACKGROUND_HOMESCREEN18homescreen 应用
BACKGROUND18运行在后台的所有其他应用
- -

有些等级优先值是相同的,这是因为这些等级是低内存查杀机制处理的方式是不同的。所有的优先级都可以在构建时通过参数配置进行调整。您可以在 b2g/app/b2g.js文件中找到相关实体。

- -
-

注意: 要获取更多关于内存溢出(out-of-memory killer)以及 Firefoex OS 是如何管理低内存状态的内容,可以参阅 Out of memory management on Firefox OS.

-
- -

在一个进程内部,主线程继承了进程的优先值,同时则给定了web worker线程比主线程高一个值的优先值。因此web worker 线程优先级与主线程相比要低一些。之所以这么做是为了避免 CPU密集性的工作降低主线程的处理速度。当比较重要的事件(如一个应用转到前台或后台,启动一个新的应用或一个已存在的应用获得 CPU wakelock)发生时,进程优先级就会发生变化。当一个进程优先级发生变化时,其中所有的线程优先级就会对应的作出调整。

- -
-

注意: cgroups 当前并没有用于资源的管理,它们在特定的设备及内核中显得并不可靠。

-
- -

 

diff --git a/files/zh-cn/archive/b2g_os/platform/feature_support_chart/index.html b/files/zh-cn/archive/b2g_os/platform/feature_support_chart/index.html deleted file mode 100644 index 591d5e7bb6..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/feature_support_chart/index.html +++ /dev/null @@ -1,158 +0,0 @@ ---- -title: 功能支持图表 -slug: Archive/B2G_OS/Platform/Feature_support_chart -tags: - - B2G - - QA - - Testing -translation_of: Archive/B2G_OS/Platform/Feature_support_chart ---- -

-
-

这里有许多不同的 Firefox OS 编译版本,您可以选择下载或者由自己编译,在每个设备上所支持的功能都会有所区别。下面的图表则可以帮助我们理解在不同设备上所支持或不支持的功能。

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
功能设备模拟器桌面版本
DialerAllUI only, no networkUI only, no network
ContactsAllAllAll
SMSAllUI only, no networkUI only, no network
CameraAllUI only, no camera supportUI only, unsure about desktop camera support at this time
GalleryAllAllAll
VideoAllUI onlyAll
MusicAll All
FM RadioAllAllUI only
EmailAllAllAll
CalculatorAllAllAll
BrowserAllAllAll
MarketplaceAllAllAll
ClockAllAllAll
CalendarAllAllAll
Home ScreenAllAllAll
Lock ScreenAllAllAll
KeyboardAllAllAll
Task ManagerAllAllAll
First-RunAll??
NotificationAllAllAll
Status BarAll一些网络状态不能被测试一些网络状态不能被测试
SettingsAllAllAll
-

 

diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/build_system_primer/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/build_system_primer/index.html deleted file mode 100644 index 85d101cf3a..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/build_system_primer/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: 构建系统入门 -slug: Archive/B2G_OS/Platform/Gaia/Build_System_Primer -translation_of: Archive/B2G_OS/Developing_Gaia/Build_System_Primer ---- -

本文介绍了Gaia构建系统是如何工作的,包括 makefile, 构建过程,环境变量及潜在定制。 

-

在构建步骤中绝大多数有意义的工作都是由存放在Gaia子文件夹 build/ 下的脚本执行的,它们主要是使用make, node.js , XPCShell (也称作JS Shell)以及 XULRunner [zh-CN]执行的。Gaia构建系统中包含许多帮助工具,可以将webapp安装,测试,定位和打包到实际设备上。它同样允许开发者通过诸如更改默认壁纸,铃声,应用和设置的方式来对Gaia自定义。

-

Makefile文件

-

 Makefile文件中包含许多有用的命令,本节会对最有用的一些命令进行解释: 

-

install-gaia

-

该命令会将Gaia层所有的应用推送到设备端。如果想要推送特定的应用,可以使用APP 标志位:

-
APP=calendar make install-gaia
-

运行上面命令时所在的位置必须是Gaia  apps 下的文件夹(例如  apps).

-

reset-gaia

-

该命令会对设备中的应用进行清理并且在安装完成应用后会设置权限的默认值,除此之外与 install-gaia 命令作用是相同的. 在构建工程时,应用会存放在 /data/local类似的目录. 它同样也会将测试和调试的应用推送到手机中。

-
-

注意: 如果在使用 reset-gaia 时加入 APP 环境变量,会使您的手机不可用(此时可以通过再次执行不带 APP 变量的命令恢复). 因此请不要这样做.

-
-

production

-

该命令会将web应用安装在/system/b2g 下,而不是/data/local,除此之外与 reset-gaia 作用是相同的。这个命令能够使您对user版本进行仿真,这个命令同样会将一系列的应用安装在user版本上

-

 

-

参考工作负载

-

These goals push variously sized workloads to the device, helping us with debugging and fixing the performance and scalability issues we might have. These goals accept the APP environment variable, or an APPS environment variable that should contain the app names separated by a space, e.g.,

-
APP=sms make reference-workload-light
-APPS="sms communications/contacts" make reference-workload-heavy
-
-  
-
-  
-
-

注意: For more information, read Hacking Gaia: Reference workloads.

-
-

环境变量

-

一些环境变量能够让你控制在设备上的构建与安装的一些方面:

-

B2G_SYSTEM_APPS=1

-

这个环境变量能够让你把应用推送到 /system/b2g 而不是 /data/local。 You should use that when you work with a user build. This variable is automatically set when running make production. This can be used for install-gaia or reset-gaia too.

-

GAIA_OPTIMIZE=1

-

This triggers an optimization pass on the JavaScript files. This is automatically set when running make production. This can be used for install-gaia or reset-gaia too.

-

PRODUCTION=1

-

This is basically an alias for make production (or is it the other way around ?).

-

DEBUG=1

-

This lets you generate a debug profile to use with the unit tests or to develop your Firefox OS app in Firefox. You must delete the existing profile directory before trying to generate a new one.

-

GAIA_DEV_PIXELS_PER_PX=1.5

-

This generates a profile suitable for running on WVGA devices.

-

Customizing the preferences

-

If you find that you have a set of custom preferences you need to set each time you flash your device, create a file called custom-prefs.js inside the build directory and store them in there. This keeps them from being overwritten and out of source control.

-

Here are some useful preferences:

-
// this enables marionette which lets you run performance tests
-// see https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS/Platform/Testing/Gaia_performance_tests
-user_pref("marionette.defaultPrefs.enabled", true);
-
-// this sets the port for remote debugging your application on the device
-user_pref("devtools.debugger.remote-port", 60000);
-
-// this enables the remote debugger
-user_pref("devtools.debugger.remote-enabled", true);
-
-// this outputs debug information about the Radio Interface Layer in logcat
-user_pref("ril.debugging.enabled", true);
-
-

This file is read each time you generate a profile. The safest way to be sure that everything is generated is to delete your profile first:

-
rm -rf profile && make profile
-

Then you can safely use the install-gaia goal.

-

FAQ

-

1) The device remains black after a flash

-

This can sometimes happen if you flash the device while it is idle. To remedy this just restart B2G by issuing the following command from the command line:

-

adb shell stop b2g && adb shell start b2g

-

 

diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/browser/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/browser/index.html deleted file mode 100644 index 856090aaca..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/browser/index.html +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: Browser -slug: Archive/B2G_OS/Platform/Gaia/Gaia_apps/Browser -tags: - - Apps - - B2G - - Firefox OS - - Gaia - - 指南 - - 浏览器 -translation_of: Archive/B2G_OS/Platform/Gaia/Gaia_apps/Browser ---- -
-

Browser app (当前是 System 的一部分) 提供了浏览器相关的功能 — 包括页面导航,搜索和书签。本文介绍了 Browser app 的基本工作以及它是如何融合进更大的 System中的。

-
-

由于 Gaia 运行 Gecko 的上层, 在基于 Gekco 实例之上,启动一个 Browser app/ System 浏览器进行常规的页面是非常容易做到的。它是由  mozBrowser API 实现的。

-
-

注意:  Firefox OS 2.1 之后, Browser app 就是 System app 的一部分了。这意味着可以同时通过点击浏览器图标启动 Browser app 或通过全局搜索以及导航的能力来进行 web 浏览。 app 和 浏览器 tab 页此后会有共同的公共体验, 它们会作为 Haida 用户体验 的一部分,存在于任务管理器和表视图中(用于边缘手势)。

-
-

System 浏览器 (浏览器框架)

-

当 Firefox OS 用户将一个 web 页面添加为标签时, 它就会显示在 homescreen 上, 这个 web 页面后续就会打开 System 浏览器而不是 Browser app。在页面底部会有一个工具栏, 包括 向前/向后/刷新的功能。在 Gaia 中,它被称之为浏览器框架或包装器( wrapper)。您可以在下面图片的右手侧看到。

-

A diagram showing that when a web page is opened in the system browser, it is given a toolbar.

-

如果想要使您的 web 页面仍具有 后退/前进/刷新 的功能, 您可以在 app 表单文件中包含下面声明来使能浏览器框架。

-
declare { chrome: { navigation: true } }
-
-

注意:  浏览器框架工具栏会影响到内容的高度,因此当在设计 web 页面布局时将其考虑进去。

-
-

代码流程

-

当在 Firefox OS 中打开一个新的 web 页面时,调用流程如下

-
Gecko > WrapperFactory > Window Manager > AppWindow > BrowserFrame
-

Wrappers inheriting from system/js/wrapper_factory will receive the mozbrowseropenwindow event for a bookmarked web page.

-

In the handleEvent section, the handler will check the event to decide whether the web page should be opened as an app or in browser chrome.

-

Finally, launchWrapper is called to launch the corresponding window.

-

全局搜索 & 导航

-

With the new search and navigation bar, users can get to their favorites, type in a URL, or discover a new app, from anywhere in Firefox OS. The search bar lives at the top of the screen, and users can just tap or swipe to open it.

-

Think of it as a combination of the Awesome Bar from the browser and the adaptive app search from the homescreen. Because Firefox OS uses web apps, when you find what you want, even if it’s a new app, it opens right away. You don’t need to install anything, because everything is instant and web—like.

-

Browser App

-

The Browser app is a certified webapp that provides a general web browser experience. The main function is located in apps/browser/js/browser.js:

-
var Browser = {
-  init: function browser_init() {
-    this.getAllElements();
-      ...
-    BrowserDB.init((function() {
-      ...
-    }
-  }
-};
-
-window.addEventListener('load', function browserOnLoad(evt) {
-  window.removeEventListener('load', browserOnLoad);
-  Browser.init();
-});
-

The Browser will call its init() function while the DOM is loaded.

-
getAllElements: function browser_getAllElements() {
-  var elementIDs = [
-    'toolbar—start', ... 'danger—dialog'];
-
-  // Loop and add element with camel style name to Modal Dialog attribute.
-  elementIDs.forEach(function createElementRef(name) {
-    this[this.toCamelCase(name)] = document.getElementById(name);
-  }, this);
-},
-

The getAllElements function is used to get all camelCase element handlers, after which the apps/browser/js/browser_db.js  is called, to prepare for adding the default search engine and bookmarks.

-

书签

-

From Firefox OS 2.0 apps/bookmark is used to handle bookmark save/remove activities.

-

The most interesting parts apps/bookmark/webapp.manifest looks like so:

-
"activities": {
-  "save—bookmark": {
-    "filters": {
-      "type": "url",
-      "url": { "required":true, "pattern":"https?:.{1,16384}" }
-    },
-    "disposition": "inline",
-    "href": "/save.html",
-    "returnValue": true
-  },
-  "remove—bookmark": {
-    "filters": {
-      "type": "url",
-      "url": { "required":true, "pattern":"https?:.{1,16384}" }
-    },
-    "disposition": "inline",
-    "href": "/remove.html",
-    "returnValue": true
-  }
-},
-

As seen above, the activity is handled by save.html and remove.html. Both operations are delegated to apps/bookmark/js/activity_handler.js:

-
var ActivityHandler = {
-  'save—bookmark': function ah_save(activity) {
-  },
-
-  'remove—bookmark': function ah_remove(activity) {
-  }
-};
-
-navigator.mozSetMessageHandler('activity', function onActivity(activity) {
-  var name = activity.source.name;
-  switch (name) {
-    case 'save—bookmark':
-    case 'remove—bookmark':
-      if (activity.source.data.type === 'url') {
-        ActivityHandler[name](activity);
-      }
-    ...
-  }
-}
-

When the message handler listener navigator.mozSetMessageHandler('activity') receives the save-bookmark or remove-bookmark activities, the ActivityHandler function is triggered to handle correspondent operations.

diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/index.html deleted file mode 100644 index c8a36a6477..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/index.html +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Gaia应用 -slug: Archive/B2G_OS/Platform/Gaia/Gaia_apps -tags: - - Apps - - B2G - - Firefox OS - - Gaia - - 架构 -translation_of: Archive/B2G_OS/Platform/Gaia/Gaia_apps ---- -
-

Gaia是Firefox OS 的前端, 它包括系统管理的功能以及附带在Firefox OS上的一些内置应用。所有的Gaia源代码(包括system和键盘IMEs)都完全由HTML5 ( HTML + CSS + JavaScript )  & 开放Web API实现的。 本文介绍了在Gaia家族工作的每一个可获得的应用的信息。

-
-

Gaia 功能性分类

-

Gaia中的应用大致可分成下面几类。

-
-

注意: 许多关于解释单个应用如何工作的页面都是链接自 Gaia Github repo 中的README文件。这是因为许多app都处在快速开发周期内,会迅速的变化(通常是每天),因此如果使MDN页面根据这些变化快速的更新是没有什么意义的。工程师维护的README页面则是当前信息最准确的来源。

-
-

平台

-

包括系统(System),设置(Settings),锁屏(Lockscreen),编译脚本(build scripts) 以及蓝牙(Bluetooth) 应用。

-

-

平台应用:进一步讲解

-
-
- System
-
- System app是在Firefox OS启动过程中由Gecko装载的第一个web应用。它会担负许多责任,一般都是系统运行所需要的,因此不会局限于对某一个web应用。
-
- Browser
-
- Browser app(当前是System 的一部分)会提供一些浏览器类似的功能—包括页面导航,搜索和书签等。
-
- Window Management
-
- Firefox OS的窗口管理功能 — 包括应用的生命周期和交互、通知、动画以及其他 — 是由System app的特定部分所处理的。本文会着眼于Firefox OS 窗口管理的细节问题。
-
- Settings
-
- Firefox OS 用户可以通过 Settings 应用来配置设备的设置信息,响应传入的活动(带有config名称的Web activities),这种传入的活动可以使其他应用跳转到Settings应用的不同的界面来处理需要的配置(例如,当没有数据链接时,会显示wifi设置界面)。
-
-
-
-  
-
-

通信

-

包括 Dialer, Contact, SMS 以及 FTU应用.

-

-

通信应用:进一步讲解

-

TBD(有待讨论)

-

生产力应用

-

包括 Email, Calendar, 以及 Clock 应用。

-

-

生产力应用:进一步讲解

-
-
- Calendar
-
- Firefox OS内置的日历应用。
-
- Clock
-
- Firefox OS原生的始终应用,包括闹钟,定时器,跑表功能。
-
- Email
-
- Gaia e-mail 应用。
-
-

多媒体

-

包括相机(Camera),  图库(Gallery), 音乐播放器(Music), 视频播放器(Video)应用以及一些多媒体相关的功能比如DRM和壁纸(wallpapers)。

-

-

多媒体:进一步讲解

-
-
- Video
-
- Video 是视频播放应用,它能够播放在您Firefox OS 设备中存储的多媒体
-
- Camera
-
- 用户可以使用Camera来从设备摄像头中捕捉和管理视频和图片,而且还能够响应其他应用想要使用摄像头功能来获取多媒体时发出的pick类型的 Web activitie
-
-

其他的Gaia 功能

-

除了这些功能,还有其他一些主要的功能例如 browser, homescreen, marketplace, test framework, PDF viewer,以及 app manager,这些都是和Gaia一起紧密开发的。

-
-
- pdf.js
-
- pdf.js 是基于HTML5的PDF阅读器,用于在Gaia内阅读PDF文件。注意 pdf.js是在Gaia外一个独立的仓库维护的。
-
diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/settings/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/settings/index.html deleted file mode 100644 index 2d14f5798f..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/settings/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: 系统设置 (Settings) -slug: Archive/B2G_OS/Platform/Gaia/Gaia_apps/Settings -translation_of: Archive/B2G_OS/Platform/Gaia/Gaia_apps/Settings ---- -
-

Settings app 允许用户来配置设备的系统设置信息,同时会对传入的 activities作出响应,即允许app开发者在app中显示特定的settings 视图(例如, 如果没有有效的数据链接,显示 wifi设置面板)。本文主要讲述了它是如何工作的。

-
-

mozSettings API 和 Data 绑定

-

从技术上讲, Settings app 是一个向用户提供对认证 window.navigator.mozSettings API 访问的UI界面。

-

 Settings app 会自动的处理基本的系统设置操作,如绑定数据字段和  mozSettings 值 — 所有基本操作,如勾选一项设置或改变输入值将会使相关的 mozSettings 值也会改变。

-

window.navigator.mozSettings API 会从Gecko 中获取系统设置的数据。 使用方式如下所示:

-
navigator.mozSettings.createLock().set(values);
-

上面是设置数据信息。

-
-

注意: 在读或写任何 mozSettings, 我们需要使用 createLock() 方法来锁定settings。

-
-

要检索数据,我们可以使用获取或设置一个回调函数的方式启动对数据的操作:

-
var reqTimerGoBack =
-window.navigator.mozSettings.createLock().get('icc.goBackTimeout');
-reqTimerGoBack.onsuccess = function icc_getTimerGoBackSuccess() {
-  goBackTimer.timeout = reqTimerGoBack.result['icc.goBackTimeout'];
-    ...
-};
-

数据会存储在一个名为 instance.result 词典下。

-

Firefox OS 2.0 开始, mozSettings 实例可以通过 js/modules/settings_cache.js 实例被重复使用:

-
var SettingsCache = require('modules/settings_cache');
-
-SettingsCache.getSettings(function(result){
-  var onlineSupportTitle = result['support.onlinesupport.title'];
-    ...
-});
-

导航

-

当用户打开  Settings app, 在概览页面会显示多个面板,这个页面则是一个功能性的独立页面。SettingsService.navigate (js/module/settings_service.js) 则会控制这些页面间的导航。

-
-

注意: For legacy panels (which are not yet ported to the new structure), settings.currentPanel is used instead of SettingsService.navigate to navigate
- between panels.

-
-

Since Firefox OS will support tablet devices as well as mobiles, the Settings app has two different types of navigation model implemented:

- -

While called, SettingsService.navigate determines what navigation model to use via the following code:

-
if (_isTabletAndLandscape()) {
-  PageTransitions.twoColumn(oldPanel, newPanel, callback);
-} else {
-  PageTransitions.oneColumn(oldPanel, newPanel, callback);
-}
-

面板

-

From Firefox OS 2.0 onwards, the basic panel structure is defined in js/modules/panel.js. It defines six lifecycle stats:

- -

All new settings panels are inherited from SettingsPanel, which extends Panel’s functionalities. The code is contained in js/modules/settings_panel.js:

-
onInit: function(panel, initOptions) {
-  ...
-
-  PanelUtils.activate(panel);
-},
-
-onBeforeShow: function(panel, beforeShowOptions) {
-  // Preset the panel every time when it is presented.
-  PanelUtils.preset(panel);
-  _addListeners(panel);
-  ...
-},
-

PanelUtils.activate — defined in js/modules/panel_utils.js — is used to parse all links in the panel and adds corresponding handlers in onInit stat, and PanelUtils.preset is used to preset elements with the settings values in the onBeforeShow stat.

-

All new settings panels are defined in the js/panels folder.

-

AMD 模块和编译时间优化

-

From Firefox OS 2.0 onwards, the Settings app uses the AMD modules pattern to implement each panel. The AMD modules are loaded via Alemeda (a lighter version of RequireJS) and built/optimized using r.js (the RequireJS optimizer). The Settings app still had dependencies on files (shared/js) which aren’t AMD modules. For those it uses the shim options defined in settings/js/config/require.js.

-

参考

-

 Settings app has a build-in README ,这个文件可以用来获取 Settings (大部分内容是由  Arthur Chen and Fred Lin 完成的)。

diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/system/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/system/index.html deleted file mode 100644 index 853dd41fbb..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/system/index.html +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: System -slug: Archive/B2G_OS/Platform/Gaia/Gaia_apps/System -translation_of: Archive/B2G_OS/Platform/Gaia/Gaia_apps/System ---- -
-

System app 是在 Firefox OS 启动过程 中由Gecko装载的第一个 web 应用,  它会处理许多运行系统所需要的任务,因此不会局限于某一个单独的 web 应用。 这篇文档主要是讲解 Sytem如何工作。

-
-
-

任何一个可以用 JavaScript 编写的应用, 会最终使用 JavaScript 构建的。 -- Atwood's Law

-
-
-

注意: 您可以在 Gaia Github 仓库中获取到 source code for the System app

-
-

system app 是如何启动的

-

当 Gecko 试图启动System应用时, 它会解析System's manifest.webapp 文件,并根据 launch_path 参数(该参数在Gaia应用中一般是 /index.html) 装载 index.html 文件。 要管理整个的移动系统,Sytem app需要装载很多资源文件。  

-

整个启动过程是从  bootstrap.js 中的下面代码开始的: 

-
window.addEventListener('load', function startup() {
-// define safelyLaunchFTU
-function safelyLaunchFTU() {
-  ...
-}
-
-if (Applications.ready) {
-  safelyLaunchFTU();
-} else {
-  ...
-}
-
-window.addEventListener('ftudone', function doneWithFTU() {
-  window.removeEventListener('ftudone', doneWithFTU);
-
-  var lock = window.navigator.mozSettings.createLock();
-  lock.set({
-    'gaia.system.checkForUpdates': true
-  });
-}
-
-  ...
-
-// With all important event handlers in place, we can now notify
-// Gecko that we're ready for certain system services to send us
-// messages (e.g. the radio).
-var evt = new CustomEvent('mozContentEvent',
-{ bubbles: true, cancelable: false,
-  detail: { type: 'system-message-listener-ready' } });
-  window.dispatchEvent(evt);
-}
-

这段代码是这样工作的:

-
    -
  1. System 是运行在浏览器引擎中真正的web应用, 并需要所有它依赖的资源都装载进去 — 包括 图片(images)和样式(styles)。 因此一旦 window.onload 事件触发, 我们就要开始这些工作。
  2. -
  3. 首先,我们要使用 safelyLaunchFTU() 函数准备启动首次启动体验(FTU)  。顾名思义, 只有当用户首次启动 Firefox OS 时, FTU才会出现。
  4. -
  5. 当用户在 FTU中点击 “完成” 时, 会启动 ftudone 自定义事件,  bootstrap.js 会监听和处理这个事件。
  6. -
  7. 下一步, 我们会使用 Settings API (navigator.mozSettings)  将  gaia.system.checkForUpdates 设置成 true,  表示系统会检查更新。
  8. -
  9. 最后,我们会通过 CustomEvent 运行自定义的 window.dispatchEvent。这是Gaia 使用的一个非常重要的设计模式, 用于系统消息的处理以及与Gecko层的通信。上面方法是指 Gaia System app 通知 Gecko层, 它已经准备好监听和处理事件了。 
  10. -
-

实现模块化

-

为了实现更好的模块化和灵活性,system 应用本身也在不断的改进。 从1.4 版本开始, 专门发起了一个关于 refactor the system module as instantiable object 的倡议来讨论该问题。

-

在所有上述代码运行后,每个对 bootstrap.js  中的系统组件的引用都是是如下的形式:

-
window.telephonySettings = new TelephonySettings();
-window.telephonySettings.start();
-

 TelephonySettings() 的源代码框架如下:

-
(function(exports) {
-  'use strict';
-  function TelephonySettings() {
-    this.init_param = false;
-  }
-
-  TelephonySettings.prototype = {
-    // Initialzes all settings.
-    start: function() {
-      ...
-    },
-
-    // Clean all settings.
-    stop: function() {
-      ...
-    },
-
-    1st_method: function ts_1st_method() {
-      ...
-    },
-
-    2nd_method: function ts_2nd_method() {
-      ...
-    }
-  };
-
-  exports.TelephonySettings = TelephonySettings;
-
-}(window));
-

这种模式可以帮助每个系统组件实现模块化,并使它们的可测性更强。

-

开机和关机动画

-

本部分会讲解 System app是如何控制开机动画和关机动画的。 init_logo_handler.js 和 sleep_menu.js 文件会对 system 开机动画和关机动画进行处理。

-

开机动画

-

开机动画当前并没有包含在主引导程序中,而是要借助于检查 EventListeners。

-

在 init_logo_handler.js 文件中的开机启动代码如下所示:

-

一旦Gecko准备将一些东西画在屏幕上时, 会选择 logo或者是动画。当DOM装载完成时, 我们会运行合适的系统处理程序来完成log或动画。当 ftudone 或者 ftuskip 运行时会将logo隐藏。 包含在  init_logo_handler.js 中的 _appendCarrierPowerOn 方法表示了如何通过监听DOMContentLoaded事件来启动动画或启动logo。logoLoader 方法则在 logo_loader.js 中定义。

-
var self = this;
-document.addEventListener('DOMContentLoaded', function() {
-  self.carrierLogo.appendChild(self.logoLoader.element);
-  self._setReady();
-});
-

一旦准备好 logo, 系统会调用 _setReady() 方法,  在方法中会建立一个监听器来监听特殊的 mozChromeEvent事件,这个事件会带有 system-first-paint 类型,表示系统系统已经准备好向屏幕绘图。

-
var elem = this.logoLoader.element;
-  ...
-window.addEventListener('mozChromeEvent', function startVideo(e) {
-  if (e.detail.type == 'system-first-paint') {
-    window.removeEventListener('mozChromeEvent', startVideo);
-    if (elem &amp;&amp; elem.ended === false) {
-      elem.play();
-    }
-  }
-});
-

此时图形元素开始运行。一旦启动 ftuopen 或 ftuskip 事件,  init_logo_handler.js 会调用默认的 handleEvent() 方法反过来触发 animate() 方法来以淡出的效果隐藏动画。

-
init: function ilh_init(logoLoader) {
-  window.addEventListener('ftuopen', this);
-  window.addEventListener('ftuskip', this);
-    ...
-},
-
-handleEvent: function ilh_handleEvent() {
-  this.animate();
-},
-

关机动画

-

当系统准备就绪时,长按电源(power)按键,会触发定义在 hardware_button.js 文件中的 holdsleep 事件。 hardware_button.js 文件会处理所有“物理按键点击“的事件,包括电源(休眠)键,home键,音量增/减键等。

-
HardwareButtonsSleepState.prototype.enter = function() {
-  this.timer = setTimeout(function() {
-    / * When the user holds Sleep button more than HOLD_INTERVAL. */
-    this.hardwareButtons.publish('holdsleep');
-    this.hardwareButtons.setState('base');
-  }.bind(this), this.hardwareButtons.HOLD_INTERVAL);
-};
-

关机动画是由 sleep_menu.js 处理的;这个脚本文件会监听 holdsleep 事件,并且当它触发时会显示菜单对话框。

-
init: function sm_init() {
-    ...
-  window.addEventListener('holdsleep', this.show.bind(this));
-    ...
-}
-

如果用户通过重启和关机菜单选项选择关机,会触发 startPowerOff() 方法, 它反过来会触发 LogoLoader() 函数来对关机动画进行处理。

-
handleEvent: function sm_handleEvent(evt) {
-  switch (evt.type) {
-    case 'click':
-      ...
-    this.handler(action);
-    break;
-    ...
-  }
-}
-
-handler: function sm_handler(action) {
-  switch (action) {
-    ...
-    case 'restart':
-      this.startPowerOff(true);
-      break;
-
-    case 'power':
-      this.startPowerOff(false);
-      break;
-    ...
-  }
-}
-

System 的功能

-

 System app 会负责许多功能和任务, 你可能还会对能在其职权范围内找到而惊讶。系统应用负责的范围包括:状态栏( statusbar)和 实用工具盘管理(utility tray management), SIM卡锁(SIM lock), 更新管理(update manager), 主屏幕启动(homescreen launcher),webapp 窗口管理(webapp window) 等。 本节会对System 提供的一些最重要的功能进行探究。

-

状态栏(Statusbar)和实用工具盘(utility tray)

-

系统状态栏和下拉菜单 (Gaia 通常称之为 utility tray; Android 称之为 notification bar) 是由 statusbar.js 和 utility_tray.js 来处理的。 在应用的 index.html 中,状态栏条目是在 <div id="statusbar" data-z-index-level="statusbar">  中定义的,而实用工具盘条目在下面的结构中定义:

-
<div id="utility-tray" data-z-index-level="utility-tray">
-  <div id="notifications-container">
-    ...
-  </div>
-</div>
-

实用工具盘(utility tray)中会有一些特殊的面板,如更新管理器,紧急回调管理器,存储监视通知,媒体播放通知和控制,蓝牙传输状态,按键输入法(IME)切换。与之相关联的处理程序和样式放置在  js/ 和style/ 文件夹中。

-

特殊的应用launcher

-

System app 有三个特殊的launchers,  在需要时会调用单独的web应用程序。

- -

锁屏

-

Lockscreen app 的主要入口文件是 system/js/lockscreen.js。用户可以在这个界面解锁,启动相机以及音乐播放器。

-

紧急拨号器

-

紧急拨号器的代码是在 gaia/apps/system/emergency-call/ 文件夹下的。 它是拨号应用的简化版本,允许用户可以访问 SIM PIN unlock dialog 实现紧急拨号服务。

-

全系统(System-wide)UI

-

System应用会处理绝大多数的全系统(system-wide) UI, 其中大部分包括的是一些对话框,如音量警告对话框,SIM PIN解锁对话框,小区广播(cell broadcast)对话框,还包括一些影响窗口行为的UI元素,如 software home按键。

-

z-index level

-

在System 应用的 index.html 文件中,许多组件都带有 data-z-index-level 属性,例如

-
<div id="sleep-menu" data-z-index-level="sleep-menu">
-  ...
-</div>
-

对应 z-index-levels 定义在 system/style/zindex.css 文件中,如

-
#screen > [data-z-index-level="sleep-menu"] {
-  z-index: 65536;
-}
-
-...
-
-#screen > [data-z-index-level="app"] > .appWindow {
-  z-index: 3;
-}
-

z-index 设置是根据元素在屏幕上显示的顺序进行排列的 — 如果元素需要在视觉层次中比较高的元素数值也会较高。这就是System app在基本水平上窗口管理的方式。 

-

software home 按键

-

 software home 按键是 home按键的一种替代,会在缺少物理 home按键的情况下自动启动。例如在 Nexus 4 中。 要控制它的外观,Gecko提供了一个专有的媒体功能称为  -moz-physical-home-button, 它能够在媒体查询时使用基于硬件Home按键的外观。 如果需要,窗口管理会为 software home按键分配一些屏幕的空间。

-

在 system/style/window.css (以及许多其他的系统样式文件中), 可以看到

-
@media not all and (-moz-physical-home-button) {
-  #screen:not(.software-button-disabled) > #windows > .appWindow {
-    bottom: 5rem;
-  }
- }
-

Home 手势 (从屏幕底部向上滑动)

-

home 手势是另外一个硬件home按键的替代;它可以在 开发者设置  中使能,而控制代码在 system/js/home_gesture.js 文件中。例如,这个手势涉及到从屏幕底部清扫,可以用来关闭应用。

-

这个手势能够在 Firefox OS 平板设备中自动使能。 而 gaia/shared/js/screen_layout.js 是专门用于检测设备是否是平板的。

-

音量警告对话框

-

在 system/js/sound_manager.js. 中包含控制音量警告对话框的代码。如果下面所有条件都满足,则会弹出音量警告对话框:

- -

SIM PIN 解锁对话框

-

控制SIM PIN 解锁对话框的代码在 system/js/simcard_dialog.js 中 — 当Passcode lock选项使能时,对话框会在锁屏界面显示。开放的应用必须要在  manifest.webapp 中包含 telephony 权限中(System app中含有该权限)。

-
-

注意:  当手机在飞行模式时,不会显示SIM PIN 解锁对话框

-
-

 

diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/window_management/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/window_management/index.html deleted file mode 100644 index c0871e3130..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/gaia_apps/window_management/index.html +++ /dev/null @@ -1,279 +0,0 @@ ---- -title: 窗口管理(Window Management) -slug: Archive/B2G_OS/Platform/Gaia/Gaia_apps/Window_Management -translation_of: Archive/B2G_OS/Platform/Gaia/Gaia_apps/Window_Management ---- -
-

一般来说,window manager 是应用的一部分,会在图形用户界面中控制窗口的放置和外观。本文会对Firefox OS是如何进行窗口管理的内容进行探究。

-
-

Firefox OS中, Window Management是System app的一部分,主要负责:

- -

在深入理解上述条目的细节前,让我们来看下应用是如何在Gaia内部启动的。 

-

App在Gaia中的启动

-

app在 Firefox OS 中的启动有几种方式,例如,通过其他app的系统消息,或者在HomeScreen中点击app图标等。 

-

-

控制app开启的事件是由 Gecko引擎和 System App 处理的,下面会有详细阐述。

-

App 结构

-

所有的 Gaia webapps 都是 packaged apps,它们都是基本的zip文件,其中会包含所有的应用程序文件: HTML, CSS, JavaScript, images, manifest, 等等。每个在 Gaia 中的 web 应用都会以下面 的基本结构进行组织:  

-
-
-
apps/[app name]/
- - js
- - styles
- - locales
- - test
- - index.html
- - manifest.webapp
-
-
-
-

-

当一个内嵌的Gaia app 从 homescreen 启动时,Gecko 会试图打开 URL 地址 manifest://[app name].gaiamobile.org:8080, 解析对应的 manifest.webapp 文件,之后运行文件中  launch_path 指定的文件 — 在所有内嵌  webapp中都是  index.html 。index.html 文件会加载所有需要的样式和 JavaScript。

-
-

注意 : 此处有一个非正式的约定,Gaia app的主要 js 入口点一般是  [app name].jsmain.js.

-
-

App启动次序

-

启动事件会发给Gecko。一旦 Gecko 准备就绪,  system/js/app_window_factory.js 文件中的 AppwindowFactory 就会收到一个 app的 webapps-launch 事件或一个用于处理挂起消息的 open-app 事件。

-
window.addEventListener('applicationready', function appReady(e) {
-  window.removeEventListener('applicationready', appReady);
-  window.addEventListener('webapps-launch', self);
-  window.addEventListener('webapps-close', self);
-  window.addEventListener('open-app', self);
-});
-

关于 handleEvent 动作的细节, this.launch(config) 会启动一个 app window 或 activity。一旦app关闭,  Appwindow 会收到 webapps-close 事件。

-

主进程中的  launch() 方法如下:

-
var app = AppWindowManager.getApp(config.origin);
-if (app) {
-  app.reviveBrowser();
-} else if (config.origin !== homescreenLauncher.origin) {
-  new AppWindow(config);
-} else if (config.origin == homescreenLauncher.origin) {
-  homescreenLauncher.getHomescreen().ensure();
-}
-

首先,会检查 app 变量是否存在并试图到Gecko 中恢复app的运行。否则,如果是常规的app,我们会创建一个关于 app 的  AppWindow 实例。另一个特殊的情况是 homescreenLauncher — 此时我们会执行一些必要的操作。

-

AppWindow

-

Firefox OS 会使用专门的  mozBrowser API 使 web 页面看起来像一个 app。 窗口管理的核心只是使用 mozBrowser API 封装来处理 内部的 iFrames (窗口)。之所以创建这个特殊的 moz-browser 类型,主要是为了使iFrame 看起来更像一个真实的浏览器窗口。

-

AppWindow 可以创建,容纳以及管理 mozBrowser iFrame。AppWindow 可以操控所有由 mozBrowser iFrame 本身触发的 mozBrowser 事件并且还可以显示相关的UI特性。

-

App 生命周期管理

-

app整个的生命周期如下:

- -

启动 app

-

当用户点击 homescreen 上的应用图标时,homescreen 会使用  mozApps API 来通知 Gecko 引擎打开对应的app。当Gecko 准备就绪时,它会发送一个适当的事件给 system app。

-

Killing apps

-

在下面情况下,App 将会被 kill 掉:

- -

对于活动的应用程序而言,在关闭动画后,被 kill app 的 iFrame 就会从 DOM tree中移除。 对于不活动的应用程序,在它们被kill 后, 对应的 iframe 就会立刻移除。

-

在下面情况下,Apps 会被中断:

- -

重启 app

-

在下面情况下, Apps 会被重启:

- -

app是如何被渲染的

-

在启动一个app时,屏幕会分为下面几部分:

- -

-

App 布局

-

应用 iframe 的主要容器如下:

-
<iframe id="browser2" mozallowfullscreen="true" mozbrowser="true" remote="true"...
-... src="", data-url="" data-frame-type="window" data-frame-origin="...">
-</iframe>
-

iframe 中包括:

- -

调整 AppWindow大小

-

AppWindow 会在下面几种情况下被调整:

- -

-

总之,屏幕的大小会受到下面要素的影响:

- -

-

AppWindow 方向

-

app 的方向可以由每个单独的app或由系统全局控制。您可以在  manifest.webapp 中使用 orientation 属性来设置方向。例如

-
"orientation": "default",
-

您也可以使用orientation API 来锁定和解锁方向:

-
screen.mozLockOrientation([‘portrait-primary’]);
-
-screen.mozUnlockOrientation();
-

可以用下面的属性值来强制对方向进行设定:

- -

要获取更多的细节,请参考 Screen.lockOrientation , 您也可以在 gaia/test_apps/uitest/js/API/orientation.js. 查看设定的实例。

-

-

App 可见性

-

只有当关掉屏幕时, System app 才会到后台;而正常的 app 到后台要依赖下面几个因素:

- -
-

注意: 当父 iframe 页面非活动时,页面可见性会被继承。

-
-

在下面情况下,APP通常会在前台运行:

- -

下面情况下,App 通常会在后台运行:

- -

对上面的规则而言,有一些意外的情况:

- -
-

注意: 此处的 Active app 是指当前正在前台运行的应用;而 inactive app是指挡在后台运行的应用(界面不可见)。

-
-

AppWindow 动画和过渡

-

为了让用户获得更顺畅的使用体验,Gaia 的窗口管理器(Window Manager)也会提供 app window 动画和过渡效果。

-

 AppWindow 动画和过渡效果是由下面的状态来管理的:

- -

在调用 setDisplayedApp() 方法时,  app 会通过下图中列出的状态来启动。

-

-

在控制 Firefox OS app动画流程时,有下面几个技巧:

- -

-

AppWindow 特定UI

-

有一些特定的 UI 元素只和特定的 app 相关,如  Browser chrome, modal dialogs, context menus, popups, 以及 error pages.

-

下面让我们来讨论下。

-

弹出框(Modal dialogs)

-

在 desktop Firefox  中,,如果您启动了浏览器开发面板, 在其中输入如  alert(), confirm()或 prompt() 等命令,就会在屏幕中心弹出一个对话框,并遮盖了下面的内容。Firefox OS 中的 modle dialogs 和这个效果是相同的。
-
-

-

快捷菜单(Context menu)对话框

-

移动开发者都会非常熟悉 快捷菜单(或长按菜单)。一般在设计app时,为了使用户能够更简便的使用 app,最常用的用户动作应该是对用户可见的。我们可以将一些无法直接放置在UI上,但又经常使用的动作放在快捷菜单中。
-
-

-

授权(Authentication) (https) 对话框

-

定义在 system/js/app_authentication_dialog.js 文件中。

-

值选择,时间,日期对话框

-

定义在 system/js/value_selector/.

-

权限对话框

-

定义在 system/js/permission_manager.jssystem/js/media_recording.js  文件。

-

特定应用

-

有些应用需要一个特殊的 appWindow 对象来处理它们包含的特定功能。其中包括:

- -

子窗口管理

-

子窗口是由 其他 app/pages 直接或间接打开的。如:

- -

当子窗口被正常终止时,它的父窗口应该被重新打开。有些自窗口可会也会包含其他的子窗口。父窗口与子窗口间进程优先级的管理也是一个问题。

-

视窗(Attention Window)

-

Attention Windows 用来获取用户的注意力:

- -

当前这些 attention window 都是被强制使用的默认方向(竖向优先)。

-

委托(Trusted) UI

-

Persona 和 mozPay API 使用的时委托 UI。它们使用特定的尺寸sizing: 80% 显示。在  trusted UI 运行时Homescreen是部分显示的。
-
-

-

历史记录管理 (History Management)

-

本节我们会讲解一些可以在 Firefox 中管理历史记录的组件。

-

任务管理器

-

任务管理器 Task manager (card 视图) 可通过长按 home 按钮触发。它会显示设备上的app历史,此时可以动态的kill一个app。

-

Web activity 处理

-

内嵌 Activities 会创建一个新的引用页面为 activity 提供数据。
-
- Window Activities 会重复使用已存在的app window 来反映 acitivity 数据。

-

边缘手势 (测试中)

-

这个测试的边缘手势动能在 Firefox 2.0+ 开发模式版本才存在,它会允许您使用手动滑动 设备的 右/左边缘来在app和web页面之间切换。

-

How is the next app to display chosen?

- -

How is the previous app chosen?

- -

截屏管理

-

截屏工具会被 任务管理器(卡片视图)所使用,来显示历史记录中的app。当app 关闭动画结束时, 就会获取到一个app的屏幕截图。

-

参考

-

From Browser to Browser

diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/hacking/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/hacking/index.html deleted file mode 100644 index 6c3633a7a5..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/hacking/index.html +++ /dev/null @@ -1,542 +0,0 @@ ---- -title: Hacking Gaia -slug: Archive/B2G_OS/Platform/Gaia/Hacking -translation_of: Firefox_OS/Developing_Gaia ---- -
-

该页面是为Gaia开发者写的。如果您在寻找关于如何编译和运行Firefox OS 的信息,可以参考 Building and installing Firefox OS page .

-
- -
-

Gaia 是web apps 的集合,并且由它组合成  Firefox OS的前端. 在Firefox OS 屏幕上看到的都是由Web技术构建的。其中包括主屏幕和所有的原生app。本文则提供了修改Gaia代码的详细说明。

-
- -

获取源码

- -

要获取Gaia的源码, fork us on GitHub 并且使用 git 将您fork的代码clone到本地。

- -
$ git clone https://github.com/mozilla-b2g/gaia.git
- -

运行Gaia

- -

有三种方式可以运行Gaia,分别是在桌面,火狐浏览器或者兼容的移动设备。

- -

B2G 桌面

- -

B2G 桌面是在Firefox OS设备上运行应用程序的桌面版本,您可以使用它在电脑桌面上运行Gaia。

- -

您可以从Firefox Nightly站点上下载B2G桌面的nightly版本。其中有关于Linux (32位 and 64 位), Mac OS X 以及 Windows的版本.

- -

Nightly 版本都会对近期的gaia版本打包。一旦您下载完成压缩包,只需要解压到文件夹中,并从解压到的文件夹中运行b2g二进制文件就可以了。 

- -
$ cd b2g
-$ ./b2g
- -

如果您出于开发的目的来运行带有指定版本Gaia的B2G, 则需要从您clone的代码位置构建一个配置文件:

- -
$ cd /path/to/gaia
-$ DEBUG=1 DESKTOP=0 make
- -

上面的命令会在gaia 生成一个名称为profile的文件夹。 DEBUG选项会将 Gaia 作为托管的应用在内置的Web服务器上运行,而不是在每次更改后都需要重新打包的原生应用。在运行上面的命令后,您可以在最后的输出行中找到配置文件夹的路径,大体是 

- -
Profile Ready: please run [b2g|firefox] -profile /path/to/gaia/profile
- -

之后则可以指定配置文件来运行B2G。

- -
$ ./b2g /path/to/gaia/profile
- -

您用可以从源码中编译出自身的B2G桌面。

- -
-

注意 : 在 Mac OS X,  b2g 二进制文件会存在于 B2G.app.您需要运行下面命令:

- -

./B2G.app/Contents/MacOS/b2g /path/to/gaia/profile

-
- -

在Firefox中运行Gaia

- -

也可以在Firefox内部运行Gaia。这种方式会让您的开发周期大大缩短,同时也可以使用标准的web开发工具和调试器。 可以参考Gaia开发快速指南 获取更多的信息.

- -

在设备上运行Gaia

- -

如果您有一个兼容的移动设备,也可以使用Firefox OS 烧机来运行Gaia。您可以参考编译和安装Firefox OS 获取更多信息. 我们也有关于如何测试Firefox OS的文章。

- -

单元测试

- -

参考Gaia单元测试  来获取如何创建和在Gaia层运行单元测试的文章。

- -

提交bug

- -

在Bugzilla的 Firefox OS > Gaia 中提交bug。在Gaia组件  (或者是子组件)中提交bug.

- -

为 Gaia做贡献

- -

Mozilla依赖开源社区的贡献,以帮助开发Gaia应用,我们也希望您能参与进来。

- -

我们可以从一些非常好的网址来发现一些bug:

- - - -

编码风格基本知识

- - - -

Additional rules

- -

Bad:

- -
if (expression) doSomething();
-
- -

Correct:

- -
if (expression) {
-  doSomething();
-}
-
- -

If you're working on the system app, check out the guidance listed here.

- -

Before submitting a patch we recommend you run gjslint on it to check for any style errors:

- -
gjslint --nojsdoc my_file.js
- -

提交一个 patch

- -

First file or assign a bug to yourself on Bugzilla, you'll need a Bugzilla account.

- -

Then create a branch on your fork of Gaia:

- -
$ git branch branchname
-$ git checkout branchname
- -

Commit your changes:

- -
$ git add /file/to/add
-$ git commit -m "Bug XXXXX - Fix the broken Gaia and save the world"
- -

Push your branch:

- -
$ git push origin branchname
- -

Send a pull request by navigating to the branch in your fork on GitHub and finding the pull request button.

- -
-

Note: Except under unusual circumstances, patches should be landing first on the master branch, not a release branch like v1-train, v1.3, etc. If they need to land on a release branch, they must go through the usual approval process as outlined on the B2G Landing wiki page.

-
- -

To request a review of your patch, attach the pull request to the bug in Bugzilla by referencing the URL of the pull request, and set the review ("r") flag to "?" and enter the bugzilla ID of one of the module owners and peers (very important - otherwise your bug will not likely be seen by anyone). The Github tweaks for bugzilla extension on AMO can help automate this process by automatically creating the attachment and adding it to the bug; you will still need to set the review flag on Bugzilla.

- -

The reviewer may ask you to make some changes; you may need to amend the original commit and force push it to the original branch/pull request. Once they're happy with your patch, they will merge it into the master branch for you. Before they do this they would prefer it if you could squash all your changes into a single commit, so your contribution can be tracked easily.

- -

The person who merges the commit (usually the reviewer) would add a r= flag in the comment of the merge commit.

- -

Make 选项

- -

you use the make command inside the Gaia repo to create a Gaia profile that can be loaded onto your device or run in a B2G Desktop build. This section looks in detail at the different make options available.

- -

There are many environment variables present in the Makefile. Do not depend on them as they may be removed in the future.

- -

Created profiles are stored in /gaia/profile, and contain the following items:

- - - -
-

Note: When you've already made a profile and you want to build a new one, you must delete the existing profile directory before trying to generate a new one.

-
- -

Default

- -
make
- -

This simply gives you an unbranded, non-debug build. For a branded build build you need to use Official Mozilla branding make; for a debug build you need Debug make.

- -

推送到设备端

- -
make install-gaia
-
-make reset-gaia
-
- -

With ADB (Android Debug Bridge) setup, these make targets will push Gaia to the device. install-gaia will just push updates of Gaia from your working directory to your device. reset-gaia will purge all existing configuration, profiles, web apps and database entries (a new settings database will be initialized) before pushing Gaia.

- -

编译特定的应用

- -
APP=system make
-
-APP=system make install-gaia
- -

When a profile already exists, APP allows you to specify which app to re-package, instead of re-packing and re-pushing all the Gaia apps.

- -

指定自定义的配置文件夹

- -

You can specify a custom directory to build your profile in, using PROFILE_FOLDER, for example:

- -
PROFILE_FOLDER=profile-b2g-desktop make
- -

不同设备的编译

- -

There are a few make options that create builds for different devices, with different purposes.

- -

Create a phone build of Gaia

- -
GAIA_DEVICE_TYPE=phone make
- -

This build gets apps from /gaia/build/config/phone/apps-engineering.list.

- -

Create a tablet build of Gaia

- -
GAIA_DEVICE_TYPE=tablet make
- -

This build gets apps from /gaia/build/config/phone/apps-engineering.list.

- -

不同类型的编译

- -

There are a few make options that create different types of build, with different purposes.

- -

Production make

- -
PRODUCTION=1 make
- -

This creates a production build of Gaia:

- - - -
-

Note: You can also use the alias make production.

-
- -

Debug make

- -
DEBUG=1 make
- -

The DEBUG variable runs Gaia as hosted apps on a built-in web server on a specific GAIA_PORT, rather than the default of packaged apps which have to be re-packaged after every change; this makes things easier to test. Launching the profile with the latest Firefox Nightly will also give you nice B2G specific panels on the Firefox Developer Tools.

- -

In addition:

- - - -

Device debug make

- -
DEVICE_DEBUG=1 make
- -

This disables screen lock on the device, and enables debugging with the ADB tool, so is useful for device debugging.

- -

In Firefox OS version > 1.2, specify this param when you want to debug Firefox OS webapps with the App Manager.

- -

Debug desktop make

- -
DEBUG=1 DESKTOP=0 make
- -

This option creates a desktop debug version, for running inside B2G desktop.

- -

Official Mozilla branding make

- -
MOZILLA_OFFICIAL=1 make
- -

Use this to make an official Mozilla-branded build.

- -

Dogfood make

- -
DOGFOOD=1 make
- -

Dogfooding options and utilities are turned on, for example the Feedback app, which allows doog fooders to easily submit feedback on the OS.

- -

System apps make

- -
B2G_SYSTEM_APPS=1 make
- -

This environment variable lets you push an app to /system/b2g instead of /data/local. You should use this when you work with a user build. This variable is automatically set when running make production. This can be used for install-gaia or reset-gaia too.

- -

Distribution and market customization build

- -
GAIA_DISTRIBUTION_DIR=./dir
- -
-

Note: Read Market Customizations for more details.

-
- -

开发/调试选项

- -

There are also make options for adding/removing features or changing settings, for debugging purposes.

- -

Enable remote debugging

- -
REMOTE_DEBUGGER=1
- -

This enables remote debugging on the device, the same as using the option in the developer settings.

- -

JavaScript optimization make

- -
GAIA_OPTIMIZE=1 make
- -

This triggers an optimization pass on Gaia's JavaScript, concatenating/compressing the files. This is automatically set when running make production. This can be used for install-gaia or reset-gaia too.

- -

High resolution image assets

- -
GAIA_DEV_PIXELS_PER_PX=1.5 make
- -

When packaging the app, this option replaces images with their *@1.5x.(gif|jpg|png) equivalents if such images exist. You need to use the above option as part of a standard make command, for example:

- -
GAIA_DEV_PIXELS_PER_PX=1.5 make reset-gaia
-
-GAIA_DEV_PIXELS_PER_PX=1.5 make install-gaia
- -

Gaia is currently targetting the following screen resolutions:

- - - -

use GAIA_DEV_PIXELS_PER_PX to make sure the images looks sharp on qHD and WVGA devices. see A pixel is not a pixel for more information about device pixels per css pixels.

- -

Haida features

- -
HAIDA=1 make reset-gaia
- -

This build enables the Haida feature set, which is currently limited to rocketbar and edge gestures, but will likely include other features in the near future.

- -

Disable first time use experience (FTU)

- -
NOFTU=1
-
- -

Disable the FTU with this environment variable.

- -

Disable lockscreen

- -

You can disable the Firefox OS lockscreen using the NO_LOCK_SCREEN option, for example:

- -
NO_LOCK_SCREEN=1 make
- -

Reference Workloads

- -

Reference workloads allow developers/testers to quickly install a large amount of data in several applications, typically on a newly-flashed phone.

- -

The commands are (from the gaia directory):

- -
make reference-workload-light
- - - -
make reference-workload-medium
- - - -
make reference-workload-heavy
- - - -
make reference-workload-x-heavy
- - - -

These targets accept the APP environment variable, or an APPS environment variable that should contain the app names separated by a space, e.g.:

- -
APP=sms make reference-workload-light
-APPS="sms communications/contacts" make reference-workload-heavy
-
- -

The apps available are:

- -
APPS="gallery music video communications/contacts sms communications/dialer"
- -

In order to install music (songs) with reference workloads, the utility mid3v2 must be installed. This utility can be installed with:

- -
sudo apt-get install python-mutagen
- -

If you run Fedora or RHEL instead, use:

- -
sudo yum install python-mutagen
- -

Documentation make

- -

Gaia docs can be built, via jsdoc3. To generate these, you can use the following command:

- -
make docs
- -

Enabling IME layout and dictionaries

- -

To enable keyboard IME layout and dictionaries enabled, use following command structure:

- -
GAIA_KEYBOARD_LAYOUTS=en,zh-Hant-Zhuyin,el,de,fr,zh-Hans-Pinyin make
- -

自定义 build-time 应用

- -

The apps that run on Firefox OS are all contained within the Gaia source tree, in one of two locations:

- - - -
-

Note: If you are building B2G rather than Gaia, the paths will of course have B2G/ on the front, e.g. B2G/gaia/apps and B2G/gaia/external-apps.

-
- -

If you want to omit some of these apps from your build of Gaia/B2G, you can do this in a few different ways:

- -
    -
  1. -

    The "brute force" method is to simply delete the apps you don't want to be present at build time, before building.

    -
  2. -
  3. -

    The more refined method is to edit the gaia/build/config/apps-*.list files to include the paths to the apps you want to include at build time. For example, gaia/build/config/apps-production.list looks something like this:

    - -
    apps/*
    -external-apps/*
    -outoftree_apps/*
    - -

    But you could also include specific apps rather than just picking them all, for example:

    - -
    apps/clock
    - -

    The mechanism for choosing which apps-*.list file is used during the build to determine the available apps is contained inside gaia/Makefile:

    - -
    GAIA_APP_TARGET?=engineering
    -...
    -ifeq ($(MAKECMDGOALS), demo)
    -GAIA_DOMAIN=thisdomaindoesnotexist.org
    -GAIA_APP_TARGET=demo
    -else ifeq ($(MAKECMDGOALS), dogfood)
    -DOGFOOD=1
    -else ifeq ($(MAKECMDGOALS), production)
    -PRODUCTION=1
    -endif
    -...
    -ifeq ($(PRODUCTION), 1)
    -GAIA_OPTIMIZE=1
    -GAIA_APP_TARGET=production
    -endif
    -
    -ifeq ($(DOGFOOD), 1)
    -GAIA_APP_TARGET=dogfood
    -endif
    -...
    -ifndef GAIA_APP_CONFIG
    -GAIA_APP_CONFIG=build$(SEP)config$(SEP)apps-$(GAIA_APP_TARGET).list
    -endif
    - -

    Initially, the GAIA_APP_TARGET variable is set to engineering, so by default building gaia from source will use app-engineering.list (which includes all the tests, demos, etc.):

    - -
    make
    -
    - -

    To specify usage of a different apps list you specify different options when running the make command. To build with apps-production.list, for example, you'd use

    - -
    PRODUCTION=1 make
    - -
      -
    • If you specifically build with DEMO=1 specified, then it will use apps-demo.list.
    • -
    • If you specifically build with DOGFOOD=1 specified, then it will use apps-dogfood.list.
    • -
    • You can completely override the decision by using GAIA_APP_CONFIG and providing your own apps-*.list file.
    • -
    - -

    gaia/Android.mk contains these lines:

    - -
    ifneq ($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)
    -GAIA_MAKE_FLAGS += PRODUCTION=1
    -B2G_SYSTEM_APPS := 1
    -endif
    - -

    When you build, if VARIANT=user or VARIANT=userdebug are set (these wind up getting reflected in the TARGET_BUILD_VARIANT variable), PRODUCTION=1 is automatically set when building gaia.

    -
  4. -
  5. -

    The third, and most refined (but most complex) method is to use customizations. These allow you to specify build-time customization instructions in separate difrectories, without modifying the core Gaia repo. You can include your own customizations in distinct directories, or use the preexisting directories that come with the source.

    - -

    For example, the basic Firefox tablet customized app list is defined in apps.list under the distribution_tablet folder (gaia/distribution_tablet). These customizations can be applied at build time using options like this:

    - -
    GAIA_DISTRIBUTION_DIR=distribution_tablet make
    - -
    -

    Note: Customizations is its own separate topic entirely. To learn more about it, read Market Customizations.

    -
    - -
    -

    Note: If you want to include custom external apps as part of your Gaia build, you need to build them in a specific way, and then place them into the gaia/external-apps/ folder. Read Building Prebundled web apps to find out how.

    -
    -
  6. -
- -
-

Important: If you are a device vendor creating a custom B2G/Gaia build for distribution, you need to satisfy certain criteria before you are allowed to include the Firefox Marketplace app on your phones/tablets/etc. Contact Mozilla for more details.

-
- -

联系小组

- - diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/index.html deleted file mode 100644 index 698c63da42..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Gaia -slug: Archive/B2G_OS/Platform/Gaia -translation_of: Archive/B2G_OS/Platform/Gaia ---- -

Gaia是Firefox OS的用户界面层.在Firefox OS启动之后,显示在屏幕上的一切东西都是由Gaia绘制出来的,包括锁屏,主屏幕,拨号界面,以及其他的应用程序.Gaia完全是由HTML,CSS,和JavaScript编写的.它和底层的操作系统以及硬件进行交互是通过标准的Web API来完成的,这些API是由Gecko实现的.

-

正因为这样的设计,Gaia不仅能直接运行在Firefox OS设备上,还能运行在其他的操作系统以及其他的web浏览器中.

-

和Gaia一起安装在设备上的第三方应用程序也可以由Gaia来启动.

- - - - - - - -
-

Gaia的相关文档

-
-
- 介绍Gaia
-
- Gaia是Firefox OS设备上使用的用户界面应用程序,它仅仅是一个运行在Firefox OS软件栈上的Web应用程序.本指南会详细的介绍Gaia.
-
-
-
- Gaia应用
-
- 对Gaia中可获得的默认应用进行介绍,包括如何使用和修改它们。
-
- Gaia hacking 指南
-
- 关于hacking和修改Gaia接口的指南。
-
- Gaia系统构建入门
-
- 在Gaia build子文件夹下由脚本执行的绝大多数有意以的构建步骤。
-
- Gaia Hacking提示和常见问题 
-
- 关于hacking Gaia的一些有用的提示以及常见问题。
-
-

查看更多...

-
-

到社区寻求帮助

-

如果你的工作需要和Gaia打交道,或者正在开发一个Gaia应用程序,有相关的社区资源可以帮助你!

- -
    -
  • 在Mozilla的Gaia IRC频道上提出你的问题: #gaia
  • -
-

不要忘记"提问的艺术"...

-
- - -

资源

- -
-

 

diff --git a/files/zh-cn/archive/b2g_os/platform/gaia/introduction_to_gaia/index.html b/files/zh-cn/archive/b2g_os/platform/gaia/introduction_to_gaia/index.html deleted file mode 100644 index 562cb61765..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gaia/introduction_to_gaia/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Gaia简介 -slug: Archive/B2G_OS/Platform/Gaia/Introduction_to_Gaia -tags: - - Apps - - B2G - - Gaia - - Settings -translation_of: Archive/B2G_OS/Platform/Gaia/Introduction_to_Gaia ---- -
-
- Gaia 是Boot to Gecko (B2G) 的用户界面; 它是一个web应用的集合,可以本地运行在B2G设备,仿真器,桌面版本或firefox版本上。添加app或规Gaia更改时使用的web技术都是 JavaScriptHTML,和 CSS.
-

 Gaia 锁屏界面

-

锁屏界面会显示网络运营商,当前时间和日期,和一个滑动条可用来解锁手机或直接进入相机拍照。  如果用户有密码锁定设置,锁屏界面会显示一个密码输入窗口。

-

-

注意一些设备默认是使能密码锁定的;这种情况下,默认的解锁PIN码是  "0000"。该功能后续可能会有所改变。

-

默认的Gaia接口

-

Gaia的默认界面,如下图所示,与您在绝大多数智能手机上看到界面是非常相似的。

-

-

这张图片显然是一个预发布版本的操作系统,其中还带有占位符图标和一些测试应用。界面顶端的状态栏放置了一些状态标识,包括当前手机选择的网络运营商(或者没有SIM卡),SIM卡信号强度,WIFI信号强度,电池点亮以及当前时间。

-

界面中间区域显示了应用的图标,滑动屏幕可查看各界面的图标。您可以在Gaia apps 一文中获取更多关于 Gaia 默认 app集合的信息。 

-

屏幕的最下方是是一个快速启动栏,一般会放置一些您最常用到的应用。您也可已从快速启动栏拖动一个app图标到中间的区域。

-

参考

- diff --git "a/files/zh-cn/archive/b2g_os/platform/gaia/weinre\350\277\234\347\250\213\350\260\203\350\257\225\345\267\245\345\205\267/index.html" "b/files/zh-cn/archive/b2g_os/platform/gaia/weinre\350\277\234\347\250\213\350\260\203\350\257\225\345\267\245\345\205\267/index.html" deleted file mode 100644 index 213a8defb1..0000000000 --- "a/files/zh-cn/archive/b2g_os/platform/gaia/weinre\350\277\234\347\250\213\350\260\203\350\257\225\345\267\245\345\205\267/index.html" +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Weinre 远程调试工具 -slug: Archive/B2G_OS/Platform/Gaia/Weinre远程调试工具 -tags: - - weinre -translation_of: Tools/Remote_Debugging ---- -

Weinre 是Apache基础工程之一,是 WEb INspector REmote 的缩写。正如其名,它是和 Firebug 或浏览器调试工具类似,但是能够在远程运行调试web页面。所以如果你使用过火狐开发者工具或Chrome的调试工具,那么上手Weinre就会非常容易,非常自然。

- -

安装 Weinre

- -

因为 Weinre 运行在 Node.js 的基础上, your first port of call would be to 安装 Node.js. Node.js comes with NPM (Node Package Manager) bundled nowadays and this is what we are going to use to install Weinre. From a terminal run the following:

- -
npm -g install weinre
- -
-

NOTE: The -g flag is used to install Weinre as a global Node.js module for command line goodness but, on Linux and Mac, this means you most likely are going to need to run the above by prepending sudo to the above command.

-
- -

Once the installation process is complete, we are ready to use Weinre to debug.

- -

启动 Weinre 服务

- -

On the terminal enter the following line to start up the Weinre server:

- -
$ weinre --boundHost 127.0.0.1 --httpPort 9090
- -

The two parameters passed here are the host to bind to and the port the server should listen on. Once the server has started the terminal should display a line similar to the following:

- -
2013-01-28T10:42:40.498Z weinre: starting server at http://127.0.0.1:9090
- -

With that, fire up a browser (NOTE: The UI for Weinre is built specifically for Webkit based browsers so, while it might work to some degree in other browsers, I would suggest you use Chrome) and point it to http://127.0.0.1:9090. Once the landing page loads, click on the link to the debug client user interface. From this portion of the UI you can see connected clients, initially one which is the current instance of the web inspector, some general properties of our server, and your targets.

- -

设置 Weinre 目标页面

- -

In Weinre targets are the web pages or apps that you want to debug, and in order for the target to be able to connect, you need to add a one liner to the relevant file of your app. For example, if you wanted to use Weinre to debug the Calendar app in Gaia you would open gaia -> apps -> calendar -> index.html and right before the clong body tag, add the following:

- -
<script src="http://127.0.0.1:9090/target/target-script-min.js#anonymous"></script>
- -

Normally that would be all you need to do to set up your target, but for FirefoxOS there is one more step. Gaia uses a Content Security Policy and as part of that, scripts are said to only be allowed to load if from the same origin as the application. So, if we were to try and load the Calendar now, the script from above would be blocked as it is not being loaded from the specified origin.

- -

To overcome this, we need to temporarily disable CSP. To do this, open up gaia -> build -> preferences.js and add the following line, around line 24:

- -
prefs.push(["security.csp.enable", false]);
- -

使用 Weinre 和 B2G Desktop 进行调试

- -

The first step we need before launching the desktop is to build our Gaia profile:

- -
DEBUG=1 make
- -

Once the profile is built, launch B2G desktop:

- -
-
/Applications/B2G.app/Contents/MacOS/b2g-bin -profile /Users/username/mozilla/projects/gaia/profile
-
- -

Once B2G launches, unlock the screen and navigate to the Calendar app. Tap the app icon and keep an eye on the Weinre debug client UI. Once the app has launched you should see a target being added. Next we want to start inspecting our code, so click on the 'Elements' tab to open up the HTML and CSS inspector. You can go right ahead and edit either the HTML or the CSS as you normally would and see the changes reflected live. Note that even though the CSS looks grayed out and disabled, it is fully editable. You can also add completely new styles to the current element using the empty element.style block or amending existing rules. You will also notice you have access to the computed styles as well as metrics of the current element.

- -

使用控制台工作

- -

The next tab of interest to us is the Console tab. Here you can code away and run any JavaScript you want directly against the current app or execute code exposed by the app. In order to demonstrate the console, we will target the Call Log portion of the dialer and interact with the records stored there. First step then is to move your script src to the Dialer which is located at gaia -> apps – > communication -> dialer -> index.html.

- -

After it is added, build your profile, launch B2G, and then launch the Dialer. With the Dialer open, click on the call log icon, bottom left. Currently the call log is already populated with some dummy data, but let’s create our own. Click over to the Console tab in Weinre, type the following, and press enter.

- -
RecentsDBManager.deleteAll();
- -

To see that our code was executed and worked, we need to refresh the call log:

- -
Recents.refresh();
- -

As you can see, our call log is empty. Next step then is to add an entry back. To do this, we will create a dummy call entry Object and then pass this to the add function of the RecentsDBManager to store it:

- -
// Dummy entry
-var recentCall = {
-    type: 'incoming-refused',
-    number: '555-6677',
-    date: new Date()
-};
-RecentsDBManager.add(recentCall);
-Recents.refresh();
- -

And as you can see now, the entry we just created has been added to storage, IndexedDB to be exact, and is visible in the call log view. As you might very well have noticed, another of the great features that comes with the console is auto-complete which will further speed up development.

- -

在移动设备上调试

- -

The above has focused on using Weinre and B2G desktop, but the process to use Weinre to inspect and debug your code running on a device is exactly the same except for the IP address you will be using. When you want to debug on the device you first need to know the IP address of your host computer. Then you need to start up Weinre using this IP as the boundHost and also as the IP when including the script into your target documents.

- -
-

On Mac and Linux you can get this address using ifconfig and on Windows it is ipconfig.

-
- -

Once you have the new IP, just stop the current instance of Weinre and then do the following:

- -
weinre --boundHost 192.168.1.1 --httpPort 9090
- -

Then inside your target document add:

- -
<script src="http://192.168.1.1:9090/target/target-script-min.js#anonymous"></script>
- -

Make and push your Gaia profile to the device using:

- -
make install-gaia
- -

Launch your target app and you are in business!

diff --git a/files/zh-cn/archive/b2g_os/platform/gonk/index.html b/files/zh-cn/archive/b2g_os/platform/gonk/index.html deleted file mode 100644 index 63d02ef70a..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/gonk/index.html +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: Gonk -slug: Archive/B2G_OS/Platform/Gonk -translation_of: Archive/B2G_OS/Platform/Gonk ---- -
-

Gonk 是 Firefox OS 平台底层的操作系统, 包括基于  Android Open Source Project (AOSP) 的 Linux Kernel 和用户空间硬件抽象层 (HAL) 。本文旨在介绍Gonk的组成;要获取更多有关 Firefox OS 架构和 Gonk 如何在其中适配的知识,请参考 Firefox OS architecture 指南。

-
- -

Gonk overview

- -

Gonk 在 Firefox OS stack 中可看作是 kernel 层级的组件,在 Gecko 和 底层硬件中间充当接口的作用。Gonk 对底层的硬件进行控制,并且将硬件信息及操控接口暴露给 Gecko中的 Web APIs。Gonk 可以看作是一个 黑盒, 在屏幕后面做了所有复杂细节的工作用于在硬件层级上对 mobile device 进行控制。

- -

Gonk 只是一个简单的 Linux 发行版本,其中包括了 Android 的一些组件(如 GPS 和 Camera)以及由  Mozilla 扩展的常用的开源工程,如 libusb, bluez, 进而将所有的层级集成到 Firefox OS 架构中。这种设计方式对 OEM 将软件组件从其他 Android 实现上移植过来是非常方便的。

- -

Gonk 是一个设备接口层,可看作是 硬件和 Gecko 之间的适配器。 Gonk is a relatively simple Linux distribution that can be treated as a Gecko Port paired with Gecko porting layers — so Gonk is a porting target of Gecko, just like there's a port of Gecko to OS X, Windows, and Android.

- -
-

Note: Since different mobile devices may have different chipsets and other hardware specs, devices may contain different Gonk distributions.

-
- -

由于 Firefox OS 工程对 Gonk 的完整控制,我们可以向 Gecko 中暴露一些在其他操作系统中无法实现的接口。例如, Gecko 已经可以直接对 full telephone stack 直接进行发给男问,并在 Gonk 中显示出 frame buffer。

- -

Gonk 架构

- -

Each mobile phone model has a specialized combination of Gonk components based on the system libraries, device drivers, and firmware required to operate the device. These components are determined by the OEM in collaboration with chipset manufacturers and ODMs. The following figure shows an example Gonk implementation:

- -

- -

This example shows the following main components (which represent only a subset of the possible components in any given Gonk implementation):

- - - -

Gonk 也会启动,管理以及关闭 b2g process, b2g process 属于 Firefox OS 的 Gecko 层。The b2g process acts as a client to service-level daemons in Gonk that interact directly with the hardware and expose to Gecko the underlying hardware functionality of the phone. Gecko talks with these daemons via inter-process communication (IPC). These components collaboratively exchange commands and protocols to request and provide services.

- -
-

Note: For more information on Gonk architecture, see the Firefox OS architecture guide.

-
- -

Porting Gonk

- -

Because Firefox OS is based on the Android kernel, existing device drivers, firmware, service daemons, and other components can be ported to work with Firefox OS, usually with minimal effort. If a custom component (for example, a custom RIL or new daemon) is needed, or if a modification must be made to an ODM’s reference design, then additional integration and testing effort might be required.

- -

In b2g, clients communicate with service-level daemons via inter-process communication (IPC). The client initiates a socket connection to the service-level daemon, submits the request (using the server’s request protocol) over that connection, receives the response, and closes the connection. OEMs are responsible for designing and implementing this inter-process communication between clients and servers.

- -
-

Note: For more information about how the porting process works, see Porting Firefox OS.

-
- -

How Mozilla works on Gonk ports with OEMs and phone manufacturers

- -

Every Gonk implementation is the result of collaboration among Mozilla, OEMs, and associated manufacturers (ODMs, chipset manufacturers).

- -

Mozilla provides source repositories and support files for Gonk in its Firefox OS distributions. The source repositories include the base Linux kernel (with only slight changes) and hooks into Gecko.

- -

OEMs are responsible for building, compiling, testing, certifying, and distributing the Firefox OS system image for a given device model. For the Gonk portion of the system image, OEMs are responsible for the bulk of the effort in order to ensure the seamless integration between Web API calls and phone hardware functionality. The type and scope of effort required is highly dependent on the specific chipsets and other hardware components used on the phone.

- -

Device components

- -

OEMs collaborate with chipset manufacturers and ODMs to provide all of the device-specific components that are needed to run the mobile device. For example, a manufacturer of the Wi-Fi components would provide the chipset and affiliated software. Components might include:

- - - -

Integration between Gonk and Gecko

- -

OEMs must ensure that hardware capabilities in the mobile device are correctly and completely exposed to the Web APIs implemented in Gecko. This involves:

- - - -

Gonk 源代码

- -

The main B2G repo on Github contains officially supported Gonk ports for a variety of devices, so you can treat it as Gonk’s repository. The list of supported devices is available in B2G/config.sh.

- -

The b2g process (along with other things), defined in Gonk, can be found at mozilla-b2g/gonk-misc. Modifications to b2g source code are made here.

- -
-

Note: In the Gecko source there’s a b2g/ folder that contains the Gonk Port of Gecko: this consists of a Linux kernel, HAL, and other OEM-specific libraries.

-
- -

Gonk 层每天的工作主要集中在 porting system 到不同的板子上,并且确保 Gecko 在不同的设备上能够正常工作。

diff --git a/files/zh-cn/archive/b2g_os/platform/index.html b/files/zh-cn/archive/b2g_os/platform/index.html deleted file mode 100644 index 3f256549c6..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/index.html +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Firefox OS 平台 -slug: Archive/B2G_OS/Platform -tags: - - B2G - - Firefox OS - - NeedsTranslation - - TopicStub -translation_of: Archive/B2G_OS/Platform ---- -

FireFox OS 平台包括很多组件。为了构建能够在FF OS中运行的应用,你不需要理解系统内部架构,如果你将要在该平台构建应用程序或者只是简单的好奇,你可能对以下文档感兴趣。

- - - - - - - - -
-

关于Firefox OS 平台的文件

- -
-
介绍 Firefox OS
-
关于 OS 如何运作
-
搭建安装 Firefox OS
-
Firefox OS 安装指南。也是在Pc搭建Firefox OS虚拟机指南
-
Gaia
-
FireFox OS 顶层文档
-
Gonk
-
关于Gonk的文档, Gonk比Gaia在操作系统中更加底层, 由Linux内核和Gecko调用的硬件抽象层组成. 
-
Gecko
-
Gecko在Firefox OS为提供标准的开放web标准实现, 像被Firefox和Thunderbird等等许多其他的应用运用着. 
-
图表支持特性                                                                                                                                                               
-
用一张图表就可以把所有Firefox OS编译的类型哪些可用的展现出来. 
-
Firefox OS 架构概述
-
对Firefox OS 架构的概述. 
-
Firefox OS 测试
-
一个Firefox OS的测试指南, 包含如何创建自动化测试. 
-
Firefox OS 端口设置
-
关于Firefox OS在新设备中的端口设置. 
-
.userconfig 文件的配置
-
如何配置Firefox OS的编译和执行通过修改.userconfig文件. 
-
- -

View All...

-
-

从社区获得帮助

- -

以下资源助你开发火狐应用

- - - -
    -
  • Ask your question on Mozilla's Boot to Gecko IRC channel: #b2g
  • -
- -

Don't forget about the netiquette...

- - - - - - -

Resources

- - -
- -

 

diff --git a/files/zh-cn/archive/b2g_os/platform/out_of_memory_management_on_firefox_os/index.html b/files/zh-cn/archive/b2g_os/platform/out_of_memory_management_on_firefox_os/index.html deleted file mode 100644 index eda111fbc8..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/out_of_memory_management_on_firefox_os/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Firefox OS 中的内存溢出管理 -slug: Archive/B2G_OS/Platform/Out_of_memory_management_on_Firefox_OS -tags: - - B2G - - Firefox OS - - Gaia - - LMK - - OOM - - Out of memory - - oom_adj - - 低内存管理器 - - 低内存通知器 -translation_of: Archive/B2G_OS/Platform/Out_of_memory_management_on_Firefox_OS ---- -
-

Firefox OS 运行在一些严重内存受限的设备上时,就会很容易出现app在运行时将内存耗尽的情况。当一个进程将系统上可用的内存耗尽时, 为了能够释放内存,kernel 层必须要 kill 掉其他的进程。本文则描述了低内存 killer和 低内存通知器是如何工作的 。

-
- -

FxOS 的操作会涉及到多进程问题—一个“主进程”运行基本的系统服务和潜在众多的“子进程”。FxOS 环境下应用很少会由用户主动关闭,因此当新的 app需要空间或已存在的 app需要额外的内存时, system会自动对应用程序的生命周期进行管理。

- -

有两个子系统负责这方面的管理:  低内存管理器 Low memory killer (LMK) 和低内存通知器Low memory notifications.

- -

低内存管理器 Low memory killer

- -

 LMK 是 Android 内核的子系统,当有获取内存空间的需求时,能够自动的对进程进行查杀。为了能够选择出哪一个进程需要第一个查杀,每个进程都要通过 /proc/<pid>/oom_adj or /proc/<pid>/oom_score_adj files 来设定一个优先级。 每个进程的优先级也可称为调整分数或 oom_adj.  oom_adj ,值越小则表示器进程优先级越高。

- -

一般来说,进程的调整得分越高,越可能被查杀。 LMK 提供了多个等级,每一个都与一定程度的闲置内存和最小调整分数对应。当闲置内存的数量低于某个特定等级时,所有高于该等级指定的最小调整分数的进程都具有被查杀的可能。LMK会开始查杀这些进程,分数高的会被先杀掉,直到闲置内存再次高于临界值为止。

- -

Note: When a background app is killed by the LMK, it is made available in the task manager/through edge swipes as a "zombie app": next time you browse to that app, it will be revived. The maximum number of apps that can be kept in this state is currently 10.

- -
-

注意: 当设备存储器不足(oom) 时杀掉的进程并不一定是导致存储器不足(oom)的原因。

-
- -

进程优先级

- -

Firefox OS 中的 app 是以下面的优先级次序策略来管理的,这种策略是根据每个应用的优先级等级和这些等级相关的 OOM 调整分数 (the current values are set in prefs)而制定的: 

- -
    -
  1. 后台应用会首先被干掉,先从使用最少的应用开始
  2. -
  3. 之后会干掉 homescreen 应用程序
  4. -
  5. 可由用户感知的后台应用会被干掉 (例如, 在后台播放音频的音乐播放器或者持有  high-priority 或 cpu wakelock,并且注册系统消息的处理程序)
  6. -
  7. 如果 keyboard 应用正在运行,会被干掉
  8. -
  9. 前台应用被干掉
  10. -
  11. 最后,已请求  high-priority 或 cpu wakelocks 的前台应用会最后被干掉
  12. -
- -
-

注意: 当子进程在前台时,会以  oom_adj 2 运行。后台的子进程运行时,其 oom_adj 会在 3 和 6 (包括6) 之间。后台运行的子进程  oom_adj 数值要取决于许多因素,如是否播放音乐,是否是homescreen 等。

-
- -

也有两个例外的情况:

- - - -

低内存通知器 Low memory notifications

- -

释放内存的第二种机制就是低内存通知器。 LMK 提供一个特定的门限值,当超出该值时,会通知用户当前系统已运行在低内存状态。system 应用和常规的用户应用都会持续的等待这个条件,并通过 observer service 发送一个 memory-pressure 方法来响应它。 这个事件只对 C++ 和 chrome JS 代码可见,并非由应用直接发送。通过Gecko 代码库,我们使用该事件可以释放尽可能多的内存— 一般会通过清除内部缓存(图片,DNS,数据库等),丢弃可重新创建的资源(例如, WebGL contexts)以及运行垃圾回收器,生命周期回收器等方式实现。

- -

当低内存情况发生时, 触发的第一个 memory-pressure 事件会有一个 low-memory 负载。 如果在预订时间(5s) 后, 还处在低内存状态, 会触发另一个 memory-pressure 事件,但此次负载值变为 low-memory-onging 。当一直处在低内存条件下,并且要清除缓存以及做其他简单的内存削减时,该负载会被使用,但应当知道一些繁重的工作,如 GC , 是不能成功的。(此段翻译可能不是太贴切,要深入理解,还请参考英文原文)

- -

 LMK 和低内存通知器是如何配合工作的

- -

当前低内存限值设定在后台进程 LMK 等级和 homescreen 之间。 因此当设备在低内存状态下运行时, LMK 和 低内存通知器联合作出的反应如下:

- -
    -
  1. 以最不经常使用的次序 kill 掉 后台 app
  2. -
  3. 如果我们没有释放足够的内存, 向所有现存的应用发送 memory-pressure 事件
  4. -
  5. 如果低内存情况还在,每个 5 秒重发一次 memory-pressure 事件,但将它们标记为 ongoing , 使 GC/CC 不会对它们动作。
  6. -
  7. Kill 掉 homescreen.
  8. -
  9. Kill 掉可感知的或高优先级的后台应用
  10. -
  11. 如果 keyboard app 正在运行,Kill 掉
  12. -
  13. Kill 掉前台应用
  14. -
  15. Kill 掉高优先级的前台应用
  16. -
  17. Kill 掉 preallocated process
  18. -
diff --git a/files/zh-cn/archive/b2g_os/platform/settings_list/index.html b/files/zh-cn/archive/b2g_os/platform/settings_list/index.html deleted file mode 100644 index fc834dc10f..0000000000 --- a/files/zh-cn/archive/b2g_os/platform/settings_list/index.html +++ /dev/null @@ -1,716 +0,0 @@ ---- -title: Firefox OS 设置选项列表 -slug: Archive/B2G_OS/Platform/Settings_list -tags: - - API - - B2G - - Firefox OS - - Settings - - WebAPI - - 参考 -translation_of: Archive/B2G_OS/Platform/Settings_list ---- -
-

Firefox OS 提供了许多设置项,用于配置设备以及内嵌的功能。这些设置项可以由 certified apps 通过使用 Settings API 来访问。

-
-
-

注意: 由于不同的 Firefox OS 发行版本及设备提供的功能会有所不同,这个列表可能并不会精确的对每个设备进行匹配。

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
设置项名称类型默认值
accessibility.invertBooleanfalse
accessibility.screenreaderBooleanfalse
alarm.enabledBooleanfalse
app.reportCrashesStringask
app.update.intervalNumber86400
audio.volume.alarmNumber15
audio.volume.bt_scoNumber15
audio.volume.dtmfNumber15
audio.volume.contentNumber15
audio.volume.notificationNumber15
audio.volume.ttsNumber15
audio.volume.telephonyNumber5
bluetooth.enabledBooleanfalse
bluetooth.debugging.enabledBooleanfalse
camera.shutter.enabledBooleantrue
clear.remote-windows.dataBooleanfalse
debug.grid.enabledBooleanfalse
debug.oop.disabledBooleanfalse
debug.fps.enabledBooleanfalse
debug.ttl.enabledBooleanfalse
debug.log-animations.enabledBooleanfalse
debug.paint-flashing.enabledBooleanfalse
debug.peformancedata.sharedBooleanfalse
deviceinfo.firmware_revisionString 
deviceinfo.hardwareString 
deviceinfo.osString 
deviceinfo.platform_build_idString 
deviceinfo.platform_versionString 
deviceinfo.softwareString 
deviceinfo.update_channelString 
gaia.system.checkForUpdatesBooleanfalse
general.useragent.updates.enabledBooleantrue
geolocation.enabledBooleantrue
keyboard.layouts.englishBooleantrue
keyboard.layouts.dvorakBooleanfalse
keyboard.layouts.otherlatinsBooleanfalse
keyboard.layouts.cyrillicBooleanfalse
keyboard.layouts.arabicBooleanfalse
keyboard.layouts.hebrewBooleanfalse
keyboard.layouts.zhuyinBooleanfalse
keyboard.layouts.pinyinBooleanfalse
keyboard.layouts.greekBooleanfalse
keyboard.layouts.japaneseBooleanfalse
keyboard.layouts.polishBooleanfalse
keyboard.layouts.portugueseBooleanfalse
keyboard.layouts.spanishBooleanfalse
keyboard.vibrationBooleanfalse
keyboard.clicksoundBooleanfalse
keyboard.autocorrectBooleantrue
keyboard.wordsuggestionBooleantrue
keyboard.currentStringen
language.currentStringen-US
lockscreen.passcode-lock.codeString0000
lockscreen.passcode-lock.timeoutNumber0
lockscreen.passcode-lock.enabledBooleanfalse
lockscreen.notifications-preview.enabledBooleantrue
lockscreen.enabledBooleantrue
lockscreen.lockedBooleantrue
lockscreen.unlock-sound.enabledBooleanfalse
mail.sent-sound.enabledBooleantrue
message.sent-sound.enabledBooleantrue
operatorvariant.mccString0
operatorvariant.mncString0
ril.iccInfo.mbdnString 
ril.sms.strict7BitEncoding.enabledBooleanfalse
ril.cellbroadcast.searchlistString 
debug.console.enabledBooleanfalse
phone.ring.keypadBooleantrue
powersave.enabledBooleanfalse
powersave.thresholdNumber0
privacy.donottrackheader.enabledBooleanfalse
ril.callwaiting.enabled  
ril.cf.enabledBooleanfalse
ril.data.enabledBooleanfalse
ril.data.apnString 
ril.data.carrierString 
ril.data.defaultServiceIdNumber0
ril.data.passwdString 
ril.data.httpProxyHostString 
ril.data.httpProxyPortNumber0
ril.data.mmscString 
ril.data.mmsproxyString 
ril.data.mmsportNumber0
ril.data.roaming_enabledBooleanfalse
ril.data.userString 
ril.mms.apnString 
ril.mms.carrierString 
ril.mms.httpProxyHostString 
ril.mms.httpProxyPortString 
ril.mms.mmscString 
ril.mms.mmsportString 
ril.mms.mmsproxyString 
ril.mms.passwdString 
ril.mms.userString 
ril.radio.preferredNetworkTypeString 
ril.radio.disabledBooleanfalse
ril.supl.apnString 
ril.supl.carrierString 
ril.supl.httpProxyHostString 
ril.supl.httpProxyPortString 
ril.supl.passwdString 
ril.supl.userString 
ril.sms.strict7BitEncoding.enabledBooleanfalse
ril.sms.defaultServiceIdNumber0
ril.telephony.defaultServiceIdNumber0
ring.enabledBooleantrue
screen.automatic-brightnessBooleantrue
screen.brightnessNumber1
screen.timeoutNumber60
tethering.usb.enabledBooleanfalse
tethering.usb.ipString192.168.0.1
tethering.usb.prefixString24
tethering.usb.dhcpserver.startipString192.168.0.10
tethering.usb.dhcpserver.endipString192.168.0.30
tethering.wifi.enabledBooleanfalse
tethering.wifi.ipString192.168.1.1
tethering.wifi.prefixString24
tethering.wifi.dhcpserver.startipString192.168.1.10
tethering.wifi.dhcpserver.endipString192.168.1.30
tethering.wifi.ssidStringFirefoxHotspot
tethering.wifi.security.typeStringopen
tethering.wifi.security.passwordString1234567890
tethering.wifi.connectedClientsNumber0
tethering.usb.connectedClientsNumber0
time.nitz.automatic-update.enabledBooleantrue
time.timezone  
ums.enabledBooleanfalse
ums.modeNumber0
vibration.enabledBooleantrue
wifi.enabledBooleantrue
wifi.screen_off_timeoutNumber600000
wifi.disabled_by_wakelockBooleanfalse
wifi.notificationBooleanfalse
wifi.connect_via_settingsBooleanfalse
icc.displayTextTimeoutNumber40000
icc.inputTextTimeoutNumber40000
-

参考

- diff --git a/files/zh-cn/archive/b2g_os/porting/index.html b/files/zh-cn/archive/b2g_os/porting/index.html deleted file mode 100644 index fb32edac40..0000000000 --- a/files/zh-cn/archive/b2g_os/porting/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: 将B2G(Firefox OS)移植到你的手机上 -slug: Archive/B2G_OS/Porting -translation_of: Archive/B2G_OS/Porting_B2G_OS/basics ---- -

Boot to Gecko (Firefox OS)使用 Android的核心驱动, 在之上加上一个基于 Gecko的用户界面,这篇文章提供了移植操作系统到新设备上的一个基本流程。

-

这个指南假设你要移植的新设备上运行的是安卓;如果你要移植到其他设备上,会需要做更多的工作。

-

设置你的编译系统

-

第一步是配置你的编译系统;你可以使用这个指南Firefox OS build prerequisites

-

克隆B2G仓库

-

然后就是克隆B2G仓库

-
git clone https://github.com/mozilla-b2g/B2G.git
-

创建原安卓系统的本地备份

-

接下来,在你尝试编译B2G之前,应该备份你的安卓系统,另外,这些东西在编译和安装过程中也能用的到。

-
mkdir my_device_backup
-cd my_device_backup
-adb pull /system system
-

在config.sh中添加一个新设备

-

下一步是向config.sh文件中添加一个新设备;你可以使用已存在的设备作为模板,这仅仅是提供编译时获取正确文件的指南。

-

为新设备创建清单文件

-

现在你需要为新设备在称为default.xml的清单文件中添加必须的仓库(repos);在github上的b2g-manifest文件作为一个模板,每一个设备都有它自己的分支,你可以使用galaxy-s2作为一个例子。

-

为新设备创建配置树

-

为新设备创建配置树,这应该在device/<manufacturer>/<device_id>中,这个树中应该至少包括:

- -

不同设备的这些内容可能会有很大的差别。尤其是BoardConfig.mk 和 extract-files.sh,这部分需要大量的研究,测试和调试才能得到哪些二进制对象应该被提取出来。

-
-

注意: 如果你可以在 CyanogenMod 上为你的设备找到一个已存在的引用,这些信息会加速你的移植过程, XDA Forum 是另一个讨论和寻找资源的好地方.

-
-

重新编译 boot.img

-

一旦你完成了上面所有步骤,你需要重新编译引导镜像,通常情况下,内核本身并不需要它,但是为适应init.rc的变化需要重新编译。

-

init.rc的变化

-

你使用的 init.rc 并不是B2G提供的;而是从你的设备上拷贝下来的。

-

你主要需要修改的是:

-

导入 init.b2g.rc

-

加入下面这些行来导入 init.b2g.rc:

-
on early-init
-    start ueventd
-    import /init.b2g.rc
-

解决权限问题

-

更正文件 /system/b2g/b2g, /system/b2g/updater, /system/b2g/plugin-container 的权限;这些行执行后挂载的系统应该可以读写:

-
chmod 0755 /system/b2g/b2g
-chmod 0755 /system/b2g/updater
-chmod 0755 /system/b2g/plugin-container
-

你可能想要从修改新设备的init.rc开始,而不是使用编译系统提供的init.rc,如果是这样,你要记得设置 BoardConfig.mk中的TARGET_PROVIDES_INIT_RC.

-

预编译核心 vs. 从源代码编译核心

-

你可以使用一个预编译的核心,或者你可以从源代码编译核心,要从源代码编译核心,在设备配置树中添加AndroidKernel.mk和核心配置。

-

旧编译系统 maguro 就是一个从源代码编译系统的例子。

-

提取并修改现存引导镜像

-

通过转存/dev/mtd/mtd1或 /dev/mtd/mtd2设备来恢复手机的引导镜像是可能的,成果镜像文件可以很容易的恢复:

-
adb shell 'cat /dev/mtd/mtd1 > /sdcard/boot.img'
-adb pull /sdcard/boot.img
-
-

 

-

获得了引导镜像文件之后你就可以通过帮助工具像unmkbootimg来解压,这个工具会解压出核心镜像(zImage)和虚拟磁盘(initramfs.cpio.gz),而且还会输出一个用于将原镜像带一些参数重新编译的命令,如:

-
$ unmkbootimg boot.img
-Kernel size 3872576
-Kernel address 0x208000
-Ramdisk size 265102
-Ramdisk address 0x1500000
-Secondary size 0
-Secondary address 0x1100000
-Kernel tags address 0x200100
-Flash page size 2048
-Board name is ""
-Command line "androidboot.hardware=aphone"
-Extracting kernel to file zImage ...
-Extracting root filesystem to file initramfs.cpio.gz ...
-All done.
----------------
-To recompile this image, use:
-  mkbootimg --kernel zImage --ramdisk initramfs.cpio.gz --base 0x200000 --cmdline 'androidboot.hardware=aphone' -o new_boot.img
----------------
-
-

 

-

要修改虚拟磁盘文件,创建一个输出文件夹并解压到此:

-
mkdir initramfs_dir
-cd initramfs_dir
-gunzip -c /path/to/your/boot.img | cpio -i
-
-

 

-

完成所有改变(如修改init.rc)并用mkbootfs重新打包虚拟磁盘,确保使用B2G主机工具的版本:

-
/path/to/your/B2G/out/host/linux-x86/bin/mkbootfs initramfs_dir | cpio -o -H newc | gzip > ../newinitramfs.cpio.gz
-
-

 

-

最后使用mkbootimg重新打包引导镜像,也要确保使用的是B2G主机工具的版本:

-
/path/to/your/B2G/out/host/linux-x86/bin/mkbootimg --kernel zImage --ramdisk newinitramfs.cpio.gz --base 0x200000 --cmdline 'androidboot.hardware=aphone' -o new_boot.img
-
-

 

-

如果你现在把新的引导镜像拷贝到 out/target/product/$DEVICE/boot.img ($DEVICE 是你的设备名称)下,它将会在调用 flash.sh时自动写入,或者你可以用下面的命令手动写入手机中:

-
adb reboot bootloader
-fastboot flash boot newboot.img
-fastboot reboot
-
-

 

-

在 flash.sh中添加新设备

-

添加新设备到 flash.sh中,具体细节将取决于写入新设备时所用的工具。

-

配置、编译和写入设备

-

现在你可以尝试编译并写入你的新设备了:

-
ANDROIDFS_DIR=my_device_backup ./config.sh <device_id> default.xml
-./build.sh
-./flash.sh
-

测试和调试

-

待续

-

FAQ

-

Forthcoming

-

See also

- diff --git a/files/zh-cn/archive/b2g_os/preparing_for_your_first_b2g_build/index.html b/files/zh-cn/archive/b2g_os/preparing_for_your_first_b2g_build/index.html deleted file mode 100644 index 405ff0fc23..0000000000 --- a/files/zh-cn/archive/b2g_os/preparing_for_your_first_b2g_build/index.html +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: 准备第一次B2G的构建 -slug: Archive/B2G_OS/Preparing_for_your_first_B2G_build -translation_of: Archive/B2G_OS/Preparing_for_your_first_B2G_build ---- -

- -

在构建B2G之前,你需要下载编译B2G构建的代码库并做配置。本篇就是教你如何完成这一过程。

- -

配置步骤会需要一些时间来下载构建FirefoxOS的必要文件,时间的长短取决你的网速。(如果网速在150KBps,下载整个Android代码库将要几十个小时)。等待下载是很乏味的过程,如果你读完本页及已经开始配置脚本,可以考虑去配置与试用一下Firefox OS 模拟器,或去熟悉一下应用开发文档(像是如何设计与创建一个应用、了解后续步骤的信息等)。

- -
-

配置和构建 B2G 的可能需要较长的时间,你可以去做一些其他工作或者和朋友去喝杯咖啡。

-
- -

如果你在等待代码下载,或者在开始前想体验一把,你可以看下下面的视频,该视频演示了构建Firefox OS准备工作。(大陆地区无法看到该视频。。。)

- -

- -

克隆B2G代码库

- -

第一步,克隆一份 B2G 远程的Git版本库到本地后,才可以开始你的第一个构建。这一步不会获取所有想要的东西!相反,只会获取B2G构建系统和配置的实用工具。最主要的B2G代码都在 Mozilla Mercurial 主仓储中。

- -

使用 git 来克隆你的版本库:

- -
git clone git://github.com/mozilla-b2g/B2G.git
- -

克隆之后(应该会花个几分钟),cd 到 B2G 的目录:

- -
cd B2G
-
- -

为你的设备配置专属 B2G

- -
重要:请注意只支援 Android 4(又名:Ice Cream Sandwich)的移动设备,或是各种支持的IT平台(目前只有 Firefox OS 设备)。请确认你手机运行的是ICS,否则这个步骤很可能会因为驱动程序在某些非Nexus设备上失败。另外,如果你需要将ICS刷入移动设备,请留意有些USB集线器和刷机工具不兼容,因此可能需要将移动设备连接到内建的USB端口。
- -
重要:如果你在 Ubuntu 12.10+ 或 Fedora 上构建,需要在检索 B2G 源码后指定 GCC4.6 为默认主编译器,(默认情况下发行版使用 GCC4.7)。可以阅读 Changing the default host compiler 了解如何做到这一点。
- -
注意:在运行任何构建命令之前,请先阅读下面左右指令,以确保你正在做的事是正确的!
- -

一旦有了构建 B2G 的系统环境,为了正确安装你需要设定移动设备  。要获得支持设备列表,可以使用  config.sh 工具, 如下所示:

- -
./config.sh
-
- -

这会显示一个支持设备列表,例如:

- -

Usage: ./config.sh [-cdflnq] (device name)
- Flags are passed through to |./repo sync|.

- -
Valid devices to configure are:
-- galaxy-s2
-- galaxy-nexus
-- nexus-4
-- nexus-4-kk
-- nexus-5
-- nexus-5-l
-- nexus-s
-- nexus-s-4g
-- flo (Nexus 7 2013)
-- otoro
-- unagi
-- inari
-- keon
-- peak
-- hamachi
-- helix
-- tarako
-- dolphin
-- dolphin-512
-- pandaboard
-- vixen
-- flatfish
-- flame
-- flame-kk
-- flame-l
-- rpi (Revision B)
-- emulator
-- emulator-jb
-- emulator-kk
-- emulator-l
-- emulator-x86
-- emulator-x86-jb
-- emulator-x86-kk
-- emulator-x86-l
-> Sony Xperia devices
-- aries (Z3 Compact KK)
-- aries-l (Z3 Compact L)
-- leo-kk (Z3 KK)
-- leo-l (Z3 L)
-- scorpion-l (Z3 Tablet Compact L)
-- sirius-l (Z2 L)
-- tianchi-l (T2U L)
-- flamingo-l (E3 L)
- -

如果你的设备未被列出,应该马上停止来帮忙将 B2G 移植到你的设备,或是等别人完成移植。我们当然比较希望你可以帮忙移植!

- -
注意:Firefox OS 手机页面上可以找到你手机的设备名。
- -
注意:对于 Keon 配置和构建在 Mac 上进行是无法工作的。针对该设备的构建你需要使用 Linux。
- -
注意:如果因为任何原因,你想要编译构建 Gecko 的某个特定版本,请阅读  Building against a custom Gecko,然后再继续。如果你想要构建一个你设备默认以外的分支(例如,建立 B2G 的特定版本),请阅读 Building a branch
- -
注意:不同设备默认的可能是自己的分支版本,未必是主干(trunk)版本.。
- -

这将是一个很好的喝咖啡时间,需要将所有所需的代码提取、构建并引导到 Gecko,这一过程会花费很长的时间,你可能需要通过使用 Ctrl-C 停止和稍后重新启动工作。如果你觉得某部分因为终止,而未完成,可以运行 “./repo sync” 来修复任何可能出现的问题。

- -

为移动设备配置

- -

首先,连接你的设备,在配置过程中需要访问它。

- -

如果你的设备被列出,可以通过运行 config.sh 指定你的设备名称再次启动配置程序。例如,要为三星 Google Nexus S 构建,请键入:

- -
./config.sh nexus-s
-
- -
注意:如果你得到了一个"fatal: manifest 'nexus-s.xml' not available"的错误提示,这时你只需要指定一个你想要使用的分支 。请阅读 Building a branch了解详情。
- -

在配置的刚开始,你可能需要设置颜色使用的选项,在这里你可以只选择“Y”,因为可能会想要一个自己的颜色版本。完事之后会继续配置流程。现在就可以去喝个咖啡休息一下,因为你第一次需要把构建 Boot to Gecko 中所有要的程序都抓下来。

- -

使用系统备份配置构建

- -

如果你的手机不再使用 Android 且 B2G tree 还没装到手机上,但聪明地作一份/system 分区的备份的话,你可以在系统备份基础上执行构建,像这样:

- -
ANDROIDFS_DIR=<absolute path to parent dir of system dir> ./config.sh <target>
-
- -

请注意,构建系统将会有默认存放目录,如“backup-inari/system”(取决于设备配置),如果打算把文件存放在默认位置,你不需要特意指定目录。

- -

注意:如果你的手机原本就运行着 Firefox OS,而从来没有运行过Android,它仍然会细致的把文件挂载到/system 分区,这样会为你指引到正确的文件。

- -

配置构建一个模拟器

- -

如果你想要在模拟器中构建,可以选择一款 ARM 设备模拟器作为指定模拟器,或是使用 "emulator-x86" 来打造x86模拟器。后者速度更快,但不能准确的表现出实际移动设备的表现。

- -

现在,举个例子,构建ARM模拟器,应该这样配置:

- -
./config.sh emulator
-
- -

在配置的刚开始,你可能需要设置颜色使用的选项,在这里你可以只选择“Y”,因为可能会想要一个自己的颜色版本。完事之后会继续配置流程。现在就可以去喝个咖啡休息一下,因为你第一次需要把构建 Boot to Gecko 中所有要的程序都抓下来。

- -

此时你应该准备好开始构建,除非你需要更高级的信息,详情如下。

- -

注意:模拟器无法在64位 Linux上构建。

- -
-

注意:./config.sh 可能会比你想想的更耗费时间和网络资源。你可能需要通过使用 Ctrl-C 停止和稍后重新启动工作。如果你觉得某部分因为终止,而未完成,可以运行 “./repo sync” 来修复任何可能出现的问题。

-
- -

构置定制一个 Gecko

- -

可能你会想要或需要以好几种版本的 Gecko 来编译 Boot to Gecko(manifest 中预设是一种)。你可以在你抓仓储(在上述的 config.sh 之前),藉由编辑 .userconfig 来做到这件事情在举例来说,如果你要根据 mozilla-central 来编译:

- -
export GECKO_PATH=/path/to/mozilla-central
-export GECKO_OBJDIR=/path/to/mozilla-central/objdir-gonk
-
- -
-

注意:如果是在 Mac OS X 中编译自定义版 Gecko 的话,文件系统会区分  mozilla-central 目录的大小写。

-
- -

注意,可以在你抓仓储之前(也就是在上述的 config.sh 之前)或之后几步。你也可以通过多个 UserConfig 的文件(使用不同的设置 - 当然每个都需要不同 OBJDIR)和编辑,保留多个构建(与调试等)。添加一个符号连接(symlink)指向一个配置(你想要使用哪个构建就指向那个配置)。

- -

欲了解更多信息,请阅读 Changing the Gecko source tree

- -

建立一个分支

- -

如果你想要构建一个非默认的分支(注:默认分支可能不是“主干”),需要调用 config.sh 并前缀分支名称,像这样:

- -
BRANCH=branch-name ./config.sh <device>
- -

分支名称应该是合乎逻辑的,主要是按照产品/版本的名称,比如v1-trainv1.0.0、v1.0.1、v1.1、v1.1.0hd、v1.2,以此类推。举个例子,在模拟器上构建 B2G Firefox 1.2,你需要键入:

- -
BRANCH=v1.2 ./config.sh emulator
- -

如果你已经运行过 config.sh,可以通过去B2G/.repo/manifests 查看分支名称,或者用 “git branch -a”,使用分支名在行的最尾端即可,如:“v1-train” 或 “master”:

- -
  remotes/origin/master
-  remotes/origin/v1-train
-  remotes/origin/v1.0.0
-  remotes/origin/v1.0.1
- -

另外要了解更多关于定制,你可以查看 Customization with the .userconfig file

- -

复制你的 B2G 树(tree)到一台新机器

- -

如果你之前已经设置了 B2G tree,如果你又有了一代新电脑,想要把 B2G tree 从一台电脑转移到另一台电脑的话,你会发现至少比起重新配置整个事情更容易。

- -

要做到这一点,将你旧电脑的硬盘挂载到新电脑,然后敲入下面的命令,就可以了:

- -
rsync -a source/ dest/
-
- -

source 是整个原码树(source tree)的完整路径(包括后面的斜线),而 dest 是你要复制到目标位置(同样也包含后面的斜线,它很重要!)。

- -
注意:如果你采用把文件从一台电脑复制到另一台电脑的方法,应该确保在开始构建之前运行一次“./build.sh clean”。如果不这样做,可能会遇到编译问题。
- -

如果你采用了这个方法迁移代码,可以跳过本文余下的部份,然后直接跳到的“构建”部份。

- -

更新你的B2G树

- -

当存储库更新到了新版本,你要更新你的B2G tree。./sync 命令不会更新你的B2G树。要做到这一点,你可以运行下面的命令:

- -
git fetch origin
-git checkout origin/master
- -

你可以运行一下命令,检查是否工作正常:

- -
git show HEAD
- -

并检查提交的版本是否与最新提交版本显示匹配:https://github.com/mozilla-b2g/B2G/commits/master

diff --git a/files/zh-cn/archive/b2g_os/quickstart/index.html b/files/zh-cn/archive/b2g_os/quickstart/index.html deleted file mode 100644 index ebe1f7c220..0000000000 --- a/files/zh-cn/archive/b2g_os/quickstart/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Build -slug: Archive/B2G_OS/Quickstart -tags: - - NeedsTranslation - - TopicStub -translation_of: Archive/B2G_OS/Quickstart ---- -
-

Quickstart information on coding open web apps.

-
-
-
- Introduction to open web apps
-
- What are open web apps? How they differ from regular web pages? Why is this significant? This article aims to answer these questions and more.
-
- Your first app
-
- This article takes you through the basic steps and additional knowledge on top of regular web development required to create installable open web apps.
-
- Introduction to Firefox OS
-
- An introduction to Firefox OS, Mozilla's new open web app-based mobile platform.
-
- Introduction to manifests
-
- An FAQ designed to answer any questions you may have about manifests, hosting apps, origins, and other such topics.
-
- App development for web developers
-
- If you're a web developer, how do open web apps differ from what you're used to? This article explains all.
-
- App development for mobile developers
-
- If you're a native mobile application developer, what advantages can open web apps bring to you, and how do they differ from what you are used to? Here are some ideas.
-
- Developing app functionality
-
- This page talks about the kinds of different functionality that you might want to build into your apps, with links to further information.
-
- Payments
-
- How do you build functionality to make people pay for installing your open web apps? Here is the lowdown.
-
- App tools
-
- Last for this section, we provide some links to more information on the tools available to help you develop great open web apps.
-
diff --git a/files/zh-cn/archive/b2g_os/quickstart/your_first_app/index.html b/files/zh-cn/archive/b2g_os/quickstart/your_first_app/index.html deleted file mode 100644 index 63c859ce8a..0000000000 --- a/files/zh-cn/archive/b2g_os/quickstart/your_first_app/index.html +++ /dev/null @@ -1,261 +0,0 @@ ---- -title: 你的第一个应用 -slug: Archive/B2G_OS/Quickstart/Your_first_app -translation_of: Archive/B2G_OS/Quickstart/Your_first_app ---- -
-
-

开放式Web应用让开发人员实现了期盼多年的夙愿:通过Firefox OS这一首款开放式Web应用平台,可以仅仅使用Html、CSS和JavaScript在跨平台的环境中生成可部署的应用。本手册包含了基本的架构和应用构建指南,你能够迅速掌握这些内容并开始创造自己的下一个伟大的应用!

-
- -

如果你想按照本指南开发,你可以下载我们的快速入门应用模板。还可以参阅应用模板指南找到更多有关其内容的介绍。

- -

应用架构

- -

打包型应用 VS. 托管型应用

- -

开放网络应用有两种类型:打包型和托管型。打包型应用本质上来说就是一个包含各种HTML、CSS、JavaScript、图像、清单(manifest)等应用资源的zip文件。托管型应用在一个给定域名的服务器上运行,就像是一个独立的网站。两种应用都需要有有效的清单。到了要在火狐市场中列出你的应用是,你要上传应用的zip文件或提供托管应用所在的URL

- -
-

- -
-

Made in partnership with Treehouse: Check them out!

-
-
- -

在本指南结束时,你将创建一个寄宿于本机(localhost)地址上的托管型应用。一旦你的应用准备好进入火狐市场,你可以选择把它作为打包应用打包或作为托管应用启动。

- -

应用清单

- -

每一个火狐应用都需要一个位于应用根目录下的manifest.webapp文件, 这个文件提供与应用有关的重要信息,如:版本、名称、描述、图标地址、本地字符串、指明应用可以从哪儿被安装等等。只有名称和描述是必须的。应用模板中的简单清单如下所示:

- -
{
-  "version": "0.1",
-  "name": "Open Web App",
-  "description": "Your new awesome Open Web App",
-  "launch_path": "/app-template/index.html",
-  "icons": {
-    "16": "/app-template/app-icons/icon-16.png",
-    "48": "/app-template/app-icons/icon-48.png",
-    "128": "/app-template/app-icons/icon-128.png"
-  },
-  "developer": {
-    "name": "Your Name",
-    "url": "http://yourawesomeapp.com"
-  },
-  "locales": {
-    "es": {
-      "description": "Su nueva aplicación impresionante Open Web",
-      "developer": {
-        "url": "http://yourawesomeapp.com"
-      }
-    },
-    "it": {
-      "description": "La tua nuova fantastica Open Web App",
-      "developer": {
-        "url": "http://yourawesomeapp.com"
-      }
-    }
-  },
-  "default_locale": "en"
-}
- -
-

- -
-

Made in partnership with Treehouse: Check them out!

-
-
- -

 

- -

一个基本的清单是你所需要最先上手的地方。关于清单的更多细节,见应用清单

- -

应用布局&设计

- -

随着不同设备上屏幕分辨率标准的增多,响应式设计已经变得越来越重要。即使你应用的主要目标平台是移动平台比如Firefox OS,其他设备很有可能也会访问它。CSS媒体选择(CSS media queries)使你可以根据设备调整布局,如下的CSS样例中所示的结构:

- -
/* The following are examples of different CSS media queries */
-
-/* Basic desktop/screen width sniff */
-@media only screen and (min-width : 1224px) {
-  /* styles */
-}
-
-/* Traditional iPhone width */
-@media
-  only screen and (-webkit-min-device-pixel-ratio : 1.5),
-  only screen and (min-device-pixel-ratio : 1.5) {
-  /* styles */
-}
-
-/* Device settings at different orientations */
-@media screen and (orientation:portrait) {
-  /* styles */
-}
-@media screen and (orientation:landscape) {
-  /* styles */
-}
- -

有许多JavaScript和CSS的框架可以用于协助响应式设计和移动应用发展(Bootstrap等),选择最适合你的应用和开发样式的框架即可。

- -

Web APIs

- -

JavaScript APIs正随着设备即时的被开发和增强。Mozilla的WebAPI致力于为JavaScript APIs引入许多标准的移动端特性。设备支持状态列表可以在WebAPI页面中查看。JavaScript的特征检测依旧是最好的做法,如下例所示:

- -
// If this device supports the vibrate API...
-if('vibrate' in navigator) {
-    // ... vibrate for a second
-    navigator.vibrate(1000);
-}
- -

在下面这个例子中,<div>的显示样式会根据设备的电池状态的改变而改变:

- -
// Create the battery indicator listeners
-(function() {
-  var battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery,
-      indicator, indicatorPercentage;
-
-  if(battery) {
-    indicator = document.getElementById('indicator'),
-    indicatorPercentage = document.getElementById('indicator-percentage');
-
-    // Set listeners for changes
-    battery.addEventListener('chargingchange', updateBattery);
-    battery.addEventListener('levelchange', updateBattery);
-
-    // Update immediately
-    updateBattery();
-  }
-
-  function updateBattery() {
-    // Update percentage width and text
-    var level = (battery.level * 100) + '%';
-    indicatorPercentage.style.width = level;
-    indicatorPercentage.innerHTML = 'Battery: ' + level;
-    // Update charging status
-    indicator.className = battery.charging ? 'charging' : '';
-  }
-})();
- -

在上面的示例代码中,一旦你确定设备支持Battery API,你就可以为chargingchangelevelchange添加时间监听器来更新元素的样式。

- -

时常检查WebAPI页面以确保更新设备API的状态

- -

Install API功能

- -

在我们的样例快速开始应用模板中,我们已经实现了一个安装按钮,可以在你把应用当作一个标准网页来浏览时可以单击它来把那个网站当作一个应用安装在Firefox OS上。按钮标签并没有什么特别的:

- -
<button id="install-btn">Install app</button>
- -

按钮的功能由Install API实现(见install.js):

- -
var manifest_url = location.href + 'manifest.webapp';
-
-function install(ev) {
-  ev.preventDefault();
-  // define the manifest URL
-  // install the app
-  var installLocFind = navigator.mozApps.install(manifest_url);
-  installLocFind.onsuccess = function(data) {
-    // App is installed, do something
-  };
-  installLocFind.onerror = function() {
-    // App wasn't installed, info is in
-    // installapp.error.name
-    alert(installLocFind.error.name);
-  };
-};
-
-// get a reference to the button and call install() on click if the app isn't already installed. If it is, hide the button.
-var button = document.getElementById('install-btn');
-
-var installCheck = navigator.mozApps.checkInstalled(manifest_url);
-
-installCheck.onsuccess = function() {
-  if(installCheck.result) {
-    button.style.display = "none";
-  } else {
-    button.addEventListener('click', install, false);
-  };
-};
-
- -

我们来简要的看一下发生了什么:

- -
    -
  1. 我们得到一个安装按钮的引用并把它储存在button变量中。
  2. -
  3. 我们使用navigator.mozApps.checkInstalled 来检查这个由http://people.mozilla.com/~cmills/location-finder/manifest.webapp这个清单来定义的应用是否已经安装在设备上。这个测试结果被储存在installCheck这个变量中。
  4. -
  5. 当测试成功完成时,它的成功完成事件被触发,因此installCheck.onsuccess = function() { ... }会被执行。
  6. -
  7. 然后我们用一个if语句判断installCheck.result是否存在。如果存在,以为着应用已经被安装了,隐藏安装按钮。在应用已经被安装的情况下不需要安装按钮(废话>_<!)
  8. -
  9. 如果应用没有被安装,为按钮添加一个单击事件监听器,所以在按钮被单击的时候install()函数会被执行。
  10. -
  11. 当单击按钮并且install()函数执行时,我们把清单位置保存在一个叫manifest_url的变量中,然后利用navigator.mozApps.install(manifest_url)来安装应用,用一个installLocFind变量来储存对那个安装的应用。你会注意到安装也会触发success和error事件,所以你可以根据应用是否成功安装来执行不同的动作。
  12. -
- -

第一次遇到可安装网络应用时你可能想要核实API的执行状态

- -
-

注意:可安装开放网络应用有一个“每个来源(origin,感觉就是URL的意思)一个应用”的安全策略;基本上, 你不可以在一个来源上托管多个可安装应用。这会让检测变得有一点复杂,但是仍有很多办法解决这个问题,比如为应用创建多个子域名、用Firefox OS模拟器测试应用、或者在Firefox Aurora/Nightly上安装测试功能,通过这种方式你可以在桌面环境上安装开发网络应用。关于来源的跟多信息详见应用清单FAQ

-
- -

WebRT APIs (基于权限的 APIs)

- -

有些WebAPI虽然可以使用但是需要特定的功能开启才具有使用的权限。应用可能会像下面这样在manifest.webapp中记录权限请求:

- -
// New key in the manifest: "permissions"
-// Request access to any number of APIs
-// Here we request permissions to the systemXHR API
-"permissions": {
-    "systemXHR": {}
-}
- -

权限分为下面三个等级:

- - - -

关于应用权限等级的更多信息,请阅读打包型应用的类型。你可以在应用权限中找到更多关于API要求权限和需要什么样的权限。

- -
-

有一点需要注意的很重要就是不是所有的Web API都在Firefox OS模拟器中实现了。

-
- -

工具&测试

- -

测试在对移动应用的支持中是至关重要的。测试可安装开放网络应用有多种方式。

- -

Firefox OS 模拟器

- -

安装和使用Firefox OS模拟器  是启动和运行你的应用最简单的方式。在你安装模拟器之后,可以通过工具->web开发者->Firefox OS模拟器菜单来启动。模拟器启动时会有一个Javascript控制台,这样你就可以在模拟器中调试你的应用。

- -

应用管理器

- -

测试工具的新宠儿被称为应用管理器。这个工具允许你通过USB链接桌面火狐浏览器和一个可兼容性设备(或者一个Firefox OS模拟器),直接将应用推送到设备上,验证应用并且像运行在设备上一样的调试。

- -

单元测试

- -

当在测试不同设备和版本时,单元测试就会非常有价值。jQuery的QUnit是一个流行的客户端测试工具,当然你也可以使用任何你喜欢的测试工具。

- -

在设备上安装Firefox OS

- -

既然Firefox OS是一个开源平台,代码和工具都可以用于在你自己的设备上构建和安装Firefox OS。构建和安装指南以及什么设备可以安装的注意事项可以在MDN上发现。

- -

特定的Firefox OS开发者预览版设备可以在开发者预览版手机页面找到更多信息。

- -

应用提交和分发

- -

一旦你的应用完成,你可以像标准网站或应用一样托管它(更多信息请阅读发布应用),或者可以发布火狐市场。你的应用清单将被验证并且你可以选择你的应用将支持的设备(比如:Firefox OS、桌面版火狐浏览器、移动版火狐浏览器、平板班火狐浏览器)。一旦验证通过,你可以为你的应用添加更多细节(截屏、描述、价格等)并且正式在火狐市场应用列表中提交应用。提交成功后,你的应用可以被任何人购买和安装。

- -

更多商场&上市信息

- -
    -
  1. 向Firefox OS商场中提交应用
  2. -
  3. 市场审查标准
  4. -
  5. 应用提交演练视频
  6. -
-
diff --git "a/files/zh-cn/archive/b2g_os/quickstart/\345\274\200\346\272\220web\345\272\224\347\224\250\347\250\213\345\272\217\347\256\200\344\273\213/index.html" "b/files/zh-cn/archive/b2g_os/quickstart/\345\274\200\346\272\220web\345\272\224\347\224\250\347\250\213\345\272\217\347\256\200\344\273\213/index.html" deleted file mode 100644 index bb2a8127cd..0000000000 --- "a/files/zh-cn/archive/b2g_os/quickstart/\345\274\200\346\272\220web\345\272\224\347\224\250\347\250\213\345\272\217\347\256\200\344\273\213/index.html" +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: 开源Web应用程序简介 -slug: Archive/B2G_OS/Quickstart/开源Web应用程序简介 -translation_of: Archive/B2G_OS/Quickstart/Intro_to_open_web_apps ---- -
-

Note: The Quickstart section has been updated with a new, more focused Quickstart article, which replaces all the previous Quickstart articles. We hope you'll find this more useful, and a quicker learning experience than the older set of articles.

-
- -

Multi devices

- -
-

本文的目的是为那些希望学习更多关于开放式Web应用程序的人提供一个良好的起点,无论你是开发人员或者项目经理,或者应用程序开发或交付中的其他角色。在这里我们将提供一个简洁、更深层次的关于Web应用程序的概述,以及其背后的理念。

-
- -

开放的Web应用程序本质上同标准的网站或页面是没有什么不同的。它们是用标准的开放的网络技术---- HTML,CSS,Javascript 等等。----并且可以使用浏览器访问。主要的区别是它们可以安装到设备并且可以脱机工作,并使用先进的API用于与设备进行交互,如相机,地址簿,和其他类似的东西。此外,它们几乎都是尽可能用开放的技术开发的。区别在于平台技术的实现,努力确保两者都支持,其一:通过不同的平台相结合的特征检测和适当的代码,其二:优美的退化。

- -

开放式Web应用程序的优势

- -

我们来看一看关于开放式Web应用程序优势的一些细节:

- - - -

The following video also looks at general advantages of open web apps, and developing for the Firefox OS platform:

- -

- -

The Web is the platform

- -

An open web app as it exists as installed on a platform like Firefox OS is not a bookmark — it’s a proper part of the system. Open Web Apps hold that great promise. They are an opportunity that we should not miss, otherwise the Web might become fragmented once more. With this in mind it should be made clear that Open Web Apps (OWA in short) are intended to be standardized and to become part of "the Web". If successful, OWA should eventually work on all browsers, operating systems and devices.

- -

At Mozilla we are working hard to create this apps platform that is backed entirely by the open Web. It’s not intended to be a “Mozilla platform” or a “Firefox platform”. The Web is the platform. We’re creating a set of open APIs and implementations to show how portable apps can exist on the Web without vendor lock-in. Other groups like Facebook and Google Chrome are also working on apps platforms backed by the Web. Facebook apps are meant to hook into Facebook and Chrome apps are designed for Chrome OS devices and Google servers. Chrome apps are the most similar to Open Web Apps. We continue to collaborate with the Google Chrome team as app standards evolve and we definitely share a lot of the same vision. There is tremendous potential for all Web based app platforms to converge and we invite all vendors to help us build the right Open Web App APIs.

- -

Even though currently you must have a Mozilla Firefox-based engine ("Web runtime") to use Open Web Apps, it is not intended that this always will be the case. Many parts of the Open Web Apps project are still being worked out and it isn't possible to implement everything in all browsers at once. Although many parts of Open Web Apps are already standardized, many other parts are still in flux. It is intended and hoped that Open Web Apps will be a standard capability that is available in all major browsers.

- -

Therefore, when you read the MDN pages that deal with Open Web Apps, please keep in mind that even though much of the information is specific to Firefox right now, it will hopefully enable you to develop Open Web Apps for all browsers in the future.

- -

Web standards

- -

OWA technology is not a single piece, it is an umbrella that groups many different technologies and some of them are very young. At the moment, parts of OWA are standardized (HTML5, CSS, JavaScript, IndexedDB, etc.). Other parts are not yet standardized and the Mozilla implementation is thus specific to Firefox or to some other Mozilla technology. As the Mozilla mission is to share and to empower everyone, this situation is only temporary. That's why in the OWA docs we will try to clearly identify the parts of OWA that are not yet standardized.

- -

Please also note that there may be some OWA-related proposals and potential standards that are not used by Mozilla.

- -

Intended eventual standards

- -

So here are the parts not standardized yet across the different Web platforms and that still are Firefox-only for the moment:

- - - -

Marketplace

- -

Buy Once, Run Everywhere

- -

From the ground up Mozilla has been building an apps system that lets users buy an app once and run it on all of their HTML5 devices. Very soon Mozilla will launch the first Firefox OS phone but that will be just one device on which to run your apps. When you purchase an app through the Firefox Marketplace, the system installs a receipt on your device. The receipt is a JSON Web Token with metadata that links to the Marketplace’s public key and its verification service URL. When an app starts up it can verify the receipt but the receipt on the device is not tied to the Firefox Marketplace. The receipt is just a cryptographically verifiable proof of purchase. Anyone can sell open Web apps if they follow the receipt specs. When you buy an app, it is intended to be portable across any device that supports the Open Web Apps system.

- -

Mozilla is building the infrastructure needed to run Open Web Apps on any HTML5 device. Firefox for Android will let you install and run apps (you can try it today on the nightly build). Installed app icons go to your home screen just like regular Android apps. You can also install and run Web apps on your Windows, Mac, or Linux desktop using Firefox (this currently works in the nightly build). Currently some version of Firefox is required, but it is intended that the Open Web Apps system will eventually be supported by all major browsers as a set of standards. From day one Mozilla has included all major HTML5 compliant browsers in its proof of concepts; you can take a look at this hosted JavaScript shim for ideas on how to support the apps platform on a non-Firefox browser.

- -

In the future the Open Web Apps system will support syncing your installed apps across devices. Since receipts are portable you could just sync them yourself if you wanted to. In case it’s not obvious, you can always run a free open Web app in any browser because it is no different than a website. It might, however, use new mobile specific web APIs which are not implemented on all platforms.

- -

The video below provides a useful overview of the advantages of open marketplaces and an open web approach to app discovery:

- -

- -

WebPayment API

- -

Commerce For Apps

- -

Part of the success of mobile app platforms like iOS and Android is that they make it very easy to try out new business models through mobile payments. Those models are still evolving but commerce is no doubt something that, at the moment, is awkward on the desktop Web and more natural on mobile. Specifically, it’s very convenient to charge something to your phone bill when you’re already accessing it from your phone anyway. With the launch of Firefox OS, the apps ecosystem will support app purchases and in-app payments through the WebPayment API. Supporting commerce is crucial for the growth of an apps platform. The use of the proposed payment API is completely optional. Mozilla won’t prevent any app from using its own in-app payment system.

- -

See also

- - diff --git a/files/zh-cn/archive/b2g_os/running_tests_on_firefox_os_for_developers/index.html b/files/zh-cn/archive/b2g_os/running_tests_on_firefox_os_for_developers/index.html deleted file mode 100644 index c7b64d1573..0000000000 --- a/files/zh-cn/archive/b2g_os/running_tests_on_firefox_os_for_developers/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: '在 Firefox OS 中运行测试程序: 开发者指南' -slug: Archive/B2G_OS/Running_Tests_on_Firefox_OS_for_Developers -translation_of: Archive/B2G_OS/Running_Tests_on_Firefox_OS_for_Developers ---- -
-

在我们自动化测试背后的团队一直在非常努力的对自动化测试的框架进行扩展以及构建了一个专门针对手机系统测试的框架以适应 Firefox OS 的需求。由于 Firefox OS 架构的关系,所有测试框架都可以工作和使用,但是也会使事情变得更复杂. 您时一名开发者,只是想运行一些测试来验证您的 patch 是否能正常工作。本文旨在对 Mozilla 中所有有效的测试资源进行梳理。

-
-

入门

-

如果您是一位 Gecko 开发者,则需要对您已经熟悉的有关 Firefox OS 特定的自动化测试文档进行回顾:  mochitest, reftest, 和 xpcshell.

-

如果您是一位 Gaia App 开发者,或者是一位 Gecko 开发者,但是对更深层次的终端用户样式测试感兴趣,则需要了解下 Gaia 测试套件。 一共有两个主测试套件:

- -

可以依据您喜爱的工具链,以及测试的内容来决定究竟要选择何种测试。

-

让我们现在来查看和运行这些测试。

-

运行 Gaia UI 测试

-

The Gaia UI Test suite can be run on real devices and B2G Desktop builds, but in this section we'll concentrate on running them on a real device, as real devices are always best where possible.

-

Note that this test is destructive and as such, you should back up anything you care about on the phone before running these tests. Depending on which tests you run, they can also make phone calls. So be aware that you want to be very careful about what you run and how you back up the phone, remove the SIM card, etc.  That said, if you've already created an engineering build they are really easy to get running. Here's how.

-

One Time Set up

-

You only need to perform the following steps once, assuming you do not change the location of your Gaia directory. Create a python virtualenv (install the virtualenv tool first if you haven't already), activate it, and install the gaia UI test tool into your virtualenv. By creating the virtual environment using the steps below, you ensure that you are running the gaia UI test harness code that lives in your Gaia repo (that's useful in case you need to debug anything).

-
$ virtualenv gaia_ui_venv # This will create a gaia_ui_venv directory where the virtual environment lives. It can be anywhere on your system.
-$ source gaia_ui_venv/bin/activate # This activates our virtualenv
-(gaia_ui_venv)$ cd <b2groot>/gaia/tests/python/gaia-ui-tests;python setup.py develop # This installs the gaia ui harness into your virtual environment. 
-

If you have already created a virtual environment for gaia ui tests, you can simply do the following:

-
$ source gaia_ui_venv/bin/activate
-

To Run the Tests

-

First you need to create the testvars file. To do this, copy the standard one over, and add in the attributes to turn off the warnings that this test will destroy all content on your phone. These are good tests, they leave no state around and as such, you will need to make sure your phone is backed up before running them. Instructions from here on will assume you've activated the virtual environment and are working in the gaia/tests/python/gaia-ui-tests directory.

-
(gaia_ui_venv)$ cp gaiatest/testvars_template.json testvars.json
-# Now edit your copy of testvars.json and add in the following attributes into the json:
-"acknowledged_risks": true,
-"skip_warning": true,
-

Now you just need to connect our phone via USB, forward the marionette port so your test runner can access it and run our tests. The tests are in gaiatest/tests and you can pick whichever one you want to run. For example, if you wanted to run contacts tests you would do the following:

-
(gaia_ui_venv)$ adb forward tcp:2828 tcp:2828
-(gaia_ui_venv)$ gaiatest --testvars=testvars.json --address=localhost:2828 gaiatest/tests/functional/contacts/
-
-

注意: To find out what UI tests are available, browse through the gaiatest directories inside the Gaia repo.

-
-

To get out of the python virtualenv, just use the special virtualenv command deactivate:

-
(gaia_ui_venv)$ deactivate
-$
-
-

注意: To learn more about the Gaia UI Tests and find more detailed information, move on to the Gaia UI Tests pages.

-
-

运行 Gaia 集成测试

-

To run the Gaia Integration tests tests you currently have to use a B2G Desktop build (note that these are also going to be available for devices soon as well). Let's look at how this is done.

-

These just require a Gaia tree and NodeJS to be installed on your computer; the following command will do the rest:

-
$ cd gaia $ make test-integration 
-

That's it — this instruction will download a B2G desktop build, and start running the tests in that build.

-
-

注意: To learn more about Gaia Integration Tests, read the Gaia Integration Tests Github repo.

-
-
-

注意: To find out what integration tests are available, look in the apps directory in the Gaia repo; integration tests can be found in test/marionette/ subfolders.

-
-

总结

-

As always, work is underway to make all our tests easier to run both locally for developers as well as in our automation systems. Feel free to drop into the #ateam channel any time you have questions about test automation for Firefox OS or any of the Mozilla automation tools.

diff --git a/files/zh-cn/archive/b2g_os/screencast_series_colon__app_basics_for_firefox_os/index.html b/files/zh-cn/archive/b2g_os/screencast_series_colon__app_basics_for_firefox_os/index.html deleted file mode 100644 index 4193506bed..0000000000 --- a/files/zh-cn/archive/b2g_os/screencast_series_colon__app_basics_for_firefox_os/index.html +++ /dev/null @@ -1,219 +0,0 @@ ---- -title: 'Screencast series: App Basics for Firefox OS' -slug: 'Archive/B2G_OS/Screencast_series:_App_Basics_for_Firefox_OS' -translation_of: 'Archive/B2G_OS/Firefox_OS_apps/Screencast_series:_App_Basics_for_Firefox_OS' ---- -
-

Firefox OS is an operating system that brings the Web to mobile devices. Instead of being a new OS with new technologies and development environments it builds on standardised web technologies that have been in use for years now. If you are a web developer and you want to build a mobile app, Firefox OS gives you the tools to do so, without having to change your workflow or learn a totally new development environment. In this collection of short videos, developers from Mozilla and Telenor met in Oslo, Norway to explain in a few steps how you can get started to build applications for Firefox OS.

-
- -

In this series you’ll learn:

- - - -
-

Note: Each of the screencasts is short enough to get through in a short break; the whole series should not take more than an hour to watch.

-
- -

Code and development environment

- -

In addition to the screencasts, you can download the accompanying code samples from GitHub. If you want to try the code examples out for yourself, you will need to set up a very simple development environment. All you need is:

- - - -

Introducing the series

- -

The series features Jan Jongboom (@janjongboom) and Sergi Mansilla (@sergimansilla) of Telenor Digital, and Chris Heilmann (@codepo8) of Mozilla; it was shot in three days in Oslo, Norway at the Telenor head office in February 2014.

- -

Here are the three of us telling you about the series and what to expect:

- -

- -

Section 1: Building your first Firefox OS app and getting it published

- -

In Section 1's five screencasts we show you how to build a Firefox OS application, how to debug and test it on your computer — and on a real device, and how to get it listed in the Firefox Marketplace. This may sound like a lot of work, but you will soon find out that if you already know how to build a website, you are 90% of the way there already.

- -

More than a website

- -

Firefox OS applications are HTML5 applications. In essence, these use the same technologies as websites do. You can start writing a website and turn it into an app simply by giving it a manifest file (see The app manifest for more details). This tells Firefox OS that you are writing an app and allows you to:

- - - -

In essence, HTML5 applications are supercharged websites and should follow the same rules, such as:

- - - -

The main difference is that for a web page to become a great application, you should very much consider mobile users. This means first and foremost that your application should:

- - - -

In many cases, this means you need to slim your web page down a bit and simplify the interface. The good news is that all your users will benefit from that.

- -

- -
-

Note: To find out more about how to design a good HTML5 App, check out the App Center on MDN.

-
- -

The app manifest

- -

The App Manifest in Firefox OS is a simple JSON file that tells the operating system about your app. In essence, this is what turns a web page into an Open Web App. In it, you define the name in different locales and you ask the operating system to get access to various services and hardware. You can also define the preferred orientation of your app and — if needed — lock it.

- -

- -

More information about the manifest and tools that can help you:

- - - -

The App Manager

- -

The simplest way to get started with Firefox OS is to try out the App Manager. This tool stands alongside the Firefox developer tools for desktop and allows you to connect to a Firefox OS simulator running on your computer, or a real Firefox OS device if you have one available. From there, you can play with Firefox OS, install apps straight onto the simulator or real device, and debug them as they are running on Firefox OS — seeing the live changes immediately without needing to uninstall or update apps.

- -

The following video provides first steps with using the App Manager along with the simulator:

- -

- -
-

Note: The App Manager allows you to debug your own applications even when you're offline, without any hassle.

-
- -

More information about the App Manager:

- - - -

Testing on a Real Device

- -

Testing your applications in the simulator is nice, but it only gets you as far as a simulated environment can. If you want to test the performance of the app interaction, or react to things like device orientation, you need a real device. Together with the developer tools and the App Manager, you can use the device and get detailed insight into what happens to your application as you use it.

- -

- -

Publishing to Marketplace

- -

The Firefox OS Marketplace is the most convenient place to list your application and make it available to people on their devices and the Web. The Marketplace also allows you to list your app for other platforms like Firefox Desktop and Firefox for Android. You can also allow users to rate your app, give you feedback, and buy your application using a simple checkout process. Getting your app listed is simple:

- - - -

- -

Applications submitted to the Marketplace are reviewed by Mozilla's app review team and you will be notified of the state of your submission within a few days. If there are issues with your application you will get a validation message during the submission but you might also get a human readable explanation of what is wrong and how to fix it.

- -
-

Note: Read Submitting an application to the Firefox Marketplace for more information about the submittion process.

-
- -

Section 2: Advanced Firefox OS topics

- -

In the first few videos we introduced you to Firefox OS and how to build your first app. We also covered how to debug your application on desktop — and on a real device — and how to get your app listed in the Firefox Marketplace. In the remaining five videos we’ll deep-dive into the technologies that enable Firefox OS apps to go that extra mile and give you access to the functionality that makes developing for a smartphone or tablet interesting to developers. Whilst some of these technologies are currently only working in Firefox OS, they are all open source and submitting as standards proposals. Working with these APIs today will mean you are ready for other devices and platforms emerging in the near future.

- -

Web APIs

- -

Smartphones are full of great technology — cameras, accelerometer, and GPS to name but a few. The problem was that all of these were not accessible by web technologies — if you wanted to access them, you needed to write native applications. To fix this, Mozilla and partners defined a set of APIs to allow developers to reach deep into the hardware of a mobile devices using JavaScript in a secure manner. These are called Web APIs and are defined in the open and available for others to implement. Firefox OS is the first platform that uses them; the below screencast explains more:

- -

- -

More information about Web APIs:

- - - -

Web Activities

- -

Web Activities are an alternative way to access the hardware of a device. Instead of getting an API to speak to the device directly, Web Activities allow you to create an ecosystem of applications on the device that talk to each other and share capabilities. For example, instead of trying to access the camera directly, your app can use a Web Activity to ask for an image and the user of the device can use their favourite application to take a photo, which is then returned to the app that requested it.

- -

Instead of asking the users for access to their hardware (which is important in terms of security), you allow them to use applications they already trust to carry out such functions. Furthermore, you can register your application as the go-to application for certain tasks in the operating system. You can think of Web Activities as being equivalent to right/Ctrl + clicking on a file in a Desktop OS and choosing which application to open the file with. You are given several choices, plus on option to tell the OS to always use this app to open this file type from now on.

- -

Web Activities allow apps to talk to each other — on the device, without any need for a server in between. All they transmit from one app to the other is the final data.

- -

- -

More information about Web Actitivies:

- - - -

Push Notifications

- -

Push Notifications — invoked using the SimplePush Web API — are a way to make applications wake up when a device receives a certain message. This allows you to build applications that can stay closed — thus saving battery — until they are needed. Notifications created this way also have the benefit of carrying no data, thus Mozilla will never get the information of your app and attackers won't be able to listen in.

- -

- -

More information about Push Notifcations using SimplePush:

- - - -

Offline functionality

- -

Apps are not much use if they don't work offline. That's partly why users prefer installed apps to just opening a browser and looking for content on their device's web browser; the term "web application" even sounds like it needs a web connection to be usable. Our users will be offline sometimes — on a plane, underground or with no data left on their SIM — and we need to ensure that our apps are still usable when this happens. HTML5 offers a few technologies that allow for offline functionality, mainly AppCache and DOMStorage.

- -

- -

More information about offline functionality:

- - - -

Where to find more

- -

We hope that this video series gave you a clear introduction to building your first open web apps. If you are interested in learning more, there are a few resources and channels you can use:

- -

- - - -

Hope to see you there,

- -

Chris, Sergi and Jan

diff --git a/files/zh-cn/archive/b2g_os/security/application_security/index.html b/files/zh-cn/archive/b2g_os/security/application_security/index.html deleted file mode 100644 index cb986bfc9d..0000000000 --- a/files/zh-cn/archive/b2g_os/security/application_security/index.html +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: 应用安全 -slug: Archive/B2G_OS/Security/Application_security -translation_of: Archive/B2G_OS/Security/Application_security ---- -
-

本文对Firefox OS 应用安全进行了详细阐述。

-
-

由Firefox OS 引入的关键性Web应用控制包含如下几个方面: 

- -

应用安全

-

FirefoxOS 支持三种类型的web应用: "web", "privileged" 以及 "certified".一个应用的类型是在它的  manifest 中声明的,同时也就决定了它能请求的权限列表。 

- -
-

注意: 要进一步的了解这三种类型,可以参考 App Manifest 文档。

-
-

应用交付

-

在Firefox OS 中,应用可以通过托管和打包这两种不同的机制交付。常规的web应用可以使用任何一种方式交付,而 privileged 和 certified 应用则必须要打包才能交付。

-

托管的应用

-

托管的应用程序中在开发者web服务器中只包含一个应用程序manifest文件,而这个文件会指向应用的index文件(通常会被称作安装路径)。通常manifest文件也会指向一个appcache manifest文件:这个文件会将应用的信息缓存起来,从而使应用启动时更加快速而且能够离线使用;同时这个文件在其他方面则不会对应用造成任何影响。 从安全的角度来看,托管的应用更像是通常的web站点。当托管应用加载时,加载页面的URL其实就是这些页面在它们web服务器的一般的URL地址。因此要链接应用中一个特定的页面或资源, 使用的URL地址与在web站点链接到那个页面的URL地址是相同的。

-

打包的应用

-

一个打包的应用 是一个开放的Web应用,会在本地zip文件中存放有关应用的所有资源(包括  HTML, CSS, JavaScript, app manifest 等) contained in a zip file, 而不是将资源存放在web服务器上。要了解更多的细节,可参考 Packaged apps

-

应用安装

-

应用是通过 Apps Javascript API 来安装的:

- -

为了能保证一个应用能够想要作为一个web应用来安装,我们必须确保不能使一个网站假冒托管的应用程序清单。 我们会要求manifest要提供一个具体的mime-type application/x-web-app-manifest+json。当manifest应用和和应用 manifest请求的页面相同,都是请求应用安装的页面时,这种限制才是放开的。

-

更新

-

有关应用更新的过程是在 Updating apps 有详细描述。

-

权限

-

应用可以被授予在正常的网页最高权限之外的权限。默认情况下,应用会和正常的web页面拥有同样的权限,为了能够得到额外的权限,第一步就是在应用程序maifest文件中列出它想要的额外权限。 

-

Manifest 声明

-

对每一个应用需要的额外权限,manifest文件必须要在manifest中列出该权限,并且以人类可阅读的描述解释为什么应用需要访问这个权限。例如,如果应用需要使用 navigator.geolocation API, 它就必须在manifest中如下声明:

-
"permissions": {
-  "geolocation":{
-    "description": "Required for autocompletion in the share screen",
-  }
-},
-
-

This allows the app to then prompt for the geolocation permission, in the same way that a web page normally would. For further detail on manifests, see App manifest.

-
-

Note: Currently permissions usage intentions are not exposed to the user — see bug 823385.

-
-

授予权限

-

When permissions are requested in the manifest, the permission is either set to allow or prompt, depending on the permissions. Allow permissions are granted by virtue of being declared in the manifest with no further approval needed. For prompt permissions, the user is prompted the first time the user accesses the related API, and has to make a choice prior to the API being granted. In general, Firefox OS only prompts users for permissions that have a privacy impact, and it is reasonable for the user to understand what they are being asked. For example, access to contacts is prompted, but access to make a raw TCP connection is implicitly granted since it is not reasonable for a user to understand the security implications of allowing this permission. Use of allow permissions is reviewed as part of Marketplace security review processes to ensure users are protected.

-

撤销权限

-

Users are allowed to change their mind about prompt permissions at any time, and can revoke these permissions via the Firefox OS settings app. Allow permissions are not user configurable, however.

-

Web 应用沙箱

-

Data stored per app

-

Each app runs in as a separate sandbox, meaning that all data stored by an app is separate from all data stored by another app. This includes things like cookie data, localStorage data, indexedDB data, and site permissions.

-

A diagram showing three Firefox OS apps all open is separate sandboxes, so none of them can affect each other.

-

This means that if the user has two apps installed, App A and App B, these apps will have a completely different set of cookies, different local data, and different permissions. This even applies if both of these apps open an <iframe> that points to the same origin. i.e. if both App A and App B open an <iframe> pointing to "http://www.mozilla.org", they will both render the website, however the website will be fetched and rendered with different cookies in the two apps.

-

A result of this is that if the user logs in to, for example, Facebook while using App A, this in no way affects App B's ability to interact with the user's account on Facebook. The login cookie that Facebook sets when the user logs in using App A is only available in App A. If App B opens an <iframe> to Facebook, the cookie wouldn't be there and so when App B opens Facebook, it receives the Facebook login page rather than the user's account.

-

Apps can't open each other

-

This means that apps can't open other apps by using iframes. If App A creates an <iframe> with the src set to the URL of App B, this won't actually open App B in the <iframe>. It will simply open the website located at that URL. It will not use any of App B's cookies and so it will behave no differently than if App B wasn't installed on the user's device.

-

This applies even for packaged apps (more about them below). If App A tries to open the packaged App B using an <iframe> pointing to the app:// URL of App B, this will simply fail to load. If this results in a 404 or some other type of error is still to be determined, but it will definitely fail to load. And it will fail in the same way no matter if App B is installed on the user's device or not, as to make it impossible for App A to determine if App B is installed.

-

The same thing happens if the top-level frame of App A is navigated to a URL for App B. We always know for a given frame which app is opened in it, therefore when attempting to load the App B URL in the App A frame, this will behave exactly like the two situations described above, i.e. in no way will App B's resources, like cookies or other local data, be used.

-

Motivation

-

There are both benefits and downsides to this approach. The downside is that if the user interacts with the same web site through several apps, he/she will have to log in to every app. Likewise, if a web site wants to store data locally, and the user interacts with this web site in several apps, the data will end up getting duplicated in each app, which could be a problem if it's a large amount of data.

-

The main benefit of this approach is that it's a more stable model. There is no way that several apps could interact with each other through a third-party website in unexpected ways such that installing an app causes another app to stop working. When an app is uninstalled there is no way that data for another app could be lost, or that another app will stop working due to functional dependence on the uninstalled app.

-

There are also large security benefits. A user can safely use his AwesomeSocial app to log in to Facebook without having to worry that the SketchGame app can mount any type of attack for getting at the user's Facebook data by exploiting bugs or other shortcomings in the Facebook web site.

-

There are also good privacy benefits. The user can safely install the PoliticalPartyPlus app without having to worry that MegaCorpEmployeeApp will be able to detect that the app was installed or what data it has created.

-

Sandboxed 权限

-

In the same way that web site data is sandboxed per app, so is permission data. If App A loads a page from http://maps.google.com and that page requests to use geolocation and the user says "yes, and remember this decision for all times", this only means that http://maps.google.com has access to geolocation within App A. If App B then opens http://maps.google.com, that page won't have access to geolocation unless the user grants that permission again.

-

And just like in the normal browser, permissions are separated by origin. If App A is granted permission to use Geolocation, this does not mean that all origins running in App A have the permission to use Geolocation. If App A opens an <iframe> to http://maps.google.com, then http://docs.google.com still has to ask the user for permission before geolocation access is granted.

-

浏览器 API 沙箱

-

To additionally secure applications that open a large set of URLs, such as browsers, we have added a browserContent flag. The browserContent flag allows each app to have not one, but two sandboxes: one for the app itself, and one for any "web content" that it opens. For example:

-

Say that the MyBrowser app is loaded from the https://mybrowser.com domain. This is the domain the scripts and resources are loaded within. The scripts and resources - - belong - to this domain.

-

Now, if a page in this app creates an <iframe mozbrowser>, a different sandbox is created and used for this <iframe>, which is different from the sandbox used by the app. So for example if this <iframe> is navigated to https://mybrowser.com, it will result in different cookies being used inside the <iframe mozbrowser>. Likewise, the contents inside the <iframe mozbrowser> will see different IndexedDB and localStorage databases from the ones opened by the app.

-

This also applies if the MyBrowser app wants to create integration with, for example, Google Maps to implement location-based browsing. If the app opens an <iframe> to http://maps.google.com, it will receive a set of cookies for the http://maps.google.com website. If the user then navigates inside the <iframe mozbrowser> containing http://maps.google.com, this will use different cookies and different permissions to the top level app.

-

Another example where this is useful is in a Yelp-like app. Yelp has the ability to visit a restaurant's website directly in the app. By using <iframe mozbrowser> to open the restaurant website, the Yelp app ensures that the restaurant website can't contain an <iframe> pointing back to Yelp's app (which points to http://yelp.com). If it does, the website will only receive the Yelp website, rather than the Yelp app. So there is no way that the restaurant website can mount an attack against the app since the contained Yelp website won't share any permissions or data with the Yelp app.

-

应用安全小结

-

The table below summarizes the different types of Firefox OS apps, and describes the format, installation, and update processes for open web apps running on Firefox OS.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Web App Types
TypeDeliveryPermission ModelInstallationUpdates
WebHosted or PackagedLess sensitive permissions, which are not dangerous to expose to unvalidated web content.Installed from anywhereCan be updated transparently to user or explicitly via a marketplace, depending on where the app was installed from, and the delivery mechanism.
PrivilegedPackaged & SignedPrivileged APIs requiring validation and authentication of the app.Installed from a trusted marketplaceUpdated via a trusted marketplace, user prompted to approve download and installation of updates.
CertifiedPackagedPowerful and dangerous APIs not available to third-party apps.Pre-installed on the deviceUpdated only as part of system level updates.
-
-

Note: For version 1.0 of Firefox OS, although web apps can be installed from any website/marketplace, privileged apps can only be installed from the Mozilla Marketplace, as support for multiple trusted marketplaces is not yet complete.

-
-

 

diff --git a/files/zh-cn/archive/b2g_os/security/index.html b/files/zh-cn/archive/b2g_os/security/index.html deleted file mode 100644 index 18730f4b81..0000000000 --- a/files/zh-cn/archive/b2g_os/security/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: Firefox OS security -slug: Archive/B2G_OS/Security -tags: - - B2G - - Firefox OS - - Mobile - - NeedsTranslation - - Security - - TopicStub -translation_of: Archive/B2G_OS/Security ---- -

下面文章介绍了 Firefox OS 安全相关的主题。其中包括安全特征概要,应用安全以及如果使安装进程保证安全。

- - - - - - - -
-

Firefox OS 安全文档 

-
-
- Firefox OS 安全模型
-
- Firefox OS 安全模型
-
- 系统安全
-
- FirefoxOS 运行时内部的安全控制细节
-
- Firefox OS 中的应用安全
-
- 在 Firefox OS 如何使应用安全概要
-
- 安全安装和更新应用
-
- Firefox OS 如何安全的安装和更新应用
-
- 对 Firefox OS 的调试和安全测试 
-
- 本指南介绍了基本的安全测试步骤,从打开远程的 JavaScript 调试器到在Firefox OS 桌面版本中设置一个拦截 HTTP(S) 代理
-
-

查看全部...

-
-

从社区获得帮助

-

如果您正在为 Firefox OS 工作或者开发一个运行在 Firefox OS 设备上的应用,这里有一些社区资源可以帮助您!

- -

不要忘记提问的艺术...

-
- - -
-

 

-
-
- Firefox OS
diff --git a/files/zh-cn/archive/b2g_os/security/security_model/index.html b/files/zh-cn/archive/b2g_os/security/security_model/index.html deleted file mode 100644 index f7c2247523..0000000000 --- a/files/zh-cn/archive/b2g_os/security/security_model/index.html +++ /dev/null @@ -1,285 +0,0 @@ ---- -title: Firefox OS security overview -slug: Archive/B2G_OS/Security/Security_model -tags: - - B2G - - Firefox OS - - IPC - - IPDL - - Mobile - - 安全 - - 指南 -translation_of: Archive/B2G_OS/Security/Security_model ---- -
-

本文对 Mozilla Firefox OS 安全架构进行了概述,包括包括保护移动设备不受平台, apps 和 数据的威胁。在 Firefox OS 中,Mozilla 实现了完整,多层次的安全模型,为移动电话提供了绝佳的防护效果。

-
-

平台安全

-

Firefox OS 平台使用了多层次的安全模型,可将各层级的开发风险降至最低。第一线的保护机制与深入防护策略相结合,进而为移动电话提供了完成的防护效果。

-

安全架构

-

Firefox OS 将基于网页的应用与底层的硬件结合起来了。这个集成技术栈包括下面几个等级:

-

- -

Gecko 扮演的是守门人的角色,为避免对移动设备的误用,它会强制执行安全策略。 Gecko 层 web  apps(Gaia 层)与 手机之间的中间阶层。Gonk 则可将移动手机底层的硬件功能直接给 Gecko 层使用。 只有在 Gecko 允许访问请求时, Web apps 才可以通过 Web APIs 访问移动手机的功能 — 而不会有直接存取或走后门的情况产生。Gecko 会强制执行权限并阻止对未授权请求的访问。

-

部署安全系统

-

将 Firefox OS 安装在智能手机上。原始系统的镜像文件是由已知,可信任的源所创建的 — 通常是设备 OEM — 它主要负责装配 构建 测试对发布包进行签名。

-

整个技术层都需要经过安全验证。文件系统权限检查是由 Linux's 访问控制清单 (ACLs) 所强制执行的。系统应用都安装在一个只读的空间中(除了更新过程外,这是可能是短暂的可读写的);一般而言,只有包含用户内容的区域才可能可读写。Various components within the device hardware have built-in protections that are implemented by default as standard industry practice — chipset manufacturers, for example, employ hardening techniques to reduce vulnerabilities. The core platform (Gecko and Gonk) is hardened to strengthen its defense against potential threats, and hardening features of the compiler are used where applicable. For further details see Runtime security.

-

更新安全系统

-

Subsequent upgrades and patches to the Firefox OS platform are deployed using a secure Mozilla process that ensures the ongoing integrity of the system image on the mobile phone. The update is created by a known, trusted source — usually the device OEM — that is responsible for assembling, building, testing, and digitally signing the update package.

-

System updates can involve all or a portion of the Firefox OS stack. If changes to Gonk are included in the update, then FOTA (Firmware Over the Air) is the install process used. FOTA updates can also include any other part of the Firefox OS stack, including device management (FOTA, firmware / drivers), settings management (Firefox OS settings), security updates, Gaia, Gecko, and other patches.

-

Updates that do not involve Gonk can be done using the Mozilla System Update Utility. Firefox OS uses the same update framework, processes, and Mozilla ARchive (MAR) format (used for update packages) as the Firefox Desktop product.

-

A built-in update service — which may be provided by the OEM — on the mobile phone periodically checks for system updates. Once a system package becomes available and is detected by the update service, the user is prompted to confirm installation. Before updates are installed on the mobile device, the device storage is checked for sufficient space to apply the update, and the distribution is verified for:

- -

在更新过程中会使用下面的安全措施:

- -

Rigorous checks are in place to ensure that the update is applied properly to the mobile phone.

-
-

Note: For more information on how thee updates work and how to create and distribute updates, read Creating and applying Firefox OS update packages.

-
-

App 安全

-

Firefox OS uses a defense-in-depth security strategy to protect the mobile phone from intrusive or malicious applications. This strategy employs a variety of mechanisms, including implicit permission levels based on an app trust model, sandboxed execution at run time, API-only access to the underlying mobile phone hardware, a robust permissions model, and secure installation and update processes. For technical details, refer to Application security.

-

In Firefox OS, all applications are web apps — programs written using HTML5, JavaScript, CSS, media, and other open web technologies (pages running within the browser are not referred to as web apps in this context). Because there are no binary ("native") applications installed by the user, all system access is mediated strictly through the Web APIs. Even access to the file system happens only through Web APIs and a back-end SQLite database — there is no direct access from apps to files stored on the SD card.

-

Firefox OS limits and enforces the scope of resources that can be accessed or used by an app, while also supporting a wide range of apps with varying permission levels. Mozilla has implemented tight control over what type of applications can access which APIs. For example, only certified apps (shipped with the phone) can have access to the Telephony API. The Dialer app has privileges to access the Telephony API in order to make phone calls, but not all certified apps can access this API.

-

This prevents a situation, for example, in which an arbitrary third-party app gets installed, dials a pay-per-use phone number (900 and 910), and racks up a large cell phone bill.

-

Other OEM apps might be selectively given access to the Telephony API, however. For example, an operator might provide a systems management application that allows a customer to manage their account, including the ability to phone the Operator’s billing or support office directly.

-

受信任(Trusted)和不受信任 (Untrusted)的 App

-

Firefox OS 根据下面的类型对 app 进行分类

- - - - - - - - - - - - - - - - - - - - - - - - - -
-

Type

-
-

Trust Level

-
-

Description

-
-

Certified

-
-

Highly Trusted

-
-

System apps that have been approved by the Operator or OEM (due to risk of device corruption or risk to critical functionality). System apps and services only; not intended for third-party applications.
- This designation is reserved for just a small number of critical applications. Examples: SMS, Bluetooth, camera, system clock, telephony, and the default dialer (to ensure that emergency services are always accessible).

-
-

Privileged

-
-

Trusted

-
-

Third-party apps that have been reviewed, approved, and digitally signed by an authorized Marketplace.

-
-

Web (everything else)

-
-

Untrusted

-
-

Regular web content. Includes both installed apps (stored on the mobile phone) and hosted apps (stored remotely, with only an app manifest stored on the mobile phone). The manifest for hosted apps can be obtained through a Marketplace.

-
-

An application’s trust level determines, in part, its ability to access mobile phone functionality.

- -

Some operations, such as network access, are assumed to be an implicit permission for all apps. In general, the more sensitive the operation (for example, dialing a phone number or accessing the Contacts list), the higher the app trust level required to execute it.

-
-

注意: for more information on the APIs available and their permission levels, consult App permissions.

-
-

Principle of Least Permissions

-

For web apps, the Firefox OS security framework follows the principle of least permissions: start with the absolute minimum permissions, then selectively grant additional privileges only when required and reasonable. By default, an app starts with very low permissions, which is comparable to untrusted web content. If the app makes Web API calls that require additional permissions, it must enumerate these additional permissions in its manifest (described later in this document). Gecko will consider granting Web API access to an application only if the applicable privileges are explicitly requested in its manifest. Gecko will grant the requested permission only if the type of the Web App (certified, trusted, or web) is sufficiently qualified for access.

-

Review Process for Privileged Apps in the Marketplace

-

In order for an app to become privileged, the app provider must submit it for consideration to an authorized Marketplace. The Marketplace subjects the app to a rigorous code review process: verifying its authenticity and integrity, ensuring that requested permissions are used for the purposes stated (in the permission rationale), verifying that the use of implicit permissions is appropriate, and validating that any interfaces between privileged app content and unprivileged external content have the appropriate mitigations to prevent elevation of privilege attacks. The Marketplace has the responsibility to ensure that the web app will not behave maliciously with the permissions that it is granted.

-

After an app passes this review, it is approved for use, its app manifest is digitally signed by the Marketplace, and it is made available for mobile users to download. The signature ensures that, if the web store were somehow hacked, the hacker could not get away with installing arbitrary content or malicious code on users’ phones. Due to this vetting process, Firefox OS gives privileged apps obtained from a Marketplace a higher degree of trust than everyday (untrusted) web content.

-
-

Note: to find out more about Marketplaces including the Firefox Marketplace, go to the Marketplace zone.

-
-

封装式(Packaged)和托管式(Hosted) Apps

-

Apps for Firefox OS can be either packaged (stored on the mobile phone) or hosted (stored on a remote web server, with just a manifest stored on the mobile phone). There are some differences in the way in which security is managed for each. Nonetheless, packaged and hosted apps are both subject to application sandboxing, which is described later in this document.

-
-

Note: You can find out more about hosted and packaged apps at App publishing options.

-
-

封装式(Packaged) Apps

-

A packaged app consists of a ZIP file containing application resources (HTML5, CSS, JavaScript, images, media), as well as a manifest that provides an explicit list of assets and their corresponding hashes. Certified and privileged apps must be packaged apps because the app manifest needs to be digitally signed. When a user obtains a packaged app, the ZIP file is downloaded onto the mobile phone, and the manifest is read from a known location inside the ZIP file. During the install process, app assets are verified and remain stored locally in the package. All explicit permissions are requested at runtime, showing the user the app's data usage intentions, and persisted by default.

-

To refer to app resources in a packaged app, the URL begins with app: using the following format:

-

app://identifier/path_within_zipfile/file.html

-

where app:// represents the mount point for the ZIP file, and identifier is a UUID that is generated when the app is installed on the mobile phone. This mechanism ensures that resources referred to with an app: URL are contained in the ZIP file. The path within an app: is relative, so relative links to resources in the ZIP file are allowed.

-

While packaged apps are primarily intended to be used for Certified or Privileged apps, regular web apps can also be packaged. However, they do not gain any increase in trust or permissions access simply because they are packaged.

-

托管式(Hosted) Apps

-

Hosted apps are located on a web server and loaded via HTTP. Only the app manifest is stored on the mobile phone. Everything else is stored remotely. Certain APIs are available only to privileged and certified apps, which requires the app to be packaged due to signing requirements. Therefore, a hosted app will not have access to any of the Web API operations that require privileged or certified app status.

-

From a security point of view, hosted apps work very much like normal websites. A hosted app is loaded by invoking a hard-coded, fully-qualified URL that points to the startup page in the root directory of the app on that web server. Once a hosted app is loaded, the mobile phone links to pages using the same URLs that are used when browsing the web site.

-

App Manifest

-

An Open Web App manifest contains information that a Web browser needs in order to interact with an app. A manifest is a JSON file with (at a minimum) a name and description for the app. For further details, refer to FAQs about app manifests.

-

Manifest 示例

-

The following code listing shows an example manifest with just basic settings:

-
{
-  "name": "My App",
-  "description": "My elevator pitch goes here",
-  "launch_path": "/",
-  "icons": {
-    "128": "/img/icon-128.png"
-  },
-  "developer": {
-    "name": "Your name or organization",
-    "url": "http://your-homepage-here.org"
-  },
-  "default_locale": "en"
-}
-

App Manifest 的安全设置

-

The manifest can also contain other settings, including the following security settings:

- - - - - - - - - - - - - - - - - - - - - - - - - -
-

Field

-
-

Description

-
-

permissions

-
-

Permissions required by the app. An app must list every Web API it intends to use that requires user permission. Most permissions make sense for privileged apps or certified apps, but not for hosted apps. Properties per API:

-
    -
  • description: A string specifying the intent behind requesting use of this API. Required.
  • -
  • access: A string specifying the type of access required for the permission. Implicit permissions are granted at install time. Required for only a few APIs. Accepted values: read, readwrite, readcreate, and createonly.
  • -
-
-

installs_allowed_from

-
-

The Origin of the app; can be singular or an array of origins (scheme+unique hostname) that are allowed to trigger installation of this app. Allows app providers to restrict installs from only an authorized Marketplace (such as https://marketplace.firefox.com/).

-
-

csp

-
-

Content Security Policy (CSP). Applied to all pages loaded in the app. Used to harden the app against bugs that would allow an attacker to inject code into the app. If unspecified, privileged and certified apps have system-defined defaults. Syntax:
- https://developer.mozilla.org/en-US/docs/Apps/Manifest#csp

-

Note that this directive can only increase the CSP applied. You cannot use it, for example, to reduce the CSP applied to a privileged App.

-
-

type

-
-

Type of application (web, privileged, or certified).

-
-

Firefox OS requires that the manifest be served with a specific mime-type (application/x-web-app-manifest+json) and from the same fully-qualified host name (origin) from which the app is served. This restriction is relaxed when the manifest app (and thus the app manifest) is same-origin with the page that requested the app to be installed. This mechanism is used to ensure that it's not possible to trick a website into hosting an application manifest.

-

沙盒技术 Sandboxed Execution

-

This section describes application and execution sandboxes.

-

Application Sandbox

-

The Firefox OS security framework uses sandboxing as a defense-in-depth strategy to mitigate risks and protect the mobile phone, platform, and data. Sandboxing is a way of putting boundaries and restrictions around an app during run-time execution. Each app runs in its own worker space and it has access only to the Web APIs and the data it is permitted to access, as well as the resources associated with that worker space (IndexedDB databases, cookies, offline storage, and so on).

-

The following figure provides an overview of this security model.

-

-

By isolating each app, its impact is contained within its own worker space and it cannot interfere with anything (such as other apps or their data) outside of that worker space.

-

Execution Sandbox

-

B2G (Gecko) runs in a highly-privileged system process that has access to hardware features in the mobile phone. At runtime, each app runs inside an execution environment that is a child process of the B2G system process. Each child process has a restricted set of OS privileges — for example, a child process cannot directly read or write arbitrary files on the file system. Privileged access is provided through Web APIs, which are mediated by the parent B2G process. The parent ensures that, when a child process requests a privileged API, it has the necessary permission to perform this action.

-

Apps communicate only with the B2G core process, not with other processes or apps. Apps do not run independently of B2G, nor can apps open each other. The only “communication” between apps is indirect (for example, when one app sets a system alarm and another app triggers a system notification as a result of it), and is mediated through the B2G process.

-

仅通过 Web API 才能硬件访问

-

Web apps have only one entry point to access mobile phone functionality: the Firefox OS Web APIs, which are implemented in Gecko. Gecko provides the sole gateway to the mobile device and underlying services. The only way to access device hardware functionality is to make a Web API call. There is no “native” API and there are no other routes (no “back doors”) to bypass this mechanism and interact directly with the hardware or penetrate into low-level software layer.

-

安全基础架构

-

The following figure shows the components of the Firefox OS security framework:

-

- -

权限管理与执行

-

Firefox OS security is designed to verify and enforce the permissions granted to web apps.

-

The system grants a particular permission to an app only if the content requests it, and only if it has the appropriate permissions requested in the app’s manifest. Some permissions require further authorization from the user, who is prompted to grant permission (as in the case of an app requesting access to the user’s current location). This app-centric framework provides more granular control over permissions than traditional role-centric approaches (in which individual roles are each assigned a set of permissions).

-

A given Web API has a set of actions and listeners. Each Web API has a required level of permission. Every time a Web API is called, Gecko checks permission requirements (role lookup) based on:

- -

If the request does not meet the permission criteria, then Gecko rejects the request. For example, untrusted apps cannot execute any Web APIs that are reserved for trusted apps.

-

要求用户权限许可

-

In addition to permissions that are implicitly associated with the web apps, certain operations require explicit permission from the user before they can be executed (for example, "can the web app access your camera?"). For these operations, web apps are required to specify, in their manifest, their justification for requiring this permission. This data usage intention informs users about what the web app intends to do with this data if permission is granted, as well as any risk involved. This allows users to make informed decisions and maintain control over their data.

-

安全 App 更新过程

-

-

For app upgrades and patches to a privileged app, app providers submit the updated package to an authorized Marketplace, where it is reviewed and, if approved, signed and made available to users. On Firefox OS devices, an App Update Utility periodically checks for app updates. If an update is available, then the user is asked whether they want to install it. Before a update is installed on the mobile device, the package is verified for:

- -

Rigorous checks are in place to ensure that the update is applied properly to the mobile phone. The complete update package must be downloaded in a specific and secure location before the update process begins. Installation does not overwrite any user data.

-
-

Note: For more information on app updates, read Updating apps.

-
-

设备安全 (硬件)

-

Security mechanisms for the mobile device hardware are typically handled by the OEM. For example, an OEM might offer SIM (Subscriber Identity Module) card locks, along with PUK (PIN Unlock Key) codes to unlock SIM cards that have become locked following incorrect PIN entries. Contact your OEM for details. Firefox OS does allow users to configure passcodes and timeout screens, which are described in the next section.

-

数据安全

-

Users can store personal data on their phone that they want to keep private, including contacts, financial information (bank & credit card details), passwords, calendars, and so on. Firefox OS is designed to protect against malicious apps that could steal, exploit, or destroy sensitive data.

-

密码和超时锁屏

-

Firefox OS allows users to set a passcode to their mobile phone so only those who supply the passcode can use the phone. Firefox OS also provides a timeout screen that is displayed after a configurable period of phone inactivity, requiring passcode authentication before resuming use of the phone.

-

沙盒数据 Sandboxed Data

-

As described earlier, apps are sandboxed at runtime. This prevents apps from accessing data that belongs to other apps unless that data is explicitly shared, and the app has sufficient permissions to access it.

-

串行数据 Serialized Data

-

Web apps do not have direct read and write access to the file system. Instead, all access to storage occurs only through Web APIs. Web APIs read from, and write to, storage via an intermediary SQLite database. There is no direct I/O access. Each app has its own data store, which is serialized to disk by the database.

-

数据破坏

-

When a user uninstalls an app, all of the data (cookies, localStorage, IndexedDB, and so on) associated with that application is deleted.

-

隐私

-

Mozilla is committed to protecting user privacy and user data according to its privacy principles (https://www.mozilla.org/privacy/), which stem from the Mozilla Manifesto (https://www.mozilla.org/about/manifesto.html). The Mozilla Firefox Privacy Policy describes how Mozilla collects and uses information about users of the Mozilla Firefox web browser, including what Firefox sends to websites, what Mozilla does to secure data, Mozilla data practices, and so on. For more information, see:

- -

Firefox OS implements these principles by putting the control of the user data in the hands of the user, who gets to decide where this personal information goes. Firefox OS provides the following features:

- diff --git a/files/zh-cn/archive/b2g_os/simulator/index.html b/files/zh-cn/archive/b2g_os/simulator/index.html deleted file mode 100644 index 908b5a4049..0000000000 --- a/files/zh-cn/archive/b2g_os/simulator/index.html +++ /dev/null @@ -1,240 +0,0 @@ ---- -title: Firefox OS 模拟器 -slug: Archive/B2G_OS/Simulator -translation_of: Archive/B2G_OS/Simulator ---- -
-

Firefox OS 模拟器目前还处于开发早期,还没有那么我们想的那么稳定和功能齐备。

-

如果你发现了bug,请 在 GitHub 上面提交,如果你有任何问题,可以在 dev-developer-tools 邮件列表 或者 irc.mozilla.org 上的 #devtools on 提问。

-

你还可阅读“获取帮助”章节中的 how to enable verbose loggingget the latest preview build

-
-

Firefox OS 模拟器(Simulator)给你提供一个在桌面系统下测试和调试 Firefox OS 应用的环境,使得 code-test-debug(编码-测试-调试)的流程比使用实体设备更加快捷。当然你并不需要一个实体设备来运行这个模拟器。

-

本质上来讲,模拟器是由下面两个部分组成的:

- -

下面的这个截图展示了一个使用模拟器调试应用的过程。

-

右上的那个截图是信息中心,它运行在一个Firefox 标签页中。 我们已经添加了一个名为“where am I?" 的打包应用。左上截图显示的是该应用正运行在模拟器中。而且我们也连接了调试工具,也就是底部的那个面板。可以看到控制台面板显示了有关该应用的一些信息。

-

-

该指南包含了下面的内容:

- -
- 想从头到尾了解如何使用模拟器调试Web应用,请参见 Firefox OS 简易攻略 一文。
-

安装模拟器

-

模拟器是以Firefox 附加组件的形式打包和分发的。安装步骤:

-
    -
  1. 使用Firefox访问 the Simulator's page on addons.mozilla.org
  2. -
  3. 点击 "添加到Firefox(Add to Firefox)"。
  4. -
  5. 下载完成后会提示你是否需要安装,点击:  "现在安装(Install Now)".
  6. -
-

鉴于该组件的体积,在安装过程中,Firefox可能会出现假死的情况。可能会出现一个对话框"警告:script无响应(Warning: Unresponsive script)"。加入你看到该对话框,点击"继续"以完成安装。这种情况不会在Firefox27以上版本中出现。

-

安装完成后,Firefox会检查是否有该组件的更新版本,如果有的话,会自动更新至最新版本。

-

安装完成后,信息中心会自动打开。当然你也可以从"Firefox" 菜单(或者“工具“菜单)-Web开发者-Firefox OS 模拟器打开。

-

-

通过信息中心,你可以把你的应用添加到模拟器并且运行该应用。下面的截图就是信息中心的样子:

-

添加,移除和刷新应用

-

添加应用

-

怎样把打包应用添加到模拟器?打开信息中心,点击 "添加文件夹(Add Directory)" ,然后选择 manifest 文件
-
- 如果要添加基于服务器端的 Web 应用(hosted app),在有”URL for page or manifest.webapp"提示的输入框中输入,然后点击“添加 URL”(Add URL). 如果链接指向的是manifest文件,那么就会使用这个manifest文件。如果链接指向的不是manifest文件,信息中心就会为该URL生成一个manifest文件: 所以通过输入网站的URL,你就可以把该网站以应用的形式添加进来。

-

在你添加应用之后,信息中心对你的manifest文件进行一系列的测试,查找一些常见的问题。具体会进行那些测试,参阅 Manifest Validation(Manifest 验证)。

-

如果在Manifest验证阶段没有发现任何错误,信息中心则会在模拟器中自动运行你的应用。

-

管理应用

-

在你添加应用之后,该应用会出现在已安装应用的管理列表中:
-
- 每条记录都告诉我们关于应用的一些信息:

- -

同时我们也可以看到4个命令:

- -
-

在模拟器窗口中刷新应用: 在应用运行的状态下,通过模拟器窗口的 菜单或者是与之绑定的快捷方式 更新和重新加载该应用。

-
-

Manifest 验证

-

加入你提供了 manifest 文件,管理器会对该文件进行一些验证并且会针对下列3类问题给出报告:

- -

这些问题会列出来,点击错误提示你会看到这些问题的详细信息。

-

Manifest 错误

-

信息中心会把下列情形当成错误,意味着如果不修复他们就无法运行你的的应用:

- -

这里是尝试添加一个没有”name"属性的manifest文件的结果:
-

-

Manifest 警告

-

信息中心会把下列情形当成警告:

- -

针对模拟器的警告

-

最后,如果应用使用了还没有被Firefox OS完全支持的特性,管理器会对此弹出警告:

- -

运行模拟器

-

可以通过两种不同的方法启动模拟器:

- -

不管是哪种方法,只要模拟器一开始运行,标签为“Stopped"按钮就会变成绿色,同时标签也会变成”Running"(运行中)。要停止模拟器的运行,只需要再次点击这个按钮。

-

模拟器会在独立的窗口中运行,屏幕区域为320*480pixels, 在底部的工具栏(toolbar)顶部的菜单栏(menubar) 还包括一些额外的功能:

-

-

你可以通过点击鼠标和按下鼠标键之后的拖拽来模拟触屏事件。所以通过在主屏的点击和从右到左的拖拽,你就会看到内置的应用和你自己添加的应用:

-

-

模拟器工具栏(Simulator toolbar)

-

在底部的工具栏中,从左到右,分别是主屏(Home)按钮, 屏幕旋转(screen Rotation)按钮和地理位置(Geolocation)按钮.

- -

-

模拟器菜单栏

-

通过顶部的菜单栏,你可以更方便快捷的运行一些有用的命令。这会使你的开发工作更有效率。

-

- -

键盘上 "App Refresh" 的快捷方式使得从表面上来看开发一个应用就像是开发一个网页(浏览器中刷新一个页面的快捷方式也是Ctrl/Cmd-R):

- -
-

"刷新应用并清除数据(强制刷新)" 隐藏的快捷方式:有些时候清除掉模拟器存储的应用数据会非常有用。所以模拟器实际上有一个隐藏的快捷方式 Shift - Ctrl/Cmd - R, 该快捷方式在刷新应用的同时,也会清除下列数据:

- -
-

调用开发者工具

-

在模拟器中你可以调用开发者工具,以帮助你调试应用。目前你可以调用 JavaScript调试器, Web控制台, 样式编辑器, 分析器 以及网络,但是我们会努力支持更多的 开发者工具

-
-

某些工具只适用于Firefox的Beta, Aurora或者是Nightly版本。

-
-

点击应用的 "Connect"(连接)按钮来调用开发者工具

-

-

接着信息中心会在标签页底部打开开发者工具面板,并且连接到该应用:

-

-

Web控制台

-

The app can log to this console using the global console object, and it displays various other messages generated by the app: network requests, CSS and JS warnings/errors, and security errors. (Learn more about the Web Console.)

-

调试器

-

Using the Debugger, you can step through JavaScript code that is running in the connected app, manage breakpoints, and watch expressions to track down errors and problems faster. (Learn more about the Debugger.)

-

样式编辑器

-

You can view and edit CSS files referenced in the app using the connected Style Editor. Your changes will be applied to the app in real time, without needing to refresh the app. (Learn more about the Style Editor.)

-

分析器

-

Using the Profiler tool connected to the app, you can to find out where your JavaScript code is spending too much time. The Profiler periodically samples the current JavaScript call stack and compiles statistics about the samples. (Learn more about the Profiler.)

-

网络监控

-

Thanks to the new Network Monitor, you can analyze the status, headers, content and timing of all the network requests initiated by the app through a friendly interface. (Learn more about the Network Monitor.)

-

收据(Receipts)

-

如果你正在开发付费应用,那么你也应该使用有效(加密签名)的收据测试一下你的收据确认码(receipt validation code) (收据确认码是用来确认一个用户是否已经购买该应用或者用户已申请退款,然后根据这两种情况来锁定或者解锁应用)。

-

通过信息中心的"Receipts" 菜单,你可以安装"Valid"(有效的), "Invalid"(无效的), 或者 "Refunded"(退款) 的测试收据。选择你希望测试的收据类型,信息中心会从市场(Marketplace)的收据服务中心获取该类型的收据,然后在模拟器中重新安装该应用,同时也会安装该收据。:

-

-

推送到设备

-

如果你有安装Firefox OS系统的实体设备,你可以把该设备连接到模拟器,然后可以把应用从信息中心推送到设备上。

-

连接设备

-

关于如何把设备连接到信息中心,请参阅 connecting a Firefox OS device to the desktop. 请注意你并不需要安装ADB(Android Debug Bridge), 因为模拟器的附加组件中已经包含了它。

-

把应用推送到设备

-

在你设置后设备和桌面后,通过USB把设备连接到桌面系统,你会看到"Device connected"(设备已连接)的提示 ,同时你也会看到一个标签为“Push"(推送)的按钮:

-

-

点击 "Push", 应用就会安装到你的Firefox OS 设备上。

-
-

手动操作步骤:

- -
-

Firefox OS 设备连接确认

-

每次重启设备后的第一次”推送“需要你在设备上确认一下:

-

-

Linux系统下的问题

-

在创建udev规则后,如果你不能连接设备,请参见bug

-

模拟器的局限

-

请注意Firefox OS 模拟器目前并不完美。

-

硬件的局限

-

除了屏幕尺寸外,模拟器无法模拟Firefox OS设备的硬件换件,比如内存,CPU。

-

Audio/video 解码

-

下面列出的编码依赖于硬件加速的解码,所以目前还没被支持:

- -

这意味目前还无法测试依赖于这些编码的应用以及像Youtube这类网站的视频回放功能

-

不支持的APIs

-

在实体设备上被支持的某些API在模拟器中并没有被支持。通常是因为桌面环境中并没有支持这些API的硬件。我们模拟出了想地理位置的一些API,希望在以后的版本中可以支持更多的API。不管怎么说,目前模拟器尚未支持下面列出的这些API。如果你使用他们,可能会弹出错误或者返回不正确的结果:

- -

帮助

-

Firefox OS模拟器目前还处于开发的早期阶段,所以在稳定性和功能完整性方面还不尽人意。

-

如果你发现任何bug,请 在GitHub上面提交. 如果你有任何问题,也可以在 dev-developer-tools mailing list 或者 #devtools on irc.mozilla.org 提问。

-

如何启用详细记录

-

使用 about:config 打开偏好设置。
- extensions.r2d2b2g@mozilla.org.sdk.console.logLevel, 把值设为0,然后 禁用/开启 这个插件。然后关于模拟器运行操作的详细信息就会现在在错误控制台(Error Console) (较新版本的Firefox里面叫浏览器控制台(Browser Console) ).

-

如何获得最新的预览版本

-

正如在 section on installing the Simulator 所解释, 你可以从 addons.mozilla.org获得模拟器的最新版本。.

-

你可能想在我们正式发布前体验最新的特性,那么你可以从下面的链接中获取预览版本:

- -

但是请注意,相比正式版,预览版并没有被完全测试,在稳定性方面也稍差一些。

diff --git a/files/zh-cn/archive/b2g_os/simulator/simulator_walkthrough/index.html b/files/zh-cn/archive/b2g_os/simulator/simulator_walkthrough/index.html deleted file mode 100644 index 40fee1e3bf..0000000000 --- a/files/zh-cn/archive/b2g_os/simulator/simulator_walkthrough/index.html +++ /dev/null @@ -1,269 +0,0 @@ ---- -title: Firefox OS 模拟器简易攻略 -slug: Archive/B2G_OS/Simulator/Simulator_Walkthrough -translation_of: Archive/B2G_OS/Simulator/Simulator_Walkthrough ---- -

In this page we'll debug a very simple (but very buggy!) web app using the Firefox OS Simulator.

-

The walkthrough is structured into six parts: each part uses a different diagnostic/debugging tool, specifically, manifest validation, the Web Console, the JavaScript Debugger, the Network Monitor, the Style Editor and the Test Receipts.

-

It's intended that each part should be self-contained, so it should be possible to read only that part and have it make sense.

-

Using manifest validation

-
-

If you want to follow along, the various revisions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-1 version of the app.

-

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

-

The walkthrough assumes that you've installed the Simulator and opened the Dashboard.

-
-

First we'll add the app to the Dashboard by clicking "Add Directory" and selecting the manifest. We'll see this:

-


-
- Clicking on "(2 errors and 0 warnings)"  we see this:

-


- This error message is pretty clear, and if we look at "manifest.webapp", we can see that it's missing a "name":

-
{
-  "description": "A simple web app",
-  "launch_path": "/index.html",
-  "icons": {
-    "128": "/style/icons/earth.png"
-  }
-}
-


- Add the "name" field to the manifest file, save it, and click "Refresh" in the Dashboard:

-
{
-  "name": "Where am I?",
-  "description": "A simple web app",
-  "launch_path": "/index.html",
-  "icons": {
-    "128": "/style/icons/earth.png"
-  }
-}
-


- This time the Dashboard should tell us that we have no errors, and should run the app:

-

-

But when you click the button, nothing happens. In the next section, we'll try using the WebConsole to diagnose this problem.

-

Using the WebConsole

-
-

If you haven't followed along from the start of this walkthrough:

-

In this section we'll debug a very simple (but very buggy!) web app using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-2 version.

-

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

-

But in this version, when we click the button nothing happens. In this section of the walkthrough, we'll use the WebConsole to try to diagnose the problem.

- The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.
-

Over in the Dashboard, you have to click the button labeled "Connect":

-

-

A Simulator window will open automatically and run the app (if it's not already), and the WebConsole should appear into the Simulator Dashboard tab.

-

In the console output you might see a few errors, warnings, and messages, but the last one in particular looks relevant:
-
-
-
- This is obviously a problem in our app's script, "whereami.js". Here are the first few lines of the script:

-
var whereami = document.getElementById('whereami');
-
-whereami.onclick = function() {
-  navigator.geolocation.getCurrentPosition(getMap, error);
-};
-


- Comparing this with our app's "index.html", the problem's obvious:

-
<!DOCTYPE html>
-
-<html>
-
-  <head>
-    <meta charset='utf-8'>
-    <script src="http://open.mapquestap.com/sdk/js/v7.0.s/mqa.toolkit.js"></script>
-    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
-
-  </head>
-
-  <body>
-    <button id ="where-am-i">Where am I?</button>
-    <div id="map"></div>
-    <script src="scripts/whereami.js"></script>
-    <link media="all" href="style/style.css" type="text/css" rel="stylesheet">
-  </body>
-
-</html>
-


- In the HTML, the button is assigned an ID of "where-am-i", but in the JavaScript, we're trying to use "whereami". So let's fix that:

-
var whereami = document.getElementById('where-am-i');
-
-whereami.onclick = function() {
-  navigator.geolocation.getCurrentPosition(getMap, error);
-};
-

Now the app starts up without any errors, but when we click the button, the map doesn't appear, and we get a new message in the WebConsole:

-

-

This message is logged by our "whereami.js" script, and indicates that the geolocation API has returned an error - but it unhelpfully doesn't tell us what the error was. We can use the JavaScript Debugger to figure that out.

-

Using the JavaScript Debugger

-
-

If you haven't followed along from the start of this walkthrough:

-

In this section we'll debug a very simple (but very buggy!) web app using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-3 version.

-

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

-

But in this version, when we click the button the Geolocation API returns an error. In this section of the walkthrough, we'll use the JavaScript Debugger to figure out exactly which error is returned.

-

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

-
-

In the WebConsole connected to the app, click the link on the right of the geolocation error log:

-


- Clicking on the "whereami.js:8" link, the JavaScript Debugger will be automatically loaded and pointed to the related file and line number.

-

According to the Geolocation API reference, the specific error is given by the code property of the error object that's passed into the error handler error(). So set a breakpoint inside error() by clicking to the left of line 8:

-

-

In the app, click "Where am I?". Execution should stop at the breakpoint:

-

-

Click where it says "Add watch expression" and type "error.code", and you'll immediately see its value, "1":

-


- According to the Geolocation API documentation, "1" means "Permission denied". This is an error web apps get if they have not requested the geolocation permission, or if the permission wasn't granted by the user.
-
- Looking at the "manifest.webapp" file, we'll see that we didn't ask for the permission:

-
{
-  "name": "Where am I?",
-  "description": "A simple web app",
-  "launch_path": "/index.html",
-  "icons": {
-    "128": "/style/icons/earth.png"
-  }
-}
-


- Let's fix that:

-
{
-  "name": "Where am I?",
-  "description": "A simple web app",
-  "launch_path": "/index.html",
-  "icons": {
-    "128": "/style/icons/earth.png"
-  },
-  "permissions": {
-    "geolocation": {
-      "description": "Needed to tell the user where they are"
-      }
-  }
-}
-


- Save "manifest.webapp", and click "Refresh" in the Dashboard one more time. Remember to resume the Debugger as it is still at the breakpoint. This time the app runs, and when you click "Where am I?" it asks you to share your location, and if you allow it, the map doesn't appear and we get a new message in the WebConsole:

-

-

This message indicates that the MapQuest API, which we have included into our app using a tag script, is not loaded correctly. We can use the Network Monitor to figure that out.

-

Using the Network Monitor

-
-

If you haven't followed along from the start of this walkthrough:

-

In this section we'll inspect network request from a very simple (but very buggy!) web app using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-4 version.

-

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

-

But in this version, when we click the button the WebConsole shows a "MQA is not defined" error. In this section of the walkthrough, we'll use the Network Monitor to figure out exactly why the MapQuest API is not loaded.

-

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

-
-
-

Warning: the Network Monitor is available for Firefox >= 23.0 (which is currently Firefox Beta)

-
-

In the Developer Tools panel connected to the app, click the Network tab and the following panel will be presented to you, where you see that requests for the "mqa.toolkit.js" resource from the "open.mapquestap.com" domain are never completed successfully:

-

-

Successful requests are green colored, if we click on one of the requests to the "open.mapquestap.com" domain (dark grey colored) and select the Timings detail panel, we can figure out that the request never reached the Connecting status, because DNS resolution did not succeed.

-

Looking at the "index.html" file, we'll see that the script tag points to the wrong domain.

-

Let's fix this bug, changing the script tag to use the correct domain: open.mapquestapi.com (add the missing 'i' to the domain name):

-
<!DOCTYPE html>
-
-<html>
-
-  <head>
-    <meta charset='utf-8'>
-    <script src="http://open.mapquestapi.com/sdk/js/v7.0.s/mqa.toolkit.js"></script>
-    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
-
-  </head>
-
-  <body>
-    <button id ="where-am-i">Where am I?</button>
-    <div id="map"></div>
-    <script src="scripts/whereami.js"></script>
-    <link media="all" href="style/style.css" type="text/css" rel="stylesheet">
-  </body>
-
-</html>
-

Save "index.html", and click "Refresh" in the Dashboard one more time. This time the app runs, and when you click "Where am I?" it asks you to share your location, and if you allow it, the app finally displays the map:
-

-

Using the Style Editor

-
-

If you haven't followed along from the start of this walkthrough:

-

In this section we'll customizing the app stylesheets using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the version whereami-5.

-

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

-

In this version all the previous bugs are already fixed, and we're going to use the Style Editor to change the style real time on the running app and save it back when we're satisfied.

-

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

-
-
-

Warning: the Style Editor is available for Firefox >= 23.0 (which is currently Firefox Beta)

-
-

In the Developer Tools connected to the app, click the Style Editor tab and the following panel will be presented to you:

-

-

Select "style/style.css" from the style sheets list on the left and make some changes to the CSS rules. The new rules will be applied to the connected app immediately:

-

-

Now you can click on the "Save" link just below "style/style.css" in the style sheets list to save it back into the project.

-

Using the Test Receipts

-
-

If you haven't followed along from the start of this walkthrough:

-

In this section we'll add payment receipt validation code to a web app using the Firefox OS Simulator. The various versions of the app are in the firefoxos-simulator-walkthrough repository on GitHub, and you can pick the walkthrough up at this point by starting with the whereami-6 version.

-

The app displays a single button labeled "Where am I?". When the user clicks the button, the app fetches the user's current location using the Geolocation API, and displays it on a map.

-

In this version we're going to change it to became a paid web app.

-

The walkthrough assumes that you've installed the Simulator, opened the Dashboard, and added the app by clicking "Add Directory" in the Dashboard, then selecting the app's "manifest.webapp" file.

-
-

Now that your app is bug-free and properly styled, you can add payment receipt validation to ensure that users of your app have purchased it.

-

Mozilla has released a small JavaScript library which will help an app check its receipts: http://github.com/mozilla/receiptverifier

-

Let's add receiptverifier to the app, e.g. adding a new script tag to its "index.html" file:

-
<!DOCTYPE html>
-
-<html>
-
-  <head>
-    <meta charset='utf-8'>
-    <script src="https://raw.github.com/mozilla/receiptverifier/master/receiptverifier.js"></script>
-    <script src="http://open.mapquestapi.com/sdk/js/v7.0.s/mqa.toolkit.js"></script>
-    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
-
-  </head>
-
-  <body>
-    <button id ="where-am-i">Where am I?</button>
-    <div id="map"></div>
-    <script src="scripts/whereami.js"></script>
-    <link media="all" href="style/style.css" type="text/css" rel="stylesheet">
-  </body>
-
-</html>
-

and check the receipts in the "scripts/whereami.js" using the "mozmarket.receipts.Verifier" API (e.g. checking the receipts on the button click or on the app loading):

-
...
-
-var verifier = new mozmarket.receipts.Verifier({
-  installs_allowed_from: '*',
-  typsAllowed: 'test-receipt',
-  logLevel: mozmarket.receipts.Verifier.levels.DEBUG,
-  onlog: mozmarket.receipts.Verifier.consoleLogger
-});
-verifier.clearCache();
-
-function verifyPaymentReceipts(cb) {
-  verifier.verify(function (verifier) {
-    if (verifier.state instanceof verifier.states.OK) {
-      cb(null); // valid payment
-    } else {
-      cb("invalid-payment"); // invalid payment
-    }
-  });
-  setTimeout(function checkNoReceipts() {
-    if (verifier.state instanceof verifier.states.NoReceipts) {
-      cb("no-receipts");
-    }
-  }, 2000);
-}
-
-whereami.onclick = function() {
-  verifyPaymentReceipts(function (err) {
-    if (err) {
-      alert("Invalid Payment Receipt.");
-    } else {
-      navigator.geolocation.getCurrentPosition(getMap, error);
-    }
-  });
-};
-
-

Receipts are cryptographically signed (by the Marketplace and the Payment services), but you can use the Simulator to install your app with a test receipt by selecting the type of receipt to install (which defaults to "None") using the "Receipts" menu in the app entry:

-

-

Now you can test how the app will behave with "Valid", "Invalid", and "Refunded" receipts (or when there isn't any receipt) and observe the results by looking at the logs produced by the receiptverifier library in the Web Console:

-

 

-

-

-
-

Note: You can get the completed app from the whereami-7 version.

-
-

 

diff --git a/files/zh-cn/archive/b2g_os/using_firefox_os_simulator/index.html b/files/zh-cn/archive/b2g_os/using_firefox_os_simulator/index.html deleted file mode 100644 index 1abeb853a8..0000000000 --- a/files/zh-cn/archive/b2g_os/using_firefox_os_simulator/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: 使用Firefox OS模拟器 -slug: Archive/B2G_OS/Using_Firefox_OS_Simulator -translation_of: Archive/B2G_OS/Simulator ---- -

The Firefox OS Simulator is a desktop platform tool that shows you what apps will look like on a phone that is running the Firefox OS. It is the easiest way to try out apps on Firefox OS before submitting them to the Firefox Marketplace. The Firefox OS Simulator was formerly called "r2d2b2g", but that name is too difficult.

-

The Simulator is packaged as a desktop Firefox add-on. You can use any recent version of Firefox from Firefox 17 onward.

-

Although there are other ways to run the Firefox OS desktop, the best and most convenient way for app developers is this one. If you're a core Firefox OS platform developer, or are working on localization, there are other tools that are better suited for your needs. The Simulator add-on includes support for adding apps to the test environment, and is configured to support remote debugging, remote Web console, and other features. It also provides a visible Home button you can click, and sets the user-agent string to the one used by Firefox OS on devices. The result is, in nearly every way, a better environment for app developers.

-

安装Firefox OS模拟器

-
    -
  1. Using Firefox, go to this link: https://addons.mozilla.org/addon/firefox-os-simulator/
  2. -
  3. Click Add to Firefox. It's a large download. Follow the prompts that appear.
  4. -
-
-

Because of the size of the add-on, Firefox may freeze for several seconds while installing it, and its unresponsive script dialog may appear, due to bug 814505. If it does, just click the Continue button, and Firefox will continue installing the add-on.

-
-

Starting the Simulator

-
    -
  1. On the Firefox menu (Windows) or the Tools menu (Mac, Linux), go to Web Developer and click Firefox OS Simulator. The dashboard appears. -

    Dashboard

    -
  2. -
  3. Click the Stopped button. It changes into the Running button and Firefox OS boots up in its own window. The default size for this window is 320x480. -

    Simulator

    -

    To stop the Simulator, click the Running button in the dashboard, or just close the Simulator window.

    -
  4. -
-
-

Note: You can also start and stop the Simulator in the Developer Toolbar command line using firefoxos start and firefoxos stop.

-
- -

Imitate swipe motions in the Simulator by clicking and dragging with the mouse. The mouse scroll wheel will move a list up and down, such as in the Settings app. Click and hold down the mouse button to simulate a long press.

-

To get back to the home screen, click the home button at the bottom of the Simulator, or press the Home key on your keyboard. On Mac keyboards without a Home key, use Fn + Left Arrow.

-

Console checkbox

-

Click the Console check box before you start the Simulator to open an error console so you can spot errors that might occur while you're working on your app.

-

Web APIs in the Simulator

-

Mozilla is working on many Web APIs to make native platform capabilities available to Open Web Apps. The Web APIs currently supported in the Simulator are:

- -

Installing an app in the Simulator

-

To install a hosted app in the Simulator, type the URL to the app's manifest in the URL box, and click Add Manifest. This will install the app in the Simulator. Here is a simple weather app that you can use as a test:

-
http://jlongster.github.com/weatherme/manifest.webapp
-

The app's icon will be added to one of the home screens in the Simulator.

-

You can also install a plain website in the same way. Just type the website's URL in the box and click Add URL, and an icon for the site will be added to a home screen. Autocompletion works if you have the website open in another tab.

-

To install a packaged app in the Simulator, click the Add Directory button, then select the mini-manifest of the app on your local filesystem.

-

To remove an app from the Simulator, click the Remove link for the app in the dashboard. You may have to restart the Simulator to see it gone.

-

Updating an app

-

If you are working on an app and need to update it in the Simulator, click the app's Update button in the dashboard. You will have to restart the Simulator. Hosted apps follow the usual rules for Website caching and working with appcache.

-

Reporting bugs

-

Remember that the Simulator is a brand-new tool and is still heavily under development. Please let us know if you find any bugs.

-

More information

-

The Simulator itself is the Firefox OS desktop client (also called the B2G desktop client), which is a build of Firefox OS that runs on Windows, Mac, and Linux. Firefox OS Simulator makes it easier to test apps on Firefox OS desktop because it includes functionality for adding apps to the environment and is configured/extended in a variety of ways to better meet the needs of app developers.

-

However, because the Simulator uses the Firefox OS desktop client, the documentation for B2G Desktop, Gaia, and B2G generally will also apply to the Simulator to some extent. Here are a couple of those docs:

-

Using the Firefox OS desktop client

-

Hacking Gaia

diff --git a/files/zh-cn/archive/b2g_os/using_the_app_manager/index.html b/files/zh-cn/archive/b2g_os/using_the_app_manager/index.html deleted file mode 100644 index 35b8506eed..0000000000 --- a/files/zh-cn/archive/b2g_os/using_the_app_manager/index.html +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: 使用应用管理器 -slug: Archive/B2G_OS/Using_the_App_Manager -translation_of: Archive/B2G_OS/Using_the_App_Manager ---- -
-

“应用管理器 (App Manager)”为桌面版 Firefox 的新工具,开发者可以通过浏览器,直接在 Firefox OS 手机 和 Firefox OS 模拟器 (Firefox OS Simulator) 中进行 HTML5 Web App 的测试、布署、调试等工作。

-

App Manager是为使用Firefox OS 1.2 及之后的版本的开发者服务的,如果您正在Firefox OS 1.1 版本上开发app,则需要参考有关Firefox OS 1.1 仿真器的介绍。

-
-

 

-

应用管理器具备下列组件:

- -

快速设置:

-

本节的目的是让开发者尽快的设置和应用工具。如果你需要一些更详细的资料,则可以请跳过本节,直接从《设备和系统配置》阅读。如遇到任何问题,也可参阅《疑难排除》获取帮助。

-
    -
  1. 确保已安装了桌面版Firefox 26+
  2. -
  3. 打开应用管理器(在地址栏输入 about:app-manager
  4. -
  5. 如果你没有实际的 Firefox OS 设备: -
      -
    1. 安装 Firefox OS 模拟器 (Firefox OS Simulator)
    2. -
    3. 在应用管理器底部的工具栏中,点击“启动模拟器” ,然后再点击模拟器名称(已安装的模拟器均应出现)。
    4. -
    -
  6. -
  7. 如果你拥有 Firefox OS 设备: -
      -
    1. 请确保你的设备运行Firefox OS 1.2+
    2. -
    3. 在Windows上,请安装你的手机制造商提供的驱动程序
    4. -
    5. 进入设备的“Settings”,停用“Screen Lock(Settings > Screen Lock)”,并启用“Remote Debugging(Settings > Device information > More information > Developer)”
    6. -
    7. 为桌面版 Firefox 安装附加组件 ADB Helper
    8. -
    9. 通过 USB 接口将设备连接到你的电脑
    10. -
    11.  你应该可以在应用管理器底部的工具栏看到设备的名称,点击它
    12. -
    -
  8. -
  9. 底部工具栏应显示 “连接到: xxx”
  10. -
  11. 点选 “应用”面板 并新增应用(打包或托管应用皆可)
  12. -
  13. “刷新”按钮将验证该 App 并安装到模拟器/设备中
  14. -
  15. 调试按钮连接开发者工具到运行中的 App
  16. -
  17. 如遇到麻烦,请参阅 疑难排除章节以得到更多帮助
  18. -
-

设备和系统配置

-

使用应用管理器前的第一件事,就是要确保你的系统和手机的设定是正确的。接着就是按照本节说明的各个步骤运行。

-

需要Firefox 1.2+

-

请确保你的设备运行Firefox OS1.2/Boot2Gecko1.2或更高版本。要检查当前 Firefox OS 版本,则可进入 Settings > Device Information > Software

-

如果您没有安装足够高版本的 Firefox OS,则你需要根据手机型号的不同,安装 Firefox 1.2+ nightly 版本,或通过源代码配置和构建自己的版本。

-

可用的构建:

- -
-

注意:要构建自己的 Firefox OS 1.2+,请参阅 编译及安装Firefox OS火狐操作系统 说明,并从 编译Firefox OS的系统需求 着手。

-
-

远程调试

-

接下来,你需要在 Firefox OS 中启用远程调试,开启方法为:进入 Settings > Device information > More information > Developer,并勾选 Remote Debugging 复选框即可。

-

ADB 或 ADB helper

-

通过 Android Debug Bridge (ADB) 连接设备与电脑并通信。有两个运行ADB的方式:

- -
-

注意:如果安装了 ADB Helper 扩展,就不需执行此指令。

-
-

将设备连接到应用管理器

-

所有配置完成之后,就可将设备连上电脑并启动应用管理器:

-
    -
  1. 通过USB接口连接电脑。
  2. -
  3. 在你设备上禁用锁屏,方法是 Settings > Screen Lock 并 取消 Lock Screen 勾选。这是非常必要的,因为当屏幕锁定后,手机和电脑的连接就会中断,这样就无法调试了。
  4. -
  5. 启动应用管理器(App Manager)  — 在桌面版 Firefox 菜单中点击 Tools > Web Developer > App Manage 启动,或在通过地址栏输入”about:app-manager“启动。
  6. -
  7. 应用管理器标签页底部,会看到连接状态栏(见下图)。您应该能够通过点击“连接到 localhost:6000”按钮即可连线设备。
  8. -
  9. 如连接成功,就会有“An incoming request to permit remote debugging connection was detected. Allow connection?”对话框。点击“OK”钮(你可能需要按下手机的电源键,才能看到该对话框)。这时连接状态栏应该更新为”连接到 B2G“,如想断开连接,可以按”断开“连接。
  10. -
-

-
-

注意:在连线状态栏中有其他控件,允许你通过模拟器连接到应用管理器 ,我们将在下一节中说明。另外要更改连接端口,则需要启动”端口映射“功能,可参阅上节的《端口映射》。

-
-

使用 Firefox OS Simulator 附加组件

-

如果你没有实际的 Firefox OS 设备来配合 App Manager,可以使用 FirefoxOS 模拟器。不过要选择适合自己操作系统的模拟器版本:

-

安装 Firefox 模拟器

-
-

注意:目前只有 Firefox OS 1.2 模拟器,未来将提供更多版本选择。

-
-

一旦你安装了模拟器,就可以在应用管理器底部栏找到并点击 ”启动模拟器“按钮。接着将出现 3 个按钮:

- -

“应用”面板

-

现在一切设定完毕,我们了解一下应用管理器的功能吧。首先是“应用”面板。在这里你可以导入现有应用到设置,便于调试。

- -

在窗口右侧会显示你应用的相关信息,如下图所示:

-

-

Manifest 编辑器

-

从 Firefox 28 开始,“应用”面板包含一个应用 manifest  编辑器:

-

-

调试

-

点击“更新”(安装)按钮,则更新(安装)应用到设备中。点击“调试”按钮将调用工具箱,让你直接来调试应用源代码。

-

-
-

注意:你可以尝试玩一下工具盒 — 比如,尝试修改DOM,CSS等等,你会立即看到实时反映到了设备上。这些修改被保存到已安装的应用代码里,在你下次在设备上打开应用后会看到改变。

-
-

在 Firefox 28 之前,这个工具都是在单独窗口中启动。从 Firefox 28 开始,这些工具都会在应用管理器中的“应用”和“设备”面板标签旁边,以标签形式出现。该标签很容易找打,该标签卡会出现应用的图标。

-

-

错误

-

如果应用没有被成功添加(例如,URL不正确,或者打包了一个错误文件夹)— 即使引入了一个错误的应用,也会被包括错误信息。

-

-

你可以在上图中删除一个应用,把鼠标悬停在左侧窗口应用名/描述上,然后按出现的“X”按钮即可。然而,这并没有真正把设备上的应用删除了,你仍然需要在设备上手动删除应用。

-

“设备”面板

-

“设备”面板显示已连接设备的相关信息。在“已安装应用”窗口中可以启动和调试设备上的应用。

-

-
-

注:Certified Apps 默认不列出。可参阅 Certified App 的调试方式

-
-

“权限”窗口显示当前设备的各种 Web API 所需要的权限。

-

-

最后,你可以点击“截图”按钮,截下当前设置显示的画面,截图会显示在 Firefox 的新标签页中,你可以另存该图。

-

调试 Certified Apps

-

目前仅限搭载 Firefox OS 1.2 开发版本的设备,才能进行 Certified Apps 的调试。若你的设备正运行开发版本,则可将首选项中的“ devtools.debugger.forbid-certified-apps”变更为“false”,即可开始 Certified Apps 的调试。具体请按照下列步骤操作:

-
    -
  1. -

    在电脑的终端/控制台中输入下列指令,以进入设备的文件系统:

    -
    adb shell
    -

    命令行会提示转为 root@android.

    -
  2. -
  3. -

    接着,使用下列命令停止B2G运行:

    -
    stop b2g
    -
  4. -
  5. -

    进入以下目录:

    -
    cd /data/b2g/mozilla/*.default/
    -
  6. -
  7. -

    这一步,使用下列代码更新 prefs.js 文件:

    -
    echo 'user_pref("devtools.debugger.forbid-certified-apps", false);' >> prefs.js
    -
  8. -
  9. -

    当你完成编辑并保存文件后,使用以下命令重新启动B2G:

    -
    start b2g
    -
  10. -
  11. -

    this will return you to your normal terminal prompt.使用 exit 命令退出 android 的文件系统;就会返回到正常的终端提示符画面。

    -
  12. -
  13. -

    接下来,重新连接到应用管理器,你应该可以看到 Certified Apps 出现,就可以进行调试了。

    -
  14. -
-
-

注意:如果你想把这个偏好设定加入自己的 Gaia 版本,且即使重设手机也能让该设定保持启用状态,则可将此偏好设定加入 build/custom-prefs.js 再执行 make reset-gaia 即可。

-
-

疑难排除

-

如果设备无法识别:

- -

无法将设备连接到应用管理器或启动模拟器?请让我们知道反馈错误

diff --git a/files/zh-cn/archive/b2g_os/using_the_b2g_emulators/index.html b/files/zh-cn/archive/b2g_os/using_the_b2g_emulators/index.html deleted file mode 100644 index 5b7b9bb025..0000000000 --- a/files/zh-cn/archive/b2g_os/using_the_b2g_emulators/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: 使用B2G仿真器 -slug: Archive/B2G_OS/Using_the_B2G_emulators -translation_of: Archive/B2G_OS/Using_the_B2G_emulators ---- -

-

This article provides a brief guide to some key things you should know when using the Boot to Gecko emulators. This doesn't purport to be a complete user manual; instead, it simply tells you a few useful things that you might not learn on your own.

-

This guide assumes you've already built one of the emulators; if you haven't, rewind to Building and installing Boot to Gecko!

-

About the B2G emulators

-

There are two B2G emulators. The first, built by configuring for "emulator-x86" when running config.sh, is an x86 device emulator. While this is much faster than emulating the ARM processor, it's not as accurate a representation of what an actual device will work like. Configuring for "emulator" when running config.sh gets you the ARM device emulator.

-
- Note: In recent months the Automation Team has stopped using the x86 emulator due to stability issues. As such, there's a fair chance that things might just not work at all on emulator-x86. Use the ARM emulator unless you have a good reason to do otherwise.
-

Once you've selected, configured, and built an emulator, the rest works the same way from a user standpoint, so the rest of this guide is common to both.

-
- Note: On Mac OS X, the B2G emulator requires a Core 2 Duo processor or later; that is, a system that is compatible with Mac OS X 10.7 "Lion." You do not actually have to be running Lion, you just have to be compatible with it.
-

Starting the emulator

-

To start the B2G emulator, type the following command:

-
./run-emulator.sh
-
-

This will handle all the emulator startup tasks for you. Now wait patiently while the emulator starts up and Boot to Gecko boots up on it. It can take a couple of minutes, so be patient.

-

When the emulator doesn't work

-

Sometimes the emulator fails to start up. Welcome to the bleeding edge of technology! Here are some tips for resolving problems.

-

Make sure the adb server is running

-

This usually happens because the adb server that handles interacting with the emulated device is either not running or has malfunctioned.

-
-

Note: If you're using the adb built by the B2G build system (which you probably are), it's located in the $B2G/out/host/<platform>/bin directory. On Mac, this is $B2G/out/host/darwin-x86/bin, for example.

-
-

Look to see if adb is even running by doing:

-
ps aux | grep adb
-
-

If it's there, do this to kill it, because it's probably not working correctly.

-
adb kill-server
-
-

If it's not there, do this:

-
adb start-server
-
-

Then try running the emulator again. If it's still not working, time to drop in on #b2g on irc.mozilla.org for help.

-

Erase configuration settings

-

Sometimes, out of date configuration settings on your emulated device can cause it to misbehave. You can delete the IndexedDB database fix this, as follows:

-
    -
  1. Make sure adb is running, as described in Make sure the adb server is running.
  2. -
  3. Start up the emulator.
  4. -
  5. in the terminal on the host computer, go into the root code build directory for your emulator, then type: out/host/<platform>/bin/adb -e shell; on Mac, this would be out/host/darwin-x86/bin/adb -e shell.
  6. -
  7. Now you're in the adb shell, and can execute shell commands on your emulated device. Let's stop B2G on the device: stop b2g.
  8. -
  9. Delete the IndexedDB database: rm -rf /data/local/indexedDB.
  10. -
  11. Restart B2G on the emulated device: start b2g.
  12. -
-

Hopefully at this point you will wind up in the Gaia interface and all will be well.

-

Configuring the emulator

-

There are several options you can change to adjust the emulator to be more similar to the device you want to emulate. This section provides some basic information on how to do that. You can adjust the emulator's configuration by editing the run-emulator.sh script (or, ideally, a copy of it). Only a few of the most useful parameters are discussed here; you'll want to look at the qemu site for details on the others.

-
- Tip: Create one copy of run-emulator.sh for each device you want to simulate; this makes it easy to start up with different configurations.
-

Changing skins

-

By default, the emulator starts up in HVGA mode; that's half-VGA, or 320x480 pixels. This is specified by the -skin parameter given to the emulator when started up. You can switch to a different display mode by editing the run-emulator.sh script (or, ideally, a copy of it). The provided skins are:

- -

The skins are located in the B2G/development/tools/emulator/skins directory. It's worth noting that the format for skins is quite simple; if you look at them, they're simply folders filled with PNG files for the various user interface objects and a text file called layout which describes the layout of the interface and screen area. It's fairly simple to create custom skins if needed.

-

Changing memory size

-

Another option you may wish or need to configure is the device memory size. The default is 512 MB; however, if the device you're emulating has more or less memory, it is likely important that you adjust this setting to match, to ensure your app will run on the baseline device you want to work on. To do this, change the value of the -memory parameter to the size you need in megabytes. Other than the 512 MB default, 256 MB and 1024 MB are likely ones you'll want to test with.

-

To change the amount of emulated storage capacity for the device (that is, the storage space for local data, like the flash storage on a mobile phone or the hard drive on a computer), change the value of the -partition-size parameter. The default is 512 MB, but you can specify any size in MB you need in order to simulate the kind of device you need to test for.

-

Network Connectivity

-

If for some reason you cannot connect your emulator to the internet you can run the following command from your commandline:

-
adb shell setprop net.dns1 10.0.2.3
diff --git a/files/zh-cn/archive/css3/index.html b/files/zh-cn/archive/css3/index.html deleted file mode 100644 index fe08545c87..0000000000 --- a/files/zh-cn/archive/css3/index.html +++ /dev/null @@ -1,1047 +0,0 @@ ---- -title: CSS3 -slug: Archive/CSS3 -tags: - - CSS - - CSS 参考 - - CSS3 - - 进阶 -translation_of: Archive/CSS3 ---- -

CSS3层叠样式表(Cascading Style Sheets)语言的最新版本,旨在扩展CSS2.1。

- -

它带来了许多期待已久的新特性, 例如圆角、阴影、gradients(渐变) 、transitions(过渡) 与 animations(动画) 。以及新的布局方式,如 multi-columns flexible box 与 grid layouts。实验性特性以浏览器引擎为前缀(vendor-prefixed),应避免在生产环境中使用,或极其谨慎地使用,因为将来它们的语法和语义都有可能被更改。

- -

模块和标准化进程

- -

CSS Level 2 经历了 9 年的时间(从 2002 年 8 月到 2011 年 6 月)才达到 Recommendation(推荐) 状态,主要原因是被一些次要特性拖了后腿。为了加快那些已经确认没有问题的特性的标准化速度,W3C 的 CSS Working Group(CSS 工作组)  作出了一项被称为 Beijing doctrine 的决定,将 CSS 划分为许多小组件,称之为模块。这些模块彼此独立,按照各自的进度来进行标准化。其中一些已经是 W3C Recommendation 状态,也有一些仍是 early Working Drafts(早期工作草案)。当新的需求被肯定后, 新的模块也会同样地添加进来。

- -

CSS Modules and Snapshots as defined since CSS3

- -

 

- -

 

- -

 

- -

 

- -

 

- -

 

- -

从形式上来说,CSS3 标准自身已经不存在了。每个模块都被独立的标准化,现在标准 CSS 包括了修订后的 CSS2.1 以及完整模块对它的扩充,模块的 level(级别)数并不一致。可以在每个时间点上为 CSS 标准定义一个 snapshots(快照),列出 CSS 2.1 和成熟的模块。

- -

W3C 会定期的发布这些 snapshots,如 2007, 2010, 20152017

- -

目前为止,还没有 level 超过 3 的模块被标准化,未来应该会有所改变。 不过有些模块,比如 Selectors(选择器)4 或 CSS Borders and Backgrounds(边框和背景)Level 4 早已拥有了 Editor's Draft(编辑草案),即使它们还没达到 First Published Working Draft(初次发布工作草案)状态。

- -
 
- -

CSS 模块状态

- -

稳定模块(Stable modules)

- -

有些 CSS 模块已经十分稳定,其状态为 CSSWG 规定的三个推荐品级之一:Candidate Recommendation(候选推荐), Proposed Recommendation(建议推荐)或 Recommendation(推荐)。表明这些模块已经十分稳定,使用时也不必添加前缀, 但有些特性仍有可能在 Candidate Recommendation 阶段被放弃。

- -

这些模块扩展并修改了 CSS2.1 规范(核心规范)。 以下为 CSS 规范当前的 snapshot。

- - - - - - - - - - - - - -
{{ SpecName("CSS3 Colors", "", "") }}{{ Spec2("CSS3 Colors") }} 自 2011 年 6 月 7 日
-

增加 {{ cssxref("opacity") }} 属性,还有 hsl(), hsla(), rgba() 和 rgb() 函数来创建 {{cssxref("<color>")}} 值。 它还将 currentColor 关键字定义为合法的颜色值。

- -

transparent 颜色目前是真彩色 (多亏了支持 alpha 通道) 并且是 rgba(0,0,0,0.0) 的别名。

- -

它废弃了 system-color keywords(系统颜色关键字), 它们已经不能在生产环境中使用。

-
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Selectors", "", "") }}{{ Spec2("CSS3 Selectors") }} 自 2011 年 9 月 29 日
-

增加:

- -
    -
  • 子串匹配的属性选择器, E[attribute^="value"], E[attribute$="value"], E[attribute*="value"]。
  • -
  • 新的伪类:{{ cssxref(":target") }}, {{ cssxref(":enabled") }} 和 {{ cssxref(":disabled") }}, {{ cssxref(":checked") }}, {{ cssxref(":indeterminate") }}, {{ cssxref(":root") }}, {{ cssxref(":nth-child") }} 和 {{ cssxref(":nth-last-child") }}, {{ cssxref(":nth-of-type") }} 和 {{ cssxref(":nth-last-of-type") }}, {{ cssxref(":last-child") }}, {{ cssxref(":first-of-type") }} 和 {{ cssxref(":last-of-type") }}, {{ cssxref(":only-child") }} 和 {{ cssxref(":only-of-type") }}, {{ cssxref(":empty") }}, 和 {{ cssxref(":not") }}。
  • -
  • 伪元素使用两个冒号而不是一个来表示::after 变为 {{ cssxref("::after") }}, :before 变为 {{ cssxref("::before") }}, :first-letter 变为 {{ cssxref("::first-letter") }}, 还有 :first-line 变为 {{ cssxref("::first-line") }}。
  • -
  • 新的 general sibling combinator(普通兄弟选择器)  ( h1~pre )。
  • -
-
- -

下一个迭代的选择器规范早已开始运作,它还没有达到 First Public Working Draft 阶段。

- - - - - - - - - - - - - -
{{ SpecName("CSS3 Namespaces", "", "") }}{{ Spec2("CSS3 Namespaces") }} 自 2011 年 9 月 29 日
-

通过定义 CSS qualified name(CSS 限定名) 的概念来增加对 XML Namespace(名空间) 的支持, 使用 ' | ' 语法并增加 {{ cssxref("@namespace") }} CSS @ 规则。

-
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Media Queries", "", "") }}{{ Spec2("CSS3 Media Queries") }} 自 2012 年 6 月 19 日
-

将之前的媒体类型 ( print, screen,……) 扩充为完整的语言, 允许使用类似 only screen 和 (color) 来实现 设备媒体能力查询功能

- -

媒体查询并非仅能用于 CSS 文档中,它也被用于 HTML 元素的某些属性中, 例如 {{ HTMLElement("link") }} 元素的 {{ htmlattrxref("media","link") }} 属性。

-
- -

该规范的下一个迭代也在进行中,借助新的媒体特征例如  hover 或 pointer,可以在 User Agent(用户代理) 上对 Web 站点的输入方法进行定制。对 ECMAScript 的检测, 使用 script 媒体特征也已经被提出。

- - - - - - - - - - - - - -
{{ SpecName("CSS3 Style", "", "") }}{{ Spec2("CSS3 Style") }} 自 2013 年 11 月 7 日
正式定义了 HTML style 全局属性内容的语法。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Backgrounds", "", "") }}{{ Spec2("CSS3 Backgrounds") }}
-

增加:

- -
    -
  • 背景支持各种类型的 {{cssxref("<image>")}}, 并不局限于之前定义的 url()。
  • -
  • 支持 multiple background images(多背景图片)。
  • -
  • {{ cssxref("background-repeat") }} 属性的 space 和 round 值,还有支持两个值的语法。
  • -
  • {{ cssxref("background-attachment") }} local 值。
  • -
  • CSS {{ cssxref("background-origin") }},{{ cssxref("background-size") }} 和 {{ cssxref("background-clip") }} 属性。
  • -
  • 支持带弧度的 border corner(边框角) CSS 属性:{{ cssxref("border-radius") }},{{ cssxref("border-top-left-radius") }},{{ cssxref("border-top-right-radius") }},{{ cssxref("border-bottom-left-radius") }} 和 {{ cssxref("border-bottom-right-radius") }} 。
  • -
  • 支持边框使用 {{cssxref("<image>")}}: {{ cssxref("border-image") }},{{ cssxref("border-image-source") }},{{ cssxref("border-image-slice") }},{{ cssxref("border-image-width") }},{{ cssxref("border-image-outset") }} 和 {{ cssxref("border-image-repeat") }} 。
  • -
  • 支持元素的阴影:{{ cssxref("box-shadow") }} 。
  • -
-
- -

背景和边框规范的 CSS4 迭代早已进行,即便它还没有达到 First Public Working Draft 阶段,它计划增加对边框的裁剪功能 (借助 CSS {{ cssxref("border-clip") }},{{ cssxref("border-clip-top") }},{{ cssxref("border-clip-right") }},{{ cssxref("border-clip-bottom") }} 和 {{ cssxref("border-clip-left") }} 属性) 或边框一角的形状 (使用 CSS {{ cssxref("border-corner-shape") }} 属性)。

- - - - - - - - - - - - - -
{{ SpecName("CSS3 Multicol", "", "") }}{{ Spec2("CSS3 Multicol") }}
增加简单的多列布局, 使用 CSS {{ cssxref("columns") }}, {{ cssxref("column-count") }}, {{ cssxref("column-fill") }}, {{ cssxref("column-gap") }}, {{ cssxref("column-rule") }}, {{ cssxref("column-rule-color") }}, {{ cssxref("column-rule-style") }}, {{ cssxref("column-rule-width") }}, {{ cssxref("column-span") }}, {{ cssxref("column-width") }}, {{ cssxref("break-after") }}, {{ cssxref("break-before") }}, 和{{ cssxref("break-inside") }}。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Speech", "", "") }}{{ Spec2("CSS3 Speech") }}
定义 speech 媒体类型,一个 aural formatting model(听觉格式化模型) 和多个用于 speech-rendering(语音呈现) 用户代理的属性。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Images", "", "") }}{{ Spec2("CSS3 Images") }}
-

定义 {{cssxref("<image>")}} 数据类型。

- -

扩充 url() 语法使其支持使用 media fragments(媒体片段) 来切割图片。

- -

增加:

- -
    -
  • {{cssxref("<resolution>")}} 数据类型的 dppx 单位。
  • -
  • image() 函数,作为 url() 的更具灵活性的替代版本, 使用 url 来定义图片。
    - 有风险:由于缺少足够的浏览器支持, image() 函数的标准化可能会被推迟到该模块的下一个迭代中。
  • -
  • 支持 linear-gradient(), repeating-linear-gradient()radial-gradient()repeating-radial-gradient()。
  • -
  • 使用 CSS {{ cssxref("object-fit") }} 属性来定义一个“替换元素”的“内容(Content)”如何适应包含这个“替换元素”的盒子。
    - 有风险: 由于缺少足够的浏览器支持, {{ cssxref("object-fit") }} 及其属性的标准化可能会被推迟到该模块的下一个迭代中。
  • -
  • 使用 CSS {{cssxref("image-resolution") }} 和 {{cssxref("image-orientation") }} 属性来覆盖一个外部图片的分辨率和方向。
    - 有风险:由于缺少足够的浏览器支持,{{cssxref("image-resolution") }} 和 {{ cssxref("image-orientation")}} 属性的标准化可能会被推迟到该模块的下一个迭代中。
  • -
-
- -

用于取代 CSS Image Level 3 的 CSS Image Values and Replaced Content Level 4 正在发展中,目前为 {{Spec2("CSS4 Images")}}。

- - - - - - - - - - - - - -
{{ SpecName("CSS3 Values", "", "") }}{{ Spec2("CSS3 Values") }}
-

使 initial 和 inherit 关键字能够被用于任意 CSS 属性中。

- -

正式定义了 CSS 2.1 中的 CSS 数据类型,之前是隐晦的由它们的语法记号和文本来定义。

- -

增加:

- -
    -
  • 定义了新的相对字体长度单位:rem 和 ch。
  • -
  • 定义了相对视口长度单位:vw,vh,vmax 和 vmin 。
  • -
  • 精确了绝对长度单位的实际尺寸,此前它们并非是绝对值,而是使用了 reference pixel(参考像素) 来定义。
  • -
  • 定义 {{ cssxref("<angle>") }},{{cssxref("<time>")}}, {{cssxref("<frequency>")}},{{cssxref("<resolution>")}}。
  • -
  • 规范 {{cssxref("<color>")}},{{cssxref("<image>")}} 和 {{cssxref("<position>")}} 定义的值。
  • -
  • {{cssxref("calc", "calc()") }},{{cssxref("attr", "attr()")}}和 toggle() 函数符号的定义。
  • -
- -

有风险: 由于缺少足够的浏览器支持,calc(), attr(), 和 toggle() 函数符号的标准化可能会被推迟到该模块的下一个迭代中。

-
- -

<ident> 和 <custom-ident> 这样的类型定义在 CSS Values and Units Module Level 4 中被推迟。

- - - - - - - - - - - - - -
{{ SpecName("CSS3 Flexbox", "", "") }}{{ Spec2("CSS3 Flexbox") }}
为 CSS {{ cssxref("display") }} 属性增加了 flexbox layout(伸缩盒布局) 及多个新 CSS 属性来控制它:{{ cssxref("flex") }},{{ cssxref("flex-align") }},{{ cssxref("flex-direction") }},{{ cssxref("flex-flow") }},{{ cssxref("flex-item-align") }},{{ cssxref("flex-line-pack") }},{{ cssxref("flex-order") }},{{ cssxref("flex-pack") }} 和 {{ cssxref("flex-wrap") }}。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Conditional", "", "") }}{{ Spec2("CSS3 Conditional") }}
增加了对样式表部分内容进行条件处理的功能, 若浏览器或文档的能力符合条件,则该部分的样式生效。它主要是允许了在 {{ cssxref("@media") }} 中嵌套 @ 规则, 增加了一个新的 CSS @ 规则, {{ cssxref("@supports") }} 和一个新的 DOM 方法 {{domxref("CSS.supports()")}}。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Text Decoration", "", "") }}{{ Spec2("CSS3 Text Decoration") }}
-

扩展:

- -
    -
  • CSS {{ cssxref("text-decoration") }} 属性作为 CSS {{ cssxref("text-decoration-line") }}, {{ cssxref("text-decoration-color") }}, 和 {{ cssxref("text-decoration-style") }} 属性的简写形式。并增加了 {{ cssxref("text-decoration-skip") }}, 和 {{ cssxref("text-underline-position") }} 属性。
  • -
- -

增加:

- -
    -
  • 使用 CSS {{ cssxref("text-emphasis") }}, {{ cssxref("text-emphasis-style") }}, {{ cssxref("text-emphasis-color") }}, 和 {{ cssxref("text-emphasis-position") }} 属性来支持 East-Asian-script emphasis marks(东亚文本重点符号)。
  • -
  • 使用 CSS {{ cssxref("text-shadow") }} 属性来支持文本的阴影。
  • -
- -

明确:

- -
    -
  • 装饰的绘制顺序。
  • -
- -

有风险: 由于缺少足够的浏览器支持,text-decoration-skip 行定位规则和在相同的基础文本上放置重点符号和 ruby 的能力的标准化可能会被推迟到该模块的下一个迭代中。

-
- - - - - - - - - - - -
{{ SpecName("CSS3 Fonts", "", "") }}{{ Spec2("CSS3 Fonts") }}
-

修正 CSS2.1 字体匹配算法,以便接近于真实的实现。

- -

增加:

- -
    -
  • 通过 CSS {{ cssxref("@font-face") }} @ 规则来支持可下载字体。
  • -
  • 借助 CSS {{ cssxref("font-kerning") }} 属性来控制 contextual inter-glyph spacing(上下文 inter-glyph 间距)。
  • -
  • 借助 CSS {{ cssxref("font-language-override") }} 属性来选择语言指定的字形。
  • -
  • 借助 CSS {{ cssxref("font-feature-settings") }} 属性来选择带有 OpenType 特性的字形。
  • -
  • 借助 CSS {{ cssxref("font-size-adjust") }} 属性来控制当使用 fallback fonts(备用字体) 时的宽高比。
  • -
  • 选择替代字体,使用 CSS {{ cssxref("font-stretch") }},{{ cssxref("font-variant-alternates") }},{{ cssxref("font-variant-caps") }},{{ cssxref("font-variant-east-asian") }},{{ cssxref("font-variant-ligatures") }},{{ cssxref("font-variant-numeric") }},和 {{ cssxref("font-variant-position") }} 属性。还扩展了相关的 CSS {{ cssxref("font-variant") }} 速记属性,并引入了 {{ cssxref("@font-features-values") }} @ 规则。
  • -
  • 当这些字体在 CSS {{ cssxref("font-synthesis") }} 属性中找不到时自动生成斜体或粗体的控制。
  • -
-
- - - - - - - - - - - -
{{ SpecName("CSS3 Cascade", "", "") }}{{ Spec2("CSS3 Cascade") }}
-

增加:

- -
    -
  • 属性的初始值和未设定值。
  • -
  • CSS {{ cssxref("all") }} 属性。
  • -
  • 域机制。
  • -
- -

明确:

- -
    -
  • 与媒体依赖的@import声明交互与样式表的加载要求。
  • -
-
- - - - - - - - - - - -
{{ SpecName("CSS3 Writing Modes", "", "") }}{{ Spec2("CSS3 Writing Modes") }}
定义了水平和垂直脚本书写模式,概况了 CSS {{ cssxref("direction") }} 和 {{ cssxref("unicode-bidi") }} 属性是如何与新 CSS {{ cssxref("text-orientation") }} 属性相互之间产生影响的,并在需要它们的地方扩展它们。
- - - - - - - - - - - -
{{ SpecName("CSS Shapes", "", "") }}{{ Spec2("CSS Shapes") }}
-

定义了可用于浮动(float)的几何图形。这些图形描述了行内元素可被包裹的区域,而非包裹其边界框( bounding box)。

-
- - - - - - - - - - - -
{{ SpecName("CSS Masks", "", "") }}{{ Spec2("CSS Masks") }}
-

定义了部分或完整隐藏可视元素的一种方式。其描述了如何使用另一图形元素或图片作为亮度遮罩(luminance)或透明度遮罩(alpha)。

-
- -

处于改善阶段的模块

- -

处于改善阶段(refining phase)的规范已基本稳定。虽然还有可能被修改,但不会和当前的实现产生冲突;其主要定义在个别特殊情况的行为。

- - - - - - - - - - - -
{{ SpecName("Web Animations", "", "") }}{{ Spec2("Web Animations") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Counter Styles", "", "") }}{{ Spec2("CSS3 Counter Styles") }}
 
- - - - - - - - - - - -
{{ SpecName("Compositing", "", "") }}{{ Spec2("Compositing") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Syntax", "", "") }}{{ Spec2("CSS3 Syntax") }}
澄清如何确定字符集; 分析和标记化算法的最小变化。
- - - - - - - - - - - -
{{ SpecName("CSS Will Change", "", "") }}{{ Spec2("CSS Will Change") }}
 
- - - - - - - - - - - - - - - -
{{ SpecName("CSS3 Transitions", "", "") }}{{ Spec2("CSS3 Transitions") }}
通过增加 CSS {{ cssxref("transition") }},{{ cssxref("transition-delay") }},{{ cssxref("transition-duration") }}, {{ cssxref("transition-property") }},和 {{ cssxref("transition-timing-function") }} 属性来支持定义两个属性值间的 transitions effects(过渡效果)。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Animations", "", "") }}{{ Spec2("CSS3 Animations") }}
允许定义动画效果, 借助于新增的 CSS {{ cssxref("animation") }}, {{ cssxref("animation-delay") }}, {{ cssxref("animation-direction") }}, {{ cssxref("animation-duration") }}, {{ cssxref("animation-fill-mode") }}, {{ cssxref("animation-iteration-count") }}, {{ cssxref("animation-name") }}, {{ cssxref("animation-play-state") }}, 和 {{ cssxref("animation-timing-function") }} 属性, 以及 {{ cssxref("@keyframes") }} @ 规则。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Transforms", "", "") }}{{ Spec2("CSS3 Transforms") }}
-

增加:

- -
    -
  • 支持适用于任何元素的 bi-dimensional transforms(二维变形),使用 CSS {{ cssxref("transform") }} 和 {{ cssxref("transform-origin") }} 属性。支持的变形有: matrix()translate()translateX()translateY(, scale()scaleX()scaleY()rotate()skewX(),和 skewY()。
  • -
  • 支持适用于任何元素的 tri-dimensional transforms(三维变形),使用 CSS  {{ cssxref("transform-style") }}, {{ cssxref("perspective") }}, {{ cssxref("perspective-origin") }}, 和 {{ cssxref("backface-visibility") }} 属性和扩展的 {{ cssxref("transform") }} 属性,使用以下变形: matrix 3d(), translate3d()translateZ()scale3d()scaleZ()rotate3d()rotateX()rotateY()rotateZ(),和 perspective()。
  • -
- -

注意: 该规范是 CSS 2D-Transforms, CSS 3D-Transforms 和 SVG transforms 合并的结果。

-
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Fragmentation", "", "") }}{{ Spec2("CSS3 Fragmentation") }}
-

定义了网页的分割将如何实行,即分页、分栏,以及窗口和孤儿页面的处理。

- -

增加:

- -
    -
  • 通过 CSS {{ cssxref("box-decoration-break") }} 属性定义一个盒(box)被在页、栏或行被分割时,诸如边框与背景颜色或图片等修饰行为的支持。
  • -
-
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Text", "", "") }}{{ Spec2("CSS3 Text") }}
-

扩展:

- -
    -
  • CSS {{ cssxref("text-transform") }} 属性的值 full-width。
  • -
  • CSS {{ cssxref("text-align") }} 属性的值 startendstart end,和 match-parent,为包含多个方向文本的文档提供良好支持。
  • -
  • CSS {{ cssxref("text-align") }} 属性的 {{cssxref("<string>")}} 值来根据该字符对齐。对于数字的小数点对齐特别有用。
  • -
  • CSS {{ cssxref("word-spacing") }} 和 {{ cssxref("letter-spacing") }} 属性拥有范围限制,来控制两端对齐时的灵活性。
  • -
- -

增加:

- -
    -
  • 使用 CSS {{ cssxref("text-space-collapse") }} 和 {{ cssxref("tab-size") }} 属性来控制空白该如何显示。
  • -
  • 使用 CSS {{ cssxref("line-break") }},{{ cssxref("word-break") }},{{ cssxref("hyphens") }},{{ cssxref("text-wrap") }},{{ cssxref("overflow-wrap") }},和 {{ cssxref("text-align-last") }} 属性来控制折行和单词边界。
  • -
  • 使用 CSS {{ cssxref("text-justify") }} 属性来控制两端对齐的行为,这是为了对更多语言类型增加支持。
  • -
  • 使用 CSS {{ cssxref("text-indent") }} 和 {{ cssxref("hanging-punctuation") }} 属性来控制 edge effect(边缘影响)。
  • -
-
- -

一部分出现在早期 CSS Text Level 3 草案中的特性被推迟到了该规范的下个迭代中

- - - - - - - - - - - -
{{ SpecName("CSS3 Variables", "", "") }}{{ Spec2("CSS3 Variables") }}
定义了允许在 CSS 中定义变量的机制。
- - - - - - - - - - - -
{{ SpecName("Compositing", "", "") }}{{ Spec2("Compositing") }}
 
- - - -

处于修正阶段的模块

- -

处于修正阶段的模块没处于改善阶段的模块稳定。它们的语法一般还需要详细审查,可能还会有些大变化,还有可能不兼容之前的规范。替代语法已通过测试并被广泛实践。

- - - - - - - - - - - -
{{ SpecName("CSS3 Basic UI", "", "") }}{{ Spec2("CSS3 Basic UI") }}
-

增加:

- -
    -
  • 使用 CSS {{ cssxref("box-sizing") }} 属性来转换盒模型的能力。
    - 处于风险中 由于缺少足够的浏览器支持 , padding-box 值的标准化可能会被推迟到该模块的下一个迭代中。
  • -
  • 根据表单内容来设置样式, 使用 CSS {{ cssxref(":indeterminate") }}, {{ cssxref(":default") }}, {{ cssxref(":valid") }}, {{ cssxref(":invalid") }}, {{ cssxref(":in-range") }}, {{ cssxref(":out-of-range") }}, {{ cssxref(":required") }}, {{ cssxref(":optional") }}, {{ cssxref(":read-only") }},和 {{ cssxref(":read-write") }} 伪类与 {{ cssxref("::value") }}, {{ cssxref("::choices") }}, {{ cssxref("::repeat-item") }}, 和 {{ cssxref("::repeat-index") }} 伪元素。
    - 处于风险中 由于缺少足够的浏览器支持 ,伪元素 {{ cssxref("::value") }}, {{ cssxref("::choices") }}, {{ cssxref("::repeat-item") }}, 和 {{ cssxref("::repeat-index") }} 标准化可能会被推迟到该模块的下一个迭代中。
  • -
  • 支持图标,通过 CSS {{ cssxref("icon") }} 属性定义, 同时在 CSS {{ cssxref("content") }} 属性中设置新图标的值。
    - 处于风险中 由于缺少足够的浏览器支持 ,{{ cssxref("icon") }} 属性和 icon 值标准化可能会被推迟到 CSS 4 中。
  • -
  • 支持 CSS {{ cssxref("outline-offset") }} 属性, 这样可以对 outline 的位置做更多的控制。
  • -
  • 支持 CSS {{ cssxref("resize") }} 属性, Web 开发者可以控制元素是否能够以及如何调整大小。
  • -
  • 支持 CSS {{ cssxref("text-overflow") }} 属性, 定义文本溢出的行为。
    - 处于风险中 由于缺少足够的浏览器支持 ,该属性的双值语法也和 {{cssxref("<string>")}} 值一样, 它们的标准化可能会被推迟到该模块的下一个迭代中。
  • -
  • 定义鼠标 hotspot(热点) 的功能, 扩展了 {{ cssxref("cursor") }} 属性, 增加了新值:  none, context-menu, cell, vertical-text, alias, copy, no-drop, not-allowed, nesw-resize, nwse-resize, col-resize, row-resize, all-scroll, zoom-in, zoom-out。
  • -
  • 指定 sequential navigation order(连续导航顺序, 即 tabbing order(移动顺序)) 的功能, 使用 CSS {{ cssxref("nav-index") }}, {{ cssxref("nav-up") }}, {{ cssxref("nav-right") }}, {{ cssxref("nav-left") }}, {{ cssxref("nav-down") }} 属性。
    - 处于风险中 由于缺少足够的浏览器支持,导航属性标准化可能会被推迟到该模块的下一个迭代中。
  • -
  • 控制 IME editor(输入法编辑器) 使用的功能, 使用 CSS {{ cssxref("ime-mode") }} 属性。
    - 处于风险中 由于缺少足够的浏览器支持,{{ cssxref("ime-mode") }}属性标准化可能会被推迟到该模块的下一个迭代中。
  • -
-
- -

这里提供了会出现在下次  CSS Basic User Interface Module 迭代中的功能列表。

- - - - - - - - - - - -
{{ SpecName("CSS3 Grid", "", "") }}{{ Spec2("CSS3 Grid") }}
添加了 grid 布局给 CSS display 属性,以及一些新的属性来控制它:{{cssxref("grid")}},{{cssxref("grid-area")}},{{cssxref("grid-auto-columns")}},{{cssxref("grid-auto-flow")}},{{cssxref("grid-auto-position")}}, {{cssxref("grid-auto-rows")}}, {{cssxref("grid-column")}}, {{cssxref("grid-column-start")}}, {{cssxref("grid-column-end")}}, {{cssxref("grid-row")}}, {{cssxref("grid-row-start")}}, {{cssxref("grid-row-end")}}, {{cssxref("grid-template")}}, {{cssxref("grid-template-areas")}}, {{cssxref("grid-template-rows")}}, and {{cssxref("grid-template-columns")}}.
- - - - - - - - - - - -
{{ SpecName("CSS3 Box Alignment", "", "") }}{{ Spec2("CSS3 Box Alignment") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Paged Media", "", "") }}{{ Spec2("CSS3 Paged Media") }}
 
- - - - - - - - - - - -
{{ SpecName("CSSOM View", "", "") }}{{ Spec2("CSSOM View") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS4 Selectors", "", "") }}{{ Spec2("CSS4 Selectors") }}
 
- - - -

处于探索阶段的模块

- - - - - - - - - - - - - -
{{ SpecName("CSS4 Images", "", "") }}{{ Spec2("CSS4 Images") }}
-

扩展:

- -
    -
  • image() 函数标记来描述图片 (rtl 或 ltr) 的方向性,允许 bidi-sensitive(双向敏感) 的图片。
  • -
  • 为 {{ cssxref("image-orientation") }} 属性增加关键字 from-image,允许使用存储在图片中的 EXIF 数据。
  • -
- -

增加:

- -
    -
  • image-set() 函数标记,允许定义不同分辨率下的对应图片实现依据分辨率选择图片。
  • -
  • element() 函数标记, 允许将页面的部分当作图片来使用。
  • -
  • cross-fade() 函数标记, 允许在两张图片之间过渡时使用中间图片,并定义了两张图片间的 interpolation(插值)。
  • -
  • conic-gradient() 和 repeating-conic-gradient() 函数标记,描述了一种新的渐变类型。
  • -
  • {{cssxref("image-rendering")}} 属性允许定义如何处理改变图片大小的行为。
  • -
-
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Device", "", "") }}{{ Spec2("CSS3 Device") }}
增加一个新的 @ 规则, {{ cssxref("@viewport") }},允许为视口指定尺寸(size)、缩放因子(zoom factor)和方向(orientation),这些将作为 initial containing block(初始包含块) 的基础。
- - - - - - - - - - - - - - - -
{{ SpecName("CSS3 GCPM", "", "") }}{{ Spec2("CSS3 GCPM") }}
增加调整打印版本的功能,允许控制页头,页脚,同时引用表索引或表内容。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Exclusions", "", "") }}{{ Spec2("CSS3 Exclusions") }}
扩展浮动机制,在任何定位方案中生成一个 exclusion regions(排斥区域)。增加形状标记,其中的内容必须流动。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Lists", "", "") }}{{ Spec2("CSS3 Lists") }}
扩展了列表计数机制, 这样可以为列表标记设置样式,并使 Web 开发者定义新的列表计数方案。
- - - - - - - - - - - - - -
{{ SpecName("CSS3 Regions", "", "") }}{{ Spec2("CSS3 Regions") }}
-

定义了一种可使内容流动至数个非连续空间的机制,称为区域(Regions)。

-
- - - - - - - - - - - - - -
{{ SpecName("Filters 1.0", "", "") }}{{ Spec2("Filters 1.0") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Template", "", "") }}{{ Spec2("CSS3 Template") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Sizing", "", "") }}{{ Spec2("CSS3 Sizing") }}
 
- - - - - - - - -
{{ SpecName("CSS Line Grid", "", "") }}{{ Spec2("CSS Line Grid") }}
- - - - - - - - - - - -
{{ SpecName("CSS3 Positioning", "", "") }}{{ Spec2("CSS3 Positioning") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Ruby", "", "") }}{{ Spec2("CSS3 Ruby") }}
 
- - - - - - - - - - - -
{{ SpecName("CSSOM", "", "") }}{{ Spec2("CSSOM") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Overflow", "", "") }}{{ Spec2("CSS3 Overflow") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Font Loading", "", "") }}{{ Spec2("CSS3 Font Loading") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Display", "", "") }}{{ Spec2("CSS3 Display") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS Scope", "", "") }}{{ Spec2("CSS Scope") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS4 Media Queries", "", "") }}{{ Spec2("CSS4 Media Queries") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS Non-element Selectors", "", "") }}{{ Spec2("CSS Non-element Selectors") }}
 
- - - - - - - - - - - -
{{ SpecName("Geometry Interfaces", "", "") }}{{ Spec2("Geometry Interfaces") }}
 
- - - - - - - - - - - -
{ SpecName("CSS3 Inline", "", "") }}{{ Spec2("CSS3 Inline") }}
 
- -

在重写的模块

- -

以下模块已经过时,需要重写。语法仍然在审查,可能会以不兼容的方式发展出很多。替代语法已通过测试并被广泛实践。

- - - - - - - - - - - -
{{ SpecName("CSS3 Box", "", "") }}{{ Spec2("CSS3 Box") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Content", "", "") }}{{ Spec2("CSS3 Content") }}
 
- - - - - - - - - - - -
{{ SpecName("CSS3 Inline Layout", "", "") }}{{ Spec2("CSS3 Inline Layout") }}
 
- -

 

diff --git a/files/zh-cn/archive/firefox_os/api/simple_push_api/index.html b/files/zh-cn/archive/firefox_os/api/simple_push_api/index.html deleted file mode 100644 index 51c37e99ca..0000000000 --- a/files/zh-cn/archive/firefox_os/api/simple_push_api/index.html +++ /dev/null @@ -1,232 +0,0 @@ ---- -title: Simple Push -slug: Archive/Firefox_OS/API/Simple_Push_API -tags: - - Simple Push -translation_of: Archive/B2G_OS/API/Simple_Push_API ---- -
{{obsolete_header("51")}} {{non-standard_header}}
- -
-

Note: The proprietary Simple Push API is deprecated in favor of the W3C Push API.

-
- -

简单推送A​​PI,也称为推送通知API,提供应用程式唤醒以接收通知的功能。您可以使用简单推送作为一个同步机制,甚至可以从第三方服务器获取最新数据。

- -

推送就是从远程服务端发来的一个事件.他的工作原理如下: An app uses the Simple Push API to request a special, unique URL called an endpoint. This request goes to an existing server maintained by Mozilla for this purpose (this is called the "push server"). When the app receives the endpoint back from the push server, the app sends the endpoint to its own server (your app server). The app server stores this endpoint, then when it wants to wake up the app, it calls the endpoint with a version number, and the push server contacts the app with a notification of the version number. The app can be made to do something when it receives the notification, including ignoring it.

- -

The Simple Push API extends Window.navigator with a push property which is a {{domxref("PushManager")}} object, and adds some new events you can receive to monitor the push status.

- -

基础示例

- -

There are several ways to use the Simple Push API. This example covers the basics of how to use it. The example consists of the general steps below. See the following sections for full information on each step.

- -
    -
  1. Add push configuration to the app's manifest file
  2. -
  3. Call PushManager.register to request an endpoint
  4. -
  5. Send the endpoint to your server
  6. -
  7. Add message handlers for push notifications to your app
  8. -
  9. Send a notification from your server using the endpoint
  10. -
- -

1. Add push configuration to the app's manifest file

- -

You need to change two things in the app's manifest file so it can use Simple Push:

- -
    -
  1. messages field - Add push and push-register to messages.
    - These indicate the app page that will receive each of these events (push and push-register). In this example, both are going to the same page: "/index.html", but they can use other pages also. See below for a more information on each of these events.
  2. -
  3. permissions field - Add that your app wants to receive push notifications.
    - It's a good idea to provide a clear description here so that the end user will understand why you need push permissions.
  4. -
- -
"messages": [
-   { "push": "/index.html"},
-   { "push-register": "/index.html"}
-],
-"permissions": {
-  "push": {
-    "description": "Required for being updated with new goals in soccer matches"
-  }
-}
- -

2. Call PushManager.register() to request an endpoint

- -

The app needs to request an endpoint by calling {{domxref("PushManager.register")}}. You have to decide when this should be called. You could call it when the user has logged in to your service, or when the user decides to start watching a soccer match, or at some other point. The code below is one way to do it.

- -
if (navigator.push) {
-  // Request the endpoint. This uses PushManager.register().
-  var req = navigator.push.register();
-
-  req.onsuccess = function(e) {
-    var endpoint = req.result;
-      console.log("New endpoint: " + endpoint );
-      // At this point, you'd use some call to send the endpoint to your server.
-      // For instance:
-      /*
-      var post = XMLHTTPRequest();
-      post.open("POST", "https://your.server.here/registerEndpoint");
-      post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
-      post.send("endpoint=" + encodeURIComponents( endpoint ) );
-      */
-      // Obviously, you'll want to add .onload and .onerror handlers, add user id info,
-      // and whatever else you might need to associate the endpoint with the user.
-    }
-
-   req.onerror = function(e) {
-     console.error("Error getting a new endpoint: " + JSON.stringify(e));
-   }
-} else {
-  // push is not available on the DOM, so do something else.
-}
- -

3. Send the endpoint to your server

- -

Once the app has received an endpoint, it needs to send it to your app server. There is more than one way to do this. For example you can send it by email, or send it by POST, PUT, or even GET. We recommend that you store the endpoint with some user data from the app, such as a cookie, a username, or whatever you use to identify your endpoint-user pair.

- -

But if you are sending to your server, we recommend that you follow these good practices:

- - - -

4. Add message handlers for push notifications to your app

- -

Once you have set up your endpoint as in the steps above, you are ready to have the app start listening for push and push-register messages using message handlers. 

- -

Add a push message handler

- -

The push message handler could be in your index.html file or in your main.js script, or even in a specific push-message.html file that contains only the message handler. That could be useful if a push message is sent and your app is closed, because it will load just a small part of the HTML/JavaScript code, and you can decide if the app needs to be fully open or do something in the background. Wherever you decide to place the push message handler, make sure that the manifest file points to the right location (see the first step above), otherwise your app may not get updates. Here is an example of a push message handler:

- -
if (window.navigator.mozSetMessageHandler) {
-  window.navigator.mozSetMessageHandler('push', function(e) {
-    console.log('My endpoint is ' + e.pushEndpoint);
-    console.log('My new version is ' +  e.version);
-    //Remember that you can handle here if you have more than
-    //one pushEndpoint
-    if (e.pushEndpoint === emailEndpoint) {
-      emailHandler(e.version);
-    } else if (e.pushEndpoint === imEndpoint) {
-      imHandler(e.version);
-    }
-  });
-} else {
-  // No message handler
-}
- -

Add a push-register message handler

- -
-

Note: Be sure to add this handler and check that it works. If you do not re-register your endpoints when this message is received by your app, the app WILL NOT BE ABLE to receive further push notifications.

-
- -

A push-register message will be sent to all apps when the device changes its internal identifier (called the UAID or User Agent Identifier). This could be because the push server has changed, or it has gone down and needs to recover, or other circumstances. If one of these things occurs, you MUST re-register all your endpoints, because your previous endpoints will not be valid anymore. Therefore your app needs to implement a push-register message handler. See the example code below.

- -
if (window.navigator.mozSetMessageHandler) {
-  window.navigator.mozSetMessageHandler('push-register', function(e) {
-    console.log('push-register received, I need to register my endpoint(s) again!');
-
-    var req = navigator.push.register();
-    req.onsuccess = function(e) {
-      var endpoint = req.result;
-      console.log("New endpoint: " + endpoint );
-      localStorage.endpoint = endpoint;
-    }
-
-    req.onerror = function(e) {
-      console.error("Error getting a new endpoint: " + JSON.stringify(e));
-    }
-  });
-} else {
-  // No message handler
-}
- -

5. Send a notification from your server using the endpoint

- -

Once you have the endpoint on your server, you can send a notification by simply sending an HTTP PUT request to the endpoint with the body version=<version>. For example, imagine an endpoint with this URL:

- -
https://updates.push.services.mozilla.com/update/abcdef01234567890abcdefabcdef01234567890abcdef
- -

and version 5:

- -
version=5
- -

Here is how the notification looks using curl:

- -
curl -X PUT -d "version=5" https://updates.push.services.mozilla.com/update/abcdef01234567890abcdefabcdef01234567890abcdef
- -

If the push server is running correctly, you will get a response with a 200 Status (OK) and a {} as a body. You may also receive a 202 Status, indicating that the message was accepted, but may be handled using an alternate system. If not, a valid HTTP error response with JSON explaining the error is returned.

- -
-

Please remember: Just because Simple Push has accepted the message, there is no guarantee that the message will be delivered successfully to the app. Many factors, ranging from a device being offline to various network failures, may prevent successful delivery of a notification. We try our best, but sometimes the universe has other plans.

-
- -

Remember that the value of version should be integer numbers, and incremental. Apps will not get new notifications if the new version is lower than that stored on the server and/or device. Versions can be useful to the app to indicate if there are "missed" events it should really check up on. You could also just use the current UTC (the number of seconds since midnight, Jan. 1, 1970, GMT) if the actual version value isn't very important to you.

- -

Unregister an endpoint

- -

Once you finish using an endpoint and you do not want to receive more notifications, we kindly ask you to unregister the old endpoint using {{domxref("PushManager.unregister")}}. This will clean up the amount of data the device sends to the push server, and will also will lower the battery usage by not sending notifications for apps that will not use them.

- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

See also

- - diff --git a/files/zh-cn/archive/index.html b/files/zh-cn/archive/index.html deleted file mode 100644 index 44a6ec1584..0000000000 --- a/files/zh-cn/archive/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Archive of obsolete content -slug: Archive -translation_of: Archive ---- -

在MDN,我们尽量避免直接删除可能对以传统平台,操作系统和浏览器为目标的人有用的内容。例如,您的目标受众可能是使用旧硬件的用户,而无法升级到最新,最好的浏览器。或者出于“原因”,您的公司需要使用非常旧的软件,您需要构建在该软件上运行的Web内容。或者,您可能只是对过时的功能或API的历史以及它的工作方式感到好奇。 
-  
- 旧文档可能有用的原因有很多。所以,我们已经建立了这个可以归档旧文档的区域。此存档内容区域中的材料不应用于为现代浏览器构建新的网站或应用程序。这里仅供参考。

- -
-

请写作者注意: 我们需要尽量保持这里的子页面,而不是全部转储到一个大文件夹中。尝试创建子类别的材料的子树。此外,只能移动这里非常过时的页面。如果有人可能真的需要实时产品的信息,可能不适合移动在这里。一般来说,在移动内容之前,最好在Matrix频道 MDN Web Docs 中进行讨论。

-
- -

{{SubpagesWithSummaries}}

- - - -

{{ListSubpages("/en-US/docs/Archive", 2, 0, 1)}}

diff --git a/files/zh-cn/archive/jxon/index.html b/files/zh-cn/archive/jxon/index.html deleted file mode 100644 index 1b7c1d69e2..0000000000 --- a/files/zh-cn/archive/jxon/index.html +++ /dev/null @@ -1,1513 +0,0 @@ ---- -title: JXON -slug: Archive/JXON -translation_of: Archive/JXON ---- -

JXON (无损 JavaScript XML对象注释)  是一个通用名称,通过它定义使用 XML的JavaScript对象的表示。 这种转换没有真正的标准,但一些公约开始出现在网络上。在某些情况下,必须从JavaScript解释器中读取XML文档的全部内容(例如用于Web应用程序语言或设置XML文档)。在这些情况下,JXON可能是最实用的方法。

- -

在本文中,我们将演示如何将解析的XML Document(即Document的一个实例)转换为JavaScript Object树(即Object的嵌套实例树),反之亦然,用一些不同的算法。首先阅读XML介绍文章会比较有帮助。

- -

如果您想要一个完整的双向JXON库(在JSON全局对象上建模),请跳至专用段落(但请阅读关于const语句兼容性的注释)。

- -
注意:如果您只想解决XML文档的某些部分(而不是以JavaScript / JSON为模板目的开始),则使用XPath而不是将整个文档转换为JSON。
- -

Conversion snippets

- -

现在想象你有这个示例XML文档:

- -
example.xml
- -
<?xml version="1.0"?>
-<!DOCTYPE catalog SYSTEM "catalog.dtd">
-<catalog>
-  <product description="Cardigan Sweater">
-   <catalog_item gender="Men's">
-     <item_number>QWZ5671</item_number>
-     <price>39.95</price>
-     <size description="Medium">
-       <color_swatch image="red_cardigan.jpg">Red</color_swatch>
-       <color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
-     </size>
-     <size description="Large">
-       <color_swatch image="red_cardigan.jpg">Red</color_swatch>
-       <color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
-     </size>
-   </catalog_item>
-   <catalog_item gender="Women's">
-     <item_number>RRX9856</item_number>
-     <discount_until>Dec 25, 1995</discount_until>
-     <price>42.50</price>
-     <size description="Medium">
-       <color_swatch image="black_cardigan.jpg">Black</color_swatch>
-     </size>
-   </catalog_item>
-  </product>
-  <script type="text/javascript"><![CDATA[function matchwo(a,b) {
-    if (a < b && a < 0) { return 1; }
-    else { return 0; }
-}]]></script>
-</catalog>
-
- -

首先,按照“如何创建DOM树”文章中的描述,创建一个类似前面示例的DOM树。如果您已经有使用XMLHttpRequest的DOM树,请跳到下一段。

- -
注意:如果您正在使用XMLHttpRequest实例来检索XML文件,请使用yourRequest.responseXML属性来获取已解析的XML文档。不要使用yourRequest.responseText
- -

这里提出的算法(参见:#1#2#3#4)将只考虑以下类型的节点及其属性:

- -
    -
  1. Document (只作为函数参数),
  2. -
  3. DocumentFragment (只作为函数参数),
  4. -
  5. Element,
  6. -
  7. Text (从不作为函数参数),
  8. -
  9. CDATASection (从不作为函数参数),
  10. -
  11. Attr (从不作为函数参数)。
  12. -
- -

对于JavaScript的使用来说,这是一个很好的标准化的妥协,因为XML文档的所有信息都包含在这些节点类型中。所有其他信息(如处理指令,模式,注释等)都将丢失。这种算法仍然被认为是无损的,因为丢失的是元信息而不是信息

- -

为了避免冲突,节点和属性名称的表示不区分大小写(总是以小写形式呈现),所以使用JavaScript设置的对象的本地属性名称必须总是具有某种大小写(即至少有一个大写字母在他们的名字),如你可以看到下面。

- -

下面的算法有些基于Parker公约(版本0.4),它规定了标签名称对象属性名称的转换以及每个标签(纯文本解析)的所有收集 text content typeof 的识别。但有一些分歧(所以,可以说我们遵循我们的惯例)。而且,对于设想的节点,所有算法都是同样无损的

- -

我们认为第三种算法最具代表性和实用性的JXON解析算法

- -

现在让我们将doc(DOM树)序列化为一个JavaScript对象树(您可以阅读关于使用对象以及Javascript如何面向对象的更多信息)。我们可以使用几种算法将其内容转换为Javascript对象树。

- -

算法 #1: 一个冗长的方式

- -

这个简单的递归构造函数将一个XML DOM树转换成一个JavaScript对象树。每个元素的文本内容都存储在keyValue属性中,而nodeAttributes(如果存在)列在子对象keyAttributes下。构造函数的参数可以是整个XML DocumentDocumentFragment或简单的Element节点。

- -
/*\
-|*|
-|*|  JXON Snippet #1 - Mozilla Developer Network
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/JXON
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|
-|*|  This framework is released under the GNU Public License, version 3 or later.
-|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
-|*|
-\*/
-
-function parseText (sValue) {
-  if (/^\s*$/.test(sValue)) { return null; }
-  if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === "true"; }
-  if (isFinite(sValue)) { return parseFloat(sValue); }
-  if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
-  return sValue;
-}
-
-function JXONTree (oXMLParent) {
-  var nAttrLen = 0, nLength = 0, sCollectedTxt = "";
-  if (oXMLParent.hasChildNodes()) {
-    for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
-      oNode = oXMLParent.childNodes.item(nItem);
-      if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; } // nodeType is "Text" (3) or "CDATASection" (4)
-      else if (oNode.nodeType === 1 && !oNode.prefix) { // nodeType is "Element" (1)
-        sProp = oNode.nodeName.toLowerCase();
-        vContent = new JXONTree(oNode);
-        if (this.hasOwnProperty(sProp)) {
-          if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }
-          this[sProp].push(vContent);
-        } else { this[sProp] = vContent; nLength++; }
-      }
-    }
-    this.keyValue = parseText(sCollectedTxt);
-  } else { this.keyValue = null; }
-  if (oParentNode.hasAttributes && oXMLParent.hasAttributes()) {
-    var oAttrib;
-    this.keyAttributes = {};
-    for (nAttrLen; nAttrLen < oXMLParent.attributes.length; nAttrLen++) {
-      oAttrib = oXMLParent.attributes.item(nAttrLen);
-      this.keyAttributes[oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
-    }
-  }
-  /*
-  * Optional properties...
-
-  this.keyLength = nLength;
-  this.attributesLength = nAttrLen;
-  // this.DOMNode = oXMLParent;
-
-  */
-
-  /* Object.freeze(this); */
-}
-
-/*
-* Optional methods... Uncomment the optional properties first!
-
-JXONTree.prototype.valueOf = function () { return this.keyValue; };
-JXONTree.prototype.toString = function () { return String(this.keyValue); };
-JXONTree.prototype.getItem = function (nItem) {
-  if (nLength === 0) { return null; }
-  var nCount = 0;
-  for (var sKey in this) { if (nCount === nItem) { return this[sKey]; } nCount++; }
-  return null;
-};
-JXONTree.prototype.getAttribute = function (nAttrId) {
-  if (nAttrLen === 0 || nAttrId + 1 > nAttrLen) { return null; }
-  var nAttr = 0;
-  for (var sAttrName in this.keyAttributes) { if (nAttr === nAttrId) { return this.keyAttributes[sAttrName]; } nAttr++; }
-  return null;
-};
-JXONTree.prototype.hasChildren = function () { return this.keyLength > 0; };
-
-*/
-
-var myObject = new JXONTree(doc);
-// we got our javascript object! try: alert(JSON.stringify(myObject));
-
- -
注意:如果你想冻结整个对象树(因为XML文档的“静态”性质),取消注释字符串:/* Object.freeze(this); */Object.freeze()方法防止将新属性添加到该属性中,防止现有属性被删除,并防止现有属性或其可枚举性,可配置性或可写性发生更改。本质上,对象树是有效的不可变的。
- -

 

- -

用这个算法我们的例子变成:

- -
{
- "catalog": {
-   "product": {
-     "catalog_item": [{
-       "item_number": {
-         "keyValue": "QWZ5671"
-       },
-       "price": {
-         "keyValue": 39.95
-       },
-       "size": [{
-         "color_swatch": [{
-           "keyValue": "Red",
-           "keyAttributes": {
-             "image": "red_cardigan.jpg"
-           }
-         }, {
-           "keyValue": "Burgundy",
-           "keyAttributes": {
-             "image": "burgundy_cardigan.jpg"
-           }
-         }],
-         "keyValue": null,
-         "keyAttributes": {
-           "description": "Medium"
-         }
-       }, {
-         "color_swatch": [{
-           "keyValue": "Red",
-           "keyAttributes": {
-             "image": "red_cardigan.jpg"
-           }
-         }, {
-           "keyValue": "Burgundy",
-           "keyAttributes": {
-             "image": "burgundy_cardigan.jpg"
-           }
-         }],
-         "purchased": {
-           "keyValue": null
-         },
-         "keyValue": null,
-         "keyAttributes": {
-           "description": "Large"
-         }
-       }],
-       "keyValue": null,
-       "keyAttributes": {
-         "gender": "Men's"
-       }
-     }, {
-       "item_number": {
-         "keyValue": "RRX9856"
-       },
-       "discount_until": {
-         "keyValue": new Date(1995, 11, 25)
-       },
-       "price": {
-         "keyValue": 42.5
-       },
-       "size": {
-         "color_swatch": {
-           "keyValue": "Black",
-           "keyAttributes": {
-             "image": "black_cardigan.jpg"
-           }
-         },
-         "keyValue": null,
-         "keyAttributes": {
-           "description": "Medium"
-         }
-       },
-       "keyValue": null,
-       "keyAttributes": {
-         "gender": "Women's"
-       }
-     }],
-     "keyValue": null,
-     "keyAttributes": {
-       "description": "Cardigan Sweater"
-     }
-   },
-   "script": {
-     "keyValue": "function matchwo(a,b) {\n if (a < b && a < 0) { return 1; }\n else { return 0; }\n}",
-     "keyAttributes": {
-       "type": "text/javascript"
-     }
-   },
-   "keyValue": null
- },
- "keyValue": null
-}
-
- -

如果您部分了解XML文档的结构,则可以使用这种技术。

- -

算法 #2: 一个不太冗长的方式

- -

这里是另一个更简单的转换方法,其中nodeAttributes列在子节点的同一对象下,但带有“@”前缀(由BadgerFish Convention提出)。如上所述,文本内容存储在keyValue属性中。构造函数的参数可以是整个XML Document,一个DocumentFragment或简单的Element节点。

- -
/*\
-|*|
-|*|  JXON Snippet #2 - Mozilla Developer Network
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/JXON
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|
-|*|  This framework is released under the GNU Public License, version 3 or later.
-|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
-|*|
-\*/
-
-function parseText (sValue) {
-  if (/^\s*$/.test(sValue)) { return null; }
-  if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === "true"; }
-  if (isFinite(sValue)) { return parseFloat(sValue); }
-  if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
-  return sValue;
-}
-
-function JXONTree (oXMLParent) {
-  if (oXMLParent.hasChildNodes()) {
-    var sCollectedTxt = "";
-    for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
-      oNode = oXMLParent.childNodes.item(nItem);
-      if ((oNode.nodeType - 1 | 1) === 3) { sCollectedTxt += oNode.nodeType === 3 ? oNode.nodeValue.trim() : oNode.nodeValue; }
-      else if (oNode.nodeType === 1 && !oNode.prefix) {
-        sProp = oNode.nodeName.toLowerCase();
-        vContent = new JXONTree(oNode);
-        if (this.hasOwnProperty(sProp)) {
-          if (this[sProp].constructor !== Array) { this[sProp] = [this[sProp]]; }
-          this[sProp].push(vContent);
-        } else { this[sProp] = vContent; }
-      }
-    }
-    if (sCollectedTxt) { this.keyValue = parseText(sCollectedTxt); }
-  }
-  if (oParentNode.hasAttributes && oXMLParent.hasAttributes()) {
-    var oAttrib;
-    for (var nAttrib = 0; nAttrib < oXMLParent.attributes.length; nAttrib++) {
-      oAttrib = oXMLParent.attributes.item(nAttrib);
-      this["@" + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
-    }
-  }
-  /* Object.freeze(this); */
-}
-
-var myObject = new JXONTree(doc);
-// we got our javascript object! try: alert(JSON.stringify(myObject));
-
- -
注意:如果你想冻结整个对象树(因为XML文档的“静态”性质),取消注释字符串:/* Object.freeze(this); */Object.freeze()方法防止将新属性添加到该属性中,防止现有属性被删除,并防止现有属性或其可枚举性,可配置性或可写性发生更改。本质上,对象树是有效的不可变的。
- -

用这个算法我们的例子变成:

- -
{
-  "catalog": {
-    "product": {
-      "catalog_item": [{
-        "item_number": {
-          "keyValue": "QWZ5671"
-        },
-        "price": {
-          "keyValue": 39.95
-        },
-        "size": [{
-          "color_swatch": [{
-            "keyValue": "Red",
-            "@image": "red_cardigan.jpg"
-          }, {
-            "keyValue": "Burgundy",
-            "@image": "burgundy_cardigan.jpg"
-          }],
-          "@description": "Medium"
-        }, {
-          "color_swatch": [{
-            "keyValue": "Red",
-            "@image": "red_cardigan.jpg"
-          }, {
-            "keyValue": "Burgundy",
-            "@image": "burgundy_cardigan.jpg"
-          }],
-          "@description": "Large"
-        }],
-        "@gender": "Men's"
-      }, {
-        "item_number": {
-          "keyValue": "RRX9856"
-        },
-        "discount_until": {
-          "keyValue": new Date(1995, 11, 25)
-        },
-        "price": {
-          "keyValue": 42.5
-        },
-        "size": {
-          "color_swatch": {
-            "keyValue": "Black",
-            "@image": "black_cardigan.jpg"
-          },
-          "@description": "Medium"
-        },
-        "@gender": "Women's"
-      }],
-      "@description": "Cardigan Sweater"
-    },
-    "script": {
-      "keyValue": "function matchwo(a,b) {\n  if (a < b && a < 0) { return 1; }\n  else { return 0; }\n}",
-      "@type": "text/javascript"
-    }
-  }
-}
-
- -

如果您部分了解XML文档的结构,则可以使用这种技术。

- -

Algorithm #3: 一种组合的技巧

- -

这是另一种转换方法。这个算法是最接近Parker约定的。除了不包含除TextCDATASection以外的其他可识别节点的节点不被视为对象,而是直接作为布尔值,字符串,数字或Date对象(请参阅Parker约定)。空节点(即不包含其他Element节点,Text节点,CDATASection节点或Attr节点)的默认值为true(请参阅代码注意事项)。另外,这次我们使用一个函数来代替构造函数。函数的参数可以是整个XML  Document,一个DocumentFragment,或者只是一个 Element 节点。根据BadgerFish公约的建议,nodeAttributes具有“@”前缀。在很多情况下,这是最实用的转换方法。

- -
/*\
-|*|
-|*|  JXON Snippet #3 - Mozilla Developer Network
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/JXON
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|
-|*|  This framework is released under the GNU Public License, version 3 or later.
-|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
-|*|
-\*/
-
-function parseText (sValue) {
-  if (/^\s*$/.test(sValue)) { return null; }
-  if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === "true"; }
-  if (isFinite(sValue)) { return parseFloat(sValue); }
-  if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
-  return sValue;
-}
-
-function getJXONTree (oXMLParent) {
-  var vResult = /* put here the default value for empty nodes! */ true, nLength = 0, sCollectedTxt = "";
-  if (oXMLParent.hasAttributes && oXMLParent.hasAttributes()) {
-    vResult = {};
-    for (nLength; nLength < oXMLParent.attributes.length; nLength++) {
-      oAttrib = oXMLParent.attributes.item(nLength);
-      vResult["@" + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
-    }
-  }
-  if (oXMLParent.hasChildNodes()) {
-    for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
-      oNode = oXMLParent.childNodes.item(nItem);
-      if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is "CDATASection" (4) */
-      else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is "Text" (3) */
-      else if (oNode.nodeType === 1 && !oNode.prefix) { /* nodeType is "Element" (1) */
-        if (nLength === 0) { vResult = {}; }
-        sProp = oNode.nodeName.toLowerCase();
-        vContent = getJXONTree(oNode);
-        if (vResult.hasOwnProperty(sProp)) {
-          if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
-          vResult[sProp].push(vContent);
-        } else { vResult[sProp] = vContent; nLength++; }
-      }
-    }
-  }
-  if (sCollectedTxt) { nLength > 0 ? vResult.keyValue = parseText(sCollectedTxt) : vResult = parseText(sCollectedTxt); }
-  /* if (nLength > 0) { Object.freeze(vResult); } */
-  return vResult;
-}
-
-var myObject = getJXONTree(doc);
-// we got our javascript object! try: alert(JSON.stringify(myObject));
-
- -
注意:如果你想冻结整个对象树(因为XML文档的“静态”性质),取消注释字符串:/* Object.freeze(this); */Object.freeze()方法防止将新属性添加到该属性中,防止现有属性被删除,并防止现有属性或其可枚举性,可配置性或可写性发生更改。本质上,对象树是有效的不可变的。
- -

用这个算法我们的例子变成:

- -
{
-  "catalog": {
-    "product": {
-      "@description": "Cardigan Sweater",
-      "catalog_item": [{
-        "@gender": "Men's",
-        "item_number": "QWZ5671",
-        "price": 39.95,
-        "size": [{
-          "@description": "Medium",
-          "color_swatch": [{
-            "@image": "red_cardigan.jpg",
-            "keyValue": "Red"
-          }, {
-            "@image": "burgundy_cardigan.jpg",
-            "keyValue": "Burgundy"
-          }]
-        }, {
-          "@description": "Large",
-          "color_swatch": [{
-            "@image": "red_cardigan.jpg",
-            "keyValue": "Red"
-          }, {
-            "@image": "burgundy_cardigan.jpg",
-            "keyValue": "Burgundy"
-          }]
-        }]
-      }, {
-        "@gender": "Women's",
-        "item_number": "RRX9856",
-        "discount_until": new Date(1995, 11, 25),
-        "price": 42.5,
-        "size": {
-          "@description": "Medium",
-          "color_swatch": {
-            "@image": "black_cardigan.jpg",
-            "keyValue": "Black"
-          }
-        }
-      }]
-    },
-    "script": {
-      "@type": "text/javascript",
-      "keyValue": "function matchwo(a,b) {\n  if (a < b && a < 0) { return 1; }\n  else { return 0; }\n}"
-    }
-  }
-}
-
- -

如果您知道XML文档的结构,这是推荐的技术。

- -

算法 #4: 一个非常简约的方式

- -

以下是另一种可以实现的转换方法。它也非常接近Parker约定。使用此算法,包含同一级别中的其他子元素,文本或CDATASection节点的所有元素节点都将被视为Boolean ,Number, String,或Date构造函数的实例。因此,任何子元素节点(如果存在)将嵌套在这些类型的对象中。

- -

For example:

- -
<employee type="usher">John Smith</employee>
-<manager>Lisa Carlucci</manager>
-
- -

becomes

- -
var myObject = {
-  "employee": new String("John Smith"),
-  "manager": "Lisa Carlucci"
-};
-
-myObject.employee["@type"] = "usher";
-
-// test
-
-alert(myObject.manager); // "Lisa Carlucci"
-alert(myObject.employee["@type"]); // "usher"
-alert(myObject.employee); // "John Smith"
-
- -
注意:这个算法代表了转换的特殊情况。生成的JavaScript对象树不可字符串化(请参阅Code considerations)。内部JavaScript访问非常实用,但如果要通过JSON字符串传输树,请不要使用它!
- -

对于第三种算法,不包含除Text或CDATASection之外的其他可识别节点的节点不被视为对象,而是直接作为Boolean ,Number(原始值), String,或Date对象;而空节点(即,不包含其他Element节点,Text节点,CDATASection节点或Attr节点)具有默认值true。至于第三个算法,它不是使用构造函数,而是一个函数。该函数的参数可以是整个XML文档,一个DocumentFragment或简单的Element节点。根据BadgerFish公约的建议,nodeAttributes具有“@”前缀。

- -
/*\
-|*|
-|*|  JXON Snippet #4 - Mozilla Developer Network
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/JXON
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|
-|*|  This framework is released under the GNU Public License, version 3 or later.
-|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
-|*|
-\*/
-
-function parseText (sValue) {
-  if (/^\s*$/.test(sValue)) { return null; }
-  if (/^(?:true|false)$/i.test(sValue)) { return sValue.toLowerCase() === "true"; }
-  if (isFinite(sValue)) { return parseFloat(sValue); }
-  if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
-  return sValue;
-}
-
-function objectify (vValue) {
-  if (vValue === null) {
-    return new (function() {
-      this.toString = function() { return "null"; }
-      this.valueOf = function() { return null; }
-    })();
-  }
-  return vValue instanceof Object ? vValue : new vValue.constructor(vValue);
-}
-
-var aTmpEls = []; // loaded element nodes cache
-
-function getJXONTree (oXMLParent) {
-  var  sProp, vContent, vResult, nLength = 0, nLevelStart = aTmpEls.length,
-      nChildren = oXMLParent.hasChildNodes() ? oXMLParent.childNodes.length : 0, sCollectedTxt = "";
-
-  for (var oNode, nItem = 0; nItem < nChildren; nItem++) {
-    oNode = oXMLParent.childNodes.item(nItem);
-    if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is "CDATASection" (4) */
-    else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is "Text" (3) */
-    else if (oNode.nodeType === 1 && !oNode.prefix) { aTmpEls.push(oNode); } /* nodeType is "Element" (1) */
-  }
-
-  var nLevelEnd = aTmpEls.length, vBuiltVal = parseText(sCollectedTxt);
-
-  if (oParentNode.hasAttributes && oXMLParent.hasAttributes()) {
-    vResult = objectify(vBuiltVal);
-    for (nLength; nLength < oXMLParent.attributes.length; nLength++) {
-      oAttrib = oXMLParent.attributes.item(nLength);
-      vResult["@" + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
-    }
-  } else if (nLevelEnd > nLevelStart) { vResult = objectify(vBuiltVal); }
-
-  for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
-    sProp = aTmpEls[nElId].nodeName.toLowerCase();
-    vContent = getJXONTree(aTmpEls[nElId]);
-    if (vResult.hasOwnProperty(sProp)) {
-    if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
-      vResult[sProp].push(vContent);
-    } else { vResult[sProp] = vContent; nLength++; }
-  }
-
-  aTmpEls.length = nLevelStart;
-
-  if (nLength === 0) { vResult = sCollectedTxt ? vBuiltVal : /* put here the default value for empty nodes: */ true; }
-  /* else { Object.freeze(vResult); } */
-
-  return vResult;
-}
-
-var myObject = getJXONTree(doc);
-alert(myObject.catalog.product.catalog_item[1].size.color_swatch["@image"]); // "black_cardigan.jpg"
-alert(myObject.catalog.product.catalog_item[1].size.color_swatch); // "Black" !
-
- -

 

- -
注意:如果你想冻结整个对象树(因为XML文档的“静态”性质),取消注释字符串:/* Object.freeze(this); */Object.freeze()方法防止将新属性添加到该属性中,防止现有属性被删除,并防止现有属性或其可枚举性,可配置性或可写性发生更改。本质上,对象树是有效的不可变的。
- -

如果您知道XML文档的结构,这是一种可能的技术。

- -

 

- -

反向算法

- -

为了从JavaScript对象树开始构建一个新的XML文档,可以将这里提出的算法颠倒过来。为了简单,我们将在这里提出一个例子,在一个单一的方法,代表了所有我们的算法的反演。

- -
/*\
-|*|
-|*|  JXON Snippet #5 - Mozilla Developer Network
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/JXON
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|
-|*|  This framework is released under the GNU Public License, version 3 or later.
-|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
-|*|
-\*/
-
-function createXML (oObjTree) {
-  function loadObjTree (oParentEl, oParentObj) {
-    var vValue, oChild;
-    if (oParentObj.constructor === String || oParentObj.constructor === Number || oParentObj.constructor === Boolean) {
-      oParentEl.appendChild(oNewDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 or 1 */
-      if (oParentObj === oParentObj.valueOf()) { return; }
-    } else if (oParentObj.constructor === Date) {
-      oParentEl.appendChild(oNewDoc.createTextNode(oParentObj.toGMTString()));
-    }
-    for (var sName in oParentObj) {
-      if (isFinite(sName)) { continue; } /* verbosity level is 0 */
-      vValue = oParentObj[sName];
-      if (sName === "keyValue") {
-        if (vValue !== null && vValue !== true) { oParentEl.appendChild(oNewDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
-      } else if (sName === "keyAttributes") { /* verbosity level is 3 */
-        for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
-      } else if (sName.charAt(0) === "@") {
-        oParentEl.setAttribute(sName.slice(1), vValue);
-      } else if (vValue.constructor === Array) {
-        for (var nItem = 0; nItem < vValue.length; nItem++) {
-          oChild = oNewDoc.createElement(sName);
-          loadObjTree(oChild, vValue[nItem]);
-          oParentEl.appendChild(oChild);
-        }
-      } else {
-        oChild = oNewDoc.createElement(sName);
-        if (vValue instanceof Object) {
-          loadObjTree(oChild, vValue);
-        } else if (vValue !== null && vValue !== true) {
-          oChild.appendChild(oNewDoc.createTextNode(vValue.toString()));
-        }
-        oParentEl.appendChild(oChild);
-      }
-    }
-  }
-  const oNewDoc = document.implementation.createDocument("", "", null);
-  loadObjTree(oNewDoc, oObjTree);
-  return oNewDoc;
-}
-
-var newDoc = createXML(myObject);
-// we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
-
- -
注意:通过这个代码,Date实例(如果存在的话)通过toGMTString() 方法转换为 Strings 。没有什么禁止使用任何其他转换方法。此外,具有true值的树的所有属性都将被转换为没有文本节点的空元素(请参阅 Code considerations)。
- -

如果要自动创建XML文档,这是一个很好的解决方案。但是,如果要重新构建以前转换为JSON的XML文档,这是一个不错的选择。虽然双向转换是非常忠实的(除了CDATASection节点,它们将被转换成文本节点),但这个过程是不必要的成本。事实上,如果您的目标是编辑XML文档,强烈建议您使用它而不是创建一个新的。

- -

The Parker Convention

- -

上面列出的用于将XML文档转换为JSON(通常称为“JXON算法”)的功能或多或少地基于Parker公约(尤其是关于将标签名称转换为对象属性名称,识别所有收集到的每个标签的文本内容以及单独的Text和/或CDATASection节点吸收为原始值)。It is called “Parker Convention” in opposition to “BadgerFish Convention”, after the comic Parker & Badger by Cuadrado. See also: BadgerFish Convention.

- -

以下是来自 xml2json-xslt项目网站的“TransformingRules”页面的Parker Convention文章(版本0.4)的转录。

- -

本公约是为了规范从XSLTJSON 的转换而编写的,所以它的一部分对于JavaScript来说是徒劳的。

- -
注意:2013年10月29日,万维网联盟(World Wide Web Consortium)在一篇关于将HTML5微数据转换为JSON的官方算法的备注中转载。但是,HTML微数据不是HTML:微数据是HTML的格式化子集。
- -

Translation JSON

- -
    -
  1. -

    The root element will be absorbed, for there is only one:

    - -
    <root>test</root>
    - -

    becomes

    - -
    "test"
    -
    -
  2. -
  3. -

    Element names become object properties:

    - -
    <root><name>Xml</name><encoding>ASCII</encoding></root>
    - -

    becomes

    - -
    {
    -  "name": "Xml",
    -  "encoding": "ASCII"
    -}
    -
    -
  4. -
  5. -

    Numbers are recognized (integers and decimals):

    - -
    <root><age>12</age><height>1.73</height></root>
    - -

    becomes

    - -
    {
    -  "age": 12,
    -  "height": 1.73
    -}
    -
    -
  6. -
  7. -

    Booleans are recognized case insensitive:

    - -
    <root><checked>True</checked><answer>FALSE</answer></root>
    - -

    becomes

    - -
    {
    -  "checked": true,
    -  "answer": false
    -}
    -
    -
  8. -
  9. -

    Strings are escaped:

    - -
    <root>Quote: &quot; New-line:
    -</root>
    -
    - -

    becomes

    - -
    "Quote: \" New-line:\n"
    -
  10. -
  11. -

    Empty elements will become null:

    - -
    <root><nil/><empty></empty></root>
    - -

    becomes

    - -
    {
    -  "nil": null,
    -  "empty": null
    -}
    -
    -
  12. -
  13. -

    If all sibling elements have the same name, they become an array

    - -
    <root><item>1</item><item>2</item><item>three</item></root>
    -
    - -

    becomes

    - -
    [1, 2, "three"]
    -
    -
  14. -
  15. -

    Mixed mode text-nodes, comments and attributes get absorbed:

    - -
    <root version="1.0">testing<!--comment--><element test="true">1</element></root>
    -
    - -

    becomes

    - -
    { "element": true }
    -
    -
  16. -
  17. -

    Namespaces get absorbed, and prefixes will just be part of the property name:

    - -
    <root xmlns:ding="http://zanstra.com/ding"><ding:dong>binnen</ding:dong></root>
    -
    - -

    becomes

    - -
    { "ding:dong" : "binnen" }
    -
    -
  18. -
- -
注意:我们的算法符合第2,3,4和7点。第三和第四个算法也符合第6点(但是true而不是null - 请参阅Code considerations)。第5点由JavaScript方法JSON.stringify()自动管理。关于第9点,我们选择忽略所有有前缀的节点;你可以通过从我们的算法中删除字符串&& !oNode.prefix来包含它们(参见 Code considerations))。
- -

额外的JavaScript转换

- -

This is the same as the JSON translation, but with these extras:

- -
    -
  1. -

    Property names are only escaped when necessary

    - -
    <root><while>true</while><wend>false</wend><only-if/></root>
    -
    - -

    becomes

    - -
    {
    -  "while": true,
    -  wend: false,
    -  "only-if": null
    -}
    -
    -
  2. -
  3. -

    Within a string, closing elements "</" are escaped as "<\/"

    - -
    <root><![CDATA[<script>alert("YES");</script>]]></root>
    - -

    becomes

    - -
    { script: "<script>alert(\"YES\")<\/script>" }
    -
    -
  4. -
  5. -

    Dates are created as new Date objects

    - -
    <root>2006-12-25</root>
    - -

    becomes

    - -
    new Date(2006, 12 - 1, 25)
    -
    -
  6. -
  7. -

    Attributes and comments are shown as comments (for testing purposes):

    - -
    <!--testing--><root><test version="1.0">123</test></root>
    -
    - -

    becomes

    - -
    /* testing */ { test /* @version = "1.0" */ : 123}
    -
    -
  8. -
  9. -

    A bit of indentation is done, to keep things legible

    -
  10. -
- -
注意:我们的算法符合第3点(但没有减少月份)。点1和2自动由JavaScript方法 JSON.stringify()进行管理。
- -

In summary

- -

我们以第三种算法作为最具代表性的JXON解析算法。单个结构化XML元素可能有八种不同的配置:

- -
    -
  1. an empty element,
  2. -
  3. an element with pure text content,
  4. -
  5. an empty element with attributes,
  6. -
  7. an element with text content and attributes,
  8. -
  9. an element containing elements with different names,
  10. -
  11. an element containing elements with identical names,
  12. -
  13. an element containing elements and contiguous text,
  14. -
  15. an element containing elements and non contiguous text.
  16. -
- -

The following table shows the corresponding conversion patterns between XML and JSON according to the third algorithm.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CaseXMLJSONJavascript access
1<animal />"animal": truemyObject.animal
2<animal>Deka</animal>"animal": "Deka"myObject.animal
3<animal name="Deka" />"animal": {"@name": "Deka"}myObject.animal["@name"]
4<animal name="Deka">is my cat</animal>"animal": { "@name": "Deka", "keyValue": "is my cat" }myObject.animal["@name"], myObject.animal.keyValue
5<animal> <dog>Charlie</dog> <cat>Deka</cat> </animal>"animal": { "dog": "Charlie", "cat": "Deka" }myObject.animal.dog, myObject.animal.cat
6<animal> <dog>Charlie</dog> <dog>Mad Max</dog> </animal>"animal": { "dog": ["Charlie", "Mad Max"] }myObject.animal.dog[0], myObject.animal.dog[1]
7<animal> in my house <dog>Charlie</dog> </animal>"animal": { "keyValue": "in my house", "dog": "Charlie" }myObject.animal.keyValue, myObject.animal.dog
8<animal> in my ho <dog>Charlie</dog> use </animal>"animal": { "keyValue": "in my house", "dog": "Charlie" }myObject.animal.keyValue, myObject.animal.dog
- -

Code considerations

- -

In these examples we chose to use a property named keyValue for the text content. The lack of standards for XML to JSON conversion leads developers to choose a variety of property names for the text content of XML Element nodes that also contain other child nodes. Sometimes a property called $ is used. Other times a property called #text is used (however, a name like this isn't a good choice, since the text content of a node can be parsed into a non-string value by our algorithms during the conversion). In the algorithms proposed here, you can easily change this name, depending on your needs.

- -

The choice of using a true value instead of a null value to represent empty nodes is due to the fact that when in an XML document there is an empty node the reason is often to express a Boolean, as in this case:

- -
<car>
-  <type>Ferrari</type>
-  <bought />
-</car>
-
- -

If the value were null it would be more cumbersome to launch a code like this:

- -
if (myObject.car.bought) {
-  // do something
-}
-
- -
Note: According to our third algorithm and our fourth algorithm, just CDATASection nodes which contain nothing but white spaces (precisely: /^\s+$/) will be parsed as null.
- -

The fourth algorithm represents a special case of conversion. As you can see, the generated JavaScript Object tree is not stringifyable. It is very practical for internal JavaScript access, but don't use it if you want to transfer the tree via JSON string (as for Worker messages, for example).

- -

We chose to ignore nodes which have a prefix (for example: <ding:dong>binnen</ding:dong>), due to their special case (they are often used in order to represents an XML Schema, which is meta-information concerning how to organize the information of the document, reserved for the XML parser). You can include them removing the string && !oNode.prefix from our algorithms (by doing so the whole tag will become the property name: { "ding:dong": "binnen" }).

- -

An important consideration is that, when using the third or the fourth algorithm, an XML Document can be used to create any type of JavaScript object. For example, If you want to create an object like the following:

- -
{
-  "myboolean": true,
-  "myarray": ["Cinema", "Hot dogs", false],
-  "myobject": {
-    "nickname": "Jack",
-    "registration_date": new Date(1995, 11, 25),
-    "privileged_user": true
-  },
-  "mynumber": 99,
-  "mytext": "Hello World!"
-}
-
- -

you must just create an XML document with the following structure:

- -
<myboolean>true</myboolean>
-<myarray>Cinema</myarray>
-<myarray>Hot dogs</myarray>
-<myarray>false</myarray>
-<myobject>
-  <nickname>Jack</nickname>
-  <registration_date>Dec 25, 1995</registration_date>
-  <privileged_user />
-</myobject>
-<mynumber>99</mynumber>
-<mytext>Hello World!</mytext>
-
- -

This example also shows how the ideal JXON document is an XML document designed specifically to be converted in JSON format, though our algorithms work fine with any kind of XML document.

- -
Note: Despite the term JXON suggesting "lossless" conversions, these techniques are not actually lossless if one needs to preserve ordering of elements, as is common with many XML dialects (including of course XHTML). The ECMAScript standard (JavaScript) indicates that object iteration order is implementation dependent.
- -

Appendix: a complete, bidirectional, JXON library

- -

Now we can create a more complete, bidirectional, JXON library based on all our algorithms (see: #1, #2, #3, #4, reverse). Its usage is modeled on the JSON native object. Before implementing it in a working environment, please read the note about the const statement compatibility. The following code is also available on GitHub.

- -
"use strict";
-
-/*\
-|*|
-|*|  JXON framework - Copyleft 2011 by Mozilla Developer Network
-|*|
-|*|  Revision #3 - October 31th, 2016
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/JXON
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|  https://github.com/madmurphy/jxon.js
-|*|
-|*|  This framework is released under the GNU Public License, version 3 or later.
-|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
-|*|
-\*/
-
-const JXON = new (function () {
-
-  function parseText (sValue) {
-    if (rIsNull.test(sValue)) { return null; }
-    if (rIsBool.test(sValue)) { return sValue.toLowerCase() === "true"; }
-    if (isFinite(sValue)) { return parseFloat(sValue); }
-    if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
-    return sValue;
-  }
-
-  function EmptyTree () {}
-
-  EmptyTree.prototype.toString = function () { return "null"; };
-
-  EmptyTree.prototype.valueOf = function () { return null; };
-
-  function objectify (vVal) {
-    return vVal === null ? new EmptyTree() : vVal instanceof Object ? vVal : new vVal.constructor(vVal);
-  }
-
-  function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
-
-    const
-      nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
-      bAttributes = oParentNode.hasAttributes && oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
-
-    var
-      sProp, vContent, nLength = 0, sCollectedTxt = "",
-      vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
-
-    if (bChildren) {
-      for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
-        oNode = oParentNode.childNodes.item(nItem);
-        if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is "CDATASection" (4) */
-        else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is "Text" (3) */
-        else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is "Element" (1) */
-      }
-    }
-
-    const nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
-
-    if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
-
-    for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
-      sProp = aCache[nElId].nodeName.toLowerCase();
-      vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
-      if (vResult.hasOwnProperty(sProp)) {
-        if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
-        vResult[sProp].push(vContent);
-      } else {
-        vResult[sProp] = vContent;
-        nLength++;
-      }
-    }
-
-    if (bAttributes) {
-
-      const
-        nAttrLen = oParentNode.attributes.length,
-        sAPrefix = bNesteAttr ? "" : sAttrsPref, oAttrParent = bNesteAttr ? {} : vResult;
-
-      for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
-        oAttrib = oParentNode.attributes.item(nAttrib);
-        oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
-      }
-
-      if (bNesteAttr) {
-        if (bFreeze) { Object.freeze(oAttrParent); }
-        vResult[sAttrProp] = oAttrParent;
-        nLength -= nAttrLen - 1;
-      }
-
-    }
-
-    if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
-      vResult[sValProp] = vBuiltVal;
-    } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
-      vResult = vBuiltVal;
-    }
-
-    if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
-
-    aCache.length = nLevelStart;
-
-    return vResult;
-
-  }
-
-  function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
-
-    var vValue, oChild;
-
-    if (oParentObj.constructor === String || oParentObj.constructor === Number || oParentObj.constructor === Boolean) {
-      oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 or 1 */
-      if (oParentObj === oParentObj.valueOf()) { return; }
-    } else if (oParentObj.constructor === Date) {
-      oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));
-    }
-
-    for (var sName in oParentObj) {
-      vValue = oParentObj[sName];
-      if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
-      if (sName === sValProp) {
-        if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
-      } else if (sName === sAttrProp) { /* verbosity level is 3 */
-        for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
-      } else if (sName.charAt(0) === sAttrsPref) {
-        oParentEl.setAttribute(sName.slice(1), vValue);
-      } else if (vValue.constructor === Array) {
-        for (var nItem = 0; nItem < vValue.length; nItem++) {
-          oChild = oXMLDoc.createElement(sName);
-          loadObjTree(oXMLDoc, oChild, vValue[nItem]);
-          oParentEl.appendChild(oChild);
-        }
-      } else {
-        oChild = oXMLDoc.createElement(sName);
-        if (vValue instanceof Object) {
-          loadObjTree(oXMLDoc, oChild, vValue);
-        } else if (vValue !== null && vValue !== true) {
-          oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
-        }
-        oParentEl.appendChild(oChild);
-      }
-    }
-
-  }
-
-  /* Uncomment the following code if you want to enable the .appendJXON() method for *all* the "element" objects! */
-
-  /*
-
-  Element.prototype.appendJXON = function (oObjTree) {
-    loadObjTree(document, this, oObjTree);
-    return this;
-  };
-
-  */
-
-  this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
-    const nVerbMask = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
-    return createObjTree(oXMLParent, nVerbMask, bFreeze || false, arguments.length > 3 ? bNesteAttributes : nVerbMask === 3);
-  };
-
-  this.unbuild = function (oObjTree, sNamespaceURI /* optional */, sQualifiedName /* optional */, oDocumentType /* optional */) {
-    const oNewDoc = document.implementation.createDocument(sNamespaceURI || null, sQualifiedName || "", oDocumentType || null);
-    loadObjTree(oNewDoc, oNewDoc, oObjTree);
-    return oNewDoc;
-  };
-
-  const
-    sValProp = "keyValue", sAttrProp = "keyAttributes", sAttrsPref = "@", /* you can customize these values */
-    aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
-
-})();
-
- -
Note: The current implementation of const (constant statement) is not part of ECMAScript 5. It is supported in Firefox & Chrome (V8) and partially supported in Opera 9+ and Safari. It is not supported in Internet Explorer 6-9, or in the preview of Internet Explorer 10. const is going to be defined by ECMAScript 6, but with different semantics. Similar to variables declared with the let statement, constants declared with const will be block-scoped. We used it only for didactic purpose. If you want a full browser compatibility of this library, please replace all the const statements with the var statements.
- -

Usage

- -

The obtained non-native JXON global object will have two methods:

- - - - - - - - - - - - - - - - -
MethodDescription
JXON.build(document[, verbosity[, freeze[, nesteAttributes]]])Returns a JavaScript Object based on the given XML Document.
JXON.unbuild(objTree[, namespaceURI[, qualifiedNameStr[, documentType]]])Returns an XML Document based on the given JavaScript Object.
- -

These methods are inverses of each other. So, you can work with the JXON object by inserting the previous code at the beginning of your scripts. If you are not interested in a bidirectional conversion, don't use it, use only one of our algotithm instead.

- -

Sample usage:

- -
var myObject = JXON.build(doc);
-// we got our javascript object! try: alert(JSON.stringify(myObject));
-
-var newDoc = JXON.unbuild(myObject);
-// we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
- -

…the same thing using AJAX:

- -
function reqListener () {
-
-    var myObject = JXON.build(this.responseXML);
-    // we got our javascript object!
-    alert(JSON.stringify(myObject));
-
-    var newDoc = JXON.unbuild(myObject);
-    // we got our Document instance!
-    alert((new XMLSerializer()).serializeToString(newDoc));
-
-};
-
-var oReq = new XMLHttpRequest();
-oReq.onload = reqListener;
-oReq.open("get", "example.xml", true);
-oReq.send();
- -

JXON.build syntax

- -

JXON.build(document[, verbosity[, freeze[, nesteAttributes]]])

- -

JXON.build description

- -

Returns a JavaScript Object based on the given XML Document.

- -

JXON.build parameters

- -
-
document
-
The XML document to be converted into JSON format.
-
verbosity Optional
-
The verbosity level of conversion (optional), from 0 to 3. It is almost equivalent to our algorithms from #4 to #1 (default value is 1, which is equivalent to the algorithm #3).
-
freeze Optional
-
A boolean (optional) expressing whether the created object must be freezed or not (default value is false).
-
nesteAttributes Optional
-
A boolean (optional) expressing whether the the nodeAttributes must be nested into a child-object named keyAttributes or not (default value is false for verbosity levels from 0 to 2; true for verbosity level 3).
-
- -

JXON.unbuild syntax

- -

JXON.unbuild(objTree[, namespaceURI[, qualifiedNameStr[, documentType]]])

- -

JXON.unbuild description

- -

Returns an XML Document based on the given JavaScript Object.

- -

JXON.unbuild parameters

- -
-
objTree
-
The JavaScript Object from which you want to create your XML Document.
-
namespaceURI Optional
-
Is a DOMString containing the namespace URI of the document to be created, or null if the document doesn't belong to one.
-
qualifiedNameStr Optional
-
Is a DOMString containing the qualified name, that is an optional prefix and colon plus the local root element name, of the document to be created.
-
documentType Optional
-
Is the DocumentType of the document to be created. It defaults to null.
-
- -

Extend the native Element.prototype object

- -

If you want to enable the .appendJXON() method for all the native element objects, you can uncomment the following code from the JXON library:

- -
  /* Uncomment the following code if you want to enable the .appendJXON() method for *all* the "element" objects! */
-
-  /*
-
-  Element.prototype.appendJXON = function (oObjTree) {
-    loadObjTree(document, this, oObjTree);
-    return this;
-  };
-
-  */
- -

Example

- -

Imagine you want to populate the following HTMLElement through JSON:

- -
<div id="form_container"></div>
- -

Then, the following code:

- -
document.getElementById("form_container").appendJXON({
-  "form": {
-    "script": {
-      "@type": "text/javascript",
-      "keyValue": "\n  function numbersOnly (oToCheckField, oKeyEvent) {\n  return oKeyEvent.charCode === 0 || /\\d/.test(String.fromCharCode(oKeyEvent.charCode));\n  }\n"
-    },
-    "input": [{
-      "@type": "hidden",
-      "@name": "instId",
-      "@value": 1234
-    }, {
-      "@type": "hidden",
-      "@name": "currency",
-      "@value": "GBP"
-    }, {
-      "@type": "hidden",
-      "@name": "amount",
-      "@value": 0
-    }, {
-      "@type": "hidden",
-      "@name": "name",
-      "@value": "CAPTURED"
-    }],
-    "table": {
-      "tr": [{
-        "th": {
-          "@style": "text-align: right;",
-          "keyValue": "Product:"
-        },
-        "td": {
-          "span": [{
-            "input": {
-              "@type": "radio",
-              "@name": "nome",
-              "@id": "rel_tshirt",
-              "@value": "tshirt"
-            },
-            "label": {
-              "@for": "rel_tshirt",
-              "keyValue": "T-Shirt"
-            },
-            "@class": "product"
-          }, {
-            "input": {
-              "@type": "radio",
-              "@name": "nome",
-              "@id": "rel_trousers",
-              "@value": "trousers"
-            },
-            "label": {
-              "@for": "rel_trousers",
-              "keyValue": "Trousers"
-            },
-            "@class": "product"
-          }, {
-            "input": {
-              "@type": "radio",
-              "@name": "nome",
-              "@id": "rel_pullover",
-              "@value": "pullover"
-            },
-            "label": {
-              "@for": "rel_pullover",
-              "keyValue": "Pullover"
-            },
-            "@class": "product"
-          }]
-        }
-      }, {
-        "th": {
-          "@style": "text-align: right;",
-          "keyValue": "Quantity:"
-        },
-        "td": {
-          "input": {
-            "@type": "text",
-            "@name": "myInput",
-            "@onkeypress": "return numbersOnly(this, event);",
-            "@onpaste": "return false;"
-          }
-        }
-      }]
-    },
-    "p": {
-      "input": {
-        "@type": "submit",
-        "@value": "Purchase!"
-      }
-    },
-    "@action": "https://secure-test.worldpay.com/wcc/purchase",
-    "@name": "BuyForm",
-    "@method": "POST"
-  }
-});
- -

will populate the previous element in the following way:

- -
<div id="form_container">
-  <form action="https://secure-test.worldpay.com/wcc/purchase" name="BuyForm" method="POST">
-    <script type="text/javascript">
-      function numbersOnly(oToCheckField, oKeyEvent) {
-        return oKeyEvent.charCode === 0 || /\d/.test(String.fromCharCode(oKeyEvent.charCode));
-      }
-    </script>
-    <input type="hidden" name="instId" value="1234" />
-    <input type="hidden" name="currency" value="GBP" />
-    <input type="hidden" name="amount" value="0" />
-    <input type="hidden" name="name" value="CAPTURED" />
-    <table>
-      <tr>
-        <th style="text-align: right;">Product:</th>
-        <td><span class="product"><input type="radio" name="nome" id="rel_tshirt" value="tshirt"/><label for="rel_tshirt">T-Shirt</label></span><span class="product"><input type="radio" name="nome" id="rel_trousers" value="trousers"/><label for="rel_trousers">Trousers</label></span><span class="product"><input type="radio" name="nome" id="rel_pullover" value="pullover"/><label for="rel_pullover">Pullover</label></span>
-        </td>
-      </tr>
-      <tr>
-        <th style="text-align: right;">Quantity:</th>
-        <td>
-          <input type="text" name="myInput" onkeypress="return numbersOnly(this, event);" onpaste="return false;" />
-        </td>
-      </tr>
-    </table>
-    <p>
-      <input type="submit" value="Purchase!" />
-    </p>
-  </form>
-</div>
- -

Other examples

- -

Example #1: How to use JXON to create an HTML document instead of an XML document:

- -
/* The structure of my document */
-var oMyHTMLStruct = {
-  "html": {
-    "head": {
-      "meta": {
-        "@http-equiv": "Content-Type",
-        "@content": "text/html; charset=UTF-8"
-      },
-      "title": "My HTML Document",
-      "script": {
-        "@type": "text/javascript",
-        "keyValue": "alert(\"Welcome!\");"
-      },
-      "style": "p:first-letter {\n  font: italic bold 30px Georgia, serif;\n}"
-    },
-    "body": {
-      "h1": "My HTML Document",
-      "p": "Hello world!!"
-    }
-  }
-};
-
-/* Create the document */
-var oMyHTMLDoc = JXON.unbuild(oMyHTMLStruct, "http://www.w3.org/1999/xhtml");
- -

…And here is the output of alert((new XMLSerializer()).serializeToString(oMyHTMLDoc)):

- -
<html>
-
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-  <title>My HTML Document</title>
-  <script type="text/javascript">
-    alert("Welcome!");
-  </script>
-  <style>
-    p:first-letter {
-      font: italic bold 30px Georgia, serif;
-    }
-  </style>
-</head>
-
-<body>
-  <h1>My HTML Document</h1>
-  <p>Hello world!!</p>
-</body>
-
-</html>
- -
Note: As we already said in the note within Code considerations, despite the bidirectional conversion between XML and JSON is lossless regarding the whole content and the structure of an XML document, it is not lossless regarding the ordering of elements, which for some XML dialects (like XHTML) is part of the information. For instance, a bidirectional conversion of the following HTML paragraph: - -
<p>She <strong>loves</strong> you. And definitely <strong>hates</strong> me.</p>
-would determine a result like the following: - -
<p><strong>loves</strong><strong>hates</strong>Sheyou. And definitelyme.</p>
-As you can see in this special case, the whole information is preserved, the ordering of the elements is not.
-It turns out then that for some XML dialects JXON can be not the best choise, while it can be a really powerful tool in dealing with standard XML. One conversion method which is lossless for element order, as it relies on arrays (but, with a less human-readable, JavaScript-friendly syntax), is JsonML.
- -

About this library

- -

The JXON.build() method summarizes all our four ways of conversion (see: #1, #2, #3, #4). The result is therefore the same of our four algorithms, depending on the level of verbosity utilised. As above, optional properties and methods (commented in the example) of the first algorithm (verbosity level: 3) are not included.

- -

The JXON.unbuild() method utilises our reverse algorithm.

- -

Therefore, all code considerations remain the same.

- -

Resources

- - - -

See also

- - diff --git a/files/zh-cn/archive/mdn/index.html b/files/zh-cn/archive/mdn/index.html deleted file mode 100644 index 95f78220b5..0000000000 --- a/files/zh-cn/archive/mdn/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: MDN -slug: Archive/MDN -tags: - - NeedsTranslation - - TopicStub -translation_of: Archive/MDN ---- -

Obsolete
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.

- -

The documentation listed below is archived, obsolete material about MDN itself.

- -

-
Content kits
MDN Content Kits are subject-based collections of technical resources to help you host a local developer meetup or give a technical presentation at an event, conference, or workshop.
How to link a GitHub account to your MDN profile
All users who wish to contribute to MDN must add a GitHub login to their MDN account in order to edit. This article describes how to add GitHub authentication to your MDN profile.
MDN and Persona sign-ins
Starting on November 1, 2016, we only support GitHub for logging into MDN. If you didn't add a GitHub login to your MDN account before we disabled Persona logins, please file an "Account Help" bug on Bugzilla.
-
Subject-matter experts
This article's purpose is to help writers find the Mozilla developers who have answers for questions about various technologies. If you're an engineer on any Mozilla project, please make sure your technology is on this list and that the contact information for your group is provided.
Zones
A zone is a special area of MDN whose content is presented with some added user interface elements, such as a special zone navigation box and enhanced visuals in the header area of the page.
-

diff --git a/files/zh-cn/archive/meta_docs/custom_classes/index.html b/files/zh-cn/archive/meta_docs/custom_classes/index.html deleted file mode 100644 index 77a4ca21c9..0000000000 --- a/files/zh-cn/archive/meta_docs/custom_classes/index.html +++ /dev/null @@ -1,239 +0,0 @@ ---- -title: 'Project:自定义_CSS_类' -slug: Archive/Meta_docs/Custom_classes -tags: - - 所有分类 -translation_of: Archive/Meta_docs/Custom_classes ---- -

-
帮助目录
- -
-
指导
-
- -
- -
参考
-
- -
- -
列表
-
- -
-
- -

- -

下面的内容,将介绍如何在 Devmo wiki 中自定义 CSS 类。无论任何原因,如果您需要为本 wiki 创建自定义 CSS 类,请随时联系 Dria.

- -

定义 CSS 类

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
结果
div.tip显示 tip 文本,范围不超出一个页的 body 部分。
div.bug显示 bug 文本,范围不超出一个页的 body 部分。
.float-left创建一个左向流 left-float 元素(通常是图形)
.float-right创建一个右向流 right-float 元素(通常是图形)
.figure定义一个未使用内容,不包含任何当前风格
.standard-table基础标准表(table)风格。
.standard-table td.header标准表(table)的表头风格。
.fullwidth-table宽度设置为 100% 的表。(就像现在你正在看的这个表)
.fullwidth-table td.header宽度设为 100% 的表的表头风格。
div.breadcrumbsbreadcrumbs 用户导航风格
div.breadcrumbs a.breadcrumbsbreadcrumbs 字符串用户导航风格。
div.breadcrumbs span.breadcrumbsbreadcrumbs 字符串导航中的本页内部标题风格。
div.side-note-left div.side-note-right用来创建一个靠单方向的文本框。它将在父级文本(通常是文档本身)中,占据一个50%宽度的文本框。建议在使用的时候,左右方向交替使用,以便提高文档的可读性。
div.highlight在左侧为段落创建一个三像素宽的蓝条。
.highlightred文本颜色变为红色
.highlightblue文本颜色变为蓝色
.highlightgreen文本颜色变为绿色
- -

例子

- -

高亮的代码

- -

我们经常会希望提请读者注意某段代码。这是可能通过使用spans,还用mediawiki内建的代码格式"indent-at-least-one-space" (“缩进至少一个空格”)。请注意,在<pre>块内使用spans是没有用的,因为mediawiki分析器忽略了spans,而直接把他们作为代码的一部分输出。

- -
<span class="highlightred">这样不会有效</span>
-
- -

取代它的方法是,缩进你想要放在高亮部分的代码,并且在内部使用spans。注意,在代码中,空行也是需要缩进的。如果在空行前面没有空格,那么前一个段落将被解释器关闭,并另起一个新段落。

- -
here is an example of
-   a codeblock with a blank line
-
- -
   that is not indented.
-
- -

很显然,上面是一个反面例子,正确的做法应该像下面这样的:

- -
here is an example of
-   a codeblock with a blank line
-
-   that is indented.
-
- - - -

 

- - - -

table.standard-table

- - - - - - - - - - - - -
表标题 1表标题 2
这里是一个例子:table.standard-table
- -

table.fullwidth-table

- - - - - - - - - - - - -
表标题 1表标题 2
这是一个例子:table.fullwidth-table
- -

Divs

- -
Tips
- -

使用 div class="note" 格式化 tip:

- -
这是一个 tip
- -
Bugs
- -

使用 div class="bug" 引用已知的 bug,可以创建指向bugzilla的bug连接:

- -
Bug 176320: Minimal innerWidth/innerHeight values for popup windows
- -
Warnings
- -

使用 div class="warning" 将一段文档做成警告高亮。最后,我们回做一些很酷的事情,并且加一些图标啊什么的。

- -
这是一个 warning.
- -
Notes
- -

div class="note" (via Template:Note) 用来将一段文档标记为一段笔记。不要直接使用 div 类,最好用模板template.

- -
这是个左边的 note。
- -

分别演示side-note-levt和side-note-right

- -
这是个右边的 note。
- -

 

- -
高亮段落
- -

div class="highlight" 的例子:

- -
-

这是一个段落 CSS 高亮的例子。通过这个方法可以让你的代码引起注意。最初,这个功能是在 XUL Tutorial 中添加进来的。

- -
这段例子
-   演示了使用
-   div
-   高亮的情况
-
-
- -

diff --git a/files/zh-cn/archive/meta_docs/devedge/index.html b/files/zh-cn/archive/meta_docs/devedge/index.html deleted file mode 100644 index 45372ce911..0000000000 --- a/files/zh-cn/archive/meta_docs/devedge/index.html +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: DevEdge -slug: Archive/Meta_docs/DevEdge -tags: - - 所有分类 -translation_of: Archive/Meta_docs/DevEdge ---- -

This is a temporary Index of the content that has been migrated from DevEdge to this wiki. The original list and mirror are linked below.

-

Migrated documents and migrator:

- -

DevEdge Content Progress list: DevEdge:Priority Content
- DevEdge Mirror site: http://devedge-temp.mozilla.org/

-

diff --git a/files/zh-cn/archive/meta_docs/external_redirects/index.html b/files/zh-cn/archive/meta_docs/external_redirects/index.html deleted file mode 100644 index a8e1988c62..0000000000 --- a/files/zh-cn/archive/meta_docs/external_redirects/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: 'Project:外部重定向' -slug: Archive/Meta_docs/External_redirects -tags: - - 所有分类 -translation_of: Archive/Meta_docs/External_redirects ---- -

-
帮助目录
- -
-
指导
-
- -
- -
参考
-
- -
- -
列表
-
- -
-
- -

-

MDC 维基可以重定向到外部网站。在category的页面里,我们使用类这样的链接。这些链接可以让我们连接到不包含在本维基内的外部页面去。

-

创建一个外部重定向

-

请按如下做法创建一个外部重定向链接:

-

首先,创建一个作为外部重定向的页面,用“(external)”作为后缀。例如:Mozilla Project Wiki (external)。这样的带有“(external)”后缀的页面将被用来作为指针,这个指针的作用在于,当用户点击指向这个页面的链接时,它将把用户带到一个维基以外的页面。这个功能主要用在目录列表里,而对于手工的连接则没什么必要。关于手工外部重定向链接的做法,请查看后面的信息。

-

Next, edit that page and add the redirect command, followed by the desired target URL enclosed in double square brackets. For example:

-
 #RE‌DIRECT [[http://wiki.mozilla.org]]
-
-

Finally, add a category to the redirect page. Note that the category must be - - on the same line - as the REDIRECT command, or the parser will ignore it. For example:

-
 #RE‌DIRECT [[http://wiki.mozilla.org]] [[Category:Mozilla Project:Other Resources]]
-
-

When this is finished, simply save the page as normal.

-

手动连接到外部重定向

-

You should not create links to external redirects. Instead, just create regular external links to the site. The reason for this is because linking to an external redirect obscures the URL and users won't know where they will end up. This can be pretty annoying, and annoying users is a bad thing.

-

编辑外部重定向

-

Since an external redirect page immediately bounces you to the external site, editing the external redirect can be a challenge. To do so, simply add "?action=edit" to the end of the URL for the external redirect page. This is somewhat inconvenient, but it works. For example:

-

Example

-

通过外部重定向迁移到引用页面

-

If you migrate an article into the MDC check the category page to see if there's an external redirect pointing at it as well.

-

If there is, check the "what links here" (link in right column, in - - Toolbox - ) to see if any other pages link to that external redirect. If any links exist, change them so they point at the newly migrated article.

-

When no pages link to the external redirect page, redirect it to the newly migrated article and put it in the "Junk" category (using [[Category:Junk]]) so it can be deleted.

-

If you have any questions about using External Redirects, feel free to email Deb Richardson at .

-

diff --git a/files/zh-cn/archive/meta_docs/index.html b/files/zh-cn/archive/meta_docs/index.html deleted file mode 100644 index eb6457acf7..0000000000 --- a/files/zh-cn/archive/meta_docs/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: MDN "meta-documentation" archive -slug: Archive/Meta_docs -translation_of: Archive/Meta_docs ---- -

Here you'll find archived "meta-documentation"; that is, documentation about how to write documentation on MDN. The articles here are obsolete and should no longer be referenced; we are retaining them here for reference while we migrate some content to new places, but very little of this is useful.

-

-
DevEdge
This is a temporary Index of the content that has been migrated from DevEdge to this wiki. The original list and mirror are linked below.
Project:外部重定向
MDC 维基可以重定向到外部网站。在category的页面里,我们使用类这样的链接。这些链接可以让我们连接到不包含在本维基内的外部页面去。
-
Project:自定义_CSS_类
下面的内容,将介绍如何在 Devmo wiki 中自定义 CSS 类。无论任何原因,如果您需要为本 wiki 创建自定义 CSS 类,请随时联系 Dria.
-

diff --git a/files/zh-cn/archive/misc_top_level/images,_tables,_and_mysterious_gaps/index.html b/files/zh-cn/archive/misc_top_level/images,_tables,_and_mysterious_gaps/index.html deleted file mode 100644 index 7fa8f2d4e0..0000000000 --- a/files/zh-cn/archive/misc_top_level/images,_tables,_and_mysterious_gaps/index.html +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: 'Images, Tables, and Mysterious Gaps' -slug: 'Archive/Misc_top_level/Images,_Tables,_and_Mysterious_Gaps' -translation_of: 'Archive/Misc_top_level/Images,_Tables,_and_Mysterious_Gaps' ---- -
-

本文所介绍的技术不再是Web开发的最佳实践。现在推荐用CSS布局。 但是当开发者不能确定用户使用的是现代浏览器时,这些技术可能是有用的,比如基于HTML的e-mail消息。

-
- -

无论何时你开始创建一个网页,当其设计是基于经典的“表格和多图像时”你的烦恼是相当多的 。 不管你是切一个图标去很好的适应设计, 或者使用大量的单像素GIFs间隔, 这些原理都是大同小异的. 在较早的时候, 这种方法是能很好工作的, 因为浏览器可以将表格单元的宽和高设置成其包含的图像的大小一样。

- -

到了2001年的时候, 以及基于标准的浏览器的兴起,它们使用HTML和CSS而不是自己的私有布局算法来布局页面. 感谢CSS规范的一个不起眼的小特性, 基于表格的精确小图像布局已经是一个可以预见的灾难了。 这完全取决于现代浏览器的正确DOCTYPE, and kaboom!

- -

组件

- -

让我们来好好的看看这个问题, 和为什么这会成为一个问题. 我们来看一个简单的例子, 如图1: 一个表格包含了一个图片.

- -

Figure 1

- -

显然大多数的设计都比这更加的复杂,但是在这里我们必须要那些东西。一个图像和一个表格就已经够了。这个例子没有什么明显的错误。这不应该是这样的,因为其实浏览器的默认行为。

- -

现在让我们看看同样一个例子在具有严格DOCTYPE声明的现代浏览器上的表现。

- -

Figure 2

- -

注意图片下面出现了一个空格。 原来的表格的标记并没有改变-- 这是因为渲染模型发生了改变。 浏览器现在渲染的是图像所在的行,而不是直接渲染图像本身,图像在行内,而图像默认是内联元素,所以发生了上面的情况。

- -

如何创造内联内容

- -

为了理解这种情况是如何发生的, 让我们来看一看行盒子的结构,图像在行盒子内, 而行盒子在一个表格中, 如图3所示,一个标准的行盒子包含有文本内容。

- -

Figure 3

- -

图三中最值得我们注意的是基线 (图中的蓝色线), 其在行盒子中。 基线的确切位置取决于线框的“默认”字体(由红色框表示),其由包含行框的元素的font-family的值确定. 基线的位置不能由人为改变。所以他的位置就在那儿。基线之下的空格被称为“下降空间”,因为这样就可以绘制小写字母如“j”,“y”和“q”的下降字符串。图4显示了当将图像添加到混合中时会发生什么。

- -

Figure 4

- -

请注意图像默认位置:其底边与线框的基线对齐。可以使用垂直对齐方式更改此位置-- 我们等会再来讲这个问题-- 但几乎没有人将其默认值改变。我们拿走文本,只留下图像,如图5所示。

- -

Figure 5

- -

所以我们有一个图像坐在只包含图像的行框的基线上. 现在考虑当我们把这个行放在表单元格中时会发生什么(图6)。

- -

Figure 6

- -

所以空格出现了--以前从未出现的空格. 在小图像下他更糟糕, 如图7所示的一个像素高的图像。

- -

Figure 7

- -

现在有各种各样的意外空格。足以让设计师疯狂。

- -

怎样修复它?

- -

显而易见的方法-- 停止创建基于表格和切片的单像素图像-- 但这对于许多设计师来说并不是很实际,它确实不会帮助修复最近浏览器中突然爆裂的旧设计. 还有一个明显的修复方法,就是确保你的文档不会触发“标准”渲染模式。

- -

你可以使用 DOCTYPE 来触发 "quirks" mode 或者 "almost standards" mode, 或者在你的文档中移除DOCTYPE声明. 缺少DOCTYPE将阻止验证,因此不推荐。对于使用遗留文档的作者,DOCTYPE的 "quirks" 模式是一个最好的选择。 在作者正在撰写新文档或尝试将设计迁移到尽可能基于标准的情况下,“几乎标准”模式可能是更好的选择。

- -

当然,XHTML Strict或HTML Strict创作的文件将触发“标准”渲染模式,因此我们将通过两种基本方法来解决严格的文档中的问题,以及一些方法来调用这些“修复“。

- -

将images设置为block元素

- -

第一选择,以及最适合大多数图形强烈设计的选择,是将图像从内联元素转换为块级元素。这样做,它不再生成一个线框,所以问题消失了 - 假设图像是唯一占据该表格单元格的东西。在最简单的情况下,我们可能会添加如下样式:

- -
 td img {display: block;}
- -

考虑这个规则将应用在如下的标记中:

- -
<table cellspacing="0" cellpadding="0" border="0" width="500">
-<tr><td><img src="nav1.gif"><img src="nav2.gif"><img src="nav3.gif"><img
-src="nav4.gif"><img src="nav5.gif"></td></tr>
-<tr><td style="background: red;">
-<img src="smallred.gif" height="1" width="1"></td></tr>
-<tr><td>
-<p style="margin: 0.5em;">This is text in another cell of the
- table.  Within the textthere is an icon <img src="icon2.gif">
- that indicates a link to another site.  It's very worldly.  Lorem
-ipsum, dolor sit amet...</p></td></tr></table>
- -

如图8所示,他在一些情况下表现很好但是在另一些情况下则不是。

- -

Figure 8

- -

细红线表明单像素间隔GIF现在只使单元格高一个像素, 正如预期一样。 不幸的是,顶部单元格中的按钮现在都是块级别,因此最终堆叠在另一个顶部,而不是并排显示。

- -

一个潜在的解决方案是将一个类添加到需要为块级别的任何图像上,然后写入匹配的规则。

- -
td img.decoration {display: block;}
-
-<td><img src="reddot.gif" class="decoration"></td>
- -

然而,根据设计,这可能会导致为这一个简单的效果添加了很多类。如果有许多单像素单元旨在创建酷堆叠线,或类似的一些东西,这将尤其如此。 如果您的标记适用于此方法,则可以对表行进行类,而不是映像。因此你可能有:

- -
tr.decoration img {display: block;}
- -

...以及标记中的以下更改:

- -
<tr class="decoration"><td style="background: red;">
-<img src="smallred.gif" height="1" width="1">
-</td></tr>
- -

其结果是仅使间隔GIF块级别,从而使其他图像单独存在。这导致图9中的结果。

- -

Figure 9

- -

或者,您可以将表格单元格替换为行,如果这是更好的选择。 然而,在任何这些情况下,如果您的表格单元格不仅仅是单个图像,那么使图像块级别可能会产生意想不到的副作用,如图8所示。

- -

当然,当我们在图9中有一个单像素间隔单元时,在顶部的导航按钮下方仍然有不需要的空间。 摆脱这个空间可以像将每个图像放在自己的单元格中一样容易,并使它们都是块级的,但是让它们放在一个单元格中,所以我们可以说明另一种方法。

- -

用 vertical alignment

- -

另一个主要选择是将图像内联并改变图像相对于线框的垂直对齐方式。例如,您可以尝试以下操作:

- -
td img {vertical-align: bottom;}
- -

这将导致图像的底部边缘与线框的底部对齐,而不是基线。 如图10所示,这具有预期的效果:我们的导航栏图像下的空间已经消失。 然而,装饰细胞仍然太高,并且其他图像相对于它们周围的文本不对准。

- -

Figure 10

- -

再次,我们可以对图像,单元格或行进行分类,以缩小效果的焦点。 然而,上面所示的样式不能克服单像素图像的问题,因为它们周围的线框将是表格单元格的字体大小的高度,因此不会缩小。 图像将移动到单元格的底部,但单元格不会“缩小”图像。 另外,比线框短的任何其他图像都很高,在它周围仍然会有空间 - 就像红色间隔单元一样。 单元格中的单像素图像现在与单元格的底部对齐,但是行框返回,它是正常文本的大小。

- -

参见例如图11,其中文档的字体大小已经被提高到大量。导航栏图像现在有空间出现在它们之上,而红色的隔片变得更大。

- -

Figure 11

- -

很难避免这种情况,因为图像(在这种方式)仍然是内联的,因此仍然参与创建一个行框。如果线框足够高,则图像周围的空间将开始出现。

- -

期待修复

- -

感谢Mozilla对CSS2的全面实施,CSS工作组注意到表单中的内联图像强制打开不需要的空间的问题。 已经有很多建议来解决这个问题,但是最有希望的方法之一就是包含在CSS3中的 line-box-contain, 如果该属性被采用,那么任何支持它的浏览器都可以模仿传统的“收缩包装”行为,而不会因为以下规则而导致其他布局不安的风险:

- -
td {line-box-contain: font replaced;}  /* proposed for CSS3 */
- -

目前的CSS3工作草案中还有其他可能的修复程序,例如line-height-policy。显然,可以找到并实现更快的解决方案,到处都是更快乐的作者。 

- -

建议

- -

对CSS3的支持不够,难以为每个固定问题提供一套明确的步骤,因为给定文档的最佳解决方案将在很大程度上取决于其结构。 如果您的文档使用过渡标记,请确保您的DOCTYPE反映该事实,并且不触发“标准”模式。 这将阻止浏览器使用基于标准的渲染,因此避免了所有的图像布局问题。 如果您使用严格的标记,或者您需要其他原因进行“标准”渲染,请记住以下准则:

- - - -

通过明智的混合方式和减少单像素图像技巧 - 在CSS功能的浏览器中,无论如何都是不必要的 - 这很有可能回避标准支持的这种奇怪的影响。 最好的解决方案可能是确保图像自身始终处于单元格中,从而允许作者使其成为块级,但一如以往将取决于作者的设计。

- - - - - -
-

Original Document Information

- - -
- -

 

diff --git a/files/zh-cn/archive/misc_top_level/index.html b/files/zh-cn/archive/misc_top_level/index.html deleted file mode 100644 index 95bf3b61ab..0000000000 --- a/files/zh-cn/archive/misc_top_level/index.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Misc top level -slug: Archive/Misc_top_level -translation_of: Archive/Misc_top_level ---- -

In progress. These pages were moved from the top level of MDN in a spate of furious reorganization.

- -

diff --git a/files/zh-cn/archive/misc_top_level/same-origin_policy_for_file_colon__uris/index.html b/files/zh-cn/archive/misc_top_level/same-origin_policy_for_file_colon__uris/index.html deleted file mode 100644 index c53fd40c77..0000000000 --- a/files/zh-cn/archive/misc_top_level/same-origin_policy_for_file_colon__uris/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: 档案同源策略 -slug: 'Archive/Misc_top_level/Same-origin_policy_for_file:_URIs' -tags: - - Same-origin policy - - XML - - 同源策略 - - 安全 -translation_of: 'Archive/Misc_top_level/Same-origin_policy_for_file:_URIs' ---- -

在Gecko 1.8或更早版本中,任意两个file:URI被认为是同源的。换句话说,本地磁盘上的任何HTML文件都可以读取本地磁盘上的任何其他文件。

- -

从Gecko 1.9开始,文件只允许读取某些其他文件。具体来说,只有当源文件的父目录是目标文件的祖先目录时,文件才能读取另一个文件。然而,目录不能以这种方式加载。

- -

举例来说,你有一个文件foo.html想要读取另一文件bar.html,你通过index.html进入了它,只有当bar.html存放于与index.html相同文件夹,或是index.html所在文件夹底下的子文件夹中时,才能读取成功。

- -

档案同源政策会影响到所有对同源政策的检查的行为,包括  XMLHttpRequest , XSLT,与XBL。

- -

至于跨window的DOM存取,基本上每一个档案都被视为不同源,除了以下例外:若是档案B被另一个档案A载入(例如透过iframe或window.open() ),而档案A、B遵照此份档案同源政策可以被判定属于同源,那么当发生跨window的DOM存取时,也可以视为同源。(译者注:应该可以理解为,可以通过subframe, link, location set, 调用window.open()之类的方法加载同源文件并对DOM进行操作

- -

例如, /home/userfoo.html  是一个frameset,而它下嵌了另一个/home/user/subdir/bar.html  的  frame ,那么foo.html和bar.html可以视为同源,但如果/home/userfoo.html  是/home/user/subdir/bar.htm的frameset下嵌的 一个frame,那么foo.html和bar.html便不可以视为同源。

- -

另外当使用者想要关闭这些档案同源政策检查,可以变更  security.fileuri.strict_origin_policy  偏好设定为从预设true到false。

diff --git a/files/zh-cn/archive/misc_top_level/using_xml_data_islands_in_mozilla/index.html b/files/zh-cn/archive/misc_top_level/using_xml_data_islands_in_mozilla/index.html deleted file mode 100644 index 205769796d..0000000000 --- a/files/zh-cn/archive/misc_top_level/using_xml_data_islands_in_mozilla/index.html +++ /dev/null @@ -1,192 +0,0 @@ ---- -title: Using XML Data Islands in Mozilla -slug: Archive/Misc_top_level/Using_XML_Data_Islands_in_Mozilla -tags: - - XML -translation_of: Archive/Misc_top_level/Using_XML_Data_Islands_in_Mozilla ---- -

One handy feature of Internet Explorer is the ability to use data islands to link data to html controls on a page. This feature is not readily built into Mozilla, but one can easily mimic this behaviour to build cross-browser web applications.

-

The basic data island we are going to use is a simple xml element either linked to the page or explicitly coding the xml into the page. For instance, let us illustrate a simple example:

-
<xml id="xmlDataIsland">
-   <loaninfo>
-       <borrower id="1">
-           <firstname>Brian</firstname>
-           <middlename>Ellis</middlename>
-           <lastname>Johnson</lastname>
-       </borrower>
-   </loaninfo>
-</xml>
-
-

With this data island, we can populate any number of controls on a page simply by linking the data island to the controls via some JavaScript and the DOM.

-

To link this, all we need to do is have a function to handle populating the controls such as:

-
function loadFields()
-{
-   var xmlNode = window.document.getElementsByTagName('xml');
-   var borrowerNode = xmlNode[0].childNodes[1];
-   if(borrowerNode.hasChildNodes())
-   {
-       var i = 0;
-       var xmlChildNode, nodeVal=;
-       while(borrowerNode.childNodes[i])
-       {
-           // get node
-           xmlChildNode = borrowerNode.childNodes[i];
-           // check nodetype
-           if(xmlChildNode.nodeType != 3) // #text == 3
-           {
-               // get nodeValue (aka text)
-               nodeVal += xmlChildNode.firstChild.nodeValue + ' ';
-           }
-           i++;
-       }
-       // set control value to nodeValue
-       window.document.getElementById('txtBorrowerName').value = nodeVal;
-   }
-}
-
-

Example 1

-

Here is another example of an XML DataIsland for use in Mozilla or IE:

-
<xml id="mxxdataisland">
-   <mxxdataisland>
-       <rowset tagid="DATES"></rowset>
-       <rowset tagid="SUBJPRP"></rowset>
-       <rowset tagid="PRODUCT"></rowset>
-   </mxxdataisland>
-</xml>
-
-

This dataisland's purpose is to inform the Application Server what tables this page is going to need access to or be requesting information from.

-

The controls on the page are then linked by way of custom attributes MXXOBJECT and MXXPROPERTY, much like the DATASRC and DATAFLD attributes used by IE. This allows the XML data returned to be parsed and linked or "bound" to the controls.

-

Note: MXXOBJECT and MXXPROPERTY are just attributes that I made up, these actually could be any attribute.

-

Binding the controls:

-
<input
-    type="text"
-    id="PropertyStAddr1"
-    name="PropertyStAddr1"
-    style="height:21px;width:302px;text-align:left;"
-    maxlength="35"
-    class="fldDefault"
-    mxxobject="SUBJPRP" mxxproperty="PropertyStAddr1" <-- here are our "binding" tags
->
-
-<input
-    type="text"
-    class="fldZipCode"
-    name="PropertyZip"
-    id="PropertyZip"
-    size="10"
-    style="height:21px;width:69px;"
-    mxxobject="SUBJPRP" mxxproperty="PropertyZip" <-- here are our "binding" tags
-    mxxxmlnode="xmldef_PropertyZip" <-- this links to a control-level data island
-    mxxtype="MXXZipCodeAutoLoadEdit" <-- optional custom type for control handling
->
-
-

Since we are passing XML to the server, we can also send the server some additional info that a particular control may need, or alert the server of other controls on the page related to or driven by a control. The following is an example of a custom dataisland for a specific control type:

-
<select
-    id="PropertyState"
-    name="PropertyState"
-    style="height:20px;width:48px;"
-    class="cmbDefault"
-    mxxtype="GFXStateList"
-    mxxxmlnode="xmldef_PropertyState"
-    mxxobject="GOXSUBJPRP" mxxproperty="PropertyState"
->
-</select>
-
-<div style="width:0px; height:0px; visibility:hidden;z-index:1">
-    <xml id="xmldef_PropertyState">
-        <mxxstatelist>
-            <status value="initialize"></status>
-            <contenttype value="abbrev"></contenttype>
-            <controls>
-                <control type="countylist" tagid="PropertyCounty" contenttype="name"
-                         valuetype ="name"></control>
-            </controls>
-        </mxxstatelist>
-    </xml>
-</div>
-
-

These XMLDataIslands don't do us any good just like this. In order for them to work we need to do 2 things.

-

1. Build control handlers to handle the updating and rendering of different control types.

-

(Note: Control types can be anything. Form objects, tables, spans, divs, iFrames, anything that you can access via the DOM and an ID is eligible)

-

2. Build a handler to build a dom to send to the server and parse the return back out to the controls.

-

All a control handler has to do is be able to updata a control value. This means all Text Inputs can share a handler, selects another, and so on. One way to do this is to scrape the controls on a given page into an associative array. Then, when a response is returned, we can parse out the xml via an id attribute to match up the xml payload with a control.

-
<input type="text" id="FirstName" ...>
-
-

Sample Object collector function:

-
   // grab all the elements for parsing
-   var tags = window.document.body.getElementsByTagName("*");
-   var pPrevElem = null;
-   var pNextElem = null;
-   for (var i = 0; i < tags.length; i++)
-   {
-       pHTMLElement = tags[i];
-
-       switch (pHTMLElement.tagName.toLowerCase())
-       {
-           case "span":
-           case "table":
-               // this indexes by controlID and stores the elementObject
-               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
-               break;
-           case "input":
-           case "select":
-           case "textarea":
-           case "button":
-               // this indexes by controlID and stores the elementObject
-               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
-               break;
-           case "div":
-               // this indexes by controlID and stores the elementObject
-               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
-               break;
-       }
-   }
-
-

The xml payload going out might be:

-
<page id="NewUser">
-    <formcontrols>
-        <control id="FirstName">
-            <value />
-        </control>
-    </formcontrols>
-</page>
-
-

The return would then be:

-
<page id="NewUser">
-    <formcontrols>
-        <control id="FirstName">
-            <value>Dennis</value>
-        </control>
-    </formcontrols>
-</page>
-
-

The parsing handler would then take the response, load it into an XML DOM, then pass out each node to the appropriate control handler.

-
   processTextControl(control, xmlNode);
-
-

Sample parsing of returned xml:

-
   // parseout to controls
-   var formControlNodes = xmlDoc.getElementsByTagName('formcontrols');
-   for(i=0; i<formControlNodes.length;++i)
-   {
-       var pFormControlNode = formControlNodes[i];
-       var pPageObject = m_MXXPageObjectsArray[pFormControlNode.getAttribute('id')];
-       if(!pPageObject)
-           continue;
-       processTextControl(pPageObject, pBoundControlNode);
-   }
-
-

The control handler would then rip out the necessary data to populate the control. In this case the value nodevalue would be used to set control.value. A select could have the options to loop through and create new Options() with or even just replace the node or innerHTML with the new payload.

-

Here is a sample page.

-

Finally here is a small table sample using XML Data Islands that works in both IE6 and Mozilla.

-

For any of the above to do us any good, we need to get this info to the server. We can do this a number of ways, including ASP, JSP, and CGI. I'm going to use XMLHTTP since it allows for me to update a page without having to reload it and it allows for the controls to update other controls and act like a regular 2 tier applicationa by providing instant updates and event handling.

-

Author: Thad Hoffman

-
-

Original Document Information

- -
-

 

diff --git a/files/zh-cn/archive/mozilla/compiling_the_npruntime_sample_plugin_in_visual_studio/index.html b/files/zh-cn/archive/mozilla/compiling_the_npruntime_sample_plugin_in_visual_studio/index.html deleted file mode 100644 index 64c3a0f200..0000000000 --- a/files/zh-cn/archive/mozilla/compiling_the_npruntime_sample_plugin_in_visual_studio/index.html +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Compiling The npruntime Sample Plugin in Visual Studio -slug: Archive/Mozilla/Compiling_The_npruntime_Sample_Plugin_in_Visual_Studio -translation_of: Archive/Mozilla/Compiling_The_npruntime_Sample_Plugin_in_Visual_Studio ---- -

通用选项

- - - -

Build

- -
    -
  1. 创建一个Win32 GUI library工程 (DLL) (在.NET 2003版本中: 选择模板中的Win32 , 然后在弹出的对话框中找到应用程序类型,勾选DLL, 不添加公共头文件。)(在VS2008版本中,选择Visualc++|Win32|Win32 Project, 然后在向导中勾选DLL).
  2. -
  3. 如果向导询问你是否创建一个空项目,那么勾选它。否则你需要在后面手动删除向导给你创建的文件。
  4. -
  5. 请注意接下来的DLL创建中文件名必须以"np"开头, 你可以以这样的命名格式给你的工程命名,或者在后面的步骤中重命名你的项目。
  6. -
  7. (如果你不是创建了一个空项目才需要进行此步骤)从你的工程与磁盘中删除.cpp文件、.h文件、ReadMe文件。
  8. -
  9. 复制npruntime例子插件源码到新创建工程的VS目录下,然后使用VS的界面向导方式添加这些文件到工程中。(.cpp文件添加到"源文件", .h 文件添加到 "头文件", .rc 文件添加到"资源文件"). 例子可以从以下网址获取:
    - https://developer.mozilla.org/en/Plugins/Samples_and_Test_Cases
  10. -
  11. 下载NPAPI SDK.
  12. -
  13. 添加NPAPI SDK的include目录 (例如 : C:\npapi-sdk\headers) 到项目属性|(所有配置)|C++|常规|附加包含目录. 注意: 如果你的项目仍然为空,C++树可能无法查看。所以先添加一些文件吧。
  14. -
  15. Add the following preprocessor definitions to Project Properties|(all configurations)|C++|Preprocessor|Preprocessor Definitions: WIN32;_WINDOWS;XP_WIN32;XP_WIN;_X86_;NPSIMPLE_EXPORTS
  16. -
  17. Disable precompiled headers using Project Properties|(all configurations)|C++|Precompiled headers|Create/Use precompiled header. They may be already disabled.
  18. -
  19. Define the function exports by adding the .def filename (e.g. nprt.def) to Project Properties|(all configurations)|Linker|Input|Module Definition File. It could be either the full path or the path relative to the project directory.
  20. -
  21. Optional: Open the above .def file and change "NPRT" to the filename of your dll as VS sees it (without "np", if you decided to rename later)
  22. -
  23. Optional: Edit the .rc file and and the top of npp_gate.cpp for the description, mimetype, file extension etc. to reflect your plugin
  24. -
  25. Remove the function NPP_GetJavaClass from npp_gate.cpp
  26. -
  27. Build
  28. -
  29. Rename the resulting DLL so that the filename starts with "np" and ends with ".dll" (or "32.dll"? 8.3?) and copy it in Mozilla's "plugins" folder
  30. -
  31. Start Mozilla and open about:plugins to verify the plugin is detected
  32. -
  33. Open the file "test.html" and begin testing. Make sure the mimetypes of your html embed tags match the mimetype specified in your nprt.rc file and the top of your npp_gate.cpp file
  34. -
- -

Version Issues

- -
    -
  1. If VC++ compiler throws you error C2664 on 'DrawText' function call, you may replace it by 'DrawTextA'. In fact, all win32 API functions dealing with character strings can be added an 'A' to the end to avoid unicode cast errors.
  2. -
  3. Visual C++ 2008 Express don't support C99 standard about int32_t, uint32_t. You have to add #include "nptypes.h" in top of plugin.h file.
  4. -
  5. Feel free to append here your issues fixes if the above guide helped you.
  6. -
diff --git a/files/zh-cn/archive/mozilla/getting_started_with_irc/index.html b/files/zh-cn/archive/mozilla/getting_started_with_irc/index.html deleted file mode 100644 index 730a987f20..0000000000 --- a/files/zh-cn/archive/mozilla/getting_started_with_irc/index.html +++ /dev/null @@ -1,316 +0,0 @@ ---- -title: Getting Started with IRC -slug: Archive/Mozilla/Getting_Started_with_IRC -tags: - - 'IRC: xgqfrms' - - MDN - - irc -translation_of: Archive/Mozilla/Getting_started_with_chat ---- -

什么是 IRC?

- -

IRC, or Internet Relay Chat, is a form of real-time text messaging between multiple users at the same time. Users connect to a server using an IRC client and join channels (chat rooms). Users type messages which are broadcasted to all users within a channel. IRC also allows one to one communication between connected users. This is the primary form of communication for members of the Mozilla community; developers, testers, users, and the like.

- -

通用规则和礼仪

- -

Once you have your client set up (see software below) and are connected to IRC, there are some basic rules you should follow to ensure the most enjoyable and productive IRC experience:

- -

 

- -

1. Try to keep messages as concise as possible. If you have something long to post, a code snippet for example, use pastebin.mozilla.org and paste the generated URL in IRC instead.

- -

2. When addressing someone directly, try to use name: message format. For example, "ashughes: good morning!"

- -

3. Every channel has its own topic. Try to keep your messages within that subject matter. For example, do not talk about Thunderbird issues in #Firefox.

- -

4. Mozilla's IRC channels are most active between 9am and 7pm PST Monday to Friday, excluding US Holidays.

- -

5. When asking a question, be patient. Sometimes, it can take a few minutes for people to respond.

- -

6. Posting a message like "Help!" is not particularly helpful. Asking a good question will result in a better experience for both you and the person trying to help. There is a good reference for what makes a good question here.

- -

7. Relax and have fun!

- -

软件

- -

ChatZilla – The Firefox Add-on

- -

There are several different applications which allow you to connect to IRC networks. The easiest one to use is an add-on for Firefox called Chatzilla. The following instructions describe how to install and configure Chatzilla for use on the Mozilla IRC network:

- -

1. Go to addons.mozilla.org to download and install Chatzilla

- -

2. Click the green Add to Firefox button

- -

3. Click the Install button on the Addon Installation dialog

- -

4. Once ChatZilla is installed, click Restart Firefox

- -

5. Once Firefox restarts, close the Add-ons dialog

- -

6. Now click Tools menu > ChatZilla to start the client

- -

7. In the textbox at the bottom of the window type /server irc.mozilla.org and press enter

- -

8. You will be given a random username when you first connect. Usually the client will just use your computer username. If this name is already in use, it will use something like IRCMonkey21710. You can change your nickname by typing /nick nickname, where nickname is your desired nickname. You can also change your nickname using the dropdown box to the left of the textbox.

- -

See the Commands section below for more IRC commands.

- -

9. To join a channel type /join #channel, where #channel is the name of the channel you want to join.

- -

See the Channels section below for some channels available on the Mozilla IRC network.

- -

Desktop Clients

- -

As mentioned earlier, ChatZilla is not the only IRC client available, though it is the simplest. The advantage is that the desktop clients allow much more detailed configuration. For example, you can connect using SSL or a non-secure connection, and you can configure the client to automatically connect to a server and join a particular set of channels when you start the client. The following are some other options available to you:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  -

Windows

-
-

Mac

-
-

Linux

-
Colloquy  -

-
 
IRSSI -

-
-

-
-

*

-
Xchat -

-
-

-
-

*

-
- -

Binary or executable program available

- -

○ Only available by downloading and compiling source code

- -

●* Binary or executable may be available. If not, you'll have to download source code and compile.

- -

w Web-based client (i.e. it runs in the browser)

- -

For a complete list of IRC clients go here.

- -

If using a desktop client, you will need to use the following information to configure the server connection:

- -

Server: irc.mozilla.org

- -

Port: 6667 (default) or 6697 (SSL)

- -

网络客户端

- -

There are also a few web-based clients which allow connecting to IRC by clicking on irc:// links. One of the simplest web-based clients is Mibbit, another is IRCCloud. These operate very much in the same way as the previously mentioned desktop clients and ChatZilla. Mibbit does NOT require flash or any other plugins.

- -

频道

- -

Here is a list of channels you should be aware of as a member of the Mozilla community: (Remember to use irc.mozilla.org and port 6697 or 6667 for your server settings)

- - - - - - - - - - - - - - - - -
#qaA channel for QA discussion
#developersA channel for Mozilla development discussion
#sumoA channel for support with Firefox
- -

For more information about the Mozilla IRC network and more channels, go here.

- -

指令

- -

The following is a list of commands you should be familiar with. Simply type them into the message box at the bottom of the screen and press enter:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/join #channelJoins you to the specified channel until you quit your IRC client or quit the channel
/leaveLeave the current channel
/mode #channel +k passwordSets a password for the channel. If #channel is not specified, the command is executed for the current channel.
/mode #channel +o nicknameSets specified user as an owner or moderator of the specified channel. If a #channel is not specified, the command is executed for the current channel.
/mode #channel +sSets the channel as a secret channel. This takes the channel off the public list of active channels and topics.
/msg nick messageSends a private message to the specified user
/nick nicknameChange your current nickname
nickname: pingGet a user's attention (nickname is the name of the user you want the attention of)
nickname: pongRespond to a user's ping (nickname is the name of the user who wants your attention)
/query nicknameOpens a private chat with the specified user
/quit messageDisconnects you from the current server displaying the message in all connected channels prior to quitting
/reload stylesSome IRC clients, Colloquy on Mac in particular, stop displaying your messages in the channel window. If this happens, you can type this command to resolve this issue.
/server server-nameManually connect to a server
/topic topicChanges the topic of the channel. The topic is a message that displays first when you join a channel.
/whois nicknameDisplay information about the specified user. This information displays in the server window.
- -

For more information about IRC commands go here.

- -

机器人

- -

Some users in IRC are not human. These users are known as bots and automatically perform certain tasks; some automatic, some triggered by other users. The most common of these bots are called NickServ, ChanServ, and Firebot.

- -

NickServ

- -

This bot allows you to register your nickname which prevents other users from using it. NickServ also automatically elevates all registered users to operators when they sign on.The following are some helpful commands which can be used by NickServ:

- - - - - - - - - - - - - - - - - - - - - - - - -
/msg NickServ REGISTER password emailThis registers your nickname with the server.
/msg NickServ IDENTIFY passwordOnce registered, you need to type this every time you want to sign into channels using your registered nickname
/msg NickServ HELPThis displays a list of commands which can be used with NickServ
/msg NickServ HELP REGISTERThis displays helpful information about nickname registration
/msg NickServ HELP IDENTIFY This displays helpful information about identifying yourself upon sign in
- -

For more information about NickServ go here.

- -

ChanServ

- -

This bot allows you to register new channels and control aspects of channels. The following are some helpful commands which can be used by ChanServ:

- - - - - - - - - - - - - - - - -
/msg ChanServ HELPThis displays a list of commands which can be used with ChanServ
/msg ChanServ IDENTIFY #channel passwordAllows you to edit the aspects of the specified channel given the correct password
/msg ChanServ REGISTER #channel password topicRegisters a channel given the correct password and sets the topic
- -

For more information about ChanServ go here.

- -

Firebot

- -

Firebot is a bot which assists with Mozilla related activities on IRC. For instance, Firebot automatically posts messages to #developers about the status of automated tests. The following are some helpful commands which can be used by Firebot:

- - - - - - - - - - - - - - - - - - - - -
bug ######When a bug number is mentioned in a message, Firebot automatically displays the link and summary from bugzilla for that bug.
/msg firebot uuidDisplays a unique identifier. This is useful when creating interfaces for add-on development.
/msg firebot cidDisplays a unique 128-bit number which can be used to identify a class or component.
/invite firebot #channelAdds firebot to the specified channel.
- -

For more information about Firebot go here.

- -

进一步阅读

- -

IRC Channel Operator's Guide (New Version) IRC Channel Operator's Guide (Old Version) [From 1995, but still quite useful]

diff --git a/files/zh-cn/archive/mozilla/help_viewer/creating_a_help_content_pack/index.html b/files/zh-cn/archive/mozilla/help_viewer/creating_a_help_content_pack/index.html deleted file mode 100644 index 2a64c576e7..0000000000 --- a/files/zh-cn/archive/mozilla/help_viewer/creating_a_help_content_pack/index.html +++ /dev/null @@ -1,200 +0,0 @@ ---- -title: Creating a Help Content Pack -slug: Archive/Mozilla/Help_viewer/Creating_a_Help_Content_Pack -translation_of: Archive/Mozilla/Help_viewer/Creating_a_Help_Content_Pack ---- -

Original doc: http://www.mozilla.org/projects/help.../content_packs I hesitate to call it "original", tho, because I've basically rewritten the entire thing so that it's easier and faster to use to create Help content. The previous document had a lot of places where ideas were simply introduced without explanation, and I've tried to go through things a bit more slowly with better descriptions. This is still very much a work in progress, tho, and I need to complete the rest of it soon (where "complete" means "use what's there that's good, build on the stuff that's not as good, and add other useful information as necessary".

-

This document describes how to integrate HTML help documentation into your application using the Mozilla Help Viewer. Documentation contained in the Help Viewer can be accessed using any XUL application or program that embeds Mozilla.

-

What is a Content Pack?

-

A Content Pack is a packaged set of files that describe Help content. Content Packs include help documents written in XHTML, a content pack descriptor file written in RDF, and a table of contents, index, and glossary (also written in RDF). You can create a content packs which inherit from existing Mozilla Help content packs.

-

The Contents of a Content Pack

-

Content Packs consist of a general pack description file, table of contents, index, search, glossary, and help documents. The help documents are written in XHTML, and the rest are written in RDF. The content pack descriptor file outlines the framework of the contents of the pack by pointing to the files describing the table of contents, index, and glossary RDF files. The table of contents and index files are simple tree-based outlines written in RDF. The glossary file is written in RDF and consists of a simple list of terms with corresponding URLs to the term definition.

-

Creating a Content Pack

-

The Content Pack Descriptor File

-

As mentioned earlier, the content pack descriptor file is written using RDF. If you don't know RDF, that's okay - for our purposes, you won't need to learn very much. If you understand the basics of HTML or (preferably) XML, you'll understand the very basics of the syntax - elements, attributes, and element contents. Understanding the syntax is important because small syntax errors can mean that a whole file won't be loaded correctly. However, while it may seem like this is a disadvantage, it's actually an advantage - if you make an error you'll know immediately, and you should be able to easily figure out what the problem is by directly loading the file in Firefox. Later, when we get to actually writing content, you'll need to know XHTML, but for now knowledge of the syntax should be enough.

-

Open up your favorite text editor and create the file content-pack.rdf. Insert into it the following text:

-
<?xml version="1.0"?>
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-         xmlns:nc="http://home.netscape.com/NC-rdf#">
-
-</rdf:RDF>
-
-

If you're familiar with HTML or XML, you might recognize this as the container element for the whole document. It serves as a wrapper around the entire contents of the file, marking it as RDF.

-

Next, you'll need to insert a rdf:Description element into the file, inside the rdf:RDF element just created:

-
    <rdf:Description rdf:about="urn:root"
-                     nc:title=""
-                     nc:defaulttopic=""
-                     nc:base="">
-    </rdf:Description>
-
-

Fill in the attributes as follows:

- -

Next, we need to describe where to find the glossary, index, and table of contents. (We're still not actually to the point where we're describing the actual data in each of these, so we'll just use some filler data for now.) Add the following code inside the rdf:Description element you just created:

-
      <nc:panellist>
-        <rdf:Seq>
-
-        </rdf:Seq>
-      </nc:panellist>
-
-

You'll create the relevant information descriptions within the rdf:Seq element.

-

The location of each of the glossary, index, and table of contents data sources is stored in one rdf:Description element contained within one rdf:li element, like so:

-
            <rdf:Seq>
-                <rdf:li>
-                    <rdf:Description nc:panelid="glossary"
-                                     nc:datasources="chrome://foo/locale/help/glossary.rdf"/>
-                </rdf:li>
-                <rdf:li>
-                    <rdf:Description nc:panelid="toc"
-                                     nc:datasources="chrome://foo/locale/help/glossary.rdf"/>
-                </rdf:li>
-                <rdf:li>
-                    <rdf:Description nc:panelid="index"
-                                     nc:datasources="chrome://foo/locale/help/glossary.rdf"/>
-                </rdf:li>
-            </rdf:Seq>
-
-

The Help Viewer UI may or may not provide a panel for each of these data sources. In Firefox 1.0 each data source had a panel. Starting with Firefox 1.1 and the Mozilla 1.8 platform, only the table of contents data source will be displayed. The glossary and index data sources will be - - hidden - - information found only in them will not be displayed unless the user conducts a search of the Help pack that would return glossary or index results.XXX this sentence is ugly - a little rewording help here would be nice

-

A data source description is pretty much the same no matter which type you're defining, and the syntax is pretty simple. Each panel is specified by one rdf:Description element with the following attributes:

- -
                <!-- Assumptions:
-                     win-toc.rdf contains Windows- and OS/2-specific info,
-                     unix-toc.rdf contains Linux- and Mac-specific info. -->
-                <rdf:li>
-                    <rdf:Description nc:panelid="toc"
-                                     nc:platform="win os2"
-                                     nc:datasources="win-toc.rdf"/>
-                </rdf:li>
-                <rdf:li>
-                    <rdf:Description nc:panelid="toc"
-                                     nc:platform="unix mac"
-                                     nc:datasources="unix-toc.rdf"/>
-                </rdf:li>
-
-

There's one final element to add inside rdf:Seq to complete the content pack descriptor file: an element to describe the Help Viewer's search function. Search automatically goes through all of the elements in the table of contents, index, and glossary, but you might wish to have Search go through more sources of data. One possible source might be an online, dynamically-generated list of added content stored on your web site. To have the Help Viewer search through these additional data sources, define another rdf:li element like so:

-
                <rdf:li>
-                    <rdf:Description nc:panelid="search"
-                                     nc:datasources=""
-                                     nc:emptysearchtext="[No matching items found.]"
-                                     nc:emptysearchlink="chrome://foo/locale/bar.html"/>
-                </rdf:li>
-
- -

Note that you can use the nc:datasources attribute to inherit content from other content packs. One common use of this is to inherit the small Using the Help Window article provided with the viewer. For example, the following code uses a datasource outside the content pack you have created to include the article in a table of contents:

-
                <rdf:li>
-                    <rdf:Description nc:panelid="toc"
-                                     nc:datasources="chrome://help/locale/help-toc.rdf chrome://foo/locale/help/glossary.rdf"/>
-                </rdf:li>
-
-
-

Each of the different data source types (toc, index, glossary, and search) may be used multiple times (and in the case of platform-specific information, must be used multiple times). However, it is recommended you use a space-separated list of URIs for nc:datasources instead of separate entries, as separate entries will require a slightly longer time to load.

-

The Glossary File

-

The glossary file has the simplest format of all the data sources you'll need because there's only one level of content. (The index, table of contents, and search data sources are more likely to be nested, complicating their formats.) Create a new RDF file (for now let's name it glossary.rdf), and add the following lines to it:

-
<?xml version="1.0"?>
-
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-         xmlns:nc="http://home.netscape.com/NC-rdf#">
-
-  <rdf:Description rdf:about="urn:root">
-    <nc:subheadings>
-      <rdf:Seq>
-
-
-      </rdf:Seq>
-    <nc:subheadings>
-  </rdf:Description>
-
-</rdf:RDF>
-
-

This forms the outer framework of a glossary description file. To add data to it, add one of the following per entry in your glossary within the rdf:Seq above:

-
        <rdf:li>
-          <rdf:Description nc:name=""
-                           nc:link=""/>
-        </rdf:li>
-
-

The rdf:li element serves purely to contain each separate entry. The rdf:Description element describes the glossary entry. It has two required attributes: nc:name and nc:link. nc:name is the name for the entry - it's what's currently displayed in the glossary as the entry's title. nc:link contains a URI referencing what will be displayed in the viewer when the entry is accessed.

-

The Index File

-
-

One important note on the index file is that there is no automatically generated set of top-level letters (e.g., A for Accessibility and Automation or B for Book and Border). Help documentation may be written in any language, so such automatic splitting is not desirable. You must implement such splitting if you wish to have it.

-
-

The index data source structurally differs from the glossary in that it is more likely to have multiple levels. A single-level index may be accomplished in exactly the same way as a glossary file, but multiple levels can make it easier to navigate to specific information. Let's start with a brief sample RDF file with a single level:

-
<?xml version="1.0"?>
-
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-         xmlns:nc="http://home.netscape.com/NC-rdf#">
-
-  <rdf:Description rdf:about="urn:root">
-    <nc:subheadings>
-      <rdf:Seq>
-        <rdf:li><rdf:Description nc:link="foo.html" nc:title="Foo"/></rdf:li>
-        <rdf:li><rdf:Description nc:link="baz.html" nc:title="Baz"/></rdf:li>
-      </rdf:Seq>
-    <nc:subheadings>
-  </rdf:Description>
-
-</rdf:RDF>
-
-

There's not much here: a single level containing the two entries "Foo" and "Baz". Now, let's say you want to add an entry "bar" underneath "Foo". How would you do this? First, you need to add an attribute to the "Foo" entry so that you can precisely refer to it. The rdf:ID attribute serves this purpose. It should be unique both within file and within the data sources in your content pack to ensure clarity.

-

 

-
        <rdf:li><rdf:Description rdf:ID="foo" nc:link="foo.html" nc:title="Foo"/></rdf:li>
-
-

Next, add the following to your file just after the existing rdf:Description element:

-
  <rdf:Description rdf:about="#foo">
-    <nc:subheadings>
-      <rdf:Seq>
-        <rdf:li><rdf:Description rdf:ID="bar" nc:link="bar.html" nc:title="bar"/></rdf:li>
-      </rdf:Seq>
-    </nc:subheadings>
-  </rdf:Description>
-
-

Except for the different value for rdf:about, this looks exactly like a top-level entry definition. The difference is a result of how RDF works. In RDF data describes data. Top-level entries describe the root node, urn:root; nested entries describe other entries. You can refer to an entry by giving the entry a unique rdf:ID attribute. Then, to describe that entry, you set an rdf:about attribute to the value of the entry's rdf:ID, prefixed by a #.

-

Nesting as described above works exactly the same no matter how deeply or shallowly nested your entry is. Nesting theoretically can work to any number of levels, but for practical reasons nesting is limited to roughly 20 levels. If you're coming anywhere close to this limit, however, you probably should be considering exactly why you need so much nesting.

-

The Table of Contents File

-

The table of contents file is the most important data source you'll create. The help viewer will display the table of contents when you start the viewer. In some versions of the viewer, it will be the - - only - data source ever directly displayed. It's the primary way to provide a structured view of the help you provide to users.

-

The table of contents also provides the list of topics from which the home page for the viewer will be chosen. Recall that in the content pack descriptor file you included an nc:defaulttopic attribute, which defaulted to "welcome". The value of that attribute is the rdf:ID of the topic you want displayed when the viewer is loaded.

-

The table of contents data source is exactly like an index data source, and if you have a working index data source you could use it as a table of contents with no changes whatsoever. See the instructions on creating glossary and index data sources to learn how to create a table of contents.

-

Additional Search Databases

-

Starting with Firefox 1.1, you can define additional information databases through which the help viewer will search. The data from these may never even be displayed to the user, but if he tries to search through Help, he will see results from these databases.

-

Defining a search database is exactly like defining a table of contents file (and therefore exactly like creating an index file), so follow the instructions there to create additional data sources as you need them.

-

Viewing your Content Pack in the Help Viewer

-

To launch the Help Viewer with your content pack, you need to have chrome://help/content/contextHelp.js loaded into the XUL file that provides the UI to open the help viewer:

-
  <script type="application/x-javascript"
-          src="chrome://help/content/contextHelp.js"/>
-
-

This will allow you to access all of the viewer functions. To open the Help Viewer, run the openHelp() function. It's exactly the same as any JavaScript command, you you can insert it in command elements, oncommand attributes, and other such places. The parameters are described below:

-
openHelp(aTopic, aContentPackSpec);
-
- -

Here is an example of how Firefox opens its help documentation:

-
openHelp('firefox-help', 'chrome://browser/locale/help/help.rdf');
-
-

Packing It All Up

-
-  
-

diff --git a/files/zh-cn/archive/mozilla/help_viewer/index.html b/files/zh-cn/archive/mozilla/help_viewer/index.html deleted file mode 100644 index 051ffdd64c..0000000000 --- a/files/zh-cn/archive/mozilla/help_viewer/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Help Viewer -slug: Archive/Mozilla/Help_viewer -translation_of: Archive/Mozilla/Help_viewer ---- -

Help Viewer: Allows information to be shown to the user inside Mozilla.

-

Introduction

-

Computers and software are incredibly complex. Naturally, then, everyone needs a little help now and then, and getting that help to the user is critical to making applications useful. Consequently, the Mozilla platform provides a cross-platform help viewer along with a framework for providing built-in help documentation. Mozilla's help viewer makes providing documentation an easy job, and this document will describe how you can use it.

- -

Articles & Tutorials

- -

Other Resources

- -
-  
-

diff --git a/files/zh-cn/archive/mozilla/index.html b/files/zh-cn/archive/mozilla/index.html deleted file mode 100644 index f4e2252d18..0000000000 --- a/files/zh-cn/archive/mozilla/index.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Archived Mozilla and build documentation -slug: Archive/Mozilla -translation_of: Archive/Mozilla ---- -

These articles are archived, obsolete documents about Mozilla, Gecko, and the process of building Mozilla projects.

-

Help Viewer
Help Viewer: Allows information to be shown to the user inside Mozilla.
Tamarin
XPInstall
XUL Explorer
XUL Explorer是一款提供一个很容易上手来进行XUL测试的 XULRunner 应用。这个编辑器很简单,他能在线预览或者在一个独立窗口预览XUL。它有一个列表的代码片段(小片段的XUL或JavaScript),可以快速插入到编辑器中。XUL可以加载和保存到文件。其中的XUL验证器和 错误控制台 可以帮助您找到问题所在。帮助菜单提供了访问 MDC上XUL信息的通道,更有 “keyword” 查找框帮助查找XUL元素。
拖拽
这部分描述了怎样实现可以拖拽和拖放到其他对象上的可拖拽对象。

diff --git a/files/zh-cn/archive/mozilla/marketplace/index.html b/files/zh-cn/archive/mozilla/marketplace/index.html deleted file mode 100644 index 3beff9da4f..0000000000 --- a/files/zh-cn/archive/mozilla/marketplace/index.html +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: 火狐应用工场 -slug: Archive/Mozilla/Marketplace -tags: - - Marketplace - - TopicStub -translation_of: Archive/Mozilla/Marketplace ---- -
火狐应用工场是一个开放的、非独占的在线应用市场,其所提供的应用都是使用HTML5技术开发的Web应用。
- -
-
-

为了提供更多、更深入的关于如何发布与管理您的应用的信息,此页面正处于不断的维护更新中。

-
- -

火狐应用工场 使得开发者可以使用标准的Web技术、语言和工具来发布跨平台的开放Web应用。Mozilla将会把它的核心理念——开放、自由、用户导向——带到每一个应用中去。

- -

火狐应用工场是我们为了发行应用(免费或付费)而自行建立的应用商城。向火狐应用工场提交应用很简单,只需要上传应用并添加必要的信息,然后等待我们审查完毕,确认应用高效、非恶意即可。向火狐应用工场提交应用还可以获得一些其它的好处。您的应用会得到更广泛的推广,付费的应用发布起来也更加简单,而且您不需要在您的Web站点上实现任何特定的API。主机的应用和打包的应用都可以提交给火狐应用工场。

-
- -
-
-

发布您的应用

- -
-
应用发布选项
-
当你完成一个开放Web应用之后,你可以选择多种不同的方式来发布它。这一章节将会向您介绍这些方式的不同。
-
向火狐应用商场提交应用
-
如果您想向火狐应用工场发布一个应用,这里提供了详尽的指引。
-
与应用发布有关的常见问题
-
这里列出了关于发布开放Web应用有关的常见的问题,相信会对您有用。
-
火狐应用商场API
-
这些API参考内容涵盖了火狐应用商场的大多数API,它们可以帮助您配置应用的收费账户,使您的应用提交自动化等。
-
-
- -
-

关于收益

- -
-
从您的应用中获取收益
-
要如何从您辛勤开发的应用中获取回报呢?不用担心,这篇文章会告诉您如何做,包括应用本身收费还是应用内收费。
-
- -

应用开发工具

- - - -

来自己建一个应用商场吧

- -
-
创建一个商店
-
您完全可以不借助火狐应用商场来发布您的应用。
-
-
-
- - - -
    -
  1. 做好准备 - -
      -
    1. 简介
    2. -
    3. 做个什么应用呢?
    4. -
    5. 您的应用面向哪些群体?
    6. -
    7. 选择合适的商业模式
    8. -
    9. 开发一款优质的应用
    10. -
    11. 本地化您的应用
    12. -
    13. 推广您的应用
    14. -
    15. 创建一个社区
    16. -
    -
  2. -
  3. 应用发布选项 -
      -
    1. 简介
    2. -
    3. 打包应用
    4. -
    5. 主机应用
    6. -
    7. 如何在两者之间选择
    8. -
    9. 面向安卓的开放Web应用
    10. -
    11. 面向桌面的开放Web应用
    12. -
    13. 发布您的应用吧
    14. -
    15. 建一个属于自己的商店
    16. -
    -
  4. -
  5. 应用提交与审核 -
      -
    1. 向火狐应用工场提交一个应用
    2. -
    3. 获取您应用的排名
    4. -
    5. 应用工场审核标准
    6. -
    7. 应用工场截图要求
    8. -
    9. 隐私条款
    10. -
    11. 应用测试与排错
    12. -
    -
  6. -
  7. 应用推广 -
      -
    1. 应用定价以及应用内购买 -
        -
      1. 简介
      2. -
      3. 支付提供商 -
          -
        1. Bango
        2. -
        -
      4. -
      -
    2. -
    3. 更新应用
    4. -
    5. 为应用添加子域
    6. -
    -
  8. -
  9. 应用获利 -
      -
    1. 从你的应用中获利
    2. -
    3. 应用付款指南
    4. -
    5. 应用内购
    6. -
    7. 确认购买Validating a receipt
    8. -
    9. 应用价格
    10. -
    11. 付款状态
    12. -
    -
  10. -
  11. 火狐商场APIs -
      -
    1. 火狐商场公共库
    2. -
    3. 提交应用API
    4. -
    5. 付款API
    6. -
    7. 火狐商场API
    8. -
    -
  12. -
  13. 火狐商场FAQ
  14. -
diff --git a/files/zh-cn/archive/mozilla/marketplace/marketplace_apis/index.html b/files/zh-cn/archive/mozilla/marketplace/marketplace_apis/index.html deleted file mode 100644 index 821b22afdf..0000000000 --- a/files/zh-cn/archive/mozilla/marketplace/marketplace_apis/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Firefox Marketplace APIs -slug: Archive/Mozilla/Marketplace/Marketplace_APIs -tags: - - API - - Apps - - Firefox OS Marketplace - - Marketplace -translation_of: Archive/Mozilla/Marketplace/Marketplace_APIs ---- -
-

Links to the main references covering Mozilla's Firefox Marketplace APIs, with which you can handle app submissions, configure a payment account for an app, and more.

-
- -
-
-
-
Marketplace utility library
-
To help you work with the Firefox Marketplace, we provide a JavaScript library you can use in your apps to make it easier to handle in-app payments and verify payment receipts.
-
上架API
-
The Submission API lets you validate your app, update your app, and fetch information about the apps available to be installed.
-
支付API
-
 
-
The Payment API lets you do things like get information about in-app purchases and get information about pricing tiers for various countries.
-
其他应用市场API
-
The full documentation for the Firefox Marketplace APIs.
-
-
- -
-
面向应用开发者的工具
- -
技术参考文档
- -
从社区获取帮助
-

如果您还不确定该做的事,欢迎随时加入讨论。

- -

别忘记网络礼仪...

-
-
diff --git a/files/zh-cn/archive/mozilla/marketplace/options/self_publishing/index.html b/files/zh-cn/archive/mozilla/marketplace/options/self_publishing/index.html deleted file mode 100644 index 0421e01082..0000000000 --- a/files/zh-cn/archive/mozilla/marketplace/options/self_publishing/index.html +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: 自主发布应用 -slug: Archive/Mozilla/Marketplace/Options/Self_publishing -translation_of: Archive/Mozilla/Marketplace/Options/Self_publishing ---- -
-

可能会出现这样一种情况,你不想让你的应用可以在火狐市场上得到,比如,你可能想要把应用分发给你组织中的成员,进行beta版本测试或者只是单纯的做你自己的事。这种情况下你可以直接使用应用源文件在Firefox OS设备上安装和使用应用,而不是发布到火狐市场。

-
-

安装到 Firefox OS 上的 Open Web Apps, 使用 {{ domxref("Apps.install") }} or {{ domxref("Apps.installPackage") }} 运行在设备上或桌面版中。 这两种情况下, 这些 API 都是通过发送描述要安装的 app 的 manifest URL 来安装的。因此自行发布应用的基本要求如下:

-
    -
  1. 服务器中包含 app 的manifest
  2. -
  3. 服务器中包含 app (对 host app 而言) 或 app 的打包 zip 文件
  4. -
  5. 在网站上的代码会合适的调用 {{ domxref("Apps.install") }} or {{ domxref("Apps.installPackage") }}
  6. -
-

局限性

-

在利用自主发布 web 应用之前,你应该了解以下局限性:

- -

自主发布打包型应用(packed apps)

-

你可以通过在一个服务器上托管应用的 ZIP 文件及 min-manifest 的方式自己发布一个 package App。mini-manifest 文件必须和 ZIP 在同一目录下,用于识别 app 的安装过程。你可以创建一个脚本来调用 {{ domxref("Apps.installPackage") }}从而传递 mini-manifest 的具体信息。我们来看一下这个过程:

-

步骤

-
    -
  1. -

    压缩你的应用内容并命名为package.zip。这个文件应该包含所有的应用资源,包括应用清单。

    -
    -

    注意:你必须要小心你希望出现在打包应用中的压缩内容,不是包含这些内容的目录。如果你压缩的是父目录,应用清单文件将会无法找到,导致打包型应用不可用。

    -
    -
  2. -
  3. 创建一个名称为  manifest.webapp 的文件,添加内容如下。这个文件也称为 mini-manifest, 因为它是 manifest 文件的裁剪版本,放置在 Packaged App ZIP 文件中。 它会被{{ domxref("Apps.installPackage") }}所调用以承接  app 的安装任务。要获得更多的细节,请查看下面的  Mini-manifest 字段
    -
    {
    -    "name": "My sample app",
    -    "package_path" : "http://my-server.com/my-app-directory/package.zip",
    -    "version": "1",
    -    "developer": {
    -        "name": "A. Developer",
    -        "url": "http://my-server.com"
    -    }
    -}
    -
  4. -
  5. 创建安装 app 的脚本文件。此处我们使用了简单的 HTML 文件 index.html,但是你可以将脚本添加到按钮或使用其他合适的方法来在你的站点上调用。 这个页面的JavaScript 会调用 the Packaged App installer API ({{ domxref("Apps.installPackage") }}) 而且还包括了一些回调函数,用于提供安装是否成功的提示信息。 -
    <html>
    -  <body>
    -    <p>Packaged app installation page</p>
    -    <script>
    -      // This URL must be a full url.
    -      var manifestUrl = 'http://my-server.com/my-app-directory/manifest.webapp';
    -      var req = navigator.mozApps.installPackage(manifestUrl);
    -      req.onsuccess = function() {
    -        alert(this.result.origin);
    -      };
    -      req.onerror = function() {
    -        alert(this.error.name);
    -      };
    -    </script>
    -  </body>
    -</html>
    -
  6. -
  7. 通过拷贝 package.zip, package.manifest, 和index.html 到你选定目录( 本例中是 my-app-directory )在你的服务器或站点上配置文件。
  8. -
  9. 现在你就可以使用一个兼容的设备(如 Firefox OS 手机)来安装 app 了。打开 index.html 文件后 (本例中的路径是 http://my-server.com/my-app-directory/index.html)  你就会得到一个弹出框,询问你是否想要安装应用。继续安装过程,一旦完成,你的 Web 页面就会提供一个安装成功或失败的提示信息。
  10. -
-
-

提示: 你可以将 Package App 托管在本地,并在设备上测试。Web Server 和设备必须网络相同,服务器必须能够处理本地网络的请求。你只需要在 mini-manifest 的 package_path 中包含绝对路径(如下所示)。如果你使用了非标准端口,记得要包含端口信息,例如 http://10.10.12.1:8080/package.zip.

-
-

Mini-manifest 字段

-

当火狐市场为你的应用生成一个迷你清单,它会从你的应用清单中取出信息填充一些字段。你可以在应用清单中找到这些字段的说明。而迷你清单中独有的字段有package_path, release_notes和 size而迷你清单中的name, version, developerlocales字段必须和应用清单相同。

-

这里有一些关于在本地调试时,迷你清单相关的信息:

-
-
- name
-
- (必须) 应用名称,最大长度128个字符。
-
- package_path
-
- (必须) 可以找到应用zip文件的URL。确保package_path是zip文件所在的绝对路径
-
- version
-
- 应用的版本号。
-
- size
-
- 应用zip文件的字节数。这对于本地测试不是必须,但是会在安装过程中提供一个进度条。
-
-
{
-  "name": "My app",
-  "package_path": "http://thisdomaindoesnotexist.org/myapp.zip",
-  "version": "1.0",
-  "size": 172496,
-  "release_notes": "First release",
-  "developer": {
-    "name": "Developer Name",
-    "url": "http://thisdomaindoesnotexist.org/"
-  },
-  "locales": {
-    "fr-FR": {
-      "name": "Mon application"
-    },
-    "se-SE": {
-      "name": "Min balla app"
-    }
-  },
-  "icons": {
-    "16": "/icons/16.png",
-    "32": "/icons/32.png",
-    "256": "/icons/256.png"
-  }
-}
-
-
-  
-
- release_notes
-
- 应用发行的相关信息。在火狐市场中,这些信息会出现在提交过程中的一个页面中。
-
- developer
-
- 开发者相关信息,包括nameurl字段。开发者信息需要迷你清单和zip中的主要清单一致。
-
- locales
-
- 本地化信息。值应该是xx-YY格式。
-
- icons
-
- 应用图标。
-
-
-

注意:在迷你清单和应用清单中的许多值需要一致,否则会导致安装失败。最安全的方式是把应用清单中的内容拷贝到迷你清单中然后加上package_path

-
-

自行发布托管应用 Hosted Apps

-

与 Packaged Apps 相比, 自行发布 Hosted App 是更直接的方式。is more straightforward, if you create its content in the same way as you would for Firefox Marketplace publication. This basically means creating the manifest file for your app. You then need to add the code to invoke {{ domxref("Apps.install") }}. This code is essentially the same as that you would use for a Packaged App, shown above, the only difference being that you can make relative reference to the location of the manifest file if you wish.

-

参考

- diff --git "a/files/zh-cn/archive/mozilla/marketplace/options/\346\211\223\345\214\205_\345\272\224\347\224\250\347\250\213\345\272\217/index.html" "b/files/zh-cn/archive/mozilla/marketplace/options/\346\211\223\345\214\205_\345\272\224\347\224\250\347\250\213\345\272\217/index.html" deleted file mode 100644 index 87dfaf1675..0000000000 --- "a/files/zh-cn/archive/mozilla/marketplace/options/\346\211\223\345\214\205_\345\272\224\347\224\250\347\250\213\345\272\217/index.html" +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: 封装的应用程序 -slug: Archive/Mozilla/Marketplace/Options/打包_应用程序 -tags: - - 封装应用程序 - - 应用市场 - - 应用程序发布 - - 应用程序种类 -translation_of: Archive/Mozilla/Marketplace/Options/Packaged_apps ---- -
-

一个封装的应用程序app就是把开放式Web应用程序的所有资源(HTML,CSS,JavaScript,应用程序的manifest,等等)封装进一个ZIP文件,而不是将这些资源放在一个Web服务器上。这篇文档从一个开发者的视角提供了封装应用程序的介绍,并且链接了你需要知道的有关封装应用程序app的一切。

-
-

一个封装的应用程序就是一个zip文件, 它包含了能够使Web应用程序运行的所有资源, 并且在zip文件的根目录下包含有应用程序的manifest 文件。应用程序的manifest提供了应用程序的详细信息,如:程序的描述, 图标等。如此封装的应用程序然后才能够安装到Firefox OS设备, Android设备,以及电脑桌面。安装的应用程序在设备上运行时,仍然能够访问Web上面的资源,如在一个Web服务器上的数据库。

-

封装的应用程序分三种类型:  Web应用程序, 特权应用程序和认证的应用程序。虽然封装应用程序能够发布任何开放的Web应用,但是特权应用和认证应用需要数字签名才能使用特权和认证API。特权应用程序签名是应用市场审查流程的一部分,而认证应用程序签名是由设备厂商和运营商完成的。

-

除了使用特权和认证API的能力之外,封装应用程序安装到设备上之后,所有应用程序的资源都位于设备中,这也为用户提供了更快速的程序启动及响应。基于这些特征,封装应用程序是开放Web应用程序发布到Firefox OS设备,Android设备以及桌面的推荐方法。

-
-

注意: 当前的Firefox应用市场支持Web和特权封装的应用。另外,Firefox应用市场仅仅支持Firefox OS的付费应用,并且支持Firefox OS, Android Firefox以及桌面Firefox的免费应用程序。 支持所有平台的的付费应用正在开发当中。

-
-

封装应用程序的种类

-

共有三种类型的封装应用程序:Web应用程序,特权应用程序及认证应用程序。每种类型的封装应用程序分别对应于Firefox OS中实现的应用程序安全模型的一个等级,本章接下来提供每个种类应用程序的更多信息。

-

Web应用程序

-

web应用程序是没有使用特权和内置(认证的)API的程序, 当提交到应用市场的封装应用程序被签注时,使用特殊的授权进程来保证特权和内置应用不被执行,因此Web应用程序不能使用特权和内置的APIs,这些应用程序也不需要特权和认证应用程序所要求的内容安全政策

-

Web应用在他的manifest.webapp文件中没有要求一定要有type域,因为type的默认值web就是正确的值。

-
-

注意: Web应用可以 自行发布 或者通过Firefox应用市场来发布。

-
-
-

注意: Web应用也可以使用托管应用程序(Hosted App)机制来发布。

-
-

特权应用程序

-

特权应用是使用了特权APIs的应用程序,与iOS和Android平台上的原生应用程序类似。当特权应用被提交到Firefox应用市场时,通过一个特别的进程来审核。这个审核进程给了应用程序用户一定程度的保障,潜在的安全,隐私及性能问题等都得到了仔细的审查。

-

要指定一个应用为特权应用程序,只要在他的manifest.webapp文件中增加type域,并设定他的值为privileged。你的应用程序要访问的每个特权API都必须添加到应用程序manifest中的permissions域中。

-

Firefox OS和Android运行环境以及desktop对于特权应用程序强行使用下面的内容安全政策(CSP)

-
"default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'"
-
-

注意: 特权应用程序只能通过Firefox应用市场来发布。

-
-

内置应用程序

-
-

内置应用程序不像第三方开发者创建的应用程序,内置应用程序通常不是总是可用的,并且不能通过Firefox应用市场发布。内置APIs长期的目标是加强(harden)内置API的认证,使他们像特权程序一样可用。如果你有兴趣了解如何使一个特殊API可用,请在dev-webapps邮件列表中提供反馈。

-
-

内置应用是使用了内置认证API的应用程序,他提供了访问设备上诸如默认的拨号器,系统设置应用这些关键系统功能。相对于特权应用程序,内置应用程序中的API权限许可都是隐含的,就是说他们不需要用户明确的核准即可使用。内置应用程序必须要设备厂商或运营商核准。

-

要指定一个程序为内置应用程序,在manifest.webapp中设定type域为certified。你的应用程序要访问的每个特权API和内置API都必须添加到应用程序manifest中的permissions域中。

-

Firefox OS为内置应用程序实现了下面的内容安全政策CSP:

-
"default-src *; script-src 'self'; object-src 'none'; style-src 'self'"
-

相对特权应用程序,内置应用为CSP实现了更严格的规则。如果你想要了解背后的原因,请查阅 默认CSP政策Bug 768029。

-
-

注意: 内置应用程序只能通过设备制造商或运营商来预装到设备中,不能透过其他任何方式发布。

-
-
-

注意: 内置应用程序的内部代号是认证应用程序。

-
-

测试封装的应用程序

-

为了测试目的,要安装封装的应用程序到Firefox OS模拟器或设备,请参考应用程序管理器。 另外,你能够从Web服务器上面安装一个封装应用程序到设备上,参考自行发布应用程序中描述的步骤。 记住当你要自行发布应用程序时,只有封装的应用程序才能被安装。

-

发布应用程序

-

你有两种选择来发布你的应用程序:一个是在Firefox应用市场,另一个是自行发布。

-

Firefox应用市场发布程序

-

提交封装的应用程序到Firefox应用市场的过程在 应用发布 章节有已经有描述。

-

当你提交你的封装的应用程序时, ZIP文件存储在Firefox应用市场的服务器里面,并且应用市场基于你ZIP文件中的应用程序manifest生成一个新的叫做mini-manifest的manifest。当用户安装你的应用程序时,mini-manifest被传递给Apps.installPackage()函数 来安装应用程序。mini-manifest的存在是为了安装和升级的目的,并不在你运行应用程序时使用。

-

自行发布

-

自行发布应用程序到Firefox应用市场外也是可能的,如在你自己的web服务器上面发布。详细内容请参考 自行发布应用程序

-

更新封装的应用程序

-

更多有关更新应用程序的信息,请参考 跟新应用程序 章节。

-

更多信息

- -

 

diff --git "a/files/zh-cn/archive/mozilla/marketplace/options/\347\256\200\344\273\213/index.html" "b/files/zh-cn/archive/mozilla/marketplace/options/\347\256\200\344\273\213/index.html" deleted file mode 100644 index 383e510b48..0000000000 --- "a/files/zh-cn/archive/mozilla/marketplace/options/\347\256\200\344\273\213/index.html" +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: 简介 — 你的发布选项 -slug: Archive/Mozilla/Marketplace/Options/简介 -tags: - - Firefox OS - - 应用市场 - - 应用程序 - - 简介 -translation_of: Archive/Mozilla/Marketplace/Options/Introduction ---- -
-

Firefox应用市场提供了直达你发布的应用程序的通道,并且使他们能够被Firefox OS,安卓Firefox以及Desktop用户很容易地发现。无论如何,它不是你应用程序发布的唯一选择。在这章节里,你将会发现你能够投递你的应用程序的形式,以及在安卓设备和PC桌面的Firefox浏览器中启用应用程序的机制,你能够发现在Firefox OS设备上的可用内存是如何影响你的应用程序,自行发布应用程序的选项和创建你自己的应用市场的方法。

-
-

你的发布选项

-
-
-
- 封装的应用程序
-
- 找到有关投递应用程序的首选方法,这个方法为你提供了访问特权和安全应用程序接口(APIs)。
-
- 托管应用程序
-
- 找到如何使你的应用程序从服务器上运行,而给用户本地安装应用程序一样的体验。
-
- 封装还是托管 ?
-
- 使用这个检查表来决定哪一个投递格式最适合你的应用程序。
-
- Android平台开放Web应用
-
- Firefox市场应用程序现在已经以APK的形式发布给了安卓用户,你能够启动它来安装并使用你的应用程序,像你使用其他安卓应用成成一样。你能够在这儿发现这是如何做到的。
-
- 桌面开放Web应用
-
- 你的web应用程序现在通过Firefox桌面浏览器安装到了Windows、Mac以及Linux 个人电脑。使用户能够像运行其他桌面应用程序一样运行你的Web应用程序。找出它是如何做到的。
-
- 内存事项
-
- Firefox OS devices come with a range of memory configurations, find out how this affects your apps and how to make sure they will run on all Firefox OS devices.
-
- 自行发布应用程序
-
- 在一些场合,如你想要在Firefox市场外的地方发布应用程序,或者为了测试,或在你的企业内分发。找到有关你的选项及如何实现他们。
-
- 创建你自己的应用市场
-
- 不管你是否是在Firefox应用市场发布你的应用程序,亦或自行发布,你有很多在商店里呈现他们的选项。本章节聚焦在这些选项和你怎样实现他们。
-
-  
-
-  
-
-
-

 

diff --git a/files/zh-cn/archive/mozilla/marketplace/prepare/introduction/index.html b/files/zh-cn/archive/mozilla/marketplace/prepare/introduction/index.html deleted file mode 100644 index 9e23e87760..0000000000 --- a/files/zh-cn/archive/mozilla/marketplace/prepare/introduction/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: 简介 — 为成功而准备 -slug: Archive/Mozilla/Marketplace/Prepare/Introduction -translation_of: Archive/Mozilla/Marketplace/Prepare/Introduction ---- -
-

学习关于如何创建优质Firefox Marketplace应用或人们所爱的游戏的相关知识,基于你的粉丝建立全球用户网。

-
- -

Creating a successful Open Web App isn't just about great coding for a great open platform. Whether you’re coding for pleasure and the joy of sharing your ideas, or you want to build a business from your coding activities, you’ll want users to download and use your apps.

- -

This section contains the advice you need to achieve your goals in terms of app downloads, revenue and use.

- -
-
-

决定制作什么

-
-
-

一个伟大的应用由一个伟大的点子开始。指导你如何选择开发什么样的应用。

-
-
-

了解你的用户

-
-
-

Understanding your users and what they are looking for in your apps is critical to success.

-
-
-

选择你的商业模式

-
-
-

为你的应用或游戏寻找合适的商业模式,如何运用他们。

-
-
-

应用本地化

-
-
-

把你的应用带给全世界意味着为全球用户进行应用本地化。了解如何本地化你的应用。

-
-
-

推广你的应用

-
-
-

Firefox Marketplace is a great way for users to discover apps, but to achieve the downloads you deserve you’ll need to shout about your app. Find out how to make a noise.

-
-
-

Creating your community

-
-
-

Nurture and grow a vibrant community around your apps and tap into their enthusiasm and expertise.

-
-
- -
-
- -
-
diff --git a/files/zh-cn/archive/mozilla/marketplace/publishing/submit/index.html b/files/zh-cn/archive/mozilla/marketplace/publishing/submit/index.html deleted file mode 100644 index a6e3468169..0000000000 --- a/files/zh-cn/archive/mozilla/marketplace/publishing/submit/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Submit -slug: Archive/Mozilla/Marketplace/Publishing/Submit -tags: - - NeedsTranslation - - TopicStub -translation_of: Archive/Mozilla/Marketplace/Publishing/Submit ---- -

This section describes the process for submitting an app to Firefox Marketplace

-

Residual details: https://developer.mozilla.org/en-US/Marketplace/Publishing/Submit/Submitting_an_app

diff --git a/files/zh-cn/archive/mozilla/rdf_datasource_how-to/index.html b/files/zh-cn/archive/mozilla/rdf_datasource_how-to/index.html deleted file mode 100644 index a75e5268f2..0000000000 --- a/files/zh-cn/archive/mozilla/rdf_datasource_how-to/index.html +++ /dev/null @@ -1,231 +0,0 @@ ---- -title: RDF 数据源 How-To -slug: Archive/Mozilla/RDF_Datasource_How-To -tags: - - RDF -translation_of: Archive/Mozilla/RDF_Datasource_How-To ---- -

 

-
-

This article is at least partially outdated. Help bring it up to date, if you can. The XPCOM registration parts and the "As of this writing, it is not currently possible to implement JavaScript XPCOM components" comment seem outdated didn't check the whole article.

-
-

This document is a cookbook that describes how to create a - - native, client-side datasource - that works with Mozilla's RDF implementation. It supercedes (and borrows from) the original document put together by Robert Churchill.

-

What is a datasource?

-

The "RDF universe" consists of a set of - - statements - about Internet - - resources - ; for example, "my home page was last modified April 2nd", or "that news article was sent by Bob". In the most abstract sense, a - - datasource - is a collection of such statements.

-

More concretely, a datasource is a - - translator - that can present information as a collection of RDF statements. For example, a "file system datasource" would translate the file system into statements like "/tmp is a directory" and "/tmp/foo is contained within /tmp". An "IMAP datasource" would use the IMAP protocol to translate your mail server's inbox as a collection of statements like "message number 126's subject is 'make money fast on the Internet'" and "message number 126 was sent by 'spammer128@hotmail.com'". An "address book" datasource could translate a database file into statements like "spammer128@hotmail.com's real name is 'Billy Dumple'" and "spammer128@hotmail.com is considered an 'important friend'."

-

Statements from one datasource can be combined with statements from another datasource using a - - composite datasource - . By combining statements from the IMAP datasource and address book datasource, above, we'd be able to identify the sender of "message 126" as an "important friend".

-

Deciding on a vocabulary

-

The - - vocabulary - is the set of properties that you will use to express relationships between elements (resources and literals) in your data model. The first question that you must answer is "should I use an existing vocabulary, or invent my own?" A reasonable answer is, "use an existing vocabulary unless you - - absolutely must - invent your own." This will allow your datasource to be integrated with other datasources with a minimum of effort.

-

There are several existing vocabularies of note, including:

- -

Mapping your data to nodes and arcs

-

[write me!]

-

Implementing the <tt>nsIRDFDataSource</tt> interface

-

Your first chore will be to implement the <tt>nsIRDFDataSource</tt> interface. There are basically two approaches that you can take in this endeavor:

-
    -
  1. -

    - - Delegate to an inner proxy - . For example, you may choose to delegate to the - - in-memory datasource - , which is a generic datasource that implements <tt>nsIRDFDataSource</tt>.

    -

    Typically, you provide a parser for reading in some sort of static storage (e.g., a data file); the parser translates the datafile into a series of calls to <tt>Assert()</tt> to set up the in-memory datasource. When <tt>Flush()</tt> is called, or the last reference to the datasource is released, a routine walks the in-memory datasource and re-serializes the graph back to the original file format. For examples of an implementation like this, look at the RDF/XML datasource or the bookmarks datasource.

    -

    You may want to choose this implementation if your primary goal is to "wrap" a legacy data store. This implementation may cause problems if your data store can be modified "on the fly" by other agents.

    -
  2. -
  3. -

    - - Aggregate the in-memory datasource - . This is an extreme case of delegation, where you use XPCOM - - aggregation - to implement the <tt>nsIRDFDataSource</tt> interface. See Aggregating the In-Memory Datasource for technical details.

    -

    If you take this approach, you won't be able to selectively implement methods of the <tt>nsIRDFDataSource</tt> interface; instead, - - all - of the methods will be "forwarded" to the in-memory datasource. This can be useful if your datasource is "read-only", and you aren't worried about modification using <tt>Assert()</tt>, etc.

    -
  4. -
  5. -

    - - Implement the interface yourself - . If you choose this route, you'll need to implement each of the <tt>nsIRDFDataStore</tt> methods "by hand". Although this is more work, it is really the only way to create a "live" datasource that may be changed by some outside agent.

    -

    The file system datasource and local mail datasource are good examples of datasources that have been implemented this way.

    -

    You'll probably need to choose this implementation if your datasource is "live", and may be modified or altered by some outside agent (e.g., new mail arriving). You may also need to choose this implementation if the data set which your datasource is modeling is too large to fit in to memory (e.g., the entire file system structure).

    -
  6. -
-

[More info on what each method needs to do - - here - ]

-

RDF Commands

-

[Describe what commands are, and why you'd implement them.]

-

Registering the datasource component

-

A datasource is an XPCOM component. As such, it must (currently, see [1]) have:

-
    -
  1. An XPCOM - - CLSID - to identify the data source implementation
  2. -
  3. An implementation class (that corresponds to the CLSID) whose code lives in a DLL. The DLL must be located in the XPCOM <tt>components</tt> directory
  4. -
  5. A - - factory - that is - - registered - to an XPCOM - - ProgID - in order to be instantiated from the repository.
  6. -
-

Constructing a DLL for a component is beyond the scope of this document; the reader is referred to the RDF factory as a guideline.

-

Registering an RDF datasource is fairly simple: in the DLL's <tt>NSRegisterSelf()</tt> method, you simply call the - - component manager' - s <tt>RegisterComponent()</tt> method:

-
extern "C" PR_IMPLEMENT(nsresult)
-NSRegisterSelf(nsISupports* aServiceManager, const char* aPath)
-{
-   nsresult rv;
-   ...
-   // Assume compMgr refers to the component manager
-   rv = compMgr->RegisterComponent(kMyDataSourceCID,
-            "My Data Source",
-            NS_RDF_DATASOURCE_PROGID_PREFIX "my-datasource",
-            aPath, PR_TRUE, PR_TRUE);
-   ...
-}
-
-

Replace <tt>kMyDataSourceCID</tt> with your datasource's CLSID. Replace <tt>"My Data Source"</tt> with a descriptive string that should appear in the registry. Finally, replace <tt>"my-datasource"</tt> with a value appropriate for your datasource. This value, when prefixed with <tt>"rdf:"</tt>, is a - - datasource identifier - , and may be used with <tt>nsIRDFService::GetDataSource()</tt> to retrieve your datasource from the RDF service. For example, the above datasource would be accessable as follows:

-
nsIRDFService* rdf;
-rv = nsServiceManager::GetService(kRDFServiceCID,
-          kIRDFServiceIID,
-          (nsISupports**) &rdf);
-
-if (NS_SUCCEEDED(rv)) {
-    nsIRDFDataSource* myDataSource;
-    rv = rdf->GetDataSource("rdf:my-datasource",
-                 &myDataSource);
-
-    if (NS_SUCCEEDED(rv)) {
-        // ...do something to myDataSource here...
-        NS_RELEASE(myDataSource);
-    }
-    nsServiceManager::ReleaseService(kRDFServiceCID, rdf);
-}
-
-

Displaying RDF as content

-

Now that you've gone through all this pain to expose your information as a datasource, you probably want to - - see - it. Using XUL, you can display the contents of your datasource in a - - tree - control - - , a - menu - - , or a - toolbar - - . In fact, you can - convert RDF to an - - arbitrary - content model using XUL Templates.

-

The following XUL fragment illustrates how to instantiate a tree control whose body is "rooted" to a resource (<tt>http://foo.bar.com/</tt>) that your datasource describes:

-
<window
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns:rdf="http://www.w3.org/TR/WD-rdf-syntax#"
-  xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul">
-
-  <tree datasources="rdf:my-datasource" ref="http://foo.bar.com/">
-    <template>
-      <treechildren>
-        <treeitem uri="...">
-          <treerow>
-            <treecell>
-              <text value="rdf:http://home.netscape.com/NC-rdf#Name" />
-            </treecell>
-            <treecell>
-              <text value="rdf:http://home.netscape.com/NC-rdf#URL" />
-            </treecell>
-          </treerow>
-        </treeitem>
-      </treechildren>
-    </template>
-
-    <treehead>
-      <treeitem>
-        <treecell>Name</treecell>
-        <treecell>URL</treecell>
-      </treeitem>
-    </treehead>
-
-    <!-- treechildren built _here_ -->
-  </tree>
-
-</window>
-
-

The important "magic attributes" have been called out in bold, above:

- -

For a complete description of how content is built from RDF, see the XUL:Template Guide.

-
-

1 As of this writing, it is not currently possible to implement JavaScript XPCOM components; however, it may soon be possible to do so via XPConnect. Update: JavaScript XPCOM should now be possible.

-

Contact: Chris Waterson (waterson@netscape.com)

-
-

Original Document Information

- -
-

 

diff --git a/files/zh-cn/archive/mozilla/tamarin/index.html b/files/zh-cn/archive/mozilla/tamarin/index.html deleted file mode 100644 index e13f983f5d..0000000000 --- a/files/zh-cn/archive/mozilla/tamarin/index.html +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: Tamarin -slug: Archive/Mozilla/Tamarin -tags: - - JavaScript - - Landing - - NeedsTranslation - - Tamarin - - TopicStub -translation_of: Archive/Mozilla/Tamarin ---- -

 

- -
-

Tamarin is a JavaScript engine written in C++. It currently implements Adobe ActionScript™ 3 (a superset of ECMAScript Edition 3) and is embedded within the Adobe® Flash® Player versions 9 and later. Tamarin's jit-compiler, NanoJIT, is also used in TraceMonkey ergo SpiderMonkey, which is Mozilla’s JavaScript engine in Firefox.

- -

Tamarin is available under the MPL/GPL/LGPL tri-license.

-
- - - - - - - - -
-

Releases

- -
-
Release Tracking
-
Information on current, past, and upcoming releases of Tamarin.
-
- -

Documentation

- -
-
Adobe ActionScript Virtual Machine 2 (AVM2) Overview (PDF, 400K)
-
The instructions, architecture, and file format supported by the AVM2. See also the possible errata.
-
- -
-
Tamarin Build Documentation
-
How to get, build, and use Tamarin.
-
 
-
Tamarin Build System Documentation
-
Documentation on how the Tamarin build system works and how to modify.
-
Tamarin commit hook
-
Instructions for installing and using the mercurial hook for Tamarin.
-
Tamarin Acceptance Testing
-
Instructions on how to validate changes to the Tamarin source code.
-
- -
-
Tamarin pages at wiki.mozilla.org
-
More documentation.
-
- -
-
MMgc overview
-
An overview of the Tamarin garbage collector.
-
- -
-
Nanojit LIR
-
In Nanojit, LIR is the source language for compilation to machine code.
-
- -
-
Tamarin strings documentation
-
The implementation of Tamarin strings has changed. This page is a how-to about the changes, and what can be done to adapt source code to the changes.
-
- -
-
Tamarin doxygen documentation
-
Documentation for the latest release.
-
- -

View All...

-
-

Get Involved!

- - - - - - - - - -
-
JavaScript
-
SpiderMonkey
-
ActionMonkey
-
Tamarin on mozilla.org
-
-
diff --git a/files/zh-cn/archive/mozilla/tamarin/tamarin_build_documentation/index.html b/files/zh-cn/archive/mozilla/tamarin/tamarin_build_documentation/index.html deleted file mode 100644 index 3841a0565c..0000000000 --- a/files/zh-cn/archive/mozilla/tamarin/tamarin_build_documentation/index.html +++ /dev/null @@ -1,416 +0,0 @@ ---- -title: Tamarin 编译文档 -slug: Archive/Mozilla/Tamarin/Tamarin_Build_Documentation -translation_of: Archive/Mozilla/Tamarin/Tamarin_Build_Documentation ---- -

Tamarin 源码版本

- -

以下说明用于获取和构建 Tamarin Central 源码.

- -

Tamarin Tracing 的相关说明, 请查看 Tamarin Tracing Build Documentation.

- -

支持平台

- -

Tamarin 目前支持以下操作系统/架构.

- - - -

获取 Tamarin 源码

- -

Tamarin 源码位于 Tamarin Central 的 Mercurial .  目前开发中的源码位于 Tamarin Redux.  在本文中 replace instances of tamarin-central with tamarin-redux to operate in the redux repository.  使用以下命令克隆一个 Tamarin 仓库:

- -
$ hg clone http://hg.mozilla.org/tamarin-central tamarin-central
-
- -

Tips for working with Mercurial can be found here.

- -

构建 Tamarin

- -

构建 Tamarin 将创建 AVMPlus 和 garbage collector (MMgc) 的所有库, 并创建一个独立的可执行文件(shell),用于以ABC文件格式执行文件. 不附加任何参数运行shell将列出可用的选项. 注意其他的命令行参数仅在调试配置中可用.

- -

Tamarin 的代码库包含一个Mozilla开发者的跨平台构建系统. 该跨平台构建系统用于日常自动化构建测试, 因此是非常可靠的系统.

- -

The Tamarin codebase has the ability to build additional code which supports debugging hooks. 在 XCode 项目中, 这是 Debug_Debugger 和 Release_Debugger 配置. The Flash Player builds Tamarin with the debugging hooks off for codesize reasons, but the Mozilla client will build Tamarin with the debugging hooks on.

- -

跨平台构建 (general instructions - 非安卓)

- -

预备条件(环境): 你需要 Python 2.5 或更高版本和 GNU make 3.81 或更高版本. (GNU make 3.80 does not work. Nor does any other brand of make.)

- -

预备条件达成后, 使用这些命令构建 Tamarin:

- -
 $ hg clone http://hg.mozilla.org/tamarin-redux/
- $ cd tamarin-redux
- $ mkdir objdir-release
- $ cd objdir-release
- $ python ../configure.py
- $ make
- ...
- $ shell/avmshell
- shell 1.0 build cyclone
- ...
-
- -

AVMPlus 的可执行文件是 avmshell.

- -

可选项:

- - - -

对于详细的构建Tamarin, 你可以通过 CPPFLAGS 进行.

- -
 $ make CPPFLAGS=-DAVMPLUS_VERBOSE
-
- -

在 OSX 10.6 (Snow Leopard) 构建的非安卓跨平台 Tamarin-redux 的其他说明

- -

(要在Mac上构建 Tamarin-central 请参阅此处的跨平台说明: https://developer.mozilla.org/index.php?title=En/Tamarin/Tamarin_Build_Documentation&revision=21

- -

The bug when building on Snow Leopard (Bug 537817) has been fixed in the Tamarin-redux repo. The work for that fix also included some changes to the configure.py default behavior to decouple the --target switch from sdk choice: 

- - - -

Example call to build on an x86_64 machine with the 10.5 sdk:

- -
$ ../configure.py --mac-sdk=105 --target=x86_64-darwin
-
- -

If ASC is not set, you will need to add ASC.jar to the utils directory in Tamarin-redux (Bug 631641).

- - - -

 

- -

在Mac上构建 Tamarin 的安卓 2.3.3 版本

- -

公共 sdk/ndk 安装

- -

To build Tamarin for Android you will need an sdk/ndk. The setup procedure below creates an android sdk/ndk entirely from publicly available sources. This sdk/ndk *must* be used if you've cloned tamarin at changeset 5844:92ad3ca84a0b or later and will be using the cross-compile build method.

- -

Steps to create a public sdk/ndk tree on a Mac:

- -

- Create an sdk/ndk top folder under your main volume named /android-public.

- -

- 下载 Android 2.3.3 的Mac sdk zip 文件自 http://developer.android.com/sdk/index.html. 解压到你的 sdk/ndk 顶级文件夹. Make sure it's named 'android-sdk-mac_86'.

- -

- Download the r5b Mac ndk zip file from http://developer.android.com/sdk/ndk/index.html. Unzip to your sdk/ndk top folder. Rename this folder to 'android-ndk'.

- -

- Run the Android SDK/AVD Manager at /android-public/android-sdk-mac_86/tools/android and add Android SDK Platform-tools (to get adb), SDK Platform Android 2.3.3, and API 10 (samples and docs are optional). If you have trouble starting the app try this:

- -

$ export ANDROID_SWT=$ANDROID_BUILD_TOP/android-sdk-mac_86/tools/lib/x86_64

- -

where $ANDROID_BUILD_TOP is the full path to your sdk/ndk top folder

- -

- Get the openssl-0.9.8r.tar (openssl-1.0.0c.tar.gz won't work) openssl files from http://www.openssl.org (use the Source link on the left). Unzip the file and put the /openssl main folder under your sdk/ndk top folder. Make sure its name is just "openssl".  Then build as follows:

- -

- Replace the Makefile in the main folder with the one attached to this page.

- -

- Change the variable ANDROID_DEVICE in the makefile (near line 65) to point to your sdk/ndk top folder.

- -

- Find the two instances of "android-ndk" and make sure they match your ndk's name (they should already).

- -

- In a terminal window change to your /openssl folder and run make build_libs to create the necessary 'libcrypto.a' and 'libssl.a' static libraries.

- -

Alternatively, run make, in which case the process will complete with errors when it tries to create the shared lib crt0.o:

- -
$ /android-public/android-ndk/toolchains/arm-eabi-4.4.0/prebuilt/darwin-x86/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/bin/ld: crt0.o:
-No such file: No such file or directory collect2: ld returned 1 exit status
-make[2]: *** [link_app.] Error 1
-make[1]: *** [openssl] Error 2
-make: *** [build_apps] Error 1
- -

You can ignore these errors. The necessary static files 'libcrypto.a' and 'libssl.a' are made correctly and are present in the /openssl folder. More information on why this happens on Mac OS is here: http://developer.apple.com/library/mac/#qa/qa2001/qa1118.html

- -

- Create a /frameworks/base/opengl/include/EGL folder under your sdk/ndk top folder. Get the ersion 1.4 EGL header files (egl.h, eglext.h and eglplatform.h) from http://www.khronos.org/registry/egl/ and save or copy them there. 

- -

构建 Tamarin Release Shell

- -

- Get tamarin-redux

- -

- Export the following variables into the environment

- -

 

- -
$ export ANDROID_TOOLCHAIN=<full path to your android sdk/ndk top folder>
-$ export ANDROID_NDK=$ANDROID_TOOLCHAIN/android-ndk
-$ export ANDROID_NDK_BIN=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin
-$ export ANDROID_SDK=$ANDROID_TOOLCHAIN/android-sdk-mac_86
-$ export PATH=$PATH:$ANDROID_SDK/platform-tools:$ANDROID_NDK_BIN
- -
- Example commands to build Tamarin: 
- -
$ hg clone http://hg.mozilla.org/tamarin-redux
-$ cd tamarin-redux
-$ mkdir objdir-release
-$ cd objdir-release
-$ ../configure.py --arm-arch=armv7-a --target=arm-android
-$ make
- -

使用此命令制作一个调试shell:

- -

../configure.py --enable-debug --arm-arch=armv7-a --target=arm-android

- -

 

- -

在Windows上使用CYGWIN的跨平台脚本:

- -

预备条件(环境): 你需要 Python 2.5 或更高版本和 GNU make 3.81 或更高版本. (GNU make 3.80 does not work. Nor does any other brand of make.)

- -

设置:

- - - -
# NOTE: The INCLUDE, LIB and LIBPATH must contain windows path information and separator and not cygwin paths.
-VS_HOME_PATH="/cygdrive/c/Program Files/Microsoft Visual Studio 9.0"
-VS_HOME="c:\Program Files\Microsoft Visual Studio 9.0"
-
-export PATH="$VS_HOME_PATH/Common7/IDE:$VS_HOME_PATH/VC/bin:$VS_HOME_PATH/Common7/Tools:$VS_HOME_PATH/VC/VCPackages:$PATH"
-export INCLUDE="$VS_HOME\VC\atlmfc\include;$VS_HOME\VC\include;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include;"
-export LIB="$VS_HOME\VC\atlmfc\lib;$VS_HOME\VC\lib;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib"
-export LIBPATH="$VS_HOME\VC\atlmfc\lib;$VS_HOME\VC\lib;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib"
-
- -

完成上方的条件后, 你现在应该可以通过这些命令进行构建:

- -
$ hg clone http://hg.mozilla.org/tamarin-central/
-$ cd tamarin-central
-$ mkdir objdir-release
-$ cd objdir-release
-$ python ../configure.py
-$ make
-...
-$ shell/avmshell.exe
-shell 1.0 build cyclone
-...
-
- -

 

- -

微软 Visual Studio

- -

Visual Studio 2008 (VS2008) 是首选的Windows构建环境. Visual Studio 2003 和 2005 不再被支持. 构建 Tamarin:

- -
    -
  1. copy tamarin/platform/win32/armasm.rules to c:/Program Files/Microsoft Visual Studio 9.0/VC/VCProjectDefaults
  2. -
  3. Build "builtin.h" following the instructions below in the section "Compiling and running applications"
  4. -
  5. Do the same for shell_toplevel.h, starting in avmplus/shell, using the command "python shell_toplevel.py"
  6. -
  7. open the Tamarin project file "platform/win32/avmplus2008.sln".
  8. -
  9. Choose your desired configuration and target, and build.
  10. -
  11. Note: now that bug 478714 has been fixed, the name of the (shell) executable will always be "avm.exe" no matter which build configuration you select. The avm.exe file will be found in a directory reflecting your configuration choice. For example, if you chose the win32 Debug_Debugger configuration your build will be under \tamarin-redux\platform\win32\obj_9\shell\Debug_Debugger by default. Building the x64 Release_Debugger configuration will create avm.exe under \tamarin-redux\platform\win32\x64\Release_Debugger. Note the "\obj9" directory under \platform\win32 for the win32 builds and "\x64" directory under \platform\win32 for 64-bit builds; this looks a little odd but preserves previous behavior as much as possible to avoid initial disruption from the shell rename fix.
  12. -
- -

你必须安装支持x64的VS2008才能构建64位配置. 

- -

如果你安装了 Windows Mobile 6 SDK, 你还可以用 Windows Mobile (ARM) 为目标构建.

- -

Apple XCode

- -

The project files are designed for XCode 3.0. Se "platform/mac/avmplus/avmplus.xcodeproj". XCode 2.2, 2.3, and 2.4 will not work.

- -

There are two targets in the XCode IDE, 'avm' for 32-bit builds and 'avm64' for 64-bit builds. There is also an aggregate target that will build both targets. Note that, whereas before when you selected the aggregate target you got a 'shell' 32-bit executable and a 'shell64' 64-bit executable in the same folder, now because of the fix to bug 478714 you will get an 'avm' executable in two separate folders, /Debug and /Debug64 respectively.

- -

The command to build from the Terminal is:

- -
   $ cd tamarin-redux
-   $ xcodebuild ARCHS=ppc -project platform/mac/avmshell/avmshell.xcodeproj
-
- -

For a debug build, add '-configuration Debug' (note the capital D and no "="). Additional configurations are: Debug_Debugger, Release and Release_Debugger.

- -

The resulting Debug executable for the command above would be built at /platform/mac/avmshell/build/Debug/avm.

- -

Intel Macs build correctly by setting ARCHS=i386.

- -

Eclipse (目前只有Mac)

- -

Eclipse (Galileo) / CDT (6.0) project for Tamarin (also works with Helios).

- -

The configurations in this initial version cover 32- and 64-bit builds for Mac OS with the GCC 4.0 toolchain (installed with Xcode 3.x).

- -

Preparing your Eclipse workspace and perspective

- - - -

将项目导入到 Eclipse

- - - -

在 Eclipse 构建

- -

8 build configurations are included for MacOS with the GCC 4.0 toolchain:

- - - -

The build location will be PROJECT_ROOT/BUILD_NAME/avm

- -

Note: As discussed above, the C++ indexer has been setup to track the current build config, so the correct conditional compiles are highlighted in the editor

- -

从 Eclipse 运行/调试

- -

For test purposes, a launch config (running the HelloWorld test from esc) has been included for each of the build configs. All are available from the Run menu.

- -

Note: if you receive an error when trying to run/debug a newly imported project, try opening a file in the project first - Eclipse can sometimes get confused as to what the 'current project' actually is. Additional things to try are clicking on the project name then refreshing it (File/Refresh or right-click/Refresh) and/or quitting and restarting Eclipse.

- -

Linux 和 Unix

- -

Tamarin is tested on Linux but not on other Unix flavors. Nonetheless, it is possible to build Tamarin on Unix. 

- -

Execute the following commands to build:

- -
   $ cd tamarin-central/platform/unix
-   $ make
-
- -

The resulting executable "shell" is built in the current directory.

- -

编译和运行应用程序

- -

Currently the only compiler for Tamarin is the Adobe ActionScript compiler. The source code for the ActionScript compiler, asc, has been open sourced as part of Adobe Flex®. This compiler is written in Java and will require the installation of a Java™ 1.4 or later JDK.

- -

A prototype self-hosting ECMAScript Edition 4 compiler, esc, is provided with Tamarin but it is not yet capable of bootstrapping itself or building applications. esc is under active development and will be able to generate Tamarin applications later this year.

- -

Use the following steps to build and install the ActionScript compiler.

- -
    -
  1. Download and build the asc source code using the subversion client
  2. -
- -
 $ svn co http://opensource.adobe.com/svn/open...box/asc-redux/ asc
- $ cd asc/build/java
- $ ant
- ...
- jar:
- [jar] Building jar asc\lib\asc.jar
- $ cd ../..
- $ java -jar lib/asc.jar   # shows usage
-
- -

You may also download the latest asc.jar from ftp://ftp.mozilla.org/pub/js/tamarin...latest/asc.jar .

- -

You should now copy asc.jar into tamarin-central/utils.

- -

asc.jar can be used to compile the builtin.abc file. The builtin.abc file provides internal information about the built-in classes (Object, Array, etc). This file is located in the core directory; you shouldn't normally need to rebuild it, unless you edit any of the ActionScript source for the built-in classes. To rebuild it, use the builtin.py script:

- -
 $ cd tamarin-central/core
- $ export ASC=../utils/asc.jar       # builtin.py uses this to find asc.jar
- $ python builtin.py
- building builtin.abc, builtin.cpp, builtin.h
- builtin: 26795
- Files: 6 Time: 1709ms
-
- -

You can now use

- -

asc.jar to compile applications.

- -
 $ cd tamarin-central
- $ echo 'print("hello, world")' > hello.as
- $ java -jar ./utils/asc.jar -import ./core/builtin.abc hello.as
- hello.abc, 86 bytes written
-
- -

Use the AVMPlus standalone executable (avmshell) built previously to run the application:

- -
 $ avmshell hello.abc
- hello, world
-
- -

Use the -help options of asc.jar and avmshell for more details.

- -

对 Tamarin 进行测试

- -

See Running Tamarin acceptance tests and Running Tamarin performance tests

- -

构建 Tamarin Windows Mobile utilities

- -

The Tamarin Windows Mobile utilities allows the existing acceptance and performance testsuites to be run on a Windows Mobile device connected to a Windows desktop machine by ActiveSync or Windows Mobile Device Center (for Windows Vista and Windows 7).  

- -
    -
  1. Setup and run ActiveSync or Windows Mobile Device Center.  You should be connected and able to see the devices file system in Windows Explorer
  2. -
  3. in tamarin repository go to the utils/wmremote directory,  open the ceremoteshell2008.sln file in Visual Studio 2008
  4. -
  5. Build all targets in Release mode (for more information see utils/wmremote/readme.txt)
  6. -
  7. copy Release/avmremote.dll to the device in the \Windows directory
  8. -
  9. export AVM=Release/ceremoteshell.exe, the ceremoteshell.exe behaves as a proxy copying and running abc files on the windows mobile device
  10. -
  11. build a windows mobile tamarin shell,  copy the shell to the windows mobile device in \Program Files\shell\avmshell.exe
  12. -
  13. (optional) Can sanity check the windows mobile shell is functioning by running $AVM hello.abc (where hello.abc is a simple abc to print a string, or can substitute with any test abc)
  14. -
  15. Now any acceptance or performance tests can be run as on desktop using test/acceptance/runtests.py or tests/performance/runtests.py
  16. -
- -

Tamarin BuildBot

- -

Adobe maintains a continuous build and test system for Tamarin Redux, similar to TinderBox.

- -

Tamarin BuildBot TryServer

- -

The TryServer/Sandbox is setup to allow users to push any code changes that they would like to have tested in the automated build/test process prior to actually pushing the changes. The Sandbox is setup so that it is able to build and test branches that are based on either tamarin-central or tamarin-tracing.

- -

Any comments, questions or problems can be directed to

- -

ActionScript QE

- -

How to

- -
    -
  1. Setup a user repository with the source and patches that will be compiled. Documentation on how to setup a user repository http://developer.mozilla.org/En/Publishing_Mercurial_Clones. Push any changes that you want to test into this repository.
  2. -
  3. Request a build via the form at http://tamarin-builds.mozilla.org/build_trigger/requestbuild.cfm -
      -
    • User Email: Your email address. An email with the build status will be sent to this address when a builder completes whether it is passes or fails.
    • -
    • Mercurial Repository: Give the location of the repository that will be used for the build. NOTE: Only repositories hosted on http://hg.mozilla.org/ are accepted.
    • -
    • Revision: Specify the revision number that will be built. Currently this only accepts the change number and not the hash.
    • -
    • Branch: Which branch of tamarin the repository is based on, Tamarin-Central or Tamarin-Tracing.
    • -
    • Description: Self explanatory
    • -
    -
  4. -
  5. Check the status of the build @ http://tamarin-builds.mozilla.org/tamarin-redux/ , you can also see your build request in the queue at http://tamarin-builds.mozilla.org/build_trigger/requestbuild.cfm. If you no longer want you sandbox to build and it has not started yet, you can delete the build request from the queue from the request page.
  6. -
- -

TryServer etiquette

- -

The sandbox is not a good substitute for running the regression tests locally to catch obvious problems.

- -

This is a shared resource, each request takes approximately 2+ hours to run so please use wisely.

diff --git a/files/zh-cn/archive/mozilla/xbl/index.html b/files/zh-cn/archive/mozilla/xbl/index.html deleted file mode 100644 index 554771a049..0000000000 --- a/files/zh-cn/archive/mozilla/xbl/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: XBL -slug: Archive/Mozilla/XBL -tags: - - XBL -translation_of: Archive/Mozilla/XBL ---- -

XML 绑定语言XBL,有时也被称为可扩展绑定语言)是用于描述可以附加到其他文档中的元素的“绑定”(bindings)的语言。绑定所附加到的元素被称为绑定元素(bound element),会获取绑定中指定的新行为。

- -

绑定可以包含在绑定元素上注册的事件处理器(event handlers)、可从绑定元素访问的新方法(methods)和属性(properties)、以及插入到绑定元素下的匿名内容。

- -

Most XUL widgets are at least partially implemented using XBL. You can build your own reusable widgets from existing XUL, HTML, SVG, and other primitives using XBL.

- -

定义

- - - -

XBL 1.0 是一个 Mozilla-specific technology,不是一个 W3C 标准。至少两个基于它的标准已经被废弃:sXBL 和 XBL 2.0。

- -
-

警告!sXBL 和 XBL 2.0 已被废弃。

-
- - - -

Some differences between sXBL and XBL2 are listed in an article by Anne van Kesteren (November, 2005).

- -

An overview of differences between Mozilla XBL and XBL2 is in a newsgroup posting by Jonas Sicking (April, 2007).

- -
-

Still living "Shadow DOM" related specs

-
- - - -

参见

- - - - - -

社区

- - - -

diff --git a/files/zh-cn/archive/mozilla/xbl/xbl_1.0_reference/dom_interfaces/index.html b/files/zh-cn/archive/mozilla/xbl/xbl_1.0_reference/dom_interfaces/index.html deleted file mode 100644 index 6e926d52b5..0000000000 --- a/files/zh-cn/archive/mozilla/xbl/xbl_1.0_reference/dom_interfaces/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: DOM Interfaces -slug: Archive/Mozilla/XBL/XBL_1.0_Reference/DOM_Interfaces -translation_of: Archive/Mozilla/XBL/XBL_1.0_Reference/DOM_Interfaces ---- -

 

-

The nsIDOMDocumentXBL Interface

-

The nsIDOMDocumentXBL interface contains methods for manipulating XBL bindings. The interface is implemented by all DOM documents.

-

IDL Definition

-
interface nsIDOMDocumentXBL {
-  NodeList getAnonymousNodes(in Element elt);
-  Element getAnonymousElementByAttribute(in Element elt,
-                                         in DOMString attrName,
-                                         in DOMString attrValue);
-  /* NOT IMPLEMENTED
-  void addBinding(in Element elt,
-                  in DOMString bindingURL);
-  void removeBinding(in Element elt,
-                      in DOMString bindingURL);
-  */
-
-  Element getBindingParent(in Node node);
-  void loadBindingDocument(in DOMString documentURL);
-};
-
-

Methods

-

getAnonymousNodes

-

The getAnonymousNodes method retrieves the anonymous children of the specified element.

- -

getAnonymousElementByAttribute

-

The getAnonymousElementByAttribute methods retrieves an anonymous descendant with a specified attribute value. Typically used with an (arbitrary) anonid attribute to retrieve a specific anonymous child in an XBL binding.

- -

addBinding

-

NOT IMPLEMENTED The addBinding method attaches the specified binding (and any bindings that the binding inherits from) to an element. This call is not necessarily synchronous. The binding may not be attached yet when the call completes. See here for more information.

- -

removeBinding

-

NOT IMPLEMENTED The removeBinding method detaches the specified binding (and any bindings that the binding inherits from explicitly using the extends attribute) from the element. See here for more information.

- -

getBindingParent

-

The getBindingParent method is used to obtain the bound element with the binding attached that is responsible for the generation of the specified anonymous node. This method enables an author to determine the scope of any content node. When content at the document-level scope is passed in as an argument, the property's value is null.

- -

loadBindingDocument

-

The loadBindingDocument method can be used to synchronously obtain the specified binding document for use within a particular document (the one on which the loadBindingDocument method was invoked). The binding document can then be modified programmatically using the DOM. Any subsequent bindings that are attached to elements within the document will be constructed from the modified binding document.

- -

Example

-

The following snippet checks to see if any anonymous child of "element" is itself an element.

-
if (element.ownerDocument instanceof Ci.nsIDOMDocumentXBL)
-{
-    var anonChildren = element.ownerDocument.getAnonymousNodes(element);
-    if (anonChildren)
-    {
-        for (var i = 0; i < anonChildren.length; i++)
-        {
-            if (anonChildren[i].nodeType == 1)
-                return false;
-        }
-    }
-}
-return true;
-
diff --git a/files/zh-cn/archive/mozilla/xbl/xbl_1.0_reference/index.html b/files/zh-cn/archive/mozilla/xbl/xbl_1.0_reference/index.html deleted file mode 100644 index b891778907..0000000000 --- a/files/zh-cn/archive/mozilla/xbl/xbl_1.0_reference/index.html +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: XBL 1.0 Reference -slug: Archive/Mozilla/XBL/XBL_1.0_Reference -tags: - - NeedsTranslation - - TopicStub - - XBL -translation_of: Archive/Mozilla/XBL/XBL_1.0_Reference ---- -

 

-

Abstract

-

This document describes Extensible Binding Language (XBL) 1.0 as implemented in Gecko browsers.

-

Extensible Binding Language is a XML-based markup language to implement reusable components (bindings) that can be bound to elements in other documents. The element with a binding specified, called the bound element, acquires the new behavior specified by the binding. Bindings can be bound to elements using Cascading Style Sheets (CSS) or DOM. One element can be bound to several bindings at once.

-

Functionally bindings should be correlated with Behaviors and Viewlink but being implemented as one integrated XML solution.

-

Bindings can contain event handlers that are registered on the bound element, an implementation of new methods and properties that become accessible from the bound element, and anonymous content that is inserted around the bound element.

-
-

There are numerous adjustments in the current implementation in comparison of earlier XBL proposals, and not all of them are reflected yet in this document. The documentation process is still in progress: please keep it in your mind while using the provided information.

-
-

XBL Elements

-

XBL 1.0 elements are in the http://www.mozilla.org/xbl namespace.

- -

Binding Attachment and Detachment

- -

DOM Interfaces

- -

Anonymous Content

- -

Binding Implementations

- -

Event Handlers

-

Example - Sticky Notes

-

Updated and adjusted for the current Firefox implementation.

-
-

This example is targeted to demonstrate the XBL usage rather than to be a practically useful application. For this reason it contains many comments and some blocks could be avoided in a more compact solution yet used here for demonstration purposes.

-
- -

View this example

-


- Download all files (.zip archive) need to ask to adjust the server - it gives "Access denied" for zip files (?)

-

References

- -
-

Original Document Information

- -
diff --git a/files/zh-cn/archive/mozilla/xpinstall/index.html b/files/zh-cn/archive/mozilla/xpinstall/index.html deleted file mode 100644 index b1d122e53b..0000000000 --- a/files/zh-cn/archive/mozilla/xpinstall/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: XPInstall -slug: Archive/Mozilla/XPInstall -tags: - - XPInstall - - XPInstall_API_reference -translation_of: Archive/Mozilla/XPInstall ---- -

Parts of this page show the use of the XPInstall API. The majority of this API is now deprecated and as of Gecko 1.9 no longer available. Extension, Theme, and plug-in developers must switch away from install.js based packages to the new packaging scheme with an install.rdf manifest. In particular plugin developers should see how to package a plugin as an extension.

- -
Cross-Platform Install (XPInstall) is a technology used by Mozilla Application Suite, Mozilla Firefox, Mozilla Thunderbird and other XUL-based applications for installing extensions. An XPI (pronounced "zippy" and derived from XPInstall) installer module is a ZIP file that contains an install script or manifest (entitled install.js or install.rdf) at the root of the file.
-跨平台安装(XPInstall)是被Mozilla应用程序套件(Firefox, Thunderbird, 其它一些基于XUL的应用程序)所使用的一项安装扩展的技术. XPI安装模块是一个ZIP文件, 它包括一个位于根路径的安装脚本文件或者清单(符合规定格式的install.js或者install.ref)文件
- -

.

- - - - - - - - -
-

Documentation

- -
-
XPInstall API 参考
-
- -
-
通过实例学习XPI安装脚本
-
This article uses the installer script from browser.xpi install package as the basis for discussing XPI installations in general.
-
这篇文章使用了取至于browser.xpi安装包中的安装脚本来讨论XPI安装的基本原理.
-
- -
-
创建XPI安装模块
-
This article describes the packaging scheme of the Mozilla and offers a tutorial for creating a new package that can then be redistributed, installed, and made available to users.
-
这篇文件描述了Mozilla安装模块的打包方案, 并提供了一个关于创建一个新的可用来分发, 安装和用户可用的安装包的教程.
-
- -
-
安装向导 (aka: Stub Installers)
-
- -

View All...

-
-

Community

- -
    -
  • View Mozilla forums...
  • -
- -

- -

Tools

- - - - - -
-
Extensions, XUL, XPI
-
-
- -

Categories

- -

Interwiki Language Links

- -

 

- -
 
- -

diff --git a/files/zh-cn/archive/mozilla/xpinstall/reference/index.html b/files/zh-cn/archive/mozilla/xpinstall/reference/index.html deleted file mode 100644 index 5111ad1a6b..0000000000 --- a/files/zh-cn/archive/mozilla/xpinstall/reference/index.html +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: XPInstall API reference -slug: Archive/Mozilla/XPInstall/Reference -translation_of: Archive/Mozilla/XPInstall/Reference ---- -

Parts of this page show the use of the XPInstall API. The majority of this API is now deprecated and as of Gecko 1.9 no longer available. Extension, Theme, and plug-in developers must switch away from install.js based packages to the new packaging scheme with an install.rdf manifest. In particular plugin developers should see how to package a plugin as an extension.

- - -

Objects

- -

Install

- -
-
Properties
-
Methods
-
- -
-
-
-
addDirectory
-
addFile
-
alert
-
cancelInstall
-
confirm
-
deleteRegisteredFile
-
execute
-
gestalt
-
getComponentFolder
-
getFolder
-
getLastError
-
getWinProfile
-
getWinRegistry
-
initInstall
-
loadResources
-
logComment
-
patch
-
performInstall
-
refreshPlugins
-
registerChrome
-
resetError
-
setPackageFolder
-
-
-
- -

InstallTrigger

- -
-
No properties
-
Methods
-
- -
-
-
-
compareVersion
-
enabled
-
getVersion
-
install
-
installChrome
-
startSoftwareUpdate
-
-
-
- -

InstallVersion

- -
-
Properties
-
Methods
-
- -
-
-
-
compareTo
-
init
-
toString
-
-
-
- -

File

- -
-
No properties
-
Methods
-
- -
-
-
-
copy
-
dirCreate
-
dirGetParent
-
dirRemove
-
dirRename
-
diskSpaceAvailable
-
execute
-
exists
-
isDirectory
-
isFile
-
macAlias
-
modDate
-
modDateChanged
-
move
-
remove
-
rename
-
size
-
windowsGetShortName
-
windowsRegisterServer
-
windowsShortcut
-
-
-
- -

WinProfile

- -
-
No properties
-
Methods
-
- -
-
-
-
getString
-
writeString
-
-
-
- -

WinReg

- -
-
No properties
-
Methods
-
- -
-
-
-
createKey
-
deleteKey
-
deleteValue
-
enumKeys
-
enumValueNames
-
getValue
-
getValueNumber
-
getValueString
-
isKeyWritable
-
keyExists
-
setRootKey
-
setValue
-
setValueNumber
-
setValueString
-
valueExists
-
-
-
- -
-
WinRegValue constructor
-
- -

Other Information

- -

Return Codes

- -

See complete list

- -

Examples

- -
-
Trigger Scripts and Install Scripts
-
- -
Code Samples
- -
-
File.macAlias
-
File.windowsShortcut
-
Install.addDirectory
-
Install.addFile
-
InstallTrigger.installChrome
-
InstallTrigger.startSoftwareUpdate
-
Windows Install
-
diff --git a/files/zh-cn/archive/mozilla/xpinstall/reference/install_object/index.html b/files/zh-cn/archive/mozilla/xpinstall/reference/install_object/index.html deleted file mode 100644 index 0a4a02a30a..0000000000 --- a/files/zh-cn/archive/mozilla/xpinstall/reference/install_object/index.html +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Install Object -slug: Archive/Mozilla/XPInstall/Reference/Install_Object -tags: - - XPInstall_API_reference -translation_of: Archive/Mozilla/XPInstall/Reference/Install_Object ---- -

Parts of this page show the use of the XPInstall API. The majority of this API is now deprecated and as of Gecko 1.9 no longer available. Extension, Theme, and plug-in developers must switch away from install.js based packages to the new packaging scheme with an install.rdf manifest. In particular plugin developers should see how to package a plugin as an extension.

- -

Install (Install 对象)

- -

Use the Install object to manage the downloading and installation of software with the XPI Installation Manager.
- 译:使用Install对象协同XPI安装管理器操纵软件的下载和安装.

- -

Overview

- -

The Install object is used primarily in installation scripts. In all cases, the Install object is implicit--like the window object in regular web page scripts--and needn't be prefixed to the object methods. The following two lines, for example, are equivalent:
- Install对象首先会被安装脚本所使用. Install对象总是隐式的, 如同在规则的web页脚本中的window对象一样, 你并不需要将其作为其方法的调用前缀. 例如, 以下两行代码功能是完全一样的:

- -
f = getFolder("Program");
-f = Install.getFolder("Program");
-
- -

An installation script is composed of calls to the Install object, and generally takes the following form:
- 一个安装脚本被书写为调用Install对象, 并且通常采取以下形式:

- -
-
Initialize the installation (初始化安装)
-
Call initInstall with the name of the installation and the necessary registry and version information.
-
调用initInstall(函数), 和安装的名称, 必须的注册以及版本信息.
-
Add the files to the installation (添加文件到安装)
-
Add files to the installation by calling getFolder to get file objects and passing those object refs to addFile as many times as necessary.
-
添加文件到安装, 通过调用 getFolder(函数)取得文件对象并传递那些对象引用到 addFile(函数), 多数时候这样做还是有必要的.
-
Perform installation (执行安装)
-
Check that the files have been added successfully (e.g., by checking the error Return Codes from many of the main installation methods, and go ahead with the install if everything is in order:
-
检查那些文件是否被添加成功(比如通过检查 Return Codes从多数主要安装函数所返回的错误代码), 并且如果所有函数的执行都是正确的, 那么就可以进行后继安装步骤:
-
- -
performOrCancel();
-function performOrCancel()
-{
-  if (0 == getLastError())
-     performInstall();
-   else
-     cancelInstall();
-}
-
- -

For complete script examples, see Script Examples.
- 完事的脚本实例, 参见 Script Examples.

diff --git a/files/zh-cn/archive/mozilla/xpinstall/reference/install_object/properties/index.html b/files/zh-cn/archive/mozilla/xpinstall/reference/install_object/properties/index.html deleted file mode 100644 index 76804ce8cd..0000000000 --- a/files/zh-cn/archive/mozilla/xpinstall/reference/install_object/properties/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Properties -slug: Archive/Mozilla/XPInstall/Reference/Install_Object/Properties -translation_of: Archive/Mozilla/XPInstall/Reference/Install_Object/Properties ---- -

 

-

Properties

-
-
- archive
-
- Full local path of the archive after it is downloaded to the platform specific temp folder. (e.g. C:\TEMP\argstest.xpi)
-
- arguments
-
- args can be passed in through the triggering APIs by attaching a ? and then the rg string to the xpi URL: (e.g. startSoftwareUpdate("http://webserver/argstest.xpi?ARGUMENT_STRING") will result in the value of Install.arguments being ARGUMENT_STRING #). Note that spaces in the arg string are legal. Everything after the question mark is treated as one string which becomes the Install.arguments property.
-
- buildID
-
- The application build ID in the form 20041231. Note that due to branching (different versions of Gecko with different feature sets might be built on the same day), using this property to "detect" the application version may produce false results. Additionally, the build ID can be 0 for custom builds.
-
- jarfile
-
- Alias for archive
-
- platform
-
- Contains information about the platform XPInstall was compiled for/runs on. For example, the value could begin with "Windows", "Macintosh" or "X11" (for Unix/Linux). For more details, see the corresponding code living in the GetInstallPlatform method of class nsInstall.
-
- url
-
- The fully qualified URL of the xpi (file URL, http URL, ftp URL, etc.) (e.g. http://dolfin/sgehani/zzz/ip.xpi). Note, even if triggered using relative URLs this will show the full URL (after qualification).
-
diff --git a/files/zh-cn/archive/mozilla/xpinstall/scripting_by_example/index.html b/files/zh-cn/archive/mozilla/xpinstall/scripting_by_example/index.html deleted file mode 100644 index fb43c1237c..0000000000 --- a/files/zh-cn/archive/mozilla/xpinstall/scripting_by_example/index.html +++ /dev/null @@ -1,246 +0,0 @@ ---- -title: Learn XPI Installer Scripting by Example -slug: Archive/Mozilla/XPInstall/Scripting_by_example -tags: - - XPInstall - - XPInstall_API_reference -translation_of: Archive/Mozilla/XPInstall/Scripting_by_example ---- -

Parts of this page show the use of the XPInstall API. The majority of this API is now deprecated and as of Gecko 1.9 no longer available. Extension, Theme, and plug-in developers must switch away from install.js based packages to the new packaging scheme with an install.rdf manifest. In particular plugin developers should see how to package a plugin as an extension.

- -

This article uses the installer script from browser.xpi install package as the basis for discussing XPI installations in general. This installer script is relatively short, but it exercises most of the important features of the XPInstall API, and it can easily be used as a template for other more general software installations. In this article, we use the unix install file, but the installers for all the platforms are quite similar, and you can easily take what you learn here and apply it to installations on any platform that mozilla supports.

- -

About browser.xpi

- -

browser.xpi is the XPI archive in which the main components of the Mozilla browser are archived for installation. Mozilla cross-platform installations use the XPI format as a way to organize, compress, and automate software installations and software updates. A XPI is a PKZIP-compressed archive (like ZIP and JAR files) with a special script at the highest level that manages the installation. That installer script , usually named install.js, is the subject of this article.

- -

First, a quick scan of the contents of the XPI file (which you can open using with any unzip utility) reveals the following high-level directory structure:

- -
install.js
-bin\
-  chrome\
-  components
-  defaults\
-  icons\
-  plugins\
-  res\
-
- -

Note that this high-level structure parallels the directory structure of the installed browser very closely:

- -

mozilla directory on linux

- -

As you will see in the installation script, the contents of the archive are installed onto the file system in much the same way that they are stored in the archive itself, though it's possible to rearrange things arbitrarily upon installation--to create new directories, to install files in system folders and other areas.

- -

Overview of the Install Script

- -

XPI install scripts are written in JavaScript using XPInstall Engine syntax defined in the XPInstall API Reference.

- -

Most installation scripts, including the one discussed here, take the following basic form (in pseudo-code and with links to the sections in which these installation steps are documented):

- -
initInstall();
-if (verify_space()) {
-   err = add_dirs_and_files;
-   register_files;
-
-   if (err==SUCCESS) { performInstall() };
-   else { cancelInstall() };
-}
-
- -

As you can see in the code listing, the verification process at the top is on lines 1 to 18; the file addition process, here part of the main installation block, is on lines 24 to 41; the registration part of the main installation block is on lines 42-58; and the execution at the end of the main block is on lines 59 to 71. If you choose not to register the installed software or do the verifications at the front end of the installation, then at a minimum, the install scripts mustinitialize, add the files to be installed, and execute.

- -

Note also that when you call methods on the Install--as you do so often in installation scripts (getFolder, initInstall, addFile, and performInstall are all examples of common Install object methods)--the Install object is implicit; like the window object in regular web page scripts, the Install object does not need to be prefixed to the method.

- -

Initializing the Installation

- -

All installations must begin with initInstall(). The initInstall() method on the Install object creates a new installation for the specified software and version. In the browser.xpi installation, this function appears at line 20: var err = initInstall("Netscape Seamonkey", "Browser", "6.0.0.2000110807");

- -

If you call a method on the Install object before initInstall(), you will get an error.

- -

The initInstall method takes the following parameters: the display name of the package, the name of the package as it appears in the client registry, and the version, which can be expressed as a number or as an InstallVersion object. In the example above, "Netscape Seamonkey" is the display name, "Browser" is the registry name, and the version is "6.0.0.2000110807." See initInstall in the XPInstall API Reference for more information on the initialization process.

- -

Verifying the Target

- -

The first thing the installation script does when it's executed is to check that there is adequate disk space for the software to be installed, where the verifyDiskSpace function is called as a condition of the main installation block that starts at line 24).

- -
 // this function verifies disk space in kilobytes
- function verifyDiskSpace(dirPath, spaceRequired)
- {
-   var spaceAvailable;
-   // Get the available disk space on the given path
-   spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
-
-   // Convert the available disk space into kilobytes
-   spaceAvailable = parseInt(spaceAvailable / 1024);
-   // do the verification
-   if(spaceAvailable < spaceRequired)
-   {
-      logComment("Insufficient disk space: " + dirPath);
-      logComment("  required : " + spaceRequired + " K");
-      logComment("  available: " + spaceAvailable + " K");
-      return(false);
-   }
-   return(true);
- }
-
- -

In the verifyDiskSpace block, fileGetDiskSpaceAvailable is called with dirPath as its expected input. This input is defined in line 22, where getFolder() is used to assign a value to the communicatorFolder variable representing the "Program" folder on the local system:

- -
var communicatorFolder = getFolder("Program");
-spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
-
- -

spaceRequired, the other expected input to the verifyDiskSpace function, is given as 17311 kilobytes on line 19. Inside the function, the two sizes are compared and if the available space is larger than the required space, the installation proceeds.

- -

Adding Files and Directories (Full of Files) to the Install

- -

Once you have verified that the target can accomodate the software to be installed and initialized the actual installation, you must add files and directories to the installation in order to have them installed. In the browser.xpi install script, the files are added in lines 26-41:

- -
  err = addDirectory("Program",
-                     "6.0.0.2000110807",
-                     "bin",              // jar source folder
-                     communicatorFolder, // target folder
-                     "",                 // target subdir
-                     true );             // force flag
-
-  logComment("addDirectory() returned: " + err);
-
-  // create the plugins folder next to mozilla
-  var pluginsFolder = getFolder("Plugins");
-  if (!fileExists(pluginsFolder))
-  {
-      var ignoreErr = dirCreate(pluginsFolder);
-      logComment("dirCreate() returned: " + ignoreErr);
-  }
-  else
-      logComment("Plugins folder already exists");
-
- -

In this case, the files are contained within a single directory, so calling the Install object's addDirectory method is sufficient to queue all the files in the archive for installation. The addDirectory, like addFile, handles both the source file location and the target location. In the example above, all of the contents of the "bin" directory in the archive are queued for installation, and the target of that installation (when the installation is actually begun with a call to performInstall at the end), is the communicatorFolder directory defined at line 22 as "Program."

- -

"Program" is one of a short list of keywords that can be used in place of full path names in methods such as addFile. "Program" represents the directory where software itself is installed (e.g., C:\Program Files\ on win32 systems), as opposed to supporting directories like "Components", "Chrome", or "Temporary" (see getFolder in the XPInstall API Reference for a list of keywords).

- -

Registering the Software

- -

Registering software is sometimes a requirement of both the operating system and of the Netscape 6 platform. When you install new chrome, for example, like the browser.xpi install does, you need to alert the chrome registry to these changes, so that skins, user preferences, packaging lists, and localization bundles will all track the new software.

- -

For registering software with the win32 operating system, the XPInstall API provides two special Install objects, WinProfile and WinReg. These two objects provide programmatic access to the Windows user profile and the Windows registry, respectively. The browser.xpi install script does not demonstrate the use of these objects, but see the XPInstall API Reference for more information about registering software with the win32 operating systems and other operating systems.

- -

To register new Netscape 6-based software (e.g., plug-ins, new components, new themes, new packages) with the chrome registry, you must use the registerChrome function of the Install object. If successful, this function returns a "0" and makes entries into theinstalled-chrome.txt file in the chrome subdirectory, which is then used to regenerate the various RDF files that make up the chrome registry.

- -
 var cf = getFolder("Chrome");
- registerChrome(CONTENT | DELAYED_CHROME, getFolder(cf,"toolkit.xpi"),"content/global/");
- registerChrome(CONTENT | DELAYED_CHROME, getFolder(cf,"browser.xpi"),"content/communicator/");
- registerChrome(CONTENT | DELAYED_CHROME, getFolder(cf,"browser.xpi"),"content/editor/");
- registerChrome(CONTENT | DELAYED_CHROME, getFolder(cf,"browser.xpi"),"content/navigator/");
- registerChrome(SKIN | DELAYED_CHROME, getFolder(cf,"modern.jar"),"skin/modern/communicator/");
- registerChrome(SKIN | DELAYED_CHROME, getFolder(cf,"modern.jar"),"skin/modern/editor/");
- ...
-
- -

In lines 42-58, registerChrome is called as many times as there are different directories that contain content that needs to be registered with the chrome registry. Note that in the first few lines of this process, new content from the XPI is being registered, and in the remainder, it is new skin information. In this most common form of the registerChrome function (it can also be used to support the now-deprecatedmanifest.rdf style of installation archive), the three parameters represent, in order, the chrome SWITCH used to indicate what kind of software is being registered, the target destination of the software (e.g., the "Chrome" folder in the example above), and the path within the XPI (or JAR theme archive) where the contents.rdf file is located.

- -

See registerChrome in the XPInstall API Reference for more information about registering new packages with the chrome registry.

- -

Executing the Installation

- -

Once you have added all the files to the installation, the final step is to actually execute the installation. Note that until this point, the install calls you have been making on the Install object are preliminary only. Recall that an install process takes the following general form:

- -
initInstall();
-if (verify_space()) {
-   err = add_dirs_and_files;
-   register_files;
-
-   if (err==SUCCESS) { performInstall() };
-   else { cancelInstall() };
-}
-
- -

In this arrangement, the actual execution of the installation is checked against the errors returned from the addition of files to the installation, which may itself have been conditioned on some verification of version and necessary disk space.

- -

The actual install code used to execute the installation appears in theinstall.js file as follows:

- -
if (err==SUCCESS)
-  {
-     err = performInstall();
-        logComment("performInstall() returned: " + err);
-  }
-
-  else
-  {
-     cancelInstall(err);
-	 logComment("cancelInstall() due to error: " + err);
-  }
-}
-else
-   cancelInstall(INSUFFICIENT_DISK_SPACE);
-
- -

performInstall is the function used to execute the install once it has been initialized and loaded, and it is the last step to installing the software. Note that in the example above, the installation is cancelled if the error code from the file addition process returns success (0), and also cancelled outside the main block if the earlier verification process is not successful.

- -

Note also the comments that indicate the success of various steps in the process--including the performInstall and cancelInstall steps--are written to the install log using the logComment, described in the following section.

- -

Installation Logging

- -

Logging is an important feature of the XPInstall API that can help you streamline and debug your installations. In the example in the Executing the Installation section and in many places in the installation script, the logComment API is used to write data to a log file that can then be reviewed when things don't go as planned.

- -

The install log is created in the product directory by default (where the browser executable is). If the installation doesn't have proper permission, the install log is written to the user's profile directory. Respectively, these directories correspond to the "Program" and "Current User" keywords for the getFolder method.

- -

Extending the Example

- -

What does all this mean to you? How can this information be adapted for your own installations? In this final section, we describe the application of the XPInstall technology described here in the creation and deployment of a very simple installation script and installation archive (XPI).

- -

Say you have a simple executable and a README file that goes with it, and you want to make it available for installation from a XPI. After putting these two files in a XPI (which, as described above, is simply a ZIP file with an install.js script at the top and a suffix of '.xpi'), the next step is to add an installation script to the XPI.

- -

Minimally, the installation script must:

- - - -

Here is an example of small but complete installation script.

- -
var xpiSrc = "cd_ripper.exe";
-var xpiDoc = "README_cdrip";
-
-initInstall("My CD Ripper", "cdrip", "1.0.1.7");
-f = getFolder("Program");
-setPackageFolder(f);
-addFile(xpiSrc);
-addFile(xpiDoc);
-
-if (0 == getLastError())
-	performInstall();
-else
-	cancelInstall();
-
- -

The example above shows this minimal installation. This install script does not include any version or disk space checking, very little error checking, only a single executable, no registration, and no commenting. It does, however, take the executable and the README file and install them on the user's system. Note also that for the installation script in a XPI to be automatically triggered from a web page, you must use a "trigger script." The following InstallTrigger function, called from an event handler on a regular web page, will point to the remotely-hosted XPI (called here 'cdrip.xpi') and trigger its installation:

- -
function putIt()
-{
-  xpi={'CD_Ripper':'cdrip.xpi'};
-  InstallTrigger.install(xpi);
-}
-...
-
-<a href="#" onclick="putIt();">install the CD Ripper Now!</a>
-
- -

See the InstallTrigger object in the XPInstall API Reference for more information on triggering installations.

- -
-

Original Document Information

- - -
- -

diff --git a/files/zh-cn/archive/mozilla/xpinstall/using_xpinstall_to_install_plugins/index.html b/files/zh-cn/archive/mozilla/xpinstall/using_xpinstall_to_install_plugins/index.html deleted file mode 100644 index 7df82abc04..0000000000 --- a/files/zh-cn/archive/mozilla/xpinstall/using_xpinstall_to_install_plugins/index.html +++ /dev/null @@ -1,227 +0,0 @@ ---- -title: Using XPInstall to Install Plugins -slug: Archive/Mozilla/XPInstall/Using_XPInstall_to_Install_Plugins -tags: - - Plugins - - XPInstall -translation_of: Archive/Mozilla/XPInstall/Installing_plugins ---- -

XPInstall is a JavaScript-based installer technology that works across all the platforms that Mozilla and Netscape browsers based on Mozilla (such as Netscape 7) are deployed. It can be a way to ensure a smooth user-experience when obtaining plugins, without obliging the user to exit the browsing environment to launch a binary installer (the classic setup.exe experience on Windows) or obliging the user to restart their browser. For plugin vendors who have already written a native code (e.g. EXE) installer, XPInstall can wrap this native installer and run it so that the user never has to leave the browsing environment and click on the EXE to run it. This article presents a guideline for improving the plugin installation experience for Netscape Gecko browsers using XPInstall. XPInstall是基于js的安装plugin插件的跨平台技术。其包*.xpi,同扩展/主题|皮肤(*.jar)是一样的(zip包)。

-

A Definition of Terms

-

XPInstall is an installer technology, and the name itself stands for "Cross Platform Install" (hence "XP" -- an abbreviation for "Cross Platform"). An XPInstall package is usually called an XPI package for short (and often pronounced "zippy"). This article is about how you can use XPInstall to install plugins to the browsers that support XPInstall.

-

An XPI Package is in fact a ZIP file with the XPI file extension (e.g. myPluginInstaller.xpi), and can be created on Windows by utilities such as WinZip. XPI Packages, like ZIP files, "contain" other files, typically: 典型的插件包结构:

- -

1。插件本身(动态库:如office.so or office.dll等,另外常见的为各种多媒体插件)。

- -

2。install.js:如何安装该插件的javascript脚本。 You can create an XPInstall file by first zipping all the items you want installed with WinZip (create a ZIP archive) and then renaming it with the XPI file extension instead of the ZIP file extension.

-

Unlike native code installers (for example, files called setup.exe), the programming language for install operations in XPI is JavaScript. Since the file format that contains the software and the install.js JavaScript file is a cross-platform file (Zip) and since JavaScript is understood by Mozilla browsers on all platforms, often one single XPI package can be deployed on all platforms. This is, in fact, how skins and themes are installed to Mozilla browsers, changing their look and feel. This article focuses on how to install plugins.

-

Which Browsers Support XPInstall?

-

哪些浏览器支持XPInstall安装方式? Currently, all Mozilla browsers released by mozilla.org support XPInstall, and a family of browsers based on Mozilla code support XPInstall. In particular, this includes:

- -

Caveats:

- -

What Does a Plugin Consist Of?

-

一个插件通常包含什么内容? Plugins can consist of the following types of files, all of which can be installed via an XPI Package:

- -

1。遵从Gecko Plugin API或Netscape Plugin API接口的动态库。[cada:也可能only ln连接文件]

- -

2。可选文件:xpt文件(该文件用来暴露该插件对外的接口描述--通常用javascript脚本可以访问)--新的插件API无须xpt文件也可以支持同样功能了!

- -

3。这种情形也特别多:即某个插件还是某个应用程序的一部分,即该插件必须依赖该应用程序才能在browser中运行,即此时插件依赖的其他文件就是该应用程序的其他相关模块。例如openoffice插件也是这样的。

-

XPInstall can be used to install any combination of these files on an end-user's machine. For those familiar with Netscape Communicator 4.x's SmartUpdate technology, this will be a familiar idea.

-

A Brief History of Netscape Installer Technologies

-

Netscape 安装技术的简要历史: This section is relevant if you are familiar with Netscape Communicator 4.x's SmartUpdate installer technology.[智能update安装技术] The use of JavaScript as the install logic is not unprecedented in Netscape browsers. Netscape Communicator 4.x uses the notion of SmartUpdate to install software, particularly plugins and Java applets to be run locally. SmartUpdate is - - not supported - by Mozilla browsers (and Netscape/AOL browsers based on Mozilla such as Netscape 7), but because of the similarity between the two installer technologies, it is easy to convert your SmartUpdate files to XPInstall files. SmartUpdate involves a digitally signed JAR file which contained the software components to be installed as well as a JavaScript install.js file (called the install script安装脚本) as the installer logic. Downloads and installs would be initiated with a security dialog box naming the certificate authority and the signer(签名安装包的验证). Often, the SmartUpdate download was triggered via the pluginurl attribute of the embed tag:

-
<embed type="application/x-randomtype" src="myfile.typ" width="50" height="50"
-pluginurl="http://mytypecompany.xyz/jarpacks/mytypeplugin.jar"></embed>
-
-

在上面的例子中, the pluginurl attribute points to the signed JAR file, which Netscape Communicator 4.x would then download (subject to the security dialog boxes) if the plugin was not located on the user's machine. SmartUpdate differs from XPInstall in that:以上是Netscape Communicator的插件包(签名的jar包)安装技术概要,他与XPInstall的区别如下:

- -

XPInstall for Mozilla-based browsers is analogous to SmartUpdate in Netscape Communicator 4.x browsers. Porting SmartUpdate deployments to XPInstall is trivial after gaining some familiarity with the new XPInstall API. 二者移植比较琐碎!详细请查看XPInstall API。

- -

XPInstall provides a cohesive API to accomplish rapid installation and setup of plugin software for end-users. The benefit of using XPInstall is to provide a streamlined installation mechanism. This section discusses what an ideal XPInstall Package will do, as well as points out some of the JavaScript API calls that you will make to accomplish these install tasks. An ideal XPI Package will:

-
    -
  1. Install to the current browser that is initiating the XPInstall installation via HTML or triggering an XPInstall installation via a Trigger Script. We will use the term current browser to refer to the browser that initiates the XPInstall download by visiting a site which requires a plugin that the current browser can not find locally. This step will involve the use of the initInstall API call to start everything off, and also the getFolder API call, which helps to locate the current browser's plugin directory.
  2. -
  3. Install the plugin software to another location on the user's hard disk, so that other Mozilla-based browsers that the user may install later can find the plugin (the browser specific components) and pick it up. The goal is to ensure that future Netscape Gecko browsers that the user may install later can benefit from the installation that the user initiated with the current browser. An example might be that the current browser is Netscape 7, but later, the user downloads a beta of the AOL software using Netscape Gecko. Rather than re-initiate the download of the plugin with the yet another browser, the second Netscape Gecko browser can detect that an installation has already occurred. This discovery mechanism hinges on making the secondary install location available from looking at a common repository of metadata. On Windows, this is the Windows System Registry. Once again, this step involves calls to getFolder to locate a "well known" directory in which to install to as a secondary install location.
  4. -
  5. On Windows: write Windows Registry keys that Netscape Gecko browsers (that get installed after the current browser) can parse to discover where the plugin is installed on the machine. In particular, the Windows Registry keys should point to the secondary install location so that future Netscape Gecko browsers can find and add to their list of available plugin locations. The exact format of these registry keys and how they should be written is covered in the section on the first install problem. To actually create and write keys to the Windows System Registry, you'll use the functions of the WinReg object.
  6. -
  7. Ensure that the plugin that has just been installed is refreshed by correctly invoking the refreshPlugins API. By refreshing your plugin, you're ensuring that the plugin is available for use immediately, without obliging the user to restart their browser. This is one of the chief advantages of a smooth XPInstall experience.
  8. -
-

The First Install Problem

-

The First Install Problem refers to the conditions arising when a plugin arrives on a user's machine before a browser arrives. The recommended install process addresses this issue, which is to install to a secondary location after installing to the current browser. In a nutshell, the first install problem can be summed up by the question: how can a browser which is installed on a user's machine after a given plugin has already been installed by the user benefit from the existing installation rather than download the same plugin again? In order to address this issue, plugin vendors are encouraged to:

- -

A Breakdown of the APIs Used

-

The recommended plugin installation process makes use of the XPInstall APIs to install to the current browser's Plugins directory, install to a secondary location, and to write to the Windows System Registry to disclose this secondary location. This section traces some of the XPInstall APIs that can do this. A complete template of an XPI Package is also presented in this section. Not all the work needs to be done in JavaScript -- if you have a native installer (EXE) that recognizes Netscape Gecko browsers, and you merely wish to wrap the EXE installer in an XPI Package for a streamlined delivery to the client, you can easily do so. This section refers extensively to the XPInstall API Documentation.

-

Initializing Installation with Plugin Identifier

-

All XPInstall installations are initiated with the initInstall method of the Install Object. Since the Install Object is available to the install script, it need not be mentioned in the install script (e.g. there is no need to invoke Install.initInstall; simply invoking initInstall will suffice). The initInstall method is polymorphic, but here is a recommended invocation mechanism:

-
initInstall("My Plugin Software", "@myplugin.com/MyPlugin,version=2.5", "2.5.0.0");
-
-

在上面的一段代码中, the initInstall method is invoked with three parameters:

- -

Caveat: Certain versions of Mozilla-based browsers (such as Netscape 6.x) treat the use of the equals character ("=") as an illegal token and thus do not allow invocation of initInstall with strings containing "=". A workaround to this would be to detect if initInstall has failed, and then invoke it again without the "=" string. Here is an example:

-
var PLID = "MyPlugin.plug/version=6.5";
-err = initInstall(SOFTWARE_NAME, PLID, VERSION);
-
-if (err != 0)
-{
-	// install may have failed because of N6 and =
-	// replace PLID with a simple string
-	err = initInstall(SOFTWARE_NAME, "MyPluginString", VERSION);
-	if (err != 0)
-		cancelInstall(err);
-}
-
-

Note that above, the PLID contains an "=" and in case the XPI package is running on browsers that treat "=" as an illegal token, the workaround is to handle the error and invoke initInstall again.

-

Using XPInstall to Run an EXE (Native Code) Installer

-

If you wish to run a native installer (EXE) to install plugin software, but wish to make the delivery of this native installer streamlined and within the browser's process, then you ought to consider wrapping it in an XPI Package. From JavaScript, you can call XPInstall's execute method of the Install Object to execute the binary. You can also call the execute method of the File object if you wish to actually install the file you are executing, rather than have it deleted. You can pass command line parameters to the executable. An example of calling the execute method from the Install Object on an executable that has a temporary life span (and is not needed after one execution) is:

-
// Initialize the installation ....
-
-// initInstall(..... ) has already been called
-
-// Using the Install Object's execute method to block on a native installer
-
-execute("setup.exe", "-s", true);
-
-// In the above sample, assume that running "setup -s" from the
-// Command Prompt runs the setup executable, and that  "-s" is some
-// invocation parameter defined by the setup.exe file, perhaps to force
-// the installer to run silently.  We are passing "-s" to the setup file.
-// By passing 'true' we are telling the Install Script to block
-// on the execution of the installable, and do it synchronously
-
-// Must call performInstall to make it all happen...
-
-err = getLastError();
-if (!err)
-   performInstall();
-else
-  cancelInstall(err);
-
-

Installing Plugin Files To the Current Browser

-

Installing to the current browser is the task that is the most important for the XPI Package to succeed in. Here is a code snippet that accomplishes this:

-
// Name of the files to be installed
-var PLUGIN_FILE    = "NPMyPlugin.dll";
-var COMPONENT_FILE = "NPMyPluginScriptablePeer.xpt";
-
-// invoke initInstall to start the installation
-
-....
-
-var pluginFolder = getFolder("Plugins");
-
-// verify disk space is appropriate
-
-....
-
-err = addFile("@myplugin.com/MyPlugin,version=2.5.0.0",
-                     "2.5.0.0", PLUGIN_FILE, pluginsFolder, null);
-    if (err != 0)
-    {
-	//alert("Installation of MyPlugin plug-in failed. Error code "+err);
-	logComment("adding file "+PLUGIN_FILE+" failed. Errror conde: " + err);
-	return err;
-    }
-
-err = addFile(null, CULT_VERSION, COMPONENT_FILE, componentsFolder, null);
-    if (err != 0)
-    {
-	alert("Installation of MyPlugin component failed. Error code "+err);
-	logComment("adding file "+COMPONENT_FILE+" failed. Error conde: " + err);
-	return err;
-    }
-
-

Installing to a Secondary Location

-

For the purposes of solving the First Install Problem, it is necessary to install to a secondary location to ensure discoverability of the plugin by other Netscape Gecko browser in addition to the current browser. A good choice for this secondary location might be the Windows directory on Windows machines. Caveat: Because of possible administrator issues, handle errors carefully!

-
// Get the Windows System directory e.g. C:\WINNT\system32\ directory
-
-var winDirectory = getFolder("Win System");
-
-// Create the Folder C:\WINNT\system32\MyPlugin
-
-var dllWin32Folder = getFolder("file:///", winDirectory+"\\MyPlugin\\");
-//Install DLL to C:\Windows Folder
-	copyErr = addFile("", VERSION, PLUGIN_FILE, dllWin32Folder, null);
-    if (copyErr != 0)
-    {
-    	logComment("First Install:"+copyErr);
-    	return copyErr;
-    }
-
-// Install the XPT file to C:\WINNT\system32\MyPlugin folder
-
-var xptWin32Folder = getFolder("file:///", winDirectory+"\\MyPlugin\\");
-	copyErr = addFile("", VERSION, COMPONENT_FILE, xptWin32Folder, null);
-    if (copyErr != 0)
-    {
-    	logComment("First Install:"+copyErr);
-    	return copyErr;
-    }
-
-

Once the secondary installation has taken place, the Win32 Registry keys have to be updated to indicate information about where the secondary install location is, so that browsers can discover it. This is accomplished with the WinReg object that is exposed to XPInstall. The pieces all come together in the template below.

-

An XPInstall Template

-

We have provided you with a template for an install script which you might want to open in another tab or window. This install script does all of the following:

- -

Certainly, this script is Windows-centric, but it is easy to port it to any other platform. Easier, perhaps, since the lengthy Win32 Registry manipulation need not occur on Linux or Mac OSX. The getFolder API provides you with enough "syntactic sugar" to determine other locations on the user's computer on different platforms and OS's. A single install.js is often capable of running on many different platforms.

-

Some Installation Concerns

-

This section gathers together some of the chief concerns about deploying XPI packages, notably: how ought a plugin download via XPI be initiated? And what about uninstalling plugins?

-

Triggering an XPInstall Download with a TriggerScript

-

A Trigger Script is web-page delivered piece of JavaScript that can automatically initiate an XPInstall download. This can be done conditionally, since Trigger Scripts can also detect what software has already been installed to the user's machine via XPInstall. This feature is useful for Web sites because:

- -

Trigger Scripts are a recommended way of initiating an XPInstall download.

-

Triggering an XPInstall Download from HTML

-

In a manner analogous to how SmartUpdate downloads were initiated by the pluginurl attribute of the embed tag, XPInstall downloads can also be initiated by HTML tags invoking plugins, notably via the codebase attribute of the object tag. This is analogous to how Internet Explorer downloads CAB files pointed to by the codebase attribute of the object tag. Here's an example of a hypothetical object tag used to invoke MyPlugin (an imaginary application):

-
	<object id="thePlugin" type="application/x-myplugin" width="100"
-	height="100" codebase="http://location/XPI/myplugin.xpi">
-
-<param .... >
-
-

In the above case, the codebase attribute points directly to the XPI Package, and if the browser can not identify any plugin to handle the (imaginary) application/x-myplugin MIME type, it will download the XPI Package.

-

Note: XPI Packages (files with the xpi extension) use the application/x-xpinstall MIME type. When serving XPI Packages from servers to clients, make sure that XPI Packages are served with this MIME type in the HTTP headers. Associate the application/x-xpinstall MIME type with XPI Packages.

-

The Uninstall Problem

-

In its current iteration, XPInstall does not have an affiliated uninstall technology. It can therefore only be used to install files or deliver native code installers to the client, and if uninstall is a legitimate concern, it might be wise to write a native code (EXE) uninstaller to remove the software. XPInstall can therefore be the "agent of delivery" to streamline the download of the EXE software, but ultimately, the logic of installation and uninstallation will be handled by EXE, which can then create files and registry entries and also clean up after itself upon removal.

-
-

Original Document Information

- -
-

 

diff --git a/files/zh-cn/archive/rss/article/index.html b/files/zh-cn/archive/rss/article/index.html deleted file mode 100644 index 58862fc363..0000000000 --- a/files/zh-cn/archive/rss/article/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Article -slug: Archive/RSS/Article -translation_of: Archive/RSS/Article ---- -

This page was auto-generated because a user created a sub-page to this page.

diff --git a/files/zh-cn/archive/rss/article/why_well-formed_web_rss_module_is_popular_-_syndicating_your_comments/index.html b/files/zh-cn/archive/rss/article/why_well-formed_web_rss_module_is_popular_-_syndicating_your_comments/index.html deleted file mode 100644 index 8ea13bb58d..0000000000 --- a/files/zh-cn/archive/rss/article/why_well-formed_web_rss_module_is_popular_-_syndicating_your_comments/index.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: 文章:为什么"Well-Formed Web RSS"模块会流行——对你的评论进行同步 -slug: >- - Archive/RSS/Article/Why_Well-Formed_Web_RSS_Module_is_Popular_-_Syndicating_Your_Comments -translation_of: >- - Archive/RSS/Article/Why_Well-Formed_Web_RSS_Module_is_Popular_-_Syndicating_Your_Comments ---- -

为什么"Well-Formed Web RSS"模块会流行

diff --git a/files/zh-cn/archive/rss/index.html b/files/zh-cn/archive/rss/index.html deleted file mode 100644 index 0fe628088e..0000000000 --- a/files/zh-cn/archive/rss/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: RSS -slug: Archive/RSS -tags: - - RSS -translation_of: Archive/RSS ---- -

 

-
- 从这里开始
- 一份指导教程将会帮助您开始使用RSS。
-
- 简单同步工具 (RSS)采用流行的HTML-类XML语言格式进行同步工作。 RSS的发展历史十分混杂,衍生出了一些彼此不兼容的版本RSS versions(其中一些基于RDF,但大部分只是基于XML。)尽管如此,RSS作为一种非常流行的同步数据格式广泛应用于新闻、博客、IP广播、IPTV等领域,而且表现出了惊人的能力。 Nonetheless, RSS is an extremely popular format that is used for syndicating news, blog posts, IPradio, and IPTV, with an amazing amount of momentum.
- - - - - - - -
-

文档

-
-
- 为什么RSS Slash会流行 —— 数一下你的评论
-
- Charles Iliya Krmpeaux谈论RSS Slash模块:为什么它在一些人中会流行?怎么用它对你的评论进行”计数“?
-
-
-
- 为什么"Well-Formed Web RSS"模块会流行——对你的评论进行同步
-
- Charles Iliya Krempeaux谈论RSS Well-Formed Web模块: 它为什么在一些人中流行?怎样使用它来链接到你的评论?
-
-
-
- RSS兼容性的迷思
-
- Mark Pilgrim将告诉你RSS混杂的历史故事以及不同版本将的细节差别。
-
-
-
- Atomic RSS
-
- Tim Bray谈论的内容有,将Atom 1.0作为RSS2.0的一种微小模式和拓展模块来使用;继续使用RSS2.0作为你的同步数据格式,同时选用Atom1.0的某些组件
-
-

查看所有……

-
-

社区

- -

相关主题

-
-
- RDF, XML
-
-
-

Categories

-

Interwiki Language Links

-

 

-

diff --git a/files/zh-cn/archive/security/digital_signatures/index.html b/files/zh-cn/archive/security/digital_signatures/index.html deleted file mode 100644 index a6bbd73af1..0000000000 --- a/files/zh-cn/archive/security/digital_signatures/index.html +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Digital Signatures -slug: Archive/Security/Digital_Signatures -translation_of: Archive/Security/Digital_Signatures ---- -

加密和解密解决了窃听问题,这是本文开头提到的三个互联网安全问题之一。但加密和解密本身并不能解决另一个问题:篡改。

- -

本节描述公钥加密如何解决篡改问题。

- -

篡改检测和相关的身份验证技术依赖于一个称为单向哈希(也称为消息摘要)的数学函数。单向哈希是具有以下特征的固定长度数:

- - - -

类似地,在公钥加密中,生成用于数字签名的密钥对。密钥对由 私有签名密钥公共验证密钥组成. 公钥被广泛分发,而私钥只有其所有者知道。这些密钥在数学上是相关的,但是选择这些参数是为了从公钥中计算私钥是不可能的,或者是非常昂贵的。加密的散列以及其他信息,如散列算法,被称为数字签名。

- -

图1显示了使用数字签名来验证签名数据完整性的简化视图。

- -

Figure 3. Using a Digital Signature to Validate Data Integrity

- -

图1显示了传输给某些签名数据的接收者的两个项目:原始数据和数字签名,这基本上是一个单向散列(原始数据的散列),已经用签名者的私钥加密。 为了验证数据的完整性,接收软件首先使用签名者的公钥来解密散列。然后使用生成原始散列的相同散列算法生成相同数据的新单向散列。(有关使用的散列算法的信息与数字签名一起发送,但图中未显示。) 最后,接收软件将新散列与原始散列进行比较。 如果两个散列匹配,则数据自签名后没有更改。如果它们不匹配,则数据可能在签名后被篡改,或者签名可能是使用与签名者提供的公钥不对应的私钥创建的。

- -

如果两个散列匹配,则收件人可以确定用于解密数字签名的公钥与用于创建数字签名的私钥相对应。 但是,要确认签名者的身份,还需要某种方式来确认公钥确实属于某个特定的人或其他实体。For a discussion of the way this works, see "Introduction to Public-Key Cryptography."

- -

数字签名的重要性与手写签名的重要性相当。 一旦您签署了一些数据,就很难拒绝以后这样做,假设私钥没有被泄露或超出了所有者的控制。一旦您签署了一些数据,就很难拒绝以后这样做,假设私钥没有被泄露或超出了所有者的控制。在某些情况下,数字签名可能与手写签名一样具有法律约束力。

- -
-

Original Document Information

- - -
diff --git a/files/zh-cn/archive/security/encryption_and_decryption/index.html b/files/zh-cn/archive/security/encryption_and_decryption/index.html deleted file mode 100644 index 8154ffdffa..0000000000 --- a/files/zh-cn/archive/security/encryption_and_decryption/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Encryption and Decryption -slug: Archive/Security/Encryption_and_Decryption -translation_of: Archive/Security/Encryption_and_Decryption ---- -

加密是使预期参与者外的仍何人不可知的的信息转换过程。解密是加密的反过程以便让信息可理解。一个加密算法也被称作暗号,是一个数学函数用于加解密。大多数情况使用两个相关联函数,一个用于加密一个用于解密。

- -

凭借大多数现代密码学,保障加密信息的隐秘不是基于加密算法,这是被广泛认知的,而是通过一个被称为密钥的数字它将必须被用到算法过程中去产生一个加密后或解密后的结果。通过正确的密钥解密很简单。没有正确的密钥解密是非常困难的,并且在某些情况下所有的尝试都是不能解密的。

- -

以下部分是对密钥来加密和解密的进一步介绍

- - - -

对称密钥加密

- -

使用对称密钥加密,加密密钥可以通过加密密钥运算得出,反之亦然。大多数的对称加密算法中,使用的是相同的密钥,如图一所示。

- -

Figure 1. Symmetric-Key Encryption

- -

对称密钥加密的实现可以是非常高效的,以至于使用者不会体验到非常大的延时就得到加密或解密的结果。对称密钥加密还提供了一定程度的认证机制,自从信息被一个对称密钥加密后不可被另一个对称密钥解密。因此,在加密通信中只要对称密钥隐秘的保存在通信双方,并能确认其通信另一方(的真实性)解密后的消息就存在意义。

- -

对称密钥加密仅仅当涉及到的双方秘密的保存对称密钥才是有效的。如果任何人发现了密钥,它会影响保密性和身份验证。拥有未经授权的对称密钥的人(虚假的第三方)不仅可以解密与该密钥一起发送的消息,还可以加密新消息并将它们发送,就好像它们来自最初使用密钥的两方中的一方。

- -

对称密钥加密在SSL协议中具有极其重要的作用,它被用于认证,篡改检测和在TCP/IP网络上的加密。SSL也使用到了公开密钥技术,它将在下一节中描述。

- -

公开密钥加密

- -

最常见实现公开密钥加密是基于RSA Data Security专利的算法。因此,这一节介绍RSA公钥加密方法。

- -

公开密钥加密(也被称作非对称加密)包含一对密 - 公钥和私钥与需要以电子方式验证其身份或签署或加密数据的实体相关联。任何公钥是可以公开的与之对应的私钥需要隐秘保存。使用公钥加密的数据仅能被你的私钥解密。图2 展示了简化的使用公钥加密是如何工作的。

- -

Figure 2. Public-Key Encryption

- -

图2所示的方案可让您自由分发公钥,只有您将能够读取使用此密钥加密的数据。通常,要将加密数据发送给某人,需要使用该人的公钥对数据进行加密,接收加密数据的人员使用相应的私钥对其进行解密。

- -

与对称密钥加密相比,公钥加密需要更多的计算,因此并不总是适用于大量数据。但是,可以使用公钥加密来发送对称密钥,然后可以使用该对称密钥来加密其他数据。这是SSL协议使用的方法。

- -

碰巧,图2所示方案的反面也适用:用您的私钥加密的数据只能用您的公钥解密。然而,这不会是加密敏感数据的理想方式,因为这意味着任何使用公钥定义的公开密钥都可以解密数据。不过,私钥加密很有用,因为这意味着您可以使用私钥对数据签名,这对于电子商务和其他密码学商业应用来说是一个重要要求。客户端软件例如Firefox接着可以使用你的公钥去确认这消息是否是被你的私钥签名和是否在签名之后被篡改。“数字签名”描述了此确认过程的工作原理。

- -

密钥长度和加密强度

- -

打破加密算法基本上是找到以纯文本访问加密数据的关键。对于对称算法,打破算法通常意味着试图确定用于加密文本的密钥。对于公钥算法,打破算法通常意味着获取两个接收者之间的共享秘密信息。

- -

破坏对称算法的一种方法是简单地尝试整个算法中的每个密钥,直到找到正确的密钥。对于公开密钥算法,由于密钥对的一半是公开的,所以另一半(私钥)可以使用发布的,但复杂的数学计算来导出。手工找到破解算法的关键就是蛮力攻击。

- -

打破算法引入了拦截,甚至模仿和欺骗性验证私人信息的风险。

- -

算法的关键优势在于找到最快的方法来破解算法并将其与蛮力攻击相比较。

- -

对于对称密钥,加密强度通常以用于执行加密的密钥的大小或长度来描述:通常,较长的密钥提供更强的加密。密钥长度以位为单位进行测量。例如,与SSL支持的RC4对称密钥密码一起使用的128位密钥提供比用于相同密码的40位密钥更好的加密保护。大致来讲,128位RC4加密比40位RC4加密强 3 x 1026倍。(有关用于SSL的RC4和其他密码的更多信息,参见“SSL介绍.") 如果最有名的破解密钥的攻击速度不比蛮力试图测试每个关键可能性的速度快,那么加密密钥就被认为是完备性密钥。

- -

不同的密码可能需要不同的密钥长度才能达到相同级别的加密强度。例如,用于公钥加密的RSA密码,由于其所基于的数学问题的性质,对于给定长度的密钥只能使用所有可能值的子集。其他密码,例如那些用于对称密钥加密的密码,可以为给定长度的密钥使用所有可能的值,而不是这些值的子集。

- -

因为破解RSA密钥相对简单,RSA公钥加密密码必须有一个非常长的密钥(至少1024位)被认为是密码强的。另一方面,对于大多数算法,对称密钥密码可以达到与80位密钥大致相同的强度水平。

- - - -
-

Original Document Information

- - -
diff --git a/files/zh-cn/archive/security/index.html b/files/zh-cn/archive/security/index.html deleted file mode 100644 index 63e3a0821e..0000000000 --- a/files/zh-cn/archive/security/index.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Security -slug: Archive/Security -tags: - - NeedsTranslation - - TopicStub -translation_of: Archive/Security ---- -

Relying on these obsolete security articles is highly discouraged. Doing so may put your systems at risk.

- -

-
-
Encryption and Decryption
加密是使预期参与者外的仍何人不可知的的信息转换过程。解密是加密的反过程以便让信息可理解。一个加密算法也被称作暗号,是一个数学函数用于加解密。大多数情况使用两个相关联函数,一个用于加密一个用于解密。
-

diff --git a/files/zh-cn/archive/security/introduction_to_public-key_cryptography/index.html b/files/zh-cn/archive/security/introduction_to_public-key_cryptography/index.html deleted file mode 100644 index b96f91ddd0..0000000000 --- a/files/zh-cn/archive/security/introduction_to_public-key_cryptography/index.html +++ /dev/null @@ -1,475 +0,0 @@ ---- -title: Introduction to Public-Key Cryptography -slug: Archive/Security/Introduction_to_Public-Key_Cryptography -translation_of: Archive/Security/Introduction_to_Public-Key_Cryptography ---- -

公钥密码及相关标准和技术是许多产品(如签名和加密电子邮件、单点登录和安全套接字层(SSL)通信)安全功能的基础。本文介绍了公钥密码的基本概念。For an overview of SSL, see "Introduction to SSL." For an overview of encryption and decryption, see "Encryption and Decryption." Information on digital signatures is available from "Digital Signatures."

- -

公钥密码是一套成熟的技术和标准,用于保护通信免受窃听、篡改和模拟攻击.

- - - -

以下各节介绍了构成这些功能基础的公钥加密的概念.

- - - -

证书和认证

- - - -

证书证明某人或某事

- -

A certificate is an electronic document used to identify an individual, a server, a company, or some other entity and to associate that identity with a public key. Like a driver's license, a passport, or other commonly used personal IDs, a certificate provides generally recognized proof of a person's identity. Public-key cryptography uses certificates to address the problem of impersonation.

- -

To get a driver's license, you typically apply to a government agency, such as the Department of Motor Vehicles, which verifies your identity, your ability to drive, your address, and other information before issuing the license. To get a student ID, you apply to a school or college, which performs different checks (such as whether you have paid your tuition) before issuing the ID. To get a library card, you may need to provide only your name and a utility bill with your address on it.

- -

Certificates work much the same way as any of these familiar forms of identification. 证书颁发机构(CA)是验证身份并颁发证书的实体. 它们可以是独立的第三方,也可以是运行自己的证书颁发服务器软件(如红帽证书系统)的组织. 验证身份所用的方法因给定CA的策略而异,正如验证其他形式的身份所用的方法因颁发ID的人和使用ID的目的而异. In general, before issuing a certificate, the CA must use its published verification procedures for that type of certificate to ensure that an entity requesting a certificate is in fact who it claims to be.

- -

CA颁发的证书将特定的公钥绑定到证书标识的实体的名称(例如雇员或服务器的名称). 证书有助于防止使用假公钥进行模拟. 只有经过证书认证的公钥才能与证书标识的实体所拥有的相应私钥一起使用.

- -

除了公钥之外,证书还始终包括它标识的实体的名称、过期日期、颁发证书的CA的名称、序列号和其他信息. 最重要的是,证书总是包含颁发CA的数字签名. CA的数字签名允许证书作为“介绍信”使用,这些用户知道并信任CA,但不知道证书标识的实体.

- -

For more information about the role of CAs, see "How CA Certificates Are Used to Establish Trust".

- -

身份验证

- -

Authentication is the process of confirming an identity. In the context of network interactions, authentication involves the confident identification of one party by another party. Authentication over networks can take many forms. Certificates are one way of supporting authentication.

- -

Network interactions typically take place between a client, such as browser software running on a personal computer, and a server, such as the software and hardware used to host a Web site. Client authentication refers to the confident identification of a client by a server (that is, identification of the person assumed to be using the client software). Server authentication refers to the confident identification of a server by a client (that is, identification of the organization assumed to be responsible for the server at a particular network address).

- -

Client and server authentication are not the only forms of authentication that certificates support. For example, the digital signature on an email message, combined with the certificate that identifies the sender, provide strong evidence that the person identified by that certificate did indeed send that message. Similarly, a digital signature on an HTML form, combined with a certificate that identifies the signer, can provide evidence, after the fact, that the person identified by that certificate did agree to the contents of the form. In addition to authentication, the digital signature in both cases ensures a degree of nonrepudiation-that is, a digital signature makes it difficult for the signer to claim later not to have sent the email or the form.

- -

Client authentication is an essential element of network security within most intranets or extranets. The sections that follow contrast two forms of client authentication:

- - - -

Password-Based Authentication

- -

Figure 4 shows the basic steps involved in authenticating a client by means of a name and password. Figure 4 assumes the following:

- - - -

Figure 4. Using a Password to Authenticate a Client to a Server

- -

These are the steps shown in Figure 4:

- -
    -
  1. In response to an authentication request from the server, the client displays a dialog box requesting the user's name and password for that server. The user must supply a name and password separately for each new server the user wishes to use during a work session.
  2. -
  3. The client sends the name and password across the network, either in the clear or over an encrypted SSL connection.
  4. -
  5. The server looks up the name and password in its local password database and, if they match, accepts them as evidence authenticating the user's identity.
  6. -
  7. The server determines whether the identified user is permitted to access the requested resource, and if so allows the client to access it.
  8. -
- -

With this arrangement, the user must supply a new password for each server, and the administrator must keep track of the name and password for each user, typically on separate servers.

- -

Proper implementation does not store passwords in plaintext. Instead it concatenates the password with a random per-user value (so called "salt") and stores the hash value of the result along with the salt. This makes certain kinds of brute-force atacks more difficult.

- -

As shown in the next section, one of the advantages of certificate-based authentication is that it can be used to replace the first three steps in Figure 4 with a mechanism that allows the user to supply just one password (which is not sent across the network) and allows the administrator to control user authentication centrally.

- -

Certificate-Based Authentication

- -

图5显示了如何使用证书和SSL协议进行客户端身份验证. 为了向服务器验证用户身份,客户端对随机生成的数据进行数字签名,并通过网络发送证书和签名数据.在本讨论中,可以将与某些数据相关联的数字签名视为客户端向服务器提供的证据. 服务器根据此证据验证用户的身份.

- -

与图4一样,图5假设用户已经决定信任服务器并请求了资源,并且服务器在评估是否授予对请求的资源的访问权限的过程中请求了客户端身份验证.

- -

Figure 5. Using a Certificate to Authenticate a Client to a Server

- -

与图4所示的过程不同,图5所示的过程需要使用SSL. 图5还假设客户端有一个有效的证书,可以用来向服务器标识客户端. 基于证书的身份验证通常被认为比基于密码的身份验证更可取,因为它基于用户所拥有的(私钥)以及用户所知道的(保护私钥的密码). 但是,需要注意的是,只有在未经授权的人员没有访问用户的机器或密码、设置了客户端软件的私钥数据库的密码以及设置软件以合理的频繁间隔请求密码的情况下,这两个假设才是真的.

- -
基于密码的身份验证或基于证书的身份验证都不能解决与对单个计算机或密码的物理访问相关的安全问题. 公钥密码只能验证用于签名某些数据的私钥是否与证书中的公钥对应. 用户有责任保护机器的物理安全并对私钥密码保密.
- -

These are the steps shown in Figure 5:

- -
    -
  1. 客户端软件(如Communicator)维护私钥数据库,这些私钥对应于为该客户端颁发的任何证书中发布的公钥. 客户端在给定会话期间第一次需要访问该数据库时(例如,用户第一次尝试访问需要基于证书的客户机身份验证的启用了SSL的服务器时),会请求该数据库的密码. 输入此密码一次后,用户在会话的其余部分不需要再次输入,即使在访问其他启用SSL的服务器时也是如此.
  2. -
  3. 客户端解锁私钥数据库,检索用户证书的私钥,并使用该私钥对根据客户端和服务器的输入随机生成的一些数据进行数字签名. 这些数据和数字签名构成了私钥有效性的“证据”. 数字签名只能使用该私钥创建,并且可以使用对应的公钥针对已签名的数据进行验证,该数据对于SSL会话是唯一的.
  4. -
  5. 客户端通过网络发送用户证书和证据(随机生成的经过数字签名的数据片段).
  6. -
  7. 服务器使用证书和证据来验证用户的身份. (For a detailed discussion of the way this works, see "Introduction to SSL.")
  8. -
  9. At this point the server may optionally perform other authentication tasks, such as checking that the certificate presented by the client is stored in the user's entry in an LDAP directory. The server then continues to evaluate whether the identified user is permitted to access the requested resource. This evaluation process can employ a variety of standard authorization mechanisms, potentially using additional information in an LDAP directory, company databases, and so on. If the result of the evaluation is positive, the server allows the client to access the requested resource.
  10. -
- -

As you can see by comparing Figure 5 to Figure 4, certificates replace the authentication portion of the interaction between the client and the server. Instead of requiring a user to send passwords across the network throughout the day, single sign-on requires the user to enter the private-key database password just once, without sending it across the network. For the rest of the session, the client presents the user's certificate to authenticate the user to each new server it encounters. Existing authorization mechanisms based on the authenticated user identity are not affected.

- -

证书应用

- -

证书有一个目的:建立信任. 它们的使用取决于它们用于确保的信任类型. 某些类型的证书用于验证演示者的身份; 其他用于验证对象或项未被篡改.

- - - -

SSL Protocol

- -

安全套接字层(SSL)协议是一组规则,用于管理服务器身份验证、客户端身份验证以及服务器和客户端之间的加密通信. SSL在Internet上广泛使用,特别是用于涉及交换机密信息(如信用卡号码)的交互.

- -

SSL至少需要一个服务器SSL证书. 作为初始“握手”过程的一部分,服务器向客户机提供其证书以验证服务器的身份. 身份验证过程使用公钥加密和数字签名来确认服务器实际上就是它声称的服务器. 一旦服务器经过身份验证,客户机和服务器就使用对称密钥加密技术(这是非常快速的),对它们在会话剩余时间内交换的所有信息进行加密,并检测可能发生的任何篡改.

- -

可以选择将服务器配置为需要客户端身份验证和服务器身份验证. 在这种情况下,在成功完成服务器身份验证之后,客户端还必须向服务器提供其证书,以便在建立加密的SSL会话之前验证客户端的身份.

- -

For an overview of client authentication over SSL and how it differs from password-based authentication, see "Authentication Confirms an Identity". For more detailed information about SSL, see "Introduction to SSL."

- -

Signed and Encrypted Email

- -

Some email programs support digitally signed and encrypted email using a widely accepted protocol known as Secure Multipurpose Internet Mail Extension (S/MIME). Using S/MIME to sign or encrypt email messages requires the sender of the message to have an S/MIME certificate.

- -

An email message that includes a digital signature provides some assurance that it was in fact sent by the person whose name appears in the message header, thus providing authentication of the sender. If the digital signature cannot be validated by the email software on the receiving end, the user will be alerted.

- -

The digital signature is unique to the message it accompanies. If the message received differs in any way from the message that was sent-even by the addition or deletion of a comma-the digital signature cannot be validated. Therefore, signed email also provides some assurance that the email has not been tampered with. As discussed at the beginning of this document, this kind of assurance is known as nonrepudiation. In other words, signed email makes it very difficult for the sender to deny having sent the message. This is important for many forms of business communication. (For information about the way digital signatures work, see "Digital Signatures".)

- -

S/MIME also makes it possible to encrypt email messages. This is also important for some business users. However, using encryption for email requires careful planning. If the recipient of encrypted email messages loses his or her private key and does not have access to a backup copy of the key, for example, the encrypted messages can never be decrypted.

- -

Single Sign-On

- -

Network users are frequently required to remember multiple passwords for the various services they use. For example, a user might have to type a different password to log into the network, collect email, use directory services, use the corporate calendar program, and access various servers. Multiple passwords are an ongoing headache for both users and system administrators. Users have difficulty keeping track of different passwords, tend to choose poor ones, and tend to write them down in obvious places. Administrators must keep track of a separate password database on each server and deal with potential security problems related to the fact that passwords are sent over the network routinely and frequently.

- -

Solving this problem requires some way for a user to log in once, using a single password, and get authenticated access to all network resources that user is authorized to use-without sending any passwords over the network. This capability is known as single sign-on.

- -

Both client SSL certificates and S/MIME certificates can play a significant role in a comprehensive single sign-on solution. For example, one form of single sign-on relies on SSL client authentication (see "Certificate-Based Authentication"). A user can log in once, using a single password to the local client's private-key database, and get authenticated access to all SSL-enabled servers that user is authorized to use-without sending any passwords over the network. This approach simplifies access for users, because they don't need to enter passwords for each new server. It also simplifies network management, since administrators can control access by controlling lists of certificate authorities (CAs) rather than much longer lists of users and passwords.

- -

In addition to using certificates, a complete single-sign on solution must address the need to interoperate with enterprise systems, such as the underlying operating system, that rely on passwords or other forms of authentication.

- -

Object Signing

- -

通信器支持一组称为对象签名的工具和技术. 对象签名使用公钥加密的标准技术,使用户可以获得关于他们下载的代码的可靠信息,就像他们可以获得关于收缩包装软件的可靠信息一样.

- -

最重要的是,对象签名帮助用户和网络管理员实现有关通过内部网或Internet分发的软件的决策,例如,是否允许由给定实体签名的Java小程序在特定用户的计算机上使用特定的计算机功能.

- -

使用对象签名技术签名的“对象”可以是applet或其他Java代码、JavaScript脚本、插件或任何类型的文件. “签名”是数字签名. 签名对象及其签名通常存储在一个称为JAR文件的特殊文件中.

- -

希望使用对象签名技术对文件进行签名的软件开发人员和其他人员必须首先获得对象签名证书.

- -

证书类型

- -

常见的证书类型包括:

- - - -
-
示例:银行向客户提供一个客户端SSL证书,该证书允许银行的服务器识别该客户并授权访问该客户的帐户. 公司可能会给新员工一个客户端SSL证书,允许公司的服务器识别该员工并授权访问公司的服务器.
-
- - - -
-
Example: Internet sites that engage in electronic commerce (commonly known as e-commerce) usually support certificate-based server authentication, at a minimum, to establish an encrypted SSL session and to assure customers that they are dealing with a web site identified with a particular company. The encrypted SSL session ensures that personal information sent over the network, such as credit card numbers, cannot easily be intercepted.
-
- - - -
-
Examples: A company deploys combined S/MIME and SSL certificates solely for the purpose of authenticating employee identities, thus permitting signed email and client SSL authentication but not encrypted email. Another company issues S/MIME certificates solely for the purpose of both signing and encrypting email that deals with sensitive financial or legal matters.
-
- - - -
-
Example: A software company signs software distributed over the Internet to provide users with some assurance that the software is a legitimate product of that company. Using certificates and digital signatures in this manner can also make it possible for users to identify and control the kind of access downloaded software has to their computers.
-
- - - -
-
示例:存储在Firefox中的CA证书决定了Firefox副本可以验证的其他证书。管理员可以通过控制存储在每个用户的Firefox副本中的CA证书来实现公司安全策略的某些方面。
-
- -

证书内容

- -

The contents of certificates are organized according to the X.509 v3 certificate specification, which has been recommended by the International Telecommunications Union (ITU), an international standards body, since 1988.

- -

Users don't usually need to be concerned about the exact contents of a certificate. However, system administrators working with certificates may need some familiarity with the information provided here.

- -

Certificate Data Formats

- -

Certificate requests and certificates can be created, stored, and installed in multiple formats: binary and text. All of these formats conform to X.509 standards. Three examples of binary formats are DER-encoded certificates, PKCS #7 certificate chains, and Netscape Certificate Sequence. Any of the binary formats can be imported in text form, which begins with the line:

- -

-----BEGIN CERTIFICATE-----

- -

Following this line is the certificate data, which can be in any of the binary formats described. This data should be base-64 encoded, as described by RFC 1113. The certificate information is followed by this line:

- -

-----END CERTIFICATE-----

- -

Distinguished Names

- -

An X.509 v3 certificate binds a distinguished name (DN) to a public key. A DN is a series of name-value pairs, such as uid=doe, that uniquely identify an entity-that is, the certificate subject.

- -

For example, this might be a typical DN for an employee of Example Corp:

- -
uid=doe,e=doe@example.net,cn=John Doe,o=Example Corp.,c=US
-
- -

The abbreviations before each equal sign in this example have these meanings:

- - - -

DNs may include a variety of other name-value pairs. They are used to identify both certificate subjects and entries in directories that support the Lightweight Directory Access Protocol (LDAP).

- -

The rules governing the construction of DNs can be quite complex and are beyond the scope of this document. For comprehensive information about DNs, see A String Representation of Distinguished Names] at the following URL:

- -
https://www.ietf.org/rfc/rfc1485.txt
-
- -

A Typical Certificate

- -

Every X.509 certificate consists of two sections:

- - - -

Here are the data and signature sections of a certificate in human-readable format:

- -
Certificate:
-Data:
- Version: v3 (0x2)
- Serial Number: 3 (0x3)
- Signature Algorithm: PKCS #1 MD5 With RSA Encryption
- Issuer: OU=Ace Certificate Authority, O=Ace Industry, C=US
- Validity:
-  Not Before: Fri Oct 17 18:36:25 1997
-  Not  After: Sun Oct 17 18:36:25 1999
- Subject: CN=Jane Doe, OU=Finance, O=Ace Industry, C=US
- Subject Public Key Info:
-  Algorithm: PKCS #1 RSA Encryption
-  Public Key:
-   Modulus:
-    00:ca:fa:79:98:8f:19:f8:d7:de:e4:49:80:48:e6:2a:2a:86:
-    ed:27:40:4d:86:b3:05:c0:01:bb:50:15:c9:de:dc:85:19:22:
-    43:7d:45:6d:71:4e:17:3d:f0:36:4b:5b:7f:a8:51:a3:a1:00:
-    98:ce:7f:47:50:2c:93:36:7c:01:6e:cb:89:06:41:72:b5:e9:
-    73:49:38:76:ef:b6:8f:ac:49:bb:63:0f:9b:ff:16:2a:e3:0e:
-    9d:3b:af:ce:9a:3e:48:65:de:96:61:d5:0a:11:2a:a2:80:b0:
-    7d:d8:99:cb:0c:99:34:c9:ab:25:06:a8:31:ad:8c:4b:aa:54:
-    91:f4:15
-   Public Exponent: 65537 (0x10001)
-  Extensions:
-   Identifier: Certificate Type
-    Critical: no
-    Certified Usage:
-     SSL Client
-   Identifier: Authority Key Identifier
-    Critical: no
-    Key Identifier:
-     f2:f2:06:59:90:18:47:51:f5:89:33:5a:31:7a:e6:5c:fb:36:
-     26:c9
-  Signature:
-   Algorithm: PKCS #1 MD5 With RSA Encryption
-   Signature:
-    6d:23:af:f3:d3:b6:7a:df:90:df:cd:7e:18:6c:01:69:8e:54:65:fc:06:
-    30:43:34:d1:63:1f:06:7d:c3:40:a8:2a:82:c1:a4:83:2a:fb:2e:8f:fb:
-    f0:6d:ff:75:a3:78:f7:52:47:46:62:97:1d:d9:c6:11:0a:02:a2:e0:cc:
-    2a:75:6c:8b:b6:9b:87:00:7d:7c:84:76:79:ba:f8:b4:d2:62:58:c3:c5:
-    b6:c1:43:ac:63:44:42:fd:af:c8:0f:2f:38:85:6d:d6:59:e8:41:42:a5:
-    4a:e5:26:38:ff:32:78:a1:38:f1:ed:dc:0d:31:d1:b0:6d:67:e9:46:a8:
-    d:c4
-
- -

Here is the same certificate displayed in the 64-byte-encoded form interpreted by software:

- -

- -----BEGIN CERTIFICATE-----
- MIICKzCCAZSgAwIBAgIBAzANBgkqhkiG9w0BAQQFADA3MQswCQYDVQQGEwJVUzER
- MA8GA1UEChMITmV0c2NhcGUxFTATBgNVBAsTDFN1cHJpeWEncyBDQTAeFw05NzEw
- MTgwMTM2MjVaFw05OTEwMTgwMTM2MjVaMEgxCzAJBgNVBAYTAlVTMREwDwYDVQQK
- EwhOZXRzY2FwZTENMAsGA1UECxMEUHViczEXMBUGA1UEAxMOU3Vwcml5YSBTaGV0
- dHkwgZ8wDQYJKoZIhvcNAQEFBQADgY0AMIGJAoGBAMr6eZiPGfjX3uRJgEjmKiqG
- 7SdATYazBcABu1AVyd7chRkiQ31FbXFOGD3wNktbf6hRo6EAmM5/R1AskzZ8AW7L
- iQZBcrXpc0k4du+2Q6xJu2MPm/8WKuMOnTuvzpo+SGXelmHVChEqooCwfdiZywyZ
- NMmrJgaoMa2MS6pUkfQVAgMBAAGjNjA0MBEGCWCGSAGG+EIBAQQEAwIAgDAfBgNV
- HSMEGDAWgBTy8gZZkBhHUfWJM1oxeuZc+zYmyTANBgkqhkiG9w0BAQQFAAOBgQBt
- I6/z07Z635DfzX4XbAFpjlRl/AYwQzTSYx8GfcNAqCqCwaSDKvsuj/vwbf91o3j3
- UkdGYpcd2cYRCgKi4MwqdWyLtpuHAH18hHZ5uvi00mJYw8W2wUOsY0RC/a/IDy84
- hW3WWehBUqVK5SY4/zJ4oTjx7dwNMdGwbWfpRqjd1A==
- -----END CERTIFICATE-----
- 
-
- -

如何使用CA证书建立信任

- -

证书颁发机构(CA)是验证身份并颁发证书的实体。它们可以是独立的第三方,也可以是运行自己的证书颁发服务器软件的组织。

- -

任何支持证书的客户端或服务器软件都维护一组受信任的CA证书。 这些CA证书确定软件可以验证哪些其他证书,换句话说,软件可以信任哪些证书的颁发者。 在最简单的情况下,软件只能验证由其中一个拥有证书的CA颁发的证书。 受信任的CA证书也可能是CA证书链的一部分,每个证书链都是由其上面的CA在证书层次结构中颁发的。

- -

以下各节说明了证书层次结构和证书链如何确定软件可以信任哪些证书。

- - - -

CA Hierarchies

- -

在大型组织中,可以将颁发证书的责任委派给多个不同的证书颁发机构。 例如,所需的证书数量可能太多,单个CA无法维护; 不同的组织单元可能有不同的政策要求;或者,对于CA来说,其实际位置可能与它向其颁发证书的人位于同一地理区域中是很重要的。

- -

可以将颁发证书的职责委托给下级CA。X.509标准包括一个用于建立如图6所示的CA层次结构的模型。

- -

Figure 6. Example of a Hierarchy of Certificate Authorities

- -

在这个模型中,根CA位于层次结构的顶部。 根CA的证书是一个自签名证书:也就是说,该证书由证书标识的根CA所在的同一实体进行数字签名。 直接隶属于根CA的CA具有由根CA签名的CA证书。 层次结构中下级CA下的CA的CA证书由上级下级CA签名。

- -

组织在建立CA层次结构方面有很大的灵活性。 图6只显示了一个示例;还有许多其他安排是可能的。

- -

Certificate Chains

- -

CA层次结构反映在证书链中。 证书链是由连续的ca颁发的一系列证书。图7显示了一个证书链,从通过两个从属CA证书标识某个实体的证书到根CA的CA证书(基于图6所示的CA层次结构)。

- -

Figure 7. Example of a Certificate Chain

- -

证书链跟踪证书从层次结构中的分支到层次结构的根的路径。 I在证书链中,会发生以下情况:

- - - -

在图7中,工程CA证书包含颁发该证书的CA(即USA CA)的DN。 USA CA的DN也是链中下一个证书的使用者名称。

- - - -

在图7中,美国CA证书中的公钥可用于验证美国CA在工程CA证书上的数字签名。

- -

Verifying a Certificate Chain

- -

Certificate chain verification is the process of making sure a given certificate chain is well-formed, valid, properly signed, and trustworthy. Red Hat software uses the following procedure for forming and verifying a certificate chain, starting with the certificate being presented for authentication:

- -
    -
  1. The certificate validity period is checked against the current time provided by the verifier's system clock.
  2. -
  3. The issuer's certificate is located. The source can be either the verifier's local certificate database (on that client or server) or the certificate chain provided by the subject (for example, over an SSL connection).
  4. -
  5. The certificate signature is verified using the public key in the issuer's certificate.
  6. -
  7. If the issuer's certificate is trusted by the verifier in the verifier's certificate database, verification stops successfully here. Otherwise, the issuer's certificate is checked to make sure it contains the appropriate subordinate CA indication in the Red Hat certificate type extension, and chain verification returns to step 1 to start again, but with this new certificate. Figure 8 presents an example of this process.
  8. -
- -

Figure 8. Verifying a Certificate Chain All the Way to the Root CA

- -

Figure 8 shows what happens when only Root CA is included in the verifier's local database. If a certificate for one of the intermediate CAs shown in Figure 8, such as Engineering CA, is found in the verifier's local database, verification stops with that certificate, as shown in Figure 9.

- -

Figure 9. Verifying a Certificate Chain to an Intermediate CA

- -

Expired validity dates, an invalid signature, or the absence of a certificate for the issuing CA at any point in the certificate chain causes authentication to fail. For example, Figure 10 shows how verification fails if neither the Root CA certificate nor any of the intermediate CA certificates are included in the verifier's local database.

- -

Figure 10. A Certificate Chain That Can't Be Verified

- -

For general information about the way digital signatures work, see "Digital Signatures". For a more detailed description of the signature verification process in the context of SSL client and server authentication, see "Introduction to SSL."

- -

Managing Certificates

- -

从加密电子邮件到访问网站,许多应用程序都使用证书。 证书的生命周期分为两个主要阶段:颁发证书的时间点(颁发和注册)和证书不再有效的时间段(续订或吊销)。 还有一些方法可以在证书的生命周期中对其进行管理。 使有关证书的信息可用于其他应用程序是发布证书,然后备份密钥对,以便在证书丢失时可以恢复。

- - - -

颁发证书

- -

颁发证书的过程取决于颁发证书的证书颁发机构及其使用目的。 签发非数字身份证明的程序也有类似的变化。 例如,如果你想从加州机动车辆管理局(Department of Motor Vehicles in California)拿到一张普通身份证(而不是驾照),要求很简单:你需要出示一些身份证明,比如一张写有你地址的公用事业账单和一张学生身份证。 如果你想获得一张正规的驾驶执照,你还需要参加一次考试——第一次拿到驾照时要参加一次驾驶考试,续签驾照时要参加一次笔试。 如果你想得到一个18轮的商业许可证,要求要严格得多。 如果您居住在其他州或国家,对各种许可证的要求将有所不同。

- -

同样,不同的ca对于颁发不同类型的证书有不同的过程。 在某些情况下,唯一的要求可能是你的电子邮件地址。在其他情况下,您的UNIX或Windows登录名和密码可能就足够了。 在比额表的另一端,对于证明可以批准大额支出或作出其他敏感决定的人的证书,签发过程可能需要公证文件、背景调查和个人面谈。

- -

根据组织的策略,颁发证书的过程可以从对用户完全透明到需要大量用户参与和复杂的过程不等。 一般来说,颁发证书的过程应该高度灵活,因此组织可以根据其不断变化的需要对其进行调整。

- -

颁发证书是可以由单独的注册机构处理的几种管理任务之一。

- -

证书和LDAP目录

- -

The Lightweight Directory Access Protocol (LDAP) for accessing directory services supports great flexibility in the management of certificates within an organization. System administrators can store much of the information required to manage certificates in an LDAP-compliant directory. For example, a CA can use information in a directory to prepopulate a certificate with a new employee's legal name and other information. The CA can leverage directory information in other ways to issue certificates one at a time or in bulk, using a range of different identification techniques depending on the security policies of a given organization. Other routine management tasks, such as key management and renewing and revoking certificates, can be partially or fully automated with the aid of the directory.

- -

Information stored in the directory can also be used with certificates to control access to various network resources by different users or groups. Issuing certificates and other certificate management tasks can thus be an integral part of user and group management.

- -

In general, high-performance directory services are an essential ingredient of any enterprise certificate management strategy.

- -

密钥管理

- -

在颁发证书之前,必须生成证书中包含的公钥和相应的私钥。 有时,为一个人颁发一个证书和密钥对(用于签名操作)和另一个证书和密钥对(用于加密操作)可能是有用的。单独的签名和加密证书使得只在本地计算机上保留私有签名密钥成为可能,从而提供最大的不可否认性,并在某个中心位置备份私有加密密钥,在用户丢失原始密钥或离开公司时可以在该位置检索该密钥。

- -

密钥可以由客户端软件生成,也可以由CA集中生成,并通过LDAP目录分发给用户。 在本地密钥生成和集中密钥生成之间进行选择时需要权衡。例如,本地密钥生成提供了最大的不可否认性,但可能需要用户更多地参与发布过程。灵活的密钥管理能力对于大多数组织来说是必不可少的。

- -

密钥恢复,或者在精心定义的条件下检索加密密钥备份的能力,可能是证书管理的关键部分(取决于组织如何使用证书)。Key recovery schemes usually involve an m of n mechanism: for example, m of n managers within an organization might have to agree, and each contribute a special code or key of their own, before a particular person's encryption key can be recovered. 这种机制确保在恢复加密密钥之前,必须有几个授权人员同意。

- -

Renewing and Revoking Certificates

- -

Like a driver's license, a certificate specifies a period of time during which it is valid. Attempts to use a certificate for authentication before or after its validity period will fail. Therefore, mechanisms for managing certificate renewal are essential for any certificate management strategy. For example, an administrator may wish to be notified automatically when a certificate is about to expire, so that an appropriate renewal process can be completed in plenty of time without causing the certificate's subject any inconvenience. The renewal process may involve reusing the same public-private key pair or issuing a new one.

- -

A driver's license can be suspended even if it has not expired-for example, as punishment for a serious driving offense. Similarly, it's sometimes necessary to revoke a certificate before it has expired-for example, if an employee leaves a company or moves to a new job within the company.

- -

Certificate revocation can be handled in several different ways. For some organizations, it may be sufficient to set up servers so that the authentication process includes checking the directory for the presence of the certificate being presented. When an administrator revokes a certificate, the certificate can be automatically removed from the directory, and subsequent authentication attempts with that certificate will fail even though the certificate remains valid in every other respect. Another approach involves publishing a certificate revocation list (CRL)-that is, a list of revoked certificates-to the directory at regular intervals and checking the list as part of the authentication process. For some organizations, it may be preferable to check directly with the issuing CA each time a certificate is presented for authentication. This procedure is sometimes called real-time status checking.

- -

Registration Authorities

- -

由证书标识的实体(有时称为最终实体)和ca之间的交互是证书管理的一个重要部分。 这些交互包括证书注册、证书检索、证书续订、证书吊销以及密钥备份和恢复等操作。一般来说,CA必须能够在响应请求之前验证最终实体的身份。 此外,有些请求需要经过授权的管理员或经理的批准才能提供服务。

- -

如前所述,不同的ca在颁发证书之前用于验证身份的方法可能有很大的不同,这取决于证书的使用组织和目的。 为了提供最大的操作灵活性,与终端实体的交互可以与CA的其他功能分离,并由一个称为注册机构(RA)的单独服务处理。

- -

An RA acts as a front end to a CA by receiving end entity requests, authenticating them, and forwarding them to the CA. After receiving a response from the CA, the RA notifies the end entity of the results. RAs can be helpful in scaling an PKI across different departments, geographical areas, or other operational units with varying policies and authentication requirements.

- -
-

Original Document Information

- - -
diff --git a/files/zh-cn/archive/web/e4x/index.html b/files/zh-cn/archive/web/e4x/index.html deleted file mode 100644 index af364a3208..0000000000 --- a/files/zh-cn/archive/web/e4x/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: E4X -slug: Archive/Web/E4X -translation_of: Archive/Web/E4X ---- -
-

已废弃
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.

-
-  
-
-
-

Warning: E4X已经过时.从Firefox 17开始,E4X在普通网页中被默认禁用,从Firefox 20开始,E4X在浏览器界面中被默认禁用,从Firefox 21开始,E4X被完全删除.使用DOMParser/DOMSerializer或者其他算法来代替.

-
-

ECMAScript for XML (E4X) is a programming language extension that adds native XML support to JavaScript. It does this by providing access to the XML document in a form that feels natural for ECMAScript programmers. The goal is to provide an alternative, simpler syntax for accessing XML documents than via DOM interfaces. A valid alternative to E4X is a non-native JXON algorithm.

-

E4X is standardized by Ecma International in ECMA-357 standard (currently in its second edition, December 2005).

-

E4X is implemented (at least partially) in SpiderMonkey (Gecko's JavaScript engine) and in Rhino (JavaScript engine written in Java).

-

 

-
- Note: In Gecko 1.8 based browsers such as Firefox 1.5, E4X is already partially enabled for web page authors. To fully enable E4X, the <script> element needs to have the MIME type "text/javascript;e4x=1" (i.e. have an attribute of the form type="text/javascript;e4x=1"). The difference between the two modes is that without the "e4x=1" MIME type, any statement-level XML/HTML comment literals (<!--...-->) are ignored for backwards compatibility with the comment hiding trick, and CDATA sections (<![CDATA[...]]>) are not parsed as CDATA literals (which leads to a JS syntax error in HTML since HTML's <script> element produces an implicit CDATA section, and therefore cannot contain explicit CDATA sections). -

someone verify the above

-
-

已经的bug和限制

- -

Workaround:

-
var response = xmlhttprequest.responseText; // bug 270553
-response = response.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, ""); // bug 336551
-var e4x = new XML(response);
-
-

资源

- -

相关链接

- diff --git a/files/zh-cn/archive/web/e4x_tutorial/accessing_xml_children/index.html b/files/zh-cn/archive/web/e4x_tutorial/accessing_xml_children/index.html deleted file mode 100644 index 16b4cf8139..0000000000 --- a/files/zh-cn/archive/web/e4x_tutorial/accessing_xml_children/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Accessing XML children -slug: Archive/Web/E4X_tutorial/Accessing_XML_children -translation_of: Archive/Web/E4X_tutorial/Accessing_XML_children ---- -

访问 XML 子节点

-

JavaScript 对象通常使用 . 或 [] 来设置性质。

-
var a = {};
-a.foo = 1;
-a["bar"] = 2;
-

在 E4X 中,点(.)和中括号([])操作符用来访问 E4X 元素的子节点。

-
var element1 = <foo>
-                 <bar/>
-               </foo>;
-var element2 = <baz/>;
-element1.bar.appendChild(element2);
-element1["bar"].appendChild(<quux/>);
-

往 element1 中的 bar 节点添加子节点,生成如下 XML 文档:

-

<foo>
-   <bar>
-     <baz/>
-     <quux/>
-   </bar>
- </foo>

-

但是要注意,给一个不存在的子元素赋值会创建这个元素。

-
var element1 = <foo/>
-element1.bar = 1;
-

生成

-

<foo>
-   <bar>1</bar>
- </foo>

-

如果子节点已经存在,点(.)操作符允许你更改它的值。

-
var elem = <foo>
-             <bar>1</bar>
-           </foo>
-elem.bar = 2;
-

会将原来的值 1 改成 2。

-

你可以用 delete 命令删除一个子节点。

-
var elem = <foo>
-             <bar/>
-             <baz/>
-           </foo>
-delete elem.bar;
-

只剩下

-

<foo>
-   <baz/>
- </foo>

-

点(.)操作符还能用于替换特定的子节点。

-
var elem1 = <foo>
-              <bar/>
-            </foo>;
-var elem2 = <red>
-              <blue/>
-            </red>;
-elem1.bar = elem2;
-

用 elem2 的全部内容替换 <bar/> 元素。

-

<foo>
-   <red>
-     <blue/>
-   </red>
- <foo>

-

XML 列表

-

许多时候,一个元素会有两个或多个相同类型的子节点。在这种情况下,访问 foo.bar 将返回一个XML 列表对象,包含所有类型为“bar”的子节点。注意:在使用 . 操作符时,判断它是返回单个元素还是一个 XML 列表,这是你的责任。在返回这些性质时,E4X 的行为并没有区别。

-

XML 列表的行为就像是一个数组。

-
var element = <foo>
-                <bar baz="1">red</bar>
-                <bar baz="2">blue</bar>
-              </foo>;
-var list = element.bar;
-list.length(); // returns 2
-list[0]; // the first bar element
-list[1]; // the second bar element
-
-

需要注意,这个列表时可修改的,在它上面做的修改都会反映到原始的 XML 文档中。

-
list[1] = "green";
-

XML 文档被修改为:

-

<foo>
-   <bar baz="1">red</bar>
-   <bar baz="2">green</bar>
- </foo>

-

特殊类型的节点

-

XML 对象有一些方法可以访问 XML 列表中的通用类型节点。

-
var a = <foo> Some text <bar>not text</bar> More text </foo>;
-var list = a.text();
-list.length(); // returns 2
-list[0]; // returns " Some text "
-list[1]; // returns " More text "
-

你同样可以访问注释节点:

-
XML.ignoreComments = false;
-var a = <foo> Some  <!-- abc --> text </foo>;
-var comments = a.comments();
-alert(comments[0]); // Returns <!-- abc -->
-

星号(*)选择器将返回 XML 列表的所有子节点。

-
var a = <foo>
-          <bar/>
-          <baz/>
-        </foo>;
-var list = a.*;
-list.length(); // returns 2
-
-

元素属性

-

很多 XML 元素都有赋有特定值的属性。例如:

-

<pets>
-   <dog color="brown">Fido</dog>
-   <cat color="grey">Fluffy</cat>
- </pets>

-

E4X 运行你用 .@ 操作符来反问这些特定元素的属性。最基本的情况如下例所示:

-
 var element = <foo bar="1"/>
- element.@bar = 2;
-

它将生成:

-

<foo bar="2"/>

diff --git a/files/zh-cn/archive/web/e4x_tutorial/descendants_and_filters/index.html b/files/zh-cn/archive/web/e4x_tutorial/descendants_and_filters/index.html deleted file mode 100644 index fbf89a871f..0000000000 --- a/files/zh-cn/archive/web/e4x_tutorial/descendants_and_filters/index.html +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Descendants and Filters -slug: Archive/Web/E4X_tutorial/Descendants_and_Filters -translation_of: Archive/Web/E4X_tutorial/Descendants_and_Filters ---- -

访问后代节点

-

很多时候,你感兴趣的节点往往不是 XML 根节点的子节点,而是嵌套在多层下的后代节点。你可以使用 .. 操作符访问任意深度的节点,或者使用 descendants 性质。例如:

-
var element = <pets>
-                <dogs>
-                  <fido color="red"/>
-		  <spike color="blue"/>
-		</dogs>
-              </pets>;
-element..fido.@color = "green";
-element..spike.@color = "purple";
-
-

两只宠物狗的颜色都做了改变。

-

点(.)操作符的所有规则都适用于 .. 操作符。那就是说,如果有多个请求的类型,就会返回一个 XML 后代的列表。星号(*)选择器会返回 XML 列表的所有后代。

-

过滤器

-

在很多情况下,尤其是用 * 选择器时,你并不想要处理 . 或 .. 操作符返回的所有节点。为了只处理其中特定的子集,可以将筛选条件放到 . 操作符后面的圆括号里。

-
var element = <dogs>
-                <fido color="brown"/>
-                <spike color="black"/>
-                <killer color="brown"/>
-              </dogs>;
-var list = element.*.(@color == "brown");
-

本来,element.* 返回一个包含三只狗的列表。但其中只有 fido 和 killer 的颜色是褐色的。因此,该过来条件创建了一个只包含 fido 和 killer 的列表。

diff --git a/files/zh-cn/archive/web/e4x_tutorial/index.html b/files/zh-cn/archive/web/e4x_tutorial/index.html deleted file mode 100644 index 4dac9ce0e8..0000000000 --- a/files/zh-cn/archive/web/e4x_tutorial/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: E4X教程 -slug: Archive/Web/E4X_tutorial -translation_of: Archive/Web/E4X_tutorial ---- -

-

下一页 »

-

- -
-

警告:E4X已废弃。 默认情况下,Firefox 16中的内容将禁用它,Firefox 17中的Chrome默认禁用,Firefox 18中将其删除。请使用DOMParser / DOMSerializer或非本机JXON算法。

-
- -

概述

- -

本教程带你走入E4X (EcmaScript for XML)基本语法. 通过使用E4X,程序员可以通过一个类似JavaScript编程的语法来操作XML文档。

- -

科目

- - - -

另请参阅

- - - -

-

下一页 »

-

- -

diff --git a/files/zh-cn/archive/web/e4x_tutorial/introduction/index.html b/files/zh-cn/archive/web/e4x_tutorial/introduction/index.html deleted file mode 100644 index 2c0a2f7a76..0000000000 --- a/files/zh-cn/archive/web/e4x_tutorial/introduction/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Introduction -slug: Archive/Web/E4X_tutorial/Introduction -tags: - - E4X - - JavaScript - - Tutorial -translation_of: Archive/Web/E4X_tutorial/Introduction ---- -

基本语法

-

如果启用了 E4X,基本的 XML 元素就是有效的语法。例如:

-
var element = <foo/>
-    
-

在开启了 E4X 的浏览器里完全有效。

-

变量的声明也不局限于单个元素,并且和 JavaScript 一样可以扩多行。

-
var element2 = <foo>
-                     <bar/>
-               </foo>
-
-

此外,和一般的 XML 文档一样,你能给一个元素指定属性。

-
var element3 = <foo baz="1"/>
-    
-

操作元素

-

E4X 的目标是为 JavaScript 程序员提供一个简单的方法来操作 XML 文档,而无需通过 DOM 接口。不过,很多你在 DOM 中用过的函数也能用到 E4X 中。最基本的就是 appendChild:

-
var element1 = <foo/>
-var element2 = <bar/>
-element1.appendChild(element2);
-
-

它会产生你期望的正确的 XML 文档:

-

<foo>
-   <bar/>
- </foo>

-

JavaScript 变量

-

当 XML 文档需要和 JavaScript 做紧密交互时,E4X 真正强大的地方才得以彰显。通过特定的语法,我们能将 JavaScript 变量的值赋给 E4X 元素。这是用大括号({})标记。

-
var a = 2;
-var b = <foo>{a}</foo>;
-
-

创建了一段 XML 文档,内容为 <foo>2</foo>。

-

你也可以将大括号标记用于元素的属性(名字或值)。例如:

-
var a = 2;
-var b = 'bar';
-var c = <foo {b}={a}>"hi"</foo>;
-

创建的 XML 稍有不同:<foo bar="2">"hi"</foo>。

-

注意:XML 元素只接受文本作为他们的值。大括号标记真正发生的是调用变量的 toString 方法,并将返回值填到相应位置。例如:

-
var a = {foo: 1};
-var b = <bar>{a}</bar>
-

实际上产生的文档是 <bar>[object Object]</bar>。

-

在内容中使用内联函数

-

虽然大括号限定执行单条语句,但通过匿名函数内联可以执行一些额外的处理:

-
var a = 'foo';
-var b = <bar>{function () {var c = a.toUpperCase(); var d = 5 * 5; return c + d;}()}</bar>
-

上述代码产生:<bar>FOO25</bar>

-

该用法更多的讨论请参加 E4X for templating

-

序列化

-

E4X 最强大的工具就是简单地调用 .toXMLString() 就可以将整个 XML 文档(或其中部分)序列化到字符串中。

-
var element1 = <foo/>;
-var element2 = <bar/>;
-element1.apppendChild(element2);
-element1.toXMLString();
-

输出为:

-

<foo>
-   <bar/>
- </foo>

-

本例使用 toString() 也能达到相同效果,不过在一个只有文本内容的元素上调用 toString() 将之产生文本内容(例如,<foo>abc</foo>.toString(); 会只产生 'abc')。

diff --git a/files/zh-cn/archive/web/e4x_tutorial/namespaces/index.html b/files/zh-cn/archive/web/e4x_tutorial/namespaces/index.html deleted file mode 100644 index 8a2fc96063..0000000000 --- a/files/zh-cn/archive/web/e4x_tutorial/namespaces/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Namespaces -slug: Archive/Web/E4X_tutorial/Namespaces -translation_of: Archive/Web/E4X_tutorial/Namespaces ---- -

E4X 与 命令空间

-

通常情况下,XML 文档包含来自多种命令空间的元素。你可以通过声明为你的 E4X 对象设置默认的命名空间。

-
default xml namespace = "http://www.w3.org/1999/xhtml";
-
-

通过重复的声明,你可以随时更改相同范围内 E4X 的命名空间。

-
default xml namespace = "http://www.w3.org/1999/xhtml";
-var a = <p>Some text</p>;
-default xml namespace = "http://www.mozilla.org/keymaster/gat...re.is.only.xul";
-var b = <label>More text</label>;
-a.appendChild(b);
-
-

得出

-

<p xmlns="http://www.w3.org/1999/xhtml">
-   Some text
-   <label xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul">More text</label>
- </p>

-

name()

-

在 XML 对象上调用 name() 会返回一个 QName 对象(Qualified Name)。QName 在支持 E4X 的 JavaScript 实现中是一个全局的构造函数。QName 对象有两个特别重要的属性:localName 返回元素的名字,且没有任何命名空间前缀;uri 返回元素所在的命名空间。

-
var info = a.name();
-info.localName; // returns 'p'.
-info.uri; // returns "http://www.w3.org/1999/xhtml"
-

没有在任何命令空间的元素,他们的 uri 是一个空字符串。

-

Namespace 全局构造函数和 QName 非常相似。Namespace 的不同之处是 toString 方法,以及 Namespace 用 prefix 属性来代替 localName 属性[1]

-

关于 E4X 的命名空间,更多的内容请参见 Processing XML with E4X

-

译者注

-
    -
  1. 原文中没有详细讲,获得 Namespace 对象的方法是调用 .namespace()。其中 QName 的 toString 方法会输出 Namespace::name 的形式,而 Namespace 的 toString 只会输出命名空间。
  2. -
diff --git a/files/zh-cn/archive/web/e4x_tutorial/the_global_xml_object/index.html b/files/zh-cn/archive/web/e4x_tutorial/the_global_xml_object/index.html deleted file mode 100644 index 910b422ada..0000000000 --- a/files/zh-cn/archive/web/e4x_tutorial/the_global_xml_object/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: The global XML object -slug: Archive/Web/E4X_tutorial/The_global_XML_object -translation_of: Archive/Web/E4X_tutorial/The_global_XML_object ---- -

全局 XML 对象

-

E4X-capable JavaScript 引擎在全局对象上放了一个新的属性。XML 对象有许多属性允许你定制解析和序列化 E4X。XML 元素从他们创建开始就记住 XML 对象的设置。

-

扩展 XML.prototype

-

XML.prototype 和 XMLList.prototype(XMLList.prototype 实际上就是 XML.prototype)不能像其他构造器(例如 Object)一样扩展。你只能在 XML.prototype 里定义方法,而不能定义字段。要向 XML.prototype 添加一个方法,则要定义 XML.prototype.function::methodName 或 XML.prototype.funciton::[methodNameString]。下例定义 fooCount() 方法,返回 XML 中 <foo> 元素的个数:

-

 

-
XML.prototype.function::fooCount = function fooCount() {
-  return this..foo.length();
-};
-<foobar><foo/><foo/><foo/></foobar>.fooCount() // returns 3
-

 

-

ignoreComments

-

默认为 true。该属性告诉 E4X 在序列化和筛选时忽略注释节点。即当 ignoreComments 为 ture 时 .comments() 返回空。观察如下例子:

-

 

-
var element = <foo>
-                <!-- my comment -->
-                <bar/>
-              </foo>;
-element.comments().length(); // returns 0
-element.toXMLString(); // returns <foo><bar/></foo>
-XML.ignoreComments = false;
-element = <foo>
-            <!-- my comment -->
-            <bar/>
-          </foo>;
-element.comments().length(); // returns 1
-element.toXMLString(); // returns <foo><!-- my comment --><bar/></foo>
-

 

-

ignoreProcessingInstructions

-

默认为 ture。该属性告诉 E4X 在序列化和筛选时忽略 XML 中的处理指令。例如:

-

 

-
var element = <foo>
-                <?process x="true"?>
-                <bar/>
-                <?process x="false"?>
-              </foo>;
-element.toXMLString(); // returns <foo><bar/></foo>
-XML.ignoreProcessingInstructions = false;
-var element = <foo>
-                <?process x="true"?>
-                <bar/>
-                <?process x="false"?>
-              </foo>;
-element.toXMLString(); // returns <foo><?process x="true"?><bar/><?process x="false"?></foo>
-

 

-

ignoreWhitespace

-

默认为 true。忽略节点之间以及节点文本头尾两端的空白,而其他的则被解析为文本节点或作为文本节点的一部分。

-

prettyPrinting

-

默认是 true。为 true 时,toXMLString() 序列化 E4X 对象时会包含换行和缩进。

-

prettyIndent

-

默认值是 2。代表 XML 树每层缩进的空格数。如果 prettyPrinting 是 false 则忽略。

diff --git a/files/zh-cn/archive/web/index.html b/files/zh-cn/archive/web/index.html deleted file mode 100644 index a6edb0c862..0000000000 --- a/files/zh-cn/archive/web/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Archived open Web documentation -slug: Archive/Web -tags: - - Archived - - NeedsTranslation - - TopicStub - - Web -translation_of: Archive/Web ---- -

The documentation listed below is archived, obsolete material about open Web topics.

-

E4X
ECMAScript for XML (E4X) is a programming language extension that adds native XML support to JavaScript. It does this by providing access to the XML document in a form that feels natural for ECMAScript programmers. The goal is to provide an alternative, simpler syntax for accessing XML documents than via DOM interfaces. A valid alternative to E4X is a non-native JXON algorithm.
E4X教程
本教程带你走入E4X (EcmaScript for XML)基本语法. 通过使用E4X,程序员可以通过一个类似JavaScript编程的语法来操作XML文档。
LiveConnect概述
这一章描述了使用 LiveConnect  技术来使JavaScript和Java能够互相通信。本章假设你熟悉Java编程。

diff --git a/files/zh-cn/archive/web/indexeddb_api_using_javascript_generators_in_firefox/index.html b/files/zh-cn/archive/web/indexeddb_api_using_javascript_generators_in_firefox/index.html deleted file mode 100644 index 33fb51b750..0000000000 --- a/files/zh-cn/archive/web/indexeddb_api_using_javascript_generators_in_firefox/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: 在 Firefox 中使用 JavaScript Generators -slug: Archive/Web/IndexedDB_API_Using_JavaScript_Generators_in_Firefox -translation_of: Archive/Web/IndexedDB_API_Using_JavaScript_Generators_in_Firefox ---- -
警告: 此项技术仅对 Firefox 浏览器生效,而对 IE、 Chrome、 Safari 等浏览器无效。
- -

生成器(generators)可用于简化 Firefox 浏览器中的异步代码,需使用 JavaScript 1.7 或更高版本。 您可以按下列方式引入 HTML:

- -
<script type="text/javascript;version=1.7" src="myScript.js"></script>
- -

一个 myScript.js 文件可能是像这样的:

- -
// 需要将生成器(generator)存储在全局变量中。
-var generator;
-
-// 通过简单的事件侦听器将接收到的事件传递给生成器。
-function grabEvent(event) {
-  generator.send(event);
-}
-
-// 关闭生成器,但必须在生成器外部进行,所以我们使用 setTimeout 函数
-function closeGenerator() {
-  setTimeout(function() {
-    generator.close();
-  }, 0);
-}
-
-// 主函数
-function databaseOperation() {
-  mozIndexedDB.open("MyTestDatabase").onsuccess = grabEvent;
-  var event = yield;
-
-  var db = event.target.result;
-
-  if (db.version != "1.0") {
-    db.setVersion("1.0").onsuccess = grabEvent;
-    event = yield;
-
-    var transaction = event.transaction;
-    db.createObjectStore("stuff");
-
-    transaction.oncomplete = grabEvent;
-    yield;
-  }
-
-  db.transaction(["stuff"]).objectStore("stuff").get("foo").onsuccess = grabEvent;
-  event = yield;
-
-  alert("Got result: " + event.target.result);
-
-  // 完成。
-  closeGenerator();
-
-  // 始终在末尾额外使用一次 yield ,否则您将看到 StopIteration 异常。
-  yield;
-}
-
-generator = databaseOperation();
-generator.next();
diff --git a/files/zh-cn/archive/web/javascript/handler.enumerate/index.html b/files/zh-cn/archive/web/javascript/handler.enumerate/index.html deleted file mode 100644 index 9a68adbf65..0000000000 --- a/files/zh-cn/archive/web/javascript/handler.enumerate/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: handler.enumerate() -slug: Archive/Web/JavaScript/handler.enumerate -translation_of: Archive/Web/JavaScript/handler.enumerate ---- -
{{JSRef}} {{obsolete_header}}
- -

代理方法handler.enumerate()决定了被代理对象在{{jsxref("Statements/for...in", "for...in")}}中的行为。不过这个方法已经在ES2016标准中被移除了。

- -

语法

- -
var p = new Proxy(target, {
-  enumerate(target) {
-  }
-});
-
- -

参数

- -

下列参数将会被用以调用 enumerate 方法。this将会指向处理器对象。

- -
-
target
-
被代理的目标对象。
-
- -

Return value

- -

该方法应当返回一个迭代器对象。

- -

描述

- -

handler.enumerate 方法决定了被代理对象在{{jsxref("Statements/for...in", "for...in")}}时的行为。

- -

触发条件

- -

这些操作可以触发这个方法。

- - - -

Invariants

- -

If the following invariants are violated, the proxy will throw a {{jsxref("TypeError")}}:

- - - -

Examples

- -

The following code traps {{jsxref("Statements/for...in", "for...in")}} statements.

- -
var p = new Proxy({}, {
-  enumerate(target) {
-    console.log('called');
-    return ['a', 'b', 'c'][Symbol.iterator]();
-  }
-});
-
-for (var x in p) { // "called"
-  console.log(x);  // "a"
-}                  // "b"
-                   // "c"
-
- -

The following code violates the invariant.

- -
var p = new Proxy({}, {
-  enumerate(target) {
-    return 1;
-  }
-});
-
-for (var x in p) {} // TypeError is thrown
-
- -

Note: Both examples make use of the shorthand syntax for method definitions.

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-enumerate', '[[Enumerate]]')}}{{Spec2('ES2015')}}Initial definition. Removed in ECMAScript 2016.
- -

Browser compatibility

- -
- - -

{{Compat("javascript.builtins.Proxy.handler.enumerate")}}

-
- -

See also

- - diff --git a/files/zh-cn/archive/web/javascript/index.html b/files/zh-cn/archive/web/javascript/index.html deleted file mode 100644 index 4687b7bf23..0000000000 --- a/files/zh-cn/archive/web/javascript/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: JavaScript -slug: Archive/Web/JavaScript -translation_of: Archive/Web/JavaScript ---- - - -

{{Obsolete_Header}}

- -

Obsolete JavaScript features and unmaintained docs

- -

{{SubpagesWithSummaries}}

diff --git a/files/zh-cn/archive/web/javascript/legacy_generator_function/index.html b/files/zh-cn/archive/web/javascript/legacy_generator_function/index.html deleted file mode 100644 index d4d213cc98..0000000000 --- a/files/zh-cn/archive/web/javascript/legacy_generator_function/index.html +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: 旧式生成器函数 -slug: Archive/Web/JavaScript/Legacy_generator_function -tags: - - 生成器函数 -translation_of: Archive/Web/JavaScript/Legacy_generator_function ---- -
.旧式生成器函数是一个SpiderMonkey专有特性,将在未来移除。从未来考虑,建议使用{{jsxref("Operators/function*", "function* 表达式")}}
- -
{{jsSidebar("Operators")}}
- -

function 关键字可以用于在表达式中定义旧式的生成器函数。为使定义的函数为一个旧式的生成器函数,该函数的函数体中需要至少包含一个 {{jsxref("Operators/yield", "yield")}} 表达式。

- -

语法

- -
function [name]([param1[, param2[, ..., paramN]]]) {
-   statements
-}
- -

参数

- -
-
name
-
函数名。 该参数可以被省略, 这种情况下将创建一个匿名函数 (anonymous). 此名字仅可在函数体内部引用。
-
paramN
-
将被传入此函数的一个参数。一个函数可以最多拥有255个参数。
-
statements
-
构成函数体的表达式。在表达式中需要至少包含一个 {{jsxref("Operators/yield", "yield")}} 表达式。
-
- -

描述

- -

关于此语法的用法说明,参见 迭代器 (Iterators) 与生成器 (Generators) 页面。

- -

浏览器兼容性

- -

Supported nowhere

- -

相关链接

- - diff --git a/files/zh-cn/archive/web/javascript/legacy_generator_function_statement/index.html b/files/zh-cn/archive/web/javascript/legacy_generator_function_statement/index.html deleted file mode 100644 index e8c8f209a9..0000000000 --- a/files/zh-cn/archive/web/javascript/legacy_generator_function_statement/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: 遗留的生成器函数 -slug: Archive/Web/JavaScript/Legacy_generator_function_statement -tags: - - JavaScript - - 参考 - - 过时 - - 非标准 -translation_of: Archive/Web/JavaScript/Legacy_generator_function_statement ---- -
{{JSSidebar("Statements")}}{{Non-standard_Header}}{{Obsolete_Header("gecko58")}} -
-

遗留的生成器函数是 SpiderMonkey 专有特性,已在 Firefox 58+ 中被移除。请考虑使用 {{JSxRef("Statements/function*", "function*")}}。

-
- -

遗留的生成器函数声明使用特殊的参数声明遗留的生成器函数。

- -

也可以使用带有 functionBody、至少一个 {{jsxref("Operators/yield", "yield")}} 表达式,和{{jsxref("Operators/Legacy_generator_function", "遗留的生成器函数表达式")}},配合 {{JSxRef("Function")}} 构造器,来定义遗留的生成器函数。

- -

语法

- -
function name([param,[, param,[..., param]]]) {
-   [statements]
-}
-
- -
-
name
-
函数名。
-
- -
-
param
-
传入函数的参数名,一个函数最多有 255 个参数。
-
- -
-
statements
-
构成函数体的语句。应至少含有一个 {{jsxref("Operators/yield", "yield")}} 表达式。
-
- -

描述

- -

用法概述可在迭代器和生成器页面上查看。

- -

浏览器兼容性

-Supported nowhere. - -

参考

- - -
diff --git a/files/zh-cn/archive/web/javascript/microsoft_extensions/activexobject/index.html b/files/zh-cn/archive/web/javascript/microsoft_extensions/activexobject/index.html deleted file mode 100644 index b275c9676b..0000000000 --- a/files/zh-cn/archive/web/javascript/microsoft_extensions/activexobject/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: ActiveXObject -slug: Archive/Web/JavaScript/Microsoft_Extensions/ActiveXObject -translation_of: Archive/Web/JavaScript/Microsoft_Extensions/ActiveXObject ---- -
{{JSRef}}
- -
警告: 该对象是微软的私有拓展名, 只在微软的IE浏览器上支持, 在win8的应用商店下载的其他浏览器应用也不被支持.
- -

ActiveXObject 启用会返回一个自动化对象的引用

- -

这个对象只能用于实例化自动化对象,它没有任何成员对象.

- -

语法 

- -
let newObj = new ActiveXObject(servername, typename[, location])
-
- -

参数

- -
-
servername
-
提供对象的应用程序的名称。
-
typename
-
要创建的对象的类型或类。
-
location {{optional_inline}}
-
要创建对象的网络服务器的名称。
-
- -

备注

- -

自动化服务器提供至少一种类型的对象。例如,文字处理应用程序可以提供应用程序对象、文档对象和工具栏对象。

- -

您可以在HKEY_CLASSES_ROOT注册注册表项中识别主机PC上的servername.typename的值。下面是您可以找到的一些示例,它们要取决于你的电脑安装了哪些程序:

- - - -
-

注意: ActiveX 对象可能会出现安全问题。要使用ActiveXObject, 你可能需要调整IE浏览器的相关安全区域的安全设置。比如说,对于本地局域网,你通常需要将自定义设置更改为"对未标记为可安全执行脚本ActiveX控件执行初始化并执行脚本"。

-
- -

To identify members of an automation object that you can use in your code, you may need to use a COM object browser, such as the OLE/COM Object Viewer, if no reference documentation is available for the Automation object.

- -

To create an Automation object, assign the new ActiveXObject to an object variable:

- -
var ExcelApp = new ActiveXObject("Excel.Application");
-var ExcelSheet = new ActiveXObject("Excel.Sheet");
-
- -

This code starts the application creating the object (in this case, a Microsoft Excel worksheet). Once an object is created, you refer to it in code using the object variable you defined. In the following example, you access properties and methods of the new object using the object variable ExcelSheet and other Excel objects, including the application object and the ActiveSheet.Cells collection.

- -
// Make Excel visible through the Application object.
-ExcelSheet.Application.Visible = true;
-// Place some text in the first cell of the sheet.
-ExcelSheet.ActiveSheet.Cells(1,1).Value = "This is column A, row 1";
-// Save the sheet.
-ExcelSheet.SaveAs("C:\\TEST.XLS");
-// Close Excel with the Quit method on the Application object.
-ExcelSheet.Application.Quit();
-
- -

Requirements

- -

Supported in the following document modes: Quirks, Internet Explorer 6 standards, Internet Explorer 7 standards, Internet Explorer 8 standards, Internet Explorer 9 standards, Internet Explorer 10 standards, Internet Explorer 11 standards. Not supported in Windows 8.x Store apps.

- -
-

Note: Creating an ActiveXObject on a remote server is not supported in Internet Explorer 9 standards mode, Internet Explorer 10 standards mode, Internet Explorer 11 standards mode, and Windows Store apps or later.

-
- -

See also

- - diff --git a/files/zh-cn/archive/web/javascript/microsoft_extensions/date.getvardate/index.html b/files/zh-cn/archive/web/javascript/microsoft_extensions/date.getvardate/index.html deleted file mode 100644 index 3587d44b2d..0000000000 --- a/files/zh-cn/archive/web/javascript/microsoft_extensions/date.getvardate/index.html +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Date.getVarDate() -slug: Archive/Web/JavaScript/Microsoft_Extensions/Date.getVarDate -translation_of: Archive/Web/JavaScript/Microsoft_Extensions/Date.getVarDate ---- -
{{JSRef(“ Global_Objects”,“ Date”)}} {{Non-standard_Header}} {{Obsolete_Header}} -
警告:  仅Internet Explorer支持此方法。
-
- -

getVarDate方法VT_DATE从{{JSxRef(“ Date”)}}对象返回值。

- -

句法

- -
dateObj.getVarDate()
-
- -

参量

- -

必需的  dateObj 引用是一个  Date 对象。

- -

返回值

- -

返回VT_DATE值。

- -

备注

- -

getVarDate()当JavaScript代码与COM对象,ActiveX对象或其他接受并返回VT_DATE格式的日期值的对象交互时,使用此  方法。这些包括Visual Basic和Visual Basic脚本版(VBScript)中的对象。返回值的实际格式取决于区域设置。

- -

要求

- -

在以下文档模式中受支持:怪癖,Internet Explorer 6标准,Internet Explorer 7标准,Internet Explorer 8标准,Internet Explorer 9标准和Internet Explorer 10标准。Windows 8.x商店应用程序不支持。

- -

适用于:  Date对象

- -

也可以看看

- - diff --git a/files/zh-cn/archive/web/javascript/microsoft_extensions/index.html b/files/zh-cn/archive/web/javascript/microsoft_extensions/index.html deleted file mode 100644 index a128cb7caf..0000000000 --- a/files/zh-cn/archive/web/javascript/microsoft_extensions/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: Microsoft JavaScript extensions -slug: Archive/Web/JavaScript/Microsoft_Extensions -tags: - - JavaScript - - 'JavaScript:Microsoft Extensions' - - NeedsTranslation - - Non-standard - - Reference - - TopicStub -translation_of: Archive/Web/JavaScript/Microsoft_Extensions ---- -
{{JSSidebar("Microsoft Extensions")}}{{Non-standard_Header}} -
-

Warning: These APIs will only work in Microsoft applications, and are not on a standards track.

-
-
- -

Microsoft browsers (Internet Explorer, and in a few cases, Microsoft Edge) support a number of special Microsoft extensions to the otherwise standard JavaScript APIs.

- -

Objects

- -
- -
- -

Functions

- -
- -
- -

Statements

- -
- -
- -

Other

- -
- -
- -

See also

- - diff --git a/files/zh-cn/archive/web/javascript/reflect.enumerate/index.html b/files/zh-cn/archive/web/javascript/reflect.enumerate/index.html deleted file mode 100644 index e8eb0bd103..0000000000 --- a/files/zh-cn/archive/web/javascript/reflect.enumerate/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: Reflect.enumerate() -slug: Archive/Web/JavaScript/Reflect.enumerate -translation_of: Archive/Web/JavaScript/Reflect.enumerate ---- -
{{JSRef}} {{obsolete_header}}
- -
Reflect.enumerate()静态方法通常返回目标对象自身和继承的可迭代属性的一个迭代器,在ECMAScript 2016中已被移除,在各浏览器中已被废弃。
- -

语法

- -
Reflect.enumerate(target)
-
- -

参数

- -
-
target
-
获取属性的目标对象。
-
- -

返回值

- -

目标对象自身和继承的可迭代属性的一个迭代器。

- -

Exceptions

- -

 {{jsxref("TypeError")}}, 如果目标不是一个 {{jsxref("Object")}}.

- -

描述

- -

Reflect.enumerate()方法返回目标对象自身和继承的可迭代属性的一个迭代器。

- -

案例

- -

使用 Reflect.enumerate()

- -
var obj = { x: 1, y: 2 };
-
-for (var name of Reflect.enumerate(obj)) {
-  console.log(name);
-}
-// logs "x" and "y"
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-reflect.enumerate', 'Reflect.enumerate')}}{{Spec2('ES2015')}}初始定义。ECMAScript 2016中已移除。
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

参照

- - diff --git a/files/zh-cn/archive/web/liveconnect/index.html b/files/zh-cn/archive/web/liveconnect/index.html deleted file mode 100644 index 34b25bd823..0000000000 --- a/files/zh-cn/archive/web/liveconnect/index.html +++ /dev/null @@ -1,800 +0,0 @@ ---- -title: LiveConnect概述 -slug: Archive/Web/LiveConnect -tags: - - Java - - JavaScript - - LiveConnect - - 高级 -translation_of: Archive/Web/LiveConnect/LiveConnect_Overview ---- -

这一章描述了使用 LiveConnect  技术来使JavaScript和Java能够互相通信。本章假设你熟悉Java编程。

- -

使用包装器(Working with Wrappers)

- -

在JavaScript中,包装器(wrapper)是一个目标语言数据类型的对象,它包装了一个源语言的对象。当使用JavaScript编程的时候,你可以使用包装器(wrapper)对象来访问Java对象的方法和字段;调用包装器(wrapper)的方法或者访问它的属性都会作用在Java对象上。在Java端,JavaScript对象被包装在类netscape.javascript.JSObject的实例中,然后传递给Java。

- -

当Javascript对象被传递给Java,运行时引擎会创建一个JSObject类型的Java包装器(wrapper);当JSObject从Java传递到JavaScript, 运行时引擎将它解包成它原来的JavaScript对象类型。JSObject类提供了一个接口用来调用JavaScript的方法和检测JavaScript的属性。

- -

JavaScript到Java通信

- -

当你引用一个Java包或者类,或者使用Java的对象和数组,你会使用某一个特别的LiveConnect对象。所有访问Java的JavaScript使用下面表格中总结的对象:

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 9.1 LiveConnect对象
对象描述
JavaArray包装了Java数组,从JavaScript代码中访问。
JavaClass引用Java类。
JavaObject包装了Java对象,从JavaScript代码中访问。
JavaPackage引用Java包。
- -

注意: 因为Java是强类型语言,而JavaScript是弱类型的语言,当你使用LiveConnect的时候,JavaScript运行时引擎会将参数值转换为其他语言中的合适数据类型。请参考 Data Type Conversion 来获取完整信息。

- -

在某些情形下,LiveConnect对象的存在是透明的,因为你凭借一定的直觉来和Java交互。例如,你能够通过使用new操作符跟上Java构造器来像下面一样创建一个Java字符串(String)对象,并且将它赋值给JavaScript变量myString:

- -
var myString = new java.lang.String("Hello world");
-
- -

在上面的例子中,变量myString是一个JavaObject,因为它持有一个Java的String对象。作为JavaObject, myString可以获取java.lang.String及其父类java.lang.Object的公有实例方法。这些Java方法在JavaScript中作为JavaObject的方法使用,你可以像下面这样来使用它们:

- -
myString.length(); // returns 11
-
- -

静态成员可以通过JavaClass对象来调用。

- -
alert(java.lang.Integer.MAX_VALUE); //alerts 2147483647
-
- -

包对象

- -

如果一个Java类不是java, sun, 或者netscape包的一部分,你需要使用Packages对象来访问它。例如,假设Redwood公司使用一个叫redwood的java包来包含各种它实现的Java类。为了创建一个redwood中HelloWorld类的实例,你像下面这样访问类的构造器:

- -
var red = new Packages.redwood.HelloWorld();
-
- -

你也可以使用默认包中的类(就是说,类没有显式的命名包)。例如,如果HelloWorld类在CLASSPATH中,并且不在包中,你可以像下面这样使用它:

- -
var red = new Packages.HelloWorld();
-
- -

LiveConnect中的java, sun, 和netscape对象提供了常用Java包的快捷方式。例如,你可以像下面这样使用:

- -
var myString = new java.lang.String("Hello world");
-
- -

来替换下面长版本:

- -
var myString = new Packages.java.lang.String("Hello world");
-
- -

使用Java数组

- -

当任何Java方法创建了一个数组,并且你在JavaScript中引用那个数组,你就会使用到JavaArray。例如,下面的代码创建了有十个int类型元素的JavaArray x对象:

- -
var x = java.lang.reflect.Array.newInstance(java.lang.Integer, 10);
-
- -

跟JavaScript的Array对象类似, JavaArray有一个length属性用来返回数组元素的长度。不像Array.length, JavaArray.length是一个只读属性, 因为Java数组的元素长度在创建的时候就固定了。

- -

包和类的引用

- -

Simple references to Java packages and classes from JavaScript create the JavaPackage and JavaClass objects. In the earlier example about the Redwood corporation, for example, the reference Packages.redwood is a JavaPackage object. Similarly, a reference such as java.lang.String is a JavaClass object.

- -

Most of the time, you don't have to worry about the JavaPackage and JavaClass objects—you just work with Java packages and classes, and LiveConnect creates these objects transparently. There are cases where LiveConnect will fail to load a class, and you will need to manually load it like this:

- -
var Widgetry = java.lang.Thread.currentThread().getContextClassLoader().loadClass("org.mywidgets.Widgetry");
-
- -

In JavaScript 1.3 and earlier, JavaClass objects are not automatically converted to instances of java.lang.Class when you pass them as parameters to Java methods—you must create a wrapper around an instance of java.lang.Class. In the following example, the forName method creates a wrapper object theClass, which is then passed to the newInstance method to create an array.

- -
// JavaScript 1.3
-var theClass = java.lang.Class.forName("java.lang.String");
-var theArray = java.lang.reflect.Array.newInstance(theClass, 5);
-
- -

In JavaScript 1.4 and later, you can pass a JavaClass object directly to a method, as shown in the following example:

- -
// JavaScript 1.4
-var theArray = java.lang.reflect.Array.newInstance(java.lang.String, 5);
-
- -

Arguments of Type char

- -

In JavaScript 1.4 and later, you can pass a one-character string to a Java method which requires an argument of type char. For example, you can pass the string "H" to the Character constructor as follows:

- -
var c = new java.lang.Character("H");
-
- -

In JavaScript 1.3 and earlier, you must pass such methods an integer which corresponds to the Unicode value of the character. For example, the following code also assigns the value "H" to the variable c:

- -
var c = new java.lang.Character(72);
-
- -

Handling Java Exceptions in JavaScript

- -

When Java code fails at run time, it throws an exception. If your JavaScript code accesses a Java data member or method and fails, the Java exception is passed on to JavaScript for you to handle. Beginning with JavaScript 1.4, you can catch this exception in a try...catch statement. (Although this functionality (along with some others) had been broken in Gecko 1.9 (see {{ bug("391642") }}) as the Mozilla-specific LiveConnect code had not been maintained inside Mozilla, with Java 6 update 11 and 12 building support for reliance on Mozilla's implementation of the generic (and cross-browser) NPAPI plugin code, this has again been fixed.)

- -

For example, suppose you are using the Java forName method to assign the name of a Java class to a variable called theClass. The forName method throws an exception if the value you pass it does not evaluate to the name of a Java class. Place the forName assignment statement in a try block to handle the exception, as follows:

- -
function getClass(javaClassName) {
-   try {
-      var theClass = java.lang.Class.forName(javaClassName);
-   } catch (e) {
-      return ("The Java exception is " + e);
-   }
-   return theClass;
-}
-
- -

In this example, if javaClassName evaluates to a legal class name, such as "java.lang.String", the assignment succeeds. If javaClassName evaluates to an invalid class name, such as "String", the getClass function catches the exception and returns something similar to the following:

- -
The Java exception is java.lang.ClassNotFoundException: String
-
- -

For specialized handling based on the exception type, use the instanceof operator:

- -
try {
-  // ...
-} catch (e) {
-  if (e instanceof java.io.FileNotFound) {
-     // handling for FileNotFound
-  } else {
-    throw e;
-  }
-}
-
- -

See Exception Handling Statements for more information about JavaScript exceptions.

- -

Java to JavaScript Communication

- -

If you want to use JavaScript objects in Java, you must import the netscape.javascript package into your Java file. This package defines the following classes:

- - - -

See the JavaScript Reference for more information about these classes.

- -

Locating the LiveConnect classes

- -

In older versions of the Netscape browser, these classes were distributed along with the browser. Starting with JavaScript 1.2, these classes are delivered in a .jar file; in previous versions of JavaScript, these classes are delivered in a .zip file. For example, with Netscape Navigator 4 for Windows NT, the classes are delivered in the java40.jar file in the Program\Java\Classes directory beneath the Navigator directory.

- -

More recently, the classes have been distributed with Sun's Java Runtime; initially in the file "jaws.jar" in the "jre/lib" directory of the runtime distribution (for JRE 1.3), then in "plugin.jar" in the same location (JRE 1.4 and up).

- -

Using the LiveConnect classes with the JDK

- -

To access the LiveConnect classes, place the .jar or .zip file in the CLASSPATH of the JDK compiler in either of the following ways:

- - - -

You can specify an environment variable in Windows NT by double-clicking the System icon in the Control Panel and creating a user environment variable called CLASSPATH with a value similar to the following:

- -
C:\Program Files\Java\jre1.4.1\lib\plugin.jar
-
- -

See the Sun JDK documentation for more information about CLASSPATH.

- -

Note: Because Java is a strongly typed language and JavaScript is weakly typed, the JavaScript runtime engine converts argument values into the appropriate data types for the other language when you use LiveConnect. See Data Type Conversions for complete information.

- -

Using the LiveConnect Classes

- -

All JavaScript objects appear within Java code as instances of netscape.javascript.JSObject. When you call a method in your Java code, you can pass it a JavaScript object as one of its argument. To do so, you must define the corresponding formal parameter of the method to be of type JSObject.

- -

Also, any time you use JavaScript objects in your Java code, you should put the call to the JavaScript object inside a try...catch statement which handles exceptions of type netscape.javascript.JSException. This allows your Java code to handle errors in JavaScript code execution which appear in Java as exceptions of type JSException.

- -

Accessing JavaScript with JSObject

- -

For example, suppose you are working with the Java class called JavaDog. As shown in the following code, the JavaDog constructor takes the JavaScript object jsDog, which is defined as type JSObject, as an argument:

- -
import netscape.javascript.*;
-
-public class JavaDog{
-    public String dogBreed;
-    public String dogColor;
-    public String dogSex;
-
-    // define the class constructor
-    public JavaDog(JSObject jsDog){
-        // use try...catch to handle JSExceptions here
-        this.dogBreed = (String)jsDog.getMember("breed");
-        this.dogColor = (String)jsDog.getMember("color");
-        this.dogSex = (String)jsDog.getMember("sex");
-    }
-}
-
- -

Notice that the getMember method of JSObject is used to access the properties of the JavaScript object. The previous example uses getMember to assign the value of the JavaScript property jsDog.breed to the Java data member JavaDog.dogBreed.

- -

Note: A more realistic example would place the call to getMember inside a try...catch statement to handle errors of type JSException. See Handling JavaScript Exceptions in Java for more information.

- -

To get a better sense of how getMember works, look at the definition of the custom JavaScript object Dog:

- -
function Dog(breed,color,sex){
-   this.breed = breed;
-   this.color = color;
-   this.sex = sex;
-}
-
- -

You can create a JavaScript instance of Dog called gabby as follows:

- -
var gabby = new Dog("lab", "chocolate", "female");
-
- -

If you evaluate gabby.color, you can see that it has the value "chocolate". Now suppose you create an instance of JavaDog in your JavaScript code by passing the gabby object to the constructor as follows:

- -
var javaDog = new Packages.JavaDog(gabby);
-
- -

If you evaluate javaDog.dogColor, you can see that it also has the value "chocolate", because the getMember method in the Java constructor assigns dogColor the value of gabby.color.

- -

Handling JavaScript Exceptions in Java

- -

When JavaScript code called from Java fails at run time, it throws an exception. If you are calling the JavaScript code from Java, you can catch this exception in a try...catch statement. The JavaScript exception is available to your Java code as an instance of netscape.javascript.JSException.

- -

JSException is a Java wrapper around any exception type thrown by JavaScript, similar to the way that instances of JSObject are wrappers for JavaScript objects. Use JSException when you are evaluating JavaScript code in Java.

- -

When you are evaluating JavaScript code in Java, the following situations can cause run-time errors:

- - - -

For example, suppose the Java object eTest evaluates the string jsCode that you pass to it. You can respond to either type of run-time error the evaluation causes by implementing an exception handler such as the following:

- -
import netscape.javascript.JSObject;
-import netscape.javascript.JSException;
-
-public class eTest {
-    public static Object doit(JSObject obj, String jsCode) {
-        try {
-            obj.eval(jsCode);
-        } catch (JSException e) {
-            if (e.getWrappedException() == null)
-                return e;
-            return e.getWrappedException();
-        }
-        return null;
-    }
-}
-
- -

In this example, the code in the try block attempts to evaluate the string jsCode that you pass to it. Let's say you pass the string "myFunction()" as the value of jsCode. If myFunction is not defined as a JavaScript function, the JavaScript interpreter cannot evaluate jsCode. The interpreter generates an error message, the Java handler catches the message, and the doit method returns an instance of netscape.javascript.JSException.

- -

However, suppose myFunction is defined in JavaScript as follows:

- -
function myFunction() {
-   try {
-      if (theCondition == true) {
-         return "Everything's ok";
-      } else {
-         throw "JavaScript error occurred";
-      }
-   } catch (e) {
-      if (canHandle == true) {
-         handleIt();
-      } else {
-         throw e;
-      }
-   }
-}
-
- -

If theCondition is false, the function throws an exception. The exception is caught in the JavaScript code, and if canHandle is true, JavaScript handles it. If canHandle is false, the exception is rethrown, the Java handler catches it, and the doit method returns a Java string:

- -
JavaScript error occurred
-
- -

See Exception Handling Statements for complete information about JavaScript exceptions.

- -

Backward Compatibility

- -

In JavaScript 1.3 and earlier versions, the JSException class had three public constructors which optionally took a string argument, specifying the detail message or other information for the exception. The getWrappedException method was not available.

- -

Use a try...catch statement such as the following to handle LiveConnect exceptions in JavaScript 1.3 and earlier versions:

- -
try {
-   global.eval("foo.bar = 999;");
-} catch (Exception e) {
-   if (e instanceof JSException) {
-      jsCodeFailed();
-   } else {
-      otherCodeFailed();
-   }
-}
-
- -

In this example, the eval statement fails if foo is not defined. The catch block executes the jsCodeFailed method if the eval statement in the try block throws a JSException; the otherCodeFailed method executes if the try block throws any other error.

- -

Data Type Conversions

- -

Because Java is a strongly typed language and JavaScript is weakly typed, the JavaScript runtime engine converts argument values into the appropriate data types for the other language when you use LiveConnect. These conversions are described in the following sections:

- - - -

JavaScript to Java Conversions

- -

When you call a Java method and pass it parameters from JavaScript, the data types of the parameters you pass in are converted according to the rules described in the following sections:

- - - -

The return values of methods of netscape.javascript.JSObject are always converted to instances of java.lang.Object. The rules for converting these return values are also described in these sections.

- -

For example, if JSObject.eval returns a JavaScript number, you can find the rules for converting this number to an instance of java.lang.Object in Number Values.

- -

Number Values

- -

When you pass JavaScript number types as parameters to Java methods, Java converts the values according to the rules described in the following table:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Java parameter typeConversion rules
double -
    -
  • The exact value is transferred to Java without rounding and without a loss of magnitude or sign.
  • -
  • NaN is converted to NaN.
  • -
-
java.lang.Double
- java.lang.Object
A new instance of java.lang.Double is created, and the exact value is transferred to Java without rounding and without a loss of magnitude or sign.
float -
    -
  • Values are rounded to float precision.
  • -
  • Values which are too large or small to be represented are rounded to +infinity or -infinity.
  • -
  • NaN is converted to NaN.
  • -
-
byte -

char
- int
- long

- short
-
    -
  • Values are rounded using round-to-negative-infinity mode.
  • -
  • Values which are too large or small to be represented result in a run-time error.
  • -
  • NaN can not be converted and results in a run-time error.
  • -
-
java.lang.StringValues are converted to strings. For example: -
    -
  • 237 becomes "237"
  • -
-
boolean -
    -
  • 0 and NaN values are converted to false.
  • -
  • Other values are converted to true.
  • -
-
- -

When a JavaScript number is passed as a parameter to a Java method which expects an instance of java.lang.String, the number is converted to a string. Use the equals() method to compare the result of this conversion with other string values.

- -

Boolean Values

- -

When you pass JavaScript Boolean types as parameters to Java methods, Java converts the values according to the rules described in the following table:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
Java parameter typeConversion rules
booleanAll values are converted directly to the Java equivalents.
java.lang.Boolean
- java.lang.Object
A new instance of java.lang.Boolean is created. Each parameter creates a new instance, not one instance with the same primitive value.
java.lang.StringValues are converted to strings. For example: -
    -
  • true becomes "true"
  • -
  • false becomes "false"
  • -
-
byte -

char
- double
- float
- int
- long

- short
-
    -
  • true becomes 1
  • -
  • false becomes 0
  • -
-
- -

When a JavaScript Boolean is passed as a parameter to a Java method which expects an instance of java.lang.String, the Boolean is converted to a string. Use the == operator to compare the result of this conversion with other string values.

- -

String Values

- -

When you pass JavaScript string types as parameters to Java methods, Java converts the values according to the rules described in the following table:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
Java parameter typeConversion rules
java.lang.String
- java.lang.Object
JavaScript 1.4: -
    -
  • A JavaScript string is converted to an instance of java.lang.String with a Unicode value.
  • -
- -

JavaScript 1.3 and earlier:

- -
    -
  • A JavaScript string is converted to an instance of java.lang.String with an ASCII value.
  • -
-
byte -

double
- float
- int
- long

- short
All values are converted to numbers as described in ECMA-262. The JavaScript string value is converted to a number according to the rules described in ECMA-262.
charJavaScript 1.4: -
    -
  • One-character strings are converted to Unicode characters.
  • -
  • All other values are converted to numbers.
  • -
- -

JavaScript 1.3 and earlier:

- -
    -
  • All values are converted to numbers.
  • -
-
boolean -
    -
  • The empty string becomes false.
  • -
  • All other values become true.
  • -
-
- -

Undefined Values

- -

When you pass undefined JavaScript values as parameters to Java methods, Java converts the values according to the rules described in the following table:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
Java parameter typeConversion rules
java.lang.String
- java.lang.Object
The value is converted to an instance of java.lang.String whose value is the string "undefined".
booleanThe value becomes false.
double
- float
The value becomes NaN.
byte -

char
- int
- long

- short
The value becomes 0.
- -

The undefined value conversion is possible in JavaScript 1.3 and later versions only. Earlier versions of JavaScript do not support undefined values.

- -

When a JavaScript undefined value is passed as a parameter to a Java method which expects an instance of java.lang.String, the undefined value is converted to a string. Use the == operator to compare the result of this conversion with other string values.

- -

Null Values

- -

When you pass null JavaScript values as parameters to Java methods, Java converts the values according to the rules described in the following table:

- - - - - - - - - - - - - - - - - - - - - - -
Java parameter typeConversion rules
Any class
- Any interface type
The value becomes null.
byte -

char
- double
- float
- int
- long

- short
The value becomes 0.
booleanThe value becomes false.
- -

JavaArray and JavaObject objects

- -

In most situations, when you pass a JavaScript JavaArray or JavaObject as a parameter to a Java method, Java simply unwraps the object; in a few situations, the object is coerced into another data type according to the rules described in the following table:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
Java parameter typeConversion rules
Any interface or class that is assignment-compatible with the unwrapped object.The object is unwrapped.
java.lang.StringThe object is unwrapped, the toString method of the unwrapped Java object is called, and the result is returned as a new instance of java.lang.String.
byte -

char
- double
- float
- int
- long

- short
The object is unwrapped, and either of the following situations occur: -
    -
  • If the unwrapped Java object has a doubleValue method, the JavaArray or JavaObject is converted to the value returned by this method.
  • -
  • If the unwrapped Java object does not have a doubleValue method, an error occurs.
  • -
-
booleanIn JavaScript 1.3 and later versions, the object is unwrapped and either of the following situations occur: -
    -
  • If the object is null, it is converted to false.
  • -
  • If the object has any other value, it is converted to true.
  • -
- -

In JavaScript 1.2 and earlier versions, the object is unwrapped and either of the following situations occur:

- -
    -
  • If the unwrapped object has a booleanValue method, the source object is converted to the return value.
  • -
  • If the object does not have a booleanValue method, the conversion fails.
  • -
-
- -

An interface or class is assignment-compatible with an unwrapped object if the unwrapped object is an instance of the Java parameter type. That is, the following statement must return true:

- -
unwrappedObject instanceof parameterType;
-
- -

JavaClass objects

- -

When you pass a JavaScript JavaClass object as a parameter to a Java method, Java converts the object according to the rules described in the following table:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
Java parameter typeConversion rules
java.lang.ClassThe object is unwrapped.
netscape.javascript.JSObject
- java.lang.Object
The JavaClass object is wrapped in a new instance of netscape.javascript.JSObject.
java.lang.StringThe object is unwrapped, the toString method of the unwrapped Java object is called, and the result is returned as a new instance of java.lang.String.
booleanIn JavaScript 1.3 and later versions, the object is unwrapped and either of the following situations occur: -
    -
  • If the object is null, it is converted to false.
  • -
  • If the object has any other value, it is converted to true.
  • -
- -

In JavaScript 1.2 and earlier versions, the object is unwrapped and either of the following situations occur:

- -
    -
  • If the unwrapped object has a booleanValue method, the source object is converted to the return value.
  • -
  • If the object does not have a booleanValue method, the conversion fails.
  • -
-
- -

Other JavaScript objects

- -

When you pass any other JavaScript object as a parameter to a Java method, Java converts the object according to the rules described in the following table:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
Java parameter typeConversion rules
netscape.javascript.JSObject
- java.lang.Object
The object is wrapped in a new instance of netscape.javascript.JSObject.
java.lang.StringThe object is unwrapped, the toString method of the unwrapped object is called, and the result is returned as a new instance of java.lang.String.
byte -

char
- double
- float
- int
- long

- short
The object is converted to a value using the logic of the ToPrimitive operator described in ECMA-262. The PreferredType hint used with this operator is Number.
booleanIn JavaScript 1.3 and later versions, the object is unwrapped and either of the following situations occur: -
    -
  • If the object is null, it is converted to false.
  • -
  • If the object has any other value, it is converted to true.
  • -
- -

In JavaScript 1.2 and earlier versions, the object is unwrapped and either of the following situations occur:

- -
    -
  • If the unwrapped object has a booleanValue method, the source object is converted to the return value.
  • -
  • If the object does not have a booleanValue method, the conversion fails.
  • -
-
- -

Java to JavaScript Conversions

- -

Values passed from Java to JavaScript are converted as follows:

- - - -

Note that instances of java.lang.Double and java.lang.Integer are converted to JavaScript objects, not to JavaScript numbers. Similarly, instances of java.lang.String are also converted to JavaScript objects, not to JavaScript strings.

- -

Java String objects also correspond to JavaScript wrappers. If you call a JavaScript method that requires a JavaScript string and pass it this wrapper, you'll get an error. Instead, convert the wrapper to a JavaScript string by appending the empty string to it, as shown here:

- -
var JavaString = JavaObj.methodThatReturnsAString();
-var JavaScriptString = JavaString + "";
diff --git "a/files/zh-cn/archive/web_\346\240\207\345\207\206/index.html" "b/files/zh-cn/archive/web_\346\240\207\345\207\206/index.html" deleted file mode 100644 index 19024fa1eb..0000000000 --- "a/files/zh-cn/archive/web_\346\240\207\345\207\206/index.html" +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Web 标准 -slug: Archive/Web_标准 -translation_of: Archive/Web_Standards ---- -
- Web标准 Web标准经过精心设计,旨在让广大用户享有最佳的上网体验,同时也确保在网上发布的文件经久不衰。由这些标准设计、构建的网站简化并降低了开发成本,同时又可以让更多人访问,并适应更多的上网设备。随着传统桌面浏览器的进化、新型互联网设备进入市场,经由这些准则开发的网站将继续正常运作。 [1]
- - - - - - - -
-

参考文章

-
-
- 将应用从IE浏览器迁移到Mozilla浏览器
-
- 是否在迁移针对IE浏览器定制的应用到Mozilla浏览器时遇到了麻烦?本文涵盖了迁移应用到开源的基于Mozilla的浏览器的过程中相关的常见问题。
-
- 在您的网页中应用Web标准
-
- 本文概述了如何升级你的网页从而使之遵循 W3C Web标准。
-
- 为什么选择符合标准而不是私有实现?
-
- 应用通常是跨多个开发小组设计的,因此在开发过程中需要一个通用标准。
-
- Web标准的商业价值
-
- 本文探讨了遵守Web标准、丢弃私有标记和技术是如何帮助一家公司实现其商业目标的。
-
-

查看全部...

-
-

社区

-
    -
  • 浏览 Mozilla 论坛...
  • -
-

- -

工具

- -

查看全部...

-

Examples

- - -
-
- CSS, DHTML, HTML, Web 开发, XHTML, XML
-
-
-
-

^ - The Web Standards Project

-

diff --git "a/files/zh-cn/archive/web_\346\240\207\345\207\206/issues_arising_from_arbitrary-element_hover/index.html" "b/files/zh-cn/archive/web_\346\240\207\345\207\206/issues_arising_from_arbitrary-element_hover/index.html" deleted file mode 100644 index c63ee0cc9e..0000000000 --- "a/files/zh-cn/archive/web_\346\240\207\345\207\206/issues_arising_from_arbitrary-element_hover/index.html" +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: 发行任意元素的hover的起因 -slug: Archive/Web_标准/Issues_Arising_From_Arbitrary-Element_hover -tags: - - CSS - - 所有分类 -translation_of: Archive/Web_Standards/Issues_Arising_From_Arbitrary-Element_hover ---- -

 

-

Summary: Thanks to long-standing limitations, we're used to thinking of hover styles as applying only to hyperlinks, which has led to some sloppy authoring practices that are now causing problems for some Web sites. This technote explains the source of the problems and how to avoid encountering them. 很多设计者都使用CSS2伪类:hover装饰他们的链接。这个创新,首先被Microsoft® Internet Explorer引入,随后被CSS规范所采用,是非常受欢迎的文本链接样式,尤其是那些看起来和动起来像以JavaScript驱动的交互动态效果。除了推进浏览器对CSS的支持以外,还产生了一些出乎意料的hovering地活泼行为在一些页面。

-

Hover和非链接元素

-

Section 5.11.3 of CSS2定义了三个动态的伪类(:hover, :active, and :focus),然后继续表示:

-
- CSS可能不会定义以上那几个状态的元素,或者状态为什么被加入的左派。脚本能否改变产生用户事件的元素,或者不同的设置和使用不同方法的指向以及活动的元素。(翻译的可能不准确,不明白可以看下原文。)
-

这样,尽管设计者们习惯于过去的想法,将这些状态被应用在专有的超链接上,但它们不是那样有限在CSS2中。理论上任何元素都能达到这三种状态,和基于这样状态的样式。这不是传统上的使用情形。

-

未指定的伪类

-

第二篇的问题来自当我们在一个选择器上考虑使用未指定的伪类的效果时。例如:

-
:hover {color: red;}
-

这样等效于CSS2的标准:

-
*:hover {color: red;}
-

哪一个都被解释为“设置任何元素的hover前景色为红色。”所以,段落、表格、标题也在hover范围内,在一个页面中任何其它元素的文本将变成红色。

-

一个公用未指定的类和伪类的hover一起使用的变量,像这样:

-
.nav:hover {color: red;}
-

在这种情况,只有实例的class属性的值是nav位置的超链接时候,才能正常工作。无论如何,这种类型的规则经常看见在像这样的联合标记中:

-
<td class="nav">
-<a href="one.html" class="nav">one</a> |
-<a href="two.html" class="nav">two</a> |
-<a href="thr.html" class="nav">three</a> |
-<a href="fou.html" class="nav">four</a>
-</td>
-

因为装入的表格有一个class的值是nav,所以当用户的鼠标移动到那个单元里面,竖线字符将会变成红色。链接将会在它们hover的时候变成红色。

-

Gecko的行为

-

在基于Netscape Gecko的20020410(Netscape 6.1+)版本后构建的浏览器中,:hover样式可应用于页面中的任意标签。这样设计者们可以使用未限定的伪类,或者使用未限定的类伪类的这种结合,这样做会出现可见的hover样式的应用会多于它们应有链接的危险。最可靠的解决方法是为选择器添加一个锚元素,像这样:

-
a:hover {color: red;}
-a.nav:hover {color: red;}
-

在基于Mozilla 1.0和更新版本(Netscape 7+)的浏览器中包含试图消除老文档遗留的问题的代码。如果页面运行在“转换显示”模式中,未限定的伪类将受限制只能用于链接。在基于Mozilla 1.3b及更新版本构建的浏览器中,这个转换显示被延伸包括了选择器,关于:hover伪类结合一个未限定的类选择器(详细资料可以查看Bugzilla上的#169078条目)。

-

命名锚记的问题

-

除了先前的描述效果之外,有两个其它的相关公共效果可能不是设计者期待的。其中一个被确认容易固定,但另一个有一些微妙。

-

首先,这个问题是设计者打开一个指定的锚记,但它没有关闭。例如:

-
<a name="pagetop">
-<h2>My Page</h2>
-

没有a </a>,这个锚记将在整个文档中有效。这样通常的意思是将获取页面中的hover样式。考虑到以下规则的效果:

-
a:hover {color: red;}
-

在一个文档中有一个未关闭的锚记,那么任何文本的样式将是设计者打开标记的前景颜色(除非其它CSS规则干涉)。

-

这里提出的第二个公用问题,哪一个锚记能接受hover样式。虽然,设计者们可能打算把选择器a:hover只应用于超链接,它也将应用于锚记,因为选择器只是规定所有的a元素应用哪一个hover样式。为了消除这个问题,设计者应该使用混合的伪类语法来描述CSS2:

-
a:link:hover {color: red;}
-a:visited:hover {color: maroon;}
-

注意像这样的语法,问题是当它们hover时,visit和未visit时链接不同。以a:hover为基础时这不是一个问题。当然,这个选择器a:link:hover将只应用于未visit的链接,所以设计者需要一样的样式同时应用于visit和未visit的链接,应该组织把2个选择器放在单一的规则中。

-

推荐

-

为了避免未预料的问题,设计者们被鼓励在打算用于超链接的动态伪类中包含元素名,以提高健壮性。此外,混合伪类要预防hover样式被用于非链接的锚。因此,以a:hover的基础为首选a:hover应该总是代替刚才的:hovera:link:hover(和a:visited:hover)。

-

相关链接

- -
-

文章原始信息

- -
-

 

diff --git "a/files/zh-cn/archive/web_\346\240\207\345\207\206/rdf_in_mozilla_faq/index.html" "b/files/zh-cn/archive/web_\346\240\207\345\207\206/rdf_in_mozilla_faq/index.html" deleted file mode 100644 index d6df231e2d..0000000000 --- "a/files/zh-cn/archive/web_\346\240\207\345\207\206/rdf_in_mozilla_faq/index.html" +++ /dev/null @@ -1,320 +0,0 @@ ---- -title: RDF 问题集 -slug: Archive/Web_标准/RDF_in_Mozilla_FAQ -tags: - - RDF -translation_of: Archive/Web_Standards/RDF_in_Mozilla_FAQ ---- -

 

-

General

-

Where do I start?

-

RDF serves two primary purposes in Mozilla. First, it is a simple, cross-platform database for small data stores. Second, and more importantly, the RDF model is used along with XUL templates as an abstract "API" for displaying information. RDF in Fifty Words or Less is a quick, high-level description of what RDF does in Mozilla. The RDF Back-end Architecture document describes in more detail how Mozilla's RDF implementation works, and gives a quick overview of the interfaces that are involved.

-

Where do I find information on Open Directory ("dmoz")?

-

Unfortunately, not here! Well, here's a little... Start at http://www.dmoz.org/ for more information on the Open Directory. The Open Directory dataset is available as a (huge) RDF/XML dump. It describes thousands of Web sites using a mix of the Dublin Core metadata vocabulary and the DMoz taxonomy. See their RDF pages for more information, or odp-rdf-announce for updates relating to their exact data format. The ChefMoz site (collaborative restaurant guide) is also available in RDF.

-

If you have problems with the DMoz and ChefMoz data, it's best to contact those projects directly. But if you do something interesting with this content (eg. have Mozilla use it, eg. by loading chunks of it into a XUL UI from a remote site), don't forget to let mozilla-rdf and the RDF Interest Group lists know. Those lists would probably also be interested in tools for cleaning / re-processing / storing the DMoz data too. See the sites using ODP data pages for some directories based on the ODP RDF dumps.

-

What is a datasource?

-

RDF can generally be viewed in two ways: either as a graph with nodes and arcs, or as a "soup" of logical statements. A datasource is a subgraph (or collection of statements, depending on your viewpoint) that are for some reason collected together. Some examples of datasources that exist today are "browser bookmarks", "browser global history", "IMAP mail accounts", "NNTP news servers", and "RDF/XML files".

-

In Mozilla, datasources can be composed together using the composite data source. This is like overlaying graphs, or merging collections of statements ("microtheories") together. Statements about the same RDF resource can then be intermingled: for example, the "last visit date" of a particular website comes from the "browser global history" datasource, and the "shortcut keyword" that you can type to reach that website comes from the "browser bookmarks" datasource. Both datasources refer to "website" by URL: this is the "key" that allows the datasources to be "merged" effectively.

-

For a more detailed account of how to write a datasource, refer to the RDF Datasource How-To.

-

How does Mozilla manage datasources?

-

The RDF service manages a table of all loaded datasources. The table is keyed by the datasource's "URI", which is either the URL of an RDF/XML file, or a "special" URI starting with rdf: that refers to a built-in datasource.

-

Datasources may be loaded via the RDF service using the GetDataSource() method. If the URI argument refers to an RDF/XML file's URL, then the RDF service will create an RDF/XML datasource and asynchronously parse it. The datasource will remain "cached" until the last reference to the datasource is released.

-

If the URI argument refers to a built-in datasource, the RDF service will use the XPCOM Component Manager to load a component whose ContractID is constructed using the "special" URI and the well-known prefix@mozilla.org/rdf/datasource;1?name=</code>.

-

For example,

-
rdf:foo
-
-

Would load:

-
@mozilla.org/rdf/datasource;1?name=foo
-
-

As with RDF/XML datasources, a datasource that is retrieved this way is "cached" by the RDF service until the last reference is dropped.

-

How do I create a datasource from an RDF/XML file?

-

You can either create an RDF/XML datasource using the RDF service's GetDataSource() method:

-
// Get the RDF service
-var RDF =
-  Components
-  .classes["@mozilla.org/rdf/rdf-service;1"]
-  .getService(Components.interfaces.nsIRDFService);
-// ...and from it, get the datasource. Make sure that your web server
-// dishes it up as text/xml (recommended) or text/rdf!
-var ds = RDF.GetDataSource("http://www.mozilla.org/some-rdf-file.rdf");
-// Note that ds will load asynchronously, so assertions will not
-// be immediately available
-
-

Alternatively, you can create one directly using the XPCOM Component Manager, as the following code fragment illustrates:

-
// Create an RDF/XML datasource using the XPCOM Component Manager
-var ds =
-  Components
-  .classes["@mozilla.org/rdf/datasource;1?name=xml-datasource"]
-  .createInstance(Components.interfaces.nsIRDFDataSource);
-// The nsIRDFRemoteDataSource interface has the interfaces
-// that we need to setup the datasource.
-var remote =
-   ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
-// Be sure that your web server will deliver this as text/xml (recommended) or text/rdf!
-remote.Init("http://www.mozilla.org/some-rdf-file.rdf");
-// Make it load! Note that this will happen asynchronously. By setting
-// aBlocking to true, we could force it to be synchronous, but this
-// is generally a bad idea, because your UI will completely lock up!
-remote.Refresh(false);
-// Note that ds will load asynchronously, so assertions will not
-// be immediately available
-
-

You may decide that you need to "manually" create an RDF/XML datasource if you want to force it to load synchronously.

-

How do I reload an RDF/XML datasource?

-

You can force an RDF/XML datasource (or any datasource that supports nsIRDFRemoteDataSource) using Refresh() method of nsIRDFRemoteDataSource. Refresh() takes a single parameter that indicates whether you'd like it to perform its operation synchronously ("blocking") or asynchrounously ("non-blocking"). You should never do a synchronous load unless you really know what you're doing: this will freeze the UI until the load completes!

-

How can I tell if an RDF/XML datasource has loaded?

-

Using the nsIRDFRemoteDataSource interface, it is possible to immediately query the loaded property to determine if the datasource has loaded or not:

-
// Get the RDF service
-var RDF =
-  Components
-  .classes["@mozilla.org/rdf/rdf-service;1"]
-  .getService(Components.interfaces.nsIRDFService);
-// Get the datasource.
-var ds = RDF.GetDataSource("http://www.mozilla.org/some-rdf-file.rdf");
-// Now see if it's loaded or not...
-var remote =
-  ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
-
-if (remote.loaded) {
-  alert("the datasource was already loaded!");
-}
-else {
-  alert("the datasource wasn't loaded, but it's loading now!");
-}
-
-

Say the datasource wasn't loaded, and is loading asynchronously. Using this API and JavaScript's setTimeout(), one could set up a polling loop that would continually check the loaded property. This is kludgy, and even worse, won't detect a failed load, for example, if there wasn't any data at the URL!

-

For this reason, there is an observer interface that allows you to spy on a datasource's progress. The following code illustrates its usage:

-
// This is the object that will observe the RDF/XML load's progress
-var Observer = {
-  onBeginLoad: function(aSink)
-    {},
-
-  onInterrupt: function(aSink)
-    {},
-
-  onResume: function(aSink)
-    {},
-
-  onEndLoad: function(aSink)
-    { alert("done!"); },
-
-  onError: function(aSink, aStatus, aErrorMsg)
-    { alert("error! " + aErrorMsg); }
-};
-// Get the RDF service
-var RDF =
-  Components
-  .classes["@mozilla.org/rdf/rdf-service;1"]
-  .getService(Components.interfaces.nsIRDFService);
-// Get the datasource.
-var ds = RDF.GetDataSource("http://www.mozilla.org/some-rdf-file.rdf");
-// Now see if it's loaded or not...
-var remote =
-  ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
-
-if (remote.loaded) {
-  alert("the datasource was already loaded!");
-}
-else {
-  alert("the datasource wasn't loaded, but it's loading now!");
-  // RDF/XML Datasources are all nsIRDFXMLSinks
-  var sink =
-    ds.QueryInterface(Components.interfaces.nsIRDFXMLSink);
-  // Attach the observer to the datasource-as-sink
-  sink.addXMLSinkObserver(Observer);
-  // Now Observer's methods will be called-back as
-  // the load progresses.
-}
-
-

Note that the observer will remain attached to the RDF/XML datasource unless removeXMLSinkObserver is called.

-

How do I access the information in a datasource?

-

The nsIRDFDataSource interface is the means by which you access and manipulate the assertions in a datasource.

- -

You can also use the RDF container interfaces to access information contained in RDF containers.

-

How do I change information in the datasource?

-

To use 'Assert' to add one assertion and 'Unassert' to remove one. Refer to Mozilla RDF Back end Architecture

-
ds.Assert(homepage, FV_quality, value, true);
-ds.Unassert(homepage, FV_quality, value, true);
-
-

How do I save changes to an RDF/XML datasource back?

-

An RDF/XML datasource can be QueryInterface()'d to nsIRDFRemoteDataSource. This interface has a Flush() method, which will attempt to write the contents of the datasource back to the URL from which they were loaded, using a protocol specific mechanism (e.g., a file: URL just writes the file; an http: URL might do an HTTP-POST). Flush() only writes the datasource if its contents have changed.

-

How do I merge two or more datasources to view them as one?

-

Use nsIRDFCompositeDataSource. This interface is derived from nsIRDFDataSource. An implementation of this interface will typically combine the statements from several datasources together as a collective. Because the nsIRDFCompositeDataSource interface is derived from nsIRDFDataSource, it can be queried and modified just like an individual data source.

-

How do I access "built-in" datasources?

-

A built-in datasource is a locally-installed component that implements nsIRDFDataSource. For example, the bookmarks service. First, check here to make sure you will be allowed to access a built-in datasource. There are several security restrictions on accessing built-in datasources from "untrusted" XUL and JS.

-

Since a built-in datasource is just an XPCOM component, you can instantiate it directly using the XPConnect component manager.

-
// Use the component manager to get the bookmarks service
-var bookmarks =
-  Components.
-  classes["@mozilla.org/rdf/datasource;1?name=bookmarks"].
-  getService(Components.interfaces.nsIRDFDataSource);
-
-// Now do something interesting with it...
-if (bookmarks.HasAssertion(
-     RDF.GetResource("http://home.netscape.com/NC-rdf#BookmarksRoot"),
-     RDF.GetResource("http://home.netscape.com/NC-rdf#child"),
-     RDF.GetResource("http://home.netscape.com/NC-rdf#PersonalToolbarFolder"),
-     true) {
-  // ...
-}
-
-

Alternatively, some datasources have "special" RDF-friendly ContractIDs that make it easy to instantiate the datasource using either the nsIRDFSerivce's GetDataSource() method or the datasources attribute on a XUL template. These ContractIDs are of the form

-
@mozilla.org/rdf/datasource;1?name=name
-
-

And are accessable via GetDataSource() and the datasources attribute using the shorthand rdf: - - name - . For example, the following XUL fragment illustrates how to add the bookmarks service as a datasource into a XUL template.

-
<tree datasources="rdf:bookmarks">
-  ...
-</tree>
-
-

How do I manipulate RDF "containers"?

-

To manipulate an RDF "container" (an <rdf:Seq>, for example), you can use nsIRDFContainerUtils which can be instantiated as a service with the following ContractID:

-
@mozilla.org/rdf/container-utils;1
-
-

You can use this service to detect if something is an RDF container using IsSeq(), IsBag(), and IsAlt(). You can "make a resource into a container" if it isn't one already using MakeSeq(), MakeBag(), or MakeAlt(). These methods return an nsIRDFContainer which allows you to do container-like operations without getting your hands too dirty.

-

Alternatively, if your datasource already has an object that is an RDF container, you can instantiate an nsIRDFContainer object with the

-
@mozilla.org/rdf/container;1
-
-

ContractID and Init() it with the datasource and resource as parameters. Note that this will fail if the resource isn't already a container.

-

XUL Templates

-

XUL templates are created by specifying a datsources attribute on an element in a XUL document.

-

There are two "forms" that XUL templates may be written in. The "simple" form, which is currently the most common form in the Mozilla codebase, and the "extended" form, which allows for sophisticated pattern matching against the RDF graph. See the XUL:Template Guide. (These are bizarrely arranged because the eventual intent is to introduce templates using the extended form -- which in many ways is conceptually simpler, even if more verbose -- and then treat the "simple" form as a shorthand for the extended form.)

-

What can I build with a XUL template?

-

You can build any kind of content using a XUL template. You may use any kind of tag (including HTML, or arbitrary XML) in the <action> section of a <rule>.

-

When should I use a XUL template?

-

One alternative to using RDF and XUL templates is to use the W3C DOM APIs to build up and manipulate a XUL (or HTML) content model. There are times, however, when doing so may be inconvenient:

-
    -
  1. There are several "views" of the data. For example, Mozilla mail/news reveals the folder hierarchy in the toolbar, the "folder pane", in several menus, and in some of the dialogs. Rather than writing three pieces of JS (or C++) code to construct the DOM trees each for <menubutton>, <menu>, and <tree> content models, you write three compact sets of rules for each content model.
  2. -
  3. The data can change. For example, a mail/news user may add or remove IMAP folders. (Note how this requirement complicates the task of building a content model!) The XUL template builder uses the rules to automatically keep all content models in sync with your changes.
  4. -
-

In order to take advantage of this functionality, you must of course be able to express your information in terms of the RDF datasource API, either by using the built-in memory datasource, using RDF/XML to store your information, or writing your own implementation (possibly in JavaScript) of nsIRDFDataSource.

-

What gets loaded when I specify "datasources="

-

The datasources attribute on the "root" of a template specifies a whitespace-separated list of datasource URIs to load. But what is a "datasource URI"? It is either:

- -

In either case, the datasource will be loaded using the nsIRDFService's GetDataSource() method, so it will be managed similarly to all other datasources loaded this way.

-

What is the security model for RDF/XML in XUL?

-

XUL that is loaded from a "trusted" URL (currently, any chrome: URL) can specify any datasource URI in the datasources attribute of the XUL template.

-

XUL that is loaded from an "untrusted" URL can only specify an RDF/XML document from the same codebase (in the Java sense of the word) that the XUL document originated from. No "special" (i.e., rdf:) datasources may be loaded from untrusted XUL.

-

How do I add a datasource to a XUL template?

-

Although it's possible to create a XUL template with an "implicit" set of datasources by specifying the datasources attribute, there are often times when you won't know the datasource that you want to add until after the XUL is loaded. For example, your XUL may need compute the datasources that it wants to display in an onload handler. Or, it may need to add a datasource later based on some user action.

-

Here's a simple example that illustrates how to do this. Let's start with the following XUL.

-
<window xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul">
-  ...
-  <tree id="my-tree" datasources="rdf:null">
-    ...
-  </tree>
-  ...
-</window>
-
-

Assuming that we've aquired a datasource somehow (e.g., like this), the following sample code illustrates how to add that datasource to the template, and then force the template to rebuild itself based on the newly added datasource's contents.

-
var ds = /* assume we got this somehow! */;
-// Get the DOM element for 'my-tree'
-var tree = document.getElementById('my-tree');
-// Add our datasource to it
-tree.database.AddDataSource(ds);
-// Force the tree to rebuild *now*. You have to do this "manually"!
-tree.builder.rebuild();
-
-

Any XUL element with a datasources attribute will "get" a database property and a builder property. The database property refers to an nsIRDFCompositeDataSource object, which is contains the datasources from which the template is built.

-

The builder property refers to an nsIXULTemplateBuilder object, which is a the "builder" that maintains the state of the template's contents.

-

Note the rdf:null datasource: this is a special datasource that says, "hey, I don't have a datasource for you yet, but I'm going to add one later, so set yourself up for it!" It causes the database and builder properties to get installed, but leaves the database empty of datasources: you've got to add these in yourself!

-

Can I manipulate a XUL template using the DOM APIs?

-

Yes: you can add rules, remove rules, change a rule's conditions, and change the content that is built by a rule. In fact, you can change anything about a template using the W3C DOM APIs.

-

The only caveat is that you must call rebuild() before the changes you've made will take effect (just as you must if you add a datasource to the XUL template).

-

How do I insert plaintext from a template?

-

To insert plaintext in a template, use the <text> element.

-
<template>
-  <rule>
-    <conditions>...</condition>
-    <bindings>...</bindings>
-    <action>
-      <text value="?some-variable" />
-    </action>
-  </rule>
-</template>
-
-

The above template will create a content model that runs a series of text nodes together.

-

Troubleshooting

-

Tricks and tips from the field.

-

My RDF/XML file won't load.

-

The most common cause for RDF/XML not to load from a web server is incorrect MIME type. Make sure your server is delivering the file as text/xml (recommended) or text/rdf (bogus).

-

Note that the W3C RDF Core WG are registering application/rdf+xml, though this isn't understood by any Mozilla code yet. (do we have a bug registered to track this? -- danbri)

-

Another possible problem: for remotely-loaded XUL and RDF, you might need to adjust Mozilla's security restrictions (see belowfor example code). If XUL isn't loading your RDF, and the mimetype is OK, this could well be your problem.

-

You can use the rdfcat and rdfpoll utilities to verify that the RDF/XML is actually valid. Both of these programs are built by default on Windows, and on Linux when the configure --enable-tests is specified.

- -

Both these programs are slow to load and run (but they will run, eventually). They initialize XPCOM and bring up Necko to be able to load and process URLs just like Mozilla does.

-

Nothing happens after I call AddDataSource.

-

Note that the template builder will not rebuild the contents of a template automatically after AddDataSource or RemoveDataSource have been called on the builder's database. To refresh the template's contents, you must manually call - - elt. - builder.rebuild() yourself.

-

Why? This was done to avoid multiple rebuilds when more than one datasource is added to the database.

-

Examples

-

Where can I find some (working) examples?

-

A few examples are posted here. Some of these are included in signed scripts, and are runnable from HTTP directly.

-

See also duplicates.rdf (for live RDF feed from Mozilla) alongside duplicates.xul. Note that for these to work, you have to relax Mozilla's security model. To do this, add the following line to your preferences file. (Shut down Mozilla first since it overwrites your preferences file when you quit.)

-
user_pref("signed.applets.codebase_principal_support", true);
-
-

Mozilla will ask you if you want to grant the scripts in duplicates.xul permission to access XPConnect; respond in the affirmative.

-

Currently, Mozilla does not allow unprivileged access to the RDF interfaces and services; see bug 122846 for details.

-

Please mail danbri, mozilla-rdf or waterson with URLs if you are aware of other examples to which we ought to link!

-

Notes

-
    -
  1. See also W3C RDF and Semantic Web pages for more information on RDF and related technologies.
  2. -
-

Contributors

- -

Author: Chris Waterson

-
-

Original Document Information

- -
-

diff --git "a/files/zh-cn/archive/web_\346\240\207\345\207\206/using_the_right_markup_to_invoke_plugins/index.html" "b/files/zh-cn/archive/web_\346\240\207\345\207\206/using_the_right_markup_to_invoke_plugins/index.html" deleted file mode 100644 index 2642ff72b1..0000000000 --- "a/files/zh-cn/archive/web_\346\240\207\345\207\206/using_the_right_markup_to_invoke_plugins/index.html" +++ /dev/null @@ -1,264 +0,0 @@ ---- -title: 用正确的标识来调用插件 -slug: Archive/Web_标准/Using_the_Right_Markup_to_Invoke_Plugins -tags: - - HTML - - Plugins - - 全部分类 -translation_of: Archive/Web_Standards/Using_the_Right_Markup_to_Invoke_Plugins ---- -

这篇文章介绍怎样使用正确的HTML来调用插件.讨论了对象元素及其嵌入元素,以及在网页中使用恰当的HTML来调用Java的细节.

- -

对象元素 Object Element: W3C标准及跨浏览器问题

- -

对象元素是HTML 4.01规范的一部分, 是被推荐的调用插件的机制. Its use is subject to a few caveats that this section outlines.

- -

Traditionally, the object element has been used differently by Microsoft Internet Explorer and by Mozilla-based browsers such as Netscape 7. In IE, the object element is used to invoke a plugin that is built on the ActiveX architecture. Here's an example of this kind of usage for IE:

- -
<!-- IE ONLY CODE -->
-<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
-codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0"
-width="366" height="142" id="myFlash">
-    <param name="movie" value="javascript-to-flash.swf" />
-    <param name="quality" value="high" />
-    <param name="swliveconnect" value="true" />
-</object>
-
- -

In the above example, the classid attribute that goes along with the object element points to a "clsid:" URN followed by the Unique Identifier of an ActiveX control (in the above example, the string beginning with "D27..."). This is, in fact, the Unique Identifier of Macromedia's Flash plugin, and developers are expected to know such Unique Identifiers in order to invoke the component of their choice. The codebase attribute used above points to a location that houses the CAB file containing the ActiveX control. In this context, the codebase attribute is used as an obtainment mechanism -- that is to say, a way to obtain a control if it isn't present. If the Flash ActiveX control is not installed, IE will then go to the URL referenced by the codebase attribute and retrieve the ActiveX control. Additional param elements (which are "children" of the above object element) specify configuration parameters for the Flash plugin. For instance, the param name="movie" tells the Flash plugin the location of the SWF file to start playing.

- -

With the release of Netscape 7.1, this kind of ActiveX use of the object element is supported for use with the Microsoft® Windows Media Player. Only the Windows Media Player is supported as an ActiveX control in Netscape 7.1. The details are covered in another article.

- -

Browsers such as Netscape 7 will not render the Flash plugin if the above kind of markup is used, because Netscape 7 does not support ActiveX or ActiveX-based component invocations, with the exception of Windows Media Player in Netscape 7.1. Mozilla-based browsers support the Netscape Plugin architecture, which is not COM based like ActiveX (and thus, not invoked via a Unique Identifier) but rather, MIME type based. Mozilla-based browsers support the use of the object element along with a MIME type. Here is an example of this usage, once again for the Macromedia Flash plugin:

- -
<object type="application/x-shockwave-flash" data="javascript-to-flash.swf"
-width="366" height="142" id="myFlash">
-    <param name="movie" value="javascript-to-flash.swf" />
-    <param name="quality" value="high" />
-    <param name="swliveconnect" value="true" />
-    <p>You need Flash -- get the latest version from
-    <a href= "http://www.macromedia.com/downloads/">here.</a></p>
-</object>
-
- -

In the above example, application/x-shockwave-flash is the Flash MIME type, and will invoke the Netscape-specific Flash architecture in Mozilla-based browsers. The data attribute points to the SWF file to play, and the configuration parameters (the param elements) are used in a consistent manner both for IE and for Mozilla-based browsers such as Netscape 7. In fact, the above usage will also work for IE, which understands MIME type invocations for certain MIME types such as Flash in addition to ActiveX-style classid invocations.

- -

Since the use of MIME type for Flash will work for both IE and Netscape 7, you can use the above markup to invoke the Flash plugin for both IE and Netscape 7. However, there are a few caveats that developers ought to bear in mind when using the object element with Mozilla-based browsers such as Netscape 7 and in IE:

- -

Caveats(警告)

- - - - - -
<!-- Usage Will Not Work As Intended -->
-<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
-codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0"
-width="366" height="142" id="myFlash">
-    <param name="movie" value="javascript-to-flash.swf" />
-    <param name="quality" value="high" />
-    <param name="swliveconnect" value="true" />
-
-	<object type="application/x-shockwave-flash" data="javascript-to-flash.swf"
-	 width="366" height="142" id="myFlashNSCP">
-		<param name="movie" value="javascript-to-flash.swf" />
-    		<param name="quality" value="high" />
-    		<param name="swliveconnect" value="true" />
-		<p>You need Flash -- get the latest version from
-		 <a href="http://www.macromedia.com/downloads/">
-		here.</a></p>
-	</object>
-
-</object>
-
- - - - - -

Recommendation

- -

In order to overcome the shortcomings that you can't nest object elements in IE and that there isn't a way you can simply use one object element in a cross-browser way (with architecture specific obtainment mechanisms), the best course of action is to dynamically write object elements based on architecture. For example, on browsers that support ActiveX, such as IE, create an object element with a classid attribute, and on browsers that support the Netscape Plugin architecture, use a MIME type. Here is an example of some JavaScript which does this:

- -
if (window.ActiveXObject)
-{
-
-// browser supports ActiveX
-// Create object element with
-// download URL for IE OCX
-
-document.write('<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"');
-document.write(' codebase="http://download.macromedia.com');
-document.write('/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0"');
-document.write(' width="366" height="142" id="myFlash">');
-document.write(' <param name="movie" value="javascript-to-flash.swf" />');
-document.write(' <param name="quality" value="high" />');
-document.write(' <param name="swliveconnect" value="true" />');
-document.write('<\/object>');
-
-}
-
-else
-{
-
-// browser supports Netscape Plugin API
-
-document.write('<object id="myFlash" data="javascript-to-flash.swf"');
-document.write(' type="application/x-shockwave-flash"');
-document.write(' width="366" height="142">');
-document.write('<param name="movie" value="javascript-to-flash.swf" />');
-document.write('<param name="quality" value="high" />');
-document.write('<param name="swliveconnect" value="true" />');
-document.write('<p>You need Flash for this.');
-document.write(' Get the latest version from');
-document.write(' <a href="http://www.macromedia.com/downloads">here<\/a>.');
-document.write('<\/p>');
-document.write('<\/object>');
-
-}
-
- -

See also: Flash Satay

- -

The Object Element and Java

- -

Mozilla-based browsers such as Netscape 6.x, Netscape 7, and CompuServe 7 ship with the Java plugin that Sun provides. Users installing Netscape 6.x and Netscape 7 have a choice of whether or not to install Java. Unlike Netscape Communicator 4.x, Netscape 6.x and 7 do not have a default Java Virtual Machine -- they rely on Sun's plugin. During the Netscape Communicator 4.x days, Netscape Communications used to develop a Java Virtual Machine which supported Java 1.5.0 and below. Now, with Netscape 6 and 7, the Java Virtual Machine is Sun's plugin. Netscape no longer develops or ships a default Netscape Java Virtual Machine with the browser.

- -

Sun's Java plugin can be invoked by the object element, just like any other plugin. Once again, IE typically invokes the plugin by way of an object element used in conjunction with a classid attribute that points to an ActiveX Unique Identifier. Each major version of the plugin has a Unique Identifier. For instance, this is an example of the type of markup that will invoke the JRE 1.4.1 in IE, using the unique identifier for the JRE 1.4.1:

- -
<!-- IE ONLY CODE -->
-<object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
-     width="460" height="160"
-codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4_1-windows-i586.cab#version=1,4,1">
-     <param...>
-     <param...>
-</object>
-
- -

The above invocation won't work for Mozilla-based browsers such as Netscape 7 because of the same reason mentioned above: classid used in conjunction with a Unique Identifier references an architecture (ActiveX) that Mozilla code (and thus Netscape 7) does not support. You can invoke the Java plugin for Netscape 7 and other Mozilla-based browsers by using the appropriate Java MIME type. Here is an example:

- -
<object type="application/x-java-applet;jpi-version=1.4.1_01"
-width="460" height="160">
-	<param name="code" value="Animator.class" />
-	<param name="imagesource" value="images/Beans" />
-	<param name="backgroundcolor" value="0xc0c0c0" />
-	<param name="endimage" value="10" />
-	<param name="soundsource" value="audio">
-	<param name="soundtrack" value="spacemusic.au" />
-	<param name="sounds" value="1.au|2.au|3.au|4.au|5.au|6.au|7.au|8.au|9.au|0.au" />
-	<param name="pause" value="200" />
-	<p>You need the Java Plugin.
-         Get it from <a href="http://java.sun.com/products/plugin/index.html">here.</a></p>
-</object>
-
- -

The above code mentions a version specific MIME type, and if the Mozilla-based browser such as Netscape 7 doesn't have JRE 1.4.1_01 installed, the alternate text is displayed. It isn't always necessary to give such a version specific MIME type. If you aren't taking advantage of any version specific features, a more generic MIME type such as application/x-java-vm will do the job just as well. The configuration parameters for the applet, including the class which contains the initial entry point (Animator.class, referenced by the "code" param element), are specified in multiple param elements.

- -

Mozilla-based browsers such as Netscape 7 also allow for a special classid attribute that can also be used. This is the special "java:" classid. Here is an example using this invocation method:

- -
<object classid="java:NervousText.class" width="534" height="50">
-	<param name="text" value="Java 2 SDK, Standard Edition v1.4" />
-	<p>You need the Java Plugin.
-	   Get it from
-	   <a href="http://java.sun.com/products/plugin/index.html">here.
-	   </a>
-	</p>
-</object>
-
- -

The "java:" classid allows you to reference the class that provides the primary entry point. The rest of the configuration parameters work via the param elements.

- - - -

The applet element is still very much supported, and is the most popular way currently to invoke Java applets. In Netscape 7 and CompuServe 7, the applet element directly invokes the Java plugin. Here is a sample:

- -
<applet code="NervousText.class" width="534" height="50">
-	<param name="text" value="Java(TM) 2 SDK, Standard Edition v1.4" />
-</applet>
-
- -

The applet element has been deprecated in the HTML 4.01 specification, but an advantage to using it is that in Mozilla-based browsers such as Netscape 7, if you are missing Java, an automatic obtainment mechanism is in place. The browser will use Netscape's Plugin Finder Service to download the missing Java plugin. The References section gathers resources about the use of the applet element.

- -

The Embed Element

- -

The embed element has been used to invoke plugins since the early days of Netscape browsers. Typically, the embed element is nested within an object element, such that the outer object element invokes an ActiveX control for IE, whereas the inner embed element invokes a Netscape Plugin. Here is an example of this usage:

- -
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
-codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0"
-width=366 height=142 id="myFlash">
-	<param name="movie" value="javascript_to_flash.swf" />
-	<param name="quality" value="high" />
-	<param name="swliveconnect" value="true" />
-		<embed src="javascript_to_flash.swf" quality="high" width="366" height="142"
-    		type="application/x-shockwave-flash"
-    		pluginspage="http://www.macromedia.com/downloads/"
-    		name="myFlash" swliveconnect="true">
-    		</embed>
-</object>
-
- -

Links to the rules governing the use of the embed element can be found in the References section. The embed element is currently the most widely used element to invoke plugins in Netscape browsers. It is important to note, however, that the embed element is not part of the HTML 4.01 Specification, and is therefore not a W3C standard. Some caveats governing the use of the embed element are:

- - - -

Note that the obtainment mechanism for the embed element -- that is, the way in which a plugin is obtained if it is missing -- comes via the pluginspage attribute. This attribute points to a page to get the plugin if it is not detected by the browser. The pluginurl attribute is another attribute that can be used, and it can be used to point directly to an XPInstall file for a more streamlined download. For the embed element in particular, these attributes in Netscape 7 and Mozilla are governed by the Plugin Finder Service preference. Under Edit | Preferences | Navigator | Helper Applications is a preference to use Netscape's Plugin Finder Service. If the user has checked Always Use the Netscape Plugin Finder Service to get Plugins then whether these attributes are specified or not makes no difference -- the browser will always consult with the Plugin Finder Service to determine if it has a plugin to handle the missing MIME type. If the preference is unchecked, the Plugin Finder Service will be consulted only if the web page author does NOT specify either of these attributes.

- -

Original Document Information

- - - -

References

- -
General -- Specifications
- - - -
Object Element
- - - -
Embed Element
- - - -
Java
- - - -
Bugs and Future Directions In Netscape and Mozilla
- - diff --git "a/files/zh-cn/archive/\345\234\250\346\202\250\347\232\204\347\275\221\351\241\265\344\270\255\345\272\224\347\224\250web\346\240\207\345\207\206/index.html" "b/files/zh-cn/archive/\345\234\250\346\202\250\347\232\204\347\275\221\351\241\265\344\270\255\345\272\224\347\224\250web\346\240\207\345\207\206/index.html" deleted file mode 100644 index ac8ec6977a..0000000000 --- "a/files/zh-cn/archive/\345\234\250\346\202\250\347\232\204\347\275\221\351\241\265\344\270\255\345\272\224\347\224\250web\346\240\207\345\207\206/index.html" +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: 在您的网页中应用Web标准 -slug: Archive/在您的网页中应用Web标准 -tags: - - Web开发 - - Web标准 -translation_of: Archive/Using_Web_Standards_in_your_Web_Pages ---- -

-

-
"Browser makers are no longer the problem. The problem lies with designers and developers chained to the browser-quirk-oriented markup of the 1990s-often because they don't realize it is possible to support current standards while accommodating old browsers."
-Web Standards Project
-

本文对如何升级你的web页面以符合World Wide Web Consortium (W3C)web标准,提供了大致说明。前两个部分分别说明验证问题,验证的好处,错误原件,错误属性;然后通过提供推荐资料、教程和参考来告诉大家,如何升级页面以通过验证以及如何应用CSS。 -

The other sections address DOM and DHTML coding practices which are at odds with the W3C web standards and suggest replacements. Every proposed W3C web standards replacement in this article is working without a problem in modern browsers like MSIE 7, Firefox 2, Opera 9, Safari 2, Konqueror 3.5+, Icab 3, etc. -

The next-to-last section, Summary of Changes, outlines all the changes described in this article. The last section offers excellent and best references for those wishing to learn more about upgrading techniques presented in this article and more for those wishing to perfect their web pages. -

-

目录

-
  1. 使用web标准的好处 -
  2. Making your page using web standards - how to -
  3. 使用 W3C DOM -
  4. Developing Cross Browser/Cross Platform Pages -
  5. 使用 XMLHttpRequest -
  6. Summary of Changes -
  7. References -
-
-

原作信息

- -
diff --git a/files/zh-cn/components.classes/index.html b/files/zh-cn/components.classes/index.html deleted file mode 100644 index cab6e6d597..0000000000 --- a/files/zh-cn/components.classes/index.html +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Components.classes -slug: Components.classes -tags: - - 'XPCOM:Language Bindings' - - XPConnect -translation_of: Mozilla/Tech/XPCOM/Language_Bindings/Components.classes ---- -

 

- -

Components.classes 是一个只读的对象,其属性值是由 ContractID 索引的。

- -

简介

- -

Components.classes 是一个只读的对象,它的属性实现了 nsIJSCID 接口。每个对象都表示了 XPCOM components 的一个 class, 而且这个 class 能够被重构或作为一个 XPCOM service 来访问。

- -

该对象的属性是由 component class 的 ContractID 或 human-readable 可读的名称进行索引的。

- -

All of the properties and methods of the nsIJSCID 以及其父接口 nsIJSID 的所有属性和方法对于使用该对象的对象都是有效的。

- -

注意  Components.classes 反映了这些组件 classes 以及能够被预先安装并且由 component manager 使用 ContractIDs 预先注册上。如果你想要使用仅仅将  CID 注册的 class, 请使用 Components.classesByID 替换Components.classes 来进行获取。

- -

Note also that it is possible that a given add-on component with a given ContractID will be present on one machine but not have been installed on another machine. If the given element in the Components.classes object is not registered on the machine then trying to access it will generate a JavaScript warning in strict mode and the value returned will be the JavaScript value undefined. You should use the in operator to test for the element before trying to access it:

- -
if (!("@some/bogus/class;1" in Components.classes))
-  // do something...
-
- -

The properties of the Components.classes object can be enumerated using a for...in loop.

- -

用法

- -

为了能够检索到给定 ContractID 的对象,你可以按照下面的方式来查询Components.classes array :

- -
var clazz0 = Components.classes["@mozilla.org/messenger;1"];
-
- -

clazz0 是针对 ContractID @mozilla.org/messenger;1 的 class 对象, 它通常不是由自己来使用的,但是该对象的 createInstancegetService 方法可用来创建 component 的一个新的实例或访问一个单例的实例,如果 contact ID 代表一种服务的话。

- -

一个 新的 XPCOM component 实例 可以从通过返回的 class 对象来创建:

- -
var obj = Components.classes["@mozilla.org/supports-array;1"]
-                    .createInstance(Components.interfaces.nsISupportsArray);
-
- -

上面也可以简写成

- -
var obj = Components.classes["@mozilla.org/supports-array;1"]
-                    .createInstance();
-obj.QueryInterface(Components.interfaces.nsISupportsArray);
-
- -

如果你不向 createInstance() 提供一个特定的接口, 它就会返回一个 针对Component 的 XPConnect wrapper, 它会仅暴露  nsISupports interface 的方法 ( 在某些特定场合下,special wrappedJSObject property 也可以被使用).

- -

To access a service   (a singleton component, 要使用单例模式访问组件,就应该使用  getService 来替代 createInstance:

- -
 var os = Components.classes["@mozilla.org/observer-service;1"]
-                    .getService(Components.interfaces.nsIObserverService);
-
- -

The first time anyone accesses a service, the corresponding component is created under the hood.

- -

简化写法

- -

实际操作时,一般会将 Components.classesComponents.interfaces 的引用存储成常量的形式:

- -
const Cc = Components.classes, Ci = Components.interfaces;
-var os = Cc["@mozilla.org/observer-service;1"]
-         .getService(Ci.nsIObserverService);
-
- -

A less known trick, useful when creating multiple instances of the same component, is to use the new operator on the class object:

- -
var clazz = Components.classes["@mozilla.org/supports-array;1"];
-var inst  = new clazz(Components.interfaces.nsISupportsArray);
-
- -

This implicitly calls the createInstance() method for you. You still have to provide the interface name each time you create an instance, which is not necessary when using Components.Constructor.

- -

Determining if a component has to be instantiated or used as a service

- -

In the general case it is not possible to programmatically determine if a given component has to be instantiated or used as a service.

- -

Often, this is stated in the documentation of the component you want to use. If this is not the case, you might want to try and find example usages of that component within MXR.

- -

diff --git a/files/zh-cn/components.utils.evalinsandbox/index.html b/files/zh-cn/components.utils.evalinsandbox/index.html deleted file mode 100644 index 57df3fe2c7..0000000000 --- a/files/zh-cn/components.utils.evalinsandbox/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Components.utils.evalInSandbox -slug: Components.utils.evalInSandbox -tags: - - Developing Mozilla - - Extensions - - JavaScript - - XPConnect -translation_of: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.evalInSandbox ---- -

Introduction

- -

在某些情况下, 你希望将 JavaScript代码限定在可靠的执行环境 . 在Firefox 1.5 (Gecko 1.8) or 之后的版本, 有这么个API允许你去干这件事. 这里引入了“沙箱”的概念,你可以在沙箱中创建和执行代码. 这些代码的执行将会受到沙箱的限制,就像在一个普通的网页中一样。

- -

Use

- -

要使用 evalInSandbox(), 你得先使用构造函数创建一个沙箱对象。 Components.utils.Sandbox. 该沙箱必须使用origin URI 或者最好使用 DOM window (nsIDOMWindow, 就像网页中的 window 对象一样)来初始化. 在 Firefox 3 (Gecko 1.9) 及以后的版本, 你也可以通过 nsIPrincipal 对象来初始化. 使用 nsIPrincipal 比使用 origin URI更好。出于对安全的考虑, URI, window, or nsIPrincipal 会被当成"源"  (e.g. 就像同源安全检测)。比如,传入一个 URI  http://www.example.com/ ,将允许沙箱中的代码从该地址创建AJAX请求。如果沙箱中的代码设置了 document.domain, 那将会修改同源检测,你可以传递一个 DOM window 对象 or nsIPrincipal 给沙箱的构造函数,而不是URI。

- -

咱们看一个关于 URI的例子:

- -
// 通过 URI 创建沙箱
-var s = Components.utils.Sandbox("http://www.example.com/");
-
- -

这段代码创建了一个空的沙箱。 当你这么操作的时候 evalInSandbox(text, sandbox),它将作为一个全局对象存在。

- -

如果想在其中添加其他对象,看下面这个例子:

- -
s.y = 5;  // 添加属性 'y'值为 5 到全局范围
-var result = Components.utils.evalInSandbox("x = y + 2; x + 3", s);
-// result is 10, s.x is now 7
-
- -

 这就是个普通操作,也干不了什么坏事:

- -
s.foo = Components;
-// 报错 "Permission Denied"
-Components.utils.evalInSandbox("foo.classes", s);
-
- -

 另一方面, 沙箱中的任何函数都能够像chrome中的代码一样执行。你可以在下一节看到好几种骚操作。

- -

Note bug 350558.

- -

Security

- -
安全警告: 当你使用evalInSandbox() 的时候,如果你依赖沙箱中执行代码返回的对象属性时,会冒出一些潜在的安全问题。
- -

比如 :

- -
<script src="prototype.js"></script>
-
-<script>
-var s = new Components.utils.Sandbox(url);
-var x = Components.utils.evalInSandbox(untrusted_code, s);
-if (x == 1) {
-  /* 调用x.valueOf() 不安全 */
-}
-
-if (x === 1) {
-  /* this code is safe */
-}
-
-var y = x.y; /* this is unsafe */
-var z = sandbox.z; /* unsafe */
-
-if (typeof x == "number") {
-  /* safe */
-}
-</script>
-
- -

我们来看看安全问题是怎么产生的, 上面例子 (x == 1) 。x.valueOf() 方法执行的时候会通过chrome code 来调用。这个时候,不安全的代码就可以在chrome code 全局范围创造一个String对象。

- -

如果该chrome code 已经添加了具有chrome 某些方法的控制权,比如:String.prototype, Object.prototype, or Function.prototype,不安全的代码就能够滥用这些。不安全代码能够做什么,取决于这些方法是什么。不管怎么样,不安全代码最终都能以chrome的权限来执行。

- -

想要避免潜在安全隐患,你需要非常小心避免使用从evalInSandbox() 返回的对象,还有,你需要确保那些不受信任的JSON串在使用 evalInSandbox() 的时候不包括任何方法和表达式。

- -


- See also: PiggyBank analysis of sandbox

diff --git a/files/zh-cn/components.utils.import/index.html b/files/zh-cn/components.utils.import/index.html deleted file mode 100644 index 2ae0425882..0000000000 --- a/files/zh-cn/components.utils.import/index.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: Components.utils.import -slug: Components.utils.import -translation_of: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.import ---- -

- -

这个方法在 Firefox 3 中被引入,它使得在不同的作用域之间分享代码变得更加容易。例如:你可以直接导入 XPCOMUtils.jsm 而不必复制/粘贴冗长的XPCOM组件。

- -

查看 Using JavaScript code modules 了解更多细节。

- -
-

Note:  Gecko 2.0  之前, JavaScript code modules 仅可以使用  file:resource: URLs. Gecko 2.0 引入了对 chrome: URLs, even those inside JAR archives 的支持。

-
- -

Syntax(语法)

- -
Components.utils.import(url [, scope]);
-
-// Or, if you use a tool such as jslint which reports compiler errors for the above,
-
-Components.utils["import"](url [, scope]);
- -

Parameters(参数)

- -
-
url
-
一个将被导入的script的URL,这个URL必须是在磁盘上的一个文件,可能在JAR之中。
-
scope
-
一个可选的导入对象,如果省略则使用全局对象。当读取文件发生错误(如语法错误等)时会抛出异常。
-
- -

Example(例子)

- -
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-
- -

Difference from mozIJSSubScriptLoader(与mozIJSSubScriptLoader的区别)

- -

The differences from mozIJSSubScriptLoader:

- - - -

Additional Resources(其他资源)

- - - -

diff --git a/files/zh-cn/components_object/index.html b/files/zh-cn/components_object/index.html deleted file mode 100644 index d5279ff32c..0000000000 --- a/files/zh-cn/components_object/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Components -slug: Components_object -tags: - - DOM - - Gecko - - Gecko DOM Reference - - 'XPCOM:Language Bindings' - - XPConnect -translation_of: Mozilla/Tech/XPCOM/Language_Bindings/Components_object ---- -

Components 对象是 XPConnect 功能被映射到 JavaScript 上的对象。Components 对象的 native 实现位置在   nsIXPCComponents , 这个接口会被映射成JavaScript 作为使用 XPConnect 的最高层级的对象。

- -

Components 的一些属性需要高级的全写,可能在 web 页面中不能正常工作。

- -

 Components 对象包含下面的成员:

- -
-
classes
-
array of classes by ContractID
-
classesByID
-
array of classes by CID
-
Constructor
-
constructor for constructor of components
-
Exception
-
constructor for XPConnect exceptions
-
ID
-
constructor for XPCOM nsIDs
-
interfaces
-
array of interfaces by interface name
-
interfacesByID
-
array of interfaces by IID
-
isSuccessCode
-
function to determine if a given result code is a success code
-
lastResult
-
result code of most recent XPConnect call
-
manager
-
the global XPCOM component manager
-
results
-
array of known result codes by name
-
returnCode
-
pending result for current call
-
stack
-
current JavaScript call stack
-
utils
-
provides access to several useful features
-
-
-
utils.atline
-
Provides access to the value of the atline property in the JavaScript environment.
-
utils.createObjectIn
-
Creates a new object in the scope of the specified object's compartment. May only be called from JavaScript code.
-
utils.evalInSandbox
-
Runs JavaScript code in a sandbox, usually used to run code with restricted privileges.
-
utils.forceGC
-
Forces a garbage collection cycle.
-
utils.getGlobalForObject 
-
Returns the global object with which a given object is associated (through its prototype chain at birth, for example).
-
utils.getWeakReference 
-
Gets a weak reference for the object passed in.
-
utils.import 
-
Loads a JavaScript module into the current script, without sharing a scope.
-
utils.lookupMethod
-
Looks up a native (i.e. declared in the interface) method or property of an XPCOM object. Serves the same purpose as XPCNativeWrapper.
-
utils.makeObjectPropsNormal
-
Ensures that all functions come from the specified object's scope, and aren't cross-compartment wrappers. May only be called from JavaScript code.
-
- -
-
utils.methodjit 已废弃 Gecko 24.0
-
Provides access to the value of the methodjit property in the JavaScript environment.
-
- -
-
utils.methodjit_always 已废弃 Gecko 24.0
-
Provides access to the value of the methodjit_always property in the JavaScript environment.
-
- -
-
utils.relimit
-
Provides access to the value of the relimit property in the JavaScript environment.
-
- -
-
utils.reportError
-
Reports a JavaScript Error object to the Error Console.
-
utils.schedulePreciseGC
-
Requests that garbage collection occur sometime in the future when no JavaScript code is running; accepts a callback function to receive notification once collection is complete.
-
utils.setGCZeal()
-
Sets the GC zeal level for the context.
-
- -
-
utils.strict
-
Provides access to the value of the strict property in the JavaScript environment.
-
- -
-
utils.werror
-
Provides access to the value of the werror property in the JavaScript environment.
-
- -
-
utils.Sandbox
-
Creates sandbox objects for use with evalInSandbox.
-
utils.xml
-
Provides access to the value of the xml property in the JavaScript environment.
-
-
-
diff --git a/files/zh-cn/creating_a_python_xpcom_component/index.html b/files/zh-cn/creating_a_python_xpcom_component/index.html deleted file mode 100644 index 79d0b2481c..0000000000 --- a/files/zh-cn/creating_a_python_xpcom_component/index.html +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: 创建Python XPCOM组件 -slug: Creating_a_Python_XPCOM_component -translation_of: Mozilla/Tech/XPCOM/Creating_a_Python_XPCOM_component ---- -

Creating Applications with Mozilla 已经包含了一个教程用于编写简单的基于JavaScript和C++(实现nsISimple接口)的组件,本文阐述如何通过Python语言使用PyXPCOM创建相同的组件。

-

(Note that some details may be missing)

-

准备

-

如果你还没有PyXPCOM的二进制文件,请参考Building PyXPCOM以编译PyXPCOM的二进制文件。

-
- Tip: 你可以从PythonExt得到PyXPCOM的二进制文件归档拷贝,解压缩xpi文件并得到任何你想要的东西。
- -

如果你想在通常的Python可执行环境中使用PyXPCOM,你需要告诉Python在哪里可以找到PyXPCOM库。或许最好的办法就是在应用中设置变量PYTHONPATH指向'bin/python'目录。当然这在你的组件通过Mozilla被加载时是没有必要的因为Python加载器会完成sys.path的修改。

-

然后你可以

-
import xpcom
-
-

在任何Python模块里(大多数情况下是在你的组件中)。

-

定义接口

-

创建一个名为"nslPySimple.idl"的文件用于定义接口:

-
#include "nsISupports.idl"
-[scriptable, uuid(2b324e9d-a322-44a7-bd6e-0d8c83d94883)]
-interface nsIPySimple : nsISupports
-{
-    attribute string yourName;
-    void write( );
-    void change(in string aValue);
-};
-
-

这与在这里使用nsISimple是相同的。理论上由于多个组件可以共享一个接口,因此使用了相同的接口文件。

-

需要特别留意一下,Python和JavaScript都是弱类型的语言,所以比较容易从一个到另一个传递信息。

-

Note: There are exceptions; see this discussion for information on the use of string and wstring for unicode transfer. See here for info on describing interfaces, and on which types can be used.

-

注册接口

-

在"components"目录中执行如下命令:

-
../xpidl -m typelib -w -v -I /usr/share/idl/mozilla/ nsIPySimple.idl
-
-

在Windows中你必须要将idl目录指定成Mozilla构建目录。例如:

-
xpidl.exe -m typelib -w -v -I C:\source\mozilla\obj-i686-pc-mingw32\dist\idl foo.idl
-
-

然后xpidl将创建nslPySimple.xpt文件并正确放置到目录中(如'components'目录)。

-

实现组件

-

不同于C++,PyXPCOM为你做了很多事情。

-

创建了一个名为"py_simple.py"的文件用于实际的代码(同样是在'components'目录中)。

-
from xpcom import components, verbose
-
-class PySimple: #PythonTestComponent
-    _com_interfaces_ = components.interfaces.nsIPySimple
-    _reg_clsid_ = "{c456ceb5-f142-40a8-becc-764911bc8ca5}"
-    _reg_contractid_ = "@mozilla.org/PySimple;1"
-    def __init__(self):
-        self.yourName = "a default name" # or mName ?
-
-    def __del__(self):
-        if verbose:
-            print "PySimple: __del__ method called - object is destructing"
-
-    def write(self):
-        print self.yourName
-
-    def change(self, newName):
-        self.yourName = newName
-
-

接口下来是注册组件;这个步骤相同于其它组件,但在Python组件不可用的状态下会失败。

-

为了注册组件,你需要在bin目录中touch(创建)一个隐藏文件.autoreg,或者是删除xpti.dat文件。之后在下一次Mozilla启动时会重新构建组件的索引,包括任何'components'目录下新的组件。这对接下来通过命令行启动Mozilla以查看组件是否注册成功来讲非常有帮助。

-

生成实现模板

-

xpcom.xpt模块被用于内部以处理类型信息,但它有一个非常好的功能,可以为任何接口的Python实现生成一个模板。

-

以脚本的方式执行这个文件并且以接口名字作为参数。例如:

-
% cd c:\mozilla\bin\python\xpcom
-% python xpt.py nsISample
-class nsISample:
-    _com_interfaces_ = xpcom.components.interfaces.nsISample
-    # If this object needs to be registered, the following 2 are also needed.
-    # _reg_clsid_ = "{a new clsid generated for this object}"
-    # _reg_contractid_ = "The.Object.Name"
-
-    def get_value( self ):
-        # Result: string
-        pass
-    def set_value( self, param0 ):
-        # Result: void - None
-        # In: param0: string
-        pass
-
-

正如你所见到的,输出的是有效的Python代码,并带有每个方法的基本的方法签名和有效的注释信息。

-

测试

-

为了看到执行结果,你需要从命令行启动Firefox,因为那才是执行结果被打印出来的地方。

- - diff --git a/files/zh-cn/creating_xpi_installer_modules/index.html b/files/zh-cn/creating_xpi_installer_modules/index.html deleted file mode 100644 index f65d207afe..0000000000 --- a/files/zh-cn/creating_xpi_installer_modules/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: Creating XPI Installer Modules -slug: Creating_XPI_Installer_Modules -tags: - - Extensions - - XPInstall -translation_of: Archive/Mozilla/XPInstall/Creating_XPI_installer_modules ---- -

Introduction

-
-

这篇文章已经比较旧了,并且主要是针对Mozilla Suite和SeaMonkey (知道他成为Toolkit). 针对其他的应用,比如Firefox和Thundebird的Addons应该参照in a different way].

-
-

Mozilla has introduced major changes to the way that themes and all the other parts of the UI are packaged. This new packaging scheme is called XPI (pronounced "zippy"), and interacts with XPInstall. A XPI file typically contains the resources to be installed (in this case the barley.jar we want to have installed in the Mozilla/bin/chrome/ directory) and an install script that guides the installation process.

-

Under the chrome/ directory, you'll notice that in addition to the package subdirectories, there are now also a handful of JAR files, or Java archives (see figure below). JAR is a file format based on the ZIP file format and is used for aggregating multiple files into a single file. These archives are redundant with the subdirectories: Mozilla now installs both the compressed and uncompressed versions of the UI, though you can change this when you build Mozilla yourself.

-
chrome/
-  US/
-  US.jar
-  chatzilla/
-  chatzilla.jar
-  chrome.rdf
-  chromelist.txt
-  classic/
-  classic.jar
-  comm/
-  comm.jar
-  content-packs/
-  content-packs.jar
-  embed-sample/
-  embed-sample.jar
-  en-US/
-  en-US.jar
-  en-mac/
-  en-mac.jar
-  en-unix/
-  en-unix.jar
-  en-win/
-  en-win.jar
-  help/
-  help.jar
-  inspector/
-  inspector.jar
-  installed-chrome.txt
-  messenger/
-  messenger.jar
-  ...
-
-

In addition to these JAR files, there are also several new RDF files. These new files represent a redesign of the way that the Mozilla UI is packaged and installed. Though the chrome directory still includes subdirectories of uncompressed files by default, a new way to aggregate and distribute the files has improved performance, made the UI components more portable and easier to install, and made the installation process a much easier one.

-

However, this new arrangement does not make things much easier for the web or user interface developer. The relatively simple process of finding the appropriate resources (i.e. XUL, JavaScript, or CSS files) in the chrome subdirectories and editing them with a text editor has been replaced by something a lot of developers find more confusing and esoteric. This article describes the new packaging scheme of Mozilla and offers a tutorial for creating a new package that can then be redistributed, installed, and made available to users.

-

The XPI Packaging Scheme

-

A complete description of the new packaging scheme is beyond the scope of this article. The reader is referred to JAR Packaging, which describes the design, goals, and options available for JAR packaging in some depth. What follows is a very brief overview of the design and a description of what Mozilla expects in installable packages.

-

Resources are collected in JAR archives whose contents are specified in contents.rdf files at their own top level. The contents.rdf file explains the structure and contents of the archive to Mozilla's chrome registry; as long as the explanation is accurate, the contents can be arranged in almost any way you want. In the package you create in this tutorial, for example, all of the resources are located under the content/ subdirectory, but they could just as easily have been archived directly at the top--along with skin and locale resources, if you wanted.

-

Where before a single manifest.rdf file described the resources in an entire package directory or archive, now contents.rdf files can be used for as large or as small a part of your package description as you want; you can use several contents.rdf files in your package to describe the various parts (e.g., one for the skin of your package, another for the content, and so on), or you can use a single one, as was common before.

-

Mozilla is alerted to these content specifications and the resources they manage either through registration as part of an installation process (as described in this tutorial) or by way of a shortcut file called installed-chrome.txt, in which developers can point at their new contents.rdf files and have them registered as they develop (a process we do not describe here). One way of another, the chrome registry is shown the contents.rdf files; the contents.rdf files in turn point to new resources, and the resources are then registered with Mozilla and accessible to the user.

-

Creating a New Package

-

The package described in this section is a very simple one, but it uses the new packaging scheme and the chrome registry to make itself a piece of self-contained and redistributable software. Once you have created a package like the one described here, Mozilla users can download and install it in a single step.

-

The Barley Package

-

The Barley windowThe barley package is a simple XUL window with a couple of buttons and an image element. One of the buttons, labeled "show aphids", displays an alert dialog by calling a function defined in the JavaScript file barley.js.

-

Since we are not updating the Mozilla UI to provide special access to this window (e.g., an item in the Tasks menu or elsewhere), the measure of the success of the installation of the barley package is that the user can, as before, invoke our software by using a special startup option:

-
mozilla -chrome chrome://barley/content
-
-

This option tells Mozilla to load a chrome other than the default, which is the main browser window. For this option to work, the designated chrome must have been installed and registered properly with Mozilla. The chrome:// url pointer corresponds to the directory Mozilla/bin/chrome/barley/content, where the main XUL file and the other resources live once they are installed.

-

Package Creation Overview

-

This tutorial describes the following sequence of steps for creating a new package:

- -

You can examine (or install!) the package described here by downloading the Barley XPI file and using a ZIP unarchiver{{Ref("zip")}} to open it.

-

All of the resources described in this article are in the XPI archive and can be adapted for use in your own development.

-

Developing the Resources

-

Needless to say, one of the first things you will have to create is the actual software you wish to make redistributable. The Barley package UI is a single XUL window with an accompanying image:

-
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
-
-<window title="barley window"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul"
-  width="175" height="375" x="20" y="20" persist="width height x y"
-  orient="vertical"
-  autostretch="always">
-
-  <script src="barley.js"/>
-
-  <image src="barley.gif" />
-    <box orient="horizontal" autostretch="never">
-      <button label="barley corn" />
-      <button label="show aphids" oncommand="bar();" />
-    </box>
-</window>
-
-

The other files that the window imports are defined in dark blue. Note that the stylesheet processing instruction at the top of the XUL file does not refer to any new skin, but imports communicator.css to make use of that skin's basic widget styles.

-

The JavaScript file barley.js contains a single function, bar(), defined as follows:

-
function bar() {
-  alert("aphids");
-}
-

If you want to use the same GIF image that is used in the Barley package, it can be grabbed from here.

-

While you are developing these resources and before you have made them a package of their own, you can test the basic layout and functionality by opening barley.xul from within Mozilla by using File -> Open. Though Mozilla will not display the file as a separate window (much less interpret it as a separate package), you ought to be able to see the image and the JavaScript function working as defined in barley.js (provided that both all three files are in the same working directory).

-

Organizing the Resources

-

Now that you have created the basic files to be included in your package, you should put them all in a single directory so that they can be bundled up. When your package includes its own theme, localization packs, or other components it's convenient (but not necessary to create a subdirectory structure that reflects the role of the different parts. For the Barley package, you only need to create a single subdirectory, content/ (see figure below).

-
barley/
-  content/
-    barley.gif
-    barley.js
-    barley.xul
-
-

Creating the contents.rdf File

-

One of the most important ingredients of the software package is the contents.rdf file that describes the contents of the package in terms that the chrome registry can make sense of. For a package such as this one with its own content but no special localization or custom skin, the contents.rdf file describes package in terms of its relation to the "root" package of Mozilla. In the following listing, the items in red are particular to the barley package and can be edited for your own distribution:

-
<?xml version="1.0"?>
-<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
-
- <!-- list all the packages being supplied -->
- <RDF:Seq about="urn:mozilla:package:root">
-   <RDF:li resource="urn:mozilla:package:barley"/>
- </RDF:Seq>
-
- <!-- package information -->
- <RDF:Description about="urn:mozilla:package:barley"
-   chrome:displayName="Barley Grain"
-   chrome:author="Ian Oeschger"
-   chrome:name="barley">
- </RDF:Description>
-
-</RDF:RDF>
-
-

Create a contents.rdf file like the one in the listing above and put it in the content/ subdirectory with the other package resources.

-
 barley/
-  content/
-    barley.gif
-    barley.js
-    barley.xul
-    contents.rdf
-
-

These four files are all you need in your new package. The next step is to zip up the contents of the working directory. Using a ZIP archiver{{Ref("zip")}}, create a new archive of the content/ subdirectory and name it barley.jar:

-

Image:Barley_JAR.png

-

Once this step is complete, the Barley package is in the same state as the JAR packages of the Mozilla UI. comm.jar, en-US.jar, and all of the other archived UI packages have a similar--if slightly more complex--structure and content specification as the barley.jar.

-

Making the Barley Install Script

-

What remains is to package up your JAR file in such a way that it can be installed using Mozilla's XPInstall technology. The XPI file format is used to designate archives that use Mozilla's XPInstall to install themselves.

-

For Barley, that installation script should read as follows:

-
// initInstall(name + version, name, version);
-var err = initInstall("barley v", "barley", "");
-
-logComment("initInstall: " + err);
-
-addFile("Barley Grain",       // displayName from contents.rdf
-  "barley.jar",               // JAR source
-  getFolder("Chrome"),        // target folder
-  "");                        // target subdir
-
-// registerChrome(TYPE, location, source)
-registerChrome(PACKAGE | DELAYED_CHROME, getFolder("Chrome","barley.jar"), "content/");
-
-if (err==SUCCESS) {
-  performInstall();
-} else {
-  cancelInstall(err);
-}
-

Note that there is no version number on Barley, and so the name + version parameter has a "v" and then nothing else. Note also the use of resource attributes specified in the contents.rdf file in the JAR. It is the correspondence of this installation script, the resources themselves, and the contents.rdf file that registers the package and makes it available.

-

Creating a XPI

-

The final step in the tutorial is to create a XPI archive in which the install.js script and the barley.jar can be redistributed. The archiving of an archive may seem a little redundant--and if you want you can instead use the XPI to archive the install script and "flat", or uncompressed, versions of the resources. But the XPI puts all of the resources of your package together, including the instructions for installing it. Like the JAR format that Mozilla uses to archive the UI packages, the XPI format is just a specially-ordered ZIP file. For a XPI file to be valid and installable, it must contain an installation script like the one above that tells Mozilla XPInstall where to put the new resources and how to register them.

-

To create a XPI, use your ZIP archiver{{Ref("zip")}} again to archive the JAR file and the installation script install.js. The archive, named barley.xpi, should contain the following two files:

-
barley.jar
-install.js
-
-

This ZIP file, when opened from Mozilla using File -> Open, will initialize its own installation and display a message like the following:

-

Image:Barley_dlog.png

-

When you click OK, Mozilla installs the new package. Exit Mozilla and restart it with

-
mozilla -chrome chrome://barley/content
-

and the new package displays. The resources are installed in the mozilla/bin/chrome/ directory, and the XPI itself can be redistributed for installation on other machines.

-

Notes

-
    -
  1. {{Note("zip")}} There exist a lot of ZIP archivers/unarchivers. For Unix, you can either use the preinstalled zip tool, or e.g. 7-Zip (free software). For Windows, you can e.g. use 7-Zip (free software), or WinZip (commercial).
  2. -
-

See also

- -
-

Original Document Information

- -
diff --git a/files/zh-cn/debugging_javascript/index.html b/files/zh-cn/debugging_javascript/index.html deleted file mode 100644 index fa6e0d7a61..0000000000 --- a/files/zh-cn/debugging_javascript/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: 调试 JavaScript -slug: Debugging_JavaScript -translation_of: Mozilla/Debugging/Debugging_JavaScript ---- -

This document is intended to help developers writing JavaScript code in Mozilla, mainly for Mozilla itself, but it may also be useful for web developers. It should give pointers to tools, aids and tricks which make debugging your code easier.

-

Web Console

-

This is the first place to go when you're debugging a web page; open the Web console using the Web Console option in the Web Developer menu. This shows any JavaScript errors in your app, as well as any logging calls from the console API.

-

Browser Console

-

The Browser Console lets you see all JavaScript errors and logging in the browser, including from Firefox code. To enable it, go to about:config in the url bar and set devtools.chrome.enabled to true. Activate it through with the menu Tools > Web Developer > Browser Console.

-

Log to the Browser Console using the standard console API after importing Console.jsm:

-
let console = (Cu.import("resource://gre/modules/devtools/Console.jsm", {})).console;
-console.log("Hello from Firefox code");
-

Error Console

-

On versions of Firefox predating the Web Console, this is the first thing you should check when there's a problem. You can get to this by choosing the Error Console menu item under the Tools menu or using -jsconsole on the command line.

-

Browser Debugger (Built-in)

-

On Firefox 19 or later, it's possible to use the built-in JS debugger on the browser itself.  Go to about:config and set the following two prefs:

-
devtools.chrome.enabled: true
-devtools.debugger.remote-enabled: true
-

After you restart the browser, you can access the Browser Debugger through Tools > Web Developer > Browser Toolbox. (Note that before Firefox 28, this was labeled "Browser Debugger" and only the debugger was available, not the whole toolbox.)

-

Access the "Browser Toolbox" through the menu

-

Note that you must accept the incoming connection :

-

Accept the incoming connection from the toolbox

-

Then, the Browser Toolbox displays the available tools for debugging. (Note that before Firefox 28, only the script debugger was available.) The use of these tools are the same as the Built-in Tools.

-


- The connected browser toolbox

-

Strict code checking

-

If you set the pref javascript.options.strict to true, the JavaScript engine gives you more types of warnings on the Error Console, most of which hint at code bugs that are easy to oversee or even bad syntax. (The pref also warns on common JavaScript idioms that are not errors).

-

Console.log in Browser Console

-

You can dump variables in the Browser Console from addon code, by adding this line to import the console utility:

-

const { console } = Components.utils.import("resource://gre/modules/devtools/Console.jsm", {});

-

This has an advantage over dump in that you can list out properties of an object logged with console.log.

-

dump()

-

The dump() function allows you to print text on the native console. Use \n to output a newline at the end.

-

To see anything, you need to set the pref browser.dom.window.dump.enabled to true, e.g. in about:config (add new pref, it doesn't exist per default).

-

Under Microsoft Windows you additionally need to start Firefox via the following command to have a native console :

-
firefox.exe -console
-
-

Using normal JavaScript object inspection, you can write a function that dumps a whole object, similar to this ddumpObject().

-

Log.jsm (formerly log4moz)

-

This is a partial implementation of the Log4* interfaces (for example, see log4j or log4net).

-
Components.utils.import("resource://gre/modules/Log.jsm");
-

"debugger" keyword

-

You can halt Venkman or Chromebug at a line using the keyword debugger. In debug builds this also dumps a stack trace to the console, even when the debugger is not running. In extensions you can print the callstack using Components.stack like this:

-
function getStackDump() {
-  var lines = [];
-  for (var frame = Components.stack; frame; frame = frame.caller) {
-    lines.push(frame.filename + " (" + frame.lineNumber + ")");
-  }
-  return lines.join("\n");
-}
-
-

Scratchpad

-

Scratchpad has chrome privileges if devtools.chrome.enabled = true. Change the scratchpad to evaluate in the context of the current browser window by setting Environment > Browser in the menu.

-

See Also

- -
-

Original Document Information

- -
- -

 

- - diff --git a/files/zh-cn/drag_and_drop/index.html b/files/zh-cn/drag_and_drop/index.html deleted file mode 100644 index 323e6bf658..0000000000 --- a/files/zh-cn/drag_and_drop/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: 拖拽 -slug: Drag_and_Drop -translation_of: Archive/Mozilla/Drag_and_drop ---- -

{{ Next("Drag and Drop JavaScript Wrapper") }}

- -

{{ deprecated_header("gecko1.9.1") }}

- -
自 Gecko 1.9.1 (Firefox 3.5)起,此API已被官方正式弃用。更新的、更简单、更便捷(portable)的API应该被用来替换此API(should be used in their place)。
- -

这部分描述了怎样实现可以拖拽和拖放到其他对象上的可拖拽对象。

- -

拖拽和拖放接口

- -

很多用户界面都允许用户在界面内拖拽某些具体的对象(Many user interfaces allow one to drag particular objects around within the interface)。举个例子来说,拖拽一些文件到其他目录下;或者以拖拽一个图标到另一个窗口的方式来打开这个图标所指代的文档。Mozilla 和 XUL 提供一些事件来处理用户试图拖拽对象时的状态。

- -

用户以按住鼠标然后移动鼠标的方式开始拖拽。当用户释放鼠标时,拖拽过程停止。事件处理器可以在拖拽开始时、停止时、还有拖拽过程中间时被调用。

- -

Mozilla 通过拖拽会话(drag session)实现了拖拽。当用户要求拖拽某个可拖拽对象时,开始一个拖拽会话(drag session)。由拖拽会话(drag session)更新鼠标指针的位置,并处理可拖拽对象最后拖放的位置。如果一个对象不可拖拽,则不会开始一个拖拽会话(drag session)。由于用户通常只有一个鼠标,所以同一时刻只有一个拖拽会话(drag session)处于使用状态。

- -

注意,拖拽会话(drag session)可以由Mozilla本身或其他应用创建。Mozilla会转换需要的拖拽数据(will translate the data being dragged as needed)。

- -

下面的列表描述了可以被调用的事件处理器,这些处理器可以绑定在任意元素上。You only need to put values for the handlers where you need to do something when the event occurs.

- -
-
ondrag {{ Fx_minversion_inline(3) }}
-
周期性地调用,贯穿整个拖拽和拖放全程。
-
ondraggesture 
-
当用户开始拖拽一个元素时被调用,确切地说是当用户按住鼠标按键并移动鼠标时。The script in this handler should set up a drag session.
-
ondragstart {{ Fx_minversion_inline(3) }} 
-
An alias for ondraggesture; this is the HTML 5 spec name for the event and may be used in HTML or XUL; however, for backward compatibility with older versions of Firefox, you may wish to continue using ondraggesture in XUL.
-
ondragover 
-
This event handler is called for an element when something is being dragged over top of it. If the object can be dropped on the element, the drag session should be notified.
-
ondragenter 
-
Called for an element when the mouse pointer first moves over the element while something is being dragged. This might be used to change the appearance of the element to indicate to the user that the object can be dropped on it.
-
ondragexit 
-
Called for an element when the mouse pointer moves out of an element while something is being dragged. The is also called after a drop is complete so that an element has a chance to remove any highlighting or other indication.
-
ondragdrop 
-
This event handler is called for an element when something is dropped on the element. At this point, the user has already released the mouse button. The element can simply ignore the event or can handle it some way, such as pasting the dragged object into itself.
-
ondragend {{ Fx_minversion_inline(3) }} 
-
Called when the drag operation is finished.
-
- -

There are two ways that drag and drop events can be handled. This first involves using the drag and drop XPCOM interfaces directly. The second is to use a JavaScript wrapper object that handles some of this for you. The code for this wrapper can be found in a file named {{ Source("toolkit/content/nsDragAndDrop.js nsDragAndDrop.js") }} which is contained in the widget-toolkit (or global) package.

- -

XPCOM Drag and Drop interfaces

- -

Two interfaces are used to support drag and drop. The first is a drag service, nsIDragService and the second is the drag session, nsIDragSession.

- -

The nsIDragService is responsible for creating drag sessions when a drag starts, and removing the drag session when the drag is complete. The function invokeDragSession should be called to start a drag inside an ondraggesture event handler. Once this function is called, a drag has started.

- -

The function invokeDragSession takes four parameters, as described below:

- -
invokeDragSession(element,transferableArray,region,actions)
-
- -
-
element 
-
A reference to the element that is being dragged. This can be retrieved by getting the property event.target during the event handler.
-
transferableArray 
-
An array of nsITransferable objects, one for each item being dragged. An array is used because you might want to drag several objects at once, such as a set of files.
-
region 
-
A region used for feedback indication. This should usually be set to null.
-
actions 
-
The actions that the drag uses. This should be set to one of the following constants, or several added together. The action can be changed during the drag depending on what is being dragged over.
-
- -
-
nsIDragService.DRAGDROP_ACTION_NONE 
-
-
-
Used to indicate that no drag is valid.
-
nsIDragService.DRAGDROP_ACTION_COPY 
-
The item being dragged should be copied to its dropped location.
-
nsIDragService.DRAGDROP_ACTION_MOVE 
-
The item being dragged should be moved to its dropped location.
-
nsIDragService.DRAGDROP_ACTION_LINK 
-
A link (or shortcut or alias) to the item being dragged should be created in the dropped location.
-
-
-
- -

The interface {{ interface("nsIDragService") }} also provides the function getCurrentSession which can be called from within the drag event handlers to get and modify the state of the drag. The function returns an object that implements {{ interface("nsIDragSession") }}.

- -

The interface nsIDragSession is used to get and set properties of the drag that is currently occuring. The following properties and methods are available:

- -
-
canDrop 
-
Set this property to true if the element the mouse is currently over can accept the object currently being dragged to be dropped on it. Set the value to false if it doesn't make sense to drop the object on it. This should be changed in the ondragover and ondragenter event handlers.
-
dragAction 
-
Set to the current action to be performed, which should be one or more of the constants described earlier. This can be used to provide extra feedback to the user.
-
numDropItems 
-
The number of items being dragged. For example, this will be set to 5 if five bookmarks are being dragged.
-
getData(transfer,index) 
-
Get the data being dragged. The first argument should be an nsITransferable object to hold the data. The second argument, index, should be the index of the item to return.
-
sourceDocument 
-
The document where the drag started.
-
sourceNode 
-
The DOM node where the drag started.
-
isDataFlavorSupported(flavor) 
-
Returns true if the data being dragged contains data of the specified flavor.
-
- -

{{ Next("Drag and Drop JavaScript Wrapper") }}

- -
-

Original Document Information

- - -
- -
- -
diff --git a/files/zh-cn/drag_and_drop_example/index.html b/files/zh-cn/drag_and_drop_example/index.html deleted file mode 100644 index f8dfde8835..0000000000 --- a/files/zh-cn/drag_and_drop_example/index.html +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: Drag and Drop Example -slug: Drag_and_Drop_Example -translation_of: Archive/Mozilla/Drag_and_drop/Drag_and_Drop_Example ---- -

拖拽实例

-

{{ Previous("Drag and Drop JavaScript Wrapper") }}

-
- Gecko 1.9.1 (Firefox 3.5) and later supports a newer and simpler API.
-

An example of implementing drag and drop will be implemented in this section.

-

Dragging Elements Around

-

Here, we'll create a simple board where items from a palette can be dragged onto the board. The user can click on one of several XUL elements on the palette and drag it onto a stack element to create an element of a particular type.

-

创建一个面板,用于拖拽目的地。把调色板元素拖拽到 stack 元素上创建一个特殊类型的元素值。

-

First, we'll add the wrapper scripts:

-

首先,我们需要添加封装脚本。

-
<script src="chrome://global/content/nsDragAndDrop.js"/>
-<script src="chrome://global/content/nsTransferable.js"/>
-<script src="dragboard.js"/>
-
-

An additional script file dragboard.js is included which will contain the code we will write ourselves.

-

我们需要自己编写 dragboard.js 文件。

-

The board will be created using a stack element. We'll use some style properties to set the width and height of the stack. A maximum size is also specified so that it doesn't resize when new elements are dragged onto it.

-

使用 stack 创建一个面板。使用CSS样式设置 stack 的宽和高。需要设置一个最大值。这样拖拽进来的元素不会改变其大小。

-

The board will need to respond to the dragdrop event so that an element is created when the user drags onto it.

-

面板需要对 dragdrop 事件进行响应,这样,拖拽到面板时,才会创建相应元素。

-
<stack id="board"
-       style="width:300px; height: 300px; max-width: 300px; max-height: 300px"
-       ondragover="nsDragAndDrop.dragOver(event, boardObserver)"
-       ondragdrop="nsDragAndDrop.drop(event, boardObserver)">
-</stack>
-
-

The board only needs to respond to the dragdrop and dragover events. We'll add a boardObserver to the file dragboard.js in a moment.

-

该面板只需要响应 dragdrop 和 dragover 事件。我们需要在 dragboard.js 文件中添加 boardObserver 对象。

-

Next, a palette will be added to the right side of the window. It will contain three buttons, one to create new buttons, one to create check boxes and the other to create textboxes. This buttons will respond to the draggesture event and start a drag.

-

接着,调色板需要添加到窗口的右侧位置。它包含三个按钮,一个用于创建新按钮,一个用于创建复选框,另一个用于创建文本框。这些按钮将响应 draggesture 事件,并开始拖拽。

-
<vbox>
-  <button label="Button"
-          elem="button"
-          ondraggesture="nsDragAndDrop.startDrag(event, listObserver)"/>
-  <button label="Check Box"
-          elem="checkbox"
-          ondraggesture="nsDragAndDrop.startDrag(event, listObserver)"/>
-  <button label="Text Box"
-          elem="textbox"
-          ondraggesture="nsDragAndDrop.startDrag(event, listObserver)"/>
-</vbox>
-
-

The nsDragAndDrop object will be called to do most of the work. We'll create a listObserver object that will set the data to be dragged. Note that each button here has an additional elem attribute. This is a made-up attribute. XUL doesn't handle it and just ignores it, but we can still retrieve it with the DOM's getAttribute function. We need this so that we know what type of element to create when dragging.

-

listObserver 对象设置被拖拽的数据,每个按钮都有一个附件属性 elem,为自定义属性。XUL不处理它,只是忽略它,但是我们可以通过 getAttirbute 方法检索到它。通过它我们可以确知在拖拽的时候创建什么类型的元素。

-

Next, we'll define the two listener objects. First, the listObserver which needs a function to handle the start of the drag.

-

接着,我们定义两个侦听对象。首先, listObserver 需要定义一个函数处理开始拖拽行为。

-
var listObserver = {
-  onDragStart: function (event, transferData, action) {
-    var txt = event.target.getAttribute("elem");
-    transferData.data = new TransferData();
-    transferData.data.addDataForFlavour("text/unicode", txt);
-  }
-}
-
-

One function has been defined, onDragStart, which will be called by the nsDragAndDrop object when necessary. The function adds the data to be dragged to the transfer object. The elem attribute is retrieved from the target of the drag event. The target will be the element that had the drag start on. We'll use the value of this attribute as the data of the drag.

-

定义了一个函数 onDragStart,需要时, nsDragAndDrop 会调用该方法。该方法向 transfer 对象添加了用于拖拽的数据。elem 属性可以从拖拽事件的目标体中获取。目标体即是拖拽行为的附属体。我们将使用该属性值作为我们拖拽的数据。

-

The boardObserver will need three functions, getSupportedFlavours, onDragOver and onDrop. The onDrop function will grab the data from the drag session and create a new element of the appropriate type.

-

boardObserver 需要三个函数,getSupportedFlavours,onDragOver, onDrop。其中 onDrop 方法将从拖拽回会话中获取数据,并创建一个合适类型的元素。

-
var boardObserver = {
-  getSupportedFlavours : function () {
-    var flavours = new FlavourSet();
-    flavours.appendFlavour("text/unicode");
-    return flavours;
-  },
-
-  onDragOver: function (event, flavour, session) {},
-
-  onDrop: function (event, dropdata, session) {
-    if (dropdata.data != "") {
-      var elem = document.createElement(dropdata.data);
-      event.target.appendChild(elem);
-      elem.setAttribute("left", "" + event.pageX);
-      elem.setAttribute("top", "" + event.pageY);
-      elem.setAttribute("label", dropdata.data);
-    }
-  }
-}
-
-

The getSupportedFlavours function needs only to return a list of flavours that the stack can accept to be dropped on it. In this case, it only accepts text. We don't need to do anything special for the onDragOver function, so no code is added in its body.

-

getSupportedFlavours 方法只需返回一系列的数据类型,这些数据类型即是 stack 可以接收的拖拽数据的数据类型。上述例子中,只能接收 text。我们不需要在拖拽过程中做特殊处理,所以 onDragOver 方法为空。

-

The onDrop handler first uses the createElement function to create a new element of the type stored in the drag session. Next, appendChild is called to add the new element to the stack, which is the target of the event. Finally, we set some attributes on the new element.

-

onDrop 方法初次使用 createElement 方法创建拖拽会话中存储类型的元素。接下来, appendChild 方法向 stack(即事件的目标体)中添加了一个新元素。最后,我们对该元素设置了一些属性。

-

The position of elements in a stack is determined by the left and top attributes. The values of the pageX and pageY properties store the mouse pointer coordinates on the window where the drop occured. This allows us to place the new element at the position where the mouse button was released. This isn't quite the correct way to do this as we actually need to calculate the coordinates of the event relative to the stack. It works here because the board is at the top-left corner of the window.

-

 stack 中元素的位置取决于其 left 和 top属性。pageX 和 pageY 属性存储了拖拽时鼠标指针在窗口上的坐标值。

-

The label attribute is set to the data from the drag also so that the button has a default label.

-

This example is fairly simple. One possible change is to use a custom flavour for the data instead of text. The problem with using text is that if the text from an external drag just happens to be set to button, a button will be created on the board. A custom type means that the board will only accept drags from the palette.

-

 

-

The final code is shown below:

-
<window title="Widget Dragger"
-        id="test-window"
-        orient="horizontal"
-        xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul">
-
-  <script src="chrome://global/content/nsDragAndDrop.js"/>
-  <script src="chrome://global/content/nsTransferable.js"/>
-  <script src="dragboard.js"/>
-
-  <stack id="board"
-         style="width:300px; height: 300px; max-width: 300px; max-height: 300px"
-         ondragover="nsDragAndDrop.dragOver(event, boardObserver)"
-         ondragdrop="nsDragAndDrop.drop(event, boardObserver)">
-  </stack>
-
-  <vbox>
-    <button label="Button"
-            elem="button"
-            ondraggesture="nsDragAndDrop.startDrag(event, listObserver)"/>
-    <button label="Check Box"
-            elem="checkbox"
-            ondraggesture="nsDragAndDrop.startDrag(event, listObserver)"/>
-    <button label="Text Box"
-            elem="textbox"
-            ondraggesture="nsDragAndDrop.startDrag(event, listObserver)"/>
-  </vbox>
-</window>
-
-
var listObserver = {
-  onDragStart: function (event, transferData, action) {
-    var txt = event.target.getAttribute("elem");
-    transferData.data = new TransferData();
-    transferData.data.addDataForFlavour("text/unicode", txt);
-  }
-};
-
-var boardObserver = {
-  getSupportedFlavours : function () {
-    var flavours = new FlavourSet();
-    flavours.appendFlavour("text/unicode");
-    return flavours;
-  },
-
-  onDragOver: function (event, flavour, session) {},
-
-  onDrop: function (event, dropdata, session) {
-    if (dropdata.data != "") {
-      var elem = document.createElement(dropdata.data);
-      event.target.appendChild(elem);
-      elem.setAttribute("left", "" + event.pageX);
-      elem.setAttribute("top", "" + event.pageY);
-      elem.setAttribute("label", dropdata.data);
-    }
-  }
-};
-
-

{{ Previous("Drag and Drop JavaScript Wrapper") }}

-
-

Original Document Information

- -
-

 

diff --git a/files/zh-cn/dynamically_modifying_xul-based_user_interface/index.html b/files/zh-cn/dynamically_modifying_xul-based_user_interface/index.html deleted file mode 100644 index 753491960c..0000000000 --- a/files/zh-cn/dynamically_modifying_xul-based_user_interface/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Dynamically modifying XUL-based user interface -slug: Dynamically_modifying_XUL-based_user_interface -translation_of: Archive/Mozilla/XULRunner/Build_Instructions ---- -

--刀波儿 18:39 2007年12月21日 (PST)

-
-

Headline text

-

link title

diff --git a/files/zh-cn/extensions/firefox/index.html b/files/zh-cn/extensions/firefox/index.html deleted file mode 100644 index 9bbac87b84..0000000000 --- a/files/zh-cn/extensions/firefox/index.html +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Firefox -slug: Extensions/Firefox -translation_of: Mozilla/Add-ons ---- -

The following articles provide help with developing extensions for Firefox. In addition, please refer to the general extension documentation that applies to all Mozilla applications. In the future, you may also develop extensions with an alternative, trimmed down but simpler API developed at Mozilla labs' Jetpack project.

- -

Documentation

Community

  • View Mozilla forums...

{{ DiscussionList("dev-extensions", "mozilla.dev.extensions") }}

Tools

... more tools ...

View All...

XUL, JavaScript, XPCOM, Themes, Developing Mozilla
-
-

{{ languages( { "ja": "ja/Extensions/Firefox" } ) }}

-
diff --git a/files/zh-cn/extensions/index.html b/files/zh-cn/extensions/index.html deleted file mode 100644 index 7dbf1a691f..0000000000 --- a/files/zh-cn/extensions/index.html +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 扩展 -slug: Extensions -tags: - - Extensions - - 扩展 -translation_of: Mozilla/Add-ons ---- -
- 构建一个扩展
- 一步步地了解如何为 Firefox 构建一个扩展。
-
-

扩展是能为 Mozilla 程序(例如 Firefox、Seamonkey和 Thunderbird)添加新功能的小巧的附加软件。从工具栏按钮到全新特性,它们能添加任何东西。它们允许用户定制程序,以适合自己的个性需要(如果他们需要新的特性);同时又保持了程序的小巧,方便下载。

-

扩展不同于插件,插件帮助浏览器现实类似于播放多媒体文件这样的特定的内容。扩展也不同于搜索插件,搜索插件在搜索栏插入附加的搜索引擎。

-
-

基本取自于 Mozilla Update 中国,但是也有不少修改的地方。

- - - - - - - -
-

文档

-

 

-

常规 (适用于全部 Mozilla 应用程序)

-
-
- 设置扩展的开发环境
-
- 一些可以令开发扩展更容易的设置的精华提示。
-
- 引导式扩展 {{gecko_minversion_inline("2.0")}}
-
- 介绍创建无需重启即可被安装、卸载和升级的扩展的方法。
-
- XUL 学习教程
-
- 一个全面的扩展开发教程
-
- 构建一个扩展
-
- 一步步地阐述如何创建一个扩展。
-
- 内嵌选项
-
- {{gecko_minversion_inline("7.0")}}
-
- 介绍如何自定义在Firefox 7开始出现的内嵌在附加组件管理器窗口中的新用户界面。
-
- 扩展安全性指导(英)
-
- 指导开发人员,以确保用户扩展的安全性
-
- 扩展性能指导(英)
-
- 介绍如何创建优质且高效的扩展。
-
- 扩展用户体验指导(英)
-
- 通用的尽可能提高扩展用户体验的做法。
-
- 扩展打包
-
- 如何把你的 Firefox 扩展打包,以供下载和安装。
-
- XUL
-
- 介绍用于描述Mozilla扩展用户界面的XUL标记语言。
-
- 性能(英)
-
- 提供一些帮助你提高附加组件性能(且体验良好)的指导和工具。
-
- 安装扩展(英)
-
- 介绍如何以编程方式安装扩展。
-
- 提交附加组件到AMO(英)
-
- 如何发布你的附加组件AMO
-
- 扩展的常见问题解答
-
- 关于扩展开发的常见问题解答。
-
-

针对特定程序的指导

-

Firefox(英语)

-

Thunderbird(英语)

-

SeaMonkey(英语)从SeaMonkey 2起支持扩展

-

Firefox 安卓版

-

Fennec(英语) (移动版火狐)

-

查看所有“扩展”标签…

-
-
-
-

社区

-

估计相当长时间内都不会被我们中国用户使用的东西,我就省略了。

- 查看Mozilla扩展开发论坛{{DiscussionList("dev-extensions", "mozilla.dev.extensions")}} - -

工具

- -

... more tools ...

- -

查看所有…

-

相关页面

- -

相关话题

-
-
- XUL, JavaScript, XPCOM, Themes, Developing Mozilla
-
-
-

Categories

-

Interwiki Language Links

diff --git a/files/zh-cn/extensions/mobile/index.html b/files/zh-cn/extensions/mobile/index.html deleted file mode 100644 index e1608005d8..0000000000 --- a/files/zh-cn/extensions/mobile/index.html +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Extensions for Firefox for Android -slug: Extensions/Mobile -translation_of: Archive/Add-ons/Legacy_Firefox_for_Android ---- -

{{LegacyAddonsNotice}}{{AddonSidebar}}

- -

下面的文章为想要开发Firefox for Android扩展的人提供了帮助.

- -

In addition, please refer to the general extension documentation that applies to all Mozilla applications.

- - - - - - - - -
-

Documentation

- -
Tutorials
- -
-
Walkthrough
-
Developing, packaging and installing a simple add-on for Firefox for Android.
-
Initialization and Cleanup
-
How to initialize your add-on when it is started and clean up when it is shut down.
-
Creating a UI
-
A quick guide to using the NativeWindow API to create user interface components.
-
Interacting with the Browser
-
A quick guide to using the BrowserApp API to access browser tabs and the web content they host.
-
- -
API Reference & Code Samples
- -
-
NativeWindow
-
Create native Android UI widgets.
-
BrowserApp
-
Access browser tabs and the web content they host.
-
Code Snippets
-
Code samples for common tasks
-
-
-

Community

- -
    -
  • -

    View Mozilla extension development forums...

    -
  • -
- -

{{ DiscussionList("dev-extensions", "mozilla.dev.extensions") }}

- - - -

Tools

- -

 

- -

View All...

-
- - - -
-
XUL, JavaScript, XPCOM, Themes, Developing Mozilla
-
- -

View all pages tagged with "Extensions"...

- -

 

diff --git "a/files/zh-cn/extensions/\345\274\225\345\257\274\345\236\213\346\211\251\345\261\225/index.html" "b/files/zh-cn/extensions/\345\274\225\345\257\274\345\236\213\346\211\251\345\261\225/index.html" deleted file mode 100644 index 49420e5a8a..0000000000 --- "a/files/zh-cn/extensions/\345\274\225\345\257\274\345\236\213\346\211\251\345\261\225/index.html" +++ /dev/null @@ -1,369 +0,0 @@ ---- -title: 自引导型扩展 -slug: Extensions/引导型扩展 -translation_of: Archive/Add-ons/Bootstrapped_extensions ---- -

browser.bookmarks.export( function() {...} // optional function ){{LegacyAddonsNotice}}{{AddonSidebar}}

- -

{{ gecko_minversion_header("2.0") }}

- -
-

注意:所有使用 Add-on SDK 创建的扩展都是自引导的。其引导代码已经自动生成,所以你不必考虑该问题。没有使用 Add-on SDK?那就继续读下去吧……

-
- -

传统形式的扩展包含覆盖接口程序段(overlay),应用程序可以从扩展的程序包中载入 XUL,并自动将其覆盖在自己的 UI 之上。这使得创建的扩展加入到应用程序的用户界面比较容易,但同时更新、安装或禁用扩展需要应用程序重启。

- - -

Traditional extensions include overlays, wherein the application can load up XUL from the extension's package and automatically apply it on top its own UI. While this makes creating extensions that add to the application's user interface relatively easy, it means that updating, installing, or disabling an extension requires an application restart.

- - -

Gecko 2.0 {{ geckoRelease("2.0") }} 引入了自引导型(bootstrapped)扩展。这是种特别的扩展,它们不使用覆盖界面来将它们的用户界面应用到应用程序中,而是用程序将它们自己插入到应用程序。这是通过包含在扩展中的一个特制的脚本文件来实现,脚本中包含了一些函数可供浏览器调用,来指挥扩展的安装、卸载、启动和关闭。

- -

应用程序所需做的就是调用该脚本文件;由扩展负责添加和去除它的用户界面,和处理任何其它所需的设置和关闭任务。

- -

本文论述了自引导型扩展将如何工作。

- -

作为题外话,所有用 Add-on SDKAdd-on Builder 创建的扩展都是自引导型的;但是,所有的引导代码都是为您特别生成的,所以实际上您并不需要真的去研究它。

- -

启动和关闭程序(process)

- -

自引导型扩展的一个关键特征是,它们必须按照应用程序的要求启动和关闭。当扩展的 startup() 函数被调用,它必须手动将它的用户界面和其它行为注入到应用程序中。同样,当它的 shutdown() 函数被调用,它必须移除添加到应用程序中的任何东西,也包括对它的所有对象的所有引用。

- -

startup() 函数会在多个场景中被调用;比如:

- - - -

shutdown() 函数会被调用的一些场景:

- - - -

修改应用程序用户界面的说明

- -

引导型附加组件中的 chrome.manifest

- -

您可以在自引导型附加组件中使用 chrome.manifest 文件来:

- -
    -
  1. 通过 chrome:// URL[在清单(manifest)中使用 contentlocaleskin 指令]使您附加组件的内容生效;
  2. -
  3. 用您的内容替换已经存在的 chrome:// URI(使用 override 指令)。
  4. -
- -

不是所有的 chrome.manifest 指令都被自引导型附加组件支持,比如在自引导型附加组件中,您仍然不能注册 XUL 覆盖界面。详见 chrome.manifest 文档。

- -

在 Firefox 10 及以上版本中,放在附加组件 XPI 根目录下的 chrome.manifest 文件(与 install.rdf 同级)会被自动加载。在 Firefox 8 和 9 中,您必须手动加载/卸载清单,使用 {{ ifmethod("nsIComponentManager", "addBootstrappedManifestLocation") }} 和 {{ ifmethod("nsIComponentManager", "removeBootstrappedManifestLocation") }}。该特征在 Firefox 8 以前的版本中无效。

- -

手动添加用户界面

- -

如果您决定继续尝试开发一个修改应用程序用户界面的自引导型扩展,这儿有几个建议给您。

- -

您需要在相关应用程序中调用 {{ domxref("document.getElementById()") }},通过 UI 元素的 ID 来查找它们,然后操纵它们来注入您的 UI。例如,您可以通过 document.getElementById("main-menubar") 来访问 Firefox 的菜单栏。

- -

确保在关闭时移除您添加的任何用户界面。

- -

创建自引导型扩展

- -

为标示一个扩展为可引导的,您需要添加下列元素到它的 安装清单

- -
<em:bootstrap>true</em:bootstrap>
- -

然后您需要添加一个 bootstrap.js 文件,它包含所要求的函数;在扩展的包中,它应该与 install.rdf 文件同级。

- -

向后兼容

- -

因为旧版本的 Firefox 并不知道 bootstrap 属性或 bootstrap.js 文件,创建一个既能作为可引导扩展又能作为传统扩展来工作的 XPI 不是特别困难。按照可引导扩展来创建您的扩展,然后同样地添加传统的覆盖界面。新版本的 Firefox 将使用 bootstrap.js 脚本并忽略部件(components)和覆盖界面,同时旧版本将使用覆盖界面。

- -

引导切入点(entry points)

- -

bootstrap.js 脚本应该包含几个特殊函数,浏览器调用它们来管理扩展。该脚本被放在一个有特权的(privileged)沙箱中执行,这个沙箱一直被保存(cached)到扩展关闭。

- -

startup

- -

当扩展需要启动它自己时被调用。它发生在应用程序启动时,或启用被禁用的扩展时(或在为安装更新而被关闭后)。可见,在应用程序的生命期内,它会被多次调用。

- -

您的附加组件应当在这时注入 UI,启动任何可能需要运行的任务,等等。

- -
void startup(
-  data,
-  reason
-);
-
- -
参数
- -
-
data
-
引导数据结构
-
reason
-
原因常量之一,表明扩展为什么被启动。可以是 APP_STARTUPADDON_ENABLE、ADDON_INSTALLADDON_UPGRADEADDON_DOWNGRADE 之一。
-
- -

shutdown

- -

当扩展需要关闭它自己时被调用,比如应用程序退出时,或准备更新/禁用扩展时。在这里必须移除所有已被注入的用户界面,关闭所有任务,并处理掉所有对象。

- -
void shutdown(
-  data,
-  reason
-);
-
- -
参数
- -
-
data
-
引导数据结构
-
reason
-
原因常量之一,表明扩展为什么被关闭。可以是 APP_SHUTDOWNADDON_DISABLE、ADDON_UNINSTALL、ADDON_UPGRADEADDON_DOWNGRADE 之一。
-
- -

install

- -

您的引导脚本必须包括 install() 函数,应用程序在安装、升级或降级扩展后,第一次调用 startup() 之前调用它。

- -
注意:如果从未启动扩展,则不会调用该方法;例如,如果扩展虽被安装但并不兼容当前版本的应用程序,且在变为兼容之前被卸载,则 install() 始终不会被调用。但是,如果扩展被升级到一个兼容应用程序的版本,将在第一次调用 startup() 之前调用它的 install() 函数。
- -
void install(
-  data,
-  reason
-);
-
- -
参数
- -
-
data
-
引导数据结构
-
reason
-
原因常量之一,表明扩展为什么被安装。可以是 ADDON_INSTALLADDON_UPGRADEADDON_DOWNGRADE 之一。
-
- -

uninstall

- -

该函数在卸载扩展的某个版本之前,最后一次调用 shutdown() 之后被调用。如果始终未调用 install(),也不会调用此函数。

- -
注意:记住这一点很重要——即使对于当前被禁用或不兼容当前应用程序的扩展,都会被调用 uninstall()。鉴于此,在实现该函数时,优雅地处理那些也许并不存在于应用程序中的 API 变得非常重要。如果一个第三方应用程序在 Firefox 未运行时移除了该扩展,该函数也不会被调用。
- -
Note: The uninstall function fires on downgrade and upgrade as well so you should make sure it is an uninstall by doing this:
-function uninstall(aData, aReason) {
- if (aReason == ADDON_UNINSTALL) {
- console.log('really uninstalling');
- } else {
- console.log('not a permanent uninstall, likely an upgrade or downgrade');
- }
-}
- -
void uninstall(
-  data,
-  reason
-);
-
- -
参数
- -
-
data
-
引导数据结构
-
reason
-
原因常量之一,表明扩展为什么被卸载。可以是 ADDON_UNINSTALLADDON_UPGRADEADDON_DOWNGRADE 之一。
-
- -

原因常量

- -

上述引导函数都接受一个 reason 参数,该参数向扩展解释为什么调用该函数。 这些原因常量如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
常量描述
APP_STARTUP1应用程序启动。
APP_SHUTDOWN2应用程序关闭。
ADDON_ENABLE3启用附加组件。
ADDON_DISABLE4禁用附加组件。(同时被错用于卸载
ADDON_INSTALL5安装附加组件。
ADDON_UNINSTALL6卸载附加组件。
ADDON_UPGRADE7升级附加组件。
ADDON_DOWNGRADE8降级附加组件。
- -

引导数据

- -

每个切入点被传入一个简单的数据结构,它包含一些关于引导附加组件的有用信息。调用 AddonManager.getAddonByID() 可以获得更多关于附加组件的信息。该数据是一个简单的 JavaScript 对象,它包括以下属性:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型描述
idstring被引导附加组件的 ID。
versionstring被引导附加组件的版本。
installPathnsIFile被引导附加组件的安装位置。可能是一个目录或一个 XPI 文件,这取决于安装该附加组件时是否解包。
resourceURInsIURI附加组件文件根目录的 URI,可能是 jar:file: URI,这取决于安装该附加组件时是否解包。{{ gecko_minversion_inline("7.0") }}
oldVersionstring以前的安装版本,如果原因是 ADDON_UPGRADEADDON_DOWNGRADE,并且方法是 installstartup。{{ gecko_minversion_inline("22.0") }}
newVersionstring将要安装的版本,如果原因是 ADDON_UPGRADEADDON_DOWNGRADE,并且方法是 shutdownuninstall。{{ gecko_minversion_inline("22.0") }}
- -
-

注意:附加组件可能会在程序启动时升降级,此时 startup 方法的原因是 APP_STARTUP,并且不会设置 oldVersion 属性。 另外需注意,在某些情形下有可能发生附加组件升降级但 uninstall 方法没有被调用的情况。

-
- - -

拓展调试器

- -

From Firefox 31 onwards, you can use the Add-on Debugger to debug bootstrapped add-ons.

- -

本地化(L10n)

- -

Localizing bootstrapped add-ons is very much the same since Firefox 7, as that is when chrome.manifest compatibility landed.

- -

JS and JSM Files - Using Property Files

- -

To localize your .js and .jsm files you have to use property files.

- -

The absolute minimum needed here is:

- -
    -
  1. File: install.rdf
  2. -
  3. File: chrome.manifest
  4. -
  5. File: bootstrap.js
  6. -
  7. Folder: locale -
      -
    1. Folder: VALID_LOCALE_HERE -
        -
      1. File: ANYTHING.properties
      2. -
      -
    2. -
    -
  8. -
- -

In the locale folder you must have folders for each of the languages you want to provide; each folder must be named a valid locale (ex: en-US). Inside this folder must be a property file. Inside the chrome.manifest file these locale must be defined. For example if you had a subfolder of en-US in locale folder your chrome.manifest file will have to contain: locale NAME_OF_YOUR_ADDON en-US locale/en-US/

- -

Here is an example: GitHub :: l10n-properties - on startup of this add-on it will show a prompt saying USA or Great Britain, which ever it deems closest to your locale. You can test different locale by going to about:config and changing preference of general.useragent.locale to en-US and then to en-GB and disabling then re-enabling the add-on.

- -

XUL and HTML Files - Using Entities from DTD Files

- -

Many times HTML pages are used, however they cannot be localized with DTD files. There are three changes you must make:

- -
    -
  1. You have to change the HTML file's extension to be .xhtml
  2. -
  3. The doctype must be defined point to a DTD file in your locale folder such as: <!DOCTYPE html SYSTEM "chrome://l10n/locale/mozilla.dtd">
  4. -
  5. Must add xmlns attribute to html tag for example: <html xmlns="http://www.w3.org/1999/xhtml">
  6. -
  7. If you have multiple DTD files read on here: Using multiple DTDs
  8. -
- -

The bare minimum needed is:

- -
    -
  1. File: install.rdf
  2. -
  3. File: chrome.manifest
  4. -
  5. File: bootstrap.js
  6. -
  7. Folder: locale -
      -
    1. Folder: VALID_LOCALE_HERE -
        -
      1. File: ANYTHING.dtd
      2. -
      -
    2. -
    -
  8. -
- -

The chrome.manifest file must include a definition for content for example: content NAME_OF_YOUR_ADDON ./

- -

The chrome.manifest file must also include a line pointing to the locale, just like in the above property section, if you had a folder named en-US in locale, the chrome.manifest file should contain: locale NAME_OF_YOUR_ADDON en-US locale/en-US/

- -

Here is an example add-on that opens an HTML page and a XUL page on install: GitHub :: l10n-xhtml-xul. Here is an example showing how to use a localized HTML page as an options page: GitHub :: l10n-html-options. You can go to about:config and change the value of the preference general.useragent.locale to en-US and then to en-GB and then reload the open pages to see the localization change.

- - -

延伸阅读

- - diff --git a/files/zh-cn/firefox_addons_developer_guide/index.html b/files/zh-cn/firefox_addons_developer_guide/index.html deleted file mode 100644 index 9a4058101c..0000000000 --- a/files/zh-cn/firefox_addons_developer_guide/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Firefox 附加组件开发指南 -slug: Firefox_addons_developer_guide -translation_of: Archive/Add-ons/Overlay_Extensions/Firefox_addons_developer_guide ---- -

{{ Next("Firefox addons developer guide/Introduction to Extensions") }}

-

第1章:介绍扩展

-

第2章:开发扩展时用到的技术

-

第3章:介绍XUL——如何建立一个直观的用户界面

-

第4章:使用XPCOM——实现高级功能

-

第5章:构建一个Firefox扩展吧

-

第6章:Firefox扩展与XUL应用程序

-

许可协议与作者

-

{{ Next("Firefox addons developer guide/Introduction to Extensions") }}

-

{{ languages( { "de" : "de/Firefox_addons_developer_guide" } ) }}

diff --git a/files/zh-cn/firefox_addons_developer_guide/introduction_to_extensions/index.html b/files/zh-cn/firefox_addons_developer_guide/introduction_to_extensions/index.html deleted file mode 100644 index 5c6cc01591..0000000000 --- a/files/zh-cn/firefox_addons_developer_guide/introduction_to_extensions/index.html +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: '章节 1: 介绍附加组件' -slug: Firefox_addons_developer_guide/Introduction_to_Extensions -translation_of: >- - Archive/Add-ons/Overlay_Extensions/Firefox_addons_developer_guide/Introduction_to_Extensions ---- -
- {{ Draft() }}
-

{{ PreviousNext("Firefox_addons_developer_guide", "Firefox_addons_developer_guide/Technologies_used_in_developing_extensions") }}

-
- Note: If you want contribute to this document please following guidelines from the Contribute page.
-

This document was authored by Hideyuki Emura and was originally published in Japanese for the Firefox Developers Conference Summer 2007. Emura-san is a co-author of Firefox 3 Hacks (O'Reilly Japan, 2008.)

-

介绍

-

假如你正在读这指南,你可能以前用过Firefox.也许第一次你看到Firefox, 你可能很惊讶地看到,它有比其他全功能浏览器更简单的结构,例如 Opera或Safari.

-

What features are considered standard for web browsers these days? Perhaps things like fine-grained tab controls, mouse gestures, extensive toolbars and buttons, a feed reader, integration with a variety of web applications, or sophisticated tools to assist with web design. But we didn't set out to create an all-in-one browser that can satisfy everyone.

-

Instead, Firefox can support these features through extensions. The core browser is limited to basic features, so it’s something that a beginner can be comfortable with, but users who want something beyond that can install extensions.

-

关于附加组件

-

使用附加组件管理器管理

-

Firefox的附加组件管理器是一个极好的方式来管理附加组件, 在容易使用上是一个重大的进步.

-

-

附加组件管理器处理下列任务:

- -

Development environment amenities

-

Initially, there wasn't adequate documentation available, and extension developers were largely left to fend for themselves1; however, now there's a considerable store of knowledge.

-

Because Firefox and its extensions are designed to support multiple languages, excellent extensions come from all over the world, and can be quickly localized by anyone interested.

-

This lowers the threshold both to using and to developing extensions; that fact, combined with Firefox's rapidly growing popularity, has created a positive feedback loop, with the number of extension users and extension developers growing explosively—there are now more than 7000 extensions and themes published at the Firefox Add-ons site (https://addons.mozilla.org).

-

What you can do with extensions

-

Let's look at what features extensions can add, and some actual examples of extensions.

-

Single feature extensions

-

{{ TODO("Update this") }}.

-

These are relatively simple extensions that add a single feature.

-
-
- Text Link
-
- Makes it so that double-clicking on an unlinked URL follows that URL.
-
- Undo Closed Tabs Button
-
- Adds a toolbar button to re-open the most recently closed tabs to the History menu.
-
-
-
- 1211576231.png
-
-
-
- Locationbar
-
- Separates a URL’s domain and path in the location bar for easier reading.
-
- locationbar.png
-
-

Feature enhancing extensions

-

{{ TODO("Update this") }}.

-

These extensions enhance features that already exist in Firefox.

-
-
-
-
- Tab Mix Plus
-
- Offers detailed tab-related settings.
-
- PrefBar
-
- Gives access to numerous preferences from the toolbar.PrefBar.png
-
- NoScript
-
- Enables and disables JavaScript execution on a site-by-site basis.
-
-

Web application integration extensions

-

{{ TODO("Update this") }}.

-

The use the APIs of certain web applications to provide certain pieces of information.

-

Forecastfox.png

-

New feature extensions

-

{{ TODO("Update this") }}.

-

Extensions can add completely new features to Firefox. This class of extension requires a greater level of knowledge and programming ability.

-
-
- GreaseMonkey
-
- UserChrome.js
-
- Both of these provide an environment for running user scripts (JavaScript) in Firefox itself, where the scripts can target specific websites.
-
-
-
- Adblock Plus
-
- Blocks the display of unwanted advertisements on web pages.
-
- All-in-One Gestures
-
- Adds mouse-gesture functionality.
-
-

Application level extensions

-

{{ TODO("Update this") }}.

-

These are sophisticated extensions that can be considered full-scale applications in their own right, essentially using Firefox as the development platform.

-

Firebug.gif

-

One-trick gag extensions

-

{{ TODO("Update this") }}.

-

There are a number of one-trick gag extensions that aren’t very useful.

-

Shiitake Mushroom (1).png

-

This is a very brief survey of a few extensions, but there are many other unique extensions available.

-

表1: Firefox的高级定制方法

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
定制方法Does it work for web sites?Does it work for Firefox?
User style sheets (change appearance through CSS) -

Yes; you can change the userContent.css file, or use the Stylish extension.

-
-

Yes; you can change the userChrome.css file, or use the Stylish extension.

-
User scripts (change appearance and functionality through JavaScript) -

Yes; you can use the GreaseMonkey extension or "bookmarklets."

-
-

Yes; you can change userChrome.js to add functionality through JavaScript.

-
附加组件 (它们可以做任何事)
主题 (它更改浏览器器的外观)
-

让我们一起编译一个附加组件

-

Table 1 shows the various customization options available to a user in Firefox. Users have flexible customization options, using CSS in user style sheets and JavaScript/DOM in user scripts (these depend on Stylish, GreaseMonkey, and userChrome.js).

-

In addition to CSS and JavaScript, extensions can take advantage of XUL and XPCOM technologies for more sophisticated features. Themes, which alter Firefox's appearance, are a kind of add-on.

-

In order to create an extension, you need an idea and just a little programming ability. The following chapters explain in detail the extension-writing techniques of some of Japan's leading extension authors. We encourage you to try your hand at it as well.

-
-
- 1 One of the authors of this special edition, Piro, is world-famous as one of the original developers.
-
-
-
-

{{ PreviousNext("Firefox_addons_developer_guide", "Firefox_addons_developer_guide/Technologies_used_in_developing_extensions") }}

diff --git a/files/zh-cn/firefox_sync/index.html b/files/zh-cn/firefox_sync/index.html deleted file mode 100644 index 4ee0b7804f..0000000000 --- a/files/zh-cn/firefox_sync/index.html +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Firefox 同步 -slug: Firefox_Sync -tags: - - Sync - - 同步 -translation_of: Archive/Mozilla/Firefox_Sync ---- -

组件与服务

- -

Sync refers to a family of related components and services which provide synchronization of data between Mozilla application instances. These components and services include:

- -
-
Firefox 同步客户端
-
The Sync client bundled with Mozilla products. It exists as a core JavaScript module providing generic functionality and UI components for each product.
-
服务器
-
A server implementation of the Sync HTTP protocol. Clients communicate through it.
-
Firefox Home
-
An iOS application that functions as a Sync client.
-
Mozilla 服务器实例
-
An instance of the server deployed and maintained by Mozilla. If you use Sync in your browser, this is what it talks to by default.
-
- -

规范

- -

There are numerous specifications concerning Sync. These include:

- - - -

The definitive source for these specifications is http://docs.services.mozilla.com/.

- -

运行服务器

- -

It is possible to run your own Sync Server instance. Full instructions are available at http://docs.services.mozilla.com/howtos/run-sync.html.

- -

如何参与和服务现状

- -

For information on the current development status of Sync including how to get involved, see https://wiki.mozilla.org/Services/Sync.

- -

相关信息

- - diff --git a/files/zh-cn/firefox_sync/javascript_client_api/index.html b/files/zh-cn/firefox_sync/javascript_client_api/index.html deleted file mode 100644 index 768a941761..0000000000 --- a/files/zh-cn/firefox_sync/javascript_client_api/index.html +++ /dev/null @@ -1,296 +0,0 @@ ---- -title: JavaScript 客户端 API -slug: Firefox_Sync/JavaScript_Client_API -translation_of: Archive/Mozilla/Firefox_Sync/JavaScript_Client_API ---- -

概览

-

This page describes how to use the client-side Sync JavaScript API. This API is available in Mozilla-based products that use Sync, such as Firefox (both desktop and mobile).

-

Please note that usage of the Sync APIs is governed by a terms of service:

-
-

By accessing or using the Firefox Sync APIs in connection with the development of your own client software to access the Firefox Sync services (a “Third Party Client”), you acknowledge that you will need to install and use a local version of the Firefox Sync server for multiple account testing and that any use of Mozilla’s hosted Firefox Sync services is subject to Mozilla’s Firefox Sync Terms of Service at https://services.mozilla.com/tos/.   Further, you agree (a) to maintain and link to (including on websites from which your Third Party Client may be downloaded) a separate, conspicuous, and reasonably detailed privacy policy detailing how data collected or transmitted by your Third Party Client is managed and protected; (b) that your Third Party Client will only store data in encrypted form on the Firefox Sync servers operated by Mozilla; (c) that you and your Third Party Client will use the Firefox Sync APIs solely for their intended purpose; (d) that your Third Party Client will not hide or mask its identity as it uses the Services and/or Firefox Sync APIs, including by failing to follow required identification conventions; and (e) that you and your Third Party Client will not use the Firefox Sync APIs for any application or service that replicates or attempts to replicate the Services or Firefox Sync experience unless such use is non-confusing (by non-confusing, we mean that people should always know with whom they are dealing and where the information or software they are downloading came from). You may not imply, either directly or by omission, that your Third Party Client is produced or endorsed by Mozilla. By providing access to the Firefox Sync APIs, Mozilla is not granting you a license to any of our trademarks.

-
-

开始之前

-

Before you start learning the JavaScript API, you should spend some time on http://docs.services.mozilla.com/ reading about how the Sync service operates. This will help fundamental understanding significantly.

-

API 位置

-

The Sync JavaScript client API is defined in files in the services/sync/ directory of mozilla-central or similar repository.

-

术语

-
-
- SyncEngine
-
- The main Sync client object. It's what starts all the magic.
-
- Engine
-
- Governs the synchronizing of a specific set of information. e.g. there is an engine for bookmarks, tabs, history, preferences, etc.
-
- Record
-
- Piece of information that gets synchronized. Records are transformed to WBO's, uploaded to a collection in a Sync server and eventually downloaded by other Sync clients.
-
- Tracker
-
- Entity that tracks changes to data. Each engine has a corresponding tracker which listens for changes to data or events it is interested in. When something of interest occurs, it interacts with the engine to let it know something has happened and it might want to take action
-
- Store
-
- Entity that serves as a data store/proxy for information in an engine. The name store is somewhat of a misnomer, as stores don't actually persistently store anything, but rather serve as short-lived data stores during the course of a single sync and act as proxies to other data stores within the application (like the places database) outside of Sync.
-
-

创建自定义引擎

-

The Sync client ships with a number of engines out of the box (history, bookmarks, etc). It is possible for other components, including 3rd party extensions, to supplement the set of engines and synchronize their own data.

-

一个小警告: the JavaScript Client API is still a young component and is continuing to evolve. Therefore, developers outside of the Sync core should know that their code could require significant refactoring in future releases. Before developing against the JavaScript API, it is recommended to speak to developers of the API. See https://wiki.mozilla.org/Services/Sync for their contact information.

-

To create a custom Sync engine to synchronize a new data you, you'll need to define an engine object that extends the base SyncEngine object. This involves writing types that extend the Store, Tracker, and Record types as well.

-

It will be very helpful to look at an existing sync engine for guidance. Have a look at one of the following files:

- -

建立一个JS模块

-

The code for your custom sync engine should live in a JS module. First off we're going to import the files mentioned above at the top the file. We're also going to import ''util.js'' as it contains many useful helpers.

-
const Cu = Components.utils;
-Cu.import("resource://services-sync/engines.js");
-Cu.import("resource://services-sync/record.js");
-Cu.import("resource://services-sync/util.js");
-
-

The Record Object

-

The record object is a wrapper around a single instance of whatever data it is that you are syncing -- a single bookmark, history URL, password or form data entry. For some sync engines, it makes sense to bundle all data into one record. The tabs and preferences engines work that way. For other engines, it makes sense to have multiple records per sync. It all depends on the data model. If in doubt, consult the Sync developers.

-

The base record objects are defined in services/sync/modules/record.js. There's a base Record object, which defines the basic record API. But, you want to use a derived class, CryptoWrapper, which seamlessly encrypts and decrypts records on the client. This makes your synchronized data more secure and unreadable by the server operators. All you have to do is write an object that extends CryptoWrapper and maintains a property called cleartext. cleartext must be a JSON-able object. Put into it all values that you want to have encrypted, stored on the server, decrypted, and synced up.
-
- You may find it useful to write getters and setters for various properties of your record implementation.
-
- The skeleton of a sample record implementation:

-
function FooRecord(collection, id) {
-  CryptoWrapper.call(this, collection, id);
-}
-FooRecord.prototype = {
-  __proto__: CryptoWrapper.prototype,
-  _logName: "Record.Foo",
-  ttl: FOO_TTL,  // optional
-
-  get bar() this.cleartext.bar,
-  set bar(value) {
-    this.cleartext.bar = value;
-  },
-  get baz() this.cleartext.baz,
-  set baz(value) {
-    this.cleartext.baz = value;
-  }
-};
-
-

To save all that typing for declaring the getters and setters, you can also use Utils.deferGetSet:

-
function FooRecord(collection, id) {
-  CryptoWrapper.call(this, collection, id);
-}
-FooRecord.prototype = {
-  __proto__: CryptoWrapper.prototype,
-  _logName: "Record.Foo",
-  ttl: FOO_TTL  // optional
-};
-Utils.deferGetSet(FooRec, "cleartext", ["bar", "baz"]);
-
-

存储对象

-

The Store object (which extends Store, as defined in services/sync/modules/engines.js) has the job of creating and maintaining a set of Record objects from the underlying data.  The store must also make updates to the underlying data itself based on incoming Record objects. The majority of the code you write for syncing a new data type will most likely be in the Store implementation.

-

Each Record that the Store keeps track of must be identified by a unique ID (unique among all records in the store) called GUID. Depending of what type of data you're working with, you might already have GUIDs built into your data that you can make use of (note that GUIDs must be allowed to change and should be URL friendly).  If not, you may have to invent your own mapping from data objects to GUIDs as long as it's consistent.  In this case, it is highly recommended to use the Utils.makeGUID() helper to generate new GUIDs:

-
let newGuid = Utils.makeGUID();
-
-

Your Store object must implement the following methods:

- -

You may also find it useful to override other methods of the base implementation, for example applyIncomingBatch if the underlying storage for your data supports batch operations.

-
-
- createRecord
-
-
-
- The createRecord( id, collection ) method gets called by the engine to request a new record for an item with a given GUID. It's your Store's responsibility to instantiate a Record object, assign the given GUID, and return it.
-
-
-
- itemExists(guid)
-
-
-
- Should simply return true if an item with the given guid exists in the store, false otherwise.
-
-
-
- changeItemID(oldId, newId)
-
-
-
- Must find the stored item currently associated with the guid oldId and change it to be associated with the guid newId.
-
-
-
- getAllIDs()
-
-
-
- Must return an iterable list containing the GUIDs of every item being stored on the local system. This can be a dictionary-type object where the keys are the GUIDs and the values are whatever; or it can simply be a list of GUIDs. This is the method that the engine will call the first time it syncs, in order to get a complete inventory of what data there is that will need to be uploaded to the server. Unless the items you're syncing have their own inherent GUIDs already defined, you'll need to invent GUIDs for all your items at this time. When one of these GUIDs is later passed as an argument to createRecord(), you need to return a record based on the matching data. Therefore, it's the responsibility of this method to define the guid -> item mapping, and to store it for later reference by other methods.
-
-
-
- wipe()
-
-
-
- When this method is called, your Store needs to completely wipe all of its stored data from the local application. That doesn't mean just whatever caches of the data the Store happens to be maintaining; it means the underlying data itself. For instance, BookmarkStore.wipe() deletes all bookmarks from the current Firefox profile. How to do this for your particular data type is up to you to figure out.
-
-

The next three methods are called by the sync algorithm when it determines that the state of the local application needs to be changed to keep it up-to-date with the user's remote activities. The sync algorithm will call your Store object with a record to be created, updated, or removed, and it is your Store object's responsibility to apply this change to the local application using whatever methods are neccessary.

-
-
- create(record)
-
-
-
- Not to be confused with createRecord(), this method (which should probably be renamed for clarity soon) tells your Store to create a new item in the local application, based on the data in record. (So for example, BookmarkStore.create() adds a new bookmark to the Firefox profile).
-
-
-
- update(record)
-
-
-
- The argument is a record which has been remotely modified; your Store should locate the matching local item (presumably using the GUID, which is available in record.id) and update it to the new values provided in record.
-
-
-
- remove(record)
-
-
-
- The argument is a record which has been remotely deleted; your Store should locate the matching local item and delete it. (Don't rely on the record that is passed in to this method having any of its attributes set correctly except for .id. The .id should be al you need, anyway.)
-
-
-
- applyIncomingBatch :
-
- TODO
-
-

Example Store Skeleton

-
// Maintains the store of all your Foo-type items and their GUIDs.
-function FooStore(name) {
-  Store.call(this, name);
-}
-FooStore.prototype = {
-  __proto__: Store.prototype,
-  itemExists: function(guid) {
-    // Return true if an item with given guid exists in the store.
-  },
-  createRecord: function(id, collection) {
-    record = new FooRecord(uri);
-    // Look up the data corresponding to this guid, by the mapping
-    // you've defined.
-    // Set the data and the guid on the new record:
-    record.bar = 17; // or whatever
-    record.id = guid;
-    // return the record
-    return record;
-  },
-  changeItemID: function(oldId, newId) {
-    // Find the item with guid = oldId and change its guid to newId.
-  },
-  getAllIDs: function() {
-    // Return a list of the GUIDs of all items.  Invent GUIDs for any items
-    // that don't have them already, and remember the mapping for later use.
-  },
-  wipe: function() {
-    // Delete everything!
-  },
-  create: function(record) {
-    // Create a new item based on the values in record
-  },
-  update: function(record) {
-    // look up the stored record with id = record.id, then set
-    // its values to those of new record
-  },
-  remove: function(record) {
-    // look up the stored record with id = record.id, then delete it.
-  }
-};
-
-

Writing a Tracker Class

-

Your tracker class must inherit from Tracker, which is defined in services/sync/modules/trackers.js. Its purpose in life is to track changes to whatever data type you are syncing. It must maintain a list of GUIDs for objects that have been changed and therefore require syncing. It also has to maintain a "score", which is a number from 0 to 100 which represents "how badly does this data type need to be synced right now". Getting your tracker to track changes in the underlying data is probably easiest to do if you register your tracker as an observer, so that it can receive notifications from one or more Mozilla components. What events you listen for is entirely up to you. You can find out more about registering as an observer here: [link].

-

The Score

-

The '''score''' is stored in this.score, a variable defined by the base Tracker class. Set your score by assigning a value to this.score. The score number is used by the scheduler to decide when your engine will be synced. Setting it to zero means "I have no need to sync". The higher you set this number, the more urgently the scheduler treats your request. Setting it to 100 means "Sync me immediately". It's up to you to figure out the best way to assign a score based on the current state of whatever data type you're tracking. Your tracker score is automatically reset to zero after each time your engine syncs.

-

The changed GUID list

-

The base class maintains a list of GUIDs that need syncing. When your tracker detects that an item has changed, you should add it to this list by calling: this.addChangedID(guid); These GUIDs correspond to the .id fields of your Record objects; see the section on the Store class for more about defining and maintaining the mapping between GUIDs and Records.

-

Example

-

Here's the skeleton of a sample Tracker class.

-
function FooTracker(name) {
- Tracker.call(this, name);
-
- // Register yourself as event listener or observer for whatever
- // you want to track. Note that this may unnecessarily slow down
- // things for users who don't use Sync. It's a bit smarter to have
- // yourself notified when to start and stop tracking therefore:
- Svc.Obs.add("weave:engine:start-tracking", this);
- Svc.Obs.add("weave:engine:stop-tracking", this);
-}
-FooTracker.prototype = {
-  __proto__: Tracker.prototype,
-  _enabled: false,
-  observe: function observe(subject, topic, data) {
-    switch (topic) {
-      case "weave:engine:start-tracking":
-        if (!this._enabled) {
-          // register event handler or observer here
-          ...
-          this._enabled = true;
-        }
-        break;
-      case "weave:engine:stop-tracking":
-        if (this._enabled) {
-          // remove event handler or observer here
-          ...
-          this._enabled = false;
-        }
-        break;
-   },
-
-   onEvent: function onEvent() {
-     /* Here is where you'd handle the event.  See the documentation for
-        whatever service you are observing to find out what to call this
-        method, what arguments to expect, and how to interpret them. */
-     var guid = 0;
-
-     /* Here is where you'd include code to figure out the GUID of the item
-        that has changed... */
-     this.addChangedID(guid);
-
-     // Update the score as you see fit:
-     this.score += 10;
-   }
- };
-
-

Writing an Engine class

-

Your Engine class serves to tie together your Store, Tracker, and Record classes into a bundle that the Sync service can instantiate and use. You're probably sick of writing subclasses by this point, but don't worry: this one is very easy. I saved it for last because it requires the least code. Your class must derive from the SyncEngine class, defined in services-sync/modules/engines.js. SyncEngine contains a lot of code which handles logic for the core sync algorithm, but your subclass won't need to call any of this directly, unless you are overriding part of the sync algorithm to provide custom sync behavior (an advanced technique outside the scope of this article).

-

A sample Engine class:

-
function FooEngine() {
-  Weave.SyncEngine.call(this, "Foo");
-}
-FooEngine.prototype = {
-  __proto__: Weave.SyncEngine.prototype,
-  _recordObj: FooRecord,
-  _storeObj: FooStore,
-  _trackerObj: FooTracker
-};
-

As you can see, there isn't actually any new code here at all; the prototype simply defines some metadata such as the Store and Tracker classes to use, and the human-readable name that will be used in the log files to identify errors and status messages coming from this engine. (Don't forget that you'll need to import Weave. So the top of your file should include:)

-
const Cu = Components.utils; // etc...
-Cu.import("resource://services-sync/main.js");
-

Installing your classes into Sync

-

You can register your engine in an "weave:service:ready" observer using the Weave.Engines.register(FooEngine) function. However, "weave:service:ready" is issued after the "weave:engine:start-tracking" observer notification. If your tracker observes "weave:engine:start-tracking", it's best to have the Sync service register your engine. Stick your engine class on to the Weave object:

-
Weave.FooEngine = FooEngine;
-
-

and add "Foo" to the services.sync.registerEngines preference (it's a comma separated list of engine names). You can also set up a component that registers a weave:service:ready observer and at that time, imports main.js as well as your engine. Also, for me, doing Weave.Engines.register(FooEngine) worked better then doing Weave.FooEngine = FooEngine. Reason for this is, Weave will iterate through the registerEngines preference and try to instantiate each engine it has there before you the line mentioned above ever has a chance to execute.This means the constructor to your engine is not ready when Weave tries to instantiate it.

-

Testing and Debugging your Engine

-

Set observers in the Tracker to tell when your datatype changes, after which the score needs to be set. You can also add api's to the engine, get a handle of the engine by going Weave.Engines.get("Foo") and call it directly.

diff --git a/files/zh-cn/generic_factory/index.html b/files/zh-cn/generic_factory/index.html deleted file mode 100644 index ea6f934744..0000000000 --- a/files/zh-cn/generic_factory/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Generic factory -slug: Generic_factory -translation_of: Mozilla/Tech/XPCOM/Generic_factory ---- -

In XPCOM, a generic factory is a factory created using the facilities in xpcom/glue/nsIGenericFactory.h.

-

XPCOM中,泛型工厂定义在这里 xpcom/glue/nsIGenericFactory.h

-

Summary

-

Most XPCOM factories can be very simple. Rick Potts wrote a templated-based generic factory (nsFactory<T>) that simplifies the factory creation process that just requires writing a CreateInstance() method. The new nsIGenericFactory interface takes this a step further, by providing a single interface that can be reused anytime a simple implementation of nsIFactory is needed. Here is the interface, and a description of its use.

-

大多数XPCOM工厂都很简单。Rick Potts编写的基于模板的泛型工厂(nsFactory<T>),简化了工厂的创建过程,只需要调用CreateInstance()方法即可。新的 nsIGenericFactory 接口更进一步,提供一个单件接口,可复用 nsIFactory的实现。

-
/**
- * Provides a Generic nsIFactory implementation that can be used by
- * DLLs with very simple factory needs.
- */
-class nsIGenericFactory : public nsIFactory {
-public:
-    static const nsIID& IID() { static nsIID iid = NS_IGENERICFACTORY_IID; return iid; }
-
-    typedef NS_CALLBACK(ConstructorProcPtr) (nsISupports *aOuter, REFNSIID aIID, void **aResult);
-
-    /**
-     * Establishes the generic factory's constructor function, which will be called
-     * by CreateInstance.
-     */
-    NS_IMETHOD SetConstructor(ConstructorProcPtr constructor) = 0;
-};
-
-

Using nsIGenericFactory is simple. Create a new instance from the repository with a CID of NS_GENERICFACTORY_CID, and and IID of NS_IGENERICFACTORY_IID. Define a constructor function that matches the ConstructorProcPtr prototype, and call nsIGenericFactory::SetConstructor with a pointer to that function. You're done. You now have a fully functional factory object.

-

从 nsIGenericFactory 库创建实例需要 NS_GENERICFACTORY_CID 和 NS_IGENERICFACTORY_IID。创建一个构造函数,要与ConstructorProcPtr 原型匹配,并且通过指针调用方法 nsIGenericFactory::SetConstructor。

-

原型的例子:

-

Examples

-
class nsIComponent : public nsISupports {
-public:
-  NS_IMETHOD DoSomething() = 0;
-};
-
-class MyComponent : public nsIComponent {
-public:
-  MyComponent();
-  virtual ~MyComponent();
-
-  static NS_METHOD Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
-
-  NS_IMPL_ISUPPORTS
-
-  NS_IMETHOD DoSomething();
-};
-
-

To create a factory for this class, simply write the following:

-

为这个类创建一个工厂:

-
nsIFactory* NewComponentFactory(nsIRepository* repository)
-{
-    nsIGenericFactory* factory = NULL;
-    nsCID kGenericFactoryCID = NS_GENERICFACTORY_CID;
-    nsresult res = repository->CreateInstance(kGenericFactoryCID, NULL, nsIGenericFactory::IID(), &factory);
-    if (res == NS_OK) {
-        factory->SetConstructor(&MyComponent::Create);
-    }
-    return factory;
-}
-
-

This example assumes that the XPCOM repository is available as an interface (which it soon will be).

-

本例中假设 XPCOM库可作为一个接口使用。

-

Background

-

(This is based on my original news posting <beard-2402991733140001@h-198-93-95-151.mcom.com>.)

-

We seem to be creating a huge number of different factory implementations. It seems to me that we can cut down on code size (all those QueryInterface, AddRef, Release implementations) if we just use the following class for all of the simple factories:

-

通过以下类可以简化我们调用类工厂的实现。即COM的实现方式。

-
// Idea:  Why not create a generic factory facility so we can avoid
- // duplication of so much nsIFactory code? All we need is an allocator
- // function, the rest of the implementation is exactly the same.
-
- #include "nsIFactory.h"
-
- class nsGenericFactory : public nsIFactory {
- public:
-    typedef nsresult (*CreatorProcPtr) (nsISupports *aOuter,
-                                        REFNSIID aIID, void **aResult);
-
-    nsGenericFactory(CreatorProcPtr creator);
-    virtual ~nsGenericFactory();
-
-    NS_DECL_ISUPPORTS
-
-    NS_IMETHOD CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult);
-
-    NS_IMETHOD LockFactory(PRBool aLock);
-
- private:
-    CreatorProcPtr mCreator;
- };
-
- nsGenericFactory::nsGenericFactory(CreatorProcPtr creator)
-    :  mCreator(creator)
- {
-    NS_INIT_REFCNT();
- }
-
- nsGenericFactory::~nsGenericFactory() {}
-
- static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
-
- NS_IMPL_ISUPPORTS(nsGenericFactory, kIFactoryIID)
-
- NS_IMETHODIMP nsGenericFactory::CreateInstance(nsISupports *aOuter,
-                                                REFNSIID aIID, void **aResult)
- {
-    return mCreator(aOuter, aIID, aResult);
- }
-
- NS_IMETHODIMP nsGenericFactory::LockFactory(PRBool aLock)
- {
-    return NS_OK;
- }
-
-

Many of our classes already have a static entry point that serves as the creator function, so in most cases, creating a new factory for a class is just:

-

类一般都有一个静态入口指针,可通过创建一个新类工厂来实现。

-
nsIFactory* NewMallocFactory()
-{
-   nsIFactory* factory = new nsGenericFactory(&nsMalloc::Create);
-   factory->AddRef();
-   return factory;
-}
-
-

Talking to Warren, he suggests that we even provide a shorthand for this, we should be able to register a factory with just a function pointer.

-
-

Original Document Information

- -
-

diff --git a/files/zh-cn/getting_started_with_nss/index.html b/files/zh-cn/getting_started_with_nss/index.html deleted file mode 100644 index 61db3e9c7b..0000000000 --- a/files/zh-cn/getting_started_with_nss/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: NSS簡介 -slug: Getting_Started_With_NSS -translation_of: Mozilla/Projects/NSS/Getting_started_with_NSS ---- -

如何参与NSS

-

Network Security Services (NSS) 是一个由Mozilla software所使用的加密算法和网络安全协议基础库

-

你想要参与并且帮助我们改善Mozilla火狐和其它使用NSS的应用的核心安全性吗?我们正期待你的帮助!

-

 

-

我们有很多任务等着你的关注,而且我们也很乐意去帮助你找到符合你的兴趣和技能的领域。你可以在irc.mozilla.org#nss 频道找到我们或者在 mozilla.dev.tech.crypto newsgroup 里提出你的问题。

-

 

-

NSS库以及它的支持性指令工具是由C语言所写成的。它的编译系统和自动测试是基于makefiles和bash scripts写成。

-

随着时间的推移,许多关于NSS不同方面的文档已经产生。你可以从这里开始:

- -

(不巧的是目前 NSS 项目沒有一位技术作家, 所以我们的文档没有归整成我们想要的方式。你也可以帮忙把文档用更好的方式整理起来。)

-

NSS 示范代码

-

一个很好的学习怎样编写NSS应用的出发点是由NSS开发者们维护的指令工具。你可以在子目录 mozilla/security/nss/cmd 找到

-

或者看一些基本的 NSS示范代码.

-

一些开发中的新示范代码可以在创建新NSS示范中找到.

-
- 非常欢迎你通过 git clone 
-

git://fedorapeople.org/~emaldonado/samples.git

-

下载示范代码

-
-

贡献机会:

-

... (这部分正在建设当中,但是仍然有很多贡献的机会)

-

你可以查看 近期任务.

-
-

 

diff --git a/files/zh-cn/getting_started_with_xulrunner/index.html b/files/zh-cn/getting_started_with_xulrunner/index.html deleted file mode 100644 index 1686cb7422..0000000000 --- a/files/zh-cn/getting_started_with_xulrunner/index.html +++ /dev/null @@ -1,202 +0,0 @@ ---- -title: XULRunner入门 -slug: Getting_started_with_XULRunner -translation_of: Archive/Mozilla/XULRunner/Getting_started_with_XULRunner ---- -

{{ Next("Windows and menus in XULRunner") }}

-

这一节通过使用XULRunner构建一个基本的桌面应用来探讨Mozilla平台。已知的Firefox(“火狐”Web浏览器)、Thunderbird(“雷鸟”Email客户端)和其它多种类应用程序都是使用这个平台编写完成的,可以坚信一点Mozilla平台可以被用来构建基本的应用程序。另有一个名为Creating XULRunner Apps with the Mozilla Build System的章节包含了更加完整的内容用于构建XULRunner应用程序。如果你需要修改XULRunner本身或是将XULRunner整合到外部二进制程序中,那么你需要阅读这个章节。

-

步骤1:下载XULRunner

-

你能够在MDC里的XULRunner主页中找到下载连接。由于我们并不创建任何的二进制XPCOM组件,所以仅需要下载并安装XULRunner运行时包而不是SDK

-

针对WIndows版本下载得到的是一个ZIP文件而并不是真正的安装程序。作为一个开发者我更喜欢这种简单解压缩就可以完成安装的方式。我假设它不会挂接到我的Windows系统上而这是件好事。这同时也意味着XULRunner是“便携式”的,所以如果你将应用开发成一种“便携式”的形式,那么你将可以将程序放到闪存存储器中或在云端同步。

-

Mac版本的XULRunner被发布成tar.bz2格式的归档文件。你可以解压缩到任何你喜欢的位置,但在本文档中的多个位置都假设了你已经将解压缩得到的文件放置在了/Library/Frameworks目录中。

-

到从版本11.10开始在Ubuntu桌面系统及它的各种变体版本中(Xubuntu,Kubuntu),XULRunner已经不再被维护并且不存在于Ubuntu的软件仓库中了。因此不管你是想手动编译XULRunner或是从Mozilla's FTP服务器上下载发布版本。一种方法就是在每次你想安装新版本时运行以下脚本:

-
- FIREFOX_VERSION=`grep -Po  "\d{2}\.\d+" /usr/lib/firefox/platform.ini`
- ARCH=`uname -p`
- XURL=https://ftp.mozilla.org/pub/mozilla.org/xulrunner/releases/$FIREFOX_VERSION/runtimes/xulrunner-$FIREFOX_VERSION.en-US.linux-$ARCH.tar.bz2
- cd /opt
- sudo sh -c "wget -O- $XURL | tar -xj"
- sudo ln -s /opt/xulrunner/xulrunner /usr/bin/xulrunner
- sudo ln -s /opt/xulrunner/xpcshell /usr/bin/xpcshell
-

你也应该保存此脚本以便使用。注意:如果你使用的Firefox是构建于Ubuntuzilla仓库的,请将/usr/lib/firefox/platform.ini替换/opt/firefox/platform.ini。

-

步骤2:安装XULRunner

-

在Windows系统中将压缩文件解压缩到一个合理的位置。我将其解压缩到了一个新创建的目录中C:\program files\xulrunner。

-

在Mac系统中将tar.bz2文件解压缩到名为XUL.Framework的目录中。将此目录拷贝到/Library/Frameworks,或是其它你喜欢的位置。

-

在Linux系统中如果你使用的是预发布(Pre-release)的XULRunner的话,你仅需要解包归档文件即可。

-
-

Optionally, if you've downloaded the compressed archive of XULRunner and would like to install it on your system you can do so by running作为可选的步骤,如果你已经下载了XULRunner的压缩文档并想将其安装到你的系统中,你可以运行以下命令来做到这一点

-

xulrunner --register-global

-

 作为管理名以上命令会将XULRunner注册给本机上的所有用户。仅注册给当前用户可以运行以下命令

-

xulrunner --register-user

-

不管你是否执行了安装过程XULRunner都会正常工作。这纯粹是为了方便。

-
-
-

In all systems you should unzip the omni.ja file into some example directory and take a look at all the awesome! First change the file extension to zip and then use your normal filesystem's decompression tool to open it up. The contents of omni.ja are available to XULRunner applications and are what make it possible to build amazing applications easily!

-
-

步骤3:创建应用程序目录结构

-

是时候了,我们做一个简单的没有什么功能的应用程序。如果你愿意你可以称它为“Hello World”。所有以下你看到的你都可以在MDC的XULRunner文档中找到更细节的内容。

-
-

Hint: Skip ahead and download the sample application, you can experiment with it while following this tutorial. You can download the sample application from https://github.com/matthewkastor/XULRunner-Examples. Please continue reading to learn the "what", "why" and "how" parts of building a XULRunner application.

-
-

在Windows中我新创建了root目录在c:\program files\myapp,但你可以将其创建在任何你喜欢的地方,使用任意一种你喜欢的OS。Windows、Mac和Linux使用了相同的目录结构。这里列出了子目录的结构:

-
+ myapp/
-|
-+-+ chrome/
-| |
-| +-+ content/
-| | |
-| | +-- main.xul
-| | |
-| | +-- main.js
-| |
-| +-- chrome.manifest
-|
-+-+ defaults/
-| |
-| +-+ preferences/
-|   |
-|   +-- prefs.js
-|
-+-- application.ini
-|
-+-- chrome.manifest
-
-

注意在目录结构中有5个文件:application.inichrome.manifest (2个)、 prefs.jsmain.xul。/chrome/chrome.manifest文件是可选的,但可能对向下兼容是有用的。请看以下记述内容。

-
-

关于可安装bundle的目录结构的更详细内容请参考Structure of an installable bundle

-
-
- Note: In XULRunner 2.0, the chrome.manifest is now used to register XPCOM components in addition to its previous uses. Part of this change means the /chrome/chrome.manifest is no longer considered the "root" manifest. XULRunner will not check that folder location for a root-level chrome.manifest. You need to move your existing chrome.manifest to the application root folder, remembering to update the relative paths within the file. You could also just create a new application root-level manifest that includes the /chrome/chrome.manifest, which is what this tutorial will do.
-

步骤4:设置 application.ini

-

application.ini 文件为你的应用扮演着XULRunner入口点的角色。它指定了你的应用打算如何使用XULRunner平台以及配置一些信息以告诉XULRunner如何运行你的程序。下面是我的文件内容:

-
[App]
-Vendor=XULTest
-Name=myapp
-Version=1.0
-BuildID=20100901
-ID=xulapp@xultest.org
-
-[Gecko]
-MinVersion=1.8
-MaxVersion=200.*
-
-
- Note: MinVersion 和MaxVersion字段指示了你的应用所兼容的Gecko版本的范围;确保你设置了它们而且你所使用的XULRunner的版本也是在这个范围之内,否则你的应用将不能工作。
-
- Note: 确保你的应用名称是小写的,并且长度大于3个字符。
-

步骤5:设置chrome清单文件

-

The chrome manifest file is used by XULRunner to define specific URIs which in turn are used to locate application resources. This will become clearer when we see how the “chrome://” URI is used. Application chrome can be in a single or a few JAR files or uncompressed as folders and files. I am using the uncompressed method for now. Here is the chrome/chrome.manifest:

-
 content myapp content/
-
-

As mentioned in Step 3, the default location of the chrome.manifest has changed in XULRunner 2.0, so we also need a simple chrome.manifest in the application root which will include the the manifest in our chrome root. Here is the application root chrome.manifest:

-
manifest chrome/chrome.manifest
-

步骤6:设置配置

-

The prefs.js file tells XULRunner the name of the XUL file to use as the main window. Here is mine:

-
pref("toolkit.defaultChromeURI", "chrome://myapp/content/main.xul");
-
-/* debugging prefs, disable these before you deploy your application! */
-pref("browser.dom.window.dump.enabled", true);
-pref("javascript.options.showInConsole", true);
-pref("javascript.options.strict", true);
-pref("nglayout.debug.disable_xul_cache", true);
-pref("nglayout.debug.disable_xul_fastload", true);
-
-

XULRunner specific preferences include:

-
-
- toolkit.defaultChromeURI
-
- Specifies the default window to open when the application is launched.
-
- toolkit.defaultChromeFeatures
-
- Specifies the features passed to window.open() when the main application window is opened.
-
- toolkit.singletonWindowType
-
- Allows configuring the application to allow only one instance at a time.
-
-
-

The toolkit preferences are described in further detail in XULRunner:Specifying Startup Chrome Window.

-

The debugging preferences are discussed in Debugging a XULRunner Application

-
-

步骤7:创建一些XUL

-

Finally, we need to create a simple XUL window, which is described in the file main.xul. Nothing fancy here, just the minimum we need to make a window. No menus or anything.

-

main.xul:

-
<?xml version="1.0"?>
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<window id="main" title="My App" width="300" height="300" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-  <script type="application/javascript" src="chrome://myapp/content/main.js"/>
-
-  <caption label="Hello World"/>
-  <separator/>
-  <button label="More >>" oncommand="showMore();"/>
-  <separator/>
-  <description id="more-text" hidden="true">This is a simple XULRunner application. XUL is simple to use and quite powerful and can even be used on mobile devices.</description>
-
-</window>
-
-
- Note: Make sure there is no extra whitespace at the beginning of the XML/XUL file
-

The application also has a JavaScript file. Most XUL applications will include some external JavaScript, so the sample application does too, just to show how to include it into the XUL file.

-

main.js:

-
function showMore() {
-  document.getElementById("more-text").hidden = false;
-}
-
-
-

For more information about XUL see: XUL.

-

For information about mixing HTML elements into your XUL read Adding HTML Elements.

-
-

步骤8:运行应用程序

-

The moment of truth. We need to get XULRunner to launch the bare-bones application.

-

Windows

-

From a Windows command prompt opened to the myapp folder, we should be able to execute this:

-
 C:\path\to\xulrunner.exe application.ini
-
-

Of course, if you opted to install xulrunner then you could simply do

-
%ProgramFiles%\xulrunner.exe application.ini
-

or on 64 bit systems

-
%ProgramFiles(x86)%\xulrunner.exe application.ini
-
-

Note: you can also install your application when you're finished debugging it. See XUL Application Packaging for details.

-
-

Mac

-

On the Mac, before you can run a XULRunner application with everything intact, you must install it using the --install-app xulrunner commandline flag. Installing the application creates an OS X application bundle:

-
 /Library/Frameworks/XUL.framework/xulrunner-bin --install-app /<path>/<to>/myapp.zip
-
-

Once installed, you can run the application:

-
 /Library/Frameworks/XUL.framework/xulrunner-bin "/Applications/Finkle/TestApp.app/Contents/Resources/application.ini"
-
-

You may run it without installing (but with the menu bar and dock icon missing) in OS X by typing:

-
/Library/Frameworks/XUL.framework/xulrunner-bin "/<full path>/TestApp/application.ini"
-
-
-

Note: The full path is required or a "Error: couldn't parse application.ini."-message will be returned.

-
-

This might also be simplified using a very simple shell script (i call mine "run.sh"):

-
#!/bin/sh
-/Library/Frameworks/XUL.framework/xulrunner-bin `pwd`/application.ini
-
-

Linux

-

On Ubuntu, you can run the application from a terminal. First change into the \myapp folder, then start the application by:

-
 xulrunner application.ini
-
-

You should now see a window that looks something like this. This particular screenshot is from Ubuntu 10.

-

myapp-screenshot.png

-

Alternative: 通过Firefox运行XUL应用

-

With Firefox 3 and later, you can tell the Firefox executable to run a XUL application from the command line. The XUL application will run instead of the Firefox browser that normally starts. This is similar to starting a XUL app using XULRunner. See Using Firefox to run XULRunner applications. This does not work if Firefox itself was installed as a XUL app - you need to use the installed XULRunner directly.

-

Further Reading:

-

There are many things you can do with XULRunner. Before you get too far into things you might want to read the XULRunner tips article. Also, throughout this tutorial you've been introduced to various bits of the Toolkit API and it may help you to get familiar with it. Once you've got an application that's ready for the world you'll love our article titled Deploying XULRunner.

-

For now, click the "next" link to learn about windows and menus in XULRunner!

-

{{ Next("Windows and menus in XULRunner") }}

-
-

Original Document Information

- -
-

{{ languages( { "ja": "ja/Getting_started_with_XULRunner", "ko": "ko/Getting_started_with_XULRunner" } ) }}

diff --git a/files/zh-cn/gre/index.html b/files/zh-cn/gre/index.html deleted file mode 100644 index cf6028ae88..0000000000 --- a/files/zh-cn/gre/index.html +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: GRE -slug: GRE -tags: - - 'Gecko:Articles' - - XULRunner - - 'XULRunner:Articles' -translation_of: Archive/Mozilla/GRE ---- -

嵌入式Mozilla技术的框架被称为GRE(Gecko运行时环境)。该嵌入式框架允许应用程序定位并嵌入一个兼容的gecko运行时,而不须要事先知道运行时安装的位置。这个文档描述了被嵌入方如何链接到一个GRE。要了解如何向GRE注册,请阅读GRE注册。 -

原来的"XRE"项目(意思是XUL运行时环境),已经被XULRunner项目取代。 -

-

Mozilla Suite: 旧GRE

-

有两种不同的GRE:旧GRE是Mozilla应用程序套件的一部分。它随着Mozilla 1.4至1.7.x的Windows版安装程序安装。在Linux上还没有正式发布过带有GRE的Mozilla,但是各个Linux分发者例如Red Hat曾向Mozilla注册过他们的好像是GRE。Mozilla套件从来没有在mac平台上支持GRE。 -

-

XULRunner: 新GRE

-

XULRunner是GRE的新版本,它不仅允许嵌入,而且能够引导启动整个XUL应用程序,例如Firefox。XULRunner支持或将要支持所有三大主流平台(Windows,mac,和Linux)。 -

-

从应用程序代码寻找和使用GRE

-

避免直接链接xpcom.dll

-

如果一个应用程序希望使用GRE,必须确保链接到一个适当的库。如果直接链接xpcom.dll/libxpcom.so(xpcom.lib导入库),您的应用程序将不能启动,除非xpcom.dll在您的PATH路径中。这样的话就妨碍了在运行时动态地寻找兼容的GRE。 -

-

寻找兼容的GRE

-

为了寻找兼容的GRE,您应当使用函数GRE_GetGREPathWithProperties(声明在 {{ Source("xpcom/glue/standalone/nsXPCOMGlue.h") }})。这将允许嵌入者指定适合的GRE版本,并指定GRE必须实现的特性(目前还没有特殊的特性被定义)。 -

-

静态链接xpcomglue.lib(the "standalone glue")

-

解决静态链接xpcomglue.lib的方案,被称为"standalone glue" (see XPCOM Glue). 该库在嵌入代码和XPCOM间提供一个中间层。要使用XPCOM glue,您必须遵循以下步骤: -

- -

依赖库和环境变量

-

XULRunner GRE被设计成不需要嵌入者在调用XPCOMGlueStartup前设置任何环境变量,比如PATH或LD_LIBRARY_PATH,因为它将动态的定位正确的依赖库。不幸的是,基于Mozilla套件的GRE没有这样的便利,特别是在Linux上。嵌入者将需要设置LD_LIBRARY_PATH环境变量,并开始一个新进程才能正确地嵌入基于套件的GRE。 -

{{ languages( { "en": "en/GRE", "ja": "ja/GRE" } ) }} diff --git a/files/zh-cn/how_to_build_an_xpcom_component_in_javascript/index.html b/files/zh-cn/how_to_build_an_xpcom_component_in_javascript/index.html deleted file mode 100644 index 8e138b620e..0000000000 --- a/files/zh-cn/how_to_build_an_xpcom_component_in_javascript/index.html +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: How to Build an XPCOM Component in Javascript -slug: How_to_Build_an_XPCOM_Component_in_Javascript -tags: - - Extensions - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Building_components_in_JavaScript ---- -

-

这是一个在javascript中构建XPCOM组件"hello world"的教程。这个教程不会描述XPCOM是怎么工作或者为什么那么工作,也不打算对每一部分代码进行解释。这个会在其他文章里面祥述elsewhere. 这个教程展示给你用最少的步骤来完成一个能工作的组件的过程。 -

Caveat: This was done on a Mac. YMMV with Windows. -


-

-

实现

-

这个组件将会公开一个方法,他返回"Hello World!". -

-

定义接口

-

如果你想在JavaScript中用你的接口, 或者从其他 XPCOM components中调用, 你要定义一个公开接口 (如果你的组件仅仅用在Javascript中, 你可以使用 wrappedJSObject 技巧来避免这里所建立的接口. 参看 here 上的例子). -

Mozilla应用中已经定义了很多接口,你可能不必再定义一个. 你可以浏览现有的Mozilla源代码里面的XPCOM接口,或者使用XPCOMViewer, 他是一个浏览注册接口和组件的GUI工具. 你可以下载旧的跟Firefox 1.5匹配的viewer,在mozdev mirrors. -

如果一个现存的接口满足你的要求,那你就不需要再写一个IDL, 编译typelib, 可以直接跳过下一节 next section. -

如果你没有发现现有的合适的接口,那你就要定义一个自己的。XPCOM使用一个IDL的修订版来定义接口, 叫做XPIDL. 这里有一个XPIDL对HelloWorld组件的定义: -

HelloWorld.idl -

-
#include "nsISupports.idl"
-
-[scriptable, uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)]
-interface nsIHelloWorld : nsISupports
-{
-  string hello();
-};
-
-

注意你要为每一个XPCOM组件建立一个UUID。参看Generating GUIDs。 -

-

编译 Typelib

-

你的接口定义必须编译成为二进制(XPT)以便于注册和在Mozilla应用中使用。编译可以利用Gecko SDK. Windows and Linux versions 的SDK可以从wiki.mozilla.org获取. 我编译了一个Mac version的SDK (1.8 branch, OS X PPC 10.4), 暂时放在 here. -

执行下面的命令来编译typelib. 其中, <tt>{sdk_dir}</tt>是你放置Gecko SDK的目录. -

-
{sdk_dir}/bin/xpidl -m typelib -w -v -I {sdk_dir}/idl -e HelloWorld.xpt HelloWorld.idl
-
-

这将会在当前目录建立一个typelib文件HelloWorld.xpt. -

-

建立组件

-

HelloWorld.js -

-
/***********************************************************
-constants
-***********************************************************/
-
-// reference to the interface defined in nsIHelloWorld.idl
-const nsIHelloWorld = Components.interfaces.nsIHelloWorld;
-
-// reference to the required base interface that all components must support
-const nsISupports = Components.interfaces.nsISupports;
-
-// UUID uniquely identifying our component
-// You can get from: http://kruithof.xs4all.nl/uuid/uuidgen here
-const CLASS_ID = Components.ID("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx}");
-
-// description
-const CLASS_NAME = "My Hello World Javascript XPCOM Component";
-
-// textual unique identifier
-const CONTRACT_ID = "@dietrich.ganx4.com/helloworld;1";
-
-/***********************************************************
-class definition
-***********************************************************/
-
-//class constructor
-function HelloWorld() {
-};
-
-// class definition
-HelloWorld.prototype = {
-
-  // define the function we want to expose in our interface
-  hello: function() {
-      return "Hello World!";
-  },
-
-  QueryInterface: function(aIID)
-  {
-    if (!aIID.equals(nsIHelloWorld) &&
-        !aIID.equals(nsISupports))
-      throw Components.results.NS_ERROR_NO_INTERFACE;
-    return this;
-  }
-};
-
-/***********************************************************
-class factory
-
-This object is a member of the global-scope Components.classes.
-It is keyed off of the contract ID. Eg:
-
-myHelloWorld = Components.classes["@dietrich.ganx4.com/helloworld;1"].
-                          createInstance(Components.interfaces.nsIHelloWorld);
-
-***********************************************************/
-var HelloWorldFactory = {
-  createInstance: function (aOuter, aIID)
-  {
-    if (aOuter != null)
-      throw Components.results.NS_ERROR_NO_AGGREGATION;
-    return (new HelloWorld()).QueryInterface(aIID);
-  }
-};
-
-/***********************************************************
-module definition (xpcom registration)
-***********************************************************/
-var HelloWorldModule = {
-  _firstTime: true,
-  registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
-  {
-    aCompMgr = aCompMgr.
-        QueryInterface(Components.interfaces.nsIComponentRegistrar);
-    aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME,
-        CONTRACT_ID, aFileSpec, aLocation, aType);
-  },
-
-  unregisterSelf: function(aCompMgr, aLocation, aType)
-  {
-    aCompMgr = aCompMgr.
-        QueryInterface(Components.interfaces.nsIComponentRegistrar);
-    aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);
-  },
-
-  getClassObject: function(aCompMgr, aCID, aIID)
-  {
-    if (!aIID.equals(Components.interfaces.nsIFactory))
-      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
-    if (aCID.equals(CLASS_ID))
-      return HelloWorldFactory;
-
-    throw Components.results.NS_ERROR_NO_INTERFACE;
-  },
-
-  canUnload: function(aCompMgr) { return true; }
-};
-
-/***********************************************************
-module initialization
-
-When the application registers the component, this function
-is called.
-***********************************************************/
-function NSGetModule(aCompMgr, aFileSpec) { return HelloWorldModule; }
-
-
-

安装

-

针对扩展:

-
  1. 复制 HelloWorld.js 和 HelloWorld.xpt 到 {extensiondir}/components/。 -
  2. 从你的 profile 目录里删除 compreg.dat 和 xpti.dat。 -
  3. 重启应用程序。 -
-

针对 Firefox:

-
  1. 如果运行于源码,请复制 HelloWorld.js 和 HelloWorld.xpt 到 {objdir}/dist/bin/components 目录。 -
  2. 从 components 目录删除 compreg.dat 和 xpti.dat。 -
  3. 从 profile 目录删除 compreg.dat 和 xpti.dat。 -
  4. 重启应用程序。 -
-

使用你的组件

-
try {
-        // this is needed to generally allow usage of components in javascript
-        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
-        var myComponent = Components.classes['@dietrich.ganx4.com/helloworld;1']
-                                    .createInstance(Components.interfaces.nsIHelloWorld);
-
-        alert(myComponent.hello());
-} catch (anError) {
-        alert("ERROR: " + anError);
-}
-
-

其它资源

- -
-
diff --git a/files/zh-cn/implementing_queryinterface/index.html b/files/zh-cn/implementing_queryinterface/index.html deleted file mode 100644 index 6fe9761e22..0000000000 --- a/files/zh-cn/implementing_queryinterface/index.html +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: 实现QueryInterface接口 -slug: Implementing_QueryInterface -translation_of: Mozilla/Implementing_QueryInterface ---- -

本文档介绍正确地实现QueryInterface()的方式 

- -

QueryInterface的参考实现

- -
NS_IMETHODIMP
-nsMyImplementation::QueryInterface( REFNSIID aIID, void** aInstancePtr )
-  {
-    NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!");
-      // It's a logic error, not a runtime error, to call me without any place to put my answer!
-
-      // ...but that won't matter when someone calls me wrongly in a non-debug build.
-    if ( !aInstancePtr )
-      return NS_ERROR_NULL_POINTER;
-
-    nsISupports* foundInterface;
-
-    if ( aIID.Equals(nsCOMTypeInfo<nsIX>::GetIID()) )
-      foundInterface = NS_STATIC_CAST(nsIX*, this);
-    else if ( aIID.Equals(nsCOMTypeInfo<nsIY>::GetIID()) )
-      foundInterface = NS_STATIC_CAST(nsIY*, this);
-
-    // ...as many cases as needed...
-
-    else if ( aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID()) )
-      foundInterface = NS_STATIC_CAST(nsISupports*, NS_STATIC_CAST(nsIX*, this));
-        // I (may) have multiple |nsISupports| in me,
-        //  so first I cast to a specific base to avoid ambiguity
-    else
-      foundInterface = 0;
-
-
-    nsresult status;
-    if ( !foundInterface )
-      status = NS_NOINTERFACE;
-    else
-      {
-        NS_ADDREF(foundInterface);
-        status = NS_OK;
-      }
-
-    *aInstancePtr = foundInterface;
-    return status;
-  }
-
-
- -

有什么好处呢?

- -

代码优点:

- - - -

一些替代方案

- -

NS_IMPL_QUERY_INTERFACE[012] 宏

- -

除了nsISupports外,上面的示例还实现了两个{{ mediawiki.external('XP') }} COM接口。NS_IMPL_QUERY_INTERFACE2宏可以为您编写此函数(尽管我很难推荐宏),例如,

- -
NS_IMPL_QUERY_INTERFACE2(nsMyImplementation, nsIX, nsIY)
-                                          // implements |nsMyImplementation::QueryInterface| as above
-
-NS_IMPL_QUERY_INTERFACE1(nsFoo, nsIFoo)   // |nsFoo::QueryInterface| provides |nsIFoo| and |nsISupports|
-NS_IMPL_QUERY_INTERFACE0(nsBar)           // |nsBar::QueryInterface| can only provide an |nsISupports|
-
- -

同样,当仅实现一个附加接口时,可以使用宏NS_IMPL_QUERY_INTERFACE1;当仅实现nsISupports时,可以使用宏NS_IMPL_QUERY_INTERFACE0 。如果使用NS_IMPL_ISUPPORTS*宏,将为您调用这些宏,这些宏提供相应的QueryInterface 实现,以及AddRefRelease

- -

调用继承的 QueryInterface

- -

有时,您只是将一个或两个新接口添加到已经支持许多其他接口的实现中。在这种情况下,在测试了所关心的特定IID之后,您可能希望调用底层实现。这节省了代码空间并降低了复杂性。下面的代码突出显示了这些差异。

- -
class nsMyImplmentation : public nsBaseImplementation, public nsIX, public nsIY { ... };
-
-NS_IMETHODIMP
-nsMyImplementation::QueryInterface( REFNSIID aIID, void** aInstancePtr )
-    /*
-      I just add the interfaces |nsIX| and |nsIY|.
-      My base class |nsBaseImplementation| provides all the rest.
-    */
-  {
-    NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!");
-
-    if ( !aInstancePtr )
-      return NS_ERROR_NULL_POINTER;
-
-    nsISupports* foundInterface;
-
-    if ( aIID.Equals(nsCOMTypeInfo<nsIX>::GetIID()) )
-      foundInterface = NS_STATIC_CAST(nsIX*, this);
-    else if ( aIID.Equals(nsCOMTypeInfo<nsIY>::GetIID()) )
-      foundInterface = NS_STATIC_CAST(nsIY*, this);
-    // Note: Don't check for |nsISupports|; |nsBaseImplementation| will do that for me.
-    else
-      foundInterface = 0;
-
-
-    nsresult status;
-    if ( !foundInterface )
-        // OK, _I_ didn't find an interface.  Maybe my base class can.
-      status = nsBaseImplementation::QueryInterface(aIID, &foundInterface);
-    else
-      {
-        NS_ADDREF(foundInterface);
-        status = NS_OK;
-      }
-
-    *aInstancePtr = foundInterface;
-    return status;
-  }
-
- -

请注意,如果 base实现 的 QueryInterface找到了适当的接口,则你的QueryInterface 不能 AddRef 它。这反映在上面的代码中。
-
- 这种技术之所以有效,是因为 nsBaseImplementation 已经是一个可以单独使用的完整类。当你从几个完整的类派生时,这种技术不太合适;但如果您对顺序敏感,则仍然可以使用它,例如,

- -
// ...
-    nsresult status;
-    if ( !foundInterface )
-      {
-        // OK, ask |nsBase1Imp| first, because I want _it_ to be the one true |nsISupports|.
-        status = nsBase1Imp::QueryInterface(aIID, &foundInterface);
-
-        if ( !foundInterface )
-          status = nsBase2Imp::QueryInterface(aIID, &foundInterface);
-
-        if ( !foundInterface )
-          status = nsBase3Imp::QueryInterface(aIID, &foundInterface);
-      }
-    else
-      {
-        NS_ADDREF(foundInterface);
-        status = NS_OK;
-      }
-    // ...
-
- -

如果您的任何基类参与真正的聚合,那么要把正确的事情做好 即使不是不可能,也是很困难的。您将不能在聚合对象上获得对 QueryInterface 的调用,这可能会返回错误的接口。这也是一个需要特别避免 聚合和复杂的层次结构 的原因。

- -

NS_GET_IID 宏

- -

您可以使用·NS_GET_IID 宏,而不是键入完整的GetIID 表达式。一般来说,我不赞成宏,除非在不同的情况下宏必须扩展为不同的文本,例如,不同的平台,调试与非调试,等等。在这种情况下,宏是必不可少的。在其他情况下,宏可能会帮助一些人,但通常会给其他人带来模糊的问题。它们总是使程序源更加脆弱。在这种情况下,宏只是为了方便起见,所以我不推荐它,但我确实提供了它作为替代。

- -
// ...
-    if ( aIID.Equals(NS_GET_IID(nsIX)) )
-      foundInterface = NS_STATIC_CAST(nsIX*, this);
-    else if ( aIID.Equals(NS_GET_IID(nsIY)) )
-      foundInterface = NS_STATIC_CAST(nsIY*, this);
-
-    // ...as many cases as needed...
-
-    else if ( aIID.Equals(NS_GET_IID(nsISupports)) )
-    // ...
- -

Thanks

- -

特别感谢 Heikki ToivonenChris WatersonJohn Bandhauer 提供的宝贵反馈,这些反馈极大地改进了这里提供的实现

diff --git a/files/zh-cn/interfaces/index.html b/files/zh-cn/interfaces/index.html deleted file mode 100644 index eb34f25e81..0000000000 --- a/files/zh-cn/interfaces/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Interfaces -slug: Interfaces -translation_of: Mozilla/Tech/XPCOM/Reference/Interface ---- -

InterfacesInterfaces

diff --git a/files/zh-cn/introducing_audio_api_extension/index.html b/files/zh-cn/introducing_audio_api_extension/index.html deleted file mode 100644 index 61e3a24924..0000000000 --- a/files/zh-cn/introducing_audio_api_extension/index.html +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: 介绍音频 API -slug: Introducing_Audio_API_Extension -translation_of: Archive/Mozilla/Introducing_the_Audio_API_Extension ---- -

音效 API 是 HTML5 規範中的媒體元素 {{ HTMLElement("audio") }} 與 {{ HTMLElement("video") }} 的補充功能,它讓開發者可以存取音效的後設資料跟音頻本身的生資料。開發者可以具象化這些音效資料,分析這些資料,甚至是創造出新的音效資料。

-

讀取音頻串流

-

loadedmetadata 事件

-

當一個媒體的後設資料傳至使用者電腦的時候,一個 loadedmetadata 事件會被觸發。這個事件有以下這些屬性:

- -

這些資料在解碼音頻資料串流的的時候會用到。下面是一個從一個音頻元素取出這些資料的例子:

-
<!DOCTYPE html>
-<html>
-  <head>
-    <title>JavaScript 後設資料範例</title>
-  </head>
-  <body>
-    <audio id="audio-element"
-           src="song.ogg"
-           controls="true"
-           style="width: 512px;">
-    </audio>
-    <script>
-      function loadedMetadata() {
-        channels          = audio.mozChannels;
-        rate              = audio.mozSampleRate;
-        frameBufferLength = audio.mozFrameBufferLength;
-      }
-      var audio = document.getElementById('audio-element');
-      audio.addEventListener('loadedmetadata', loadedMetadata, false);
-    </script>
-  </body>
-</html>
-
-

MozAudioAvailable 事件

-

當播放一個音頻源的時候,樣本資料會被傳播至音頻處理層級而這些樣本也會被輸入進音頻緩衝(大小取決於mozFrameBufferLength)。當緩衝被填滿的時候,一個 MozAudioAvailable 事件會被觸發,而這個事件就含有一段時間內的樣本。這些樣本不一定在事件被觸發的時候已經被播放過,也不一定馬上反應媒體元素上的靜音設定或是音量調整。音頻的播放、暫停、跳躍都會影響生音頻資料串流。

-

MozAudioAvailable 事件有兩個屬性:

- -

frame緩衝含有一個音頻樣本的陣列。請注意樣本不會照對應的頻道分隔,而是混在一起。舉例來說,一個二頻道訊號:頻道1-樣本1 頻道2-樣本1 頻道1-樣本2 頻道2-樣本2 頻道3-樣本1 頻道3-樣本2。

-

讓我們擴充之前的範例,在一個 {{ HTMLElement("div") }} 元素裡顯示時間戳記跟首兩個樣本:

-
<!DOCTYPE html>
-<html>
-  <head>
-    <title>JavaScript 具象化範例</title>
-    <body>
-    <audio id="audio-element"
-           src="revolve.ogg"
-           controls="true"
-           style="width: 512px;">
-    </audio>
-	<pre id="raw">hello</pre>
-    <script>
-      function loadedMetadata() {
-        channels          = audio.mozChannels;
-        rate              = audio.mozSampleRate;
-        frameBufferLength = audio.mozFrameBufferLength;
-      }
-
-      function audioAvailable(event) {
-        var frameBuffer = event.frameBuffer;
-        var t = event.time;
-
-        var text = "Samples at: " + t + "\n"
-        text += frameBuffer[0] + "  " + frameBuffer[1]
-        raw.innerHTML = text;
-      }
-
-      var raw = document.getElementById('raw')
-      var audio = document.getElementById('audio-element');
-      audio.addEventListener('MozAudioAvailable', audioAvailable, false);
-      audio.addEventListener('loadedmetadata', loadedMetadata, false);
-
-    </script>
-  </body>
-</html>
-
-

產生一個音頻串流

-

產生並裝置一個由腳本撰寫的 {{ HTMLElement("audio") }} 元素(也就是沒有 src 屬性)也是可以的。你可以用腳本設定音頻串流,然後寫入音頻樣本。網頁製作者必須產生一個音頻物件然後使用 mozSetup() 函式來設定頻道的數量跟頻率(赫茲)。舉例來說:

-
// 產生一個新的音頻元素
-var audioOutput = new Audio();
-// 設定此音頻元素的串流為「雙聲道,44.1千赫」
-audioOutput.mozSetup(2, 44100);
-
-

再來就需要做樣本。這些樣本和 mozAudioAvailable 事件的樣本用的格式是一樣的。這些樣本可以用 mozWriteAudio() 函式來寫入音頻串流。請注意並不是所有的樣本都會被寫入串流。函示會回傳被寫入串流的樣本數,這對於下一次要寫入資料的時候的很好用。請看下面的例子:

-
// 用JS陣列來寫樣本
-var samples = [0.242, 0.127, 0.0, -0.058, -0.242, ...];
-var numberSamplesWritten = audioOutput.mozWriteAudio(samples);
-
-// 用參數化陣列來寫樣本
-var samples = new Float32Array([0.242, 0.127, 0.0, -0.058, -0.242, ...]);
-var numberSamplesWritten = audioOutput.mozWriteAudio(samples);
-
-

我們在下一個範例做一個脈動:

-
<!doctype html>
-<html>
-  <head>
-     <title>及時產生音頻</title>
-   <script type="text/javascript">
-     function playTone() {
-       var output = new Audio();
-      output.mozSetup(1, 44100);
-       var samples = new Float32Array(22050);
-       var len = samples.length;
-
-       for (var i = 0; i < samples.length ; i++) {
-         samples[i] = Math.sin( i / 20 );
-       }
-              output.mozWriteAudio(samples);
-     }
-   </script>
- </head>
- <body>
-   <p>當你按下以下的按鈕之後,這個demo會撥一秒鐘的音調。</p>
-   <button onclick="playTone();">播放</button>
- </body>
- </html>
-

mozCurrentSampleOffset() 方法回傳音頻串流的「可聽位置」,也就是最後一次被播放的樣本的位置。

-
// 取得當時後端音頻串流的可聽位置(以樣本數計算)。
-var currentSampleOffset = audioOutput.mozCurrentSampleOffset();
-
-

對於正在被播放的樣本(正在被硬體播放的樣本位置可以由 mozCurrentSampleOffset() 取得),為了保持一點點的領先(「一點點」一般大約是500 ms),你應該定期地用 mozWriteAudio() 寫入固定額度的音頻資料。舉例來說,假如我們設此音頻為雙聲道與每秒44100個樣本、間隔時間為100 ms、pre-buffer為500 ms,則我們每次需要寫 (2 * 44100 / 10) = 8820 個樣本,總計的樣本數是 (currentSampleOffset + 2 * 44100 / 2)。(譯注:個人覺得這段寫得很怪,直接看例子可能會比較好懂。)

-

為了讓聲音的播放不間斷但是在寫入音頻資料資料與播放的時間差為最小,自動偵測最小的pre-buffer也是可能的。為了達到這個目的,你可以在一開始的時候寫入很小部份的資料,當看到 mozCurrentSampleOffset() 的回傳值大於 0 的時候測量其時間差。

-
var prebufferSize = sampleRate * 0.020; // 初使緩衝為 20 ms
-var autoLatency = true, started = new Date().valueOf();
-...
-// 延遲(Latency)的自動偵測
-if (autoLatency) {
-  prebufferSize = Math.floor(sampleRate * (new Date().valueOf() - started) / 1000);
-  if (audio.mozCurrentSampleOffset()) { // 開始播放了嗎?
-    autoLatency = false;
-}
-
-

處理音頻串流

-

由於 MozAudioAvailable 事件與 mozWriteAudio() 方法都是使用 Float32Array 為傳值,把一個音頻串流的輸出直接接上(或是處理過後接上)另一個是可以做到的。你應該將第一個音頻串流設為靜音使得只有第二音頻元素能被聽到。

-
<audio id="a1"
-       src="song.ogg"
-       controls>
-</audio>
-<script>
-var a1 = document.getElementById('a1'),
-    a2 = new Audio(),
-    buffers = [];
-
-function loadedMetadata() {
-  // 將音頻 a1 設為靜音
-  a1.volume = 0;
-  // 講 a2 的設定弄成與 a1 相等,然後由這個播放。
-  a2.mozSetup(a1.mozChannels, a1.mozSampleRate);
-}
-
-function audioAvailable(event) {
-  // 寫入當下的 framebuffer
-  var frameBuffer = event.frameBuffer;
-  writeAudio(frameBuffer);
-}
-
-a1.addEventListener('MozAudioAvailable', audioAvailable, false);
-a1.addEventListener('loadedmetadata', loadedMetadata, false);
-
-function writeAudio(audio) {
-  buffers.push(audio);
-
-  // 有在緩衝裡的資料的話,寫入該資料
-  while(buffers.length > 0) {
-    var buffer = buffers.shift();
-    var written = a2.mozWriteAudio(buffer);
-    // 如果非所有資料都被寫進去的話,將之留在緩衝裡:
-    if(written < buffer.length) {
-      buffers.unshift(buffer.slice(written));
-      return;
-    }
-  }
-}
-</script>
-
-

參見

- -

{{ languages( { "en": "en/Introducing_the_Audio_API_Extension"} ) }}

diff --git a/files/zh-cn/jsdbgapi_reference/index.html b/files/zh-cn/jsdbgapi_reference/index.html deleted file mode 100644 index 0e0f61c471..0000000000 --- a/files/zh-cn/jsdbgapi_reference/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: JSDBGAPI 参考 -slug: JSDBGAPI_Reference -translation_of: Mozilla/Projects/SpiderMonkey/JSDBGAPI ---- -

 

-


- Obviously this stuff is almost entirely undocumented.

-

See the implementation of the trap, untrap, watch, unwatch, line2pc, and pc2line functions in {{ Source("js/src/shell/js.cpp") }}. Also the (scant) comments in {{ Source("js/src/jsdbgapi.h") }}.

-

Breakpoints

- -

Watchpoints

- -

Inspecting the stack

- - - - - -

Evaluating debug code

- -

Examining object properties

- - - - -

Hooks

- - -

Memory usage

- -

System objects

- -

Profiling

-

These functions can be used to profile a SpiderMonkey application using the Mac profiler, Shark. See Profiling JavaScript with Shark.

- -

The following JSNative functions can be used to expose the above four APIs to scripts.

- diff --git a/files/zh-cn/localization_quick_start_guide/index.html b/files/zh-cn/localization_quick_start_guide/index.html deleted file mode 100644 index 69de9017d3..0000000000 --- a/files/zh-cn/localization_quick_start_guide/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: 本地化入门指南 -slug: Localization_Quick_Start_Guide -tags: - - 入门指南 -translation_of: Mozilla/Localization/Quick_start_guide ---- -

欢迎来到 Mozilla 本地化(简称 l10n)!

-

不管你来这里是想在 Mozilla 项目中开始你自己的本地化工作,还是促进已有的本地化,你都找到到了正确的地方。这份指南包含你加入 Mozilla 本地化计划所需的所有基本、技术信息。我们将带你走遍入门的所有步骤,从设置初始环境到测试再到发布你自己的本地化成果。一路上,你将会知道你可以去贡献的各种项目以及用于本地化的工具。

-

当我们关注特定的样例时,我们通常会取自火狐项目,因为它是 Mozilla 中被本地化最广泛的项目。当你接近指南末尾时,你应该能够更改火狐的本地化设置,然后在火狐的界面中看到对应的变化。最后,当你读完这份指南时,你将会拥有用于贡献的所有必需工具!

-

请记住,这份指南仅仅在 Mozilla 本地化的技术方面给予指导,访问 L10n Process 页面以了解整个过程。

-
-

初始设置

- 本地化之前的技术准备
-
-

翻译阶段

- 本地化翻译工具教程
-
-

质量保证阶段

- 本地化测试教程
-
-

发布阶段

- 交付你的本地化工作的步骤
-
- 这四个阶段组成了本地化计划的技术层面。点击任意链接以了解其更多信息。如果想知道全部情况,我们建议你从绿色方框开始,然后逐步看下去。
-

 

-
- 注意:这份指南为以下两种类型的贡献者而写:那些开始新的本地化工作的,以及那些加入已有的本地工作的。了解哪些信息适用于哪种类型的贡献者是重要的。为帮助你过滤并得到最合适的信息,请注意所有针对开始新本地化的贡献者的信息使用橙色文字,而所有针对加入已有本地化的贡献者的信息使用蓝色文字
-

 

-

{{ Next("Localization_Quick_Start_Guide/Initial_setup") }}

diff --git a/files/zh-cn/localization_quick_start_guide/initial_setup/index.html b/files/zh-cn/localization_quick_start_guide/initial_setup/index.html deleted file mode 100644 index 90441845b1..0000000000 --- a/files/zh-cn/localization_quick_start_guide/initial_setup/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 最初的准备 -slug: Localization_Quick_Start_Guide/Initial_setup -tags: - - bug-840092 -translation_of: Mozilla/Localization/Quick_start_guide/Initial_setup ---- -

作为参与到本地化(L10n)项目的先决条件,你需要访问到源码,获取相关工具以及一个配置好的本地环境(也就是你的电脑)。你还需要确定在你的地区是否已经存在一个本地化成果。在参与之前,我们将在这里详述你需要的账户,工具以及这些工具配置的设置。

- -

新的或现有的(本地化)

- -

在其它事情开始之前,你需要了解你是否将创建一个新的本地化或者加入一个已存在的本地化。这将决定在这篇指南以下部分当中,什么信息对你是最适用的。

- -

以下是你要做的内容:

- -

浏览现有的本地化社区名录(localization community directory)查看是否已经存在一个属于你本地的(本地化社区)。

- -
    -
  1. 如果已经存在(这样的)一个社区,联系他们并询问你可以怎样提供帮助。
  2. -
  3. 如果(这样的)一个社区不存在,发送一封电子邮件给新本地化新闻组(new-locales newsgroup)寻求额外的指引。
  4. -
- -

账户

- -

当你开始时,有少量的账户需要你注意。对于你开始做贡献,它们不是必须的,但当你准备生成一份正式的发布版时,将需要它们。现在,只需意识到这些(账户)将和你努力的进程一样重要。这些账户将存储你的代码,贡献,并帮你生成一份正式的本地化文档。

- -
-
hg (Mercurial)
-
Mercurial 是一个版本控制环境,存放主要的 Mozilla 源代码和每个正式的 Mozilla 本地化代码。你将需要它来本地化 Mozilla 应用程序。For anyone to gain access to hg repos, you must visit the Mozilla Commiter page and follow the process outlined there. Here is an example bug that illustrates the process well. Use this bug template when filing your hg account registration bug. Add a request about creating your locale's repository to the new locales newsgroup.
-
SVN
-
SVN 是一个版本控制环境,Mozilla 用来存放 Mozilla 源网站和每一个正式的 Mozilla 本地化。See this wiki page about how to gain access to SVN. Add a request about creating your locale's repository to the new locales newsgroup.
-
- -
-
Web-based L10n tools
-
We'll talk about these in a little bit. For now, just be aware that should you choose to use them, you may need to create a personal account.
-
Mozilla LDAP
-
You will need a Mozilla LDAP account once you're ready to have your localization registered on the main Mozilla repositories. Add a request about creating your LDAP account to the new locales newsgroup.
-
Locale-specific Bugzilla component
-
Having a Bugzilla component specific to your locale will help us to track your localization's progress from first steps to official release. It will also notify us when you're having problems unique to your localization team's work. Add a request about creating your locale's Bugzilla component to the new locales newsgroup.
-
- -

Local environment tools

- -

Similar to accounts, there is a number of environment tools that you should install on your personal computer. These tools will help you to store your contributions, build Mozilla applications and language packs, and test your work.

- -
-
Hg (Mercurial)
-
As noted above, we use Mercurial for maintaining Mozilla source code and localized code. Not only will you need a localization repository to store your localizations, but you need to have it installed and configured on your personal computer as well. You can find everything you need to know about installing and configuring Mercurial for your localization work here.
-
- -
-
compare-locales
-
compare-locales is a Python script that helps you check your work without needing to run Firefox or another application. Install intructions are located here.
-
L10n checks
-
L10n checks is another Python script that helps you check your work without running an application. Install instructions are located here.
-
autoconf 2.13
-
autoconf is a utility that is vital to manually creating Mozilla application builds and language packs. We use version 2.13 and higher for these builds. You can find the source files and install instructions here.
-
wget
-
wget is a command-line utility that allows you to retrieve files using internet protocols. We use it for retrieving files from repositories. You can find the source files and install instructions here.
-
Perl
-
Perl is a programming language that will help you create Mozilla application builds and language packs. You can find the source files and install instructions here.
-
Python
-
Python is a programming language in which many of our L10n testing scripts are written. You can find the source files and install instructions here.
-
Locale Switcher or Quick Locale Switcher
-
Both Locale Switcher and Quick Locale Switcher are add-ons for Mozilla applications. Either one is necessary to enable you to see your work within a Mozilla application. You can install either by searching for them in Firefox's add-ons manager or following these links.
-
A solid, Unicode-based, text editor
-
Here are some suggestions: - -
-
GNU make
-
Make is a tool which controls the generation of executables. You can find version 3.79.1 or higher here. Unfortunately, other varieties of make won't do.
-
- -

结束

- -

现在你已经完成你的最初的准备,是时候开始最棒的部分:翻译!

- -

{{ PreviousNext("Localization_Quick_Start_Guide", "Localization_Quick_Start_Guide/Translation_phase") }}

diff --git a/files/zh-cn/localizing_with_pontoon/index.html b/files/zh-cn/localizing_with_pontoon/index.html deleted file mode 100644 index 27d17d1954..0000000000 --- a/files/zh-cn/localizing_with_pontoon/index.html +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: 使用Pontoon进行本地化 -slug: Localizing_with_Pontoon -tags: - - 本地化 -translation_of: Mozilla/Localization/Localizing_with_Pontoon ---- -

Pontoon是一个基于web网页的、所见即所得(WYSIWYG)的本地化(l10n 即 localization)工具。在Mozilla基金会,我们使用Pontoon本地化Mozilla网站,包括 Firefox 和 Mozilla.org。Pontoon是一个非常简单和直观的,仅需要很少甚至没有技术背景,就能在l10n本 地化工作流程中,学会使用的工具。以下,我们将讨论如何在本地化项目中使用 Pontoon,从最初的注册登录到最终面对你的贡献者(参与该项目的志愿者或 工作人员)。在这个过程中,我们将挑出Pontoon的一些贴心特性,那将使你十分有效率,并将使你能更容易地进行本地化贡献。

- -
-

你是开发者吗? 你可以阅读《在你的项目中实现 Pontoon》,或了解如何在 GitHub 上参与。

-
- -

起步

- -

Pontoon的主页十 分易于使用。简单的从下拉选单中,挑中你想要的工作项目和你的区域设定。Pontoon系统将自动为你打开所选的本地化项目,从而启动它。要开始一个本地 化项目,点击右下角的Persona图标并登录。注意因为这里我们的目标(是教学啦),我们将特意使用Gaia的浏览器应用来演示Pontoon的功能和 工作流程。说到Gaia,下面就是Gaia浏览器应用的样子!

- -

Browser app and workspace

- -

好了,下面我们可以开始一些翻译工作了吗?

- -

翻译字符

- -

当使用Pontoon做本地化的时候,你可以有多种选择,来决定怎样翻译那些字符串。你可以选择在上下文中翻译,还是使用Pontoon工作间,或混合使用这两种都行。我们将以上下文翻译作开始。

- -

Edit string button

- - - -

在上下文环境中

- -

这就是Pontoon的上下文环境的样子。Pontoon打开一个网页(这里就是Gaia的网页浏览器应用本身),对该网页启用实时编辑模式。下面是你如何翻译你的第一个字符串:

- -
    -
  1. 将鼠标移动到你想翻译的文本上。
  2. -
  3. 文本上会出现一个编辑按钮。点击它启动编辑模式。
  4. -
  5. 用你译好的语言替代其中的英语(en-US)文本。
  6. -
  7. 点击保存图标来存储你的译文。
  8. -
  9. 看看屏幕上随即的变化,这多简单!
  10. -
- -

- -

- -

- -
-

- -

- -

Workspace alone

- -

在上下文环境之外

- -

右侧就是Pontoon的工作间,它基本上分为两列:左侧是原文本字符的空间,右侧是你输入的翻译。在你翻译的时候,它们将出现在浏览器应用的窗口。

- -

下面是如何做:

- -
    -
  1. 点击想翻译的原文右侧的文本编辑框。
  2. -
  3. 输入你的翻译。
  4. -
  5. 点击文本编辑框右边的保存按钮。
  6. -
  7. 可以看一下,浏览器应用加上译文后现在是什么样子了。
  8. -
  9. 看这多容易!
  10. -
-
- -

- -

- - - -

翻译助手

- -

你可能注意到了,当鼠标滑过工作间的段落行时,每个当前行会变绿,并有一些辅助图标出现在原文的左侧。更可能你还注意到了,在原文和翻译框之间的复制按钮。我们称这些为翻译帮手。下面是每个帮手在你翻译的时候,会怎么帮助你:

- -

String l10n features

- -
-
copy active  直接将原文复制到翻译目标
-
复制按钮在工作区中间的两列。 此助手将源字符串复制到文本框中以供保存。 复制按钮还会将源列中的任何建议复制并粘贴到目标文本框中。
-
original string active  原文字符
-
原始字符串图标显示 en-US 中的源字符串,供您进行翻译。
-
other users active  其他人的建议
-
助手显示其他用户为此源字符串建议的翻译。注意:此功能仍在开发中。
-
Other locales active  其它项目的机器翻译建议
-
此助手显示来自其他语言环境的匹配翻译。
-
translation memory active  翻译记事本的建议
-
此助手显示您的翻译记忆库文件中的匹配项。
-
Machine translation active  机器翻译
-
此助手提供从机器翻译引擎生成的翻译建议。
-
- - - -

除了你在每个段落找到的翻译帮助工具,在 Pontoon 的黑色工作区还提供其他一些工具。

- -

black bar

- -
-
Info  信息
-
The info helper gives you important, project-specific information. For example, it can profile the project's target audience or give you the anticipated project timeline.
-
     项目URL选择表
-
This helper opens a menu with all of your Pontoon projects. It allows you to switch between project's to localize from within the workspace.
-
     本地化设定选择表
-
The locale selector allows you to switch from locale to locale from within the workspace.
-
     页面选择表
-
This helper opens a menu with all of the project's sub pages, allowing you to navigate through every page and localize them all.
-
     进度条
-
This helper displays your progress on the page you're actively localizing. It is measured in number of strings translated.
-
- -

发布你的本地化项目

- -

假设你想发布你的l10n本地化工作到一个项目账户。Pontoon已经给了你这么做的方便!下面是如何发表你的本地化项目的步骤:

- -

commit export

- -
    -
  1. Click on your Persona ID in the bottom right corner.
  2. -
  3. Based on the repository your project is connected to, select any of the options: -
      -
    • SVN: click "Commit to SVN" and enter your SVN credentials.
    • -
    • Transifex: click "Save to Transifex" and enter your Transifex credentials.
    • -
    • Other: select which file format you would like to export your work in and save it to a directory on your computer.
    • -
    -
  4. -
  5. Pat yourself on the back, do a little dance, go to sleep, do something to celebrate your work!
  6. -
- -

diff --git a/files/zh-cn/localizing_with_verbatim/index.html b/files/zh-cn/localizing_with_verbatim/index.html deleted file mode 100644 index 26faae491a..0000000000 --- a/files/zh-cn/localizing_with_verbatim/index.html +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: 通过Verbatim本地化 -slug: Localizing_with_Verbatim -translation_of: Mozilla/Localization/Localizing_with_Pontoon ---- -

Verbatim是一个基于网络的工具(尤其是Mozilla托管的Pootle 实例),以展现本地化Mozilla网页内容。由于基于网络,本地用户必须连接网络才能使用。它可以用于本地化各种Mozilla项目,并且能够支持任何语言。本页将引导您完成本地化一个常见的Mozilla Web项目。这里的教程将为您提供使用Verbatim本地化您希望添加到本地化社区的任何Mozilla Web项目的坚实基础。我们将讨论Verbatim目前正在使用的具体项目,如何开始使用Verbatim,以及通过使用Verbatim实现的任务。

- -

Getting started with Verbatim

- -

There are essentially two ways to get started with Verbatim: start a new localization or join an existing localization community's efforts. Either way, you will need to follow these steps to start working on a Verbatim project.

- - - - - - - - - - - - - - - - - - - - - - -
Start a new localization on VerbatimJoin an existing localization on Verbatim
-
    -
  1. Point your browser to http://localize.mozilla.org. This is where Verbatim is hosted.
  2. -
-
-
    -
  1. Point your browser to http://localize.mozilla.org. This is where Verbatim is hosted.
  2. -
-
-
    -
  1. If you have a Mozilla LDAP account, simply sign in using your LDAP credentials. If not, register for an account and sign in once you've completed registration. The links for both are located in the upper right-hand corner of the page.
  2. -
-
-
    -
  1. If you have a Mozilla LDAP account, simply sign in using your LDAP credentials. If not, register for an account and sign in once you've completed registration. The links for both are located in the upper right-hand corner of the page.
  2. -
-
-
    -
  1. File a bug using this prefilled bugzilla template. Add your locale code and language name to the description field, as well as any other information you'd like to share. See the following example.
  2. -
- -
Example: I would like to request that you add the en-US as a new localization in Verbatim. The langauge is English. Also, I like cookies. Lots and lots of cookies. I can easily be motivated by any and all baked goods.
-
-
    -
  1. Contact the community to find out which projects they need you to concentrate your efforts on. See the following example for what you could include in your email to the community leaders.
  2. -
- -
Example: I would like to join your localization efforts on Verbatim for this locale. Where would be the best place for me to begin? Also, I would like to buy you a drink to encourage you to let me join the team!
-
- -

Now that you're registered and logged in, we'll outline the general translation workflow, using the Firefox Home project as our example.

- -

Translating

- -

First thing's first, you need to find untranslated source strings to translate.

- -
    -
  1. Navigate to the Firefox Home project page.
  2. -
  3. Select your language from the Overview tab.
  4. -
  5. Now click on the the Translate tab. This tab will display the directories for the Firefox Home page.
  6. -
  7. Select the LC Messages directory. This is where the project's .po files containing translatable strings are located. You will now see an overview of each .po file.
  8. -
  9. In the summary column, the number of words untranslated will be shown as a link. Click on that link to be taken directly to the first string that needs to be translated.
  10. -
- -

Now you're ready to contribute translations and you won't believe how easy it is. Check it out, you can contribute translations in two simple steps:

- -
    -
  1. Simply type your translation in the box to below the English string
  2. -
  3. Select Suggest. If you have approval permission, select Submit. You will then be taken to the next string that needs translating.
  4. -
  5. Hooray! You're translating! Repeat steps one and two for the remainder of the untranslated strings.
  6. -
- -
Note: If you come across a string that already has a suggested translation, you can still suggest your own translation if you feel it is more accurate.
- -

Some extra cool features on Verbatim

- -

Here are a few additional items about the Verbatim interface that you should be aware of. Some of these can be seen in the screen shot below.

- -

Translate Tab.png

- - - -

Additional tasks

- -

If you are a localizer with approval priviledges, here are a few more tasks that you should be aware of.

- -

Review suggested translations

- -
    -
  1. Click on the Review tab. It will show how many strings are waiting for review for each .po file.Review Tab1.png
  2. -
  3. Select Review suggestions to start approving suggestions. It will take you to the first string that needs to be reviewed.
  4. -
  5. You can accept the suggestion by clicking the green checkmark or reject the suggestion by clicking the red X (see the screen shot from the previous section).
  6. -
- -

It is important to note that only submitted strings will appear in your localized pages. Neither suggestions nor fuzzy strings will appear. Before commiting your final localized product, make sure all strings have been submitted.

- -

Using VCS on Verbatim

- -

VCS (Version Control System) is the repository system we use to update the project's strings as well as push your translated content onto the web. The difference between the two tasks is simply a matter of which link to click.

- -

VCS.pngTo push your strings onto the web and see your changes, simply select the Commit to VCS link underneath each file name. It usually takes about an hour before you can see your changes on the project site.

- -

To update your .po files with new untranslated strings, simple select the Update from VCS link underneath each file name.

- -

 

- -

-Note: Some projects are automatically updated nightly while others require you to manually update them to receive new source content. Be sure to pay close attention to this, as it can alter your workflow.
- -

Translating Verbatim files with an external application

- -

While in the Translate tab, you have the option to export the .po and .xliff files and translate the strings with an external application (i.e., a text editor or translation memory tool).

- -
    -
  1. To download the .po file, select the Download link found underneath each file name. To download the .xliff file, select the Download XLIFF link.
  2. -
  3. Proceed to translate the strings using your selected tool.
  4. -
- -

Once you've finished your translations, you'll need to upload your file to Verbatim. You can do this from the Translate tab.

- -
    -
  1. Navigate to the bottom of the files list to the Upload File section.
  2. -
  3. Click on the Browse button and select the file you wish to upload.
  4. -
  5. Select an upload setting from the options provided.
  6. -
  7. Once your upload setting has been selected, click Upload.
  8. -
- -
Important: There have been some problems in the past with community members updating their source strings while others are in the process of localizing the previous updated files. This can cause community members to overlook new source strings, producing untranslated strings in a localized project. Be sure to coordinate these manual updates within your community to avoid this problem.
- -

You're ready to go!

- -

Whew! You've arrived at the end! Time to take what you've learned and put it to good use spreading Mozilla to everyone in your region. Have fun and let us know if you run into any difficulties. We'll be happy to help in any way we can.

- -

 

- -

Back: Quick Start Guide

diff --git a/files/zh-cn/mdn/contribute/howto/link_a_github_account/index.html b/files/zh-cn/mdn/contribute/howto/link_a_github_account/index.html deleted file mode 100644 index 5be8c9fe23..0000000000 --- a/files/zh-cn/mdn/contribute/howto/link_a_github_account/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: 如何在您的MDN账户中关联一个GitHub账户 -slug: MDN/Contribute/Howto/Link_a_GitHub_account -tags: - - MDN - - 文档 -translation_of: Archive/MDN/Howto_Link_a_Github_account ---- -
{{MDNSidebar}}
- -
{{IncludeSubnav("/zh-CN/docs/MDN")}}
- -
-

Note: Support for Persona logins on MDN was disabled on November 1, 2016. The method for adding a Github account to your profile therefore no longer works. If you didn't add a GitHub login to your MDN account before we disabled Persona logins, please file an "Account Help" bug on Bugzilla. For further reading about the end of life of Persona, see: Persona shutdown guidelines.

-
- - -

由于Mozilla的 Persona 身份认证系统将会于2016年11月30日起关闭,所有希望为MDN做贡献的用户都需要用其他手段来登录到 MDN。当前,我们支持的唯一选择就是 GitHub,所以您需要在截止日期过后使用 GitHub 账户登入并编辑 MDN。这篇文章讲述了如何将 GitHub 身份认证添加到您的MDN账户中。

- -
-

您必须在2016年11月30日前完成此操作,否则您将再也无法登录 MDN!

-
- -

概述

- -

将GitHub身份认证添加到您的账户中并不难。下面我们将进一步讨论细节,但首先,先看一下步骤概述:

- -
    -
  1. 登录您的 MDN 账户
  2. -
  3. 转到 账户关联 页面
  4. -
  5. 添加 GitHub 身份认证。
  6. -
- -

详细指南

- -

下面是一个手把手的教程,教您如何完成您需要知道的事情。

- -

登入您的 MDN 账户

- -
    -
  1. 在任意MDN页面的顶端,将鼠标悬浮于或点击登录框。它会显示可用的身份认证方式:Persona 或 GitHub 
    - Sign in box on MDN, showing Persona and Github.
  2. -
  3. 选择 Persona ,然后用您常用的登录凭据登入。
  4. -
- -

转到账户关联页面

- -

有两种方法转到账户关联页面。

- -

一种方法就是点击下面的链接。

- - -

还有一种方法就是完成下列步骤:

- -
    -
  1. 在任意 MDN 的页面顶端单击您的用户名(就是您未登录时登入框的位置)。这将带您到您的资料页面。
  2. -
  3. 点击“齿轮”菜单,然后单击 Account connections (账户关联)。
    - Gear menu in profile, showing the "Account connections" option
  4. -
- -

添加 GitHub 身份认证

- -

您现在位于"Account connections"(账户关联)页面,它罗列了您已连接到您的 MDN 个人资料的外部账户。如果 GitHub 账户已经列出,那么恭喜你!您已经完成了!但为了测试一下您是否牢记您的密码,可以登出 MDN,再使用您的 GitHub 身份凭证登入。

- -

如果 Github 没有列出,请看看页面底部的已连接账户列表。您可以看到连接一个新的账号小节,这里列出了您可以与您的 MDN 个人资料建立连接的账户。如下图:

- -

- -

要想添加 GitHub:

- -
    -
  1. 点击 连接 Github。MDN 将会向 Github 请求权限连接这两个账户。如果您还未登录 Github,登录页面将会显示出来:
    - Screenshot of GitHub sign in window.
  2. -
  3. 如果您为您的 Github 账户开通了两步验证,您须要输入您的验证码:
    - Screenshot of GitHub's Two-factor authentication window.
  4. -
  5. 现在您登录您的 Github 账户了。您可以进行授权,以连接 Github 与 MDN 账户(除非您曾经因某些原因授权过)。此页面如下图:
    - Screenshot of GitHub "Authorize application" window.
    - 点击绿色的 Authorize application(授权应用) 按钮授予您的 MDN 账户访问您的 Github 账户的权限。当您的 Github 账户成功与 MDN 账户建立连接时,您将看到这一信息:
    - Account successfully created.
  6. -
- -

现在您不仅可用 GitHub 登录 MDN,还已经使用 GitHub 身份认证登入了!您已经准备好应对 Persona 关闭了。如有必要,您应该确定已经更新了安装的所有密码管理器。

- -

相关链接

- - diff --git a/files/zh-cn/mdn/contribute/persona_sign-in/index.html b/files/zh-cn/mdn/contribute/persona_sign-in/index.html deleted file mode 100644 index d10ee0432f..0000000000 --- a/files/zh-cn/mdn/contribute/persona_sign-in/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: MDN 和 Persona登录 -slug: MDN/Contribute/Persona_sign-in -translation_of: Archive/MDN/Persona_sign-ins ---- -
{{MDNSidebar}}
-

警告:我们不再提供使用 Persona 登录到 MDN 的服务。所以请您马上将 GitHub 账户关联到您的 MDN 资料以继续登录 MDN。

-
- -

当前MDN给志愿者提供有两种身份认证方式:Mozilla Persona 和 GitHub。从 2016 年 11 月 1 日开始,我们将会把 Persona 从可选登录方式中移除。因此您必须在您的个人资料中启用 Github 身份认证以避免无法登陆到 MDN 的情况出现,您若有任何问题都可以联系 Account Help

- -

我们认识到这很不方便,我们也为此深感抱歉。但不幸的是, 我们不得不这样做。了解更多内容可以参见{{anch("Why is Persona being removed", "Why was Persona removed?")}}

- -

为什么 Persona 会被移除?

- -

Mozilla 已经关闭了 Persona 项目,而 Persona 将会于2016年11月1日起停止服务。您可以参看在 Mozilla wiki 上的文章以了解更多Mozilla关停Persona决定的信息。我们现在目前把 GitHub 作为唯一的认证方式。

- -

Persona 何时会被移除?

- -

我们将会在2016年11月1日禁用Persona这个身份认证方式,换句话来说,您最后能用Persona登录MDN的日子将会是2016年10月31日。我们将从现在开始,越发频繁、紧急地发布通告,以催促您在您的MDN资料中关联一个GitHub账户。请您尽快完成,以避免丢失您MDN账户上的任何数据。

- -

MDN 会提供其他身份认证方式吗?

- -

我们很乐意这样做,但现在还没有其他认证方式能够符合我们的要求;另外我们当前并没有将开发人员资源与其他供应商进行整合。所以目前您作为志愿者访问 MDN 的唯一方式就是在您的 MDN 资料中关联的一个 GitHub 账户

- -

当然请记住,您并不需要为了阅读我们的内容而登录到 MDN。但如果您有一个账户,并希望能在将来任何时候给MDN做贡献,请您一定要在2016年10月31日前添加一个Github 账户到您的个人资料里,时间越快越好

diff --git a/files/zh-cn/mdn/guidelines/layout/index.html b/files/zh-cn/mdn/guidelines/layout/index.html deleted file mode 100644 index 919994b78d..0000000000 --- a/files/zh-cn/mdn/guidelines/layout/index.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: MDN page layout guide -slug: MDN/Guidelines/Layout -translation_of: Archive/Meta_docs/MDN_page_layout_guide ---- -
{{MDNSidebar}}

这些指南补充了MDN 风格指南 中关于 MDN 上各种页面类型的具体布局。这有助于让贡献者们创建的内容结构与 MDN 上其他页面保持一致。

-

{{LandingPageListSubpages}}

diff --git a/files/zh-cn/mdn/user_guide/writing/index.html b/files/zh-cn/mdn/user_guide/writing/index.html deleted file mode 100644 index 5b2c6762f3..0000000000 --- a/files/zh-cn/mdn/user_guide/writing/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: 写作内容 -slug: MDN/User_guide/Writing -tags: - - 写作内容 -translation_of: Archive/Meta_docs/Writing_content ---- -

在MDN上经常会有一些东西需要加进来和更新。不管是一个全新出彩API的文档或者一个旧API的细微修改,你会找到很多可以出力的机会。关于怎么使用编辑器,和我们为了自动化结构与内容格式使用的宏系统的细节,请参看MDN editor guide

-

编辑一个已经存在的页面

-

如果你找到一个想去修正的页面,简单点击右上方的“编辑”按钮。这会打开一个 WYSIWYG编辑器来帮助你修改页面内容。

-

有很多原因你会去编辑一个已经存在的页面:

- -

增加一个新页面

-

这是个大的任务!在MDN上添加一个新的页面会让Web爱上你,拥抱你。这里有一些显而易见的原因,包括给未文档化的API做文档,增加一个新的教程或者?做一个主题的指南。

-

当你登陆后,按以下步骤去创建一个新的页面在MDN上:

-
-
- 点击一个 "missing page" 链接
-
- 当你浏览MDN的时候,你会偶然发现有些链接的页面还不存在。很多时候,当我们创建文章,我们会把需要创建的页面链接加进去,即使它们还没做好。这有助于我们跟踪那些最终需要完成的事,虽然有时候会花一些时间回过去完成它们。你可以随意去做!只要点击这些链接,你会直接进入新网页的编辑器。
-
-  
-
- 创建一个子页面
-
- 在每篇文章的最右上角是“This Page“下拉菜单。菜单里面有”New sub-page“选项。点击这个选项会打开一个页面编辑器,在这个新的页面在站点层次上的父页面是你选择”New sub-page“那个页面。只需填写标题和标签,就可以开始写正文了。
-
- 创建一个副本
-
- 你也可以克隆一个已经存在的页面,使用“This page“下拉菜单的”Clone this page“选项。点击该选项会复制当前页面,其父页面和当前页面完全相同。接着页面上会打开编辑器,你就可以设置页面的标题和标签,然后编辑页面的内容。给一个现有站点参考区域增加一个新的页面,通常是一个好的方式。比如,这会给你内容布局的样式。
-
- 创建一个链接到还没存在的页面,然后点击它
-
- 这有点儿混合模式。因为每个页面应该被某处链接到,你可以从给一个新的文章创建一个已有页面的链接开始,然后保存页面。你可以点击你刚刚插入的链接,接着在打开的编辑器中写新的文章。
-
-

 

-

 

-
-

注意:如果你没有登录,当你想要查看未存在的文章时,会跳出404错误提示,而不是跳出新页面的编辑器。

-
-

寻找信息

-

有很多信息没有出现在这里。有时候这些信息你很难搜寻到,但你恰好很需要用到,这里有一些提示来帮助你。

-
-
- 模块化所有者列表
-
- Mozilla的项目在一个“模块所有者”基础上进行;每一个重要的组件都有一个或者多个所有者负责它的进展。这些所有者往往是信息的最好来源--至少是个好的方式找到对的人来讨论。
-
- Mozilla源交叉参考
-
- MXR(Mozilla cross-reference的缩写)能让你得到所有Mozilla工程的源代码(有些事例除外,比如Firefox OS是托管在Github上)。代码和有关评论常常是信息的重要资源。
-
- Mozilla wiki
-
- The Mozilla wiki(常被称作“wikimo“)是过程和设计的一些笔记,草稿,计划和初步的方案等。尽管看起来一团糟,但也是宝贵的知识库。
-
diff --git a/files/zh-cn/mercurial_faq/index.html b/files/zh-cn/mercurial_faq/index.html deleted file mode 100644 index aac59c6c7b..0000000000 --- a/files/zh-cn/mercurial_faq/index.html +++ /dev/null @@ -1,650 +0,0 @@ ---- -title: 使用 Mercurial -slug: Mercurial_FAQ -translation_of: Mercurial/Using_Mercurial ---- -

安装和配置 Mercurial

-

See Installing Mercurial. Even if you already have Mercurial installed, make sure

- -

我应如何...

-

我怎么才能一窥 Mozilla?

-

To clone the main development repository for Gecko and Firefox use:

-
hg clone https://hg.mozilla.org/mozilla-central/ src
-cd src
-

For the list of other repositories see Getting Mozilla Source Code Using Mercurial.

-

如何编辑和更新文件?

-

You can randomly edit files in the working directory, just like with CVS.

-

The common command to update a tree is:

-
hg pull -u
-
-

It is not possible to update only one directory; you have to update the entire tree.

-

如何才能 diff 和 patch 文件?

- -

Preferred diff options are hg diff -p -U 8 which includes 8 lines of context and shows the relevant function for the block. You can make these options default in the Mercurial configuration file.

-

How can I generate a patch for somebody else to check-in for me?

-

If you don't have commit access yourself, you need to attach your patches to a bug for somebody to check in.  In order to do that, you should make sure that your patch has the following conditions:

-
    -
  1. It has a correctly formatted author name.
  2. -
  3. It has a correctly formatted commit message.
  4. -
  5. It is generated in git style.
  6. -
-

Here is a very easy way to get this setup working using mq.  First, you need to edit your ~/.hgrc file.  You only need to do this once.  Your hgrc file should have the following contents at least:

-
[ui]
-username = John Smith <john@smith.com>
-
-[defaults]
-qnew = -Ue
-
-[extensions]
-mq =
-
-[diff]
-git = 1
-showfunc = 1
-unified = 8
-
-

Now, in order to create a patch, you should enter:

-
hg qnew name.patch
-
-

which opens up your favorite editor so that you can enter a good commit message.  A good sample commit message looks like: "Bug 123456 - Change this thing to work better by doing something; r=reviewers".  You don't need to enter the final commit message (for example, if you haven't received reviews yet).  You can edit the commit message of the current mq patch at any time using hg qref -e.

-

The ~/.hgrc default -U argument for the qnew command add the author information to the patch (using a From: header), and the default -e argument opens up the editor for you to type in a commit message.

-

Now, after editing some source code, you can use hg qref to update your patch file.

-

To attach the patch to the bug, you can use the file named name.patch located in your <repository>/.hg/patches directory directly.

-

I'm all used to git, but how can I provide Mercurial-ready patches ?

-

Please refer to https://github.com/jlebar/moz-git-tools and especially the git-patch-to-hg-patch tool, that provides an easy way to convert from git-generated patch to Mercurial-ready ones.

-

Usage is pretty straight-forward:

-
$ git-patch-to-hg-patch YourGitGeneratedPatch.patch
-

How do I check stuff in?

-

Required configuration

-

Before committing any changes, add these lines to your ~/.hgrc file:

-
[ui]
-username = Your Name <your.email@example.com>
-
-

To push to mozilla-central and other mozilla-hosted repositories you have to have committer access, and you must edit the file (your-local-hg-root)/.hg/hgrc (note, this is NOT your ~/.hgrc) to add this line:

-
[paths]
-default = http://hg.mozilla.org/mozilla-central/
-default-push = ssh://hg.mozilla.org/mozilla-central/
-
-

You also have to tell ssh what username to use when connecting to hg.mozilla.org. This should be the username associated with your Mozilla LDAP account. You can do this either by making the default-push path above more complicated (user@host.name@hg.mozilla.org) or by adding lines to your ~/.ssh/config :

-
Host hg.mozilla.org
-User user@host.domain
-
-

Check what you're going to commit

-

Next, to check if you're really committing what you want to commit (especially important when doing merges or other trickier commits):

-
hg status
-hg diff
-
-

status shows the files that have changed in your working directory compared to what's in your repository (the parent revisions, which you can see by using hg parents). hg diff shows the actual changes in those files, as unified diffs. You can add a -U8 option to see more context.

-

Commit to the local repository

-

As the next step, you will commit your changes to your local repository:

-
hg commit
-
-

This commits every change reported by hg status. You can limit the commit to specific files or directories using hg commit filenames. You can commit on behalf of someone else using hg commit -u "Someone Else <someone@example.com>". See hg help commit for more details.

-

To add new files to the repository and to remove obsolete ones use

-
hg addremove
-
-

Check what you're going to push

-

Before you push, you likely want to check what changesets will be pushed. You can do this using the outgoing command:

-
hg outgoing
-
-

This will give you a list of changesets that will be pushed to the default remote repository. Add a repository argument to see outgoing changesets for another repository.

-

Push to the central repository

-

To push those changes upstream to the central repository:

-
hg push
-
-

Preventing accidental pushes

-

Since the qpush command can easily be mistyped as push, it can cause an accidental push when applying an MQ patch was intended instead. To prevent accidental pushes you can add the following hook in your ~/.hgrc file:

-
[hooks]
-pre-push = printf 'Are you sure you want to push to remote? (y/n): '; read R; [ x"$R" == "xy" ]
-
-

This will cause the push command to request confirmation each time it is invoked and abort if the user types anything but y.

-

How do I deal with "abort: push creates new remote heads!"?

-

Whatever you do, don't do 'push -f' like the message suggests. (It'll probably fail anyway, but don't try it.)

-

Someone pushed new commits upstream since your last pull. You then committed your patch locally and are trying to push that commit upstream; that upstream has a different tip commit that you started from.

-
  YOU ---> o  9123b7791b52 - Kaitlin Jones <kaitlin@example.net> - Bug 123456 - Trebled fromps (r=gavin)
-           |
-TRUNK ---> | o  306726089e22 - Robert Longson <longsonr@example.com> - Bug 437448. New-style nsSVGString
-           | |
-           | o  ba9b9a7c52a5 - Robert Longson <longsonr@example.com> - Bug 437448. New-style nsSVGString
-           |/
-           o  f8f4360bf155 - Robert O'Callahan <robert@example.org> - Bug 421436. Remove hack that gives
-

There are three things you can do. In all cases, you are strongly encouraged to take steps to back up your patch (perhaps by obtaining a diff: hg log -p -r 12345 to show the patch for rev 12345).

-

Using hg merge

-

Run hg pull, then hg merge. If there are any merge conflicts, hg will open a merge program to try to help you resolve them manually. (If you fail to make sense of the merge tool, that's OK.  Just close it; hg will detect that the conflicts weren't all resolved and spit out some hg update -C commands that you can use to undo and then retry the busted merge.)

-

Even if there were no conflicts, you have to commit the merge: hg commit -m "Merge bug 123456".

-
  YOU ---> o 1fe7659c29a9 - Kaitlin Jones <kaitlin@example.net> - Merge bug 123456.
-           |\
-           o | 9123b7791b52 - Kaitlin Jones <kaitlin@example.net> - Bug 123456 - Trebled fromps (r=gavin)
-           | |
-TRUNK ---> | o  306726089e22 - Robert Longson <longsonr@example.com> - Bug 437448. New-style nsSVGString
-           | |
-           | o  ba9b9a7c52a5 - Robert Longson <longsonr@example.com> - Bug 437448. New-style nsSVGString
-           |/
-           o  f8f4360bf155 - Robert O'Callahan <robert@example.org> - Bug 421436. Remove hack that gives
-

Now you can hg push as normal.

-

This leaves a merge commit in the log, which some people find annoying, so it's usually better to avoid this solution.

-

If you decide to use this method, it is advantageous to enable the Mercurial fetch extension (by means of a fetch = line in the [extensions] section of your <repository>/.hg/hgrc or your $HOME/.hgrc file) so you can do the pull + merge + commit sequence in one step (assuming no merge conflicts) by using the hg fetch command.

-

Using Mercurial queues

-

A way to solve your problem without leaving a merge commit is to import your commit into mq control, pop it off the queue, update, and then commit it again before pushing:

-
% hg log -l 5
-415[tip]   d1accb6ee840   2008-04-30 09:57 -0700   vladimir
-  b=430873; fast path drawImage with a canvas as source
-414   3a3ecbb4873e   2008-04-30 09:55 -0700   vladimir
-  cvs sync
-% hg qimport -r 415
-Turn the new commit you made into a MQ patch
-% hg qtop
-415.diff
-% hg qpop
-Patch queue now empty
-Pop the MQ patch off the stack. At this point, the tip of your tree is also in the remote repository
-% hg pull -u
-... various pull/update messages ...
-% hg qpush
-applying 415.diff
-Now at: 415.diff
-Fix up conficts as necessary; if you fixed up any, run hg qrefresh first
-% hg incoming
-comparing with ssh://hg.mozilla.org/mozilla-central/
-searching for changes
-no changes found
-Make sure	nobody pushed while you were merging. Otherwise, qpop, pull and qpush again
-% hg qfinish 415.diff
-Turn the MQ patch into a regular revision
-% hg log -l 5
-verify that the log looks good, with your commit on top
-% hg push
-
-

If you already use mq to manage your patches, then just make sure you pull/update right before committing and pushing your patch. If you have problems with the above, it's ok to just do a simple merge as described previously.

-

In this case, if there are merge conflicts, MQ will produce .rej files. Some people prefer this over being thrown into a merge program.

-

Using hg rebase

-

(Requires Mercurial 1.1 or higher)

-

This is the simplest and easiest way to deal with the problem. You can rebase your local changesets (including mq patches) on top of the tip using the rebase extension. To do this, simply enable the extension by adding this to the following section of your .hgrc:

-
[extensions]
-hgext.rebase =
-
-

Now, type hg pull --rebase to pull and rebase your local changesets at the same time. More details and options can be found at the Mercurial wiki.

-

If you have conflicting changes, you'll be thrown into your preferred merge tool.

-
- Note: As of Mercurial 1.1, rebasing (especially with mq patches) might lose rename data; this is a known bug that has been fixed in Mercurial 1.3. 
-
- Note: If you had done a normal hg pull without --rebase after your hg commit, you will have to first undo that by doing hg rollback. Only the very last action can be undone, so if you did anything else after the hg pull, you're out of luck.
-
- Note: If you have local changes, hg pull --rebase (just like hg merge) will refuse to work, so you'll have to revert your local changes first:
-
hg diff > old.diff
-hg revert .
-hg pull --rebase
-hg push
-patch -p 1 -i old.diff
-rm old.diff
-
-

How do I see what these commands will do before I do them?

-

If you want to see what hg commit will commit, run hg diff first.

-

If you want to see what hg push will push, run hg outgoing first.

-

If you want to see what hg pull will pull, run hg incoming first.

-

These pairs of commands all take similar arguments, for good reason. These are a good idea to use all the time when you're learning mercurial. And even once you're an expert, always doing outgoing before push is a good idea.

-

How can I customize the format of the patches Mercurial creates?

-

Edit your ~/.hgrc file and add some lines like these:

-
[defaults]
-diff=-U 8 -p
-qdiff=-U 8
-#for Mercurial 1.1 use:
-#qdiff=-U 8 -p
-
[diff]
-git=true
-
-

The {{ mediawiki.external('defaults') }} section affects the default output of the hg diff and hg qdiff commands. The options behave the same as they would on the command line. Try hg help diff for more info.

-

The {{ mediawiki.external('diff') }} section affects all patches generated by Mercurial, even hg export and those generated for Mercurial's internal use. You need to be a lot more careful with this, but git=true is recommended. Without it, Mercurial cannot diff binary files and does not track the execute mode bit.  You may want to add showfunc=true here to get diffs that show the function being changed in each hunk, and you may want to add unified=8 to make all diffs (including the internal ones mq uses) have 8 lines of context. Note that this may increase the risk of mq patches failing to apply!

-

How do I get a diff -w?

-

There is a known issue where hg diff -w doesn't work.

-

To get around this add the following to your ~/.hgrc file, editing existing sections where applicable:

-
[extensions]
-hgext.extdiff =
-
-[extdiff]
-cmd.diffw = diff
-opts.diffw = -w -r -N -p -U 8
-
-

You can, of course, add your other favourite diff options to opts.diffw. Once you've added this, you will now have a new hg command, hg diffw.

-

hg diffw -r -2 is the equivalent of hq qdiff -w for the topmost patch in the queue.

-

How do I generate a bundle?

-

Sometimes the tree will be under sheriff control, and they will specifically ask for a bundle.  If you don't have sufficient rights to push to mozilla-central, you might also generate bundles and attach them to bugs when you add checkin-needed to a bug after it has the necessary reviews and approval.

-

Creating a bundle is quite simple.  Once you have your changes all done, commit them to your local repository.  You can also commit more than one changeset.  Once you have everything committed, instead of pushing you'll run hg bundle:

-
hg bundle outputfile.hg
-
-

By default, hg bundle will bundle everything that hg outgoing would display (and what you would push with hg push).  You can limit how far forward you want to bundle as well by specifying a revision with -r.  That will take all changes up until that revision.

-

Backing out changes

-

Reverting the whole tree to a known-good revision

-

It's easy, like using a sledgehammer is easy. But this is usually overkill.

-
$ hg pull -u
-$ hg revert --all -r a0193d83c208       # use your known-good revision id here
-$ hg commit                             # be kind, include the revision id in your commit message
-$ hg push
-
-

There's a more precise alternative:

-

Backing out a single changeset

-

Suppose changeset f8f4360bf155 broke something.

-
$ hg pull -u
-$ hg backout f8f4360bf155               # use the revision id of the bad change here
-
-

This creates and commits a new changeset that reverts all the changes in that revision.

-

If you see this message:

-
the backout changeset is a new head - do not forget to merge
-
-

That means you need to merge, because your history now looks like this:

-
  YOU ---> o  9123b7791b52 - Kaitlin Jones <kaitlin@example.net> - Backed out changeset f8f4360bf155
-           |
-TRUNK ---> | o  4e5bfb83643f - Simon Montagu <smontagu@example.org> - imported patch 435856
-           | |
-           | o  6ee23de41631 - Phil Ringnalda <philringnalda@example.com> - Bug 438526 - Opening links w
-           | |
-           | o  22baa05d0e8a - Robert O'Callahan <robert@example.org> - Remove DOM testcase from exclusi
-           | |
-           | o  c1aec2094f7e - Robert Longson <longsonr@example.com> - Bug 437448. New-style nsSVGString
-           | |
-           | o  306726089e22 - Robert Longson <longsonr@example.com> - Bug 437448. New-style nsSVGString
-           | |
-           | o  ba9b9a7c52a5 - Robert Longson <longsonr@example.com> - Bug 437448. New-style nsSVGString
-           |/
-           o  f8f4360bf155 - Robert O'Callahan <robert@example.org> - Bug 421436. Remove hack that gives
-           |
-           ⋮ (the past)
-
-

Your backout changeset is based on an old revision. It doesn't contain more recent changes.

-

Handle this like any other merge. If you've never done a merge before, get help. (It could be trivial or it could be a huge headache. There's plenty about merging elsewhere in this FAQ.)

-

Backing out multiple changesets that are not at tip

-

Your push of many changesets was bad, but you didn't find out until after a lot of subsequent activity. You want to back out the bad but keep the probably-good changesets from the subsequent activity.

-

NB: this is hard, error-prone, and will likely b0rk your local tree if you mess up. If in doubt, ask someone else to do it for you.

-

What one would really like to do is

-
hg backout --from-rev $FIRST_BAD --to-rev $LAST_BAD
-
-

or, if local hg could access pushlog

-
hg backout --push $LAST_BAD
-
-

but, since hg can't do either (yet), we're stuck. What we'll do instead is travel back in hg-time to the last bad cset, revert all changes between last-bad and last-good, then merge that reversion to the current tip. Your tree might look like

-
 MERGE_TO ---> @  c6abfc89215a - Chris Pearce <chris@pearce.org.nz> - Bug 485288 - Replace all usage of video  autobuffer attribute with preload=auto. a=test-fix
-               |
-               o  d6e8fddeb95b - Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Disable test_preload_actions.html case 9 until bug 568402 is fixed. a=test-fix
-               |
-               o  571d2664ead0 - Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Don't show throbber on video controls if we're not loading a resource. r=dolske a=blocking2.0
-               |
-               o  3f7dfabab5e4 - Rich Dougherty <rich@rd.gen.nz>, Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Replace HTMLMediaElement.autobuffer attribute with 'preload'. r=roc a=blocking2.0
-               |
-               o  d7d9cf4ab76a - Chris Pearce <chris@pearce.org.nz> - Bug 519897 - Supported indexed Ogg files. r=doublec
-               |
-               o    2a0e5811ece9 - Chris Pearce <chris@pearce.org.nz> - Commit merge of backout of 66dcf25705f9. a=backout
-               |\
-               | o  958a30df30dd - Chris Pearce <chris@pearce.org.nz> - Backed out changeset 66dcf25705f9
-               | |
-               o |  6eead86e13dd - Michael Wu <mwu@mozilla.com> - Bug 556644 - Yet another removed-files.in update, r=rs a=blocking-beta5
-               | |
-               o |  69c6ce104f45 - Chris Jones <jones.chris.g@gmail.com> - Bug 588216: Avoid race between IO-thread loop->PostTask() and main-thread loop->SetNestableTasksAllowed() that led to Tasks being ignored. r=bent
-               | |
-               o |  73899b33ca4b - Ben Turner <bent.mozilla@gmail.com> - Bug 576716 - 'Crash [@ TypedArrayTemplate<int>::init] or [@ TypedArrayTemplate<int>::create]'. Adding a test, r=vlad a=blocker
-               | |
-               o |  3bd62d459019 - Mark Banner <bugzilla@standard8.plus.com> - Follow up to bug 587984 bustage fix for l10n repacks. r=Pike,ted,a=bustage-fix
-               | |
-               o |  e1ca9091e5a6 - Benjamin Stover <webapps@stechz.com> - Bug 575731: Make test more stable in the face of various themes. r,a=sicking
-               | |
-               o |  bb200e1f52b4 - Jonas Sicking <jonas@sicking.cc> - Bug 550959: Require version 2.5 of python. r=ted a=sicking
-               | |
-               o |  992491c618de - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (12/12): fix assertions in nsStyleAnimation triggered by part 3.  r=dbaron  a2.0=dbaron
-               | |
-               o |  2f078585a0f6 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (11/12): Make all assertions fatal in Declaration.h, Declaration.cpp, nsCSSDataBlock.h, nsCSSDataBlock.cpp, nsCSSValue.h, nsCSSValue.cpp, nsCSSProps.h, and nsCSSProps.cpp.  r=dbaron  a2.0=dbaron
-               | |
-               o |  5a9bd15fd7a8 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (10/12): Don't directly manipulate the contents of mTempData in the CSS parser.  r=dbaron  a2.0=dbaron
-               | |
-               o |  4bb2e0074aeb - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (9/12): Add an AddLonghandProperty method to nsCSSExpandedDataBlock.  r=dbaron  a2.0=dbaron
-               | |
-               o |  659a0864e035 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (8/12): remove the last MoveValue call from the CSS parser.  r=dbaron  a2.0=dbaron
-               | |
-               o |  980f0170d982 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (7/12): cleanup pass on css/Declaration.{h,cpp} and nsCSSDataBlock.{h,cpp}.  r=dbaron  a2.0=dbaron
-               | |
-               o |  f09c1638d3c1 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (6/12): remove vestiges of nsCSSType.  r=dbaron  a2.0=dbaron
-               | |
-               o |  b88472b0af90 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (5/12): eliminate ValueList as a storage type.  r=dbaron  a2.0=dbaron
-               | |
-               o |  a3e21759b570 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (4/12): eliminate ValuePairList as a storage type.  r=dbaron  a2.0=dbaron
-               | |
-               o |  ed89c9e297ab - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (3/12): eliminate Rect as a storage type.  r=dbaron  a2.0=dbaron
-               | |
-               o |  4fc85e572c38 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (2/12): eliminate ValuePair as a storage type.  r=dbaron  a2.0=dbaron
-               | |
-               o |  301875d4f9b6 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (1/12): Move all the CSS 'storage types' (rect, value pair, etc) to nsCSSValue.h and their code to nsCSSValue.cpp.  r=dbaron  a2.0=dbaron
-               | |
- LAST_BAD ---> o |  90ad165ae21b - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part i: Use nsIWidget::CreateChild in nsIView::CreateWidget* (where possible). r=roc a=blocking-fennecb1
-               | |
-               o |  037a5d6b376a - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part h: Add an nsIWidget::CreateChild interface to sweep (relevant to this bug) code dealing with native widgets under the widget/src/* rug. sr=roc
-               | |
-               o |  f1af117d4598 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part g: Split nsIView::CreateWidget into CreateWidget, CreateWidgetForParent, and CreateWidgetForPopup in preparation of eliminating IIDs here. sr=roc
-               | |
-               o |  5bf0b315a5aa - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part f: Split out window initialization code in preparation for multiple CreateWidget* methods. r=roc
-               | |
-               o |  353da995af6f - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part e: Simplify the logic for creating popup widgets. r=roc
-               | |
-               o |  7735c00eabe9 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part d: Simplify nsView::LoadWidget and return early if it fails. r=roc
-               | |
-               o |  7b17bcefb174 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part c: Initialize default widget init data earlier so that it's always available. r=roc
-               | |
-               o |  c5945b6a97ed - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part b: Remove nsIDeviceContext::SupportsNativeWidgets because it's not used meaningfully, and will be confusing in content processes. sr=roc
-               | |
-               o |  5452db293694 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part a: Add nsIView::Impl() and nsView::CreateWidget() to get rid of |static_cast<nsview*>(this)|. r=roc
-               | |
-               o |  9407827b5166 - Chris Jones <jones.chris.g@gmail.com> - Bug 582075, part 0.5: Add support for aInitData=NULL to the Windows nsWindow implementation. r=dougt
-               | |
-               o |  88a279b64473 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part 0: Log the repaint region bounding rect in DumpPaintEvent. r=roc
-               | |
-               o |  cebb111fbfc4 - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 3: Remove nsSVGUtils::GetThebesComputationalSurface and use gfxPlatform::ScreenReferenceSurface instead. r=jwatt
-               | |
-               o |  7b3726c3a580 - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 2: Change nsIPresShell::CreateRenderingContext to GetReferenceRenderingContext, that uses the shared 1x1 surface, and use it all over the place. r=mats,sr=dbaron
-               | |
-FIRST_BAD ---> o |  b3e968d831ec - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 1: Create a single static 1x1 surface in gfxPlatform that can be used to create contexts for text measurement etc. r=vlad
-               | |
-LAST_GOOD ---> o |  55ef0e0529bc - Mounir Lamouri <mounir.lamouri@gmail.com> - Bug 506554 - Implement the CSS3 pseudo-classes :required and :optional for HTML. r=sicking sr=bz a2.0=blocking
-               | |
-</int></int>
-

We want to erase all changes between $FIRST_BAD and $LAST_BAD, then merge to $MERGE_TO

-
$ MERGE_TO="c6abfc89215a"
-$ LAST_BAD="90ad165ae21b"
-$ LAST_GOOD="55ef0e0529bc"
-$ hg up -r $LAST_BAD
-90 files updated, 0 files merged, 4 files removed, 0 files unresolved
-
-

We just traveled back in time to the last cset we want to nuke. Now we'll revert the changes between $FIRST_BAD and $LAST_BAD.

-
$ hg revert --all --no-backup -r $LAST_GOOD
-reverting accessible/src/msaa/nsTextAccessibleWrap.cpp
-reverting content/svg/content/src/SVGMotionSMILPathUtils.h
-reverting content/svg/content/src/nsSVGPathElement.cpp
-reverting gfx/src/nsIDeviceContext.h
-reverting gfx/src/thebes/nsThebesDeviceContext.cpp
-reverting gfx/src/thebes/nsThebesDeviceContext.h
-reverting gfx/thebes/gfxPlatform.cpp
-reverting gfx/thebes/gfxPlatform.h
-reverting layout/base/nsCSSFrameConstructor.cpp
-reverting layout/base/nsDocumentViewer.cpp
-reverting layout/base/nsIPresShell.h
-reverting layout/base/nsPresShell.cpp
-reverting layout/build/nsLayoutStatics.cpp
-reverting layout/generic/nsFrameFrame.cpp
-reverting layout/generic/nsObjectFrame.cpp
-reverting layout/generic/nsSimplePageSequence.cpp
-reverting layout/generic/nsTextFrameThebes.cpp
-reverting layout/inspector/src/inFlasher.cpp
-reverting layout/printing/nsPrintEngine.cpp
-reverting layout/svg/base/src/nsSVGForeignObjectFrame.cpp
-reverting layout/svg/base/src/nsSVGGlyphFrame.cpp
-reverting layout/svg/base/src/nsSVGImageFrame.cpp
-reverting layout/svg/base/src/nsSVGPathGeometryFrame.cpp
-reverting layout/svg/base/src/nsSVGUtils.cpp
-reverting layout/svg/base/src/nsSVGUtils.h
-reverting layout/xul/base/src/nsMenuPopupFrame.cpp
-reverting layout/xul/base/src/nsSplitterFrame.cpp
-reverting layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
-reverting view/public/nsIView.h
-reverting view/src/nsView.cpp
-reverting view/src/nsView.h
-reverting widget/public/nsIWidget.h
-reverting widget/src/beos/nsWindow.h
-reverting widget/src/cocoa/nsChildView.h
-reverting widget/src/cocoa/nsCocoaWindow.h
-reverting widget/src/windows/nsWindow.cpp
-reverting widget/src/xpwidgets/nsBaseWidget.cpp
-reverting widget/src/xpwidgets/nsBaseWidget.h
-$ hg commit -m 'Back out bug 585817 and bug 582057'
-created new head
-
-

After committing the reversion, we now have a new head that doesn't include the probably-good changes after $LAST_BAD.

-
@  1767c1fb9418 - Chris Jones <jones.chris.g@gmail.com> - Back out bug 585817 and bug 582057
-|
-| o  c6abfc89215a - Chris Pearce <chris@pearce.org.nz> - Bug 485288 - Replace all usage of video  autobuffer attribute with preload=auto. a=test-fix
-| |
-| o  d6e8fddeb95b - Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Disable test_preload_actions.html case 9 until bug 568402 is fixed. a=test-fix
-| |
-| o  571d2664ead0 - Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Don't show throbber on video controls if we're not loading a resource. r=dolske a=blocking2.0
-| |
-| o  3f7dfabab5e4 - Rich Dougherty <rich@rd.gen.nz>, Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Replace HTMLMediaElement.autobuffer attribute with 'preload'. r=roc a=blocking2.0
-| |
-| o  d7d9cf4ab76a - Chris Pearce <chris@pearce.org.nz> - Bug 519897 - Supported indexed Ogg files. r=doublec
-| |
-| o    2a0e5811ece9 - Chris Pearce <chris@pearce.org.nz> - Commit merge of backout of 66dcf25705f9. a=backout
-| |\
-| | o  958a30df30dd - Chris Pearce <chris@pearce.org.nz> - Backed out changeset 66dcf25705f9
-| | |
-| o |  6eead86e13dd - Michael Wu <mwu@mozilla.com> - Bug 556644 - Yet another removed-files.in update, r=rs a=blocking-beta5
-| | |
-| o |  69c6ce104f45 - Chris Jones <jones.chris.g@gmail.com> - Bug 588216: Avoid race between IO-thread loop->PostTask() and main-thread loop->SetNestableTasksAllowed() that led to Tasks being ignored. r=bent
-| | |
-| o |  73899b33ca4b - Ben Turner <bent.mozilla@gmail.com> - Bug 576716 - 'Crash [@ TypedArrayTemplate<int>::init] or [@ TypedArrayTemplate<int>::create]'. Adding a test, r=vlad a=blocker
-| | |
-| o |  3bd62d459019 - Mark Banner <bugzilla@standard8.plus.com> - Follow up to bug 587984 bustage fix for l10n repacks. r=Pike,ted,a=bustage-fix
-| | |
-| o |  e1ca9091e5a6 - Benjamin Stover <webapps@stechz.com> - Bug 575731: Make test more stable in the face of various themes. r,a=sicking
-| | |
-| o |  bb200e1f52b4 - Jonas Sicking <jonas@sicking.cc> - Bug 550959: Require version 2.5 of python. r=ted a=sicking
-| | |
-| o |  992491c618de - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (12/12): fix assertions in nsStyleAnimation triggered by part 3.  r=dbaron  a2.0=dbaron
-| | |
-| o |  2f078585a0f6 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (11/12): Make all assertions fatal in Declaration.h, Declaration.cpp, nsCSSDataBlock.h, nsCSSDataBlock.cpp, nsCSSValue.h, nsCSSValue.cpp, nsCSSProps.h, and nsCSSProps.cpp.  r=dbaron  a2.0=dbaron
-| | |
-| o |  5a9bd15fd7a8 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (10/12): Don't directly manipulate the contents of mTempData in the CSS parser.  r=dbaron  a2.0=dbaron
-| | |
-| o |  4bb2e0074aeb - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (9/12): Add an AddLonghandProperty method to nsCSSExpandedDataBlock.  r=dbaron  a2.0=dbaron
-| | |
-| o |  659a0864e035 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (8/12): remove the last MoveValue call from the CSS parser.  r=dbaron  a2.0=dbaron
-| | |
-| o |  980f0170d982 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (7/12): cleanup pass on css/Declaration.{h,cpp} and nsCSSDataBlock.{h,cpp}.  r=dbaron  a2.0=dbaron
-| | |
-| o |  f09c1638d3c1 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (6/12): remove vestiges of nsCSSType.  r=dbaron  a2.0=dbaron
-| | |
-| o |  b88472b0af90 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (5/12): eliminate ValueList as a storage type.  r=dbaron  a2.0=dbaron
-| | |
-| o |  a3e21759b570 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (4/12): eliminate ValuePairList as a storage type.  r=dbaron  a2.0=dbaron
-| | |
-| o |  ed89c9e297ab - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (3/12): eliminate Rect as a storage type.  r=dbaron  a2.0=dbaron
-| | |
-| o |  4fc85e572c38 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (2/12): eliminate ValuePair as a storage type.  r=dbaron  a2.0=dbaron
-| | |
-| o |  301875d4f9b6 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (1/12): Move all the CSS 'storage types' (rect, value pair, etc) to nsCSSValue.h and their code to nsCSSValue.cpp.  r=dbaron  a2.0=dbaron
-|/ /
-o |  90ad165ae21b - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part i: Use nsIWidget::CreateChild in nsIView::CreateWidget* (where possible). r=roc a=blocking-fennecb1
-| |
-o |  037a5d6b376a - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part h: Add an nsIWidget::CreateChild interface to sweep (relevant to this bug) code dealing with native widgets under the widget/src/* rug. sr=roc
-| |
-o |  f1af117d4598 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part g: Split nsIView::CreateWidget into CreateWidget, CreateWidgetForParent, and CreateWidgetForPopup in preparation of eliminating IIDs here. sr=roc
-| |
-o |  5bf0b315a5aa - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part f: Split out window initialization code in preparation for multiple CreateWidget* methods. r=roc
-| |
-o |  353da995af6f - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part e: Simplify the logic for creating popup widgets. r=roc
-| |
-o |  7735c00eabe9 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part d: Simplify nsView::LoadWidget and return early if it fails. r=roc
-| |
-o |  7b17bcefb174 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part c: Initialize default widget init data earlier so that it's always available. r=roc
-| |
-o |  c5945b6a97ed - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part b: Remove nsIDeviceContext::SupportsNativeWidgets because it's not used meaningfully, and will be confusing in content processes. sr=roc
-| |
-o |  5452db293694 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part a: Add nsIView::Impl() and nsView::CreateWidget() to get rid of |static_cast<nsview*>(this)|. r=roc
-| |
-o |  9407827b5166 - Chris Jones <jones.chris.g@gmail.com> - Bug 582075, part 0.5: Add support for aInitData=NULL to the Windows nsWindow implementation. r=dougt
-| |
-o |  88a279b64473 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part 0: Log the repaint region bounding rect in DumpPaintEvent. r=roc
-| |
-o |  cebb111fbfc4 - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 3: Remove nsSVGUtils::GetThebesComputationalSurface and use gfxPlatform::ScreenReferenceSurface instead. r=jwatt
-| |
-o |  7b3726c3a580 - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 2: Change nsIPresShell::CreateRenderingContext to GetReferenceRenderingContext, that uses the shared 1x1 surface, and use it all over the place. r=mats,sr=dbaron
-| |
-o |  b3e968d831ec - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 1: Create a single static 1x1 surface in gfxPlatform that can be used to create contexts for text measurement etc. r=vlad
-| |
-o |  55ef0e0529bc - Mounir Lamouri <mounir.lamouri@gmail.com> - Bug 506554 - Implement the CSS3 pseudo-classes :required and :optional for HTML. r=sicking sr=bz a2.0=blocking
-| |
-</int></int>
-

We want to merge with those probably-good changesets. Note that if any of those probably-good changesets touched code you backed out, you'll need to resolve merge conflicts.

-
$ hg merge $MERGE_TO
-92 files updated, 0 files merged, 2 files removed, 0 files unresolved
-(branch merge, don't forget to commit)
-$ hg commit -m 'Merge backout'
-
-

OK, good to go. Your tree should look something like

-
@    8fccc434c295 - Chris Jones <jones.chris.g@gmail.com> - Merge backout
-|\
-| o  1767c1fb9418 - Chris Jones <jones.chris.g@gmail.com> - Back out bug 585817 and bug 582057
-| |
-o |  c6abfc89215a - Chris Pearce <chris@pearce.org.nz> - Bug 485288 - Replace all usage of video  autobuffer attribute with preload=auto. a=test-fix
-| |
-o |  d6e8fddeb95b - Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Disable test_preload_actions.html case 9 until bug 568402 is fixed. a=test-fix
-| |
-o |  571d2664ead0 - Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Don't show throbber on video controls if we're not loading a resource. r=dolske a=blocking2.0
-| |
-o |  3f7dfabab5e4 - Rich Dougherty <rich@rd.gen.nz>, Chris Pearce <chris@pearce.org.nz> - Bug 548523 - Replace HTMLMediaElement.autobuffer attribute with 'preload'. r=roc a=blocking2.0
-| |
-o |  d7d9cf4ab76a - Chris Pearce <chris@pearce.org.nz> - Bug 519897 - Supported indexed Ogg files. r=doublec
-| |
-o |    2a0e5811ece9 - Chris Pearce <chris@pearce.org.nz> - Commit merge of backout of 66dcf25705f9. a=backout
-|\ \
-| o |  958a30df30dd - Chris Pearce <chris@pearce.org.nz> - Backed out changeset 66dcf25705f9
-| | |
-o | |  6eead86e13dd - Michael Wu <mwu@mozilla.com> - Bug 556644 - Yet another removed-files.in update, r=rs a=blocking-beta5
-| | |
-o | |  69c6ce104f45 - Chris Jones <jones.chris.g@gmail.com> - Bug 588216: Avoid race between IO-thread loop->PostTask() and main-thread loop->SetNestableTasksAllowed() that led to Tasks being ignored. r=bent
-| | |
-o | |  73899b33ca4b - Ben Turner <bent.mozilla@gmail.com> - Bug 576716 - 'Crash [@ TypedArrayTemplate<int>::init] or [@ TypedArrayTemplate<int>::create]'. Adding a test, r=vlad a=blocker
-| | |
-o | |  3bd62d459019 - Mark Banner <bugzilla@standard8.plus.com> - Follow up to bug 587984 bustage fix for l10n repacks. r=Pike,ted,a=bustage-fix
-| | |
-o | |  e1ca9091e5a6 - Benjamin Stover <webapps@stechz.com> - Bug 575731: Make test more stable in the face of various themes. r,a=sicking
-| | |
-o | |  bb200e1f52b4 - Jonas Sicking <jonas@sicking.cc> - Bug 550959: Require version 2.5 of python. r=ted a=sicking
-| | |
-o | |  992491c618de - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (12/12): fix assertions in nsStyleAnimation triggered by part 3.  r=dbaron  a2.0=dbaron
-| | |
-o | |  2f078585a0f6 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (11/12): Make all assertions fatal in Declaration.h, Declaration.cpp, nsCSSDataBlock.h, nsCSSDataBlock.cpp, nsCSSValue.h, nsCSSValue.cpp, nsCSSProps.h, and nsCSSProps.cpp.  r=dbaron  a2.0=dbaron
-| | |
-o | |  5a9bd15fd7a8 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (10/12): Don't directly manipulate the contents of mTempData in the CSS parser.  r=dbaron  a2.0=dbaron
-| | |
-o | |  4bb2e0074aeb - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (9/12): Add an AddLonghandProperty method to nsCSSExpandedDataBlock.  r=dbaron  a2.0=dbaron
-| | |
-o | |  659a0864e035 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (8/12): remove the last MoveValue call from the CSS parser.  r=dbaron  a2.0=dbaron
-| | |
-o | |  980f0170d982 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (7/12): cleanup pass on css/Declaration.{h,cpp} and nsCSSDataBlock.{h,cpp}.  r=dbaron  a2.0=dbaron
-| | |
-o | |  f09c1638d3c1 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (6/12): remove vestiges of nsCSSType.  r=dbaron  a2.0=dbaron
-| | |
-o | |  b88472b0af90 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (5/12): eliminate ValueList as a storage type.  r=dbaron  a2.0=dbaron
-| | |
-o | |  a3e21759b570 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (4/12): eliminate ValuePairList as a storage type.  r=dbaron  a2.0=dbaron
-| | |
-o | |  ed89c9e297ab - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (3/12): eliminate Rect as a storage type.  r=dbaron  a2.0=dbaron
-| | |
-o | |  4fc85e572c38 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (2/12): eliminate ValuePair as a storage type.  r=dbaron  a2.0=dbaron
-| | |
-o---+  301875d4f9b6 - Zack Weinberg <zweinberg@mozilla.com> - Bug 576044 (1/12): Move all the CSS 'storage types' (rect, value pair, etc) to nsCSSValue.h and their code to nsCSSValue.cpp.  r=dbaron  a2.0=dbaron
- / /
-| o  90ad165ae21b - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part i: Use nsIWidget::CreateChild in nsIView::CreateWidget* (where possible). r=roc a=blocking-fennecb1
-| |
-| o  037a5d6b376a - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part h: Add an nsIWidget::CreateChild interface to sweep (relevant to this bug) code dealing with native widgets under the widget/src/* rug. sr=roc
-| |
-| o  f1af117d4598 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part g: Split nsIView::CreateWidget into CreateWidget, CreateWidgetForParent, and CreateWidgetForPopup in preparation of eliminating IIDs here. sr=roc
-| |
-| o  5bf0b315a5aa - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part f: Split out window initialization code in preparation for multiple CreateWidget* methods. r=roc
-| |
-| o  353da995af6f - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part e: Simplify the logic for creating popup widgets. r=roc
-| |
-| o  7735c00eabe9 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part d: Simplify nsView::LoadWidget and return early if it fails. r=roc
-| |
-| o  7b17bcefb174 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part c: Initialize default widget init data earlier so that it's always available. r=roc
-| |
-| o  c5945b6a97ed - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part b: Remove nsIDeviceContext::SupportsNativeWidgets because it's not used meaningfully, and will be confusing in content processes. sr=roc
-| |
-| o  5452db293694 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part a: Add nsIView::Impl() and nsView::CreateWidget() to get rid of |static_cast<nsview*>(this)|. r=roc
-| |
-| o  9407827b5166 - Chris Jones <jones.chris.g@gmail.com> - Bug 582075, part 0.5: Add support for aInitData=NULL to the Windows nsWindow implementation. r=dougt
-| |
-| o  88a279b64473 - Chris Jones <jones.chris.g@gmail.com> - Bug 582057, part 0: Log the repaint region bounding rect in DumpPaintEvent. r=roc
-| |
-| o  cebb111fbfc4 - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 3: Remove nsSVGUtils::GetThebesComputationalSurface and use gfxPlatform::ScreenReferenceSurface instead. r=jwatt
-| |
-| o  7b3726c3a580 - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 2: Change nsIPresShell::CreateRenderingContext to GetReferenceRenderingContext, that uses the shared 1x1 surface, and use it all over the place. r=mats,sr=dbaron
-| |
-| o  b3e968d831ec - Robert O'Callahan <roc@ocallahan.org> - Bug 585817. Part 1: Create a single static 1x1 surface in gfxPlatform that can be used to create contexts for text measurement etc. r=vlad
-| |
-| o  55ef0e0529bc - Mounir Lamouri <mounir.lamouri@gmail.com> - Bug 506554 - Implement the CSS3 pseudo-classes :required and :optional for HTML. r=sicking sr=bz a2.0=blocking
-| |
-$ hg out
-comparing with http://hg.mozilla.org/mozilla-central
-searching for changes
-1767c1fb9418 - Chris Jones <jones.chris.g@gmail.com> - Back out bug 585817 and bug 582057
-8fccc434c295 - Chris Jones <jones.chris.g@gmail.com> - Merge backout
-</int></int>
-
-

Maintaining a branch of mozilla-central

-

Let foo be the project you are working on. We assume that the project directory will be http://hg.mozilla.org/projects/foo and is a branch of mozilla-central. We also assume that you want to push some patches on foo and periodically synchronize both repositories.

-

Modify hgrc

-

To make things simpler, you can modify the hgrc file in the repository. You can find it here: /path/to/repository/.hg/hgrc

-

Change it to:

-
[paths]
-default = http://hg.mozilla.org/projects/foo
-m-c = ssh://hg.mozilla.org/mozilla-central
-default-push = ssh://hg.mozilla.org/projects/foo
-
-

Synchronize mozilla-central and foo project

-

You can push to foo as you would push to any repository but you might want to keep in sync both repositories. To do that, you can run these commands:

-
hg pull -u   # Get all the changes to foo in your repo.
-hg pull m-c  # Get all the changes to mozilla-central in your repo.
-hg merge     # Here, the things might be complex and would need extra carefulness.
-# resolve merge conflicts, if any
-hg commit -m "Merge foo with mozilla-central."
-hg push      # Push the merge to foo.
-hg push m-c  # Push the changes to mozilla-central.
-
-

Help

-

Help, I can't push!

-

If you're trying to push, and you can't, first try this:

-
$ ssh hg.mozilla.org
-
-

If you see output like:

-
Permission denied (publickey,gssapi-with-mic).
-
-

it may have the following reasons:

- -

If you see output like:

-
You are not allowed to use this system, go away!
-
-

then you need to file a bug in mozilla.org:Server Operations.

-

You should expect the ssh command to disconnect you immediately, since you're not supposed to have shell access. It may give the output:

-
Could not chdir to home directory : No such file or directory
-
-

which is harmless (although some people see it and some people don't).

-

If you see output like:

-
ssl required
-
-

then you need to configure your default-push correctly.

-

Branch merges

-

As part of the rapid release process, the contents of e.g. mozilla-aurora and mozilla-beta are subject to merge events that happen according to the planned branch migration dates. After a branch merge event occurred, if you attempt to use "hg update" in your local tree, you may get error messages such as "abort: crosses branches". In order to fix it, first make sure you don't have local changes, then run "hg update -C -r default".

-

Other

-

What's the difference between hg pull and hg update?

-

hg-diagram.png

-

hg pull copies changesets from one repository to another.  It only brings changes into your local repository, not your working copy.  It will touch the network if you're pulling from a remote repository.

-

hg update updates your working copy.  It only modifies your working copy.  It will not touch the network (unless your directory is on a network filesystem).

-

How does Mercurial handle line endings?

-

The Windows version of Mercurial does not automatically convert line endings between Windows and Unix styles. All our repositories use Unix line endings. We need a story for Windows, but right now I have no ideas.

-

(How about a pre-commit hook that rejects pushes containing CR with a suitably informative error message? We possibly want to make exceptions for certain types of files (at least binary files of course), but we can tweak the hook as necessary as these crop up. Mercurial 1.0 adds a standard hook for this in the win32text extension that we could use/adapt. --jwatt)

-

See Also

- -

{{ languages( { "es": "es/FAQ_de_Mercurial" } ) }}

diff --git a/files/zh-cn/midas/index.html b/files/zh-cn/midas/index.html deleted file mode 100644 index f463b504de..0000000000 --- a/files/zh-cn/midas/index.html +++ /dev/null @@ -1,324 +0,0 @@ ---- -title: Midas 所见即所得编辑功能 -slug: Midas -translation_of: Mozilla/Projects/Midas ---- -

简介

-

Midas是一个Gecko内建的富文本编辑器的代号。Midas可以通过JS激活。当Midas可用时,文档将变成用户可编辑状态。Midas的脚本是基于IE所支持的DHTML commands。IE中通过设置文档对象的designMode属性让整个文档变成可编辑状态;这也是Gecko中的Midas采用的调用方式。IE也支持让某个特定元素进入可编辑状态,只要在钙元素上使用contentEditable属性;从FireFox3开始,Gecko也支持使用contentEditable。只要调用了Midas,就可以使用document文档对象的一些方法相关方法。

-

属性

-
-
- document.designMode
-
- 将该属性设置为“on”,该文档将可编辑。
-
-

注意

-

整个文档变为可编辑状态后,开发者常将此文档载入iframe框架,然后在父文档中编写代码。根据标准,iframe元素拥有contentDocument属性引用其内联框架的document对象,同样还有contentWindow属性可以引用内联框架的window对象。

-

除了内建的命令意外,通过操纵Selectionrange对象可以实现更高级的编辑功能。编辑文档的时候用到这些对象可以提高编辑器的友好性。

-

案例

-

该示例代码展示了最基本的代码结构:

-
<html>
-	<head>
-		<title>Simple Edit Box</title>
-	</head>
-	<body>
-		<iframe
-			id="MidasForm"
-			src="about:blank"
-			onload="this.contentDocument.designMode='on';"
-		></iframe>
-	</body>
-</html>
-
-

方法

-
-
- document.execCommand
-
- 执行给定的命令。
-
- document.queryCommandEnabled
-
- 文档在当前状态下是否可以执行给定的命令。
-
- document.queryCommandIndeterm
-
- 检测当前选定的内容是否处于不确定的状态。
-
- document.queryCommandState
-
- 检测给出的命令是否已在当前选择的内容上执行。
-
- document.queryCommandValue
-
- 检测给定命令操作的当前文档、范围或选定内容的当前值。
-
-

支持的命令

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CommandValueDescription
backcolor -

颜色代码

-
-

设置文档背景色。

-
bold  -

如果没有选中文本,将在光标处插入一个标志位。

-

如果选中了一段文本并且该文本内容已经是粗体,那么这些粗体样式会被移除。否则,所有文本都会从普通状态变为粗体。

-
contentReadOnly  -

该命令可以让编辑器变为只读状态(true)或可编辑状态(false)。当页面需要进行其他活动(比如保存编辑状态,利用AJAX向服务器提交数据)的时候,该命令会很有用。

-
copy  -

如果选择了一段文本,该命令可以将其内容拷贝到剪贴板。如果没有选中文本,什么也不会发生。

-

note: this command won't work without setting a pref or using signed JS. See: more about security preferences

-

note: the shortcut key will automatically trigger this command (typically accel-C) with or without the signed JS or any code on the page to handle it.

-
createlinkA URI.This command will not do anything if no selection is made. If there is a selection, a link will be inserted around the selection with the url parameter as the href of the link.
cut If there is a selection, this command will copy the selection to the clipboard and remove the selection from the edit control. If there isn't a selection, nothing will happen. -

note: this command won't work without setting a pref or using signed JS. See: more about security preferences

-

note: the shortcut key will automatically trigger this command (typically accel-X) with or without the signed JS or any code on the page to handle it.

-
decreasefontsize This command will add a <small> tag around selection or at insertion point.
delete This command will delete all text and objects that are selected. If no text is selected it deletes one character to the right. This is similar to the Delete button on the keyboard.
fontnameA font nameThis command will set the font face for a selection or at the insertion point if there is no selection. -

The given string is such as would be used in the "face" attribute of the font tag, i.e., a comma-separated list of font names.

-
fontsizeA numberThis command will set the fontsize for a selection or at the insertion point if there is no selection. -

The given number is such as would be used in the "size" attribute of the font tag.

-
forecolorA color codeThis command will set the text color of the selection or at the insertion point.
formatblockH1, H2, H3, H4, H5, H6, P, DIV, ADDRESS, BLOCKQUOTE (more?)The selection surrounded by the given block element.
headingH1, H2, H3, H4, H5, H6Selected block will be formatted as the given type of heading.
hilitecolorA color codeThis command will set the hilite color of the selection or at the insertion point. It only works with styleWithCSS enabled.
increasefontsize This command will add a <big> tag around selection or at insertion point.
indent Indent the block where the caret is located. If the caret is inside a list, that item becomes a sub-item one level deeper.
insertbronreturntrue/falseSelects whether pressing return inside a paragraph creates another paragraph or just inserts a <br> tag.
inserthorizontalrulenull/string (when string is the Line's id)This command will insert a horizontal rule (line) at the insertion point. -

Does it delete the selection? Yes!

-
inserthtmlA string.This command will insert the given html into the <body> in place of the current selection or at the caret location. -

The given string is the HTML to insert.

-
insertimageA URI.This command will insert an image (referenced by the given url) at the insertion point.
insertorderedlist Depends on the selection. If the caret is not inside a non-LI block, that block becomes the first LI and an OL. If the caret is inside a bulleted item, the bulleted item becomes a numbered item.
insertunorderedlist Depends on the selection. If the caret is not inside a non-LI block, that block becomes the first LI and UL. If the caret is inside a numbered item, the numbered item becomes a bulleted item.
insertparagraph Inserts a new paragraph.
italic If there is no selection, the insertion point will set italic for subsequently typed characters. -

If there is a selection and all of the characters are already italic, the italic will be removed. Otherwise, all selected characters will become italic.

-
justifycenter Center-aligns the current block.
justifyfull Fully-justifies the current block.
justifyleft Left-aligns the current block.
justifyright Right aligns the current block.
outdent Outdent the block where the caret is located. If the block is not indented prior to calling outdent, nothing will happen. -

If the caret is in a list item, the item will bump up a level in the list or break out of the list entirely.

-
paste This command will paste the contents of the clipboard at the location of the caret. If there is a selection, it will be deleted prior to the insertion of the clipboard's contents. -

note: this command won't work without setting a pref or using signed JS. user_pref("capability.policy.policynames", "allowclipboard"); user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess"); See: more about security preferences

-

note: the shortcut key will automatically trigger this command (typically accel-V) with or without the signed JS or any code on the page to handle it.

-
redo This command will redo the previous undo action. If undo was not the most recent action, this command will have no effect. -

note: the shortcut key will automatically trigger this command (typically accel-shift-Z)

-
removeformat Removes inline formatting from the current selection.
selectall This command will select all of the contents within the editable area. -

note: the shortcut key will automatically trigger this command (typically accel-A)

-
strikethrough If there is no selection, the insertion point will set strikethrough for subsequently typed characters. -

If there is a selection and all of the characters are already striked, the strikethrough will be removed. Otherwise, all selected characters will have a line drawn through them.

-
styleWithCSS This command is used for toggling the format of generated content. By default (at least today), this is true. An example of the differences is that the "bold" command will generate <b> if the styleWithCSS command is false and generate css style attribute if the styleWithCSS command is true.
subscript If there is no selection, the insertion point will set subscript for subsequently typed characters. -

If there is a selection and all of the characters are already subscripted, the subscript will be removed. Otherwise, all selected characters will be drawn slightly lower than normal text.

-
superscript If there is no selection, the insertion point will set superscript for subsequently typed characters. -

If there is a selection and all of the characters are already superscripted, the superscript will be removed. Otherwise, all selected characters will be drawn slightly higher than normal text.

-
underline If there is no selection, the insertion point will set underline for subsequently typed characters. -

If there is a selection and all of the characters are already underlined, the underline will be removed. Otherwise, all selected characters will become underlined.

-
undo This command will undo the previous action. If no action has occurred in the document, then this command will have no effect. -

note: the shortcut key will automatically trigger this command (typically accel-Z)

-
unlink If the insertion point is within a link or if the current selection contains a link, the link will be removed and the text will remain.
{{ Deprecated_header() }}
readonly This command has been replaced with contentReadOnly. It takes the same values as contentReadOnly, but the meaning of true and false are inversed.
useCSS This command has been replaced with styleWithCSS. It takes the same values as styleWithCSS, but the meaning of true and false are inversed.
-

 

diff --git a/files/zh-cn/midas/security_preferences/index.html b/files/zh-cn/midas/security_preferences/index.html deleted file mode 100644 index be9edc27a0..0000000000 --- a/files/zh-cn/midas/security_preferences/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Midas editor module security preferences -slug: Midas/Security_preferences -translation_of: Mozilla/Projects/Midas/Security_preferences ---- -
-

Note: If you've reached this page from a message box in Firefox or another Mozilla product, try using keyboard shortcuts for the Cut, Copy, and Paste commands:

- -

注意:如果你从火狐信息邮箱,或者火狐的其他产品有到达这个页面,试着使用键盘快捷键,剪切,复制,黏贴命令。

- - - -

The information on the rest of this page is for Web developers and advanced users. Please do not try to modify this page.

- -

这个网页剩余的信息是为了网页开发者好和高级的用户。请不要试着修改这个页面。

- -

 

-
- -

To protect users' private information, unprivileged scripts cannot invoke the Cut, Copy, and Paste commands in Midas, which is Mozilla's rich text editor component.

- -

在Midas中为了保护用户的私有信息,没有权限的脚本 不能调用剪切,复制和黏贴命令,那个是火狐强大的文本编辑组件。

- -

This means that the corresponding buttons on the Mozilla Rich Text Editing demo page will not work. To enable these functions, you must modify your browser preferences.

- -

这个意味着那个符号命令的按钮在火狐强大文本编辑演示页面不能够工作。为了启动这个功能,你可以修改浏览器的首选项。

- -
-

Warning: Changing these preferences can leave your browser insecure, especially if you grant permission to untrusted sites.

- -

警告:改变这个首选项可能不安全的离开你的浏览器,尤其如果你获得允许为了不真实的网站。

- -

Only change these settings as needed to try the demo above and to test your own add-on or Firefox-internal code, and be sure to restore the default settings when you're done!

- -

仅仅改变这些设置如需要试着演示上面的和测试你拥有的添加在或者火狐内部的代码,当你做的时候确保恢复默认的设置。

-
- -

Changing the preferences in Firefox

- -

在火狐中改变首选项。

- -
    -
  1. Quit Firefox. If you have Quick Launch running (on Windows, this is an icon in the toolbar), quit that too.
  2. -
  3. 退出火狐。如果你有快速的开始运行(在windows,这是一个图标在那个工具池里),也退出。
  4. -
  5. Find your Firefox profile directory.
  6. -
  7. 找到你的火狐资料目录
  8. -
  9. Open the user.js file from that directory in a text editor. If there's no user.js file, create one.
  10. -
  11. 打开那个user.js文件从在文本编辑器的目录。如果没有user.js文件,创建一个。
  12. -
  13. Add these lines to user.js:
  14. -
  15. 在user.js中添加下面这些行。
  16. -
  17. -
    user_pref("capability.policy.policynames", "allowclipboard");
    -user_pref("capability.policy.allowclipboard.sites", "https://www-archive.mozilla.org");
    -user_pref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess");
    -user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess");
    -
    -
  18. -
  19. Change the URL https://www.mozilla.org to the site for which you want to enable this function.
  20. -
  21. 改变那个URL https://www.mozilla.org 这个网站,你想要使用这个功能。
  22. -
  23. Save the file and restart Firefox. The Clipboard buttons in the demo, or similar buttons on the sites you listed, should now function.
  24. -
  25. 保存这个文件和重启火狐。那在演示中的剪切板按钮或者在网站中你列表类似的按钮,应该有现在的功能。
  26. -
- -
-

Note: The preference is site as well as protocol specific. For example:

- -

注意;那个首选项网址也是特定协议。例如

- -
user_pref("capability.policy.allowclipboard.sites", "http://www-archive.mozilla.org")
-
- -

is not the same as:

- -

不是相同的和下面的

- -
user_pref("capability.policy.allowclipboard.sites", "https://www-archive.mozilla.org")
-
- -

This is because the first uses HTTP while the second uses HTTPS.

- -

这是因为第一个使用HTTP 然而第二个使用HTTPS

- -

If you want to allow multiple URLs to access the Paste operation, separate the URLs with a space. For example:

- -

如果你想要允许多条URL访问那个黏贴操作,使用独立的URL的一个空间。例如:

- -
user_pref("capability.policy.allowclipboard.sites", "https://www-archive.mozilla.org https://developer.mozilla.org")
-
-
- -

Again, keep in mind the security risks involved here and be sure to remove permission to access the clipboard once you no longer need it enabled.

- -

再次说明,牢记那个安全危机在这里涉及的,和确保移除允许访问那个剪切板一旦你不在需要启动它。

- -

See also

- -

另见:

- - diff --git a/files/zh-cn/migrate_apps_from_internet_explorer_to_mozilla/index.html b/files/zh-cn/migrate_apps_from_internet_explorer_to_mozilla/index.html deleted file mode 100644 index 906d245c28..0000000000 --- a/files/zh-cn/migrate_apps_from_internet_explorer_to_mozilla/index.html +++ /dev/null @@ -1,1057 +0,0 @@ ---- -title: 网页代码移植:从_IE_到_Mozilla -slug: Migrate_apps_from_Internet_Explorer_to_Mozilla -tags: - - Web Development - - Web Standards -translation_of: Archive/Mozilla/Migrate_apps_from_Internet_Explorer_to_Mozilla ---- -

介绍

-

Netscape当初创建Mozilla浏览器的时候,就决定使用W3C标准。因此,Mozilla并不是完全的向前兼容Netscape Navigator 4.x和微软IE的遗留代码。比如,Mozilla不支持我后面要提到的<layer>。像IE4那样的浏览器,是在W3C的标准被提出之前创建的,它含有很多怪癖的遁词(quirk)。在这篇文章里,我将要描述Mozilla的Quirk模式,它提供了强大的对IE和其他浏览器的HTML向前兼容功能。

-

我还会介绍一些其他的Mozilla可以支持的,但没有W3C相关规则的非标准技术,如XMLHttpRequest和Rich-text编辑功能:

- -

通用跨浏览器代码小技巧

-

Even though Web standards do exist, different browsers behave differently (in fact, the same browser may behave differently depending on the platform). Many browsers, such as Internet Explorer, also support pre-W3C APIs and have never added extensive support for the W3C-compliant ones.

-

Before I go into the differences between Mozilla and Internet Explorer, I'll cover some basic ways you can make a Web application extensible in order to add new browser support later.

-

Since different browsers sometimes use different APIs for the same functionality, you can often find multiple if() else() blocks throughout the code to differentiate between the browsers. The following code shows blocks designated for Internet Explorer:

-
. . .
-
-var elm;
-
-if (ns4)
-  elm = document.layers["myID"];
-else if (ie4)
-  elm = document.all["myID"]
-
-

The above code isn't extensible, so if you want it to support a new browser, you must update these blocks throughout the Web application.

-

The easiest way to eliminate the need to recode for a new browser is to abstract out functionality. Rather than multiple if() else() blocks, you increase efficiency by taking common tasks and abstracting them out into their own functions. Not only does this make the code easier to read, it simplifies adding support for new clients:

-
var elm = getElmById("myID");
-
-function getElmById(aID){
-  var element = null;
-
-  if (isMozilla || isIE5)
-    element = document.getElementById(aID);
-  else if (isNetscape4)
-    element = document.layers[aID];
-  else if (isIE4)
-    element = document.all[aID];
-
-  return element;
-}
-
-

The above code still has the issue of browser sniffing, or detecting which browser the user is using. Browser sniffing is usually done through the useragent, such as:

-
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031016
-
-

While using the useragent to sniff the browser provides detailed information on the browser in use, code that handles useragents often can make mistakes when new browser versions arrive, thus requiring code changes.

-

If the type of browser doesn't matter (suppose that you have already blocked nonsupported browsers from accessing the Web application), it is much better and more reliable to sniff by browser capability or object feature support. You can usually do this by testing the required functionality in JavaScript. For example, rather than:

-
if (isMozilla || isIE5)
-
-

You would use:

-
if (document.getElementById)
-
-

This would allow other browsers that support that W3C standard method, such as Opera or Safari, to work without any changes.

-

Useragent sniffing, however, makes sense when accuracy is important, such as when you're verifying that a browser meets the Web application's version requirements or you are trying to work around a bug.

-

JavaScript also allows inline conditional statements, which can help with code readability:

-
var foo = (condition) ? conditionIsTrue : conditionIsFalse;
-
-

For example, to retrieve an element, you would use:

-
function getElement(aID){
-  return (document.getElementById) ? document.getElementById(aID)
-                                   : document.all[aID]);
-}
-
-

Or another way is to use the || operator:

-
function getElement(aID){
-  return (document.getElementById(aID)) || document.all[aID]);
-}
-
-

Mozilla和Internet Explorer的区别

-

First, I'll discuss the differences in the way HTML behaves between Mozilla and Internet Explorer.

-

工具提示(tooltips)

-

Legacy browsers introduced tooltips into HTML by showing them on links and using the value of the alt attribute as a tooltip's content. The latest W3C HTML specification created the title attribute, which is meant to contain a detailed description of the link. Modern browsers will use the title attribute to display tooltips, and Mozilla only supports showing tooltips for that attribute and not the alt attribute.

-

HTML实体(Entities)

-

HTML markup can contain several entities, which the W3C web standards body has defined. You can reference entities through their numerical or character reference. For example, you can reference the white space character #160 with &#160; or with its equivalent character reference &nbsp;.

-

Some older browsers, such as Internet Explorer, had such quirks as allowing you to use entities by replacing the ; (semi-colon) character at the end with regular text content:

-
&nbsp Foo
-&nbsp&nbsp Foo
-
-

Mozilla will render the above &nbsp as white spaces, even though that is against the W3C specification. The browser will not parse a &nbsp if it is directly followed by more characters, for example:

-
&nbsp12345
-
-

This code does not work in Mozilla, since it goes against the W3C web standards. Always use the correct form (&nbsp;) to avoid browser discrepancies.

-

DOM 差异

-

The Document Object Model (DOM) is the tree structure that contains the document elements. You can manipulate it through JavaScript APIs, which the W3C has standardized. However, prior to W3C standardization, Netscape 4 and Internet Explorer 4 implemented the APIs similarly. Mozilla only implements legacy APIs if they are unachievable with W3C web standards.

-

存取元素

-

To retrieve an element reference using the cross-browser approach, you use document.getElementById(aID), which works in Internet Explorer 5.0+, Mozilla-based browsers, other W3C-compliant browsers and is part of the DOM Level 1 specification.

-

Mozilla does not support accessing an element through document.elementName or even through the element's name, which Internet Explorer does (also called global namespace polluting). Mozilla also does not support the Netscape 4 document.layers method and Internet Explorer's document.all. While document.getElementById lets you retrieve one element, you can also use document.layers and document.all to obtain a list of all document elements with a certain tag name, such as all <div> elements.

-

The W3C DOM Level 1 method gets references to all elements with the same tag name through getElementsByTagName(). The method returns an array in JavaScript, and can be called on the document element or other nodes to search only their subtree. To get an array of all elements in the DOM tree, you can use getElementsByTagName("*").

-

The DOM Level 1 methods, as shown in Table 1, are commonly used to move an element to a certain position and toggle its visibility (menus, animations). Netscape 4 used the <layer> tag, which Mozilla does not support, as an HTML element that can be positioned anywhere. In Mozilla, you can position any element using the <div> tag, which Internet Explorer uses as well and which you'll find in the HTML specification.

- - - - - - - - - - - - - - - - -
- Table 1. Methods used to access elements
MethodDescription
document.getElementById( aId )Returns a reference to the element with the specified ID.
document.getElementsByTagName( aTagName )Returns an array of elements with the specified name in the document.
-

纵横DOM

-

Mozilla supports the W3C DOM APIs for traversing the DOM tree through JavaScript (see Table 2). The APIs exist for each node in the document and allow walking the tree in any direction. Internet Explorer supports these APIs as well, but it also supports its legacy APIs for walking a DOM tree, such as the children property.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 2. Methods used to traverse the DOM
Property/MethodDescription
childNodesReturns an array of all child nodes of the element.
firstChildReturns the first child node of the element.
getAttribute( aAttributeName )Returns the value for the specified attribute.
hasAttribute( aAttributeName )Returns a boolean stating if the current node has an attribute defined with the specified name.
hasChildNodes()Returns a boolean stating whether the current node has any child nodes.
lastChildReturns the last child node of the element.
nextSiblingReturns the node immediately following the current one.
nodeNameReturns the name of the current node as a string.
nodeTypeReturns the type of the current node. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ValueDescription
1Element Node
2Attribute Node
3Text Node
4CDATA Section Node
5Entity Reference Node
6Entity Node
7Processing Instruction Node
8Comment Node
9Document Node
10Document Type Node
11Document Fragment Node
12Notation Node
-
nodeValueReturns the value of the current node. For nodes that contain text, such as text and comment nodes, it will return their string value. For attribute nodes, the attribute value is returned. For all other nodes, null is returned.
ownerDocumentReturns the document object containing the current node.
parentNodeReturns the parent node of the current node.
previousSiblingReturns the node immediately preceding the current one.
removeAttribute( aName )Removes the specified attribute from the current node.
setAttribute( aName, aValue )Sets the value of the specified attribute with the specified value.
-

Internet Explorer has a nonstandard quirk, where many of these APIs will skip white space text nodes that are generated, for example, by new line characters. Mozilla will not skip these, so sometimes you need to distinguish these nodes. Every node has a nodeType property specifying the node type. For example, an element node has type 1, while a text node has type 3 and a comment node is type 8. The best way to only process element nodes is to iterate over all child nodes and only process those with a nodeType of 1:

-
HTML:
-  <div id="foo">
-    <span>Test</span>
-  </div>
-
-JavaScript:
-  var myDiv = document.getElementById("foo");
-  var myChildren = myXMLDoc.childNodes;
-  for (var i = 0; i < myChildren.length; i++) {
-    if (myChildren[i].nodeType == 1){
-      // element node
-    };
-  };
-
-

内容建立和处理

-

Mozilla supports the legacy methods for adding content into the DOM dynamically, such as document.write, document.open and document.close. Mozilla also supports Internet Explorer's innerHTML method, which it can call on almost any node. It does not, however, support outerHTML (which adds markup around an element, and has no standard equivalent) and innerText (which sets the text value of the node, and which you can achieve in Mozilla by using textContent).

-

Internet Explorer has several content manipulation methods that are nonstandard and unsupported in Mozilla, including retrieving the value, inserting text and inserting elements adjacent to a node, such as getAdjacentElement and insertAdjacentHTML. Table 3 shows how the W3C standard and Mozilla manipulate content, all of which are methods of any DOM node.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 3. Methods Mozilla uses to manipulate content
MethodDescription
appendChild( aNode )Creates a new child node. Returns a reference to the new child node.
cloneNode( aDeep )Makes a copy of the node it is called on and returns the copy. If aDeep is true, it copies over the node's entire subtree.
createElement( aTagName )Creates and returns a new and parentless DOM node of the type specified by aTagName.
createTextNode( aTextValue )Creates and returns a new and parentless DOM textnode with the data value specified by aTextValue.
insertBefore( aNewNode, aChildNode )Inserts aNewNode before aChildNode, which must be a child of the current node.
removeChild( aChildNode )Removes aChildNode and returns a reference to it.
replaceChild( aNewNode, aChildNode )Replaces aChildNode with aNewNode and returns a reference to the removed node.
-

文件片断

-

For performance reasons, you can create documents in memory, rather than working on the existing document's DOM. DOM Level 1 Core introduced document fragments, which are lightweight documents that contain a subset of a normal document's interfaces. For example, getElementById does not exist, but appendChild does. You can also easily add document fragments to existing documents.

-

Mozilla creates document fragments through document.createDocumentFragment(), which returns an empty document fragment.

-

Internet Explorer's implementation of document fragments, however, does not comply with the W3C web standards and simply returns a regular document.

-

JavaScript differences

-

Most differences between Mozilla and Internet Explorer are usually blamed on JavaScript. However, the issues usually lie in the APIs that a browser exposes to JavaScript, such as the DOM hooks. The two browsers possess few core JavaScript differences; issues encountered are often timing related.

-

JavaScript date differences

-

The only Date difference is the getYear method. As per the ECMAScript specification (which is the specification JavaScript follows), the method is not Y2k-compliant, and running new Date().getYear() in 2004 will return "104". Per the ECMAScript specification, getYear returns the year minus 1900, originally meant to return "98" for 1998. getYear was deprecated in ECMAScript Version 3 and replaced with getFullYear(). Internet Explorer changed getYear() to work like getFullYear() and make it Y2k-compliant, while Mozilla kept the standard behavior.

-

JavaScript execution differences

-

Different browsers execute JavaScript differently. For example, the following code assumes that the div node already exists in the DOM by the time the script block executes:

-
...
-<div id="foo">Loading...</div>
-
-<script>
-  document.getElementById("foo").innerHTML = "Done.";
-</script>
-
-

However, this is not guaranteed. To be sure that all elements exist, you should use the onload event handler on the <body> tag:

-
<body onload="doFinish();">
-
-<div id="foo">Loading...</div>
-
-<script>
-  function doFinish() {
-    var element = document.getElementById("foo");
-    element.innerHTML = "Done.";
-  }
-</script>
-...
-
-

Such timing-related issues are also hardware-related -- slower systems can reveal bugs that faster systems hide. One concrete example is window.open, which opens a new window:

-
<script>
-  function doOpenWindow(){
-    var myWindow = window.open("about:blank");
-    myWindow.location.href = "http://www.ibm.com";
-  }
-</script>
-
-

The problem with the code is that window.open is asynchronous -- it does not block the JavaScript execution until the window has finished loading. Therefore, you may execute the line after the window.open line before the new window has finished. You can deal with this by having an onload handler in the new window and then call back into the opener window (using window.opener).

-

Differences in JavaScript-generating HTML

-

JavaScript can, through document.write, generate HTML on the fly from a string. The main issue here is when JavaScript, embedded inside an HTML document (thus, inside an <script> tag), generates HTML that contains a <script> tag. If the document is in strict rendering mode, it will parse the </script> inside the string as the closing tag for the enclosing <script>. The following code illustrates this best:

-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-...
-<script>
-  document.write("<script type='text\/javascript'>alert('Hello');<\/script>")
-</script>
-
-

Since the page is in strict mode, Mozilla's parser will see the first <script> and parse until it finds a closing tag for it, which would be the first </script>. This is because the parser has no knowledge about JavaScript (or any other language) when in strict mode. In quirks mode, the parser is aware of JavaScript when parsing (which slows it down). Internet Explorer is always in quirks mode, as it does not support true XHTML. To make this work in strict mode in Mozilla, separate the string into two parts:

-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-...
-<script>
-  document.write("<script type='text\/javascript'>alert('Hello');</" + "script>")
-</script>
-
-

Debug JavaScript

-

Mozilla provides several ways to debug JavaScript-related issues found in applications created for Internet Explorer. The first tool is the built-in JavaScript console, shown in Figure 1, where errors and warnings are logged. You can access it in Mozilla by going to Tools -> Web Development -> JavaScript Console or in Firefox (the standalone browser product from Mozilla) at Tools -> JavaScript Console.

-

Figure 1. JavaScript console

-

Javascript Console

-

The JavaScript console can show the full log list or just errors, warnings, and messages. The error message in Figure 1 says that at aol.com, line 95 tries to access an undefined variable called is_ns70. Clicking on the link will open Mozilla's internal view source window with the offending line highlighted.

-

The console also allows you to evaluate JavaScript. To evaluate the entered JavaScript syntax, type in 1+1 into the input field and press Evaluate, as Figure 2 shows.

-

Figure 2. JavaScript console evaluating

-

JavaScript Console evaluating

-

Mozilla's JavaScript engine has built-in support for debugging, and thus can provide powerful tools for JavaScript developers. Venkman, shown in Figure 3, is a powerful, cross-platform JavaScript debugger that integrates with Mozilla. It is usually bundled with Mozilla releases; you can find it at Tools -> Web Development -> JavaScript Debugger. For Firefox, the debugger isn't bundled; instead, you can download and install it from the Venkman Project Page. You can also find tutorials at the development page, located at the Venkman Development Page.

-

Figure 3. Mozilla's JavaScript debugger

-

Mozilla's JavaScript debugger

-

The JavaScript debugger can debug JavaScript running in the Mozilla browser window. It supports such standard debugging features as breakpoint management, call stack inspection, and variable/object inspection. All features are accessible through the user interface or through the debugger's interactive console. With the console, you can execute arbitrary JavaScript in the same scope as the JavaScript currently being debugged.

-

CSS differences

-

Mozilla-based products have the strongest support for Cascading Style Sheets (CSS), including most of CSS1, CSS2.1 and parts of CSS3, compared to Internet Explorer as well as all other browsers.

-

For most issues mentioned below, Mozilla will add an error or warning entry into the JavaScript console. Check the JavaScript console if you encounter CSS-related issues.

-

Mimetypes (when CSS files are not applied)

-

The most common CSS-related issue is that CSS definitions inside referenced CSS files are not applied. This is usually due to the server sending the wrong mimetype for the CSS file. The CSS specification states that CSS files should be served with the text/css mimetype. Mozilla will respect this and only load CSS files with that mimetype if the Web page is in strict standards mode. Internet Explorer will always load the CSS file, no matter with which mimetype it is served. Web pages are considered in strict standards mode when they start with a strict doctype. To solve this problem, you can make the server send the right mimetype or remove the doctype. I'll discuss more about doctypes in the next section.

-

CSS and units

-

Many Web applications do not use units with their CSS, especially when you use JavaScript to set the CSS. Mozilla tolerates this, as long as the page is not rendered in strict mode. Since Internet Explorer does not support true XHTML, it does not care if no units are specified. If the page is in strict standards mode, and no units are used, then Mozilla ignores the style:

-
<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-  "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-  <head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <title>CSS and units example</title>
-  </head>
-  <body>
-    // works in strict mode
-    <div style="width: 40px; border: 1px solid black;">
-      Text
-    </div>
-
-    // will fail in strict mode
-    <div style="width: 40; border: 1px solid black;">
-      Text
-    </div>
-  </body>
-</html>
-
-

Since the above example has a strict doctype, the page is rendered in strict standards mode. The first div will have a width of 40px, since it uses units, but the second div won't get a width, and thus will default to 100% width. The same would apply if the width were set through JavaScript.

-

JavaScript and CSS

-

Since Mozilla supports the CSS standards, it also supports the CSS DOM standard for setting CSS through JavaScript. You can access, remove, and change an element's CSS rules through the element's style member:

-
<div id="myDiv" style="border: 1px solid black;">
-  Text
-</div>
-
-<script>
-  var myElm = document.getElementById("myDiv");
-  myElm.style.width = "40px";
-</script>
-
-

You can reach every CSS attribute that way. Again, if the Web page is in strict mode, you must set a unit or else Mozilla will ignore the command. When you query a value, say through .style.width, in Mozilla and Internet Explorer, the returned value will contain the unit, meaning a string is returned. You can convert the string into a number through parseFloat("40px").

-

CSS overflow differences

-

CSS added the notion of overflow, which allows you to define how to handle overflow; for example, when the contents of a div with a specified height are taller than that height. The CSS standard defines that if no overflow behavior is set in this case, the div contents will overflow. However, Internet Explorer does not comply with this and will expand the div beyond its set height in order to hold the contents. Below is an example that shows this difference:

-
<div style="height: 100px; border: 1px solid black;">
-  <div style="height: 150px; border: 1px solid red; margin: 10px;">
-    a
-  </div>
-</div>
-
-

As you can see in Figure 4, Mozilla acts like the W3C standard specifies. The W3C standard says that, in this case, the inner div overflows to the bottom since the inner content is taller than its parent. If you prefer the Internet Explorer behavior, simply do not specify a height on the outer element.

-

Figure 4. DIV overflow

-

DIV Overflow

-

hover differences

-

The nonstandard CSS hover behavior in Internet Explorer occurs on quite a few web sites. It usually manifests itself by changing text style when hovered over in Mozilla, but not in Internet Explorer. This is because the a:hover CSS selector in Internet Explorer matches <a href="">...</a> but not <a name="">...</a>, which sets anchors in HTML. The text changes occur because authors encapsulate the areas with the anchor-setting markup:

-
CSS:
-  a:hover {color: green;}
-
-HTML:
-  <a href="foo.com">This text should turn green when you hover over it.</a>
-
-  <a name="anchor-name">
-    This text should change color when hovered over, but doesn't
-    in Internet Explorer.
-  </a>
-
-

Mozilla follows the CSS specification correctly and will change the color to green in this example. You can use two ways to make Mozilla behave like Internet Explorer and not change the color of the text when hovered over:

- -

Quirks versus standards mode

-

Older legacy browsers, such as Internet Explorer 4, rendered with so-called quirks under certain conditions. While Mozilla aims to be a standards-compliant browser, it has three modes that support older Web pages created with these quirky behaviors. The page's content and delivery determine which mode Mozilla will use. Mozilla will indicate the rendering mode in View -> Page Info (or Ctrl+I) ; Firefox will list the rendering mode in Tools -> Page Info. The mode in which a page is located depends on its doctype.

-

Doctypes (short for document type declarations) look like this:

-

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

-

The section in blue is called the public identifier, the green part is the system identifier, which is a URI.

-

Standards mode

-

Standards mode is the strictest rendering mode -- it will render pages per the W3C HTML and CSS specifications and will not support any quirks. Mozilla uses it for the following conditions:

- -

Almost standards mode

-

Mozilla introduced almost standards mode for one reason: a section in the CSS 2 specification breaks designs based on a precise layout of small images in table cells. Instead of forming one image to the user, each small image ends up with a gap next to it. The old IBM homepage shown in Figure 5 offers an example.

-

Figure 5. Image gap

-

Image Gap

-

Almost standards mode behaves almost exactly as standards mode, except when it comes to an image gap issue. The issue occurs often on standards-compliant pages and causes them to display incorrectly.

-

Mozilla uses almost standards mode for the following conditions:

- -

You can read more about the image gap issue.

-

Quirks mode

-

Currently, the Web is full of invalid HTML markup, as well as markup that only functions due to bugs in browsers. The old Netscape browsers, when they were the market leaders, had bugs. When Internet Explorer arrived, it mimicked those bugs in order to work with the content at that time. As newer browsers came to market, most of these original bugs, usually called quirks, were kept for backwards compatibility. Mozilla supports many of these in its quirks rendering mode. Note that due to these quirks, pages will render slower than if they were fully standards-compliant. Most Web pages are rendered under this mode.

-

Mozilla uses quirks mode for the following conditions:

- -

For further reading, check out: Mozilla Quirks Mode Behavior and Mozilla's DOCTYPE sniffing.

-

Event differences

-

Mozilla and Internet Explorer are almost completely different in the area of events. The Mozilla event model follows the W3C and Netscape model. In Internet Explorer, if a function is called from an event, it can access the event object through window.event. Mozilla passes an event object to event handlers. They must specifically pass the object on to the function called through an argument.

-

A cross-browser event handling example follows (note that it means you can't define a global variable named event in your code):

-
<div onclick="handleEvent(event);">Click me!</div>
-
-<script>
-  function handleEvent(aEvent) {
-    var myEvent = window.event ? window.event : aEvent;
-  }
-</script>
-
-

The properties and functions that the event object exposes are also often named differently in Mozilla and Internet Explorer, as Table 4 shows.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 4. Event properties differences between Mozilla and Internet Explorer
Internet Explorer NameMozilla NameDescription
altKeyaltKeyBoolean property that returns whether the alt key was pressed during the event.
cancelBubblestopPropagation()Used to stop the event from bubbling farther up the tree.
clientXclientXThe X coordinate of the event, in relation to the element viewport.
clientYclientYThe Y coordinate of the event, in relation to the element viewport.
ctrlKeyctrlKeyBoolean property that returns whether the Ctrl key was pressed during the event.
fromElementrelatedTargetFor mouse events, this is the element from which the mouse moved away.
keyCodekeyCodeFor keyboard events, this is a number representing the key that was pressed. It is 0 for mouse events. For keypress events (not keydown/keyup) of keys that produce output, the Mozilla equivalent is charCode, not keyCode.
returnValuepreventDefault()Used to prevent the event's default action from occurring.
screenXscreenXThe X coordinate of the event, in relation to the screen.
screenYscreenYThe Y coordinate of the event, in relation to the screen.
shiftKeyshiftKeyBoolean property that returns whether the Shift key was pressed during the event.
srcElementtargetThe element to which the event was originally dispatched.
toElementcurrentTargetFor mouse events, this is the element to which the mouse moved.
typetypeReturns the name of the event.
-

Attach event handlers

-

Mozilla supports two ways to attach events through JavaScript. The first, supported by all browsers, sets event properties directly on objects. To set a click event handler, a function reference is passed to the object's onclick property:

-
<div id="myDiv">Click me!</div>
-
-<script>
-  function handleEvent(aEvent) {
-    // if aEvent is null, means the Internet Explorer event model,
-    // so get window.event.
-    var myEvent = aEvent ? aEvent : window.event;
-  }
-
-  function onPageLoad(){
-    document.getElementById("myDiv").onclick = handleEvent;
-  }
-</script>
-
-

Mozilla fully supports the W3C standard way of attaching listeners to DOM nodes. You use the addEventListener() and removeEventListener() methods, and have the benefit of being able to set multiple listeners for the same event type. Both methods require three parameters: the event type, a function reference, and a boolean denoting whether the listener should catch events in their capture phase. If the boolean is set to false, it will only catch bubbling events. W3C events have three phases: capturing, at target, and bubbling. Every event object has an eventPhase attribute indicating the phase numerically (0 indexed). Every time you trigger an event, the event starts at the DOM's outermost element, the element at the top of the DOM tree. It then walks the DOM using the most direct route toward the target, which is the capturing phase. When the event reaches the target, the event is in the target phase. After arriving at the target, it walks up the DOM tree back to the outermost node; this is bubbling. Internet Explorer's event model only has the bubbling phase; therefore, setting the third parameter to false results in Internet Explorer-like behavior:

-
<div id="myDiv">Click me!</div>
-
-<script>
-
-  function handleEvent(aEvent) {
-    // if aEvent is null, it is the Internet Explorer event model,
-    // so get window.event.
-    var myEvent = aEvent ? aEvent : window.event;
-  }
-
-  function onPageLoad() {
-    var element = document.getElementById("myDiv");
-    element.addEventListener("click", handleEvent, false);
-  }
-</script>
-
-

One advantage of addEventListener() and removeEventListener() over setting properties is that you can have multiple event listeners for the same event, each calling another function. Thus, to remove an event listener requires all three parameters be the same as the ones you use when adding the listener.

-

Mozilla does not support Internet Explorer's method of converting <script> tags into event handlers, which extends <script> with for and event attributes (see Table 5). It also does not support the attachEvent and detachEvent methods. Instead, you should use the addEventListener and removeEventListener methods. Internet Explorer does not support the W3C events specification. However, IE can be remediated to support addEventListener and removeEventListener.

- - - - - - - - - - - - - - - - - - - -
- Table 5. Event method differences between Mozilla and Internet Explorer
Internet Explorer MethodMozilla MethodDescription
attachEvent(aEventType, aFunctionReference)addEventListener(aEventType, aFunctionReference, aUseCapture)Adds an event listener to a DOM element.
detachEvent(aEventType, aFunctionReference)removeEventListener(aEventType, aFunctionReference, aUseCapture)Removes an event listener to a DOM element.
-

Rich text editing

-

While Mozilla prides itself with being the most W3C web standards compliant browser, it does support nonstandard functionality, such as innerHTML and rich text editing, if no W3C equivalent exists.

-

Mozilla 1.3 introduced an implementation of Internet Explorer's designMode feature, which turns an HTML document into a rich text editor field. Once turned into the editor, commands can run on the document through the execCommand command. Mozilla does not support Internet Explorer's contentEditable attribute for making any widget editable. You can use an iframe to add a rich text editor.

-

Rich text differences

-

Mozilla supports the W3C standard of accessing iframe's document object through IFrameElmRef.contentDocument, while Internet Explorer requires you to access it through document.frames{{ mediawiki.external('\"IframeName\"') }} and then access the resulting document:

-
<script>
-function getIFrameDocument(aID) {
-  var rv = null;
-
-  // if contentDocument exists, W3C compliant (Mozilla)
-  if (document.getElementById(aID).contentDocument){
-    rv = document.getElementById(aID).contentDocument;
-  } else {
-    // IE
-    rv = document.frames[aID].document;
-  }
-  return rv;
-}
-</script>
-
-

Another difference between Mozilla and Internet Explorer is the HTML that the rich text editor creates. Mozilla defaults to using CSS for the generated markup. However, Mozilla allows you to toggle between HTML and CSS mode using the useCSS execCommand and toggling it between true and false. Internet Explorer always uses HTML markup.

-
Mozilla (CSS):
-  <span style="color: blue;">Big Blue</span>
-
-Mozilla (HTML):
-  <font color="blue">Big Blue</font>
-
-Internet Explorer:
-  <FONT color="blue">Big Blue</FONT>
-
-

Below is a list of commands that execCommand in Mozilla supports:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 6. Rich text editing commands
Command NameDescriptionArgument
boldToggles the selection's bold attribute.---
createlinkGenerates an HTML link from the selected text.The URL to use for the link
deleteDeletes the selection.---
fontnameChanges the font used in the selected text.The font name to use (Arial, for example)
fontsizeChanges the font size used in the selected text.The font size to use
fontcolorChanges the font color used in the selected text.The color to use
indentIndents the block where the caret is.---
inserthorizontalruleInserts an <hr> element at the cursor's position.---
insertimageInserts an image at the cursor's position.URL of the image to use
insertorderedlistInserts an ordered list (<ol>) element at the cursor's position.---
insertunorderedlistInserts an unordered list (<ul>) element at the cursor's position.---
italicToggles the selection's italicize attribute.---
justifycenterCenters the content at the current line.---
justifyleftJustifies the content at the current line to the left.---
justifyrightJustifies the content at the current line to the right.---
outdentOutdents the block where the caret is.---
redoRedoes the previous undo command.---
removeformatRemoves all formatting from the selection.---
selectallSelects everything in the rich text editor.---
strikethroughToggles the strikethrough of the selected text.---
subscriptConverts the current selection into subscript.---
superscriptConverts the current selection into superscript.---
underlineToggles the underline of the selected text.---
undoUndoes the last executed command.---
unlinkRemoves all link information from the selection.---
useCSSToggles the usage of CSS in the generated markup.Boolean value
-

For more information, visit Rich-Text Editing in Mozilla.

-

XML differences

-

Mozilla has strong support for XML and XML-related technologies, such as XSLT and Web services. It also supports some non-standard Internet Explorer extensions, such as XMLHttpRequest.

-

How to handle XML

-

As with standard HTML, Mozilla supports the W3C XML DOM specification, which allows you to manipulate almost any aspect of an XML document. Differences between Internet Explorer's XML DOM and Mozilla are usually caused by Internet Explorer's nonstandard behaviors. Probably the most common difference is how they handle white space text nodes. Often when XML generates, it contains white spaces between XML nodes. Internet Explorer, when using Node.childNodes, will not contain these white space nodes. In Mozilla, those nodes will be in the array.

-
XML:
-  <?xml version="1.0"?>
-  <myXMLdoc xmlns:myns="http://myfoo.com">
-    <myns:foo>bar</myns:foo>
-  </myXMLdoc>
-
-JavaScript:
-  var myXMLDoc = getXMLDocument().documentElement;
-  alert(myXMLDoc.childNodes.length);
-
-

The first line of JavaScript loads the XML document and accesses the root element (myXMLDoc) by retrieving the documentElement. The second line simply alerts the number of child nodes. Per the W3C specification, the white spaces and new lines merge into one text node if they follow each other. For Mozilla, the myXMLdoc node has three children: a text node containing a new line and two spaces; the myns:foo node; and another text node with a new line. Internet Explorer, however, does not abide by this and will return "1" for the above code, namely only the myns:foo node. Therefore, to walk the child nodes and disregard text nodes, you must distinguish such nodes.

-

As mentioned earlier, every node has a nodeType property representing the node type. For example, an element node has type 1, while a document node has type 9. To disregard text nodes, you must check for types 3 (text node) and 8 (comment node).

-
XML:
-  <?xml version="1.0"?>
-  <myXMLdoc xmlns:myns="http://myfoo.com">
-    <myns:foo>bar</myns:foo>
-  </myXMLdoc>
-
-JavaScript:
-  var myXMLDoc = getXMLDocument().documentElement;
-  var myChildren = myXMLDoc.childNodes;
-
-  for (var run = 0; run < myChildren.length; run++){
-    if ( (myChildren[run].nodeType != 3) &&
-          myChildren[run].nodeType != 8) ){
-      // not a text or comment node
-    };
-  };
-
-

See Whitespace in the DOM for more detailed discussion and a possible solution.

-

XML data islands

-

Internet Explorer has a nonstandard feature called XML data islands, which allow you to embed XML inside an HTML document using the nonstandard HTML tag <xml>. Mozilla does not support XML data islands and handles them as unknown HTML tags. You can achieve the same functionality using XHTML; however, because Internet Explorer's support for XHTML is weak, this is usually not an option.

-

IE XML data island:

-
<xml id="xmldataisland">
-  <foo>bar</foo>
-</xml>
-
-

One cross-browser solution is to use DOM parsers, which parse a string that contains a serialized XML document and generates the document for the parsed XML. Mozilla uses the DOMParser object, which takes the serialized string and creates an XML document out of it. In Internet Explorer, you can achieve the same functionality using ActiveX. The object created using new ActiveXObject("Microsoft.XMLDOM") has a loadXML method that can take in a string and generate a document from it. The following code shows you how:

-
var xmlString = "<xml id=\"xmldataisland\"><foo>bar</foo></xml>";
-var myDocument;
-
-if (window.DOMParser) {
-  // This browser appears to support DOMParser
-  var parser = new DOMParser();
-  myDocument = parser.parseFromString(xmlString, "text/xml");
-} else if (window.ActiveXObject){
-  // Internet Explorer, create a new XML document using ActiveX
-  // and use loadXML as a DOM parser.
-  myDocument = new ActiveXObject("Microsoft.XMLDOM");
-  myDocument.async = false;
-
-  myDocument.loadXML(xmlString);
-} else {
-  // Not supported.
-}
-
-

See Using XML Data Islands in Mozilla for an alternative approach.

-

XMLHttpRequest

-

Internet Explorer allows you to send and retrieve XML files using MSXML's XMLHTTP class, which is instantiated through ActiveX using new ActiveXObject("Msxml2.XMLHTTP") or new ActiveXObject("Microsoft.XMLHTTP"). Since there is no standard method of doing this, Mozilla provides the same functionality in the global JavaScript XMLHttpRequest object. Since version 7 IE also supports the "native" XMLHttpRequest object.

-

After instantiating the object using new XMLHttpRequest(), you can use the open method to specify what type of request (GET or POST) you use, which file you load, and if it is asynchronous or not. If the call is asynchronous, then give the onload member a function reference, which is called once the request has completed.

-

Synchronous request:

-
var myXMLHTTPRequest = new XMLHttpRequest();
-myXMLHTTPRequest.open("GET", "data.xml", false);
-
-myXMLHTTPRequest.send(null);
-
-var myXMLDocument = myXMLHTTPRequest.responseXML;
-
-

Asynchronous request:

-
var myXMLHTTPRequest;
-
-function xmlLoaded() {
-  var myXMLDocument = myXMLHTTPRequest.responseXML;
-}
-
-function loadXML(){
-  myXMLHTTPRequest = new XMLHttpRequest();
-  myXMLHTTPRequest.open("GET", "data.xml", true);
-  myXMLHTTPRequest.onload = xmlLoaded;
-  myXMLHTTPRequest.send(null);
-}
-
-

Table 7 features a list of available methods and properties for Mozilla's XMLHttpRequest.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 7. XMLHttpRequest methods and properties
NameDescription
void abort()Stops the request if it is still running.
string getAllResponseHeaders()Returns all response headers as one string.
string getResponseHeader(string headerName)Returns the value of the specified header.
functionRef onerrorIf set, the references function will be called whenever an error occurs during the request.
functionRef onloadIf set, the references function will be called when the request completes successfully and the response has been received. Use when an asynchronous request is used.
void open (string HTTP_Method, string URL)
-
- void open (string HTTP_Method, string URL, boolean async, string userName, string password)
Initializes the request for the specified URL, using either GET or POST as the HTTP method. To send the request, call the send() method after initialization. If async is false, the request is synchronous, else it defaults to asynchronous. Optionally, you can specify a username and password for the given URL needed.
int readyStateState of the request. Possible values: - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ValueDescription
0UNINITIALIZED - open() has not been called yet.
1LOADING - send() has not been called yet.
2LOADED - send() has been called, headers and status are available.
3INTERACTIVE - Downloading, responseText holds the partial data.
4COMPLETED - Finished with all operations.
-
string responseTextString containing the response.
DOMDocument responseXMLDOM Document containing the response.
void send(variant body)Initiates the request. If body is defined, it is sent as the body of the POST request. body can be an XML document or a string serialized XML document.
void setRequestHeader (string headerName, string headerValue)Sets an HTTP request header for use in the HTTP request. Has to be called after open() is called.
string statusThe status code of the HTTP response.
-

XSLT differences

-

Mozilla supports XSL Transformations (XSLT) 1.0. It also allows JavaScript to perform XSLT transformations and allows running XPath on a document.

-

Mozilla requires that you send the XML and XSLT files with an XML mimetype (text/xml or application/xml). This is the most common reason why XSLT won't run in Mozilla but will in Internet Explorer. Mozilla is strict in that way.

-

Internet Explorer 5.0 and 5.5 supported XSLT's working draft, which is substantially different than the final 1.0 recommendation. The easiest way to distinguish what version an XSLT file was written against is to look at the namespace. The namespace for the 1.0 recommendation is http://www.w3.org/1999/XSL/Transform, while the working draft's namespace is http://www.w3.org/TR/WD-xsl. Internet Explorer 6 supports the working draft for backwards compatibility, but Mozilla does not support the working draft, only the final recommendation.

-

If XSLT requires you to distinguish the browser, you can query the "xsl:vendor" system property. Mozilla's XSLT engine will report itself as "Transformiix" and Internet Explorer will return "Microsoft".

-
<xsl:if test="system-property('xsl:vendor') = 'Transformiix'">
-  <!-- Mozilla specific markup -->
-</xsl:if>
-<xsl:if test="system-property('xsl:vendor') = 'Microsoft'">
-  <!-- Internet Explorer specific markup -->
-</xsl:if>
-
-

Mozilla also provides JavaScript interfaces for XSLT, allowing a Web site to complete XSLT transformations in memory. You can do this using the global XSLTProcessor JavaScript object. XSLTProcessor requires you to load the XML and XSLT files, because it needs their DOM documents. The XSLT document, imported by the XSLTProcessor, allows you to manipulate XSLT parameters.

-

XSLTProcessor can generate a standalone document using transformToDocument(), or it can create a document fragment using transformToFragment(), which you can easily append into another DOM document. Below is an example:

-
var xslStylesheet;
-var xsltProcessor = new XSLTProcessor();
-
-// load the xslt file, example1.xsl
-var myXMLHTTPRequest = new XMLHttpRequest();
-myXMLHTTPRequest.open("GET", "example1.xsl", false);
-myXMLHTTPRequest.send(null);
-
-// get the XML document and import it
-xslStylesheet = myXMLHTTPRequest.responseXML;
-
-xsltProcessor.importStylesheet(xslStylesheet);
-
-// load the xml file, example1.xml
-myXMLHTTPRequest = new XMLHttpRequest();
-myXMLHTTPRequest.open("GET", "example1.xml", false);
-myXMLHTTPRequest.send(null);
-
-var xmlSource = myXMLHTTPRequest.responseXML;
-
-var resultDocument = xsltProcessor.transformToDocument(xmlSource);
-
-

After creating an XSLTProcessor, you load the XSLT file using XMLHttpRequest. The XMLHttpRequest's responseXML member contains the XML document of the XSLT file, which is passed to importStylesheet. You then use the XMLHttpRequest again to load the source XML document that must be transformed; that document is then passed to the transformToDocument method of XSLTProcessor. Table 8 features a list of XSLTProcessor methods.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 8. XSLTProcessor methods
MethodDescription
void importStylesheet(Node styleSheet)Imports the XSLT stylesheet. The styleSheet argument is the root node of an XSLT stylesheet's DOM document.
DocumentFragment transformToFragment(Node source, Document owner)Transforms the Node source by applying the stylesheet imported using the importStylesheet method and generates a DocumentFragment. owner specifies what DOM document the DocumentFragment should belong to, making it appendable to that DOM document.
Document transformToDocument(Node source)Transforms the Node source by applying the stylesheet imported using the importStylesheet method and returns a standalone DOM document.
void setParameter(String namespaceURI, String localName, Variant value)Sets a parameter in the imported XSLT stylesheet.
Variant getParameter(String namespaceURI, String localName)Gets the value of a parameter in the imported XSLT stylesheet.
void removeParameter(String namespaceURI, String localName)Removes all set parameters from the imported XSLT stylesheet and makes them default to the XSLT-defined defaults.
void clearParameters()Removes all set parameters and sets them to defaults specified in the XSLT stylesheet.
void reset()Removes all parameters and stylesheets.
-
-

Original Document Information

- -
-

 

diff --git a/files/zh-cn/mmgc/index.html b/files/zh-cn/mmgc/index.html deleted file mode 100644 index 5389541ea5..0000000000 --- a/files/zh-cn/mmgc/index.html +++ /dev/null @@ -1,476 +0,0 @@ ---- -title: MMgc -slug: MMgc -translation_of: Archive/MMgc ---- -

MMgc is the Tamarin (née Macromedia) garbage collector, a memory management library that has been built as part of the AVM2/Tamarin effort. It is a static library that is linked into the Flash Player but kept separate, and can be incorporated into other programs.

-

Using MMgc

-

Managed vs. Unmanaged Memory

-

MMgc is not only a garbage collector, but a general-purpose memory manager. The Flash Player uses it for nearly all memory allocations.

-

MMgc can handle both managed and unmanaged memory.

-

Managed memory is memory that is reclaimed automatically by the garbage collector. The garbage collector is "managing" it, detecting when the memory is no longer reachable from anywhere in the application and reclaiming it at that time. In MMgc, you get managed memory by subclassing GCObject/GCFinalizedObject/RCObject, or by calling GC::Alloc.

-

Unmanaged memory is everything else. This is C++ memory management as you're accustomed to it. Memory can be allocated with the new operator, and must be explicitly deleted in your C++ code at some later time using the delete operator.

-

Another way to think about it:

- -

MMgc contains a page allocator called GCHeap, which allocates large blocks (megabytes) of memory from the system and doles out 4KB pages to the unmanaged memory allocator (FixedMalloc) and the managed memory allocator (GC).

-

MMgc namespace

-

The MMgc library is in the C++ namespace MMgc.

-

You can qualify references to classes in the library; for example: MMgc::GC, MMgc::GCFinalizedObject.

-

Alternately, you can open the MMgc namespace in your C++ source so that you can refer to the objects more concisely:

-
 using namespace MMgc;
- ...
- GC* gc = GC::GetGC(this);
- GCObject* gcObject;
-
-

GC class

-

The class MMgc::GC is the main class of the GC. It represents a full, self-contained instance of the garbage collector.

-

It may be multiply instantiated; you may have multiple instances of the garbage collector running at once.  Each instance manages its own set of objects; objects are not allowed to reference objects in other GC instances.

-

The GC typically is constructed early in your program's initialization, and then passed to operations like operator new for allocating GC objects.

-

There are a few methods that you may need to call directly, such as Alloc and Free.

-

GC::Alloc, GC::Free

-

The Alloc and Free methods are garbage-collected analogs for malloc and free. Memory allocated with Alloc doesn't need to be explicitly freed, although it can be freed with Free if it is known that there are no other references to it.

-

Alloc is often used to allocate arrays and other objects of variable size that contain GC pointers or are otherwise desirable to have in managed memory.

-

These flags may be passed to Alloc to control the allocation type.

-
/**
-* flags to be passed as second argument to alloc
-*/
-enum AllocFlags
-{
-  kZero=1,
-  kContainsPointers=2,
-  kFinalize=4,
-  kRCObject=8
-};
-
-

kZero zeros out the memory. Otherwise, the memory contains undefined values.

-

kContainsPointers indicates to the GC that the memory will contain pointers to other GC objects, and thus needs to be scanned by the GC's mark phase. If you know for certain that the objects will not contain GC pointers, leave this flag off; it will make the mark phase faster by excluding your object.

-

kFinalize and kRCObject are used internally by the GC; you should not need to set them in your user code.

-

GC::GetGC

-

Given the pointer to any GCObject, it is possible to get a pointer to the GC object that allocated it.

-
void GCObject::Method() {
-  GC* gc = MMgc::GC::GetGC(this);
-  ...
-}
-
-

This practice should be used sparingly, but is sometimes useful.

-

Base Classes

-

GCObject

-

A basic garbage collected object.

- -
class MyObject : public MMgc::GCObject { ... };
-MyObject* myObject = new (gc) MyObject();
-
- -
class MyUnmanagedObject : public MMgc::GCRoot {
- MyObject *object;
-};
-
- -
class MyOtherManagedObject : public MMgc::GCObject {
- DWB(MyObject*) object;
-};
-
- -
// Optimization: Get rid of myObject now, because we know there are no other
-// references, so no need to wait for GC to clean it up.
-delete myObject;
-
- -
class MyObject : public MMgc::GCObject {
- ~MyObject() { assert(!"this will never be hit (unless we also descend from GCFinalizedObject)"); }
-};
-
-
GCObject::GetWeakRef
-
GCWeakRef *GetWeakRef() const;
-
-

The GetWeakRef method returns a weak reference to the object. Normally, a pointer to the object is considered a hard reference -- any such reference will prevent the object from being destroyed. Sometimes, it is desirable to hold a pointer to a GCObject, but to let the object be destroyed if there are no other references. GCWeakRef can be used for this purpose. It has a get method which returns the pointer to the original object, or NULL if that object has already been destroyed.

-

GCFinalizedObject

-

Base class: GCObject

-

A garbage collected object with finalization support.

-

All of the rules from GCObject above apply to GCFinalizedObject.

-

The finalizer (C++ destructor) of a GCFinalizedObject will be invoked when MMgc collects the object.

-
class MyFinalizedObject : public MMgc::GCFinalizedObject
-{
-public:
-  ~MyFinalizedObject()
-  {
-    // Do finalization behavior, like closing network connections,
-    // freeing unmanaged memory owned by this object, etc.
-  }
-};
-
-

RCObject

-

Base class: GCFinalizedObject

-

This is a reference-counted, garbage collected object.

-

RCObject is used instead of GCObject when more immediate reclamation of memory is desired. For instance, the avmplus::String class in AVM+ is a RCObject. Strings are created very frequently, and are often temporary objects with very short lifetimes. By making them RCObjects, the GC is able to reclaim them much faster and limit memory growth.

-

All of the rules for GCObject apply to RCObject, and there are a few more:

- -
class MyObject : public MMgc::RCObject { ... };
-class MyUnmanagedObject : public MMgc::GCRoot {
-  DRC(MyObject*) myObject;
-};
-
- -
class MyObject : public MMgc::RCObject { ... };
-class MyOtherManagedGCObject : public MMgc::GCObject {
-  DRCWB(MyObject*) myObject;
-};
-class MyOtherManagedRCObject : public MMgc::RCObject {
-  DRCWB(MyObject*) myObject;
-};
-
- -
class MyObject : public MMgc::RCObject {
-public:
- MyObject() { x = 1; y = 2; z = 3; }
- ~MyObject() { x = y = z = 0; }
-private:
- int x;
- int y;
- int z;
-};
-
-

 

-

GCRoot

-

If you have a pointer to a GCObject from an object in unmanaged memory, the unmanaged object must be a subclass of GCRoot.

-

GCRoot must be subclassed by any unmanaged memory class that holds GC pointers.

-
class MyGCObject : public MMgc::GCObject { ... };
-class MyGCRoot : public MMgc::GCRoot {
- MyGCObject* myGCObject;
-};
-
-

Note that a GCRoot is NOT a garbage-collected object. It is an unmanaged memory object that contains GC pointers.

-

MMgc keeps a list of all GCRoots in the system and makes sure that it marks them. GCRoots are generally expected to be allocated using MMgc's unmanaged memory allocators, so that MMgc can figure out how big the GCRoot object is.

-

Use of GCRoot is required to have GC pointers from unmanaged memory, since without GCRoot, those pointers won't be marked by the mark phase of the GC.

-

Note that GCRoot can be used either by subclassing, or by creating a GCRoot and passing it the memory locations to treat as a root:

-
/** subclassing constructor */
-GCRoot(GC *gc);
-/** general constructor */
-GCRoot(GC *gc, const void *object, size_t size);
-
-

Allocating objects

-

Allocating unmanaged objects is as simple as using global operator new/delete, the same way you always have.

-

To allocate a managed (GC) object, you must use the parameterized form of operator new, and pass it a reference to the MMgc::GC object.

-
class MyObject : public MMgc::GCObject { ... };
-...
-MyObject* myObject = new (gc) MyObject();
-
-

DWB/DRC/DRCWB

-

There are several smart pointer templates which must be used in your C++ code to work properly with MMgc.

-

DWB

-

DWB stands for Declared Write Barrier.

-

It must be used on a pointer to a GCObject/GCFinalizedObject, when that pointer is a member variable of a class derived from GCObject/GCFinalizedObject/RCObject/RCFinalizedObject.

-
class MyManagedClass : public MMgc::GCObject
-{
-  // MyManagedClass is a GCObject, and
-  // avmplus::Hashtable is a GCObject, so use DWB
-  DWB(avmplus::Hashtable*) myTable;
-};
-
-

DRC

-

DRC stands for Deferred Reference Counted.

-

It must be used on a pointer to a RCObject/RCFinalizedObject, when that pointer is a member variable of a C++ class in unmanaged memory.

-
class MyUnmanagedClass
-{
-  // MyUnmanagedClass is not a GCObject, and
-  // avmplus::Stringp is a RCObject, so use DRC
-  DRC(Stringp) myString;
-};
-
-

DRCWB

-

DRCWB stands for Deferred Reference Counted, with Write Barrier.

-

It must be used on a pointer to a RCObject/RCFinalizedObject, when that pointer is a member variable of a class derived from GCObject/GCFinalizedObject/RCObject/RCFinalizedObject.

-
class MyManagedClass : public MMgc::GCObject
-{
-  // MyManagedClass is a GCObject, and
-  // avmplus::Stringp is a RCObject, so use DRCWB
-  DRCWB(Stringp) myString;
-};
-
-

When are the macros not needed?

-

Write barriers are not needed for stack-based local variables, regardless of whether the object pointed to is GCObject, GCFinalizedObject, RCObject or RCFinalizedObject. The GC marks the entire stack during collection, and not incrementally, so write barriers aren't needed.

-

Write barriers are not needed for pointers to GC objects from unmanaged memory (GCRoot). GCRoots are marked at the end of the mark phase, and not incrementally, so no write barriers are required. DRC() is required for RC objects, since the reference count must be maintained.

-

Write barriers are not needed for C++ objects that exist purely on the stack, and never in the heap. The Flash Player class "NativeInfo" is a good example. Such objects are essentially the same as stack-based local variables.

-

Zeroing RCObjects

-

All RCObjects (including all subclasses) must zero themselves out completely upon destruction. Asserts enforce this. The reason is that our collector zeroes memory upon free and this was hurting performance. Since MMgc must traverse objects to decrement refcounts properly upon destruction, I just made destructors do zeroing too. This mostly applies to non-pointer fields as DRCWB smart pointers do this for you.

-

Poisoned Memory

-

In DEBUG builds, MMgc writes "poison" into deallocated memory as a debugging aid. Here's what the different poison values mean:

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
0xfafafafaUninitialized unmanaged memory
0xededededUnmanaged memory that was freed explicitly
0xbabababaManaged memory that was freed by the Sweep phase of the garbage collector
0xcacacacaManaged memory that was freed by an explicit call to GC::Free (including DRC reaping)
0xdeadbeefThis is written to the 4 bytes just after any object allocated via MMgc. It is used for overwrite detection.
0xfbfbfbfbA block given back to the heap manager is memset to this (fb == free block).
-

Finalizers

-

If your C++ class is a subclass of GCFinalizedObject or RCFinalizedObject, it has finalizer support.

-

A finalizer is a method which will be invoked by the GC when an unreachable object is about to be destroyed.

-

It's similar to a destructor. It differs from a destructor in that it is usually called nondeterministically, i.e. in whatever random order the GC decides to destroy objects. C++ destructors are usually invoked in a comparatively predictable order, since they're invoked explicitly by the application code.

-

In MMgc, the C++ destructor is actually used as the finalizer.

-

If you don't subclass GCFinalizedObject or RCFinalizedObject, any C++ destructor on your garbage collected class will basically be ignored. Only if you subclass GCFinalizedObject or RCFinalizedObject will MMgc know that you want finalization behavior on your class.

-

It's best to avoid finalizers if you can, since finalization behavior can be unpredictable and nondeterministic, and also slows down the GC since the finalizers need to be invoked.

-

Finalizer Access Rules

-

Finalizers are very restricted in the set of objects they may access. Finalizers may not perform any of the following actions:

- -

If a finalized object holds a reference to an RCObject, it may safely call decrementref on the RCObject.

-

Threading

-

The GC routines are not currently thread safe, we're operating under the assumption that none of the player spawned threads create GC'd things. If this isn't true we hope to eliminate other threads from doing this and if we can't do that we will be forced to make our GC thread safe, although we hope we don't have to do that.

-

Threading gets more complicated because it makes sense to re-write ChunkMalloc and ChunkAllocBase to get their blocks from the GCHeap. They can also take advantage of the 4K boundary to eliminate the 4 byte per allocation penalty.

-

Troubleshooting MMgc

-

Dealing with bugs

-

GC bugs are hard.

-

Forgetting a write barrier

-

If you forget to put a write barrier on a pointer, the incremental mark process might miss the pointer being changed. The result will be an object that your code has a pointer to, but which the GC thinks is unreachable. The GC will destroy the object, and later you will crash with a dangling pointer.

-

When you crash with what looks like a dangling pointer to a GC object, check for missing write barriers in the vicinity.

-

Forgetting a DRC

-

If you forget to put a DRC macro on a pointer to an RCObject from unmanaged memory, you can get a dangling pointer. The reference count of the object may go to zero, and the object will be placed in the ZCT. Later, the ZCT will be reaped and the object will be destroyed. But you still have a pointer to it. When you dereference the pointer later, you'll crash with a dangling pointer.

-

When you crash with what looks like a dangling pointer to a RC object, look at who refers to the object. See if there are missing DRC macros that need to be put in.

-

Wrong macro

-

If you put DWB instead of DRCWB, you'll avoid dangling pointer issues from a missing write barrier, but you might hit dangling pointer issues from a zero reference count.

-

If you crash with a dangling pointer to a RC object, check for DWB macros that need to be DRCWB.

-

Unmarked unmanaged memory

-

If you have pointers to GC objects in your unmanaged memory objects, the unmanaged objects need to be GCRoots.

-

GCRoots are known to the GC and will be marked during a collection. Pointers must be marked for the GC to consider the objects "live"; otherwise, the objects will be considered unreachable and will be destroyed. And you'll be left with dangling pointers to these destroyed objects.

-

If you get a crash dereferencing a pointer to a GC object, and the pointer was a member variable in an unmanaged (non-GC) object, check whether the unmanaged object is a GCRoot. If it isn't, maybe it needs to be.

-

Finding missing write barriers

-

There are some automatic aids in the MMgc library which can help you find missing write barriers. Look in MMgc/GC.cpp.

-
// before sweeping we check for missing write barriers
-bool GC::incrementalValidation = false;
-
-
// check for missing write barriers at every Alloc
-bool GC::incrementalValidationPedantic = false;
-
-

If you suspect you have missing write barriers, turn these switches on in a DEBUG build. (The second switch will slow your application down a lot more than the first switch, so you could try the first, then the second.)

-

When a missing write barrier is detected, MMgc will assert and drop you into the debugger, and will print out a message telling you which object contained the missing write barrier, the address of the member variable that needs it, and what object didn't get marked due to the missing write barrier.

-

Sometimes, this missing write barrier detection will turn up a false positive. If you can't find anything wrong with the code, it might just be a false positive.

-

Debugging Aids

-

MMgc has several debugging aids that can be useful in your development work.

-

Underwrite/overwrite detection

-

MMgc can often detect when you write outside the boundaries of an object, and will throw an assert in debugging builds when this happens.

-

Leak detection (for unmanaged memory)

-

When the application is exiting, MMgc will detect memory leaks in its unmanaged memory allocators and print out the addresses and sizes of the leaked objects, and stack traces if stack traces are enabled.

-

Stack traces are enabled via the MMGC_MEMORY_PROFILER feature and setting the MMGC_PROFILE environment variable to 1.  The MMGC_MEMORY_PROFILER feature is implied by the debugger feature and is always on in DEBUG builds.

-

Deleted object poisoning and write detection

-

MMgc will "poison" memory for deleted objects, and will detect if the poison has been written over by the application, which would indicate a write to a deleted object.

-

Stack traces (walk stack frame and lookup IPs)

-

When #define MEMORY_INFO is on, MMgc will capture a stack trace for every object allocation. This slows the application down but can be invaluable when debugging. Memory leaks will be displayed with their stack trace of origin.

-

Sample stack trace:

-
xmlclass.cpp:391 toplevel.cpp:164 toplevel.cpp:507 interpreter.cpp:1098 interpreter.cpp:20 methodenv.cpp:47
-
-

Allocation traces, deletion traces etc.

-

If you're trying to see why memory is not getting reclaimed; GC::WhosPointingAtMe() can be called from the msvc debugger and will spit out objects that are pointing to the given memory location.

-

Memory Profiler

-

MMgc's memory profiler can display the state of your application's heap, showing the different classes of object in memory, along with object counts, byte counts, and percentage of total memory. It can also display stack traces for where every object was allocated. The report can be output to the console or to a file, and can be configured to be displayed pre/post sweep or via API call.

-

The Memory Profiler use sRTTI and stack traces to get information by location and type:

-
class avmplus::GrowableBuffer - 24.9% - 3015 kb 514 items, avg 6007b
-    98.9% - 2983 kb - 512 items - poolobject.cpp:29 abcparser.cpp:948 …
-    0.8%  -   24 kb -   1 items - poolobject.cpp:29 abcparser.cpp:948 …
-class avmplus::String - 13.2% - 1602 kb 15675 items, avg 104b
-    65.6% - 1051 kb - 14397 items - stringobject.cpp:46 avmcore.cpp:2300 …
-    20.4% -  326 kb - 10439 items - avmcore.cpp:2300 abcparser.cpp:1077 …
-    6.5%  -  103 kb -  3311 items - avmcore.cpp:2300 abcparser.cpp:1077 …
-
-

Other Profiling Tools

-

The gcstats flag on the GC object controls verbose output.  In the avmshell this is enable with the -memstats flag.  Output looks like this:

-
[mem] ------- gross stats -----
-[mem] private 5877 (23.0M) 100%
-[mem]    mmgc 5792 (22.6M) 98%
-[mem]            unmanaged 13 (52K) 0%
-[mem]            managed 2596 (10.1M) 44%
-[mem]            free 3081 (12.0M) 52%
-[mem]    jit 0 (0K) 0%
-[mem]    other 85 (340K) 1%
-[mem] bytes (interal fragmentation) 2527 (9.9M) 96%
-[mem]   managed bytes  2520 (9.8M) 97%
-[mem]   unmanaged bytes  7 (28K) 53%
-[mem] -------- gross stats end -----
-
-

Numbers are in pages (with M and K in parens).   Private is the number of private committed pages in the process, mmgc is the amount of memory GCHeap has asked for from the OS (not including JIT).   FixedMalloc vs. GC allocations are shown in the unmanaged vs. managed split.    Free is the amount of memory GCHeap is holding onto that isn't in use by the mutator.    Other is the delta between private and mmgc, it includes things like system malloc, stacks, loaded library data areas etc.   When this is enable this information is logged everytime we log something interesting.  So far something interesting means an incremental mark cycle, a sweep or a DRC reap.   They are logged like this:

-
[mem] sweep(21) reclaimed 910 whole pages (3640 kb) in 22.66 millis (2.4975 s)
-[mem] mark(1) 0 objects (180866 kb 205162 mb/s) in 0.88 millis (2.5195 s)
-[mem] DRC reaped 114040 objects (3563 kb) freeing 903 pages (7800 kb) in 17.41 millis (2.0015 s)
-
-

How MMgc works

-

Mark/Sweep

-

The MMgc garbage collector uses a mark/sweep algorithm. This is one of the most common garbage collection algorithms.

-

Every object in the system has an associated "mark bit."

-

A garbage collection is divided into two phases: Mark and Sweep.

-

In the Mark phase, all of the mark bits are cleared. The garbage collector is aware of "roots", which are starting points from which all "live" application data should be reachable. The collector starts scanning objects, starting at the roots and fanning outwards. For every object it encounters, it sets the mark bit.

-

When the Mark phase concludes, the Sweep phase begins. In the Sweep phase, every object that wasn't marked in the Mark phase is destroyed and its memory reclaimed. If an object didn't have its mark bit set during the Mark phase, that means it wasn't reachable from the roots anymore, and thus was not reachable from anywhere in the application code.

-

The following Flash animation illustrates the working of a mark/sweep collector:

-

(temporarily not working) <gflash>600 300 GC.swf</gflash>

-

One pass

-

The mark sweep algorithm described above decomposes into ClearMarks/Mark/Finalize/Sweep. In our original implementation ClearMarks/Finalize/Sweep visited every GC page and every object on that page. 3 passes! Now we have one pass where marks are cleared during sweep so clear marks isn't needed at the start. Also Finalize builds up a lists of pages that need sweeping so sweep doesn't need to visit every page. This has been shown to cut the Finalize/Sweep pause in half (which happens back to back atomically). Overall this wasn't a huge performance increase due to the fact the majority of our time is spent in the Mark phase.

-

Conservative Collection

-

MMgc is a conservative mark/sweep collector. Conservative means that it may not reclaim all of the memory that it is possible to reclaim; it will sometimes make a "conservative" decision and not reclaim memory that might've actually been free.

-

Why make the collector conservative? It simplifies writing C++ application code to run on top of the collector. The alternative to conservative collection is exact collection. To do exact colllection, every C++ class and variable would need to specify exactly which variable contained a GC pointer or not. This is a lot to ask from our C++ developers, so instead, MMgc assumes that every memory location might potentially contain a GC pointer.

-

That means that it might occasionally turn up a "false positive." A false positive is a memory location that looks like it contains a pointer to a GC object, but it's really just some JPEG image data or an integer variable or some other unrelated data. When the GC encounters a false positive, it has to assume that it MIGHT be a pointer since it doesn't have an exact description of whether that memory is a pointer or not. So, the not-really-pointed-to object will be leaked.

-

Memory leaks don't sound like an OK thing, right? Well, memory leaks that result from programmer error tend to be bad leaks... leaks that grow over time. With such a leak, you can be pushing hundreds of megabytes of RAM real quick. With a conservative GC, the leaks tend to be random, such that they don't grow over time. The occasional random leak from a false positive can be OK. That doesn't mean we shouldn't worry about it at all, but often conservative GC suffices.

-

It is possible that a future version of MMgc might do exact marking. This would be needed for a generational collector.

-

Deferred Reference Counting (DRC)

-

MMgc uses Deferred Reference Counting (DRC). DRC is a scheme for getting more immediate reclamation of objects, while still achieving high performance and getting the other benefits of garbage collection.

-

Classic Reference Counting

-

Previous versions of the Flash Player, up to Flash Player 7, used reference counting to track object lifetimes.

-
class Object
-{
-public:
-  Object() { refCount = 0; }
-  void AddRef() { refCount++; }
-  void Release() {
-    if (!--refCount) delete this;
-  }
-  int refCount;
-}
-
-

Reference counting is a kind of automatic memory management. Reference counting can track relationships between objects, and as long as AddRef and Release are called at the proper times, can reclaim memory from objects that are no longer referenced.

-

Problem: Circular References

-

Reference counting falls down when circular references occur in objects. If object A and object B are reference counted and refer to each other, their reference counts will both be nonzero even if no other objects in the system point to them. Locked in this embrace, they will never be destroyed.

-

Image:Tamarin-MMGC-CircularReferences.png

-

This is where garbage collection helps. Mark/sweep garbage collection can detect that these objects containing circular references are really not reachable from anywhere else in the application, and can reclaim them.

-

The problem with going from reference counting to pure mark/sweep garbage collection is that a lot of time may be spent in the garbage collector. This time will pause the entire application, and give the impression of poor performance. Even with an incremental collector that doesn't have big pauses, a GC sweep only kicks in every so often, so memory usage can grow very quickly to a high peak before the GC collects unused objects.

-

So, some kind of reference counting is still attractive to lower the amount of work the GC has to do, and to get more immediacy on memory reclamation.

-

However, reference counting is also slow because the reference counts need to be constantly maintained. So, it's attractive to find some form of reference counting that doesn't require maintaining reference counts for every single reference.

-

Enter Deferred Reference Counting

-

In Deferred Reference Counting, a distinction is made between heap and stack references.

-

Stack references to objects tend to be very temporary in nature. Stack frames come and go very quickly. So, performance can be gained by not performing reference counting on the stack references.

-

Heap references are different since they can persist for long periods of time. So, in a DRC scheme, we continue to maintain reference counts in heap-based objects. So, reference counts are only maintained to heap-to-heap references.

-

We basically ignore the stack and registers. They are considered stack memory.

-

Zero Count Table

-

Of course, when an object's reference count goes to zero, what happens? If the object was immediately destroyed, that could leave dangling pointers on the stack, since we didn't bump up the object's reference count when stack references were made to it.

-

To deal with this, there is a mechanism called the Zero Count Table (ZCT).

-

When an object reaches zero reference count, it is not immediately destroyed; instead, it is put in the ZCT.

-

When the ZCT is full, it is "reaped" to destroy some objects.

-

If an object is in the ZCT, it is known that there are no heap references to it. So, there can only be stack references to it. MMgc scans the stack to see if there are any stack references to ZCT objects. Any objects in the ZCT that are NOT found on the stack are deleted.

-

Incremental Collection

-

The Flash Player is frequently used for animations and video that must maintain a certain framerate to play properly. Applications are also getting larger and larger and consuming more memory with scripting giving way to full fledged application component models (ala Flex). Unfortunately the flash player suffers a periodic pause (at least every 60 seconds) due to garbage collection requirements that may cause unbounded pauses (the GC pause is proportional to the amount of memory the application is using). One way to avoid this unbounded pause is to break up the work the GC needs to do into "increments".

-

In order to collect garbage we must trace all the live objects and mark them. This is the part of the GC work that takes the most time and the part that needs to be incrementalized. In order to incrementalize marking it needs to be a process that can be stopped and started. Our marking algorithm is a conservative marking algorithm that makes marking automatic, there are no Mark() methods the GC engine needs to call, marking is simply a tight loop that processes a queue. The way it works is that all GC roots are registered with the GC library and it can mark everything by traversing the roots. At the beginning all the GC roots are pushed onto the work queue. Items on the queue are conservatively marked and unmarked GC pointers discovered while processing each item are pushed on to the queue. When the queue is empty all the marking is complete. Thus the queue itself is a perfect way to maintain marking state between marking increments. This isn't an accident, the GC system was in part designed this way so that it could be easily incrementalized.

-

The problem then becomes:

-
    -
  1. How to account for the fact that the mutator is changing the state of the heap between marking increments
  2. -
  3. How much time to spend marking in each increment
  4. -
-

Mark consistency

-

A correct collector never deletes a live object (duh). In order to be correct we must account for a new or unmarked object being stored into an object we've already marked. In implementation terms this means a new or unmarked object is stored in an object that has already been processed by the marking algorithm and is no longer in the queue. Unless we do something we will delete this object and leave a dangling pointer to it in its referent.

-

There are a couple different techniques for this, but the most popular one based on some research uses a tri-color algorithm with write barriers. Every object has 3 states: black, gray and white.

- - - - - - - - - - - - - - - -
Image:Tamarin-MMGC-Gcblack.pngBlack means the object has been marked and is no longer in the work queue
Image:Tamarin-MMGC-Gcgray.pngGray means the object is in the work queue but not yet marked
Image:Tamarin-MMGC-Gcwhite.pngWhite means the object isn't in the work queue and hasn't been marked
-

The first increment will push all the roots on to the queue, thus after this step all the roots are gray and everything else is white. As the queue is processed all live objects go through two steps, from gray to black and white to gray. Whenever a pointer to a white object is written to a black object we have to intercept that write and remember to go back and put the white object in the work queue, that's what a write barrier does. The other scenarios we don't care about:

-
    -
  1. Gray written to Black/Gray/White - since the object is gray its on the queue and will be marked before we sweep
  2. -
  3. White written to Gray - the white object will be marked as reachable when the gray object is marked
  4. -
  5. White written to White - the referant will either eventually become gray if its reachable or not in which case both objects will get marked
  6. -
  7. Black written to Black/Gray/White - its black, its already been marked
  8. -
-

So a write barrier needs to be inserted anywhere we could possibly store a pointer to a white object into a black object. In practice this means:

-
    -
  1. Setting a property on an object to another object (creating an arch in the reachabilty graph)
  2. -
  3. Native code that writes a pointer to a GC object into another GC object
  4. -
  5. Writing an object to a GC root
  6. -
-

1 and 2 are pretty well isolated. 1 is the SetSlot method in the AVM- and some assembly code in the AVM+. #2 can be found by examining all non-const methods of GC objects (and making all fields private, something the AVM+ code base does already). #3 is a little harder because there are a good # of GC roots. This is an unfortunate artifact of the existing code base, the AVM+ is relatively clean and its reachability graph consists of basically 2 GC roots (the AvmCore and URLStreams) but the AVM- has a bunch (currently includes SecurityCallbackData, MovieClipLoader, CameraInstance, FAPPacket, MicrophoneInstance, CSoundChannel, URLRequest, ResponceObject, URLStream and UrlStreamSecurity). In order to make things easier we could avoid WB's for #3 by marking the root set twice. The first increment pushes the root set on to the queue and when the queue is empty we process the root set again, this second root set processing should very fast since the majority of objects should already be marked and the root set is usually small (marked objects are ignored and not pushed on to the work queue). This would mean that developers would only have to take into account #2 really when writing new code.

-

Illustration of Write Barriers

-

The following Flash animation demonstrates how a write barrier works.

-

(temporarily not working) <gflash>600 300 GC2.swf</gflash>

-

Detecting missing Write Barriers

-

To make sure that we injected write barriers into all the right places we plan on implementing a debug mode that will search for missing write barriers. The signature of a missing write barrier is a black to white pointer that exists right before we sweep, after the sweep the pointer will point to deleted memory. Also we can check throughout the incremental mark by making sure any black -> white pointers have been recorded by the write barrier. Furthermore we can run this check even more frequently than every mark increment, for instance every time our GC memory allocators request a new block from our primary allocator (the way our extremely helpful greedy collection mode works). This would of course be slow but with good code coverage should be capable of finding all missing write barriers. Only checking for missing write barriers before every sweep will probably be a small enough performance impact to enable it in DEBUG builds. The more frequent ones will have to be turned on manually.

-

Write Barrier Implementation

-

There are a couple options for implementing write barriers. At the finest level of granularity everytime a a white object is written to a black object we push the white object onto the work queue (thus making it grey). Another solution is to put the black object on the work queue, thus if multiple writes occur to the black object we only needed one push on the the queue. This could be a significant speedup if the black object was a large array getting populated with a bunch of new objects. On the other hand if the black is a huge array and only a couple slots had new objects written to them we are wasting time by marking the whole thing.

-

A popular solution to this is what's called card marking. Here you divide memory into "cards" and when a white object is written to a black object you mark the card containing the slot the pointer to the white object was written to. After all marking is done you circle back and remark the black portion of any card that was flagged by the write barrier. There are two techniques to optimize this process. One is to save all the addresses of all pages that had cards marked (so you don't have to bring every page into memory to check its hand, so to speak). Another option is to check every page while doing the normal marking and it any of its cards where flagged handle them immediately since your already reading/writing from that page. The result will be at the end of the mark cycle fewer things need to be marked. These two optimizations can be combined.

-

Increment Time Slice

-

Before diving into the this it should be acknowledged that another way to go about this is to use a background thread and not worry about incremental marking. This approach was not chosen for the following reasons:

-
    -
  1. Coordinating the marking thread and the main thread will require locking and may suffer due to lock overhead/contention
  2. -
  3. Supporting Mac classic's cooperative threads makes this approach harder
  4. -
  5. Flash's frame based architecture gives us a very natural place to do this work
  6. -
  7. We have better control over how much time is spent marking without threads
  8. -
-

When SMP systems become more prevalent it may be worth investigating this approach because true parallelism may afford better performance.

-

Another point to consider is whether marking should always be on or should be turned on and off at some point based on memory allocation patterns. I think we want the later because:

-
    -
  1. All WB's take the fast path when we're not marking, so the more time we spend out of the marking phase the better performance will be overall
  2. -
  3. Applications that have low or steady state memory requirements shouldn't suffer any marking penalty
  4. -
-

The first thing to determine is when we decide to start marking. Currently we make the decision on when to do a collection based on how much memory has been allocated since the last collection, if its over a certain fraction of the the total heap size we do a collection and if its not we expand. Similarly we can base the decision on when to start marking when we've consumed a certain portion of the heap since the last collection, call this the ISD (incremental start divisor). So if we go with an ISD of 4 we start marking when a quarter of the heap is left and an ISD of 1 means we're always marking.

-

Now that we know when we start marking there are two conflicting goals to achieve in selecting the marking time slice:

-
    -
  1. Maintain the frame rate
  2. -
  3. Make sure the collector gets to the sweep stage soon enough to avoid too much heap expansion
  4. -
-

If we don't maintain the frame rate the movie will appear to pause and if we don't mark fast enough the mutator could get ahread of the collector and allocate memory so fast that the collection never finishes and memory grows unbounded. The ideal solution will result in only one mark incremental per frame unless the mutator is allocating memory so fast we need to mark more aggressively to get to the sweep. So the frequency of the incremental marking will be based on two factors: the rate at which we can trace memory and the rate at which the mutator is requesting more memory. Study of real world apps will be used to determine how best to factor these to rates together.

-

GCHeap

-

The GC library has a tiered memory allocation strategy, consisting of 3 parts:

-
    -
  1. A page-granular memory allocator called the GCHeap
  2. -
  3. A set of fixed size allocators for sizes up to 2K
  4. -
  5. A large allocator for items over 2K
  6. -
-

When you want to allocate something we figure out what size class it's in and then ask that allocator for the memory. Each fixed size allocator maintains a doubly linked list of 4K blocks that it obtains from the GCHeap. These 4K blocks are aligned on 4K boundaries so we can easily allocate everything on 8-byte boundaries (a necessary consequence of the 32-bit atom design-- 3 type bits and 29 pointer bits). Also we store the GCAlloc::GCBlock structure at the beginning of the 4K block so each allocation doesn't need a pointer to its block (just zero the lower 12 bits of any GC-allocated thing to get the GCBlock pointer). The GCBlock contains bitmaps for marking and indicating if an item has a destructor that needs to be called (a GCFinalizedObject base class exists defining a virtual destructor for GC items that need it). Deleted items are stored in a per-block free list which is used if there are any otherwise we get the next free item at the end. If we don't have anything free and we reach the end, we get another block from the GCHeap.

-

GCHeap's reserve/commit strategy

-

GCHeap reserves 16MB of address space per heap region. The goal of reserving so much address space is so that subsequent expansions of the heap are able to obtain contiguous memory blocks. If we can keep the heap contiguous, that reduces fragmentation and the possibility of many small "Balkanized" heap regions.

-

Reserving 16MB of space per heap region should not be a big deal in a 2GB address space... it would take a lot of Player instances running simultaneously to exhaust the 2GB address space of the browser process. By allocating contiguous blocks of address space and managing them ourselves, fragmentation of the IE heap may actually be decreased.

-

On Windows, this uses the VirtualAlloc API to obtain memory. On Mac OS X and Unix, we use mmap. VirtualAlloc and mmap can reserve memory and/or commit memory. Reserved memory is just virtual address space. It consumes the address space of the process but isn't really allocated yet; there are no pages committed to it yet. Memory allocation really occurs when reserved pages are committed. Our strategy in GCHeap is to reserve a fairly large chunk of address space, and then commit pages from it as needed. By doing this, we're more likely to get contiguous regions in memory for our heap.

-

GCHeap serves up 4K blocks to the size class allocators or groups of contiguous 4K blocks for requests from the large allocator. It maintains a free list and blocks are coalesced with their neighbors when freed. If we use up the 16MB reserved chunk, we reserve another one, contiguously with the previous if possible.

-

When memory mapping is not available

-

GCHeap can fall back on a malloc/free approach for obtaining memory if a memory mapping API like VirtualAlloc or mmap is not available. In this case, GCHeap will allocate exactly as much memory as is requested when the heap is expanded and not try to reserve additional memory pages to expand into. GCHeap won't attempt to allocate contiguous regions in this case.

-

We currently use VirtualAlloc for Windows (supported on all flavors of Windows back to 95), mmap on Mach-O and Linux. On Classic and Carbon, we do not currently use a memory mapping strategy... these implementations are calling MPAllocAligned, which can allocate 4096-byte aligned memory. We could potentially bind to the Mach-O Framework dynamically from Carbon, if the user's system is Mac OS X, and call mmap/munmap.

diff --git a/files/zh-cn/mobile/index.html b/files/zh-cn/mobile/index.html deleted file mode 100644 index 0d0a6b7b99..0000000000 --- a/files/zh-cn/mobile/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Mobile -slug: Mobile -translation_of: Mozilla/Mobile ---- -
-

移动设备上的Firefox研发代号为Fennec,为移动电话和非PC设备带来了真实的Web体验。本页为Web和附加组件开发者提供了的相关资 源。

-

通过在Twitter上的 @mozmobile, 订阅mobile newsletter,或者成为在Facebook上的一名Fan,您可以得到项目的最新消息。

-

最新移动开发者消息见:加入移动附加组件的挑战!

-
diff --git a/files/zh-cn/mobile/viewport_meta_tag/index.html b/files/zh-cn/mobile/viewport_meta_tag/index.html deleted file mode 100644 index 78f6e9bb52..0000000000 --- a/files/zh-cn/mobile/viewport_meta_tag/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: 在移动浏览器中使用viewport meta标签控制布局 -slug: Mobile/Viewport_meta_tag -tags: - - viewport - - 布局 - - 移动 - - 视口 -translation_of: Mozilla/Mobile/Viewport_meta_tag ---- -

背景

- -

浏览器的 {{glossary("viewport")}} 是可以看到Web内容的窗口区域,通常与渲染出的页面的大小不同,这种情况下,浏览器会提供滚动条以滚动访问所有内容。
-
- 窄屏幕设备(如移动设备)在一个虚拟窗口或视口中渲染页面,这个窗口或视口通常比屏幕宽;然后缩小渲染的结果,以便在一屏内显示所有内容。然后用户可以移动、缩放以查看页面的不同区域。例如,如果移动屏幕的宽度为640px,则可能会用980px的虚拟视口渲染页面,然后缩小页面以适应640px的窗口大小。
-
- 这样做是因为许多页面没有做移动端优化,在小窗口渲染时会乱掉(或看起来乱)。所以,这种虚拟视口是一种让未做移动端优化的网站在窄屏设备上看起来更好的办法。

- -

viewport meta 标签

- -

但是,对于用媒体查询针对窄屏幕做了优化的页面,这种机制不大好 - 比如如果虚拟视口宽 980px,那么在 640px 或 480px 或更小宽度要起作用的媒体查询就不会触发了,浪费了这些响应式设计。
-
- 为了缓解这个问题,Apple 在 Safari iOS 中引入了“viewport meta 标签”,让Web开发人员控制视口的大小和比例。很多其他移动浏览器现在也支持此标签,但它不属于 Web 标准。 苹果的文档详尽地说明了web开发人员可以怎样使用这一标签,然而我们还是不得不仔细推敲Fennec究竟应该怎样实现它。例如,Safari的文档指出标签的内容应为”由逗号分隔的列表“,但是现有的浏览器和网页都把逗号、分号及空格混用作分隔符。
-
- 可以在A Tale of Two Viewports了解更多在不同移动浏览器中视口的情况。

- -

视口基础

- -

一个典型的针对移动端优化的站点包含类似下面的内容:

- -
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
- -

width属性控制视口的宽度。可以像width=600这样设为确切的像素数,或者设为device-width 特殊值,代表缩放为 100% 时以 CSS 像素计量的屏幕宽度。(相应的也有heightdevice-height属性,可能对包含基于视口高度调整大小及位置的元素的页面有用。)

- -

initial-scale 属性控制页面最初加载时的缩放等级。maximum-scaleminimum-scaleuser-scalable属性控制允许用户以怎样的方式放大或缩小页面。

- -
-

 使用 user-scalable=no 会导致可访问性问题,让有视觉障碍(如视力差)的用户使用困难。

-
- -

像素并非像素

- -

近年来,屏幕分辨率已经涨到人眼难以区分单个像素大小的程度。例如,最近的智能手机通常具有5英寸屏幕,分辨率高达1920-1080像素(~400dpi)。因此,许多浏览器让每个 CSS 像素对应多个硬件像素,以便在很小的物理尺寸上显示的页面能看清楚。最初这样做在许多触控优化的网站上有可用性和可读性问题, Peter-Paul Koch在A pixel is not a pixel中写到过。
-
- 在高 dpi 屏幕上,初始比例 = 1 的页面将被浏览器有效缩放。他们的文字将是流畅和清晰的,但位图图像可能无法利用全屏分辨率。为了在这些屏幕上获得更清晰的图像,Web开发人员可能希望以比其最终大小更高的比例设计图像(或整个布局),然后使用CSS或视口属性缩小它们。这与CSS 2.1标准一致:

- -
-

如果显示设备的像素密度与典型的电脑显示器差异明显,用户代理应当重新调整像素值。推荐的做法是,将一个像素单位(pixel unit)对应为特定数量的设备像素(device pixel),使这个数量的设备像素所占的大小最接近参考像素的大小。而参考像素(reference pixel)的大小则推荐为阅读者在一臂远的距离观看像素密度为 96 dpi 的设备时一个像素所占的视角大小

-
- -

对于Web开发人员,这意味着页面的大小远小于实际像素数,浏览器可能会相应地调整其布局和图像的大小。不过要记得不是所有移动设备的宽度都一样,你应该确保你的页面在不同屏幕尺寸和不同方向上都能很好地显示。

- -

默认比例依赖于显示密度。在密度低于200 dpi的显示设备上,比例为1.0。在密度介于200及300 dpi之间的显示设备上,比例为1.5。对于具有300 dpi以上密度的显示设备,比例为密度除以 150 dpi 后向下取整的结果。注意,只有在视口比例为1时,默认比例才会生效。否则,CSS 像素(即像素单位)与设备像素之间的关系依赖于当前的缩放等级。

- -

视口宽度及屏幕宽度

- -

网站可以将其视口设置为特定大小。例如,定义 "width=320,initial-scale=1" 可在纵向的小手机屏幕上精确显示。但这样一来浏览器就不会渲染大尺寸页面,从而导致问题。为解决此问题,浏览器将根据需要扩展视口宽度,以按要求的比例填充屏幕,在iPad等大屏幕设备上尤其有用。 (Allen Pike的viewport for iPad sites对web开发者做了充分说明。)

- -

对于设置了初始或最大缩放的页面,width属性实际上变成了最小视口宽度。比如,如果你的布局需要至少500像素的宽度,那么你可以使用以下标记。当屏幕宽度大于500像素时,浏览器会扩展视口(而不是放大页面)来适应屏幕:

- -
<meta name="viewport" content="width=500, initial-scale=1">
- -

可用属性还有 minimum-scale、 maximum-scale 和 user-scalable。这些属性会影响初始尺寸及宽度,并且会限制缩放等级。

- -

移动浏览器在处理屏幕方向改变时稍有差异。例如,Mobile Safari通常在竖屏转横屏时只缩放页面,而不会把页面重新布局成横屏载入时的效果。如果web开发者想让iPhone在方向切换时保持固定比例,需要增加一个maximum-scale值来避免这样的的缩放,这会带来并非预期的禁止用户缩放页面的副作用:

- -
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
-
- -

通过将初始缩放和最小缩放设置为0.86来限制一些智能手机的缩小操作。结果是水平滚动在任何方向都被抑制,用户可以根据需要放大。

- -
<meta name="viewport" content="width=device-width, initial-scale=0.86, maximum-scale=3.0, minimum-scale=0.86">
- -

手机平板通用的视口尺寸

- -

如果你想知道各种手机和平板设备各有怎样的视口宽度,这里有一个手机平板视口尺寸的综合列表。它提供了一些诸如横屏及竖屏的视口宽度、物理屏幕宽度、操作系统以及像素密度的信息。

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Device', '#viewport-meta', '<meta name="viewport">')}}{{Spec2('CSS3 Device')}}Non-normatively describes the Viewport META element
- -

显然,viewport meta 标签为人们所需,因为大多数流行的浏览器均已支持这个标签,成千上万的站点也正在使用这个标签。如果有一个真正的标准让网页控制视口属性该多好。随着标准化工作逐步推进,Mozilla 会跟进任何最新的变化。

diff --git a/files/zh-cn/mozilla/accessibility/index.html b/files/zh-cn/mozilla/accessibility/index.html deleted file mode 100644 index 38f8dff03d..0000000000 --- a/files/zh-cn/mozilla/accessibility/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Accessibility and Mozilla -slug: Mozilla/Accessibility -tags: - - Accessibility - - Mozilla - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Accessibility ---- -

La accesibilidad es la idea de que el software (entre otras cosas) debe estar diseñado para ser utilizable y, en la medida de lo posible, conveniente para las personas con discapacidad. Mozilla se esfuerza por hacer que su software sea accesible; los documentos a continuación cubren las formas en que lo hacemos . SO Estos artículos proporcionan detalles acerca de la accesibilidad Mozilla específico -.

- -

{{LandingPageListSubpages}}=Mx

diff --git a/files/zh-cn/mozilla/accessibility/software_accessibility_today/index.html b/files/zh-cn/mozilla/accessibility/software_accessibility_today/index.html deleted file mode 100644 index 8f6884cbd0..0000000000 --- a/files/zh-cn/mozilla/accessibility/software_accessibility_today/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: 软件无障碍:我们前进到哪里了? -slug: Mozilla/Accessibility/Software_accessibility_today -tags: - - Accessibility - - 可访问性 - - 无障碍 -translation_of: Mozilla/Accessibility/Software_accessibility_today ---- -

在过去的二十年内,计算机软件的无障碍辅助功能已经出现了大幅改善。本文综述了这一方面的发展进度和技术。

- -

我们前进到哪里了?

- -

到目前为止,桌面计算机环境背后最大的驱动力来自微软公司,首先,他们开发出了 MS DOS,随后是一代又一代的 Microsoft Windows。在设计时,这些操作系统并没有考虑到残疾人的需要。许多人,包括那些失明或有其他身体残疾的人,无法使用一些为微软操作系统编写的应用程序。这些应用程序假设计算机用户可以:

- - - -

如果一个人不能做到完成上面列出的项目中的任何一条,他就会发现自己无法使用许多流行的计算机应用程序。以下是一些在执行这些任务时会遇到问题的人群:

- - - -

我们还必须考虑到,有越来越多的上了年纪的 50 后、60 后,还有 70 后开始出现视觉、视力或者灵活性方面的问题。当您将所有可能的用户群体加在一起时,就会发现,无障碍功能其实有很多潜在的用户!

- -

In answer to this problem, many small accessibility hardware and software vendors created products and software which helped people who could not perform one of the four basic tasks to use common computer applications. Some examples of these assistive devices and software include:

- - - -

In fact, the entire adaptive technology industry has grown up around these issues. One great place to go and learn about this industry is the CSUN conference in Los Angeles, which takes place every year in mid-late March.

- -

访问屏幕内容的替代方法

- -

大多数计算机程序都是图形化的,对于有视力障碍的人来说,其中一些程序难以使用或者根本无法使用。好在,这种情况不一定就无法挽回。以下是一些现在的视力障碍读者使用桌面软件的方式:

- -
-
Text-to-speech (TTS)
-
Makes the computer talk to the user: Those who can't read print at all usually use talking programs (text-to-speech). Talking programs are also useful for print disabilities other than visual impairments, such as dyslexia. Additionally, text-to-speech is used by those who cannot speak, in place of their own voice. Finally, this technology could be useful to mainstream users, on portable information appliances, or to access information when the eyes are busy elsewhere.
-
放大
-
Enlarges the screen's contents: For those with low vision, it may suffice to use a larger font, a built-in high contrast theme, or even just an an extra large screen. Otherwise, screen magnification programs may be used, which allow zooming in to portions of the screen, while following the mouse or the current focus. Screen magnifiers also have some built-in text-to-speech and the ability to filter text and images through various color palettes, such as black on yellow for high contrast, or green on blue for low contrast.
-
The Optacon
-
Provides access to printed words, graphics and on-screen information by means of an array vibrating pins the size of an index finger. The user uses one hand to read the vibrating pins, and the other hand moves a mini-camera over the material to be read. Unfortunately, the unit is not currently produced, although there is occasional talk of resurrecting this useful device.
-
Braille
-
A solution used for quiet reading, for detailed work, and by deaf-blind users. This can come in the form of hard copy braille printed on braille embossers, or from a refreshable braille display (see below). These technologies requires special drivers, braille formatting routines and software based text-to-braille translation. The importance of braille itself must be emphasized. For those that read it, braille can offer higher levels of employment and life fulfillment.
-
- - - - - - - - - - - - -
Refreshable braille displays of various sizesA braille embosser
- -

Audio- and braille- based user interfaces are concepts that software designers are historically untrained for. The basic concept is easy - dealing with information when you're blind is like seeing everything through a mail slot - sequentially and methodically. Only small pieces of sequential, non-graphical information can be conveyed - via text-to-speech or a refreshable braille display. Whatever the user does, the software needs to respond with small, bite sized pieces of information that are as short and to the point as possible. Ideally, intelligent decisions are made, so the user does not have to wade through as much non-relevant data.

- -

操作计算机、输入数据的替代方法

- -

Another problem is how people with disabilities get information into the computer. If you're physically disabled, you may not be able to type on a regular keyboard or use a mouse. Here are some of the alternative ways physically disabled people enter information:

- -
-
粘滞键
-
Make entering key combinations easy. For example to make a capital letter, first press the shift key, release it, then press the letter to be capitalized. The sticky key technique is utilized by people who have only one usable hand, or who have no use of their hands and type using a stick in their mouth.
-
Single switch
-
Technologies enable persons with severe physical disabilities. Some, like Stephen Hawking, enter information by choosing among lists of options. They might press a switch down to begin moving a highlight bar through the list, and release the switch when the desired option is highlighted.
-
特种键盘
-
Exist to make data entry easier. However, any special features are generally handled in the keyboard itself, so that no special programming is required.
-
语音识别
-
Technology lets people talk to the computer. This technology has come a long way, but still needs to be more integrated into mainstream software.
-
Consistent keyboard support and hotkeys
-
Many people can't use a mouse. Extremely consistent keystroke support is a very important consideration. Blind testers have knack for finding ways to improve keystroke support in almost any given piece of software. Testing with people that have disabilities generally benefits everyone. Use the accessible toolkit checklist to make sure your UI controls adhere to standards.
-
- -

一大主要限制——上下文缺失

- -

这些无障碍软件厂商开发的解决方案大大增加了几十万残障人士的就业率和幸福指数,这些工作的重要性绝不能被轻视。然而,这些解决方案都没能为残障人士提供一个完全可访问、高度易用的工作环境。这是由于一个和上下文有关的简单问题——用户与计算机间的交互是由交互的上下文决定的。当用户在键盘上输入一些东西,或者一个应用程序在屏幕上显示了一些文本或图像,在不同的上下文中,这些交互行为的具体含义也可以是截然不同的。举个例子,一个应用程序可能在处理任务时显示一个电灯泡,而另一个程序可能是在完成任务后显示电灯泡。如果盲人不能得知显示是哪个程序显示了电灯泡,就无法理解这个电灯泡代表什么意思,只能靠猜。类似地,语音识别软件常常需要用户补充交互的上下文信息,来保证用户的语音输入作用到正确的上下文中。这个上下文的问题依然困扰着现代的辅助功能解决方案。

- -

The most recent noteable attempt at solving this problem was put forth by Microsoft in 1997, and is called Microsoft Active Accessibility (MSAA). Realizing that complete accessibility was not possible without cooperation between applications and accessibility aids such as screen reading software or voice recognition software, Microsoft Active Accessibility defines a Windows-based standard by which applications can communicate context and other pertanent information to accessibility aids. This solution has seen only partial success, largely due to the fact that it requires significant changes to applications which are made accessible. Because most popular desktop and productivity applications are not open source, this forced disabled people to rely on the companies which produce this software to make it accessible. These companies were often reluctant for various reasons including the large amount of time required to do so. On a positive note, recent federal purchasing rules such as Section 508 have caused many companies to pay attention and implement MSAA support.

- -

步入开源软件之门

- -

Microsoft was on the right track with Microsoft Active Accessibility, but because the source code to most popular desktop applications which are used in large corporations is not publicly available, they were never made fully accessible. In open source, however, making the necessary modifications to make them accessible is very possible.

- -

Open source software is an ideal way to the needs of disabled users, because accessibility can be fully integrated into the core designs, rather than tacked onto as an afterthought. It also gives disabled programmers a chance to control their own destiny, by giving them the opportunity and the right to directly fix the innaccessible software themselves.

- -

Furthermore, any software solution that can enable equality should by all rights be free of charge - an integral part of society's infrastructure. If no special hardware is required, why should a disabled person pay extra money to use the same software as everyone else? That said, there is still an important role for adaptive technology vendors in creating special services and hardware, or even proprietary software on platforms where that is appropriate. . The ideal situation would be for adaptive technology professionals to make money on rehab, trainingand support - something there is currently not enough of. Each end user has a unique set problems, and in the open source world, providing highly customized solutions can be a business in itself.

- -

Right now, GUI's on Linux are mostly not accessible. Microsoft Windows is still far more accesible. Gnome, KDE, StarOffice, KOffice, Mozilla and all other GUI software packages in Linux are unuseable by large numbers of disabled users. There has been some progress with the support of Gnome's ATK APIs in many of these packages, and the development of GOK (Gnome Onscreen Keyboard) and Gnopernicus (screenreader and magnifier). However, these solutions are not yet truly usable for real disabled end users.

- -

我需要做什么?

- -

Mozilla 开发者

- - - -

其他开发者

- -

无论您从事何种工作,可访问性的基础是要了解每一个用户都是不同的。在此之后,具体需要采用的技术可能会随工程环境的不同而变化。下面的{{anch("参见")}}含有分别适用于 Web 开发者和桌面应用程序开发者的各种信息与工具。

- -

参见

- - diff --git a/files/zh-cn/mozilla/add-ons/add-on_guidelines/index.html b/files/zh-cn/mozilla/add-ons/add-on_guidelines/index.html deleted file mode 100644 index 58b185e048..0000000000 --- a/files/zh-cn/mozilla/add-ons/add-on_guidelines/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: 附加组件准则 -slug: Mozilla/Add-ons/Add-on_guidelines -tags: - - add-on - - 附加组件 -translation_of: 'https://extensionworkshop.com/documentation/publish/add-on-policies/' ---- -

REDIRECT https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/AMO/Policy/Reviews

diff --git a/files/zh-cn/mozilla/add-ons/amo/index.html b/files/zh-cn/mozilla/add-ons/amo/index.html deleted file mode 100644 index 0845e54e3d..0000000000 --- a/files/zh-cn/mozilla/add-ons/amo/index.html +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: AMO -slug: Mozilla/Add-ons/AMO -tags: - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Add-ons/AMO ---- -

{{AddonSidebar}}

- -

Content to be added.

diff --git a/files/zh-cn/mozilla/add-ons/amo/policy/contact/index.html b/files/zh-cn/mozilla/add-ons/amo/policy/contact/index.html deleted file mode 100644 index c847ed92d1..0000000000 --- a/files/zh-cn/mozilla/add-ons/amo/policy/contact/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: AMO 联系信息 -slug: Mozilla/Add-ons/AMO/Policy/Contact -tags: - - 附加组件支持 -translation_of: Mozilla/Add-ons#Contact_us ---- -

{{AddonSideBar}}

- -

感谢您愿意与Mozilla 附加组件小组联络。 请仔细阅读此页面,以确保您的请求能到达正确的地方。

- -

附加组件支持

- -

如果您有关于特定附加组件的支持问题,例如“如何使用此附加组件?” 或“为什么不能正常工作?”,请通过附加组件列表页上列出的支持渠道联系该附加组件作者。

- -

附加组件审查相关

- -

如果您有关于附加组件审核希望报告违反政策的问题,请发送电子邮件至 amo-editors@mozilla.org。几乎所有的附加组件报告都属于这个类别。请务必包含相关附加组件的链接以及您的问题或评论的详细说明。

- -

附加组件安全漏洞

- -

如果您在附加程序中发现了安全漏洞,即使它不在此处托管,Mozilla也对您的发现感兴趣并将与附加开发人员一起尽快更正该问题。附加组件的安全问题可以直接报告Bugzillaconfidentially 或发邮件给 amo-admins@mozilla.org.

- -

网站功能与发展

- -

如果您发现本网站有问题 , 我们乐意修复。请在Github 上传BUG报告, 报告中包括问题的位置以及您如何遇到这个问题。

- -

关于这些政策或您的插件如何与我们联系。

diff --git a/files/zh-cn/mozilla/add-ons/amo/policy/index.html b/files/zh-cn/mozilla/add-ons/amo/policy/index.html deleted file mode 100644 index 58179ed4fa..0000000000 --- a/files/zh-cn/mozilla/add-ons/amo/policy/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: AMO Policies -slug: Mozilla/Add-ons/AMO/Policy -tags: - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Add-ons/AMO/Policy ---- -

{{AddonSidebar}}

- -

Mozilla 致力于为我们的用户和开发人员确保极佳的附加体验,在提交您的附加组件之前,请查阅下列政策。

- -
-
开发者协议
-
Effective January 5, 2016
审核处理
-
Add-ons extend the core capabilities of Firefox, allowing users to modify and personalize their Web experience. A healthy add-on ecosystem, built on trust, is vital for developers to be successful and users to feel safe making Firefox their own. For these reasons, Mozilla requires all add-ons to comply with the following set of policies on acceptable practices. The below is not intended to serve as legal advice, nor is it intended to serve as a comprehensive list of terms to include in your add-on’s privacy policy.

-
精选的Add-ons
-
How up-and-coming add-ons become featured and what's involved in the process.

- 联系我们 - -

How to get in touch with us regarding these policies or your add-on.

- -
diff --git a/files/zh-cn/mozilla/add-ons/code_snippets/canvas/index.html b/files/zh-cn/mozilla/add-ons/code_snippets/canvas/index.html deleted file mode 100644 index 002a1b8600..0000000000 --- a/files/zh-cn/mozilla/add-ons/code_snippets/canvas/index.html +++ /dev/null @@ -1,237 +0,0 @@ ---- -title: Canvas 代码片段 -slug: Mozilla/Add-ons/Code_snippets/Canvas -translation_of: Archive/Add-ons/Code_snippets/Canvas ---- -

{{LegacyAddonsNotice}}

- -

关于使用<canvas>的一般信息,请参阅 canvas topic page.

- -

网页中可以用到的代码

- -

在画布中获取特定颜色的像素数量

- -

下面的函数将返回画布上颜色(RGB格式)为r、g、b的像素数量。如果用户希望像这篇博客文章中在另一个区域绘画,那么这将非常有用。 

- -
function getpixelamount(canvas, r, g, b) {
-  var cx = canvas.getContext('2d');
-  var pixels = cx.getImageData(0, 0, canvas.width, canvas.height);
-  var all = pixels.data.length;
-  var amount = 0;
-  for (i = 0; i < all; i += 4) {
-    if (pixels.data[i] === r &&
-        pixels.data[i + 1] === g &&
-        pixels.data[i + 2] === b) {
-      amount++;
-    }
-  }
-  return amount;
-};
-
- -

在画布中获取某一个像素的颜色

- -

下面的代码片段返回一个对象,该对象在画布的x和y的位置上具有RGBA值。这可以用来确定鼠标光标是否在一个特定的形状中。

- -
function getpixelcolour(canvas, x, y) {
-  var cx = canvas.getContext('2d');
-  var pixel = cx.getImageData(x, y, 1, 1);
-  return {
-    r: pixel.data[0],
-    g: pixel.data[1],
-    b: pixel.data[2],
-    a: pixel.data[3]
-  };
-}
-
- -

链式调用方法

- -

这个类允许可以像jQuery那样链式地访问 2D 渲染上下文的方法和属性 。

- -
function Canvas2DContext(canvas) {
-  if (typeof canvas === 'string') {
-    canvas = document.getElementById(canvas);
-  }
-  if (!(this instanceof Canvas2DContext)) {
-    return new Canvas2DContext(canvas);
-  }
-  this.context = this.ctx = canvas.getContext('2d');
-  if (!Canvas2DContext.prototype.arc) {
-    Canvas2DContext.setup.call(this, this.ctx);
-  }
-}
-Canvas2DContext.setup = function() {
-  var methods = ['arc', 'arcTo', 'beginPath', 'bezierCurveTo', 'clearRect', 'clip',
-    'closePath', 'drawImage', 'fill', 'fillRect', 'fillText', 'lineTo', 'moveTo',
-    'quadraticCurveTo', 'rect', 'restore', 'rotate', 'save', 'scale', 'setTransform',
-    'stroke', 'strokeRect', 'strokeText', 'transform', 'translate'];
-
-  var getterMethods = ['createPattern', 'drawFocusRing', 'isPointInPath', 'measureText', // drawFocusRing not currently supported
-    // The following might instead be wrapped to be able to chain their child objects
-    'createImageData', 'createLinearGradient',
-    'createRadialGradient', 'getImageData', 'putImageData'
-  ];
-
-  var props = ['canvas', 'fillStyle', 'font', 'globalAlpha', 'globalCompositeOperation',
-    'lineCap', 'lineJoin', 'lineWidth', 'miterLimit', 'shadowOffsetX', 'shadowOffsetY',
-    'shadowBlur', 'shadowColor', 'strokeStyle', 'textAlign', 'textBaseline'];
-
-  for (let m of methods) {
-    let method = m;
-    Canvas2DContext.prototype[method] = function() {
-      this.ctx[method].apply(this.ctx, arguments);
-      return this;
-    };
-  }
-
-  for (let m of getterMethods) {
-    let method = m;
-    Canvas2DContext.prototype[method] = function() {
-      return this.ctx[method].apply(this.ctx, arguments);
-    };
-  }
-
-  for (let p of props) {
-    let prop = p;
-    Canvas2DContext.prototype[prop] = function(value) {
-      if (value === undefined)
-        return this.ctx[prop];
-      this.ctx[prop] = value;
-      return this;
-    };
-  }
-};
-
-var canvas = document.getElementById('canvas');
-
-// Use context to get access to underlying context
-var ctx = Canvas2DContext(canvas)
-  .strokeStyle('rgb(30, 110, 210)')
-  .transform(10, 3, 4, 5, 1, 0)
-  .strokeRect(2, 10, 15, 20)
-  .context;
-
-// Use property name as a function (but without arguments) to get the value
-var strokeStyle = Canvas2DContext(canvas)
-  .strokeStyle('rgb(50, 110, 210)')
-  .strokeStyle();
-
- -

Code usable only from privileged code

- -

These snippets are only useful from privileged code, such as extensions or privileged apps.

- -

将canvas图片保存到文件中

- -

The following function accepts a canvas object and a destination file path string. The canvas is converted to a PNG file and saved to the specified location. The function returns a promise which resolves when the file has been completely saved.

- -
function saveCanvas(canvas, path, type, options) {
-    return Task.spawn(function *() {
-        var reader = new FileReader;
-        var blob = yield new Promise(accept => canvas.toBlob(accept, type, options));
-        reader.readAsArrayBuffer(blob);
-
-        yield new Promise(accept => { reader.onloadend = accept });
-
-        return yield OS.File.writeAtomic(path, new Uint8Array(reader.result),
-                                         { tmpPath: path + '.tmp' });
-    });
-}
-
- -

将一个远程页面加载到canvas元素上

- -

The following class first creates a hidden iframe element and attaches a listener to the frame's load event. Once the remote page has loaded, the remotePageLoaded method fires. This method gets a reference to the iframe's window and draws this window to a canvas object.

- -

Note that this only works if you are running the page from chrome. If you try running the code as a plain webpage, you will get a 'Security error" code: "1000' error.

- -
RemoteCanvas = function() {
-    this.url = 'http://developer.mozilla.org';
-};
-
-RemoteCanvas.CANVAS_WIDTH = 300;
-RemoteCanvas.CANVAS_HEIGHT = 300;
-
-RemoteCanvas.prototype.load = function() {
-    var windowWidth = window.innerWidth - 25;
-    var iframe;
-    iframe = document.createElement('iframe');
-    iframe.id = 'test-iframe';
-    iframe.height = '10px';
-    iframe.width = windowWidth + 'px';
-    iframe.style.visibility = 'hidden';
-    iframe.src = this.url;
-    // Here is where the magic happens... add a listener to the
-    // frame's onload event
-    iframe.addEventListener('load', this.remotePageLoaded, true);
-    //append to the end of the page
-    window.document.body.appendChild(iframe);
-    return;
-};
-
-RemoteCanvas.prototype.remotePageLoaded = function() {
-    // Look back up the iframe by id
-    var ldrFrame = document.getElementById('test-iframe');
-    // Get a reference to the window object you need for the canvas
-    // drawWindow method
-    var remoteWindow = ldrFrame.contentWindow;
-
-    //Draw canvas
-    var canvas = document.createElement('canvas');
-    canvas.style.width = RemoteCanvas.CANVAS_WIDTH + 'px';
-    canvas.style.height = RemoteCanvas.CANVAS_HEIGHT + 'px';
-    canvas.width = RemoteCanvas.CANVAS_WIDTH;
-    canvas.height = RemoteCanvas.CANVAS_HEIGHT;
-    var windowWidth = window.innerWidth - 25;
-    var windowHeight = window.innerHeight;
-
-    var ctx = canvas.getContext('2d');
-    ctx.clearRect(0, 0,
-                  RemoteCanvas.CANVAS_WIDTH,
-                  RemoteCanvas.CANVAS_HEIGHT);
-    ctx.save();
-    ctx.scale(RemoteCanvas.CANVAS_WIDTH / windowWidth,
-              RemoteCanvas.CANVAS_HEIGHT / windowHeight);
-    ctx.drawWindow(remoteWindow,
-                   0, 0,
-                   windowWidth, windowHeight,
-                   'rgb(255, 255, 255)');
-    ctx.restore();
-};
-
- -

Usage:

- -
var remoteCanvas = new RemoteCanvas();
-remoteCanvas.load();
-
- -

将图像文件转换为base64字符串

- -

下面代码加载远程图片,并把它的内容转化为 Data URI scheme

- -
var canvas = document.createElement('canvas');
-var ctxt = canvas.getContext('2d');
-function loadImageFile(url, callback) {
-  var image = new Image();
-  image.src = url;
-  return new Promise((accept, reject) => {
-    image.onload = accept;
-    image.onerror = reject;
-  }).then(accept => {
-    canvas.width = this.width;
-    canvas.height = this.height;
-    ctxt.clearRect(0, 0, this.width, this.height);
-    ctxt.drawImage(this, 0, 0);
-    accept(canvas.toDataURL());
-  });
-}
-
- -

Usage:

- -
loadImageFile('myimage.jpg').then(string64 => { alert(string64); });
-
- -

如果你想获取本地文件(使用文件选择input元素)的 base64 内容,你必须使用 FileReader 对象。

diff --git a/files/zh-cn/mozilla/add-ons/code_snippets/index.html b/files/zh-cn/mozilla/add-ons/code_snippets/index.html deleted file mode 100644 index bfe77a4e38..0000000000 --- a/files/zh-cn/mozilla/add-ons/code_snippets/index.html +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: Code snippets -slug: Mozilla/Add-ons/Code_snippets -tags: - - Add-ons - - Code snippets - - Extensions - - NeedsTranslation - - TopicStub -translation_of: Archive/Add-ons/Code_snippets ---- -

{{LegacyAddonsNotice}}

- -

This is a quick list of useful code snippets (small code samples) available for developers of extensions for the various Mozilla applications. Many of these samples can also be used in XULRunner applications, as well as in actual Mozilla code itself.

- -

These examples demonstrate how to accomplish basic tasks that might not be immediately obvious.

- -

General

- -
-
Examples and demos from MDN articles
-
A collection of examples and demos from articles.
-
Window code
-
Opening and manipulating windows
-
Toolbar
-
Toolbar related code
-
Sidebar
-
Sidebar related code
-
Forms
-
Forms related code
-
XML
-
Code used to parse, write, manipulate, etc. XML
-
File I/O
-
Code used to read, write and process files
-
Drag & Drop
-
Code used to setup and handle drag and drop events
-
Dialogs
-
Code used to display and process dialog boxes
-
Alerts and Notifications
-
Modal and non-modal ways to notify users
-
Preferences
-
Code used to read, write, and modify preferences
-
JS XPCOM
-
Code used to define and call XPCOM components in JavaScript
-
Running applications
-
Code used to run other applications
-
<canvas> related
-
WHAT WG Canvas-related code
-
Signing a XPI
-
How to sign an XPI with PKI
-
Delayed Execution
-
Performing background operations.
-
Miscellaneous
-
Miscellaneous useful code fragments
-
HTML to DOM
-
Using a hidden browser element to parse HTML to a window's DOM
-
- -

JavaScript libraries

- -

Here are some JavaScript libraries that may come in handy.

- -
-
StringView
-
A library that implements a StringView view for JavaScript typed arrays. This lets you access data in typed arrays using C-like string functions.
-
Rosetta
-
By default, the only possible standardized scripting language for HTML is ECMAScript. Hence, if you are going to use another scripting language you might expect that most of the browsers will not recognize it. Nevertheless, the increasing computational power of modern browsers together with the introduction of typed arrays in ECMAScript allow us, in theory, to build full virtual machines in pure ECMAScript. Therefore, it is also possible, in theory, to use ECMAScript for a smaller task: parsing exotic programming languages (i.e., creating compilers). This snippets shows a possible way to start from.
-
- -

Browser-oriented code

- -
-
Tabbed browser code (Firefox/SeaMonkey)
-
Basic operations, such as page loading, with the tabbed browser, which is the heart of Mozilla's browser applications
-
Cookies
-
Reading, writing, modifying, and removing cookies
-
Page Loading
-
Code used to load pages, reload pages, and listen for page loads
-
Interaction between privileged and non-privileged code
-
How to communicate from extensions to websites and vice-versa.
-
Downloading Files
-
Code to download files, images, and to monitor download progress
-
Password Manager
-
Code used to read and write passwords to/from the integrated password manager
-
Bookmarks
-
Code used to read and write bookmarks
-
JavaScript Debugger Service
-
Code used to interact with the JavaScript Debugger Service
-
- -

SVG

- -
-
General
-
General information and utilities
-
SVG Animation
-
Animate SVG using JavaScript and SMIL
-
SVG Interacting with Script
-
Using JavaScript and DOM events to create interactive SVG
-
Embedding SVG in HTML and XUL
-
Using SVG to enhance HTML or XUL based markup
-
- -

XUL Widgets

- -
-
HTML in XUL for Rich Tooltips
-
Dynamically embed HTML into a XUL element to attain markup in a tooltip
-
Label and description
-
Special uses and line breaking examples
-
Tree
-
Setup and manipulation of trees using XUL and JS
-
Scrollbar
-
Changing style of scrollbars. Applies to scrollbars in browser and iframe as well.
-
Autocomplete
-
Code used to enable form autocomplete in a browser
-
Boxes
-
Tips and tricks when using boxes as containers
-
Tabbox
-
Removing and manipulating tabs in a tabbox
-
- -

Windows-specific

- -
-
Finding Window Handles (HWND) (Firefox)
-
How to use Windows API calls to find various kinds of Mozilla window handles. Window handles can be used for IPC and Accessibility purposes.
-
Using the Windows Registry with XPCOM
-
How to read, write, modify, delete, enumerate, and watch registry keys and values.
-
- - - -

The content at MozillaZine Example Code is slowly being moved here, but you can still find useful examples there for now.

diff --git a/files/zh-cn/mozilla/add-ons/code_snippets/js_xpcom/index.html b/files/zh-cn/mozilla/add-ons/code_snippets/js_xpcom/index.html deleted file mode 100644 index e5ab2b6189..0000000000 --- a/files/zh-cn/mozilla/add-ons/code_snippets/js_xpcom/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: JS XPCOM -slug: Mozilla/Add-ons/Code_snippets/JS_XPCOM -translation_of: Archive/Add-ons/Code_snippets/JS_XPCOM ---- -

{{LegacyAddonsNotice}}

- -

这是一些解决XPCOM组件相关的有用的JavaScript代码。

- -

Contract IDs

- -

契约ID是XPCOM对象独一无二的名字。它们用于创建或者获得XPCOM中的对象。

- -

Interfaces

- -

Every XPCOM object implements one or more interfaces. An interface is simply a list of constants and methods that can be called on the object, an example is nsIFile. Every XPCOM object must implement the nsISupports interface.

- -

Accessing XPCOM components from JavaScript

- -

XPCOM objects are either created as new instances (each creation gives you a completely new COM object) or as services (each access gives you the same COM object, often called a singleton). Whether you must create a new instance or access as a service depends on the contract. In order to get an XPCOM object you need to know the contract ID of the object and the interface that you wish to use on it.

- -

Creating an instance of a component

- -

The preferred method of creating XPCOM instances is via the Components.Constructor helper. For example,

- -
var nsFile = Components.Constructor("@mozilla.org/file/local;1", "nsIFile", "initWithPath");
-
-var file = new nsFile(filePath);
-
- -

They can also be created and initialized manually:

- -
var file = Components.classes["@mozilla.org/file/local;1"]
-                     .createInstance(Components.interfaces.nsIFile);
-file.initWithPath(filePath);
-
- -

This creates a new instance of the object with contract ID @mozilla.org/file/local;1 and allows you to call methods from the nsIFile interface on it.

- -

Getting an XPCOM service

- -
var preferences = Components.classes["@mozilla.org/preferences-service;1"]
-                            .getService(Components.interfaces.nsIPrefService);
-
- -

You can then call any methods in the nsIPrefService interface on the preferences object.

- -

Getting a different interface for a component

- -

Some components implement more than one interface. Sometimes JavaScript is clever enough to know all the interfaces available on a component, but in most cases you will have to explicitly check for an interface. With the preferences service from the previous example we can do the following:

- -
var preferences = preferences.QueryInterface(Components.interfaces.nsIPrefBranch2);
-
- -

This allows you to use the methods in the nsIPrefBranch2 interface.

- -

Determining which interfaces an XPCOM component supports

- -

To display a list of all interfaces that an XPCOM component supports, do the following:

- -
// |c| is the XPCOM component instance
-for each (i in Components.interfaces) { if (c instanceof i) { alert(i); } }
-
- -

In this context, instanceof is the same as QueryInterface except that it returns false instead of throwing an exception when |c| doesn't support interface |i|. Another difference is that QueryInterface returns an object, where as instanceof returns a boolean.

- -

XPCOMUtils - About protocol handler

- -

{{ Fx_minversion_inline(3) }}This example implements a quick about protocol handler in JS using XPCOMUtils.jsm.

- -
Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-function AboutHandler() {}
-AboutHandler.prototype = {
-    newChannel: function(uri) {
-        var channel = Services.io.newChannel("chrome://mystuff/content/mystuff.xul", null, null);
-        channel.originalURI = uri;
-        return channel;
-    },
-    getURIFlags: function(uri) {
-        // Do NOT return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT unless
-        // you make sure to set a non-system principal in newChannel.
-        return 0;
-    },
-
-    classDescription: "About MyStuff Page",
-    classID: Components.ID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"),
-    contractID: "@mozilla.org/network/protocol/about;1?what=mystuff",
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule])
-}
-
-var NSGetModule = XPCOMUtils.generateNSGetModule([AboutHandler]);
-}
-
diff --git a/files/zh-cn/mozilla/add-ons/code_snippets/modules/index.html b/files/zh-cn/mozilla/add-ons/code_snippets/modules/index.html deleted file mode 100644 index 413e32f59a..0000000000 --- a/files/zh-cn/mozilla/add-ons/code_snippets/modules/index.html +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Modules -slug: Mozilla/Add-ons/Code_snippets/Modules -translation_of: Archive/Add-ons/Code_snippets/Modules ---- -

{{LegacyAddonsNotice}}

- -

一些简单的代码将JavaScript模块转换为非Mozilla特定的代码(例如,如果移植到浏览器)。eval()的使用可能不会被关注,因为它仅在EXPORTED_SYMBOLS 数组上使用,而不依赖于用户输入。

- -
函数importModule(thatObj){
-    thatObj = thatObj || 窗口;
-
-    var EXPORTED_SYMBOLS = [
-    //把符号放在这里
-    ]。
-
-    //你的代码在这里...
-
-    //在你的代码结尾处:(假设'i'和'thatObj'都没有被导出!)
-    for(var i = 0; i <EXPORTED_SYMBOLS.length; i ++){thatObj [EXPORTED_SYMBOLS [i]] = eval(EXPORTED_SYMBOLS [i]);}
-}
-
- -

或一次性使用模块:

- -
(function(thatObj){
-    thatObj = thatObj || 窗口;
-
-    var EXPORTED_SYMBOLS = [
-    //把符号放在这里
-    ]。
-
-    //你的代码在这里...
-
-    //在你的代码结尾处:(假设'i'和'thatObj'都没有被导出!)
-    for(var i = 0; i <EXPORTED_SYMBOLS.length; i ++){thatObj [EXPORTED_SYMBOLS [i]] = eval(EXPORTED_SYMBOLS [i]);}
-})(); //可以在这里放置一个对象参数
diff --git a/files/zh-cn/mozilla/add-ons/code_snippets/queryselector/index.html b/files/zh-cn/mozilla/add-ons/code_snippets/queryselector/index.html deleted file mode 100644 index 364909681f..0000000000 --- a/files/zh-cn/mozilla/add-ons/code_snippets/queryselector/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: QuerySelector -slug: Mozilla/Add-ons/Code_snippets/QuerySelector -tags: - - $ - - $$ - - querySelector -translation_of: Archive/Add-ons/Code_snippets/QuerySelector ---- -

 {{ fx_minversion_header(3.5) }}

- -

沿着其他框架,如jQuery或Prototype, 缩短“querySelector”的名称可以很方便:

- -
    HTMLDocument.prototype.$ = function (selector) {
-        // Only for HTML
-        return this.querySelector(selector);
-    };
-    $(`div`);
-    HTMLDocument.prototype.$$ = function (selector) {
-        // Only for HTML
-        return this.querySelectorAll(selector);
-    };
-    $$(`div`);
- -
function $ (selector, el) {
-     if (!el) {el = document;}
-     return el.querySelector(selector);
-}
-function $$ (selector, el) {
-     if (!el) {el = document;}
-     return el.querySelectorAll(selector);
-     // Note: the returned object is a NodeList.
-     // If you'd like to convert it to a Array for convenience, use this instead:
-     // return Array.prototype.slice.call(el.querySelectorAll(selector));
-}
-alert($('#myID').id);
-
- -

(请注意,在使用火狐浏览器控制台时,上述功能可自动使用.)

- -

 XUL 甚至 XML可以很简单的支持(有以下两种替代方法,添加ChromeWindow.prototype 或者 Window.prototype,访问 this.document.querySelector, 或者根据jQuery 风格的链接,即在每个原型的$()方法中返回的‘this'

- -
HTMLDocument.prototype.$ = function (selector) { // 只用于HTML
-    return this.querySelector(selector);
-};
-
-Example:
-
-<h1>Test!</h1>
-<script>
-HTMLDocument.prototype.$ = function (selector) {
-    return this.querySelector(selector);
-};
-alert(document.$('h1')); // [object HTMLHeadingElement]
-</script>
-
- -
XULDocument.prototype.$ = function (selector) { // 只用于XUL
-    return this.querySelector(selector);
-};
-
-Example:
-
-<label value="Test!"/>
-<script type="text/javascript"><![CDATA[
-XULDocument.prototype.$ = function (selector) { // 只用于XUL
-    return this.querySelector(selector);
-};
-
-alert(document.$('label')); // [object XULElement]
-]]></script>
-
- -
Document.prototype.$ = function (selector) { // 只用于XML
-    return this.querySelector(selector);
-};
-var foo = document.implementation.createDocument('someNS', 'foo', null); // Create an XML document <foo xmlns="someNS"/>
-var bar = foo.createElementNS('someNS', 'bar'); // add <bar xmlns="someNS"/>
-foo.documentElement.appendChild(bar);
-alert(foo.$('bar').nodeName); // gives 'bar'
-
- -
Element.prototype.$ = function (selector) { // 可用于HTML,XUL,XML
-    return this.querySelector(selector);
-};
-
-HTML 例子:
-<h1><a>Test!<a/></h1>
-<script>
-Element.prototype.$ = function (selector) {
-    return this.querySelector(selector);
-};
-alert(document.getElementsByTagName('h1')[0].$('a').nodeName); // 'A'
-
-XUL 例子:
-<hbox><vbox/></hbox>
-<script type="text/javascript"><![CDATA[
-Element.prototype.$ = function (selector) {
-    return this.querySelector(selector);
-};
-var XULNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
-alert(document.getElementsByTagNameNS(XULNS, 'hbox')[0].$('vbox').nodeName); // vbox
-]]></script>
-
-XML 例子:
-<foo xmlns="someNS"><bar/></foo> in document earlier
-var foo = document.getElementsByTagNameNS('someNS', 'foo')[0];
-alert(foo.$('bar'));
-
-
- -

注意在XML中,  # 'id'选择器将不能体现为'id'属性(因此一个这样名字的属性不一定是XML的ID,尽管他在HTML 和XUL中是这样的), 也不会对 xml:id 起作用.

- -

然而,它将工作于指向没有无前缀属性选择器 (例如'id',但是不是 xml:id: http://www.w3.org/TR/selectors-api/#resolving) (即使 CSS3 支持命名空间属性选择器: http://www.w3.org/TR/css3-selectors/#attrnmsp 以及可能将xml:id 当作 #: http://www.w3.org/TR/css3-selectors/#id-selectors ).

diff --git a/files/zh-cn/mozilla/add-ons/code_snippets/timers/index.html b/files/zh-cn/mozilla/add-ons/code_snippets/timers/index.html deleted file mode 100644 index f15f127f61..0000000000 --- a/files/zh-cn/mozilla/add-ons/code_snippets/timers/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: JavaScript timers -slug: Mozilla/Add-ons/Code_snippets/Timers -translation_of: Archive/Add-ons/Code_snippets/Timers ---- -

{{LegacyAddonsNotice}}

- -

 

- -

JavaScript的代码块通常情况下是顺序执行的。不过有几个JavaScript内置函数(计时器),能够让我们推迟任意指令的执行:

- - - -

The setTimeout() function is commonly used if you wish to have your function called once after the specified delay. The setInterval() function is commonly used to set a delay for functions that are executed again and again, such as animations. The setImmediate() function can be used instead of the setTimeout(fn, 0) method to execute heavy operations in IE. The requestAnimationFrame() function tells the browser that you wish to perform an animation and requests that the browser schedule a repaint of the window for the next animation frame.

- -

Documentation

- -
-
{{domxref("window.setTimeout","setTimeout()")}}
-
Calls a function or executes a code snippet after specified delay.
-
{{domxref("window.setInterval","setInterval()")}}
-
Calls a function or executes a code snippet repeatedly, with a fixed time delay between each call to that function.
-
{{domxref("window.setImmediate","setImmediate()")}}
-
Calls a function immediately after the browser has completed other operations, such as events and display updates.
-
{{domxref("window.clearTimeout","clearTimeout()")}}
-
Clears the delay set by setTimeout().
-
{{domxref("window.clearInterval","clearInterval()")}}
-
Cancels repeated action which was set up using setInterval().
-
{{domxref("window.clearImmediate","clearImmediate()")}}
-
Cancels the immediate actions, just like {{domxref("window.clearTimeout","clearTimeout()")}} for {{domxref("window.setTimeout","setTimeout()")}}.
-
Using JavaScript timers within animations (Javascript Daemons Management)
-
In Computer science a daemon is a task that runs as a background process, rather than being under the direct control of an interactive user. In JavaScript programming language, all daemons are processes created by JavaScript timers or by a {{domxref("Worker")}} instantiation. Here are some code snippets which simplify and abstract the management of daemons.
-
{{domxref("window.requestAnimationFrame","requestAnimationFrame()")}}
-
requestAnimationFrame() tells the browser that you wish to perform an animation and requests that the browser schedule a repaint of the window for the next animation frame. The method takes as an argument a callback to be invoked before the repaint.
-
{{domxref("performance.now","performance.now()")}}
-
-

performance.now() returns a timestamp, measured in milliseconds, accurate to one thousandth of a millisecond. This timestamp is equal to the number of milliseconds since the navigationStart attribute of the performance.timing interface.

-
-
Date.now()
-
Date.now() returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
-
Using JavaScript timers within workers
-
Workers can use timeouts and intervals just like the main thread can. This can be useful, for example, if you want to have your worker thread run code periodically instead of nonstop.
-
Functions available to workers
-
In addition to the standard JavaScript set of functions (such as String, Array, Object, JSON etc), there are a variety of functions available from the DOM to workers. This article provides a list of those.
-
Basic animations
-
Since we're using script to control canvas elements it's also very easy to make (interactive) animations. Unfortunately the canvas element was never designed to be used in this way (unlike Flash) so there are limitations.
-
Timer.jsm
-
The Timer.jsm JavaScript code module contains pure-JavaScript implementations of setTimeout and clearTimeout that are compatible with the DOM window functions, but that can be used by code that does not have access to a DOM window (for example, JavaScript code modules or content frame scripts).
-
- -

See also

- - - -

<embed height="0" id="xunlei_com_thunder_helper_plugin_d462f475-c18e-46be-bd10-327458d045bd" type="application/thunder_download_plugin" width="0">

diff --git a/files/zh-cn/mozilla/add-ons/creating_custom_firefox_extensions_with_the_mozilla_build_system/index.html b/files/zh-cn/mozilla/add-ons/creating_custom_firefox_extensions_with_the_mozilla_build_system/index.html deleted file mode 100644 index 617d86487c..0000000000 --- a/files/zh-cn/mozilla/add-ons/creating_custom_firefox_extensions_with_the_mozilla_build_system/index.html +++ /dev/null @@ -1,470 +0,0 @@ ---- -title: Creating Custom Firefox Extensions with the Mozilla Build System -slug: >- - Mozilla/Add-ons/Creating_Custom_Firefox_Extensions_with_the_Mozilla_Build_System -translation_of: >- - Archive/Add-ons/Creating_Custom_Firefox_Extensions_with_the_Mozilla_Build_System ---- -
- Note: All instructions in this article apply to the Mozilla 1.8 branch only (i.e. Firefox 1.5). I'll try to keep it up-to-date as the trunk changes, but you certainly should not assume that this will work with the 1.7 branch (i.e. Firefox 1.0) or older.
-

There is a wealth of material on creating extensions for Firefox. All of these documents currently assume, however, that you are developing your extension using XUL and JavaScript only. For complex extensions, it may be necessary to create components in C++ that provide additional functionality. Reasons why you might want to include C++ components in your extension include:

-

有大量如何创建扩展的资料, 但是这些文档都假定仅仅使用XUL和Javascript开发扩展. 对于复杂的扩展, 可能需要C++开发相关的功能代码. 下列原因可能使你想要在扩展中包括C++组件(Components):

- -

This article describes how to set up the development environment for a large, complex Firefox extension with any or all of the above-mentioned requirements. The process of garnering this information has been somewhat painful due to the lack of published information on this topic, but has been assisted by the contributions of various members of the Mozilla development community, who have shown extraordinary patience in fielding ignorant newbie questions. I can’t stress enough that I’m far from a Mozilla expert, though I’m getting better. There may be much in this document that is inaccurate, misleading or just plain wrong. In fact, one of my goals in writing this is to fine-tune these instructions until they constitute a definite guide for hardcore hackers who want to extend the Firefox platform. If you’re one of the many people who know more about this than I do, your help in improving this article would be greatly appreciated.

-

I should also stress that you do not have to build Mozilla or use the Mozilla build system if you want to create C++ components for Mozilla. If you are just looking to create an XPCOM component or two, this is probably overkill, and you might want to take a look at this guide instead. On the other hand, if you are an experienced developer or team, and you know that you are going to build a large, complex extension, you would do well to consider the approach described in this article.

-

One final note: I’ve only tried these techniques inside Firefox, but they’ll probably work more or less unchanged on other Gecko-based platforms like Thunderbird or Seamonkey. If someone can confirm this and/or provide guidelines for what’s different, I’ll update the article to incorporate this information.

-

Bambi Meets Mozilla(小鹿斑比遇见Mozilla)

-

None of this is for the faint of heart. In particular, the initial step involves building Mozilla, which is a huge - nay, gargantuan! - project. Many intelligent developers have been driven to the brink of insanity trying to build it for the first time. If you're not an experienced C++ developer, I wouldn’t even bother. Stick to JavaScript.

-

(小鹿斑比小时候很胆小)其实这些并不适合胆小者. 尤其是, 第一步编译Mozilla, 那是庞大的 -- 非常非常巨大的 -- 项目. 在初次编译Mozilla时, 许多聪明的开发者都快被逼疯了. 如果你不是资深的C++开发者, 就别烦恼了, 继续玩Javascript.

-

On Windows Platforms

-

The first time I built Mozilla I used this guide. I can’t even remember why anymore, but I got stuck in a number of places, and the whole affair ended up taking far longer than I originally expected. Much furniture was smashed, much hair torn out by the roots. Here’s a comprehensive looking guide that’s gotten good reviews. Follow every step methodically and you’ll probably be alright. Focus on the fact that once you get the build working, it’ll probably work effortlessly from then on. Maybe.

-

On Other Platforms

-

On other platforms, namely Linux and MacOS, the process is much easier. All the tools for building are available built-in, and therefore all you have to do is run some commands in the terminal. You can find full instructions for almost any OS here.

-

Structuring Your Project(构造您的项目)

-

Mozilla includes a number of complex extensions that are integrated into its build process. It has thus been necessary to solve all of the issues involved in creating and registering XPCOM components, building JAR files and manifests, installing the lot into the Firefox extensions/ directory and so forth. So it behooves us to piggyback on this infrastructure to build our extension.

-

First of all, think of a catchy name for your extension and create a directory with that name under the /mozilla/extensions/ directory. Use only lowercase letters. You should see a bunch of other directories (inspector/, reporter/ and so forth) at the same level in the build tree.

-

Note that before actually building anything, the Mozilla build system invokes a configuration process that generates the actual makefiles used for the build from makefile templates called Makefile.in. The actual makefiles tend to be very similar or identical to the templates, but the extra flexibility gained from having the makefiles generated dynamically is one of the things that makes the build system so powerful.

-

Anatomy of a Simple C++ Extension(分析一个简单的C++扩展)

-

We assume that you are using C++ to write XPCOM components that can be used either from other C++ components or from JavaScript. The process of creating a component is actually relatively straightforward when the Mozilla build system is used.

-

In the simplest case, a component will consist of a single main directory with two subdirectories, public/ and src/. The main directory and each subdirectory must contain a Makefile.in (from now on I’ll just refer to this file as a makefile although we know that it is actually used to generate the real makefile). This makefile says two things. First of all, it lists the subdirectories that make up the extension, so the build system knows where to look for additional makefiles. Secondly, it instructs the build system to create a new extension, rather than copying the components directly into Firefox’s binary directory. The main advantage of using an extension is that it is easy to package everything up and install it on another machine.

-

So here’s your basic, plain-vanilla top-level makefile (Makefile.in in the main extension directory):

-
DEPTH		= ../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = myextension
-
-DIRS		= public src
-
-XPI_NAME		= myextension
-INSTALL_EXTENSION_ID	= myextension@mycompany.com
-XPI_PKGNAME		= myextension
-
-DIST_FILES = install.rdf
-
-include $(topsrcdir)/config/rules.mk
-
-

A detailed description of the make process, describing the key features of this makefile, can be found here. MODULE and XPI_NAME are both set to the name of your extension; they should be repeated in all project makefiles so that all of the files land in the same place in the XPI staging area (see below). INSTALL_EXTENSION_ID is the unique ID of your extension. This can be a GUID, but the format shown above is prettier and, let’s face it, a lot easier to remember. You don’t have to provide an XPI_PKGNAME, but if you do an XPI file, suitable for distribution, is automatically created in the root of the XPI staging area (/mozilla/$(MOZ_OBJDIR)/dist/xpi-stage/).

-

Every extension must include an install.rdf file that tells Firefox how to install it. This file should be located in the main extension directory and look something like this:

-
<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>myextension@mycompany.com</em:id>
-    <em:version>0.1</em:version>
-
-    <em:targetApplication>
-      <!-- Firefox -->
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>1.0+</em:minVersion>
-        <em:maxVersion>1.0+</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- front-end metadata -->
-    <em:name>My First Extension</em:name>
-    <em:description>Just an example.</em:description>
-    <em:creator>allpeers.com</em:creator>
-    <em:homepageURL>http://www.allpeers.com/blog/</em:homepageURL>
-  </Description>
-</RDF>
-
-

There's a detailed description of the format of the install.rdf file. Use the DIST_FILES variable in the makefile to tell make to copy the file into the extension directory and (optional) XPI file.

-

Public Interfaces(公共接口)

-

The public/ directory contains any interfaces that need to be accessed by other modules. These can be IDL files describing XPCOM interfaces, which are used to generate normal C++ header files for inclusion in your source files. They can also be normal C++ header files that are to be used directly by other modules. The easiest way to accomplish the latter is to use inline implementations for all methods so you don’t have any additional linking dependencies. Otherwise you will have to link statically to your module if you use these public headers in other modules. Personally I would discourage this practice (among other things, static linking means the same code gets loaded more than once into memory, and the code won’t be available from JavaScript or other non-C++ languages) and encourage the use of XPCOM wherever possible.

-

The makefile in the public/ directory should follow this model:

-
DEPTH		= ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= myextension
-XPIDL_MODULE	= myextension
-
-XPI_NAME = myextension
-
-EXPORTS = \
-		myHeader.h \
-		$(NULL)
-
-XPIDLSRCS	= \
-		myIFirstComponent.idl \
-		myISecondComponent.idl \
-		$(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
-

XPIDL_MODULE is the name of the generated XPT file that contains type information about your IDL interfaces. If you have multiple modules, make absolutely sure that you use a different value for XPIDL_MODULE for each one. Otherwise the first module’s XPT file will be overwritten by the second and you’ll get NS_ERROR_XPC_BAD_IID errors when you try to access its IDL interfaces from your code. The files under EXPORTS are copied directly to the /mozilla/$(MOZ_OBJDIR)/dist/include/myextension/ directory and are thus accessible from other modules (the value of MOZ_OBJDIR is defined in /mozilla/.mozconfig). XPIDLSRCS are run through the IDL processor, and the generated C++ headers are copied into the same include directory. In addition, an XPT (type library) file is generated and placed in the components/ subdirectory of your extension.

-

Source Files(源文件)

-

Now it’s time to create the makefile and source files in the src/ subdirectory. If you're implementing interfaces that you've described using IDL, the easiest way to do this is to leave the src/ directory empty and run make on the public/ directory only; this will be explained shortly.

-

Then open the generated header file for your interface from /mozilla/$(MOZ_OBJDIR)/dist/include/myextension/. It contains stubs for the component .H and .CPP files that you can copy and paste into your implementation files. All you have to do is fill in the implementation stubs in the C++ file and you’re good to go.

-

Here’s an example of the makefile you need to place into your src directory:

-
DEPTH		= ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-IS_COMPONENT = 1
-MODULE = myextension
-LIBRARY_NAME =  myExtension
-USE_STATIC_LIBS = 1
-
-XPI_NAME = myextension
-
-REQUIRES	= xpcom \
-		  string \
-		  $(NULL)
-
-CPPSRCS		= \
-		  myFirstComponent.cpp \
-		  mySecondComponent.cpp \
-		  myExtension.cpp \
-		  $(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
-EXTRA_DSO_LDOPTS += \
-  $(XPCOM_GLUE_LDOPTS) \
-  $(NSPR_LIBS) \
-  $(NULL)
-
-# NOTE: If you are coding against the 1.8.0 branch (not 1.8 branch or trunk), the
-# above line won't work, due to linker flag issues. Use the following
-# variables instead:
-#
-# EXTRA_DSO_LDOPTS += \
-#   $(MOZ_COMPONENT_LIBS) \
-#   $(NULL)
-#
-# Unfortunately, using MOZ_COMPONENT_LIBS links against xpcom_core, which means
-# your components will not work in future versions of Firefox.
-
-

The REQUIRES section tells make which modules your components uses. This causes the relevant subdirectories of /mozilla/$(MOZ_OBJDIR)/dist/include/ to be added to the C++ compiler's include path. If you’re including Mozilla headers and the compiler isn’t finding them, it could well mean that you haven’t listed all of the necessary modules here. CPPSRCS lists the source files that need to be built.

-

In this example, the first two files contain the implementation of the extension’s two components. The final file, myExtension.cpp, contains the code necessary to register these components, as described in the next section.

-

Registering Your Components(注册组件)

-

In order to use your components from other C++ modules and JavaScript, you first have to register them. To do this, your extension needs to implement a class that exposes the nsIModule interface, which has methods for accessing the components defined in a module. Luckily, this can be accomplished through the use of a few simple macros, so you don’t have to concern yourself with the messy details of what’s happening under the hood.

-

The first step is to define a CID, contract ID and class name for each of your components. Place the following code (adapting the #defines accordingly) into the header of each component that you want to be able to instantiate using the component manager:

-
// {00000000-0000-0000-0000-000000000000}
-#define MYFIRSTCOMPONENT_CID \
-	{ 0x00000000, 0x0000, 0x0000, \
-	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
-
-#define MYFIRSTCOMPONENT_CONTRACTID	"@mycompany.com/myfirst;1"
-#define MYFIRSTCOMPONENT_CLASSNAME	"My First Component"
-
-

Obviously you need to fill in the CID with a real GUID. Under Windows, this can be generated using guidgen.exe. Unix people can use uuidgen (comes standard with most unixes and Linux distros).

-

Now create the myExtension.cpp file like so:

-
#include "nsXPCOM.h"
-
-#include "nsIGenericFactory.h"
-
-/**
- * Components to be registered
- */
-#include "myFirstComponent.h"
-#include "mySecondComponent.h"
-
-NS_GENERIC_FACTORY_CONSTRUCTOR(myFirstComponent)
-NS_GENERIC_FACTORY_CONSTRUCTOR(mySecondComponent)
-
-//----------------------------------------------------------
-
-static const nsModuleComponentInfo components[] =
-{
-	{
-		MYFIRSTCOMPONENT_CLASSNAME,
-		MYFIRSTCOMPONENT_CID,
-		MYFIRSTCOMPONENT_CONTRACTID,
-		myFirstComponentConstructor
-	},
-	{
-		MYSECONDCOMPONENT_CLASSNAME,
-		MYSECONDCOMPONENT_CID,
-		MYSECONDCOMPONENT_CONTRACTID,
-		mySecondComponentConstructor
-	},
-};
-
-NS_IMPL_NSGETMODULE(MyExtension, components)
-
-

The NS_IMPL_NSGETMODULE macro creates the appropriate module object providing access to all of the components listed in the nsModuleComponentInfo array.

-

Building It(编译扩展)

-

As mentioned above, you’ll probably want to build your extension immediately after creating your IDL files in order to generate the C++ stubs for your component implementations. I’m assuming that you’ve already built Firefox successfully. If not, return immediately to the beginning of this article and don’t come back til you have a functioning firefox.exe. Do not pass go. Do not collect $200.

-

Still here? Okay, now we have to modify your .mozconfig (in the /mozilla/ root directory) so that your extension is built along with Mozilla. Add the following line at the end of the file:

-
ac_add_options --enable-extensions=default,myextension
-
-

Now launch make from the Mozilla root:

-
make -f client.mk build
-
-

Even if you have an up-to-date Firefox build, you’ll have to wait a while for make to recurse over the entire Mozilla source tree looking for new stuff (on my machine, which is pretty fast, this takes a good 10-15 minutes). Eventually it will reach your extension and generate a bunch of stuff under /mozilla/$(MOZ_OBJDIR)/:

- -

A lot of this stuff won’t get created on this first pass since make will gag when it doesn’t find the source files for your components. Don’t worry about this; all you need are the generated header files that contain the C++ implementation stubs. Go back and flesh out the C++ implementation of your components so that the build can complete next time. Remember that you should never, ever modify any of these generated files. Always modify the files used to generate them and rerun make. There might be exceptions to this rule, but if you’re changing the generated files directly, you’re probably doing something wrong.

-

The process of walking the entire Mozilla tree takes a long time. If you already have a Mozilla build, you can avoid this by creating a makefile for your extension directly. Go to the root of your $(MOZ_OBJDIR) and (from a bash-compatible shell) enter:

-
../build/autoconf/make-makefile extensions/myextension
-
-

If your $(MOZ_OBJDIR) is located outside your $(TOPSRCDIR), you'll need to do:

-
$(TOPSRCDIR)/build/autoconf/make-makefile -t $(TOPSRCDIR) extensions/myextension
-
-

in order for the script to know where your source is (it'll use the extension path you gave it relative to the current dir to figure out where you want your makefiles to go).

-

This will generate the proper makefile for your extension. Whether you build the whole Mozilla tree or take this shortcut, you can build from now on by going to /mozilla/$(MOZ_OBJDIR)/extensions/myextension/ and typing "make" on the command line. It should build your component without bothering with the rest of Mozilla. If everything works out, you’ll see your XPI file in the XPI staging area. You’ll also see the "exploded" version of the XPI (i.e. the unzipped directory structure) underneath /mozilla/$(MOZ_OBJDIR)/dist/bin/extensions. (If something goes wrong, figure out what, fix it and then come back here and add it to this article.)

-

To make sure that the build really finished, launch Firefox and check that your extension is listed when you select Tools/Extensions. If you are using Firefox as your regular browser (and if you’re not, why not!?), you might be annoyed by the fact that you have to close regular Firefox before running your custom-built version. If so, try setting the MOZ_NO_REMOTE environment variable to "1" before running the development version of Firefox. You’ll also need to use a different profile for your development version:

-
firefox -P development
-
-

Where development is replaced with the name of the extra profile you’ve created. This will let you run both versions of Firefox simultaneously, saving you oodles of time over the course of the build/test cycle.

-

No Place Like Chrome

-

Yippee-ki-yay! Now you have an extension that does, well, absolutely nothing. It’s time to do something with those groovy components that you’ve implemented and registered. The simplest way to do this is to write some JavaScript and XUL code. At this point, it would be very helpful to have a bit of experience writing "regular" extensions (i.e. without using custom C++ components). If you’ve never done this, I strongly recommend that you think of a cool idea for something simple that you’ve always wanted to tweak in Firefox and write it. Just displaying a new menu item that opens a "Hello, World!" dialog box would be already be a great exercise to get warmed up with.

-

Assuming you know how to write XUL/JavaScript extensions, you’re aware that the most important stuff goes in the chrome/ directory of your extension. Well, the fact that you’re also using C++ components doesn’t change that one whit. So now you need to create the normal content/, locale/ and skin/ directories in which to place your chrome files. Personally I like placing these directly under the root directory of my module, but I don’t suppose it makes any difference if you prefer putting them under a chrome/ subdirectory or whatever. Let freedom reign!

-

Once you’ve written the necessary chrome files (for instance, an overlay that adds a menu item to instantiate and use one of your components), you need to package them up as part of your extension. This is accomplished through the use of a JAR Manifest. For our simple extension example, this file might look something like this:

-
myextension.jar:
-%  content myextension %content/
-%  locale myextension en-US %locale/en-US/
-%  skin myextension classic/1.0 %skin/classic/
-%  overlay chrome://browser/content/browser.xul chrome://myextension/content/MyExtensionOverlay.xul
-	content/MyExtensionOverlay.js		(content/MyExtensionOverlay.js)
-	content/MyExtensionOverlay.xul		(content/MyExtensionOverlay.xul)
-	locale/en-US/MyExtension.dtd		(locale/en-US/MyExtension.dtd)
-	locale/en-US/MyExtension.properties	(locale/en-US/MyExtension.properties)
-	skin/classic/MyExtension.css		(skin/classic/MyExtension.css)
-
-

Place this code in a file called jar.mn in the root directory of your extension, making sure that the paths in parentheses point to actual files (when interpreted relative to the root directory). You also have to make one small change to the makefile in the same directory, adding the following line:

-
USE_EXTENSION_MANIFEST = 1
-
-

This tells make to create a single manifest file called chrome.manifest instead of creating separate manifests with goofy names for each package.

-

Now launch make again, and you should see a chrome subdirectory appear in your extension (/mozilla/$(MOZ_OBJDIR)/dist/bin/extensions/myextension@mycompany.com/). Note that the chrome directory contains a JAR (i.e. ZIP) file with all the chrome files listed in jar.mn as well as a complete directory structure mirroring that of the JAR file. The directory structure, however, is empty. Why? I don’t know. Don’t worry about this, the files in the JAR are the ones that are actually used.

-

Keeping it Complex

-

If you’re developing a really complex extension with lots of XPCOM components, you’ll probably want to divide your code up into smaller modules.

-
Kinda, Sorta Complex Extensions
-

For a moderately complex extension, it’s probably enough just to subdivide the code into a single level of modules. Let’s assume that you have a base/ module that defines a bunch of basic XPCOM components and an advanced/ module that defines some chrome as well as other components that use the basic components. Your complete directory structure will look something like this:

- -

Other than that, nothing really changes. The makefiles in the base/ and advanced/ directories should look more or less like your original root makefile, remembering to change the DEPTH variable to account for the fact that they’ve moved a level further away from the Mozilla root. You also need to remove the DIST_FILES variable since that’s going to be in the top-level makefile. Every makefile that generates anything should define the XPI_NAME variable to make sure generated files go into your extension and not into the global components/ directory. In fact, just define this in every makefile to be safe. You can use the same MODULE in both base/ and advanced/ so that all the generated include files go into the same directory, but make sure that you don’t use the same XPIDL_MODULE in the two public/ directories or one of the component type libraries (i.e. XPT files) will overwrite the other one and all hell will break loose.

-

Each module must also have a different value for the LIBRARY_NAME variable. This is the name of the generated dynamic library, so if we call the libraries "myBase" and "myAdvanced", we’ll end up with myBase.dll and myAdvanced.dll (on Windows, at least). And each of these modules is going to have a separate C++ file for registering components. So there will be two files that look like myExtension.cpp in the original example, say Base.cpp and Advanced.cpp. Finally, each module will obviously have its own jar.mn, though they can reference the same JAR filename and package name if you want all the chrome files to be organized in a single JAR file and package. The only file that really stays put is install.rdf, which still exists once and only once in the extension root directory.

-

As for the top-level makefile, it will now look like this:

-
DEPTH		= ../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = myextension
-
-DIRS		= base advanced
-
-XPI_NAME               = myextension
-INSTALL_EXTENSION_ID   = myextension@mycompany.com
-XPI_PKGNAME		= myextension
-
-DIST_FILES = install.rdf
-
-include $(topsrcdir)/config/rules.mk
-
-
Seriously Complex Extensions
-

At some point, even a single module may grow to the point where you want to divide it further into submodules. The difference between having separate modules and having a single module with separate submodules is that the submodules all share the same file for registering components (the famous myExtension.cpp file), and when compiled they create a single dynamic library. The decision to split a module into submodules is all about code organization; it doesn’t really affect the final product at all.

-

To split a module into submodules, first create a subdirectory for each submodule. Then create an additional directory called build/. Each submodule will be configured to create a static library, and the build/ directory will pull these libraries together to create a single dynamic component library. Confused? Here’s an example, showing just the advanced/ subbranch of the myextension/ directory:

- -

As you can see, we’ve split advanced/ into two submodules: intricate/ and multifarious/, and we’ve added an additional build/ subdirectory. We’ve left the chrome directories directly under advanced/, since they aren’t tied to any specific submodule. This means that jar.mn will stay in the same place.

-

The intricate/ and multifarious/ makefiles will look a lot like the original advanced/ makefile, but we’ll need to tweak them a bit. As always, we have to adjust the DEPTH variable since the makefiles are deeper in the directory structure. And we should change the LIBRARY_NAME to indicate that we’re generating a static library for each submodule. By convention the "_s" suffix is used for this purpose. So let’s call them "myIntricate_s" and "myMultifarious_s". Finally, we define the variable FORCE_STATIC_LIB, resulting in a makefile that starts something like this:

-
DEPTH		= ../../../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = myextension
-LIBRARY_NAME = myIntricate_s
-FORCE_STATIC_LIB = 1
-USE_STATIC_LIBS = 1
-
-XPI_NAME = myextension
-
-...more stuff here...
-
-

The build makefile pulls together the static libraries generated by the submodules and creates a single (dynamic) component library:

-
DEPTH		= ../../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-IS_COMPONENT = 1
-MODULE = myextension
-LIBRARY_NAME = myAdvanced
-USE_STATIC_LIBS = 1
-
-XPI_NAME = myextension
-
-DEFINES += XPCOM_GLUE
-
-SHARED_LIBRARY_LIBS = \
-		$(DIST)/lib/$(LIB_PREFIX)myIntricate_s.$(LIB_SUFFIX) \
-		$(DIST)/lib/$(LIB_PREFIX)myMultifarious_s.$(LIB_SUFFIX) \
-                $(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
-                $(DIST)/lib/$(LIB_PREFIX)xpcom.$(LIB_SUFFIX) \
-                $(DIST)/lib/$(LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
-                $(DIST)/lib/$(LIB_PREFIX)plds4.$(LIB_SUFFIX) \
-                $(DIST)/lib/$(LIB_PREFIX)plc4.$(LIB_SUFFIX) \
-		$(NULL)
-
-REQUIRES	= \
-		xpcom \
-		string \
-		$(NULL)
-
-CPPSRCS		= \
-		Advanced.cpp \
-		$(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
-LOCAL_INCLUDES += \
-        -I$(srcdir)/../intricate/src \
-        -I$(srcdir)/../multifarious/src \
-        $(NULL)
-
-

The makefile in the advanced/ directory should list the intricate/, multifarious/ and build/ directories in its DIRS variable. Make sure that build/ comes last since it can’t create the component library until the other makefiles have completed.

-

Other Topics

-

Adding Data Files to Your Extensions

-

In some cases, you may wish to include additional files in your extension that don’t belong in the chrome/ subdirectory. Examples might be database files or XML schemas. This can be achieved by adding a custom step to your makefile that copies the files from the source tree into the extension’s target directory.

-
Copying Data Files Into Target Directory
-

Let’s say that you have some data files containing statistical information that you want to include in your extension and make available to your components. You’ve placed these files, which have the extension .TXT, into a stats/ subdirectory under your extension directory in the source tree. The following makefile rule can be used to copy these files into the final target directory of the extension:

-
export::
-	if test ! -d $(FINAL_TARGET)/stats; then \
-		$(NSINSTALL) -D $(FINAL_TARGET)/stats; \
-	fi
-	$(INSTALL) $(srcdir)/*.txt $(FINAL_TARGET)/stats
-
-
Accessing Data Files From Components
-

The trick to accessing your data files is to figure out where the home directory of your extension is. Rumor has it that at some future date, this will possible through the nsIExtensionManager interface or something similar. In the meantime, there is a simple and reliable hack that can be used to achieve this. In the implementation of any JavaScript XPCOM component, there is a special __LOCATION__ (two leading and two trailing underscores) symbol that points to the component’s implementation file. So you can write a simple component which deduces the root directory of your extensions by extrapolating from its location.

-

This article explains how to create an XPCOM component in JavaScript. You’ll need an IDL file for an interface that looks something like this:

-
interface myILocation : nsISupports
-{
-    readonly attribute nsIFile locationFile;
-};
-
-

Place the IDL file in the public/ directory of your project or subproject. In the src/ directory, place the JavaScript file that implements the component. The component implementation will include the methods for retrieving the path or file for the extension’s home directory:

-
myLocation.prototype =
-{
-  QueryInterface: function(iid)
-  {
-    if (iid.equals(nsISupports))
-      return this;
-    if (iid.equals(myILocation))
-      return this;
-
-    Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
-    return null;
-  },
-
-  get locationFile()
-  {
-     return __LOCATION__.parent.parent;
-  }
-}
-
-

This assumes that the component resides in a subdirectory of the extension directory (by convention, this directory is called components/). The parent property of __LOCATION__ returns the components/, and the parent of this is the extension directory.

-

The last step is to modify the makefile of the source directory where you placed your JavaScript file so that it is copied into the appropriate location in the extension:

-
export::
-	$(INSTALL) $(srcdir)/*.js $(FINAL_TARGET)/components
-
-

Now you can instantiate an instance of this component and use the locationFile property to get an nsIFile interface that points to your extension’s home directory.

-

Using Third-Party Libraries

-

For more sophisticated extensions, you may want to integrate third-party libraries that provide specialized functionality for database connectivity, image processing, networking and the like. If you want your extension to run on all Firefox platforms, you will need to have the source code for the library in question, so I assume that this is available.

-

The most convenient approach from the perspective of the development cycle is to create a Mozilla-style makefile for the library. This works well for libraries that have a straightforward make process without extensive configuration. A good example of this is the SQLite library included in the Mozilla build tree at db/sqlite. By adapting the makefile in this way, the library is created as part of the standard Mozilla build process, which eliminates additional build steps. The downside is that you will need to update the modified makefile any time a new version of the library is released.

-

For libraries that have complex configuration processes, use a non-standard compiler or have other special characteristics, it may be unfeasible to create a Mozilla-compliant makefile. In this case, I would recommend placing the entire library distribution inside the project or subproject that uses it. So if library acmelib is used inside the multifarious/ subproject in the above example, it would be placed as a subdirectory underneath that subproject (at the same level as public/ and src/).

-

Of course, this means that you will have to build acmelib manually on all platforms before launching the Mozilla build. But at least you can then refer to include files and import libraries from your component using relative paths.

-

Building for Multiple Platforms

-

TODO

-
-

Original Document Information

- -
-

 

diff --git a/files/zh-cn/mozilla/add-ons/creating_opensearch_plugins_for_firefox/index.html b/files/zh-cn/mozilla/add-ons/creating_opensearch_plugins_for_firefox/index.html deleted file mode 100644 index b03cc689c9..0000000000 --- a/files/zh-cn/mozilla/add-ons/creating_opensearch_plugins_for_firefox/index.html +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: 为 Firefox 创建 OpenSearch 插件 -slug: Mozilla/Add-ons/Creating_OpenSearch_plugins_for_Firefox -translation_of: Web/OpenSearch ---- -

{{ fx_minversion_header("2") }}

-

Firefox 2 支持使用 OpenSearch 格式开发搜索引擎插件. 使用 OpenSearch 格式开发能够在IE 7 以及 Firefox上实现兼容. 这是这种语法被推荐使用的原因.

-

Firefox 也支持不被包括在 OpenSearch格式  中的其它的搜索功能,例如搜索建议(search suggestion)以及 SearchForm 元素. 这篇文章主要关注创建与OpenSearch格式兼容的支持额外的firefox特殊特征的搜索插件.

-

OpenSearch 描述文件也能被如在 Autodiscovery of search plugins  中描述的一样被advertised(道歉这里不知如何翻译) ,并且能够如在 Adding search engines from web pages中所说的进行编程安装.

-

OpenSearch 描述文件

-

遵循以下的模板,你就会发现通过 XML 文件写一个搜索引擎实际上是如此的简单。 粗体字部分需要根据具体你所写的搜索引擎需要来进行定制 。

-
<?xml version="1.0" encoding="UTF-8"?>
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
-                       xmlns:moz="http://www.mozilla.org/2006/browser/search/">
-  <ShortName>engineName</ShortName>
-  <Description>engineDescription</Description>
-  <InputEncoding>inputEncoding</InputEncoding>
-  <Image width="16" height="16" type="image/x-icon">data:image/x-icon;base64,imageData</Image>
-  <Url type="text/html" method="method" template="searchURL">
-    <Param name="paramName1" value="paramValue1"/>
-    ...
-    <Param name="paramNameN" value="paramValueN"/>
-  </Url>
-  <Url type="application/x-suggestions+json" template="suggestionURL"/>
-  <moz:SearchForm>searchFormURL</moz:SearchForm>
-</OpenSearchDescription>
-
-
- ShortName
-
- 对搜索引擎的简称
-
- 限制: 名称仅能包含16个字符以下的纯文本. 名称不能包含HTML标志或其他标志.
-
-
-
- Description
-
- 对于搜索引擎的简单描述
-
- 限制: 描述仅能包含少于1024个字符的纯文本.  名称不能包含HTML标志或其他标志.
-
-
-
- InputEncoding
-
- 向搜索引擎所输内容的字符编码.例如: <InputEncoding>UTF-8</InputEncoding>.
-
-
-
- Image
-
- 使用指向一个图标的URL来代表这个搜索引擎. 可能的话, 应提供16x16大小的"image/x-icon"类型的图像以及一个64x64大小的 "image/jpeg" 或 "image/png"类型的图像. 链接也可以使用 data: URI schemeThe data: URI kitchen在这能找到一个能有效地帮助你构建写在此处的数据的工具. -
<Image height="16" width="16" type="image/x-icon">http://example.com/favicon.ico</Image>
-  OR
-<Image height="16" width="16">data:image/x-icon;base64,AAABAAEAEBAAA ... DAAA=</Image>
-
- Firefox以base64编码的data: URI (搜索插件被保存在 profile中的 "searchplugins" 文件夹) 缓存此图标. 当这完成时, http: URIs 被改变为 data: URIs.
-
-
-
- Url
-
- 描述用来实现搜索请求的一个或多个URL.  method 属性决定使用 GET 还是 POST请求来获取返回的数据. template 属性指定实现搜索请求的 URL.
-
-
- 注意: IE7 不支持 POST 请求.
-
-
-
-
- 这是两种firefox支持的URL类型:
-
- -
-
- 这两种URL任何一种你都能使用 {searchTerms}来替换用户在搜索栏中输入的搜索内容. 其他支持的动态搜索参数可见 OpenSearch 1.1 parameters.
-
-
-
- 对使用搜索建议查询来说,  URL template用来获取JSON格式的建议列表. 若需要知道关于如何在服务器上实现搜索建议支持, 请见 Supporting search suggestions in search plugins.
-
-

Image:SearchSuggestionSample.png

-
-
- Param
-
- 这个参数用来包括那些需要和搜索查询一起被传递的作为键值对的参数. 你能使用{searchTerms}来指代用户输入的搜索条目.
-
-
- 注意: IE7不支持此元素.
-
-
-
-
- SearchForm
-
- 跳往搜索页的 URL. 这使得Firefox能让用户直接浏览目的网站.
-
-
- 注意: 这个元素是firefox限定的, 并不是 OpenSearch 的一部分, 我们在例子中使用 "moz:" XML命名前缀来确保其它的不支持此元素的用户代理能安全地忽略此元素.
-
-
-

自动搜寻搜索插件

-

提供搜索插件的网站能宣传自己以使firefox使用者能容易地下载并安装此插件.

-

要支持自动搜寻 你仅需在 你网页的<head> 中加上一条:

-
<link rel="search" type="application/opensearchdescription+xml" title="searchTitle" href="pluginURL">
-
-

斜体字部分解释如下:

-
-
- searchTitle
-
- 搜索的名称, 如 "Search MDC" or "Yahoo! Search". 这个值应该与你在插件文件中的ShortName相一致.
-
-
-
- pluginURL
-
- 指向 XML搜索插件的URL, 能让浏览者下载插件.
-
-

如果你的网站提供多个插件, 你能为他们每一个都支持自动搜寻功能. 例如:

-
<link rel="search" type="application/opensearchdescription+xml" title="MySite: By Author" href="http://www.mysite.com/mysiteauthor.xml">
-<link rel="search" type="application/opensearchdescription+xml" title="MySite: By Title" href="http://www.mysite.com/mysitetitle.xml">
-
-

这样,你的网站提供的插件就能同时以作者和名称分别作为搜索条目而被搜索.

-

为 OpenSearch 插件支持自动更新

-

{{ fx_minversion_note("3.5", "This section covers a feature introduced in Firefox 3.5.") }}

-

从Firefox 3.5开始, OpenSearch 插件能够自动更新.  要支持这个, 需要包括一个额外的 "application/opensearchdescription+xml"类型Url 元素.  rel属性需要设为 "self" , template 属性需要是指向能自动更新的OpenSearch文档的 URL.

-

例如:

-
<Url type="application/opensearchdescription+xml"
-     rel="self"
-     template="http://www.foo.com/mysearchdescription.xml" />
-
-
- 注意:  addons.mozilla.org (AMO) 不支持 OpenSearch 插件的自动更新. 如果你想将你的插件发布在 AMO上, 你不应该使用自动更新.
-

排错指南

-

如果你的搜索插件有错误, 当在firefox2中添加插件时会出错. 然而,错误信息可能并不是完全有所帮助的, 因此接下来的建议能帮你发现问题.

- -

另外, 搜索插件服务提供了日志机制,这对于插件开发者来说可能能起到一定作用 . 使用 about:config 设定 'browser.search.log' 为 true. 插件被加载后日志信息将显示在火狐的 Error Console 中(Tools->Error Console).

-

参考资料

- -

{{ languages( { "es": "es/Creación_de_plugins_OpenSearch_para_Firefox", "de": "de/OpenSearch_Plugin_für_Firefox_erstellen", "ca": "ca/Creació_de_connectors_OpenSearch_per_al_Firefox", "fr": "fr/Création_de_plugins_OpenSearch_pour_Firefox", "ja": "ja/Creating_OpenSearch_plugins_for_Firefox", "pl": "pl/Tworzenie_wtyczek_OpenSearch_dla_Firefoksa", "pt": "pt/Criando_plugins_OpenSearch_para_o_Firefox" } ) }}

diff --git a/files/zh-cn/mozilla/add-ons/creating_opensearch_plugins_for_firefox_clone/index.html b/files/zh-cn/mozilla/add-ons/creating_opensearch_plugins_for_firefox_clone/index.html deleted file mode 100644 index 5c511cc132..0000000000 --- a/files/zh-cn/mozilla/add-ons/creating_opensearch_plugins_for_firefox_clone/index.html +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: 为 Firefox 创建 OpenSearch 插件 -slug: Mozilla/Add-ons/Creating_OpenSearch_plugins_for_Firefox_clone -tags: - - 定制 - - 搜索 ---- -

{{ fx_minversion_header("2") }}

- -

Firefox 2 支持使用 OpenSearch 格式开发搜索引擎插件. 使用 OpenSearch 格式开发能够在IE 7 以及 Firefox上实现兼容. 这是这种语法被推荐使用的原因.

- -

Firefox 也支持不被包括在 OpenSearch格式  中的其它的搜索功能,例如搜索建议(search suggestion)以及 SearchForm 元素. 这篇文章主要关注创建与OpenSearch格式兼容的支持额外的firefox特殊特征的搜索插件.

- -

OpenSearch 描述文件也能被如在 Autodiscovery of search plugins  中描述的一样被advertised(道歉这里不知如何翻译) ,并且能够如在 Adding search engines from web pages中所说的进行编程安装.

- -

OpenSearch 描述文件

- -

遵循以下的模板,你就会发现通过 XML 文件写一个搜索引擎实际上是如此的简单。 粗体字部分需要根据具体你所写的搜索引擎需要来进行定制 。

- -
<?xml version="1.0" encoding="UTF-8"?>
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
-                       xmlns:moz="http://www.mozilla.org/2006/browser/search/">
-  <ShortName>engineName</ShortName>
-  <Description>engineDescription</Description>
-  <InputEncoding>inputEncoding</InputEncoding>
-  <Image width="16" height="16" type="image/x-icon">data:image/x-icon;base64,imageData</Image>
-  <Url type="text/html" method="method" template="searchURL">
-    <Param name="paramName1" value="paramValue1"/>
-    ...
-    <Param name="paramNameN" value="paramValueN"/>
-  </Url>
-  <Url type="application/x-suggestions+json" template="suggestionURL"/>
-  <moz:SearchForm>searchFormURL</moz:SearchForm>
-</OpenSearchDescription>
- -
-
ShortName
-
对搜索引擎的简称
-
限制: 名称仅能包含16个字符以下的纯文本. 名称不能包含HTML标志或其他标志.
-
- -
-
Description
-
对于搜索引擎的简单描述
-
限制: 描述仅能包含少于1024个字符的纯文本.  名称不能包含HTML标志或其他标志.
-
- -
-
InputEncoding
-
向搜索引擎所输内容的字符编码.例如: <InputEncoding>UTF-8</InputEncoding>.
-
- -
-
Image
-
使用指向一个图标的URL来代表这个搜索引擎. 可能的话, 应提供16x16大小的"image/x-icon"类型的图像以及一个64x64大小的 "image/jpeg" 或 "image/png"类型的图像. 链接也可以使用 data: URI schemeThe data: URI kitchen在这能找到一个能有效地帮助你构建写在此处的数据的工具. -
<Image height="16" width="16" type="image/x-icon">http://example.com/favicon.ico</Image>
-  OR
-<Image height="16" width="16">data:image/x-icon;base64,AAABAAEAEBAAA ... DAAA=</Image>
-
- Firefox以base64编码的data: URI (搜索插件被保存在 profile中的 "searchplugins" 文件夹) 缓存此图标. 当这完成时, http: URIs 被改变为 data: URIs.
-
- -
-
Url
-
描述用来实现搜索请求的一个或多个URL.  method 属性决定使用 GET 还是 POST请求来获取返回的数据. template 属性指定实现搜索请求的 URL.
-
-
注意: IE7 不支持 POST 请求.
-
-
- -
-
这是两种firefox支持的URL类型:
-
- - - -
-
这两种URL任何一种你都能使用 {searchTerms}来替换用户在搜索栏中输入的搜索内容. 其他支持的动态搜索参数可见 OpenSearch 1.1 parameters.
-
- -
-
对使用搜索建议查询来说,  URL template用来获取JSON格式的建议列表. 若需要知道关于如何在服务器上实现搜索建议支持, 请见 Supporting search suggestions in search plugins.
-
- -

Image:SearchSuggestionSample.png

- -
-
Param
-
这个参数用来包括那些需要和搜索查询一起被传递的作为键值对的参数. 你能使用{searchTerms}来指代用户输入的搜索条目.
-
-
注意: IE7不支持此元素.
-
-
- -
-
SearchForm
-
跳往搜索页的 URL. 这使得Firefox能让用户直接浏览目的网站.
-
-
注意: 这个元素是firefox限定的, 并不是 OpenSearch 的一部分, 我们在例子中使用 "moz:" XML命名前缀来确保其它的不支持此元素的用户代理能安全地忽略此元素.
-
-
- -

自动搜寻搜索插件

- -

提供搜索插件的网站能宣传自己以使firefox使用者能容易地下载并安装此插件.

- -

要支持自动搜寻 你仅需在 你网页的<head> 中加上一条:

- -
<link rel="search" type="application/opensearchdescription+xml" title="searchTitle" href="pluginURL">
-
- -

斜体字部分解释如下:

- -
-
searchTitle
-
搜索的名称, 如 "Search MDC" or "Yahoo! Search". 这个值应该与你在插件文件中的ShortName相一致.
-
- -
-
pluginURL
-
指向 XML搜索插件的URL, 能让浏览者下载插件.
-
- -

如果你的网站提供多个插件, 你能为他们每一个都支持自动搜寻功能. 例如:

- -
<link rel="search" type="application/opensearchdescription+xml" title="MySite: By Author" href="http://www.mysite.com/mysiteauthor.xml">
-<link rel="search" type="application/opensearchdescription+xml" title="MySite: By Title" href="http://www.mysite.com/mysitetitle.xml">
-
- -

这样,你的网站提供的插件就能同时以作者和名称分别作为搜索条目而被搜索.

- -

为 OpenSearch 插件支持自动更新

- -

{{ fx_minversion_note("3.5", "This section covers a feature introduced in Firefox 3.5.") }}

- -

从Firefox 3.5开始, OpenSearch 插件能够自动更新.  要支持这个, 需要包括一个额外的 "application/opensearchdescription+xml"类型Url 元素.  rel属性需要设为 "self" , template 属性需要是指向能自动更新的OpenSearch文档的 URL.

- -

例如:

- -
<Url type="application/opensearchdescription+xml"
-     rel="self"
-     template="http://www.foo.com/mysearchdescription.xml" />
-
- -
注意:  addons.mozilla.org (AMO) 不支持 OpenSearch 插件的自动更新. 如果你想将你的插件发布在 AMO上, 你不应该使用自动更新.
- -

排错指南

- -

如果你的搜索插件有错误, 当在firefox2中添加插件时会出错. 然而,错误信息可能并不是完全有所帮助的, 因此接下来的建议能帮你发现问题.

- - - -

另外, 搜索插件服务提供了日志机制,这对于插件开发者来说可能能起到一定作用 . 使用 about:config 设定 'browser.search.log' 为 true. 插件被加载后日志信息将显示在火狐的 Error Console 中(Tools->Error Console).

- -

参考资料

- - - -

{{ languages( { "es": "es/Creación_de_plugins_OpenSearch_para_Firefox", "de": "de/OpenSearch_Plugin_für_Firefox_erstellen", "ca": "ca/Creació_de_connectors_OpenSearch_per_al_Firefox", "fr": "fr/Création_de_plugins_OpenSearch_pour_Firefox", "ja": "ja/Creating_OpenSearch_plugins_for_Firefox", "pl": "pl/Tworzenie_wtyczek_OpenSearch_dla_Firefoksa", "pt": "pt/Criando_plugins_OpenSearch_para_o_Firefox" } ) }}

diff --git a/files/zh-cn/mozilla/add-ons/extension_frequently_asked_questions_move/index.html b/files/zh-cn/mozilla/add-ons/extension_frequently_asked_questions_move/index.html deleted file mode 100644 index 6b9e091642..0000000000 --- a/files/zh-cn/mozilla/add-ons/extension_frequently_asked_questions_move/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: 扩展的常见问题解答 -slug: Mozilla/Add-ons/Extension_Frequently_Asked_Questions_move -translation_of: Archive/Mozilla/Extension_Frequently_Asked_Questions ---- -

这里是关于扩展开发中最常见问题的解答集锦。其中的绝大多数是关于 FireFox 的,但是大部分能够方便的移植到 SeaMonkey,Thunderbird 或其它 Mozilla 应用上。

-

如果你还不知道怎么开始,可以先看看我们的教程:构建一个扩展或者 MozillaZine 上的新手教程。然后用扩展向导创建一个供开始用的简单扩展。

-

不要忘记先设置好扩展的开发环境

-

调试

-

调试之前先设置扩展的开发环境

-

如果调试的代码很复杂,可能会用到 Venkman JavaScript 调试器。在用 Venkman 调试扩展代码之前需要把 "Debug -> Exclude Browser Files" 选项勾掉。

-

怎样记录代码中的错误?

-

javascript.options.showInConsole 设为 true,这样错误就会被记录在错误控制台中,使得 bug 容易追踪些。

-

怎样显示扩展当前状态?

-

要想显示变量值,调试消息等,可以使用 alert(),dump() ,Components.utils.reportError() 或者控制台服务。当然也可以用 Venkman 调试器。

-

为什么我的脚本不能正确运行?

-

如果你的脚本不能如预期运行,第一个要检查的是错误控制台(参见#)。

-

访问尚未加载完毕的 DOM 也常常是错误的来源。这种错误通常是因为初始化代码被放在程序顶层(即所有函数之外)。通过监听 load 事件延期执行初始化代码可以解决这个问题(load 事件表示窗口已经加载完毕):

-
function exampleBrowserStartup(event)
-{
-  // 初始化代码
-}
-window.addEventListener("load", exampleBrowserStartup, false);
-
-

 

-

不能访问网页的文档(document)对象

-

要从 browser.xul 这个 overlay 中访问当前网页,应当使用 content.document 而不是 document。这是因为 document 表示浏览器窗口自身。更多信息参考 Working with windows in chrome code

-

无法在扩展中使用 XMLHttpRequest

-

使用 XMLHttpRequest 发送接收信息时,一般都需要做跨域(crosss domain)操作。 一般来说跨域很麻烦,但因为在 chrome 窗口内发起请求时,是在安全区域内的,所以请求会被默许。

-

You need to make sure that you are initializing the cross domain XMLHttpRequest from JavaScript code that is referencing a XUL window. If you try and execute the request in relation to the browser content document, as opposed to the "document" of the XUL window, you will receive a Permission Denied error.

-

XML 文件是规范的,但是却出现 XML 解析错误!

-

示例代码

-

得到更多帮助

-

 

-

 

diff --git a/files/zh-cn/mozilla/add-ons/extension_packaging/index.html b/files/zh-cn/mozilla/add-ons/extension_packaging/index.html deleted file mode 100644 index 8057385c7c..0000000000 --- a/files/zh-cn/mozilla/add-ons/extension_packaging/index.html +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: 扩展打包 -slug: Mozilla/Add-ons/Extension_Packaging -tags: - - Extensions - - Toolkit API -translation_of: Archive/Add-ons/Extension_Packaging ---- -

 

-

扩展为一种可安装包的形式,它可以由使用者下载并安装,或者是由外部程序或应用程序提供的预安装包。扩展使用目录结构,此结构提供有chrome,components,和其他文件以扩展XUL程序的功能。

-

每个扩展必须提供一个install.rdf文件,包含关于扩展的元数据,例如唯一的ID,版本,作者,和兼容性信息。

-

扩展文件和install.rdf准备好之后,有几种方法准备扩展以便安装:将扩展目录ZIP打包为用户可安装的XPI(xpinstall)文件,直接将扩展解开到用户程序或设置目录中,或将扩展注册到Windows注册表中。

-

制作扩展XPI

-

一个XPI (XPInstall) 文件就是一个简单的ZIP文件,包括了扩展文件,install.rdf文件在ZIP的根目录中。使用者可以从网站上下载或者从本地安装XPI文件,将其打开或拖拽到扩展管理窗口。

-

XPI文件的MIME类型被Firefox识别为 - - application/x-xpinstall - ,因为大多数HTTP服务器不能够默认设置为将.xpi返回MIME类型。在Apache HTTP服务器上,可以在设置文件或.htaccess中增加以下命令来实现:

-
AddType application/x-xpinstall .xpi
-
-

直接安装扩展文件

-

如果你知道程序的位置(例如,如果你作为应用程序安装者的角色来安装扩展),你可以直接将扩展文件安装到<appdir>/extensions/<extensionID>中。在下次程序启动的时候扩展管理器会自动找到此扩展。

-

当使用此方法的时候你必须核实以确保系统允许扩展目录和文件正确设置。否则,扩展管理器在此扩展下不能够正确运行,或者扩展本身不能正确工作。

-

使用Windows注册表工具注册扩展所在目录

-

外部安装程序(例如Java虚拟机)也许希望将应用程序整合点作为扩展安装,即便是应用程序还没有安装。这可以在Windows中使用注册表来完成。

-

多条目扩展 XPIs

-

在有些情况下也许希望用单独的XPI文件安装多个扩展/主题。一种特殊的扩展XPI称为多条目包,用来解释如何创建此类型的扩展包。(需要Firefox 1.5/XULRunner 1.8。)

-

Toolkit API的官方参考

-

-

diff --git a/files/zh-cn/mozilla/add-ons/install_manifests/index.html b/files/zh-cn/mozilla/add-ons/install_manifests/index.html deleted file mode 100644 index 936ae3fb86..0000000000 --- a/files/zh-cn/mozilla/add-ons/install_manifests/index.html +++ /dev/null @@ -1,363 +0,0 @@ ---- -title: 安装清单 -slug: Mozilla/Add-ons/Install_Manifests -tags: - - bug-840092 - - bug-840092-dup -translation_of: Archive/Add-ons/Install_Manifests ---- -

简介

-

安装清单是一个附加文件,具有Add-on的XUL程序(例如火狐或者雷鸟),用这个文件来确定即将要安装的add-on的安装信息。他包含了add-on的元数据验证、创建者信息、add-on的详细介绍页面地址、版本号、如何更新、兼容性、等等。

-

安装清单的格式是 RDF/XML.

-

这个文件名字必须为 install.rdf 并且必须放在 XPI 文件的根目录。

-

结构

-

安装清单的最基本结构如下:

-
-
<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-  <Description about="urn:mozilla:install-manifest">
-    <!-- properties -->
-  </Description>
-</RDF>
-
-
-

有些属性是是必须的,有些是可选的。有些属性只是简单的字符串啥啥啥的,有些属性会很复杂。

-

必要的属性

-

你的清单必须要包含下面的这些属性,不听话的话,你的add-on是不会安装成功滴。

-

id

-

id是一个这样子的东东:

- -
extensionname@example.org
-

后面的这个格式更容易生成和操作。火狐1.5已经检测你的id,确保它是属于第一种格式还是其他格式,并且让那些id格式乱七八糟的add-on不会被安装。

-

例如:

-
<em:id>extensionname@example.org</em:id>
-
-<em:id>{daf44bf7-a45e-4450-979c-91cf07434c3d}</em:id>
-

版本

-

一个标志当前add-on版本的字符串。

-

对于火狐/雷鸟1.0来说,这个格式必须满足这里所说的要求: Extension Versioning, Update and Compatibility. 对于火狐/雷鸟1.5, 看这里:Toolkit version format.

-

示例:

-
<em:version>2.0</em:version>
-
-<em:version>1.0.2</em:version>
-
-<em:version>0.4.1.2005090112</em:version>
-

Firefox 1.5 / XULRunner 1.8 - add-ons that do not use a valid version format will not be installed. The version format is different from, although backwards-compatible with, 1.0's.

-

For addons hosted on addons.mozilla.org - Mozilla's update website may repackage your add-on and correct or reject malformed version strings.

-

类型

-

一个整数代表add-on的类型

- - - - - - - - - - - - - - - - - - - - - - - -
2扩展
4主题
8地区(译者注:多语言)
32多个物品包
64拼写检测字典
-

例如:

-
<em:type>2</em:type>
-

{{ Fx_minversion_inline(1.5) }} This property was added for Firefox 1.5, and is only required for add-on types other than Extensions and Themes.

-

{{ Fx_minversion_inline(3) }} Firefox 2 and previous supported a value of 16 to represent plug-ins. In Firefox 3 this has been removed.

-

targetApplication

-

An object specifying an application targeted by this add-on. This means that the add-on will work with the application identified by the id property (<em:id>) specified (for a comprehensive list of application IDs and valid min/maxVersions for them see Valid application versions for add-on developers), from the minimum version (<em:minVersion>) up to and including the maximum version (<em:maxVersion>). These version strings are formatted in the same fashion as the version property and will be compared to the application version; this allows the extension author to specify which versions of Firefox an extension has been tested with.

-

id, minVersion, and maxVersion are all required.

-
- Extensions compatible with Firefox 3.5 should specify a maxVersion of 3.5.*, so that they are automatically compatible with security and stability updates. For Firefox 3.0, a maxVersion of 3.0.* should be used. Extensions compatible only with Firefox or Thunderbird 2 should specify a maxVersion of 2.0.0.*.
-

The Install Manifest must specify at least one of these objects, and may specify more if the add-on targets multiple applications that support the Add-on Manager (e.g. Firefox and Thunderbird)

-

Examples

-
<em:targetApplication>
- <Description>
-  <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!--Firefox-->
-  <em:minVersion>1.5</em:minVersion>
-  <em:maxVersion>3.0.*</em:maxVersion>
- </Description>
-</em:targetApplication>
-

{{ Fx_minversion_inline(3) }} Gecko 1.9 based applications allow you to use the special targetApplication id toolkit@mozilla.org to say that the add-on is compatible with any toolkit app with a toolkit version matching the minVersion and maxVersion.

-

name

-

The name of the add-on; intended for display in the UI.

-

Examples

-
<em:name>My Extension</em:name>
-

Optional Property Reference

-

You may need to supply these properties, depending on the capabilities of your add-on.

-

bootstrap

-

{{ Fx_minversion_inline(4) }} A Boolean value that tells the application whether the extension is boot-strappable. At the moment this only works for add-ons with em:type="2". The default value is false. For more information, see Bootstrapped extensions.

-

unpack

-

{{ Fx_minversion_inline(4) }} A true or false value that tells the application whether the extension requires its files be unpacked into a directory in order to work or whether the extension can be loaded direct from the XPI. In versions before Gecko 2.0 all extensions were unpacked, in Gecko 2.0 and later the default is to not unpack. If an extension includes the following then it must request unpacking:

- -

Examples

-
<Description about="urn:mozilla:install-manifest">
-   <em:id>extension@mysite.com</em:id>
-   <em:unpack>true</em:unpack>
-   ...
-</Description>
-

localized

-

{{ Fx_minversion_inline(3) }} Allows you to localize the add-on's name, description, contributors and other metadata. The localized description must specify at least one em:locale which indicates which locales to use this information for.

-

Examples

-

This declares a set of add-on metadata to be displayed when the application is running in the de-DE locale.

-
<em:localized>
-  <Description>
-    <em:locale>de-DE</em:locale>
-    <em:name>Tab Sidebar</em:name>
-    <em:description>Zeigt in einer Sidebar Vorschaubilder der Inhalte aller offenen Tabs an.</em:description>
-  </Description>
-</em:localized>
-

The following properties which are described elsewhere in this page can be included in the localized property:

- -

More documentation can be found at Localizing extension descriptions.

-

description

-

A short description of the add-on - intended for display in the user interface. This description should fit on one short line of text.

-

Examples

-
<em:description>Advanced foo tools.</em:description>
-

creator

-

The name of the creator/principal developer - intended for display in the user interface.

-

Examples

-
<em:creator>John Doe</em:creator>
-

or

-
<em:creator>CoolExtension Team</em:creator>
-

developer

-

{{ Fx_minversion_inline(2) }} The name(s) of co-developers. You may specify more than one of this value to specify multiple developers.

-

Examples

-
<em:developer>Jane Doe</em:developer>
-<em:developer>Koos van der Merwe</em:developer>
-
-

translator

-

{{ Fx_minversion_inline(2) }} The name(s) of translators. You may specify more than one of this value to specify multiple translators.

-

Examples

-
<em:translator>Janez Novak</em:translator>
-<em:translator>Kari Nordmann</em:translator>
-
-

contributor

-

The name(s) of additional contributors. You may specify more than one of this value to specify multiple contributors.

-

Examples

-
<em:contributor>John Doe</em:contributor>
-
-<em:contributor>John Doe</em:contributor>
-<em:contributor>Jane Doe</em:contributor>
-<em:contributor>Elvis Presley</em:contributor>
-
-

homepageURL

-

A link to the add-on's home page - intended for display in the user interface.

-

Examples

-
<em:homepageURL>http://www.foo.com/</em:homepageURL>
-
-

updateURL

-

A link to a custom Update Manifest file that specifies available updates to the add-on. The format is described below. If enabled, the add-on manager periodically checks with this Manifest file to determine if newer versions are available.

-
- Note: It is strongly recommended that the updateURL be an HTTPS (secure) link. Non-secure update URLs can be hijacked by a malicious update.rdf file, enabling malware to infiltrate the user's computer. Alternatively, you could host your extension on AMO and leave out the updateURL completely. This provides secure updates automatically.
-

{{ Fx_minversion_inline(3) }} For security reasons, Gecko 1.9 applications require that if you specify an updateURL, it must be an https URL, or you must include an updateKey.

-

Your server must send this file as text/rdf, text/xml or application/xml+rdf or the update checker may not work.

-

The addon manager will substitute the following values into this URL in case you wish to generate the response RDF dynamically, such as using PHP or CGI:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
%REQ_VERSION%The version of the request. Currently 1
%ITEM_ID%The id of the addon being updated
%ITEM_VERSION%The version of the addon being updated
%ITEM_MAXAPPVERSION%The maxVersion of the targetApplication object corresponding to the current application for the addon being updated.
%ITEM_STATUS%{{ Fx_minversion_inline(2) }} Comma separated list of the add-ons operating status in the application. Contains at the least either userEnabled or userDisabled plus any number of incompatible, blockslisted or needsDependencies.
%APP_ID%The id of the current application
%APP_VERSION%The version of the application to check for updates for
%CURRENT_APP_VERSION%{{ Fx_minversion_inline(3.5) }} The version of the current application
%APP_OS%{{ Fx_minversion_inline(1.5) }} The value of OS_TARGET from the Firefox build system, identifying the operating system being used.
%APP_ABI%{{ Fx_minversion_inline(1.5) }} The value of the TARGET_XPCOM_ABI value from the Firefox build system, identifying the compiler/architecture combination used to compile the current application.
%APP_LOCALE%{{ Fx_minversion_inline(3) }} The current application's locale.
%UPDATE_TYPE%{{ Fx_minversion_inline(4) }} UPDATE_TYPE_COMPATIBILITY(32), UPDATE_TYPE_NEWVERSION(64)
%COMPATIBILITY_MODE%{{ Fx_minversion_inline(10) }} related to default to compatible, values could be normal, ignore or strict.
-

Examples

-
<em:updateURL>http://www.foo.com/update.cgi?id=%ITEM_ID%&amp;version=%ITEM_VERSION%</em:updateURL>
-<em:updateURL>http://www.foo.com/extension/windows.rdf</em:updateURL>
-
-

For add-ons hosted on addons.mozilla.org: You may not specify an updateURL property. By default, Mozilla applications using the Add-on Manager (such as Firefox and Thunderbird) will send update requests to addons.mozilla.org using the default web service. Every time you upload a new version of your add-on or change its compatibility parameters through the author interface, your update manifest will be generated automatically. Add-ons currently marked as experimental will not be updated due to security concerns.

-

Format of the Update Manifest: The Update Manifest is a RDF/XML datasource. For examples of an update manifest, see Extension Versioning, Update and Compatibility and Enabling Extension Updates (external).

-

updateKey

-
- {{ Gecko_minversion_header(1.9) }} {{ Fx_minversion_header(3) }}
-

To ensure the security of update rdf data that is retrieved over plain http you must use a digital signature to verify the contents of the data. In order to do so you must include the public part of the cryptographic key in an updateKey entry in the install.rdf of the add-on. This can be generated using the McCoy tool. Any line breaks and whitespace as part of this entry are ignored.

-
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
-              Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
-              NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
-              awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
-
-

optionsURL

-

The chrome:// URL of the extension's options dialog box. This is only useful to extensions. If this property is specified, when the extension is selected in the Extensions list, the Options button is enabled and will show this.

-
<em:optionsURL>chrome://myext/content/options.xul</em:optionsURL>
-

{{ gecko_minversion_note("7", "In Firefox 7 you can also simply include your options XUL as a file named options.xul, in the base directory of the add-on.") }}

-

{{ h3_gecko_minversion("optionsType", 7) }}

-

The type of user-interface used for displaying the options. Accepted values are:

- - - - - - - - - - - - - - - -
1Opens optionsURL in a dialog box
2Options are displayed inside the Add-on Manager
3Opens optionsURL in a new tab (if the application supports that), or a dialog box
-

optionsType defaults to 1 if there is an optionsURL included in install.rdf or 2 if there is no optionsURL and the file options.xul exists in the root of the add-on.

-
<em:optionsType>2</em:optionsType>
-
-

aboutURL

-

The chrome:// URL of the extension's about dialog box. This is only useful to extensions. If this property is specified, when the extension is selected in the Extensions list, the About... link in the extension's context menu will show this dialog, rather than the default.

-
-

{{ gecko_callout_heading("2.0") }}

-

The dialog receives the Addon object representing your add-on as a parameter.

-
-

Examples

-
<em:aboutURL>chrome://myext/content/about.xul</em:aboutURL>
-
-

iconURL

-

A chrome:// URL to an icon to display in the add-ons list. The icon will be displayed at 32x32 in Firefox 3.6 and lower. In Firefox 4.0 and later the icon can be up to 48x48 pixels in size. If this property is not specified, a default icon is used.

-
<em:iconURL>chrome://myext/skin/icon.png</em:iconURL>
-
-
- Note: For the above example to work you will also have to add a skin package line to your chrome.manifest file. See Chrome Registration#skin. Alternatively you can place your icon in the directory specified in your content package line.
-

{{ gecko_minversion_note("1.9.2", "Starting in Gecko 1.9.2 (Firefox 3.6), you can also simply include your icon, named icon.png, in the base directory of the add-on. This allows your add-on's icon to be displayed even when the add-on is disabled, or if the manifest is missing an iconURL entry.") }}

-

{{ h3_gecko_minversion("icon64URL", "2.0") }}

-

A chrome:// URL to a 64x64 pixel icon to display in the add-on's details view . If this property is not specified, the smaller icon above will be used.

-
<em:icon64URL>chrome://myext/skin/icon64.png</em:icon64URL>
-
-
- Note: For the above example to work you will also have to add a skin package line to your chrome.manifest file. See Chrome Registration#skin. Alternatively you can place your icon in the directory specified in your content package line.
-

{{ h3_gecko_minversion("targetPlatform", "1.8") }}

-

A string specifying a platform that the add-on supports. It contains either the value of OS_TARGET alone or combined with TARGET_XPCOM_ABI, separated by an underscore (_).

-

You can specify multiple targetPlatform properties per manifest. If any value matches the application's build parameters, it will be installed; if not, the user will get an appropriate error message.

-

Examples

-
<em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
-
-<em:targetPlatform>Linux</em:targetPlatform>
-
-<em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
-
-<em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
-

Usually, you would use only the OS part for themes or for extensions that are not fully cross-platform. For extensions including binary (compiled) components, you should never use the OS alone, but include the ABI (s) that you compiled the components with. If you want to include multiple versions of the components, you should also use Platform-specific Subdirectories.

-

Notes

- -

This property was added for Firefox/Thunderbird 1.5. Previous versions of these applications will ignore the restrictions and install the add-on regardless of the platform.

-

{{ h3_gecko_minversion("strictCompatibility", "10.0") }}

-

A Boolean value indicating if the add-on should be enabled when the version of the application is greater than its max version. By default, the value of this property is false meaning that the compatibility checking will not be performed against the max version.

-
<em:strictCompatibility>true</em:strictCompatibility>
-

Usually, there is no need to restrict the compatibility: not all new releases will break your extension and, if it is hosted on AMO, you'll get notice several weeks in advance if a potential risk has been detected. Moreover, an extension being disabled, even for a short period, leads to a bad experience for the user. About the only time you should need to set this if your add-on does things that are likely to be broken by Firefox updates. You do not need to set this flag if your add-on has a binary component, since add-ons with binary components are always subject to strict compatibility checking (because binary components need to be rebuilt for every major application release anyway).

-
- Note: If you want to restore the old behavior of strict compatibility checking of all add-ons, regardless of the value of this setting in their manifests, you can set the extensions.strictCompatibility preference to true.
-
-

{{ gecko_callout_heading("11.0") }}

-

Starting in Gecko 11.0 {{ geckoRelease("11.0") }}, applications such as Firefox will assume add-ons that have not been updated in a very long time are no longer compatible by default.

-
-

Obsolete Property Reference

-

These properties were required in older versions of the Add-on Manager, but have been replaced with newer and better mechanisms.

-

file

-

Firefox 1.0 This property pointed to a chrome .jar file that contains chrome packages that require registration with the Chrome Registry.

-

The <em:file> property has a complex object value. The uri of the value is urn:mozilla:extension:file:jarFile.jar where jarFile.jar is the name of the jar file that contains the chrome package's files. This could also be the name of a directory that contains the chrome package's files, un-jarred (e.g. urn:mozilla:extension:file:directory). In either case, the referenced chrome package file(s) must be placed in the chrome subdirectory of the XPI's top level.

-

This object has a package property (with a path within the jar file or directory that leads to the location where the contents.rdf file responsible for registering that package is located), a locale property (ditto, but to register the locale) and a skin property (ditto, but to register the theme material).

-

In extensions for Firefox 1.5, this property is no longer necessary: the chrome.manifest at the top level of the XPI is used to locate chrome to register. If there is no chrome.manifest, this property is still read by the Add-on Manager and a chrome.manifest is generated from old-style contents.rdf.

-

Examples

-
<em:file>
- <Description about="urn:mozilla:extension:file:myext.jar">
-  <em:package>content/myext/</em:package>
-  <em:locale>locale/en-US/myext/</em:locale>
-  <em:skin>skin/classic/myext/<em:skin>
- </Description>
-</em:file>
-
-

An Install Manifest may specify multiple file properties, one for each jar file or subdirectory that contains chrome to register.

-

hidden

-

Firefox 1.0 - 3.5 A boolean value that when true makes the add-on not show up in the add-ons list, provided the add-on is installed in a {{ Anch("restricted access area") }} (so it does not work for add-ons installed in the profile). This is for bundling integration hooks to larger applications where having an entry in the Extensions list does not make sense.

-
- Note: This property is no longer supported under Gecko 1.9.2 (Firefox 3.6) or later, to prevent extensions from being installed in such a way that the user might not be able to tell they're installed.
-

Examples

-
<em:hidden>true</em:hidden>
-
-

requires

-

Firefox 2.0 - 3.6.x. Other versions will ignore the restrictions and install the add-on regardless of the requirements.

-

See Replacement for install.rdf property "requires" discussion for rationale behind removing this feature and the suggested workaround.

-

<em:requires> has a similar syntax to the <em:targetApplication> tag (i.e. you must specify <em:id>, <em:minVersion>, <em:maxVersion> when using it). If the add-on specified by the <em:id> tag is not installed or has an incompatible version, the extension manager will disable your extension and show the message "Requires additional items". You can add as many <em:requires> tags as you like. Your extension will be disabled if any of the specified requirements fail. It is not possible to add dependencies that are specific to a <em:targetApplication>. See Extension Dependencies for more details.

-

Glossary

-

restricted access area

-

A restricted access area is an install location that could be restricted on a restricted-access account, regardless of whether or not the location is restricted with the current user privileges (see {{ Source("toolkit/mozapps/extensions/public/nsIExtensionManager.idl#80", "nsIInstallLocation::restricted") }}). Currently, the ($APPDIR)/extensions folder and the registry install location under HKEY_LOCAL_MACHINE (see Adding Extensions using the Windows Registry for details) are restricted.

-

The ($PROFILE)/extensions and HKEY_CURRENT_USER install locations, on the other hand, are not restricted.

diff --git a/files/zh-cn/mozilla/add-ons/legacy_add_ons/index.html b/files/zh-cn/mozilla/add-ons/legacy_add_ons/index.html deleted file mode 100644 index 9200ccb0f6..0000000000 --- a/files/zh-cn/mozilla/add-ons/legacy_add_ons/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: 旧式附件组件 -slug: Mozilla/Add-ons/Legacy_add_ons -translation_of: Archive/Add-ons/Legacy_add_ons ---- -

{{LegacyAddonsNotice}}{{AddonSidebar}}

- -

本节包含附件组件开发的旧式技术文档链接,包括:

- - diff --git a/files/zh-cn/mozilla/add-ons/overlay_extensions/index.html b/files/zh-cn/mozilla/add-ons/overlay_extensions/index.html deleted file mode 100644 index 6504a2ef16..0000000000 --- a/files/zh-cn/mozilla/add-ons/overlay_extensions/index.html +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: Overlay扩展 -slug: Mozilla/Add-ons/Overlay_Extensions -tags: - - Add-ons - - Extensions - - Landing - - NeedsTranslation - - TopicStub -translation_of: Archive/Add-ons/Overlay_Extensions ---- -

{{LegacyAddonsNotice}}{{AddonSidebar}}

- -

本页面为那些基于 Gecko 的应用开发扩展插件的开发者们提供了可用的参考文献链接。

- - - -

唯一可行的方法是开发扩展在 Gecko 2.0 发布之前. 但是现在有两种可以选择的技术:免重启扩展和基于 SDK 的扩展插件. 这些特定的 JavaScript APIs 仍旧可以被这些较新的技术使用。

- -

Prior to Firefox 4, and the Gecko 2 engine that powers it, this was the only way to develop extensions. This methodology has largely been superseded by restartless extensions, and the Add-on SDK, which is built on top of them. The privileged JavaScript APIs described here can still be used in these newer types of add-ons.

- -

XUL 学校

- -

XUL 学校 是一个综合性的拓展开发指南,主要针对 Firefox 的扩展开发,但是绝大多数可应用于其他基于 Gecko 的应用。

- -

更多资源

- -
-
-
-
设置环境
-
设置扩展开发需要的应用.
-
XUL
-
相关的指南介绍XUL 扩展的接口.
-
代码片段
-
提供了很多的简单示例代码片段.
-
安装扩展
-
如何通过把扩展的文件拷贝进应用的安装目录来安装扩展.
-
Firefox 插件的开发者指南
-
开发扩展的指南.
-
-
- -
-
-
JavaScript 模块代码
-
适用于扩展开发者的 JavaScript 模块。
-
扩展偏好
-
如何在你的扩展出现在附加组件管理界面的时候指定偏好设置。
-
常见问题
-
常见的扩展开发中的错误。
-
扩展打包
-
看看扩展是如何被打包和安装的。
-
Firefox 的二进制扩展
-
为 Firefox 创建二进制扩展。
-
-
-
diff --git a/files/zh-cn/mozilla/add-ons/performance_best_practices_in_extensions/index.html b/files/zh-cn/mozilla/add-ons/performance_best_practices_in_extensions/index.html deleted file mode 100644 index d6a6f7515b..0000000000 --- a/files/zh-cn/mozilla/add-ons/performance_best_practices_in_extensions/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: 扩展中的性能最佳实践 -slug: Mozilla/Add-ons/Performance_best_practices_in_extensions -translation_of: Archive/Add-ons/Performance_best_practices_in_extensions ---- -

Firefox 的一个巨大优势就是可扩展性非常强。扩展组件几乎可以做任何事情。但这也带来了一个劣势: 扩展组件如果写的不好,将会大大的影响浏览器性能,包括 firefox 的整体体验。 本文则提供了一些最佳实践方式,他们不仅能够提升你的组件的性能和速度,也会对 firefox 带来同样的影响。

-

提升启动性能

-

Extensions are loaded and run whenever a new browser window opens. That means every time a window opens, your extension can have an impact on how long it takes the user to see the content they're trying to view. There are several things you can do to reduce the amount of time your extension delays the appearance of the user's desired content.

-

只在需要的时候装载需要的东西

-

Don't load things during startup that are only needed if the user clicks a button, or if a given preference is enabled when it's not. If your extension has features that only work when the user has logged into a service, don't load the resources for those features until the user actually logs in.

-

使用  JavaScript code modules

-

You can create your own JavaScript code modules incorporating sets of features that are only needed under specific circumstances. This makes it easy to load chunks of your extension on the fly as needed, instead of loading everything all at once.

-

This has an advantage over XPCOM modules, which are always loaded when your extension starts up.

-

Of course, for extremely simple extensions it may not make sense to modularize your code.

-

Defer everything that you can

-

Most extensions have a load event listener in the main overlay that runs their startup functions. Do as little as possible here. The browser window is blocked while your add-on's load handler runs, so the more it does, the slower Firefox will appear to the user.

-

If there is anything that can be done even a fraction of a second later, you can use an {{ interface("nsITimer") }} or the {{ domxref("window.setTimeout()") }} method to schedule that work for later.  Even a short delay can have a big impact.

-

通用性能提示

-

避免产生内存泄漏

-

Memory leaks require the garbage collector and the cycle collector to work harder, which can significantly degrade performance.

-

Zombie compartments are a particular kind of memory leak that you can detect with minimal effort.  See the Zombie compartments page, especially the Proactive checking of add-ons section.

-

See Common causes of memory leaks in extensions for ways to avoid zombie compartments and other kinds of leaks.

-

As well as looking for these specific kinds of leaks, it's worth exercising your extension's functionality and checking the contents of about:memory for any excessive memory usage.  For example, bug 719601 featured a "System Principal" JavaScript compartment containing 100s of MBs of memory, which is much larger than usual.

-

Use JavaScript Modules

-

JavaScript modules are just like any other JavaScript, with the exception that they are singletons and Firefox can cache the compiled code for faster use the next time the browser is started. Any time your add-on loads JavaScript from an {{ HTMLElement("script") }} element you should consider using a JavaScript Module instead. For more on how JavaScript modules work, see the Using JavaScript Code Modules page.

-

Avoid Writing Slow CSS

- -

Avoid DOM mutation event listeners

-

Adding DOM mutation listeners to a document disables most DOM modification optimizations and profoundly degrades the performance of further DOM modifications to that document. Moreover, removing the listeners does not reverse the damage. For these reasons, the following events should be avoided wherever possible: DOMAttrModified, DOMAttributeNameChanged, DOMCharacterDataModified, DOMElementNameChanged, DOMNodeInserted, DOMNodeInsertedIntoDocument, DOMNodeRemoved, DOMNodeRemovedFromDocument, DOMSubtreeModified

-

For more on these events and their deprecation, see Mutation events. Use Mutation Observers instead if possible.

-

延迟加载服务 services

-

The XPCOMUtils JavaScript module provides two methods for lazily loading things:

- -

As of Firefox 4.0, many common services are already cached for you in Services.jsm.

-

Reduce file I/O

-

TODO: Give examples below, link to code, bugs, docs.

- -

Use the right compression level for JAR and XPI files

-

Reading data from compressed archives costs time. The higher the compression level of the archive, the higher also the performance cost of reading the data from it. So any JAR files in your extension should always be packed with compression level 0 (no compression) for better performance. It may seem counter-intuitive, but doing this will increase the JAR file size and actually decrease the XPI file size as it allows for compression between files inside the JAR to be done when compressing the XPI (essentially a poor-man's solid archive effect).

-

If your extension doesn't specify em:unpack then its XPI file will not be unpacked in Firefox 4 and used directly instead. This makes choosing a low compression level preferable; we recommend using compression level 1. It will increase the download size only a small amount, even compared to maximum compression.

-

使用异步 I/O

-

This cannot be stressed enough: never do synchronous I/O on the GUI thread.

- -

Unnecessary onreadystatechange in XHR

-

addEventListener(load/error) and/or xhr.onload/.onerror are usually sufficient for most uses and will only be called once, contrary to onreadystatechange. When using XHR in websites people tend to use onreadystatechange (for compatiblity reasons). Often it is enough to just load the resource or handle errors. load/error event listener are far less often called than onreadystatechange, i.e. only once, and you don't need to check readyState or figure out if it is an error or not. Only use onreadystatechange if you want to process the response while it is still arriving.

-

Removing Event Listeners

-

Remove event listener if they are not needed any more. It is better to actually remove event listener instead of just having some flag to check if the listener is active which is checked every time when an event is propagated. Abandon schemes like: function onMouseOver(evt) { if (is_active) { /* doSomeThing */ } } Also, remove "fire-once" listeners again:

-
 function init() {
-   var largeArray;
-   addEventListener('load', function onLoad() {
-        removeEventListener('load', onLoad, true);
-        largeArray.forEach();
- }, true);
-
-

Else a lot of closure stuff might be still referenced (largeArray in this example). And the listener will sit idle in some internal table.

-

Populate menus as needed

-

Populate "context" menus (page, tabs, tools) as needed and keep computation to a minimum (UI responsiveness). There is no need to populate the context menu every time something changes. It is enough to populate it once the user actually needs it. Add a listener to the "popupshowing" event and compute there.

-

Avoid mouse movement events

-

Avoid mouse movement events (enter/over/exit) or at least keep computation to a minimum. Mouse movement events, especially the mouseover event, usually happen at high frequency. Best would be to only store the new information and compute "stuff" once the user actually requests it (e.g. in a popupshowing event). Also don't forget to remove the event listeners when no longer needed (see above).

-

Avoid polling

-

Use {{ interface("nsIObserverService") }} functionality instead. Everybody is free to post "custom" notifications via {{ interface("nsIObserverService") }}, but few extensions actually use this. However, a lot of other services also provide observer functionality, such as nsIPrefBranch2.

-

aPNG/aGIF inappropriate in a lot of cases

-

Animations require a lot of time to set up, as a lot of images are decoded (the frames). Animated images may have their cached representations evicted quite often, causing the frames of your animated images to be reloaded lots of times, not just once. {{ interface("nsITree") }} / {{ XULElem("tree") }} seems to be extra special in this regard, as it doesn't seem to cache animations at all under certain circumstances.

-

base64/md5/sha1 implementations

-

Do not ship your own base64/md5/sha1 implementations. Regarding base64 there are the built-in atob/btoa functions that do the job just well and are available in overlay script as well as in in JavaScript modules and components. Hashes can be computed using {{ interface("nsICryptoHash") }}, which accepts either a string or an {{ interface("nsIInputStream") }}.

-

Image sprites

-

You may combine multiple images into one (sprites). See {{ cssxref("-moz-image-region") }}. Most XUL widgets that are used to display some image (incl. {{ XULElem("button") }} and {{ XULElem("toolbarbutton") }}) allow to use {{ cssxref("list-style-image") }}. Avoid the imagesrc/src attributes to define images where possible.

-

Consider using Chrome Workers

-

You can use a {{ domxref("ChromeWorker") }} to execute long running tasks or do data processing.

-

参考

- diff --git a/files/zh-cn/mozilla/add-ons/plugins/index.html b/files/zh-cn/mozilla/add-ons/plugins/index.html deleted file mode 100644 index f35791a3bf..0000000000 --- a/files/zh-cn/mozilla/add-ons/plugins/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Plugins -slug: Mozilla/Add-ons/Plugins -tags: - - Add-ons - - NPAPI - - NeedsTranslation - - Plugins - - TopicStub -translation_of: Archive/Plugins ---- -
-

Important: Since Firefox 52, all plugin support except Flash has been dropped (see Plug-in support has been dropped other than Flash for more details). Flash usage is also set to be phased out in the future.

-
- -
-

Note: Plugins are now a legacy technology. They are not available on most mobile devices. Mozilla encourages website developers to avoid using plugins wherever possible and use standard Web APIs instead. If there are plugin features which are not available in the web platform, we encourage developers to post their use cases to mozilla.dev.platform project list, so that Mozilla can prioritize web platform work to make those use cases possible.

-
- -

For more information about plugin roadmap, see non-archived plugin information.

- -

Plugins are shared libraries that users can install to display content that the browser can't display natively. For example, the Adobe Reader plugin lets the user open PDF files directly inside the browser, and the QuickTime and RealPlayer plugins are used to play special format videos in a web page.

- -

Plugins are written using NPAPI, the cross-browser API for plugins. The main source of documentation for NPAPI is the Gecko Plugin API Reference. To make your plugin scriptable from web pages, use npruntime.

- -

Plugins can be written completely from scratch using C APIs (usually in C or C++) or they may be built on a plugin framework such as Firebreath, JUCE, or QtBrowserPlugin. There are also some code generation tools that may be helpful. More information about these tools can be found on the External Resources page.

- -

Plugins are different from extensions, which modify or enhance the functionality of the browser itself. Plugins are also different from search plugins, which plug additional search engines in the search bar.

- -
-
-
-
-
Gecko Plugin API Reference (NPAPI)
-
This reference describes the application programming interfaces for NPAPI plugins and provides information about how to use these interfaces.
-
Site Author Guide For Click-To-Activate Plugins
-
These guidelines will help website authors use plugins when they are blocked by default with the Firefox click-to-activate feature.
-
- -
-
Scripting plugins (npruntime)
-
This reference describes the new cross-browser NPAPI extensions that let plugins be scriptable and also let them access the script objects in the browser.
-
- -
-
Shipping a plugin as a Toolkit bundle
-
Plugins can be shipped as a Toolkit bundle, allowing a user to easily install, uninstall and manage their personal plugins.
-
- -
-
Supporting private browsing in plugins
-
Firefox 3.5 introduced support for private browsing; learn how to make your plugin respect the user's privacy wishes.
-
Multi-Process Plugin Architecture
-
How Firefox loads plugins into a separate process. Firefox 3.6.4 introduced out-of-process plugins which execute in a separate process so that a crashing plugin does not crash the browser.
-
Logging and Debugging for Multi-Process Plugins
-
How to create a plugin log to aid in debugging problems with multi-process plugins.
-
-
- -
-
-
Writing a plugin for Mac OS X
-
Learn how to write a plugin for Mac OS X; a template Xcode project is provided.
-
- -
-
Monitoring Plugins
-
Use an observer service notification to monitor the amount of time spent executing calls in plugins. This can be useful when trying to determine if a plug-in is consuming too many resources.
-
- -
-
Scripting Plugins: Macromedia Flash
-
This article explains how JavaScript can be used to access methods from within the Flash plugin, as well as how a feature called FSCommands can be used to access JavaScript functions from within the Flash animation.
-
- -
-
Plugins: The First Install Problem
-
The First Install Problem is the name given to the conditions arising when a plugin or embeddable software installs itself on a system first, before any other Gecko-based browser.
-
- -
-
Plugins: Samples and Test Cases
-
NPAPI plugin samples and test cases.
-
External Resources for Plugin Creation
-
External projects, frameworks, and blog posts that may be useful.
-
- -
-
XEmbed Extension for Mozilla Plugins
-
Recent versions of Mozilla on *nix-based systems include an extension for writing plugins that use XEmbed instead of using the old Xt-based main loop that most plugins have been using since the Netscape 3.x days.
-
-
-
- -
-

Categories

- -

Interwiki Language Links

- -
-
-

Join the plugin development community

- -
-
Choose your preferred method for joining the discussion:
- - -
- -
-
-
diff --git a/files/zh-cn/mozilla/add-ons/plugins/reference/index.html b/files/zh-cn/mozilla/add-ons/plugins/reference/index.html deleted file mode 100644 index fcb2ba7232..0000000000 --- a/files/zh-cn/mozilla/add-ons/plugins/reference/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: NPAPI plugin reference -slug: Mozilla/Add-ons/Plugins/Reference -tags: - - Deprecated - - Landing - - NPAPI - - NeedsTranslation - - Plugins - - Reference - - TopicStub -translation_of: Archive/Plugins/Reference ---- -

{{deprecated_header}}

-

The articles below describe each of the APIs related to NPAPI plugins.

-

{{LandingPageListSubpages}}

diff --git a/files/zh-cn/mozilla/add-ons/plugins/samples_and_test_cases/index.html b/files/zh-cn/mozilla/add-ons/plugins/samples_and_test_cases/index.html deleted file mode 100644 index 4d0ac34085..0000000000 --- a/files/zh-cn/mozilla/add-ons/plugins/samples_and_test_cases/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Samples and Test Cases -slug: Mozilla/Add-ons/Plugins/Samples_and_Test_Cases -translation_of: Archive/Plugins/Samples_and_Test_Cases ---- -

NPAPI Plugin Samples

-

Collections of NPAPI plugin samples can be found in the Seamonkey source code at /modules/plugin/sdk/samples.

-

The samples may not build any more on all platforms. There are plans to clean up the sample plugin situation - better organization, updated build systems, get them building on all platforms. However, even if one cannot build the samples they can still be very valuable as code references.

-

There is a guide to compiling the npruntime sample in Visual Studio.

-

In addition to those samples, there are 2 more plugins in the tree that might be helpful.

- -

NPAPI Plugin Test Cases

- -

{{ languages( { "de": "de/Plugins/Beispiele_und_Testfälle" } ) }}

diff --git a/files/zh-cn/mozilla/add-ons/plugins/shipping_a_plugin_as_a_toolkit_bundle/index.html b/files/zh-cn/mozilla/add-ons/plugins/shipping_a_plugin_as_a_toolkit_bundle/index.html deleted file mode 100644 index 30aae2d422..0000000000 --- a/files/zh-cn/mozilla/add-ons/plugins/shipping_a_plugin_as_a_toolkit_bundle/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Shipping a plugin as an extension -slug: Mozilla/Add-ons/Plugins/Shipping_a_plugin_as_a_Toolkit_bundle -tags: - - Extensions - - Plugins -translation_of: Archive/Plugins/Shipping_a_plugin_as_a_Toolkit_bundle ---- -

One of the new features that is available in Firefox 1.5 is the ability to place browser plug-ins in a Firefox extension.

-

Historically, most people have chosen to use an install.js script to install a plug-in. When this method is used, you can choose to either place the plug-in into the plugins directory, or place it into your own directory and modify the Windows registry to let Firefox know where to find the plug-in. The downside to this method is that once the plug-in is installed, it might be difficult for users to upgrade, uninstall, or disable the plug-in. As of Firefox 3 (and any Gecko 1.9 based application) the use of install.js scripts is no longer possible and plugins must either be shipped as an executable installer or as an extension as described here.

-

Bundle structure

-

Toolkit bundles can be used for all add-ons including extensions, themes and plugins. Plugin packages should only need to package a small set of files in the follow structure in the xpi file:

-
install.rdf
-plugins/
-    pluginlib.dll
-    plugintypes.xpt
-
-

The install.rdf file contains an install manifest that describes the plugin to the user. The library and scripting interfaces are held in the <tt>plugins</tt> directory.

-

Platform-specific files

-

It is possible to package multiple plugin libraries for different operating systems into a single xpi bundle. In the xpi you can use the following structure:

-
platform/
-    Linux_x86-gcc3/
-        plugins/
-            libplugin.so
-    Darwin_ppc-gcc3/
-        plugins/
-            libplugin.dylib
-
-

More specific information can be found in the platform-specific subdirectories documentation.

-

Install Manifest

-

The install manifest describes the plugin to the user. For a plugin the manifest only needs to be very simple:

-
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>mypluginid@myplugin.com</em:id>
-    <em:name>My Plugin</em:name>
-    <em:version>1.0</em:version>
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>1.5</em:minVersion>
-        <em:maxVersion>3.0.*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-  </Description>
-</RDF>
-
-

This contains 4 required pieces of information.

-
    -
  1. Every add-on must have a unique id. This can be in a guid form but the simpler email form is preferred now. You should aim to use a domain-name that you own and then your own unique short-name for the plugin before the @.
  2. -
  3. The plugin must have a name to identify the plugin to the user in the list of add-ons.
  4. -
  5. The version is fairly self-descriptive, it must be a toolkit version format.
  6. -
  7. The target application block says which versions of an application the plugin is compatible with. It includes the application ID and the minimum and maximum version of the application that the plugin works with. There can be multiple targetApplication blocks listed.
  8. -
-

Providing updates

-

When plugins are packaged in this way they can make use of the built in add-on update system. This allows a remote update file to be read periodically and an updated version of the plugin offered to the user or to mark the plugin as compatible with a wider range of applications.

-

This is performed by including an updateURL in the install manifest. This should point to an update.rdf file on the internet which will include the updated versions and version information for the plugin.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/builder/index.html b/files/zh-cn/mozilla/add-ons/sdk/builder/index.html deleted file mode 100644 index 1baa282d43..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/builder/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Builder -slug: Mozilla/Add-ons/SDK/Builder -translation_of: Archive/Add-ons/Add-on_SDK/Builder ---- -

The Add-on Builder was a web-based development environment that allowed developers to create add-ons using the SDK APIs, but without needing to use the cfx command line tool. It was retired on April 1, 2014, and the "builder.addons.mozilla.org" domain now redirects to this page.
-
- If you have only used the SDK through the Builder, you already know most of what you need to know to develop using just the SDK. The high-level and low-level APIs used for Builder add-ons are exactly the same for Builder and SDK. To switch to the SDK:

- diff --git a/files/zh-cn/mozilla/add-ons/sdk/guides/content_scripts/index.html b/files/zh-cn/mozilla/add-ons/sdk/guides/content_scripts/index.html deleted file mode 100644 index fa95b15db3..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/guides/content_scripts/index.html +++ /dev/null @@ -1,486 +0,0 @@ ---- -title: Content Scripts(内容脚本) -slug: Mozilla/Add-ons/SDK/Guides/Content_Scripts -translation_of: Archive/Add-ons/Add-on_SDK/Guides/Content_Scripts ---- -
{{AddonSidebar}} -

很多 add-ons 需要访问和修改 web 页面的内容。但是 add-on 的主代码不能直接访问 web 内容。替代方案是, SDK add-ons 需要使用一些分散的脚本代理访问 web 内容,这些脚本被称作内容脚本(content scripts)。本页面描述如何开发和部署内容脚本。

- -

内容脚本是在使用SDK时很令人疑惑的点,但你很有可能不得不使用它们。下面有五个基本原则:

- - - -

这个完整的 add-on 表现出所有的这些原则。它的"main.js"使用 tabs 模块附加了一个内容脚本到当前标签页。本例中内容脚本作为字符串传递,内容脚本简单地替换了页面的内容:

- -
// main.js
-var tabs = require("sdk/tabs");
-var contentScriptString = 'document.body.innerHTML = "<h1>this page has been eaten</h1>";'
-
-tabs.activeTab.attach({
-  contentScript: contentScriptString
-});
- -

下面的高层次 SDK 模块能使用内容脚本来修改 web 页面:

- - - -

另外,还能使用 HTML 定义了一些 SDK 用户接口组件,并且使用分类的脚本来和这些内容交互。从很多方面来讲,这些脚本就像内容脚本一样,但它们并不是本文的关注点。要学习如何和用户接口模块的内容交互,请参看模块定义文档:panelsidebarframe

- -

这篇指南中列出的几乎所有的示例都是完整并且且最小的,可以在 Github 的 addon-sdk-content-scripts repository 页面上获得。

- -

加载用户脚本

- -
-

你可以声明一个字符串或者指定 contentScriptcontentScriptFile 选项加载一个单独的脚本。contentScript 选项接受一个作为脚本的字符串:

- -
// main.js
-
-var pageMod = require("sdk/page-mod");
-var contentScriptValue = 'document.body.innerHTML = ' +
-                         ' "<h1>Page matches ruleset</h1>";';
-
-pageMod.PageMod({
-  include: "*.mozilla.org",
-  contentScript: contentScriptValue
-});
- -

contentScriptFile 选项接受一个作为 resource:// URL 的字符串,指向一个存储在你的 add-on 的 data 目录中的脚本文件。jpm不会默认创建"data"目录,所以你必须创建该目录并将你的用户脚本放进去。

- -

本 add-on 提供一个 URL ,指向"content-script.js"文件,存储在 add-on 根目录下的 data 子目录:

- -
// main.js
-
-var data = require("sdk/self").data;
-var pageMod = require("sdk/page-mod");
-
-pageMod.PageMod({
-  include: "*.mozilla.org",
-  contentScriptFile: data.url("content-script.js")
-});
- -
// content-script.js
-
-document.body.innerHTML = "<h1>Page matches ruleset</h1>";
- -
-

从 Firefox 34 开始,你可以使用"./content-script.js"替代 self.data.url("content-script.js")。所以你可以像这样重写:

- -
var pageMod = require("sdk/page-mod");
-
-pageMod.PageMod({
-  include: "*.mozilla.org",
-  contentScriptFile: "./content-script.js"
-});
-
-
- -
-

除非你的内容脚本非常简单并且固定是一个静态的字符串,请不要使用 contentScript:否则,你会在从 AMO 获取你的add-on上遇到问题。

- -

相反,把脚本放到一个单独的文件并用 contentScriptFile 加载它。这回事你的代码更易维护、安全、调试和审核。

-
- -

你可以给 contentScriptcontentScriptFile 传递字符串数组来加载多个脚本:

- -
// main.js
-
-var tabs = require("sdk/tabs");
-
-tabs.on('ready', function(tab) {
-  tab.attach({
-      contentScript: ['document.body.style.border = "5px solid red";', 'window.alert("hi");']
-  });
-});
-
- -
// main.js
-
-var data = require("sdk/self").data;
-var pageMod = require("sdk/page-mod");
-
-pageMod.PageMod({
-  include: "*.mozilla.org",
-  contentScriptFile: [data.url("jquery.min.js"), data.url("my-content-script.js")]
-});
- -

如果你这么做,这些脚本之间可以直接交互,就像他们被同一个 web 页面加载一样。

- -

你也可以把 contentScriptcontentScriptFile 一起用。如果你这么做,使用 contentScriptFile 定义的脚本会在使用 contentScript 定义的脚本之前加载。这使你能够用 URL 加载比如 jQuery 这样的 JavaScript 库,然后传递一个简单的能够使用jQuery脚本:

- -
// main.js
-
-var data = require("sdk/self").data;
-var pageMod = require("sdk/page-mod");
-
-var contentScriptString = '$("body").html("<h1>Page matches ruleset</h1>");';
-
-pageMod.PageMod({
-  include: "*.mozilla.org",
-  contentScript: contentScriptString,
-  contentScriptFile: data.url("jquery.js")
-});
- -
-

除非你的内容脚本非常简单并且固定是一个静态的字符串,请不要使用 contentScript:否则,在从 AMO 获取你的 add-on 上,你会遇到问题。

- -

相反,把脚本放到一个单独的文件并用 contentScriptFile 加载它。这回事你的代码更易维护、安全、调试和审核。

-
- -

控制附加脚本的时间

- -

contentScriptWhen 选项指定了什么时候加载内容脚本。从这里选一个:

- -
    -
  • "start":页面 document 元素插入 DOM 之后,立即加载脚本。这时 DOM 的内容仍未加载,所以脚本不能与其交互。
  • -
  • "ready":页面 DOM 加载完后加载脚本:也就是说,在那个时间点 DOMContentLoaded 事件触发。这时,内容脚本可以和DOM内容交互,但外部引用的样式表和图片可能还没有完成加载。
  • -
  • "end":页面上所有内容(DOM、JS、CSS、images)加载完后,加载脚本,就是在 window.onload 事件触发的时候
  • -
- -

默认值为 "end"

- -

注意 tab.attach() 不支持 contentScriptWhen,因为它原来就是在页面加载页面的时候被调用的。

- -

传递配置选项

- -

contentScriptOptions 是一个作为只读对象暴露给内容脚本的JSON对象,在 self.options 的属性里:

- -
// main.js
-
-var tabs = require("sdk/tabs");
-
-tabs.on('ready', function(tab) {
-  tab.attach({
-      contentScript: 'window.alert(self.options.message);',
-      contentScriptOptions: {"message" : "hello world"}
-  });
-});
- -

这里可以使用任何可以转成json的值(object、array、string等等)。

- -

访问 DOM

- -

内容脚本可以访问页面的 DOM,就像任何页面中加载的脚本(页面脚本)一样。但是内容脚本和页面脚本之间是隔离的:

- -
    -
  • 内容脚本不能看到任何由页面脚本添加到页面的 JavaScript 对象
  • -
  • 如果页面脚本重定义了某个 DOM 对象的行为,但内容脚本只会看到原来的那个行为。
  • -
- -

相反也是如此:页面脚本不能看到内容脚本添加的 JavaScript 对象。

- -

例如,假想一个页面用页面脚本添加变量 foowindow 对象:

- -
<!DOCTYPE html">
-<html>
-  <head>
-    <script>
-    window.foo = "hello from page script"
-    </script>
-  </head>
-</html>
- -

在这个脚本后面加载到页面的其他脚本也可以访问 foo。但是内容脚本不能:

- -
// main.js
-
-var tabs = require("sdk/tabs");
-var mod = require("sdk/page-mod");
-var self = require("sdk/self");
-
-var pageUrl = self.data.url("page.html")
-
-var pageMod = mod.PageMod({
-  include: pageUrl,
-  contentScript: "console.log(window.foo);"
-})
-
-tabs.open(pageUrl);
- -
console.log: my-addon: null
-
- -

这种隔离策略有着很合理的理由。首先,这意味着内容脚本不会泄露对象给 web 页面,这样可能会打开安全漏洞。第二,这意味着,在内容脚本创建对象的时候,可以不用担心是否会和页面脚本添加的对象相冲突。

- -

这种隔离意味着,例如,如果一个 web 页面加载了 jQuery 库,那么内容脚本不能够看到由该库添加的 jQuery 对象——但是可以看到内容脚本添加的自己的 jQuery 对象,并且它不会和页面脚本的 jQuery 版本冲突。

- -

和页面脚本交互

- -

一般来说,这种内容脚本和页面脚本的隔离正是你所希望的。但是有时候你也许会希望和页面脚本交互:你想在内容脚本和页面脚本之间共享对象来,来在它们之间发送消息。如果你需要这么做,请阅读和页面脚本交互

- -

事件监听器

- -

你可以监听 DOM 的事件,就像在页面脚本中一样,但是有两个重要的区别:

- -

第一,如果你向 setAttribute() 传递字符串,来定义了事件监听器,那么此监听器被当做是在页面上下文中的,所以它不能访问任何内容脚本中的变量。

- -

如下,内容脚本会失败报错"theMessage is not defined":

- -
var theMessage = "Hello from content script!";
-anElement.setAttribute("onclick", "alert(theMessage);");
- -

Second, if you define an event listener by direct assignment to a global event handler like onclick, then the assignment might be overridden by the page. For example, here's an add-on that tries to add a click handler by assignment to window.onclick:

- -
var myScript = "window.onclick = function() {" +
-               "  console.log('unsafewindow.onclick: ' + window.document.title);" +
-               "}";
-
-require("sdk/page-mod").PageMod({
-  include: "*",
-  contentScript: myScript,
-  contentScriptWhen: "start"
-});
- -

这个示例会在大多数页面上正常工作,但是会在定义 onclick 的页面上失败:

- -
<html>
-  <head>
-  </head>
-  <body>
-    <script>
-    window.onclick = function() {
-      window.alert("it's my click now!");
-    }
-    </script>
-  </body>
-</html>
- -

由于这些原因,最好还是用 addEventListener() 添加一个事件监听器,定义监听器为一个函数:

- -
var theMessage = "Hello from content script!";
-
-anElement.onclick = function() {
-  alert(theMessage);
-};
-
-anotherElement.addEventListener("click", function() {
-  alert(theMessage);
-});
- -

和 add-on 通信

- -

为了使 add-on 脚本和内容脚本相互通信,任何一通信端都要访问 port 对象。

- -
    -
  • 要从一头发送消息到另一头,使用 port.emit()
  • -
  • 要从另一头接收消息,使用 port.on()
  • -
- -

消息是异步的:也就是说,发送方不会等待接收方的回应,而仅仅是发送消息完后继续处理别的事情。

- -

这里有一个简单的 add-on 使用 port 发送一个消息到内容脚本:

- -
// main.js
-
-var tabs = require("sdk/tabs");
-var self = require("sdk/self");
-
-tabs.on("ready", function(tab) {
-  var worker = tab.attach({
-    contentScriptFile: self.data.url("content-script.js")
-  });
-  worker.port.emit("alert", "Message from the add-on");
-});
-
-tabs.open("http://www.mozilla.org");
- -
// content-script.js
-
-self.port.on("alert", function(message) {
-  window.alert(message);
-});
- -
-

context-menu 模块没有使用这里描述的通信模型。了解更多关于使用 context-menu 和内容脚本通信的事情,参看 context-menu documentation

-
- -

在内容脚本中访问 port

- -

内容脚本中,port 对象是作为global下 self 对象的属性。所以要从内容脚本中发送消息的话:

- -
self.port.emit("myContentScriptMessage", myContentScriptMessagePayload);
- -

要从 add-on 代码接收消息

- -
self.port.on("myAddonMessage", function(myAddonMessagePayload) {
-  // Handle the message
-});
- -
-

注意 global下 self 对象和 self 模块完全不一样,后者提供一个API给 add-on,用来访问它的数据文件和ID。

-
- -

在内容脚本中访问 port

- -

在 add-on 代码中,联通 add-on 和某一特定内容脚本上下文的通道被封装入 worker 对象。所以和内容脚本通信的 port 对象其实是其相对应的 worker 对象的一个属性。

- -

但是,这个 worker 没有暴露给 add-on 代码,以及同样所有的模块。

- -

page-worker

- -

page-worker 对象直接整合了 work API。所以要从一个由 page-worker 关联的内容脚本接收消息的话,你可以使用 pageWorker.port.on()

- -
// main.js
-
-var self = require("sdk/self");
-
-var pageWorker = require("sdk/page-worker").Page({
-  contentScriptFile: self.data.url("content-script.js"),
-  contentURL: "http://en.wikipedia.org/wiki/Internet"
-});
-
-pageWorker.port.on("first-para", function(firstPara) {
-  console.log(firstPara);
-});
- -

要从你的 add-on 发送用户定义的消息,你可以只调用 pageWorker.port.emit()

- -
// main.js
-
-var self = require("sdk/self");
-
-var pageWorker = require("sdk/page-worker").Page({
-  contentScriptFile: self.data.url("content-script.js"),
-  contentURL: "http://en.wikipedia.org/wiki/Internet"
-});
-
-pageWorker.port.on("first-para", function(firstPara) {
-  console.log(firstPara);
-});
-
-pageWorker.port.emit("get-first-para");
- -
// content-script.js
-
-self.port.on("get-first-para", getFirstPara);
-
-function getFirstPara() {
-  var paras = document.getElementsByTagName("p");
-  if (paras.length > 0) {
-    var firstPara = paras[0].textContent;
-    self.port.emit("first-para", firstPara);
-  }
-}
- -

page-mod

- -

单个 page-mod 对象可以附加它的脚本到多个页面,每个页面有它自己的上下文来运行内容脚本,所以每个页面都需要相互隔离的通道(worker)。

- -

所以 page-mod 没有直接整合 worker 的 API。而是在每次内容脚本被附加到页面时,page-mod 发送一个 attach 事件,它的监听器会给对应的上下文传递一个 worker。通过为 attach 提供一个监听器,你可以访问被一个 page-mod 附加到页面上的内容脚本的 port 对象:

- -
// main.js
-
-var pageMods = require("sdk/page-mod");
-var self = require("sdk/self");
-
-var pageMod = pageMods.PageMod({
-  include: ['*'],
-  contentScriptFile: self.data.url("content-script.js"),
-  onAttach: startListening
-});
-
-function startListening(worker) {
-  worker.port.on('click', function(html) {
-    worker.port.emit('warning', 'Do not click this again');
-  });
-}
- -
// content-script.js
-
-window.addEventListener('click', function(event) {
-  self.port.emit('click', event.target.toString());
-  event.stopPropagation();
-  event.preventDefault();
-}, false);
-
-self.port.on('warning', function(message) {
-  window.alert(message);
-});
-
- -

上面的 add-on 里有两条消息:

- -
    -
  • 当用户点击页面元素时,click 从 page-mod 被发送到当前 add-on。
  • -
  • warning 发送一条傻气的字符串回给page-mod
  • -
- -

Tab.attach()

- -

Tab.attach() 方法返回一个 worker,你可以用来和附加的内容脚本通信。

- -

这个 add-on 添加了一个按钮到Firefox:等用户点击按钮是,这个 add-on 附加一个内容脚本到当前的标签页,发送给内容脚本一条名为 "my-addon-message"的消息,并且监听名为"my-script-response"的响应:

- -
//main.js
-
-var tabs = require("sdk/tabs");
-var buttons = require("sdk/ui/button/action");
-var self = require("sdk/self");
-
-buttons.ActionButton({
-  id: "attach-script",
-  label: "Attach the script",
-  icon: "./icon-16.png",
-  onClick: attachScript
-});
-
-function attachScript() {
-  var worker = tabs.activeTab.attach({
-    contentScriptFile: self.data.url("content-script.js")
-  });
-  worker.port.on("my-script-response", function(response) {
-    console.log(response);
-  });
-  worker.port.emit("my-addon-message", "Message from the add-on");
-}
-
- -
// content-script.js
-
-self.port.on("my-addon-message", handleMessage);
-
-function handleMessage(message) {
-  alert(message);
-  self.port.emit("my-script-response", "Response from content script");
-}
- -

port的API

- -

参看 port 对象的参考文档.

-
- -

postMessage的API

- -

port 对象加载之前,add-on 代码和内容脚本可以使用另一个 API 通信:

- - - -

这个API依然可用,并且还有文档,但是没有理由替代前文描述的 port API。 例外是 context-menu 模块,它还是使用 postMessage。

- -

内容脚本的内容脚本

- -

内容脚本可用直接和其他同一个上下文中的内容脚本通信。举个例子,如果一次 Tab.attach() 的调用附加了两个脚本,那么他们可用直接相互查看,就像加载在同一页面内的页面脚本一样。但是如果你调用 Tab.attach() 两次,每次附加一个内容脚本,那么这些内容脚本之间不能通信。你必须使用port API 通过 add-on 的主代码来传递消息。

- -

跨域的内容脚本

- -

默认情况下,内容脚本没有跨域的权限。特别是,它们不能访问在不同 iframe 中的在另外的域名上的内容,也不能发起跨域的 XMLHttpRequests。

- -

但是,你可以把需要的域名添加到 package.json"permissions"键下的 "cross-domain-content"键下,为这些域名打开这些特性。参阅文章跨域内容脚本

-
- -
 
- -
 
diff --git a/files/zh-cn/mozilla/add-ons/sdk/guides/index.html b/files/zh-cn/mozilla/add-ons/sdk/guides/index.html deleted file mode 100644 index 51fbdef445..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/guides/index.html +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: 教程 -slug: Mozilla/Add-ons/SDK/Guides -tags: - - NeedsTranslation - - TopicStub -translation_of: Archive/Add-ons/Add-on_SDK/Guides ---- -

下面列出了一些文章可以加深你对SDK的理解

-
-

投稿者的教程

-
-
-
-
- 起步
-
- 学会如何使用SDK : 编写代码, 调试bug, 提交补丁, 审核项目, 获得帮助.
-
- 模块
-
- 通过SDK学会模块的使用 (以CommonJS为规范), 懂得如何使用 sandboxes 和compartments 提高安全性, 并且了解内置的 SDK module loader (被称为Cuddlefish).
-
- 类 和 继承
-
- 学会继承在JavaScript中的运行机制, 使用构造(constructors)原型(prototypes), 并知道如何使用SDK提供的函数帮助器简化它.
-
-
-
-
-
- 私有成员
-
- 通过 前缀, 闭包, 和WeakMaps 学会私有成员如何在JavaScript中的实现, 使用 命名空间(通常指WeakMaps) 学会SDK如何支持私有成员.
-
- 脚本运行流程
-
- SDK的设计目的是为了使控制网页内容的扩展脚本可以在不同进程的环境中运行. 这篇文章强调了这一设计的特点.
-
-
-
-
-

SDK的基础结构

-
-
-
-
- SDK 模块结构
-
- SDK是可重复使用的 JavaScript 模块. 这里解释了什么是模块, 怎样加载模块, 和SDK模块树的构造.
-
- SDK API 生存周期
-
- 为SDK的API定义生命周期,  包括API稳定性的排名
-
-
-
-
-
- 程序 ID
-
- 程序ID 是扩展独一无二的标识符. 教程解释了如何定义你自己的程序 ID.
-
- Firefox 兼容
-
- 解决不同版本SDK生成的扩展与不同版本Firefox的兼容问题
-
-
-
-
-

SDK 常用技巧

-
-
-
-
- 善用 事件触发
-
- 通过SDK的事件触发框架 写出以事件驱动为基础的代码
-
-
-
-
-
- 脚本的两种类型
-
- 这篇文章可以帮助你理解扩展中的API和普通脚本的区别
-
-
-
-

 

-
-

XUL 迁移

-
-
-
-
- XUL 迁移教程
-
- 把XUL扩展迁移到SDK的技巧
-
- XUL 与 SDK 不同
-
- 比较 传统的以XUL为基础的扩展 和 SDK 两者优点和缺点
-
-
-
-
-
- 移植例子
-
- 一个简单地教你如何让 基于XUL的扩展 迁移到 SDK中的实例
-
-
-
-

 

diff --git a/files/zh-cn/mozilla/add-ons/sdk/guides/multiprocess_firefox_and_the_sdk/index.html b/files/zh-cn/mozilla/add-ons/sdk/guides/multiprocess_firefox_and_the_sdk/index.html deleted file mode 100644 index c22dd0181e..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/guides/multiprocess_firefox_and_the_sdk/index.html +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: 多进程 Firefox 与 SDK -slug: Mozilla/Add-ons/SDK/Guides/Multiprocess_Firefox_and_the_SDK -translation_of: Archive/Add-ons/Add-on_SDK/Guides/Multiprocess_Firefox_and_the_SDK ---- -

我们目前正在使 Firefox 变为多进程,它为浏览器界面使用一个操作系统进程,为运行的网页使用另一个进程来执行代码,这个项目被称为 "electrolysis" 或者 "e10s"。更多信息请参考多进程 Firefox 相关页面

- -

本文章介绍了开发者如何测试基于 SDK 的附加组件是否与多进程的 Firefox 兼容,以及如何解决出现的问题。

- -

SDK 的合约

- -

SDK 为附加组件的开发者承诺了:

- - - -

在实践中,大多数底层 API 将正常工作,但可以直接访问网页内容的底层 API 无法正常工作。

- -

兼容性垫片

- -

举例来说,你可能认为这是行不通的:

- -
var contentDocument = require("sdk/window/utils")
-  .getMostRecentBrowserWindow().content.document;
- -

但是,Firefox 为附加组件提供了许多 API 的兼容性垫片。这意味着许多 API,包括上述例子的那个,仍然工作。虽然有两条警示需注意:

- - - -

We don't yet have a complete list of low-level APIs that are not multiprocess compatible: that is, will not work without the shims. Where we know that a low-level API is not multiprocess compatible, we've indicated that in the documentation page for it.

- -

测试

- -

To test whether an add-on works without the shims, use the "multiprocess" permission.

- -
-

Note that you can only do this if you are using jpm. You can't use the "multiprocess" permission if you are using cfx.

-
- -

Setting this permission will disable the shims for your add-on, so you can test to see if it's really multiprocess compatible or not.

- -

However, there's a catch: some of the SDK's APIs themselves still depend on the shims. So by setting the "multiprocess" permission, your add-on might not work, even if you are only using high-level APIs. For example:

- -
var selection = require("sdk/selection");
-
-function myListener() {
-  console.log(selection.text);
-}
-
-selection.on('select', myListener);
-
- -

This add-on will not work if you've set the "multiprocess" permission, because sdk/selection depends on the shims. We're working on fixing these problems: see bug 1004745 and its dependencies.

- -

使用框架脚本

- -

If the shims don't enable your add-on to work properly, or you're trying to remove your dependency on the shims, then the solution is the same as it is for all add-ons:

- - - -

In the rest of this section we'll outline some SDK-specific details of using the message manager. However, you'll also need to read the main message manager documentation for the details on working with frame scripts.

- -
-

If you're used to working with content scripts in the SDK, then frame scripts might feel similar, but they're actually very different. Frame scripts are more like a part of the main add-on code that just happens to be running in the content process.

- -

Differences between frame scripts and content scripts include:

- - -
- -

访问消息管理器

- -

全局消息管理器

- -

To access the global message manager, you load the nsIMessageListenerManager service. Before you can do this in an SDK add-on, you have to require("chrome") to get access to the Components object:

- -
const {Cc, Ci} = require("chrome");
-
-var globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
-  .getService(Ci.nsIMessageListenerManager);
- -

窗口消息管理器

- -

The window message manager is available as the messageManager property of a chrome window. To understand what a chrome window is, you need to distinguish three sorts of windows:

- - - -

So to get a window message manager from the SDK, you have a couple of options:

- -

(1) Use the window/utils module:

- -
// Note that although this code uses window/utils,
-// it's safe to run in the chrome process because
-// it only accesses chrome objects.
-
-// get the active chrome window
-var browserWindow = require("sdk/window/utils").getMostRecentBrowserWindow();
-
-var windowMM = browserWindow.messageManager;
- -

(2) Use viewFor to convert an SDK window to a chrome window:

- -
// get the active SDK window
-var windows = require("sdk/windows").browserWindows;
-var activeWindow = windows.activeWindow;
-
-// convert it to a chrome window
-var browserWindow = require("sdk/view/core").viewFor(activeWindow);
-
-var windowMM = browserWindow.messageManager;
- -

浏览器消息管理器

- -

The browser message manager is available as the messageManager property of an XUL browser.

- -

In the SDK, to get a browser for a given tab, you can use the tabs/utils module's getBrowserForTab function. getBrowserForTab expects an XUL tab as an argument, so if you have an SDK tab object, you'll need to convert it to an XUL tab using viewFor:

- -
// get the active SDK tab
-var tab = require("sdk/tabs").activeTab;
-// convert it to an XUL tab
-var xulTab = require("sdk/view/core").viewFor(tab);
-// get the XUL browser for this tab
-var xulBrowser = require("sdk/tabs/utils").getBrowserForTab(xulTab);
-
-var browserMM = xulBrowser.messageManager;
- -

Again, although this code uses tabs/utils, it's safe to run in the chrome process because it only accesses chrome objects.

- -

载入框架脚本

- -

You can load frame scripts using the message manager, passing in a chrome:// or resource:// URL pointing to the script. With the SDK, the simplest approach is to keep frame scripts under your add-on's data directory, and pass in a resource:// URL created using self.data.url:

- -
const self = require("sdk/self");
-
-messageManager.loadFrameScript(self.data.url("frame-script.js"), false);
- -

Note that unlike the APIs to load content scripts, you can only load a single frame script here.

- -

例子

- -

For example, this add-on trivially accesses content directly using a low-level API:

- -
function logContent() {
-  var contentDocument = require("sdk/window/utils")
-    .getMostRecentBrowserWindow().content.document;
-  console.log(contentDocument.body.innerHTML);
-}
-
-require("sdk/ui/button/action").ActionButton({
-  id: "log-content",
-  label: "Log Content",
-  icon: "./icon-16.png",
-  onClick: logContent
-});
- -

This add-on will work by default due to the shims, but will break if you set multiprocessCompatible. So you could rewrite the add-on to use frame scripts:

- -
/*
-frame-script.js is in the "data" directory, and has this content:
-
-sendAsyncMessage("sdk-low-level-apis-e10s@jetpack:got-content",
-                 content.document.body.innerHTML);
-
-*/
-
-const self = require("sdk/self");
-
-function logContentAsync() {
-  var tab = require("sdk/tabs").activeTab;
-  var xulTab = require("sdk/view/core").viewFor(tab);
-  var xulBrowser = require("sdk/tabs/utils").getBrowserForTab(xulTab);
-
-  var browserMM = xulBrowser.messageManager;
-  browserMM.loadFrameScript(self.data.url("frame-script.js"), false);
-  browserMM.addMessageListener("sdk-low-level-apis-e10s@jetpack:got-content",
-                               logContent);
-}
-
-function logContent(message) {
-  console.log(message.data);
-}
-
-require("sdk/ui/button/action").ActionButton({
-  id: "log-content",
-  label: "Log Content",
-  icon: "./icon-16.png",
-  onClick: logContentAsync
-});
- -

现在附加组件能正常工作了,即使你设置了 multiprocessCompatible。

diff --git a/files/zh-cn/mozilla/add-ons/sdk/guides/working_with_events/index.html b/files/zh-cn/mozilla/add-ons/sdk/guides/working_with_events/index.html deleted file mode 100644 index 4c24b84e13..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/guides/working_with_events/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Working with Events -slug: Mozilla/Add-ons/SDK/Guides/Working_with_Events -translation_of: Archive/Add-ons/Add-on_SDK/Guides/Working_with_Events ---- -

The Add-on SDK supports event-driven programming.

-

Objects emit events on state changes that might be of interest to add-on code, such as browser windows opening, pages loading, network requests completing, and mouse clicks. By registering a listener function to an event emitter an add-on can receive notifications of these events.

-

We talk about content scripts in more detail in the Working with Content Scripts guide.

-

Additionally, if you're using content scripts to interact with web content, you can define your own events and use them to communicate between the main add-on code and the content scripts. In this case one end of the conversation emits the events, and the other end listens to them.

-

So there are two main ways you will interact with the EventEmitter framework:

- -

This guide only covers the first of these; the second is explained in the Working with Content Scripts guide.

-

Adding Listeners

-

You can add a listener to an event emitter by calling its on(type, listener) method.

-

It takes two parameters:

- -

For example, the following add-on registers a listener with the tabs module to listen for the ready event, and logs a string to the console reporting the event:

-
var tabs = require("sdk/tabs");
-
-tabs.on("ready", function () {
-  console.log("tab loaded");
-});
-
-

It is not possible to enumerate the set of listeners for a given event.

-

The value of this in the listener function is the object that emitted the event.

-

Listening to all events

-
-

This example uses the action button API, which is only available from Firefox 29 onwards.

-
-

From Firefox 28 onwards, you can pass the wildcard "*" as the type argument. If you do this, the listener will be called for any event emitted by that object, and its argument will be the name of the event:

-
var ui = require('sdk/ui');
-var panels = require("sdk/panel");
-var self = require("sdk/self");
-
-var panel = panels.Panel({
-  contentURL: self.data.url("panel.html")
-});
-
-panel.on("*", function(e) {
-  console.log("event " + e + " was emitted");
-});
-
-var button = ui.ActionButton({
-  id: "my-button",
-  label: "my button",
-  icon: "./icon-16.png",
-  onClick: handleClick
-});
-
-function handleClick(state) {
-  panel.show({
-    position: button
-  });
-}
-

This wildcard feature does not yet work for the tabs or windows modules.

-

Adding Listeners in Constructors

-

Event emitters may be modules, as is the case for the ready event above, or they may be objects returned by constructors.

-

In the latter case the options object passed to the constructor typically defines properties whose names are the names of supported event types prefixed with "on": for example, "onOpen", "onReady" and so on. Then in the constructor you can assign a listener function to this property as an alternative to calling the object's on() method.

-

For example: the ActionButton object emits an event when the button is clicked.

-

The following add-on creates a button and assigns a listener to the onClick property of the options object supplied to the button's constructor. The listener loads https://developer.mozilla.org/:

-
require("sdk/ui/button/action").ActionButton({
-  id: "visit-mozilla",
-  label: "Visit Mozilla",
-  icon: "./icon-16.png",
-  onClick: function() {
-    require("sdk/tabs").open("https://developer.mozilla.org/");
-  }
-});
-
-

This is exactly equivalent to constructing the button and then calling the button's on() method:

-
var button = require("sdk/ui/button/action").ActionButton({
-  id: "visit-mozilla",
-  label: "Visit Mozilla",
-  icon: "./icon-16.png"
-});
-
-button.on("click", function() {
-  require("sdk/tabs").open("https://developer.mozilla.org/");
-});
-
-

Removing Event Listeners

-

Event listeners can be removed by calling removeListener(type, listener), supplying the type of event and the listener to remove.

-

The listener must have been previously been added using one of the methods described above.

-

In the following add-on, we add two listeners to the tabs module's ready event. One of the handler functions removes the listener again.

-

Then we open two tabs.

-
var tabs = require("sdk/tabs");
-
-function listener1() {
-  console.log("Listener 1");
-  tabs.removeListener("ready", listener1);
-}
-
-function listener2() {
-  console.log("Listener 2");
-}
-
-tabs.on("ready", listener1);
-tabs.on("ready", listener2);
-
-tabs.open("https://www.mozilla.org");
-tabs.open("https://www.mozilla.org");
-
-

We should see output like this:

-
info: tabevents: Listener 1
-info: tabevents: Listener 2
-info: tabevents: Listener 2
-
-

Listeners will be removed automatically when the add-on is unloaded.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/base64/index.html b/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/base64/index.html deleted file mode 100644 index bbde3e418f..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/base64/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: base64 -slug: Mozilla/Add-ons/SDK/High-Level_APIs/base64 -translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/base64 ---- -

{{AddonSidebar}}

- -
-

不稳定

-
- -

使用Base64算法编码和解码数据

- -
var base64 = require("sdk/base64");
-
-var encodedData = base64.encode("Hello, World");//"SGVsbG8sIFdvcmxk"
-var decodedData = base64.decode(encodedData);//"Hello, World"
- -

Globals

- -

函数

- -

encode(data, charset)

- -

将数据编码成ASCII的Base64字符串。

- -
参数
- -

data : string
- 需要被编码的字符串

- -

charset : string
- 字符串的编码字符集(可选)。唯一能接受的值“UTF-8”。为了进行编码和解码Unicode字符串,需要设置字符集参数:

- -
var base64 = require("sdk/base64");
-
-var encodedData = base64.encode(unicodeString, "utf-8");
-
- -
返回
- -

string : 编码后的Base64字符串。

- -

decode(data, charset)

- -

解码一个已使用base-64编码的数据字符串

- -
参数
- -

data : string
- 需要被解码的字符串

- -

charset : string
- 字符串的编码字符集(可选)。唯一能接受的值“UTF-8”。为了进行编码和解码Unicode字符串,需要设置字符集参数:

- -
var base64 = require("sdk/base64");
-
-var decodedData = base64.decode(encodedData, "utf-8");
-
- -
返回
- -

string : 解码后的字符串

- -
 
diff --git a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/clipboard/index.html b/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/clipboard/index.html deleted file mode 100644 index e56a9223cd..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/clipboard/index.html +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: clipboard(剪贴板) -slug: Mozilla/Add-ons/SDK/High-Level_APIs/clipboard -translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/clipboard ---- -

{{AddonSidebar}}

- -
-

稳定版

-
- -

操作系统剪贴板,设置或获取其内容

- -

用法

- -

你可以选择性地设置将要获取或设置的内容的格式. 支持一下格式:

- - - -

如果没有提供格式参数的话,剪贴板模块会自动检测。

- -

现在在Windows操作系统下,"image"格式并不支持透明度。

- -

示例

- -

设置和获取剪贴板内容。

- -
var clipboard = require("sdk/clipboard");
-clipboard.set("Lorem ipsum dolor sit amet");
-var contents = clipboard.get();
- -

将剪贴板内容设置为某些html。

- -
var clipboard = require("sdk/clipboard");
-clipboard.set("<blink>Lorem ipsum dolor sit amet</blink>", "html");
- -

如果剪贴板内容中包含有html,则将其在新标签页中打开。

- -
var clipboard = require("sdk/clipboard");
-if (clipboard.currentFlavors.indexOf("html") != -1)
-  require("sdk/tabs").open("data:text/html;charset=utf-8," + clipboard.get("html"));
- -

将剪贴板内容设置为一幅图片。

- -
var clipboard = require("sdk/clipboard");
-clipboard.set("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYA" +
-              "AABzenr0AAAASUlEQVRYhe3O0QkAIAwD0eyqe3Q993AQ3cBSUKpygfsNTy" +
-              "N5ugbQpK0BAADgP0BRDWXWlwEAAAAAgPsA3rzDaAAAAHgPcGrpgAnzQ2FG" +
-              "bWRR9AAAAABJRU5ErkJggg%3D%3D");
- -

如果剪贴板内容中包含图片,则将其在新标签页中打开。

- -
var clipboard = require("sdk/clipboard");
-if (clipboard.currentFlavors.indexOf("image") != -1)
-  require("sdk/tabs").open(clipboard.get());
- -

如前所述,图片的参数类型很容易被忽略,例如在网页中选中复制一张图片,得到的格式会是html而不是所预期的image。如果你是想将剪贴板的内容设置成像data URL这样的文本字符串而不是图片的话,可以通过将格式设置为text实现。

- -
var clipboard = require("sdk/clipboard");
-
-clipboard.set("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYA" +
-              "AABzenr0AAAASUlEQVRYhe3O0QkAIAwD0eyqe3Q993AQ3cBSUKpygfsNTy" +
-              "N5ugbQpK0BAADgP0BRDWXWlwEAAAAAgPsA3rzDaAAAAHgPcGrpgAnzQ2FG" +
-              "bWRR9AAAAABJRU5ErkJggg%3D%3D", "text");
- -

Globals

- -

函数

- -

set(data, datatype)

- -

将用户剪贴板上的内容用data替换。

- -
参数
- -

data : string
- 要放入剪贴板的内容。

- -

datatype : string
- 内容的格式 ,为"text"或"html" 或 "image"。可选参数.

- -

get(datatype)

- -

获取用户当前剪贴板的内容。

- -
参数
- -

datatype : string
- 只有当剪贴板中的内容格式为datatype指定的格式时才获取 (可选).。当剪贴板中的内容非所提供的datatype指定的格式时,函数回返回null。

- -

属性

- -

currentFlavors

- -

剪贴板上的内容有时会是多种格式。例如,HTML内容即能匹配HTML格式(html),又能匹配纯文本格式(text)。这个属性为一个数组,数组中的元素是剪贴板内容所匹配的所有格式,如["text","html"]。

- -
 
diff --git a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/index.html b/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/index.html deleted file mode 100644 index d0d7bd569a..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: High-Level APIs -slug: Mozilla/Add-ons/SDK/High-Level_APIs -translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs ---- -

{{AddonSidebar}}

- -

此页面列出的模块使用的是高级的API:创建用户界面,与网络进行交互并与浏览器交互。

- -

除非文件明确说明,否则这些API是稳定的,我们避免做出不兼容的改变。 - -{{ LandingPageListSubpages ("/en-US/Add-ons/SDK/High-Level_APIs", 5) }}

diff --git a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/notifications/index.html b/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/notifications/index.html deleted file mode 100644 index 415450dca7..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/notifications/index.html +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: notifications(通知) -slug: Mozilla/Add-ons/SDK/High-Level_APIs/notifications -tags: - - Add-on SDK - - 通知 -translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/notifications ---- -

{{AddonSidebar}}

- -
-

Stable

-
- -

向用户展示短暂的 toaster 风格的桌面消息。

- -

用法

- -

本 API 支持Windows、使用Growl(或者像OS X 10.9 Mavericks那样的通知中心)的 OS X 的桌面通知,以及使用 libnotify 的Linux系统

- -

这儿有个典型的例子。当消息被点击,控制台上回记录一个字符串。

- -
var notifications = require("sdk/notifications");
-notifications.notify({
-  title: "Jabberwocky",
-  text: "'Twas brillig, and the slithy toves",
-  data: "did gyre and gimble in the wabe",
-  onClick: function (data) {
-    console.log(data);
-    // console.log(this.data) would produce the same result.
-  }
-});
-
- -

下面这个示例用来展示一个保存在 add-on 的 data 目录下的图标。参看 self 模块文档以获取更多信息。

- -
var notifications = require("sdk/notifications");
-var self = require("sdk/self");
-var myIconURL = self.data.url("myIcon.png");
-
-notifications.notify({
-  text: "I have an icon!",
-  iconURL: myIconURL
-});
- -
-

从 Firefox 34 起,你能使用 "./myIcon.png" 作为 self.data.url("myIcon.png") 的别名。所以你也可以把上面的代码重写成这样:

- -
var notifications = require("sdk/notifications");
-var myIconURL = "./myIcon.png";
-
-notifications.notify({
-  text: "I have an icon!",
-  iconURL: myIconURL
-});
-
- -

本模块依赖于底层系统的通知服务。如果用户的系统不支持桌面通知或者通知服务没有运行:

- - - -

Globals

- -

函数

- -

notify(options)

- -

向用户展示一个短暂的通知

- -
参数
- -

options : object
- 可选项:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType 
titlestring -

作为消息标题的字符串。

-
text作为消息体的字符串。 -

 

-
iconURLstring -

消息里的图标的 URL 。可以是个远程的、本地的或者使用 self 模块的 URL。

-
onClickfunction -

用户点击消息是调用的函数。它会传递一个 data 值。

-
datastring -

传递给 onClick 的字符串。

-
- -
 
- -
 
- -
 
diff --git a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/panel/index.html b/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/panel/index.html deleted file mode 100644 index 3a86fb0c61..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/panel/index.html +++ /dev/null @@ -1,899 +0,0 @@ ---- -title: panel -slug: Mozilla/Add-ons/SDK/High-Level_APIs/panel -translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/panel ---- -
-

稳定版本

-
- -

创建临时的 add-on's 用户界面对话框.

- -

用法

- -

该模块导出了一个单独的构造函数函数 Panel() 构建一个Panel对话框 .

- -

面板是一个对话框。其内容是指定的HTML,你可以在它执行脚本,所以面板的外观和行为是有限的只有你可以使用HTML,CSS,JavaScript。

- -

下面的截图显示了一个面板,其内容是从当前打开的选项卡的列表中构建的:

- -

- -

面板是呈现临时用户界面中容易忽视和解聘的用户比模态对话框的方式,是有用的,因为面板隐藏瞬间用户交互部分的应用程序接口外。

- -


- 面板的内容加载快作为它是创建,面板显示之前,和内容仍然加载时面板是隐藏的,所以它是可能保持面板周围的背景,更新其内容适当地准备下一次显示。

- -


- 您的插件可以接收通知,当面板显示或隐藏通过听其显示和隐藏事件。
- 打开面板将关闭已打开的面板。

- -

Panel 内容

- -

该面板的内容指定为HTML,它是在contenturl选项面板的构造函数提供的URL加载。

- -


- 你可以加载远程HTML到面板:

- -
var panel = require("sdk/panel").Panel({
-  width: 180,
-  height: 180,
-  contentURL: "https://en.wikipedia.org/w/index.php?title=Jetpack&useformat=mobile"
-});
-
-panel.show();
- -

- -

你也可以加载HTML已经打包你的 add-on,这可能是你将如何创建对话框。要做到这一点,在你的 add-on 的 data 目录中保存的HTML 和加载使用 data.url()方法,由 self 模块导出, 像下面:

- -
var panel = require("sdk/panel").Panel({
-  contentURL: require("sdk/self").data.url("myFile.html")
-});
-
-panel.show();
- -
-

从Firefox 34以后, 你可以使用 "./myFile.html" 作为self.data.url("myFile.html")别名. 所以你可以重写成下面的示例:

- -
var panel = require("sdk/panel").Panel({
-  contentURL: "./myFile.html"
-});
-
-panel.show();
-
-
- -

Panel positioning

- -

By default the panel appears in the center of the currently active browser window. You can position the panel by passing a position to the panel's constructor or to its show() method.

- -

Attaching panels to buttons

- -

You can attach a panel to a toggle button by passing the button itself as the position option to the panel's show() method or to its constructor:

- -
var { ToggleButton } = require('sdk/ui/button/toggle');
-var panels = require("sdk/panel");
-var self = require("sdk/self");
-
-var button = ToggleButton({
-  id: "my-button",
-  label: "my button",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onChange: handleChange
-});
-
-var panel = panels.Panel({
-  contentURL: self.data.url("panel.html"),
-  onHide: handleHide
-});
-
-function handleChange(state) {
-  if (state.checked) {
-    panel.show({
-      position: button
-    });
-  }
-}
-
-function handleHide() {
-  button.state('window', {checked: false});
-}
- -

- -

Updating panel content

- -

You can update the panel's content by:

- - - -

Scripting panel content

- -

You can't directly access your panel's content from your main add-on code. To access the panel's content, you need to load a script into the panel. In the SDK these scripts are called "content scripts" because they're explicitly used for interacting with web content.

- -

While content scripts can access the content they're attached to, they can't use the SDK's APIs. So implementing a complete solution usually means you have to send messages between the content script and the main add-on code.

- - - -

For example, here's an add-on whose content script intercepts mouse clicks on links inside the panel, and sends the target URL to the main add-on code. The content script sends messages using self.port.emit() and the add-on script receives them using panel.port.on().

- -
var myScript = "window.addEventListener('click', function(event) {" +
-               "  var t = event.target;" +
-               "  if (t.nodeName == 'A')" +
-               "    self.port.emit('click-link', t.toString());" +
-               "}, false);"
-
-var panel = require("sdk/panel").Panel({
-  contentURL: "http://www.bbc.co.uk/mobile/index.html",
-  contentScript: myScript
-});
-
-panel.port.on("click-link", function(url) {
-  console.log(url);
-});
-
-panel.show();
- -

This example uses contentScript to supply the script as a string. It's usually better practice to use contentScriptFile, which is a URL pointing to a script file saved under your add-on's data directory.

- -
-

Warning: Unless your content script is extremely simple and consists only of a static string, don't use contentScript: if you do, you may have problems getting your add-on approved on AMO.

- -

Instead, keep the script in a separate file and load it using contentScriptFile. This makes your code easier to maintain, secure, debug and review.

-
- -

Getting user input

- -
-

Note: This example uses the action button API, which is only available from Firefox 29 onwards.

-
- -

The following add-on adds a button which displays a panel when clicked. The panel just contains a {{HTMLElement("textarea")}} element: when the user presses the return key, the contents of the <textarea> is sent to the main add-on code.

- -

- -

The add-on consists of six files:

- - - -

"main.js" is saved in your add-on's lib directory, and the other files go in your add-on's data directory:

- -
my-addon/
-         data/
-              get-text.js
-              icon-16.png
-              icon-32.png
-              icon-64.png
-              text-entry.html
-         lib/
-             main.js
-
- -

The "main.js" looks like this:

- -
var data = require("sdk/self").data;
-// Construct a panel, loading its content from the "text-entry.html"
-// file in the "data" directory, and loading the "get-text.js" script
-// into it.
-var text_entry = require("sdk/panel").Panel({
-  contentURL: data.url("text-entry.html"),
-  contentScriptFile: data.url("get-text.js")
-});
-
-// Create a button
-require("sdk/ui/button/action").ActionButton({
-  id: "show-panel",
-  label: "Show Panel",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onClick: handleClick
-});
-
-// Show the panel when the user clicks the button.
-function handleClick(state) {
-  text_entry.show();
-}
-
-// When the panel is displayed it generated an event called
-// "show": we will listen for that event and when it happens,
-// send our own "show" event to the panel's script, so the
-// script can prepare the panel for display.
-text_entry.on("show", function() {
-  text_entry.port.emit("show");
-});
-
-// Listen for messages called "text-entered" coming from
-// the content script. The message payload is the text the user
-// entered.
-// In this implementation we'll just log the text to the console.
-text_entry.port.on("text-entered", function (text) {
-  console.log(text);
-  text_entry.hide();
-});
- -

The content script "get-text.js" looks like this:

- -
// When the user hits return, send the "text-entered"
-// message to main.js.
-// The message payload is the contents of the edit box.
-var textArea = document.getElementById("edit-box");
-textArea.addEventListener('keyup', function onkeyup(event) {
-  if (event.keyCode == 13) {
-    // Remove the newline.
-    text = textArea.value.replace(/(\r\n|\n|\r)/gm,"");
-    self.port.emit("text-entered", text);
-    textArea.value = '';
-  }
-}, false);
-// Listen for the "show" event being sent from the
-// main add-on code. It means that the panel's about
-// to be shown.
-//
-// Set the focus to the text area so the user can
-// just start typing.
-self.port.on("show", function onShow() {
-  textArea.focus();
-});
- -

Finally, the "text-entry.html" file defines the <textarea> element:

- -
<html>
-<head>
-    <style type="text/css" media="all">
-      textarea {
-        margin: 10px;
-      }
-      body {
-        background-color: gray;
-      }
-    </style>
-  </head>
-<body>
-    <textarea rows="13" cols="33" id="edit-box"></textarea>
-  </body>
-</html>
- -

Finally, save these three icon files to the "data" directory:

- - - - - - - - - - - - - - - - -
icon-16.png
icon-32.png
icon-64.png
- -

To learn much more about content scripts, see the Working with Content Scripts guide.

- -

Scripting trusted panel content

- -
-

Note: This example uses the action button API, which is only available from Firefox 29 onwards.

-
- -

We've already seen that you can package HTML files in your add-on's data directory and use them to define the panel's content. We can call this "trusted" content, because unlike content loaded from a source outside the add-on, the add-on author knows exactly what it's doing. To interact with trusted content you don't need to use content scripts: you can just include a script from the HTML file in the normal way, using script tags.

- -

Like a content script, these scripts can communicate with the add-on code using the postMessage() API or the port API. The crucial difference is that these scripts access the postMessage and port objects through the addon object, whereas content scripts access them through the self object.

- -

To show the difference, we can easily convert the text-entry add-on above to use normal page scripts instead of content scripts.

- -

The main add-on code is exactly the same as the main add-on code in the previous example, except that we don't attach a content script:

- -
var data = require("sdk/self").data;
-// Construct a panel, loading its content from the "text-entry.html"
-// file in the "data" directory, and loading the "get-text.js" script
-// into it.
-var text_entry = require("sdk/panel").Panel({
-  contentURL: data.url("text-entry.html")
-});
-
-// Create a button
-require("sdk/ui/button/action").ActionButton({
-  id: "show-panel",
-  label: "Show Panel",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onClick: handleClick
-});
-
-// Show the panel when the user clicks the button.
-function handleClick(state) {
-  text_entry.show();
-}
-
-// When the panel is displayed it generated an event called
-// "show": we will listen for that event and when it happens,
-// send our own "show" event to the panel's script, so the
-// script can prepare the panel for display.
-text_entry.on("show", function() {
-  text_entry.port.emit("show");
-});
-
-// Listen for messages called "text-entered" coming from
-// the content script. The message payload is the text the user
-// entered.
-// In this implementation we'll just log the text to the console.
-text_entry.port.on("text-entered", function (text) {
-  console.log(text);
-  text_entry.hide();
-});
- -

The page script is exactly the same as the content script above, except that instead of self, we use addon to access the messaging APIs:

- -
// When the user hits return, send the "text-entered"
-// message to main.js.
-// The message payload is the contents of the edit box.
-var textArea = document.getElementById("edit-box");
-textArea.addEventListener('keyup', function onkeyup(event) {
-  if (event.keyCode == 13) {
-    // Remove the newline.
-    text = textArea.value.replace(/(\r\n|\n|\r)/gm,"");
-    addon.port.emit("text-entered", text);
-    textArea.value = '';
-  }
-}, false);
-// Listen for the "show" event being sent from the
-// main add-on code. It means that the panel's about
-// to be shown.
-//
-// Set the focus to the text area so the user can
-// just start typing.
-addon.port.on("show", function onShow() {
-  textArea.focus();
-});
- -

Finally, the HTML file now references "get-text.js" inside a {{HTMLElement("script")}} tag:

- -
<html>
-<head>
-    <style type="text/css" media="all">
-      textarea {
-        margin: 10px;
-      }
-      body {
-        background-color: gray;
-      }
-    </style>
-  </head>
-  <body>
-    <script src="get-text.js"></script>
-    <textarea rows="13" cols="33" id="edit-box"></textarea>
-  </body>
-</html>
-
- -

Styling panel content

- -

The panel's default style is different for each operating system:

- -

This helps to ensure that the panel's style is consistent with the dialogs displayed by Firefox and other applications, but means you need to take care when applying your own styles.

- -

If the panel's content is packaged along with your add-on and specified using an HTML file in your data directory, you can style it by embedding CSS directly in the HTML file or by referencing a CSS file stored under data:

- -
<!DOCTYPE HTML>
-<html>
-  <head>
-    <link href="panel-style.css" type="text/css" rel="stylesheet">
-  </head>
-  <body>
-    My panel content
-  </body>
-</html>
- -

From Firefox 31 onwards, you can style panel content using the contentStyle or contentStyleFile options. You can use these options even if the panel content is not packaged along with the add-on:

- -
var panel = require("sdk/panel").Panel({
-  contentURL: "https://en.wikipedia.org/w/index.php?title=Jetpack&useformat=mobile",
-  contentStyle: "body { border: 3px solid blue; }"
-});
-
-panel.show();
- -
var self = require("sdk/self");
-
-var panel = require("sdk/panel").Panel({
-  contentURL: "https://en.wikipedia.org/w/index.php?title=Jetpack&useformat=mobile",
-  contentStyleFile: self.data.url("panel-style.css")
-});
-
-panel.show();
- -

Private browsing

- -

If your add-on has not opted into private browsing, and it calls panel.show() when the currently active window is a private window, then the panel will not be shown.

- -

Panel limitations

- -

Although panels can host HTML documents, they are not implemented as browser tabs, so many things that work in normal web pages do not work inside panels:

- - - -

Globals

- -

Constructors

- -

Panel(options)

- -

Creates a panel.

- -
Parameters
- -

options : object
- Optional options:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType 
widthnumber -

The width of the panel in pixels. Optional.

-
heightnumber -

The height of the panel in pixels. Optional.

-
position -

object, button, widget

-
-

The position of the panel. Ignored if the panel is opened by a widget.

- -

This may be one of three things:

- -
    -
  • a toggle button. If this is supplied the panel will be shown attached to the button. See the section on attaching panels to buttons.
  • -
  • a widget object. If this is supplied the panel will be shown attached to the widget.
  • -
  • an object which specifies where in the window the panel should be shown. The rest of this section describes this object.
  • -
- -

The position object has one or more of the following properties: top, right, bottom and left. Their values are expressed in pixels. Any other properties will be ignored.

- -

The default alignment along each axis is centered: so to display a panel centred along the vertical or horizontal axis, just omit that axis:

- -
-// Show the panel centered horizontally and
-// aligned to the bottom of the content area
-require("sdk/panel").Panel({
-  position: {
-   bottom: 0
-  }
-}).show();
-
-// Show the panel centered vertically and
-// aligned to the left of the content area
-require("sdk/panel").Panel({
-  position: {
-    left: 0
-  }
-}).show();
-
-// Centered panel, default behavior
-require("sdk/panel").Panel({}).show();
- -

As with the CSS top, bottom, left, and right properties, setting both top and bottom or both left and right will implicitly set the panel's height or width relative to the content window:

- -
-// Show the panel centered horizontally, with:
-// - the top edge 40px from the top
-// of the content window
-// - the bottom edge 100px from the bottom
-// of the content window
-require("sdk/panel").Panel({
-  position: {
-    top: 40,
-    bottom: 100
-  }
-}).show();
- -

If you set both top and bottom, but also set the panel's height explicitly using the height property, then the panel will ignore bottom, just as CSS does for its properties with the same name:

- -
-// Show the panel centered horizontally, with:
-// - the top edge 40px from the top
-// of the content window
-// - a height of 400px
-require("sdk/panel").Panel({
-  position: {
-    top: 40,
-    bottom: 100,
-  },
-  height: 400
-}).show();
-
-// This is equivalent to:
-
-require("panel").Panel({
-  position {
-    top: 40
-  },
-  height: 400
-}).show();
- -

The same principle is applied in the horizontal axis with width, left and right.

-
focusboolean -

Set to false to prevent taking the focus away when the panel is shown. Only turn this off if necessary, to prevent accessibility issue. Optional, default to true.

-
contentURLstring,URL -

The URL of the content to load in the panel. That is, they can't refer to remote scripts. The URLs are usually constructed using self.data.url().

- -
-

From Firefox 34, you can use "./my-file.html" as an alias for self.data.url("my-file.html").

-
-
allowobject -

An optional object describing permissions for the content. It should contain a single key named script whose value is a boolean that indicates whether or not to execute script in the content. script defaults to true.

-
contentScriptFilestring,array -

A URL or an array of URLs. The URLs point to scripts to load into the panel.

- -

The scripts must be packaged with the add-on under the add-on's data directory. That is, they can't refer to remote scripts. The URLs are usually constructed using self.data.url().

- -
-

From Firefox 34, you can use "./my-script.js" as an alias for self.data.url("my-script.js").

-
- -

Content scripts specified by this property are loaded before those specified by the contentScript property.

-
contentScriptstring,array -

A string or an array of strings containing the texts of content scripts to load. Content scripts specified by this property are loaded after those specified by the contentScriptFile property.

-
contentStyleFilestring, array -

A URL or an array of URLs. The URLs point to CSS stylesheets to load into the panel.

- -

The stylesheets must be packaged with the add-on under the add-on's data directory. That is, they can't refer to remote stylesheets. The URLs are usually constructed using self.data.url().

- -

Stylesheets specified by this property are loaded before those specified by the contentStyle property.

-
contentStylestring, array -

A string or an array of strings containing the texts of stylesheets to load. Stylesheets specified by this property are loaded after those specified by the contentStyleFile property.

-
contentScriptWhenstring -

When to load the content scripts. This may take one of the following values:

- -
    -
  • "start": load content scripts immediately after the document element for the panel is inserted into the DOM, but before the DOM content itself has been loaded
  • -
  • "ready": load content scripts once DOM content has been loaded, corresponding to the DOMContentLoaded event
  • -
  • "end": load content scripts once all the content (DOM, JS, CSS, images) for the panel has been loaded, at the time the window.onload event fires
  • -
- -

This property is optional and defaults to "end".

-
contentScriptOptionsobject -

Read-only value exposed to content scripts under addon.options property.

- -

Any kind of jsonable value (object, array, string, etc.) can be used here. Optional.

-
contextMenuboolean -
-

New in Firefox 33

-
- -

Whether to show a context menu when the user context-clicks in the panel. The context menu will be the same one that's displayed in web pages. Optional, defaults to false.

-
onMessagefunction -

Include this to listen to the panel's message event.

-
onShowfunction -

Include this to listen to the panel's show event.

-
onHidefunction -

Include this to listen to the panel's hide event.

-
- -

Panel

- -

The Panel object represents a floating modal dialog that can by an add-on to present user interface content.

- -

Once a panel object has been created it can be shown and hidden using its show() and hide() methods. Once a panel is no longer needed it can be deactivated using destroy().

- -

The content of a panel is specified using the contentURL option. An add-on can interact with the content of a panel using content scripts which it supplies in the contentScript and/or contentScriptFile options. For example, a content script could create a menu and send the user's selection to the add-on.

- -

Methods

- -

destroy()

- -

Destroys the panel, unloading any content that was loaded in it. Once destroyed, the panel can no longer be used. If you just want to hide the panel and might show it later, use hide instead.

- -

postMessage(message)

- -

Sends a message to the content scripts.

- -
Parameters
- -

message : value
- The message to send. Must be stringifiable to JSON.

- -

show(options)

- -

Displays the panel.

- -

If the options argument is given, it will be shallow merged with the options provided in the constructor: the options passed in the show method takes precedence.

- -

Passing options here is useful for making temporary changes without touching the default values.

- -
Parameters
- -

options : object
- Optional options:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType 
widthnumber -

The width of the panel in pixels. Optional.

-
heightnumber -

The height of the panel in pixels. Optional.

-
positionobject -

The position of the panel. Optional. See Panel's options for further details.

-
focusboolean -

Set to false to prevent taking the focus away when the panel is shown.

-
- -

hide()

- -

Stops displaying the panel.

- -

resize(width, height)

- -

Resizes the panel.

- -
Parameters
- -

width : number
- The new width of the panel in pixels.

- -

height : number
- The new height of the panel in pixels.

- -

on(type, listener)

- -

Registers an event listener with the panel.

- -
Parameters
- -

type : string
- The type of event to listen for.

- -

listener : function
- The listener function that handles the event.

- -

removeListener(type, listener)

- -

Unregisters an event listener from the panel.

- -
Parameters
- -

type : string
- The type of event for which listener was registered.

- -

listener : function
- The listener function that was registered.

- -

Properties

- -

port

- -

EventEmitter object that allows you to:

- - - -

See the guide to communicating using port for details.

- -

isShowing

- -

Tells if the panel is currently shown or not. This property is read-only.

- -

height

- -

The height of the panel in pixels.

- -

width

- -

The width of the panel in pixels.

- -

focus

- -

Whether or not focus will be taken away when the panel is shown. This property is read-only.

- -

contentURL

- -

The URL of content loaded into the panel. This can point to local content loaded from your add-on's "data" directory or remote content. Setting it updates the panel's content immediately.

- -

allow

- -

An object describing permissions for the content. It contains a single key named script whose value is a boolean that indicates whether or not to execute script in the content.

- -

contentScriptFile

- -

A local file URL or an array of local file URLs of content scripts to load. Content scripts specified by this property are loaded before those specified by the contentScript property.

- -

contentScript

- -

A string or an array of strings containing the texts of content scripts to load. Content scripts specified by this property are loaded after those specified by the contentScriptFile property.

- -

contentScriptWhen

- -

When to load the content scripts. This may have one of the following values:

- - - -

contentScriptOptions

- -

Read-only value exposed to content scripts under addon.options property.

- -

Any kind of jsonable value (object, array, string, etc.) can be used here. Optional.

- -

Events

- -

show

- -

This event is emitted when the panel is shown.

- -

hide

- -

This event is emitted when the panel is hidden.

- -

message

- -

If you listen to this event you can receive message events from content scripts associated with this panel. When a content script posts a message using self.postMessage(), the message is delivered to the add-on code in the panel's message event.

- -
Arguments
- -

value : Listeners are passed a single argument which is the message posted from the content script. The message can be any JSON-serializable value.

- -

error

- -

This event is emitted when an uncaught runtime error occurs in one of the panel's content scripts.

- -
Arguments
- -

Error : Listeners are passed a single argument, the Error object.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/tabs/index.html b/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/tabs/index.html deleted file mode 100644 index b85bb94ab3..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/tabs/index.html +++ /dev/null @@ -1,669 +0,0 @@ ---- -title: tabs -slug: Mozilla/Add-ons/SDK/High-Level_APIs/tabs -translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/tabs ---- -

{{AddonSidebar}}

- -
-

Stable

-
- -

打开、操作和访问标签页,以及接收标签页事件

- -

用法

- -

打开标签页

- -

你可以注册事件监听器,以便在标签打开、关闭、完成DOM内容加载、被激活或被闲置时接收通知:

- -
var tabs = require("sdk/tabs");
-tabs.open("http://www.example.com");
- -

跟踪标签页

- -

You can register event listeners to be notified when tabs open, close, finish loading DOM content, or are made active or inactive:

- -
var tabs = require("sdk/tabs");
-
-// Listen for tab openings.
-tabs.on('open', function onOpen(tab) {
-  myOpenTabs.push(tab);
-});
-
-// Listen for tab content loads.
-tabs.on('ready', function(tab) {
-  console.log('tab is loaded', tab.title, tab.url);
-});
- -

访问标签页

- -

The module itself can be used as a list of all opened tabs across all windows. In particular, you can enumerate it:

- -
var tabs = require('sdk/tabs');
-for (let tab of tabs)
-  console.log(tab.title);
- -

You can also access individual tabs by index:

- -
var tabs = require('sdk/tabs');
-
-tabs.on('ready', function () {
-  console.log('first: ' + tabs[0].title);
-  console.log('last: ' + tabs[tabs.length-1].title);
-});
- -

You can access the currently active tab:

- -
var tabs = require('sdk/tabs');
-
-tabs.on('activate', function () {
-  console.log('active: ' + tabs.activeTab.url);
-});
- -

跟踪单个标签页

- -

Given a tab, you can register event listeners to be notified when the tab is closed, activated or deactivated, or when the page hosted by the tab is loaded or retrieved from the "back-forward cache":

- -
var tabs = require("sdk/tabs");
-
-function onOpen(tab) {
-  console.log(tab.url + " is open");
-  tab.on("pageshow", logShow);
-  tab.on("activate", logActivate);
-  tab.on("deactivate", logDeactivate);
-  tab.on("close", logClose);
-}
-
-function logShow(tab) {
-  console.log(tab.url + " is loaded");
-}
-
-function logActivate(tab) {
-  console.log(tab.url + " is activated");
-}
-
-function logDeactivate(tab) {
-  console.log(tab.url + " is deactivated");
-}
-
-function logClose(tab) {
-  console.log(tab.url + " is closed");
-}
-
-tabs.on('open', onOpen);
- -

操作标签页

- -

You can get and set various properties of tabs (but note that properties relating to the tab's content, such as the URL, will not contain valid values until after the tab's ready event fires). By setting the url property you can load a new page in the tab:

- -
var tabs = require("sdk/tabs");
-tabs.on('activate', function(tab) {
-  tab.url = "http://www.example.com";
-});
- -

在标签页中运行脚本

- -

You can attach a content script to the page hosted in a tab, and use that to access and manipulate the page's content (see the Modifying the Page Hosted by a Tab tutorial):

- -
var tabs = require("sdk/tabs");
-
-tabs.on('activate', function(tab) {
-  var worker = tab.attach({
-    contentScript: 'self.port.emit("html", document.body.innerHTML);'
-  });
-  worker.port.on("html", function(message) {
-    console.log(message)
-  })
-});
- -

Note that tab.attach is tab-centric: if the user navigates to a new page in the same tab, then the worker and content scripts will be reattached to the new page.

- -

附加样式表

- -
-

Firefox 34 新增。

-
- -

You can't attach style sheets to a tab using tab.attach(), but from Firefox 34 onwards you can attach and detach them using the low-level stylesheet/style and content/mod APIs. Here's an add-on that uses a toggle button to attach a stylesheet to the active tab, and detach it again. The stylesheet is called "style.css" and is located in the add-on's "data" directory:

- -
var tabs = require("sdk/tabs");
-var { attach, detach } = require('sdk/content/mod');
-var { Style } = require('sdk/stylesheet/style');
-var { ToggleButton } = require("sdk/ui/button/toggle");
-
-var style = Style({
-  uri: './style.css'
-});
-
-var button = ToggleButton({
-  id: "stylist",
-  label: "stylist",
-  icon: "./icon-16.png",
-  onChange: function(state) {
-    if (state.checked) {
-      attach(style, tabs.activeTab);
-    }
-    else {
-      detach(style, tabs.activeTab);
-    }
-  }
-});
- -

隐私窗口

- -

If your add-on has not opted into private browsing, then you won't see any tabs that are hosted by private browser windows.

- -

Tabs hosted by private browser windows won't be seen if you enumerate the tabs module itself, and you won't receive any events for them.

- -

To learn more about private windows, how to opt into private browsing, and how to support private browsing, refer to the documentation for the private-browsing module.

- -

转为XUL标签页

- -

To convert from the high-level Tab objects used in this API to the low-level XUL tab objects used in the tabs/utils API and by traditional add-ons, use the viewFor() function exported by the viewFor module.

- -

To convert back the other way, from a XUL tab to a high-level Tab object, use the modelFor() function, exported by the modelFor module.

- -

Here's an example converting from a high-level Tab to a XUL tab and then back the other way:

- -
var { modelFor } = require("sdk/model/core");
-var { viewFor } = require("sdk/view/core");
-
-var tabs = require("sdk/tabs");
-var tab_utils = require("sdk/tabs/utils");
-
-function mapHighLevelToLowLevel(tab) {
-  // get the XUL tab that corresponds to this high-level tab
-  var lowLevelTab = viewFor(tab);
-  // now we can, for example, access the tab's content directly
-  var browser = tab_utils.getBrowserForTab(lowLevelTab);
-  console.log(browser.contentDocument.body.innerHTML);
-  // get the high-level tab back from the XUL tab
-  var highLevelTab = modelFor(lowLevelTab);
-  console.log(highLevelTab.url);
-}
-
-tabs.on("ready", mapHighLevelToLowLevel);
-
- -

Note that directly accessing XUL objects and web content like this means you're no longer protected by the compatibility guarantees made by the SDK's high-level APIs. In particular, your code might not work with multiprocess Firefox.

- -

全局变量

- -

函数

- -

open(options)

- -

Opens a new tab. The new tab will open in the active window or in a new window, depending on the inNewWindow option.

- -

示例

- -
var tabs = require("sdk/tabs");
-
-// Open a new tab on active window and make tab active.
-tabs.open("http://www.mysite.com");
-
-// Open a new tab in a new window and make it active.
-tabs.open({
-  url: "http://www.mysite.com",
-  inNewWindow: true
-});
-
-// Open a new tab on active window in the background.
-tabs.open({
-  url: "http://www.mysite.com",
-  inBackground: true
-});
-
-// Open a new tab as an app tab and do something once it's open.
-tabs.open({
-  url: "http://www.mysite.com",
-  isPinned: true,
-  onOpen: function onOpen(tab) {
-    // do stuff like listen for content
-    // loading.
-  }
-});
- -
参数
- -

options : object
- 必选项:

- - - - - - - - - - - - - - - - -
NameType 
urlstring -

String URL to be opened in the new tab. This is a required property.

-
- -

可选项:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType 
isPrivateboolean -

Boolean which will determine whether the new tab should be private or not. If your add-on does not support private browsing this will have no effect. See the private-browsing documentation for more information. Defaults to false.

-
inNewWindowboolean -

If present and true, a new browser window will be opened and the URL will be opened in the first tab in that window. This is an optional property.

-
inBackgroundboolean -

If present and true, the new tab will be opened to the right of the active tab and will not be active. This is an optional property.

-
isPinnedboolean -

If present and true, then the new tab will be pinned as an app tab.

-
onOpenfunction -

A callback function that will be registered for the 'open' event. This is an optional property.

-
onClosefunction -

A callback function that will be registered for the 'close' event. This is an optional property.

-
onReadyfunction -

A callback function that will be registered for the 'ready' event. This is an optional property.

-
onLoadfunction -

A callback function that will be registered for the 'load' event. This is an optional property.

-
onPageShowfunction -

A callback function that will be registered for the 'pageshow' event. This is an optional property.

-
onActivatefunction -

A callback function that will be registered for the 'activate' event. This is an optional property.

-
onDeactivatefunction -

A callback function that will be registered for the 'deactivate' event. This is an optional property.

-
- -

属性

- -

activeTab

- -

The currently active tab in the active window. This property is read-only. To activate a Tab object, call its activate method.

- -

示例

- -
// Get the active tab's title.
-var tabs = require("sdk/tabs");
-console.log("title of active tab is " + tabs.activeTab.title);
- -

length

- -

The number of open tabs across all windows.

- -

事件

- -

open

- -

This event is emitted when a new tab is opened. This does not mean that the content has loaded, only that the browser tab itself is fully visible to the user.

- -

Properties relating to the tab's content (for example: title, favicon, and url) will not be correct at this point. If you need to access these properties, listen for the ready event:

- -
var tabs = require("sdk/tabs");
-tabs.on('open', function(tab){
-  tab.on('ready', function(tab){
-    console.log(tab.url);
-  });
-});
- -
参数
- -

Tab : Listeners are passed the tab object that just opened.

- -

close

- -

This event is emitted when a tab is closed. When a window is closed this event will be emitted for each of the open tabs in that window.

- -
参数
- -

Tab : Listeners are passed the tab object that has closed.

- -

ready

- -

This event is emitted when the DOM for a tab's content is ready. It is equivalent to the DOMContentLoaded event for the given content page.

- -

A single tab will emit this event every time the DOM is loaded: so it will be emitted again if the tab's location changes or the content is reloaded.

- -

After this event has been emitted, all properties relating to the tab's content can be used.

- -
参数
- -

Tab : Listeners are passed the tab object that has loaded.

- -

activate

- -

This event is emitted when an inactive tab is made active.

- -
参数
- -

Tab : Listeners are passed the tab object that has become active.

- -

deactivate

- -

This event is emitted when the active tab is made inactive.

- -
参数
- -

Tab : Listeners are passed the tab object that has become inactive.

- -

Tab

- -

A Tab instance represents a single open tab. It contains various tab properties, several methods for manipulation, as well as per-tab event registration.

- -

Tabs emit all the events described in the Events section. Listeners are passed the Tab object that triggered the event.

- -

方法

- -

pin()

- -

Pins this tab as an app tab.

- -

unpin()

- -

Unpins this tab.

- -

close(callback)

- -

Closes this tab.

- -
参数
- -

callback : function
- A function to be called when the tab finishes its closing process. This is an optional argument.

- -

reload()

- -

Reloads this tab.

- -

activate()

- -

Makes this tab active, which will bring this tab to the foreground.

- -

getThumbnail()

- -

Returns thumbnail data URI of the page currently loaded in this tab.

- -

attach(options)

- -

Attach one or more scripts to the document loaded in the tab. Note that by attaching inside ready event, this becomes tab-centric: if the user navigates to a new page in the same tab, then the content scripts will be reattached to the new page.

- -

示例

- -
var tabs = require("sdk/tabs");
-
-tabs.on('ready', function(tab) {
-  var worker = tab.attach({
-      contentScript:
-        'document.body.style.border = "5px solid red";'
-  });
-});
- -
参数
- -

options : object
- 可选项:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType 
contentScriptFilestring,array -

The local file URLs of content scripts to load. Content scripts specified by this option are loaded before those specified by the contentScript option. Optional.

-
contentScriptstring,array -

A string or an array of strings of code to be evaluated in the context. Content scripts specified by this option are loaded after those specified by the contentScriptFile option. Optional.

-
contentScriptOptionsobject -

You can use this option to define read-only values for your content scripts.

- -

The option consists of an object literal listing name:value pairs for the values you want to provide to the content script. For example:

- -
-// main.js
-
-const tabs = require("sdk/tabs");
-
-tabs.open({
-  url: "./page.html",
-  onReady: function(tab) {
-    tab.attach({
-      contentScriptFile: "./content-script.js",
-      contentScriptOptions: {
-        a: "blah"
-      }
-    });
-  }
-});
- -

The values are accessible to content scripts via the self.options property:

- -
-// content-script.js
-
-alert(self.options.a);
-
onMessagefunction -

A function called when the content worker receives a message from content scripts. Listeners are passed a single argument, the message posted from the content script. Optional.

-
onErrorfunctionA function called when the content worker receives an error from content scripts. Listeners are passed a single argument, error, which is the error posted from the content script and an object of type Error. Optional
- -
返回
- -

Worker : Worker 对象能够用来和内容脚本通信。查看 Content Scripts guide 了解详细信息。

- -

属性

- -

id

- -

The unique id for the tab. This property is read-only.

- -

title

- -

The title of the tab (usually the title of the page currently loaded in the tab) This property can be set to change the tab title.

- -

url

- -

The URL of the page currently loaded in the tab. This property can be set to load a different URL in the tab.

- -

favicon

- -

The URL of the favicon for the page currently loaded in the tab. This property is read-only.

- -
This property is deprecated. From version 1.15, use the favicon module's getFavicon() function instead.
- -

contentType

- -
-

This is currently an experimental API, so we might change it in future releases.

- -

Returns the MIME type that the document currently loaded in the tab is being rendered as. This may come from HTTP headers or other sources of MIME information, and might be affected by automatic type conversions performed by either the browser or extensions. This property is read-only.

-
- -

index

- -

The index of the tab relative to other tabs in the application window. This property can be set to change its relative position.

- -

isPinned

- -

Whether or not this tab is pinned as an app tab. This property is read-only.

- -

window

- -

标签页的window对象.

- -

readyState

- -
-

Firefox 33 新增。

-
- -

A string telling you the load state of the document hosted by this tab. This corresponds directly to Document.readyState. It has one of four possible values:

- - - -

Once a tab's readyState has entered "interactive", you can retrieve properties such as the document's URL.

- -

事件

- -

close

- -

This event is emitted when the tab is closed. It's also emitted when the tab's window is closed.

- -
参数
- -

Tab : Listeners are passed the tab object.

- -

ready

- -

This event is emitted when the DOM for the tab's content is ready. It is equivalent to the DOMContentLoaded event for the given content page. At this point the document itself is fully loaded and parsed, but resources such as stylesheets and images may still be loading.

- -

A single tab will emit this event every time the DOM is loaded: so it will be emitted again if the tab's location changes or the content is reloaded. After this event has been emitted, all properties relating to the tab's content can be used.

- -
参数
- -

Tab : Listeners are passed the tab object.

- -

load

- -

This event is emitted when the page for the tab's content is loaded. It is equivalent to the load event for the given content page. At this point the document and its resources, such as images and stylesheets, have finished loading.

- -

This event can be used for pages that do not have a DOMContentLoaded event, like images. For pages that have a DOMContentLoaded event, load is fired after ready.

- -

A single tab will emit this event every time the page is loaded: so it will be emitted again if the tab's location changes or the content is reloaded. After this event has been emitted, all properties relating to the tab's content can be used.

- -
参数
- -

Tab : Listeners are passed the tab object.

- -

pageshow

- -

The pageshow event is emitted when the page for a tab's content is loaded. It is equivalent to the pageshow event for the given content page.

- -

This event is similar to the load and ready events, except unlike load and ready, pageshow is triggered if the page was retrieved from the bfcache. This means that if the user loads a page, loads a new page, then moves back to the previous page using the "Back" button, the pageshow event is emitted when the user moves back to the previous page, while the load and ready events are not.

- -

This event is not emitted when the tab is made the active tab: to get notified about that, you need to listen to the activate event.

- -

After this event has been emitted, all properties relating to the tab's content can be used. It is emitted after load and ready.

- -
参数
- -

Tab : Listeners are passed the tab object.

- -

persisted : Listeners are passed a boolean value indicating whether or not the page was loaded from the bfcache.

- -

activate

- -

This event is emitted when the tab is made active.

- -

Note that you cannot guarantee that a tab's content, or even its url, are initialized at the time activate is emitted. This is because when a new tab is opened, its activate event may be emitted before the content is loaded.

- -

You can use the tab's readyState property to determine whether the tab's content and url will be available: if readyState is uninitialized or loading, then you can't access the tab's properties and must wait for the tab's ready event.

- -
参数
- -

Tab : Listeners are passed the tab object.

- -

deactivate

- -

This event is emitted when the tab is made inactive.

- -
参数
- -

Tab : Listeners are passed the tab object.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/url/index.html b/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/url/index.html deleted file mode 100644 index f98da9baf9..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/url/index.html +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: url -slug: Mozilla/Add-ons/SDK/High-Level_APIs/url -translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/url ---- -
-

实验性的

-
- -

构建,验证,解析URL

- -

Globals

- -

构造函数

- -

URL(source, base)

- -

URL构造函数可以创建一个URL对象,并验证提供的字符串是否是有效的URL。SDK中,任何接受URL参数的API,除非特殊说明,均接受的是此对象而不是字符串。

- -
参数
- -

source : string
- 一个表示URL的字符串,如果接受的参数不是有效的URL字符串,此构造函数会抛出一个异常。

- -

base : string
- 一个设置的字符串,用来表示一个相对路径的源。

- -

DataURL(uri)

- -

DataURL构造函数创建一个data: URL对象, 并验证提供的字符串是否是一个有效的data: URL。

- -
参数
- -

uri : string
- 一个表示Data URL的字符串。如果它不是一个合法的URL字符串,此构造函数会抛出一个错误。

- -

函数

- -

toFilename(url)

- -

尝试将给定的URL转换成本地文件路径。这个方法会自动尝试解决非文件协议, such as the resource: protocol, to their place on the file system. 除非URL无法转换,否则,本方法会将本地路径作为字符串返回。

- -
参数
- -

url : string
- 字符串格式的URL。

- -
返回
- -

string : 转换后的本地路径字符串

- -

fromFilename(path)

- -

讲一个给定的路径转换成 file: URL.

- -
参数
- -

path : string
- 需要被转换的本地文件路径字符串。

- -
Returns
- -

string : 转换后的字符串。

- -

isValidURI(uri)

- -

检查一个URL字符串是合法。 isValidURI("http://mozilla.org") 将返回 true, 而 isValidURI("mozilla.org") 将返回 false

- -
参数
- -

uri : string
- 需要被测试的URL。

- -
Returns
- -

boolean : 代表字符串是否有效的布尔值。

- -

getTLD(url)

- -

返回给定域名的顶级域名: 内部使用的是 getPublicSuffix()

- -
var urls = require("sdk/url");
-console.log(urls.getTLD("http://www.bbc.co.uk/"));          // "co.uk"
-console.log(urls.getTLD("https://developer.mozilla.org/")); // "org"
- -
参数
- -

url : string
- 给定的URL字符串

- -
返回
- -

string : 对应的顶级域名。

- -

URL

- -

方法

- -

toString()

- -

返回URL的字符表示形式。

- -
返回
- -

string : 字符串格式的URL。

- -

属性

- -

scheme

- -

URL使用的协议

- -

userPass

- -

URL中的username:password 部分,null 表示不存在。

- -

host

- -

URL的主机部分。 null 表示无此部分。例子:

- -
var url = require("sdk/url").URL("https://developer.mozilla.org/en-US/Add-ons");
-console.log(url.host);  // developer.mozilla.org
- -

port

- -

URL使用的端口。 null 表示不存在。

- -

path

- -

URL的路径部分,例子:

- -
var url = require("sdk/url").URL("https://developer.mozilla.org/en-US/Add-ons");
-console.log(url.path);  // /en-US/Add-ons
- -

hostname

- -

表示URL的域的字符串。参见 window.location.hostname

- -

pathname

- -

'/'开始的路径字符串。参见 window.location.pathname

- -

hash

- -

'#' 开始的hash字符串,参见 window.location.hash

- -

href

- -

整个URL字符串,参见 window.location.href

- -

origin

- -

该URL的源的字符串,参见 window.location.origin

- -

protocol

- -

该URL使用的协议字符串,包括最后的':',参见 window.location.protocol

- - - -

以'?'开始的URL的参数段,包括最开始的'?'参见window.location.search.

- -

DataURL

- -

方法

- -

toString()

- -

返回数据的URL字符串形式。如果是 base64 的URL,数据会以base64编码方式编码。

- -
返回
- -

string : URL字符串

- -

属性

- -

mimeType

- -

数据的MIME类型,默认为空字符串。

- -

parameters

- -

一个HashMap的数据包含URL参数。默认情况下是一个空对象。

- -

base64

- -

定义了数据属性的编码。

- -

data

- -

包含数据的URL字符串。如果URI给构造函数包含Base64参数,这个字符串会被解码。

diff --git a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/widget/index.html b/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/widget/index.html deleted file mode 100644 index 3d374a0752..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/high-level_apis/widget/index.html +++ /dev/null @@ -1,839 +0,0 @@ ---- -title: widget -slug: Mozilla/Add-ons/SDK/High-Level_APIs/widget -tags: - - ZH -translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/widget ---- -

{{LegacyAddonsNotice}}{{AddonSidebar}}

- -
-

Deprecated in Firefox 29 and removed in Firefox 38.

- -

The widget API is deprecated from Firefox 29 onwards. Please see the ui module for replacements. In particular, for a simple button, try the action button or toggle button APIs, and for a more complex widget try the toolbar or sidebar APIs.

-
- -

Create a simple user interface for an add-on in Firefox's add-on bar.

- -

Usage

- -

"Widgets" are small pieces of content that live in the Firefox 4 add-on bar. They can be simple icons or complex web pages. You can attach panels to them that open when they're clicked, or you can define a custom click handler to perform some other action, like opening a web page in a tab.

- -

There are a few advantages to using widgets over an ad hoc user interface. First, your users will be accustomed to interacting with add-ons via widgets and the add-on bar. Second, it allows Firefox to treat your interface as a first-class citizen. For example, in the future Firefox may allow the user to drag widgets from the add-on bar to other toolbars. By exposing your interface as a widget, your add-on would automatically inherit such functionality.

- -

Creation and content

- -

Widgets can contain images or arbitrary web content. You can include this content inline as a string by using the content property, or point to content using a URL with the contentURL property.

- -

Upon creation, the widget is automatically added to the add-on bar. You can set the width of a widget, but the height is fixed so as to fit in the add-on bar. If the content is an image, it is automatically scaled to be 16x16 pixels.

- -

For example, this widget contains an image, so it looks like a simple icon:

- -
require("sdk/widget").Widget({
-  id: "mozilla-icon",
-  label: "My Mozilla Widget",
-  contentURL: "http://www.mozilla.org/favicon.ico"
-});
- -

You can make contentURL point to an HTML or icon file which you have packaged inside your add-on. Just save the file in your add-on's data directory, and reference it using the data.url() method of the self module:

- -
var data = require("sdk/self").data;
-
-require("sdk/widget").Widget({
-  id: "my-widget",
-  label: "My Widget",
-  contentURL: data.url("my-content.html")
-});
- -

This widget contains an entire web page:

- -
require("sdk/widget").Widget({
-  id: "hello-display",
-  label: "My Hello Widget",
-  content: "Hello!",
-  width: 50
-});
- -

Widgets are quite small by default, so this example used the width property to grow it in order to show all the text.

- -

Scripting widget content

- -

To interact with the widget's content you need to load a separate script into the panel. In the SDK these scripts are called "content scripts" because they're explicitly used for interacting with web content.

- -

While content scripts can access the content they're attached to, they can't use the SDK's APIs. So implementing a complete solution usually means you have to send messages between the content script and the main add-on code.

- - - -
-

Unless your content script is extremely simple and consists only of a static string, don't use contentScript: if you do, you may have problems getting your add-on approved on AMO.

- -

Instead, keep the script in a separate file and load it using contentScriptFile. This makes your code easier to maintain, secure, debug and review.

-
- - -

For example, suppose we want to implement a media player as an add-on. We could implement the main user interface as a widget hosting an array of buttons to control play/pause/stop functions.

- -

We can then use a content script to listen for clicks on those buttons. But because content scripts can't use the SDK's APIs, we'll want the content script to send messages to the main add-on code, which can then implement the media player functions using the SDK.

- -

The widget's content is specified using HTML like this:

- -
<html>
-  <body>
-    <img src="play.png" id="play-button">
-    <img src="pause.png" id="pause-button">
-    <img src="stop.png" id="stop-button">
-  </body>
-</html>
- -

We just include three icons, and assign an ID to each one. This HTML file, and the icon files it references, are saved in the add-on's data directory.

- -

Next, we write a content script that listens for click events on each icon and sends the corresponding message to the main add-on code:

- -
var play_button = document.getElementById("play-button");
-play_button.onclick = function() {
-  self.port.emit("play");
-}
-
-var pause_button = document.getElementById("pause-button");
-pause_button.onclick = function() {
-  self.port.emit("pause");
-}
-
-var stop_button = document.getElementById("stop-button");
-stop_button.onclick = function() {
-  self.port.emit("stop");
-}
- -

We save this file in the add-on's data directory as "button-script.js". Finally. in the add-on's "main.js" file, we create the widget, assign it the HTML file and the content script, and listen for events from the content script:

- -
const widgets = require("sdk/widget");
-const data = require("sdk/self").data;
-
-var player = widgets.Widget({
-  id: "player",
-  width: 72,
-  label: "Player",
-  contentURL: data.url("buttons.html"),
-  contentScriptFile: data.url("button-script.js")
-});
-
-player.port.on("play", function() {
-  console.log("playing");
-});
-
-player.port.on("pause", function() {
-  console.log("pausing");
-});
-
-player.port.on("stop", function() {
-  console.log("stopping");
-});
- -

To learn much more about content scripts, see the Working with Content Scripts guide.

- -

Scripting trusted widget content

- -

We've already seen that you can package HTML files in your add-on's data directory and use them to define the widget's content. We can call this "trusted" content, because unlike content loaded from a source outside the add-on, the add-on author knows exactly what it's doing. To interact with trusted content you don't need to use content scripts: you can just include a script from the HTML file in the normal way, using script tags.

- -

Like a content script, these scripts can communicate with the add-on code using the postMessage() API or the port API. The crucial difference is that these scripts access the postMessage and port objects through the addon object, whereas content scripts access them through the self object.

- -

To show the difference, convert the player add-on above to use normal page scripts instead of content scripts.

- -

First, in the content script, change self to addon, and wrap it in a function:

- -
function init() {
-  var play_button = document.getElementById("play-button");
-  play_button.onclick = function() {
-    addon.port.emit("play");
-  }
-
-  var pause_button = document.getElementById("pause-button");
-  pause_button.onclick = function() {
-    addon.port.emit("pause");
-  }
-
-  var stop_button = document.getElementById("stop-button");
-  stop_button.onclick = function() {
-    addon.port.emit("stop");
-  }
-}
- -

Next, add a script tag to reference "button-script.js", and call its init() function on load:

- -
<html>
-  <head>
-    <script src="button-script.js"></script>
-  </head>
-  <body onLoad="init()">
-    <img src="play.png" id="play-button">
-    <img src="pause.png" id="pause-button">
-    <img src="stop.png" id="stop-button">
-  </body>
-</html>
-
- -

Finally, remove the line attaching the content script from "main.js":

- -
const widgets = require("sdk/widget");
-const data = require("sdk/self").data;
-
-var player = widgets.Widget({
-  id: "player",
-  width: 72,
-  label: "Player",
-  contentURL: data.url("buttons.html")
-});
-
-player.port.emit("init");
-
-player.port.on("play", function() {
-  console.log("playing");
-});
-
-player.port.on("pause", function() {
-  console.log("pausing");
-});
-
-player.port.on("stop", function() {
-  console.log("stopping");
-});
- -

Attaching panels to widgets

- -

You can supply a panel to the widget's constructor: if you do this, the panel is automatically displayed when the user clicks the widget.

- - -

- -
data = require("sdk/self").data
-
-var clockPanel = require("sdk/panel").Panel({
-  width:215,
-  height:160,
-  contentURL: data.url("clock.html")
-});
-
-require("sdk/widget").Widget({
-  id: "open-clock-btn",
-  label: "Clock",
-  contentURL: data.url("History.png"),
-  panel: clockPanel
-});
- -

Note that this is, at the moment, the only way you can attach a panel to a widget.

- -

You must supply the panel in the widget's constructor for it to work. If you assign the panel to the widget after construction, the panel can still be shown but will not be anchored to the widget:

- -
data = require("sdk/self").data
-
-var clockPanel = require("sdk/panel").Panel({
-  width:215,
-  height:160,
-  contentURL: data.url("clock.html")
-});
-
-widget = require("sdk/widget").Widget({
-  id: "open-clock-btn",
-  label: "Clock",
-  contentURL: data.url("History.png")
-});
-
-widget.panel = clockPanel;
-
-// Will not be anchored
-widget.panel.show();
- -

Also, if you try to call panel.show() inside your widget's click event listener, the panel will not be anchored:

- -
data = require("sdk/self").data
-
-var clockPanel = require("sdk/panel").Panel({
-  width:215,
-  height:160,
-  contentURL: data.url("clock.html")
-});
-
-require("sdk/widget").Widget({
-  id: "open-clock-btn",
-  label: "Clock",
-  contentURL: data.url("History.png"),
-  panel: clockPanel,
-  onClick: function() {
-    // Will not be anchored
-    this.panel.show();
-  }
-});
- -

See bug 638142.

- -

Private windows

- -

If your add-on has not opted into private browsing, then your widget will not appear in any private browser windows.

- -

To learn more about private windows, how to opt into private browsing, and how to support private browsing, refer to the documentation for the private-browsing module.

- -

Examples

- -

For conciseness, these examples create their content scripts as strings and use the contentScript property. In your own add-ons, you will probably want to create your content scripts in separate files and pass their URLs using the contentScriptFile property. See Working with Content Scripts for more information.

- -
var widgets = require("sdk/widget");
-
-// A basic click-able image widget.
-widgets.Widget({
-  id: "google-link",
-  label: "Widget with an image and a click handler",
-  contentURL: "http://www.google.com/favicon.ico",
-  onClick: function() {
-    require("sdk/tabs").activeTab.url = "http://www.google.com/";
-  }
-});
- -
// A widget that changes display on mouseover.
-widgets.Widget({
-  id: "mouseover-effect",
-  label: "Widget with changing image on mouseover",
-  contentURL: "http://www.yahoo.com/favicon.ico",
-  onMouseover: function() {
-    this.contentURL = "http://www.bing.com/favicon.ico";
-  },
-  onMouseout: function() {
-    this.contentURL = "http://www.yahoo.com/favicon.ico";
-  }
-});
- -
// A widget that updates content on a timer.
-widgets.Widget({
-  id: "auto-update-widget",
-  label: "Widget that updates content on a timer",
-  content: "0",
-  contentScript: 'setTimeout(function() {' +
-                 '  document.body.innerHTML++;' +
-                 '}, 2000)',
-  contentScriptWhen: "ready"
-});
- -
// A widget created with a specified width, that grows.
-var myWidget = widgets.Widget({
-  id: "widget-effect",
-  label: "Wide widget that grows wider on a timer",
-  content: "I'm getting longer.",
-  width: 50,
-});
-require("sdk/timers").setInterval(function() {
-  myWidget.width += 10;
-}, 1000);
- -
// A widget communicating bi-directionally with a content script.
-var widget = widgets.Widget({
-  id: "message-test",
-  label: "Bi-directional communication!",
-  content: "<foo>bar</foo>",
-  contentScriptWhen: "ready",
-  contentScript: 'self.on("message", function(message) {' +
-                 '  alert("Got message: " + message);' +
-                 '});' +
-                 'self.postMessage("ready");',
-  onMessage: function(message) {
-    if (message == "ready")
-      widget.postMessage("me too");
-  }
-});
- -

Globals

- -

Constructors

- -

Widget(options)

- -

Creates a new widget. The widget is immediately added to the add-on bar.

- -
Parameters
- -

options : object
- Required options:

- - - - - - - - - - - - - - - - - - - - - -
NameType 
labelstring -

A string description of the widget used for accessibility, title bars, and error reporting.

-
idstring -

A string used to identify your widget in order to save its location when the user moves it in the browser. This string has to be unique and must not be changed over time.

-
- -

Optional options:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType 
contentstring -

An optional string value containing the displayed content of the widget. It may contain HTML. Widgets must have either the content property or the contentURL property set.

- -

If the content is an image, it is automatically scaled to be 16x16 pixels.

-
contentURLstring -

An optional string URL to content to load into the widget. This can be local content or remote content, an image or web content. Widgets must have either the content property or the contentURL property set.

- -

If the content is an image, it is automatically scaled to be 16x16 pixels.

-
panelPanel -

An optional panel to open when the user clicks on the widget. Note: If you also register a "click" listener, it will be called instead of the panel being opened. However, you can show the panel from the listener by calling this.panel.show().

-
widthinteger -

Optional width in pixels of the widget. If not given, a default width is used.

-
onClickfunction -

Include this to listen to the widget's click event.

-
onMessagefunction -

Include this to listen to the widget's message event.

-
onMouseoverfunction -

Include this to listen to the widget's mouseover event.

-
onMouseoutfunction -

Include this to listen to the widget's mouseout event.

-
onAttachfunction -

Include this to listen to the widget's attach event.

-
tooltipstring -

Optional text to show when the user's mouse hovers over the widget. If not given, the label is used.

-
allowobject -

An optional object describing permissions for the content. It should contain a single key named script whose value is a boolean that indicates whether or not to execute script in the content. script defaults to true.

-
contentScriptFilestring,array -

A local file URL or an array of local file URLs of content scripts to load. Content scripts specified by this property are loaded before those specified by the contentScript property.

-
contentScriptstring,array -

A string or an array of strings containing the texts of content scripts to load. Content scripts specified by this property are loaded after those specified by the contentScriptFile property.

-
contentScriptWhenstring -

When to load the content scripts. This may take one of the following values:

- -
    -
  • "start": load content scripts immediately after the document element for the widget is inserted into the DOM, but before the DOM content itself has been loaded
  • -
  • "ready": load content scripts once DOM content has been loaded, corresponding to the DOMContentLoaded event
  • -
  • "end": load content scripts once all the content (DOM, JS, CSS, images) for the widget has been loaded, at the time the window.onload event fires
  • -
- -

This property is optional and defaults to "end".

-
contentScriptOptionsobject -

Read-only value exposed to content scripts under self.options property.

- -

Any kind of jsonable value (object, array, string, etc.) can be used here. Optional.

-
- -

Widget

- -

Represents a widget object.

- -

Methods

- -

destroy()

- -

Removes the widget from the add-on bar.

- -

postMessage(data)

- -

Sends a message to the widget's content scripts.

- -
Parameters
- -

data : value
- The message to send. The message can be any JSON-serializable value.

- -

on(type, listener)

- -

Registers an event listener with the widget.

- -
Parameters
- -

type : string
- The type of event to listen for.

- -

listener : function
- The listener function that handles the event.

- -

removeListener(type, listener)

- -

Unregisters an event listener from the widget.

- -
Parameters
- -

type : string
- The type of event for which listener was registered.

- -

listener : function
- The listener function that was registered.

- -

getView(window)

- -

Retrieve a WidgetView instance of this widget relative to a browser window.

- -
Parameters
- -

window : BrowserWindow
- The BrowserWindow instance to match.

- -
Returns
- -

WidgetView : A WidgetView instance associated with the browser window. Any changes subsequently applied to this object will only be applied to the widget attached to that window.

- -

Properties

- -

label

- -

The widget's label. Read-only.

- -

content

- -

A string containing the widget's content. It can contain HTML. Setting it updates the widget's appearance immediately. However, if the widget was created using contentURL, then this property is meaningless, and setting it has no effect.

- -

contentURL

- -

The URL of content to load into the widget. This can point to local content loaded from your add-on's "data" directory or remote content, an image or web content. Setting it updates the widget's appearance immediately. However, if the widget was created using content, then this property is meaningless, and setting it has no effect.

- -

Setting the contentURL property will break the channel of communication between this widget and any content scripts it contains. Messages sent from the content script will no longer be received by the main add-on code, and vice versa. This issue is currently tracked as bug 825434.

- -

panel

- -

A panel to open when the user clicks on the widget.

- -

width

- -

The widget's width in pixels. Setting it updates the widget's appearance immediately.

- -

tooltip

- -

The text of the tooltip that appears when the user hovers over the widget.

- -

allow

- -

A object describing permissions for the content. It contains a single key named script whose value is a boolean that indicates whether or not to execute script in the content.

- -

contentScriptFile

- -

A local file URL or an array of local file URLs of content scripts to load.

- -

contentScript

- -

A string or an array of strings containing the texts of content scripts to load.

- -

contentScriptWhen

- -

When to load the content scripts. This may have one of the following values:

- - - -

contentScriptOptions

- -

Read-only value exposed to content scripts under self.options property.

- -

Any kind of jsonable value (object, array, string, etc.) can be used here. Optional.

- -

port

- -

Object that allows you to:

- - - -

See the guide to communicating using port for details.

- -

Events

- -

attach

- -

This event is emitted when a browser window is opened and a new WidgetView object is created. If the widget has a content script, this event is fired only when the content script is applied according to the contentScriptWhen attribute.

- -
Arguments
- -

WidgetView : The related WidgetView object.

- -

click

- -

This event is emitted when the widget is clicked.

- -
Arguments
- -

WidgetView : Listeners are passed a single argument which is the WidgetView that triggered the click event.

- -

message

- -

If you listen to this event you can receive message events from content scripts associated with this widget. When a content script posts a message using self.postMessage(), the message is delivered to the add-on code in the widget's message event.

- -
Arguments
- -

value : Listeners are passed a single argument which is the message posted from the content script. The message can be any JSON-serializable value.

- -

mouseover

- -

This event is emitted when the user moves the mouse over the widget.

- -

mouseout

- -

This event is emitted when the user moves the mouse away from the widget.

- -

WidgetView

- -

Represents a widget instance specific to one browser window.

- -

Anything you do to an instance of this object will only be applied to the instance attached to its browser window: widget instances attached to other browser windows will be unaffected.

- -

By contrast, any changes you make to an instance of the normal Widget class will be applied across all browser windows.

- -

This class has all the same methods, attributes and events as the Widget class except for the getView method and the attach event.

- -

In this example WidgetView is used to display different content for http and https schemes:

- -
// A widget that update its content specifically to each window.
-var tabs = require("sdk/tabs");
-var windows = require("sdk/windows").browserWindows;
-var widget = require("sdk/widget").Widget({
-  id: "window-specific-test",
-  label: "Widget with content specific to each window",
-  content: " ",
-  width: 50
-});
-// Observe tab switch or document changes in each existing tab:
-function updateWidgetState(tab) {
-  var view = widget.getView(tab.window);
-  if (!view) return;
-  // Update widget displayed text:
-  view.content = tab.url.match(/^https/) ? "Secured" : "Unsafe";
-}
-tabs.on('ready', updateWidgetState);
-tabs.on('activate', updateWidgetState);
- -

Methods

- -

destroy()

- -

Removes the widget view from the add-on bar.

- -

postMessage(data)

- -

Sends a message to the widget view's content scripts.

- -
Parameters
- -

data : value
- The message to send. The message can be any JSON-serializable value.

- -

on(type, listener)

- -

Registers an event listener with the widget view.

- -
Parameters
- -

type : string
- The type of event to listen for.

- -

listener : function
- The listener function that handles the event.

- -

removeListener(type, listener)

- -

Unregisters an event listener from the widget view.

- -
Parameters
- -

type : string
- The type of event for which listener was registered.

- -

listener : function
- The listener function that was registered.

- -

Properties

- -

label

- -

The widget view's label. Read-only.

- -

content

- -

A string containing the widget view's content. It can contain HTML. Setting it updates the widget view's appearance immediately. However, if the widget view was created using contentURL, then this property is meaningless, and setting it has no effect.

- -

contentURL

- -

The URL of content to load into the widget. This can point to local content loaded from your add-on's "data" directory or remote content, an image or web content. Setting it updates the widget's appearance immediately. However, if the widget was created using content, then this property is meaningless, and setting it has no effect.

- -

Setting the contentURL property will break the channel of communication between this widget and any content scripts it contains. Messages sent from the content script will no longer be received by the main add-on code, and vice versa. This issue is currently tracked as bug 825434.

- -

panel

- -

A panel to open when the user clicks on the widget view.

- -

width

- -

The widget view's width in pixels. Setting it updates the widget view's appearance immediately.

- -

tooltip

- -

The text of the tooltip that appears when the user hovers over the widget view.

- -

allow

- -

A object describing permissions for the content. It contains a single key named script whose value is a boolean that indicates whether or not to execute script in the content.

- -

contentScriptFile

- -

A local file URL or an array of local file URLs of content scripts to load.

- -

contentScript

- -

A string or an array of strings containing the texts of content scripts to load.

- -

contentScriptWhen

- -

When to load the content scripts. This may have one of the following values:

- - - -

contentScriptOptions

- -

Read-only value exposed to content scripts under self.options property.

- -

Any kind of jsonable value (object, array, string, etc.) can be used here. Optional.

- -

port

- -

Object that allows you to:

- - - -

See the guide to communicating using port for details.

- -

Events

- -

detach

- -

The detach event is fired when the widget view is removed from its related window. This can occur if the window is closed, Firefox exits, or the add-on is disabled.

- -

click

- -

This event is emitted when the widget view is clicked.

- -

message

- -

If you listen to this event you can receive message events from content scripts associated with this widget view. When a content script posts a message using self.postMessage(), the message is delivered to the add-on code in the widget view's message event.

- -
Arguments
- -

value : Listeners are passed a single argument which is the message posted from the content script. The message can be any JSON-serializable value.

- -

mouseover

- -

This event is emitted when the user moves the mouse over the widget view.

- -

mouseout

- -

This event is emitted when the user moves the mouse away from the widget view.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/index.html b/files/zh-cn/mozilla/add-ons/sdk/index.html deleted file mode 100644 index 3c6398ed48..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/index.html +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: 附加组件 SDK -slug: Mozilla/Add-ons/SDK -tags: - - More Example - - Need Tanslate - - TopicStub -translation_of: Archive/Add-ons/Add-on_SDK ---- -
-

Support for extensions using XUL/XPCOM or the Add-on SDK was removed in Firefox 57, released November 2017. As there is no supported version of Firefox enabling these technologies, this page will be removed by December 2020.

- -

Add-ons using the techniques described in this document are considered a legacy technology in Firefox. Don't use these techniques to develop new add-ons. Use WebExtensions instead. If you maintain an add-on which uses the techniques described here, consider migrating it to use WebExtensions.

- -

Starting from Firefox 53, no new legacy add-ons will be accepted on addons.mozilla.org (AMO) for desktop Firefox and Firefox for Android.

- -

Starting from Firefox 57, only extensions developed using WebExtensions APIs will be supported on Desktop Firefox and Firefox for Android.

- -

Even before Firefox 57, changes coming up in the Firefox platform will break many legacy extensions. These changes include multiprocess Firefox (e10s), sandboxing, and multiple content processes. Legacy extensions that are affected by these changes should migrate to use WebExtensions APIs if they can. See the "Compatibility Milestones" document for more information.

- -

A wiki page containing resources, migration paths, office hours, and more, is available to help developers transition to the new technologies.

-
- -

你可以使用Add-on SDK来开发Firefox的附加组件。你可以使用各种各样的标准Web技术:JavaScript, HTML和CSS。该SDK不仅包括一些用来创建附加组件的 JavaScript API,还提供了开发、运行、测试、打包附加组件的一些工具。

- -
-

教程

- -
-
-
-
快速入门
-
如何安装SDK使用jpm工具开发、测试、打包附加组件
-
与浏览器交互
-
打开网页监听页面加载列出打开的标签页
-
开发技术
-
学习常用开发技术,如单元测试日志创建可复用模块本地化移动开发
-
-
- -
-
-
创建用户界面组件
-
创建用户界面组件如工具条按钮, 上下文菜单菜单项对话框
-
修改网页
-
-

通过URL匹配修改页面或者动态修改某个tab选项卡

-
-
将其组合在一起
-
关于注释器的附加组件的例子演示.
-
-
-
- -
-

指南

- -
-
-
-
贡献者指南
-
学习如何开始构建 SDK和关于SDK最重要的术语, 如 模块 类和继承, 私有属性, 内容处理.
-
SDK的基础构建
-
SDK的底层技术方面: 模块,程序ID, Firefox 兼容的规则定义.
-
内容脚本
-
-
-

一个详细的指南内容脚本

-
-
-
-
- -
-
-
SDK语法
-
SDK的事件框架和插件的脚本和内容脚本之间的区别。
-
SDK的 事件框架add-on scripts 和 content scripts 的区别.
-
XUL 迁移
-
指导  移植 XUL add-ons 到 SDK. 本指南包括 两工具 和 一个 工作实例 比较 XUL 和 add-on.
-
-
-
- -
-

参考

- -
-
-
-
高级API
-
高级SDK API的参考文档.
-
工具参考
-
用于 jpm工具 开发的参考文档, 测试, 打包add-ons, 全局 控制台记录, 和package.json 文件.
-
-
- -
-
-
低级API
-
低级SDK API的参考文档.
-
-
-
diff --git a/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/index.html b/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/index.html deleted file mode 100644 index 673c369430..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: 低层 API -slug: Mozilla/Add-ons/SDK/Low-Level_APIs -translation_of: Archive/Add-ons/Add-on_SDK/Low-Level_APIs ---- -

{{AddonSidebar}}

- -

本节的模块实现了低层的 API,这些模块大至分为三类:

- - - -

这些模块仍在开发中,我们预期在将来发布的版本中会做出不兼容的变更。

- -

{{ LandingPageListSubpages ("/zh-CN/Add-ons/SDK/Low-Level_APIs", 5) }}

- -

 

diff --git a/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/test_assert/index.html b/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/test_assert/index.html deleted file mode 100644 index 5f7537ec42..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/test_assert/index.html +++ /dev/null @@ -1,283 +0,0 @@ ---- -title: test/assert -slug: Mozilla/Add-ons/SDK/Low-Level_APIs/test_assert -translation_of: Archive/Add-ons/Add-on_SDK/Low-Level_APIs/test_assert ---- -

{{LegacyAddonsNotice}}{{AddonSidebar}}

- -
-

Unstable

-
- -

实现在 CommonJS Unit Testing specification version 1.1 其中定义的断言接口。

- -

Usage

- -

To use the assert module, write a set of unit tests following the instructions in the unit testing tutorial. Each test will be passed an Assert object when you run the tests using jpm test. You can use this object to make assertions about your program's state.

- -

For example:

- -
var a = 1;
-
-exports["test value of a"] = function(assert) {
-  assert.ok(a == 1, "test that a is 1");
-}
-
-require("sdk/test").run(exports);
- -

Globals

- -

Constructors

- -

Assert(logger)

- -

Create a new Assert object. This function is only called by the unit test framework, and not by unit tests themselves.

- -
Parameters
- -

logger : object
- Object used to log the results of assertions.

- -

Assert

- -

An object used to make assertions about a program's state in order to implement unit tests.

- -

The Assert object's interface is defined by the CommonJS Unit Testing specification, version 1.1.

- -

Methods

- -

ok(guard, message)

- -

Tests whether an expression evaluates to true.

- -
assert.ok(a == 1, "test that a is equal to one");
- -

This is equivalent to:

- -
assert.equal(a == 1, true, "test that a is equal to one");
- -
Parameters
- -

guard : expression
- The expression to evaluate.

- -

message : string
- Optional message to log, providing extra information about the test.

- -

equal(actual, expected, message)

- -

Tests shallow, coercive equality with ==:

- -
assert.equal(1, 1, "test that one is one");
- -
Parameters
- -

actual : object
- The actual result.

- -

expected : object
- The expected result.

- -

message : string
- Optional message to log, providing extra information about the test.

- -

notEqual(actual, expected, message)

- -

Tests that two objects are not equal, using !=:

- -
assert.notEqual(1, 2, "test that one is not two");
- -
Parameters
- -

actual : object
- The actual result.

- -

expected : object
- The expected result.

- -

message : string
- Optional message to log, providing extra information about the test.

- -

deepEqual(actual, expected, message)

- -

Tests that two objects have a deep equality relation. Deep equality is defined in the CommonJS specification for Assert, item 7, which is quoted here:

- -
-
    -
  1. All identical values are equivalent, as determined by ===.
  2. -
  3. If the expected value is a Date object, the actual value is equivalent if it is also a Date object that refers to the same time.
  4. -
  5. Other pairs that do not both pass typeof value == "object", equivalence is determined by ==.
  6. -
  7. For all other Object pairs, including Array objects, equivalence is determined by having the same number of owned properties (as verified with Object.prototype.hasOwnProperty.call), the same set of keys (although not necessarily the same order), equivalent values for every corresponding key, and an identical "prototype" property. Note: this accounts for both named and indexed properties on Arrays.
  8. -
-
- -
assert.deepEqual({ a: "foo" }, { a: "foo" }, "equivalent objects");
- -
Parameters
- -

actual : object
- The actual result.

- -

expected : object
- The expected result.

- -

message : string
- Optional message to log, providing extra information about the test.

- -

notDeepEqual(actual, expected, message)

- -

Tests that two objects do not have a deep equality relation, using the negation of the test for deep equality:

- -
assert.notDeepEqual({ a: "foo" }, Object.create({ a: "foo" }),
-                    "object's inherit from different prototypes");
- -
Parameters
- -

actual : object
- The actual result.

- -

expected : object
- The expected result.

- -

message : string
- Optional message to log, providing extra information about the test.

- -

strictEqual(actual, expected, message)

- -

Tests that two objects are equal, using the strict equality operator ===:

- -
// This test will pass, because "==" will perform type conversion
-exports["test coercive equality"] = function(assert) {
-  assert.equal(1, "1", "test coercive equality between 1 and '1'");
-}
-
-// This test will fail, because the types are different
-exports["test strict equality"] = function(assert) {
-  assert.strictEqual(1, "1", "test strict equality between 1 and '1'");
-}
- -
Parameters
- -

actual : object
- The actual result.

- -

expected : object
- The expected result.

- -

message : string
- Optional message to log, providing extra information about the test.

- -

notStrictEqual(actual, expected, message)

- -

Tests that two objects are not equal, using the negation of the strict equality operator ===:

- -
// This test will fail, because "==" will perform type conversion
-exports["test coercive equality"] = function(assert) {
-  assert.notEqual(1, "1", "test coercive equality between 1 and '1'");
-}
-
-// This test will pass, because the types are different
-exports["test strict equality"] = function(assert) {
-  assert.notStrictEqual(1, "1", "test strict equality between 1 and '1'");
-}
- -
Parameters
- -

actual : object
- The actual result.

- -

expected : object
- The expected result.

- -

message : string
- Optional message to log, providing extra information about the test.

- -

throws(block, error, message)

- -

Assert that a block of code throws the expected exception.

- -

This method takes an optional Error argument:

- - - - -

For example, suppose we define two different custom exceptions:

- -
function MyError(message) {
-  this.name = "MyError";
-  this.message = message || "Default Message";
-}
-
-MyError.prototype = new Error();
-MyError.prototype.constructor = MyError;
-
-function AnotherError(message) {
-  this.name = "AnotherError";
-  this.message = message || "Default Message";
-    console.log(this.message);
-}
-
-AnotherError.prototype = new Error();
-AnotherError.prototype.constructor = AnotherError;
- -

We can check the type of exception by passing a function as the Error argument:

- -
exports["test exception type 1 expected to pass"] = function(assert) {
-  assert.throws(function() {
-    throw new MyError("custom message");
-  },
-  MyError,
-  "test throwing a specific exception");
-}
-
-exports["test exception type 2 expected to fail"] = function(assert) {
-  assert.throws(function() {
-    throw new MyError("custom message");
-  },
-  AnotherError,
-  "test throwing a specific exception");
-}
- -

We can check the message by passing a regular expression:

- -
exports["test exception message 1 expected to pass"] = function(assert) {
-  assert.throws(function() {
-    throw new MyError("custom message");
-  },
-  /custom message/,
-  "test throwing a specific message");
-}
-
-exports["test exception message 2 expected to pass"] = function(assert) {
-  assert.throws(function() {
-    throw new AnotherError("custom message");
-  },
-  /custom message/,
-  "test throwing a specific exception");
-}
-
-exports["test exception message 3 expected to fail"] = function(assert) {
-  assert.throws(function() {
-    throw new MyError("another message");
-  },
-  /custom message/,
-  "test throwing a specific message");
-}
- -
Parameters
- -

block : block
- The block of code to test.

- -

error : function|RegExp
- Either a constructor function returning the type of exception expected, or a regular expression expected to match the exception's message property.

- -

message : string
- Optional message to log, providing extra information about the test.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/ui_button_action/index.html b/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/ui_button_action/index.html deleted file mode 100644 index d826b15d7f..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/low-level_apis/ui_button_action/index.html +++ /dev/null @@ -1,526 +0,0 @@ ---- -title: ui/button/action -slug: Mozilla/Add-ons/SDK/Low-Level_APIs/ui_button_action -translation_of: Archive/Add-ons/Add-on_SDK/Low-Level_APIs/ui_button_action ---- -
-

实验性的(译者备注:暂不翻译,可能会废弃)

-
-

Add a button to the Firefox user interface. With this module you can create buttons that display icons and can respond to click events.

-

Usage

-


- Creating buttons

-

To create a button you must give it an ID, an icon, and a label:

-
var { ActionButton } = require("sdk/ui/button/action");
-
-var button = ActionButton({
-    id: "my-button",
-    label: "my button",
-    icon: {
-      "16": "./firefox-16.png",
-      "32": "./firefox-32.png"
-    },
-    onClick: function(state) {
-        console.log("button '" + state.label + "' was clicked");
-    }
-  });
-

By default, the button appears in the Firefox toolbar:

-

However, users can move it to the Firefox menu panel using the toolbar customization feature:

-

-

Badged buttons

-
-

New in Firefox 36.

-
-

You can add a "badge" to a button using its badge property. This can be a number or a string, and you can update it at any time. By default the badge's color is red, but you can set your own color using the badgeColor property, specified as a CSS <color> value:

-
var { ToggleButton } = require("sdk/ui/button/toggle");
-
-var button = ToggleButton({
-    id: "my-button1",
-    label: "my button1",
-    icon: "./icon-16.png",
-    onChange: changed,
-    badge: 0,
-    badgeColor: "#00AAAA"
-  });
-
-function changed(state) {
-  button.badge = state.badge + 1;
-  if (state.checked) {
-    button.badgeColor = "#AA00AA";
-  }
-  else {
-    button.badgeColor = "#00AAAA";
-  }
-}
-

-

Specifying multiple icons

-

You can specify just one icon, or multiple icons in different sizes.

-

If you specify multiple icons, Firefox will select the best-fitting icon based on the device screen resolution and the place the icon appears. For example, in the screenshots above, Firefox uses the small icon when the button is in the toolbar and the large icon when the button is in the menu panel. Read more about specifying icons in the reference documentation for the ActionButton constructor.

-

Responding to click events

-

You can respond to click events by assigning a listener to the button's click event. You can do this in the button's constructor, by assigning the listener to the onClick option. You can also add, or change, the listener afterwards:

-
var { ActionButton } = require("sdk/ui/button/action");
-
-var button = ActionButton({
-    id: "my-button",
-    label: "my button",
-    icon: {
-      "16": "./firefox-16.png",
-      "32": "./firefox-32.png"
-    },
-    onClick: firstClick
-  });
-
-function firstClick(state) {
-  console.log("You clicked '" + state.label + "'");
-  button.removeListener("click", firstClick);
-  button.on("click", subsequentClicks);
-}
-
-function subsequentClicks(state) {
-  console.log("You clicked '" +  state.label + "' again");
-}
-

The listener is passed a state object that contains all the button's properties.

-

You can generate click events programmatically with the button's click() method.

-

Disabling buttons

-

You can disable a button by setting its disabled property to true. A disabled button will not generate click events and its icon will appear disabled:

-

-

Updating state

-

You can update all the button's properties except for its id.

-

By default, the button has global state: that is, its properties are the same across all open windows and tabs, and updating them updates the button's state across all open windows and tabs.

-

You can set state to be specific to a window or tab using the button's state() method. To set state like this, call state() with 2 parameters:

- -

Here's an add-on with a button that disables itself when you click it, but only for the currently active window:

-
var { ActionButton } = require("sdk/ui/button/action");
-
-var button = ActionButton({
-    id: "my-button",
-    label: "my button",
-    icon: {
-      "16": "./firefox-16.png",
-      "32": "./firefox-32.png"
-    },
-    onClick: disableForThisWindow
-  });
-
-function disableForThisWindow(state) {
-  button.state("window", {
-    disabled: true
-  });
-}
-

To fetch the state for a specific window or tab, call state(), passing in the window or tab you are interested in, and it will return the state:

-
var labelForActiveTab = button.state("tab").label;
-

To learn more about this, see the API documentation for state().

-

Destroying buttons

-

When you've finished with a button, destroy it by calling its destroy() method. After that, any attempts to access any of its properties or to call any of its methods will throw exceptions.

-

Globals

-

Constructors

-

ActionButton(options)

-

Creates an action button.

-
Parameters
-

options : object
- Required options:

- - - - - - - - - - - - - - - - - - - - - - - - - -
NameType 
idstring -

The button's ID. This is used internally to keep track of this button. The ID must be unique within your add-on.

-
labelstring -

The button's human-readable label. When the button is in the toolbar, this appears in a tooltip, and when the button is in the menu, it appears underneath the button as a legend.

-
iconurl, string, object -

One or more icons for the button. You can specify this in one of three ways: 

-
    -
  • as a resource:// URL pointing at an icon file in your add-on's "data" directory, typically constructed using self.data.url(iconfile)
  • -
  • as a relative path: a string in the form "./iconfile", where "iconfile" is a relative path to the icon file beginning in your add-on's "data" directory
  • -
  • as an object, or dictionary of key-value pairs. Here you can specify a range of sizes for your button's icon. Each key-value pair specifies an icon: -
      -
    • each value specifies an image file as a resource:// URL or relative path.
    • -
    • each key must be a numeric string such as "16", or "32", which represents the size in pixels of the corresponding image.
    • -
    -
  • -
-
-var { ActionButton } = require('sdk/ui/button/action');
-var self = require("sdk/self");
-
-var button1 = ActionButton({
-    id: "my-button1",
-    label: "my button1",
-    icon: self.data.url("firefox-16.png")
-  });
-
-var button2 = ActionButton({
-    id: "my-button2",
-    label: "my button2",
-    icon: "./firefox-16.png"
-  });
-
-var button3 = ActionButton({
-    id: "my-button3",
-    label: "my button3",
-    icon: {
-      "16" : "./firefox-16.png",
-      "32" : "./firefox-32.png",
-      "64" : "./firefox-64.png"
-    }
-  });
-

If you use the final form, Firefox will automatically choose the best-fit icon for your button, depending on the device screen resolution and where the button is in the UI. On a device with a "normal" screen resolution, the toolbar has space for 18 x 18 pixels and the menu panel has space for 32 x 32 pixels. On a high resolution screen (such as a HiDPI display), these are doubled to 36 x 36 and 64 x 64 pixels, respectively. So you can supply three icon files:

-
-icon: {
-  "16": "./addon16.png",
-  "32": "./addon32.png",
-  "64": "./addon64.png"
-}
-

This will look fine in both toolbar and menu panel, and for both screen resolutions. However, the icons in the toolbar will not quite fill the space available, so you can instead supply four icons:

-
-icon: {
-  "18": "./addon18.png", // toolbar icon non HiDPI
-  "32": "./addon32.png", // menu panel icon non HiDPI
-  "36": "./addon36.png", // toolbar icon HiDPI
-  "64": "./addon64.png"  // menu panel icon HiDPI
-}
-
-
-

Optional options:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameType 
disabledboolean -

Determines whether the button is disabled. Disabled buttons appear disabled in the UI, and do not respond to clicks. Defaults to false.

-
onClickfunction -

Click handler for the button.

-
badgeNumber or String -
-

New in Firefox 36.

-
-

Badge to attach to the button.

-
badgeColorCSS <color> value -
-

New in Firefox 36.

-
-

Color for the badge. If badgeColor is omitted and badge is specified, then the badge is red.

-
-

ActionButton

-

Methods

-

click()

-

Click the button. This will cause the button to generate the click event:

-
var { ActionButton } = require('sdk/ui/button/action');
-
-var button = ActionButton({
-  id: "my-button",
-  label: "my button",
-  icon: {
-    "16": "./firefox-16.png",
-    "32": "./firefox-32.png"
-  },
-  onClick: function(state) {
-      console.log("You clicked '" + state.label + "'");
-  }
-});
-
-button.click();
-
-

state()

-

Get or set the button's state for a specific window or tab.

-

By default, a button's properties are global, meaning that they are the same across all open windows and tabs, and that if you update these properties, then they are updated across all windows and tabs. But sometimes you want a button attached to one window (or tab) to have a different state to a button attached to a different window (or tab). That's what state() is for.

-

To set a button's properties for a specific window or tab, call state(), passing it the window or tab you want the property to apply to, and the property value to set. A special shortcut allows you to pass the string "window" or "tab" to select the currently active window or tab.

-

For example, if you have a button like this:

-
var { ActionButton } = require('sdk/ui/button/action');
-
-var button = ActionButton({
-  id: "my-button",
-  label: "default",
-  icon: "./firefox-16.png"
-});
-

You can change its label for only the currently active window like this:

-
button.state("window", {
-  "label" : "window-specific label"
-});
-

You can change its label for only the currently active tab like this:

-
button.state("tab", {
-  "label" : "tab-specific label"
-});
-
-

To fetch the button state for a specific window or tab, call state(), passing it the window or tab you're interested in, and it will return a state object containing all the properties for the button associated with that window or tab. Again. you can use the strings "window" or "tab" as shortcuts. For example, this add-on:

- -
var { ActionButton } = require('sdk/ui/button/action');
-var tabs = require("sdk/tabs");
-
-var button = ActionButton({
-  id: "my-button",
-  label: "default label",
-  icon: "./firefox-16.png"
-});
-
-tabs.open({
-  url: "https://mozilla.org/",
-  onOpen: onNewTab
-});
-
-function onNewTab(tab) {
-  // Modify the label only for the new tab
-  button.state(tab, {
-    "label" : "tab-specific label"
-  });
-
-  // access the global label -> "default label"
-  console.log(button.label);
-
-  // access the window's label -> "default label"
-  console.log(button.state("window").label);
-
-  // access the first tab's label -> "default label"
-  console.log(button.state(tabs[0]).label);
-
-  // access the second tab's label -> "tab-specific label"
-  console.log(button.state(tabs[1]).label);
-}
-

Setting a property won't affect a more-specific property setting. For example, if you have a window with two tabs, and you set a tab-specific label, then set the window-specific label, this will not overwrite the tab-specific label:

-
var { ActionButton } = require('sdk/ui/button/action');
-var tabs = require("sdk/tabs");
-
-var button = ActionButton({
-  id: "my-button",
-  label: "default label",
-  icon: "./firefox-16.png"
-});
-
-tabs.open({
-  url: "https://mozilla.org/",
-  onOpen: onNewTab
-});
-
-function onNewTab(tab) {
-  // Modify the label only for the new tab
-  button.state(tab, {
-    "label" : "tab-specific label"
-  });
-
-  // Modify the label for the window
-  button.state("window", {
-    "label" : "window-specific label"
-  });
-
-  // access the global label -> "default label"
-  console.log(button.label);
-
-  // access the window's label -> "window-specific label"
-  console.log(button.state("window").label);
-
-  // access the first tab's label -> "window-specific label"
-  console.log(button.state(tabs[0]).label);
-
-  // access the second tab's label -> "tab-specific label"
-  console.log(button.state(tabs[1]).label);
-}
-

The best way to think of this is as a tree: the global state is the root, followed by the state for each window, followed by the state for each tab in a window. If a property value for a node in the tree has not been set explicitly using state(), then it inherits its value from the next level up. So if you have one window containing two tabs, and have set the button's label only for tab A, then tab B will inherit label's value from the window, and changing the value for the window will implicitly change the value for tab B.

-

To delete a tab- or window-specific state, assign null to the property. After that, the property will inherit its value from the less-specific state as before:

-
var { ActionButton } = require('sdk/ui/button/action');
-var tabs = require("sdk/tabs");
-
-var button = ActionButton({
-  id: "my-button",
-  label: "default label",
-  icon: "./firefox-16.png"
-});
-
-tabs.open({
-  url: "https://mozilla.org/",
-  onOpen: onNewTab
-});
-
-function onNewTab(tab) {
-  // Modify the label only for the new tab
-  button.state(tab, {
-    "label" : "tab-specific label"
-  });
-
-  // Modify the label for the window
-  button.state("window", {
-    "label" : "window-specific label"
-  });
-
-  // access the global label -> "default label"
-  console.log(button.label);
-
-  // access the window's label -> "window-specific label"
-  console.log(button.state("window").label);
-
-  // access the first tab's label -> "window-specific label"
-  console.log(button.state(tabs[0]).label);
-
-  // access the second tab's label -> "tab-specific label"
-  console.log(button.state(tabs[1]).label);
-
-  // Reset the tab-specific state
-  button.state(tab, null);
-
-  // access the second tab's label -> "window-specific label"
-  console.log(button.state(tabs[1]).label);
-}
-

Finally, you can pass the button itself into state(). This is an alternative way to set or get the global state. The reason for using this, rather than setting properties individually, is that you can define an object with the properties to set in one place, then apply it to the global state with a single line:

-
const defaultState = {
-  "label": "default label",
-  "icon": "./default.png",
-}
-
-const differentState = {
-  "label": "different label",
-  "icon": "./different.png",
-}
-
-var { ActionButton } = require("sdk/ui/button/action");
-
-var button = ActionButton({
-    id: "default-label",
-    label: "default label",
-    icon: "./default.png",
-    onClick: function(state) {
-      if (button.label == "default label") {
-        button.state(button, differentState);
-      }
-      else {
-        button.state(button, defaultState);
-      }
-      console.log(button.state(button).label);
-      console.log(button.state(button).icon);
-    }
-  });
-
-
Parameters
-

target : button, tab, window, string

- -

state : object, null
- Include this parameter only if you are setting state. It is an object containing all the properties you wish to set. For example:

-
button.state("tab", {
-  "label" : "tab-specific label",
-  "icon": "./tab-specific-icon.ico"
-});
-

To reset state, pass null:

-
button.state("tab", null);
-
Returns
-

state : if you have passed the second state argument to make this function a setter, it returns undefined. Otherwise, it functions as a getter and returns the button's state for the specified object. This logs the state for the button associated with the currently active tab:

-
console.log(button.state("tab"));
-

This object represents a snapshot of the state at the time state() is called. It is not kept up to date with changes made to the button:

-
button.label = "foo";
-var state = button.state(button);
-button.label = "bar";
-console.log(state.label) // foo
-

on()

-

Add a listener to an event emitted by the button. The button only emits one type of event, click:

-
button.on("click", handleClick)
-
-function handleClick(state) {
-  console.log("button '" + state.label + "' was clicked");
-}
-
Parameters
-

event : string
- The event to listen for. Action buttons only emit one type of event, "click".

-

listener : function
- Function that will be called on click.

-

once()

-

Assign a listener to the first occurrence only of an event emitted by the button. The button only emits one type of event, click. The listener is automatically removed after the first time the event is emitted.

-
Parameters
-

event : string
- The event to listen for. Action buttons only emit one type of event, "click".

-

listener : function
- Function that will be called on click.

-

removeListener()

-

Removes an event listener. For example, this code is equivalent to once():

-
button.on("click", handleClick)
-
-function handleClick(state) {
-  console.log("button '" + state.label + "' was clicked");
-  button.removeListener("click", handleClick);
-} 
-
Parameters
-

event : string
- The event to listener is listening for. Action buttons only emit one type of event, "click".

-

listener : function
- The listener to remove.

-

destroy()

-

Destroy the button. After calling this function, the button will no longer appear in the UI, and accessing any of its properties or methods will throw an error.

-

Properties

-

id

-

The button's unique ID. This is read-only.

-

label

-

The button's label.

-

icon

-

The button's icon or icons, as a URL, relative path, or object containing a set of key-value pairs.

-

disabled

-

Boolean property indicating whether or not the button is disabled.

-

badge

-
-

New in Firefox 36.

-
-

Value to attach to the button as a badge. May be a number or a string.

-

badgeColor

-
-

New in Firefox 36.

-
-

Color for the badge, specified as a CSS <color> value.

-

Events

-

click

-

This event is emitted when a user clicks the button or your add-on calls the button's click() method.

-
Arguments
-

state : The button's state. This contains all the button's properties.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tools/index.html b/files/zh-cn/mozilla/add-ons/sdk/tools/index.html deleted file mode 100644 index 8c67b4644e..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tools/index.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Tools -slug: Mozilla/Add-ons/SDK/Tools -tags: - - Add-on SDK - - CFX - - JPM - - NeedsTranslation - - TopicStub -translation_of: Archive/Add-ons/Add-on_SDK/Tools ---- -

Articles listed here provide a reference for the SDK's tools:

- -

{{ LandingPageListSubpages ("/en-US/Add-ons/SDK/Tools", 7) }}

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tools/jpm/index.html b/files/zh-cn/mozilla/add-ons/sdk/tools/jpm/index.html deleted file mode 100644 index db429ef078..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tools/jpm/index.html +++ /dev/null @@ -1,652 +0,0 @@ ---- -title: jpm -slug: Mozilla/Add-ons/SDK/Tools/jpm -tags: - - Add-on SDK - - JPM -translation_of: Archive/Add-ons/Add-on_SDK/Tools/jpm ---- -

{{AddonSidebar}}

- -
-

你能在Firefox 38或更高的版本中使用jpm。

- -

本文为jpm参考。

-
- -

cfx 的Node版本允许你测试、运行以及打包扩展。

- -

你也可以阅读 jpm教程 开始学习。

- -

jpm 用法:

- -
jpm [command] [options]
-
- -

jpm支持以下全局参数:

- -
-h, --help        - 显示帮助信息并退出
--V, --version     - 打印出jpm版本号
---addon-dir       - 源代码目录,默认为当前目录
-
- -

安装

- -

jpm发布在node包管理器 npm 上。

- -

安装npm

- -

有两种方法来获取npm。

- - - -

要测试安装是否成功,运行:

- -
​/usr/bin/env node -v
- -

如果出现错误提示  /usr/bin/env: node: No such file or directory 并且你的 nodejs 是通过包管理的方式安装的,那你的 nodejs 很有可能安装为其它的名字。为了保证jpm的兼容,PATH之中必须是以node为可执行文件名的。在Debian和Ubuntu系统上,你可以通过安装兼容包nodejs-legacy来解决这个问题:

- -
sudo apt-get install nodejs-legacy
- -

在其它的发行版中,你或许必须手动创建一共本地符号链接:​

- -
sudo ln -s "$(which nodejs)" /usr/local/bin/node
- -

安装jpm

- -

在你安装好npm并且将其加入你的PATH中后,你可以像安装其他npm包一样来安装jpm。

- -

全局安装jpm

- -
npm install jpm --global
- -

取决于你的安装,你可能需要管理员权限执行:

- -
sudo npm install jpm --global
- -

局部安装jpm

- -

如果你不想,或者不能够全局安装jpm,你或许可以只为你安装它:

- -
npm install jpm
- -

在局部安装的情况下,为了在终端中运行jpm,你必须首先将目录"$HOME/node_modules/.bin/"添加到你的终端PATH中。将下行中的命令添加到$HOME/.profile的末尾来实现永久添加(.profile将在每次运行一个新终端时被执行):

- -
export PATH="$HOME/node_modules/.bin/:$PATH"
- -

通过git来安装jpm

- -

另外,你也可以通过git安装jpm的最新版本

- -
git clone https://github.com/mozilla-jetpack/jpm.git
-cd jpm
-npm install
-npm link
-
- -

jpm安装完毕后

- -

在全部搞定后,在命令行窗口中输入:

- -
jpm
- -

屏幕上显示了一系列可用的 jpm 命令。不同于 cfx,当在安装时使用了 --global 参数,你能在任何路径下启动的命令提示符中使用 jpm 命令。

- -

还有问题?

- -

如果你看不懂本文,要寻求帮助。SDK 用户和项目团队成员在项目邮件列表中讨论问题和建议。其他人也许会和你有一样的问题,所以试着搜索一下列表。也欢迎你发表一个新问题。你也可以在 Mozilla 的 IRC 网络#jetpack 房间里和其他SDK的用户聊天。

- -

命令参考

- -

有六个命令:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
jpm init创建一个基本的 add-on 作为你 add-on 的开端。
jpm run运行一个带有你的 add-on 的 Firefox 实例。
jpm test运行你插件的单元测试
jpm xpi将你的插件打包为 XPI 文件(火狐的插件扩展文件名)
jpm post把你的 add-on 打包成 XPI 文件,然后发送到某一个URL。
jpm watchpost无论是否有文件变更,把你的 add-on 打包成 XPI 文件发送到某一个URL。
jpm sign将你的插件打包为 XPI 文件并且取回一个由Mozilla签名的新XPI文件。
- -

jpm init

- -

这个命令从头开始初始化一个新的 add-on。

- -

新建一个目录,转到该目录下,然后运行 jpm init

- -
mkdir my-addon
-cd my-addon
-jpm init
- -

然后你会被要求提供关于你的 add-on 的一些信息:这会用来创建 package.json 文件。

- - - -

大部分字段都有一个默认值,显示在那些问题的后面的括号里。如果你按了回车,那么你的 add-on 就用那个默认值。

- -

一旦你提供了一个值或者接受了默认值,你会看到"package.json"的完整内容,并被询问是否接受。

- -

然后 jpm 创建一个基本的 add-on,作为你开发的起点,文件结构如下:

- - - -

jpm run

- -

此命令运行一个新的装有你的 add-on 的 Firefox实例:

- -
jpm run
- -

jpm run 有以下选项:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-b --binary BINARY -

指定二进制文件,使用该版本的火狐。可以用全路径,也可以用相对路径。

- -
-jpm run -b /path/to/Firefox/Nightly
- 参看选择浏览器版本
--binary-args CMDARGS -

传递附件参数到 Firefox。

- -

例如,为了传递 -jsconsole参数给 Firefox 并打开浏览器,试试下面命令:

- -
-jpm run --binary-args -jsconsole
- -

要传递多个参数,或者参数中间有空格,就把他们用引号括起来:

- -
-jpm run --binary-args '-url mzl.la -jsconsole'
-
--debug运行这个 add-on 的Add-on 调试器
-o --overload PATH -

不再使用 Firefox 内建的 SDK 模块,使用指定 PATH 路径下的模块。如果加了 -o 但 PATH 没有指定,jpm 会寻找 JETPACK_ROOT 环境变量用作路径

- -

参看重载内建模块以获取更多信息

-
-p --profile= PROFILE -

在你每次调用jpm run时,jpm 默认使用一个干净的临时的 Firefox 配置文件(profile)。使用--profile 选项以使得 jpm 使用已有的配置文件来打开 Firefox。

- -

PROFILE的值可以是一个profile的名字或路径。

- -

参看 使用 profile 以获取更多信息。

-
-v --verbose(查看)详细操作
--no-copy -
小心使用,因为 jpm run|test 会改变很多配置,不要和你的主配置文件一起使用。
- -
只有使用 --profile 的时候回生效
- 禁止配置文件的拷贝,允许重用配置。
 
- -

jpm test

- -

这个命令用来运行 add-on 的单元测试。命令:

- - - -
jpm test
- -

查看 单元测试教程 assert 模块参考文档获取更多具体内容。

- -

jpm test 接受一下选项:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-b --binary BINARY -

指定所用 Firefox 的版本。BINARY 可被指定为绝对路径或者基于当前路径的相对路径。

- -
-jpm test -b /path/to/Firefox/Nightly
- -

请查看选择一个浏览器版本

-
--binary-args CMDARGS -

传递附件参数给 Firefox。

- -

例如,传递 -jsconsole 参数,它会打开浏览器控制台,试试下面的命令:

- -
-jpm test --binary-args -jsconsole
- -

传递多个参数,或者参数间有空格,请将它们用引号括起来:

- -
-jpm test --binary-args '-url mzl.la -jsconsole'
-
--debug运行 add-on debugger 附件到当前 add-on 上。
-f --filter FILE[:TEST] -

只运行名字和 FILE 匹配的测试文件,且名字匹配 TEST(可选)的测试函数。

- -
-jpm test --filter base64:btoa
- -

上面的命令值会运行名字中含有"base64"的文件,在这些文件中只会运行名字中含有"btoa"的测试函数。

-
-o --overload PATH -

不使用 Firefox 内建的模块,而使用 PATH 路径下的模块。如果 -o 指定而 PATH 被忽略,jpm会查找 JETPACK_ROOT 环境变量并将其用作路径。

- -

查看重载内建模块以获取更多信息。

-
-p --profile PROFILE -

你每次运行jpm call时,默认地,jpm使用一个干净的临时 Firefox 配置文件。使用--profile 选项来让 jpm 使用一个现有配置文件来打开火狐。

- -

PROFILE 的值可以是配置文件的名称或者指向配置文件的路径。

- -

查看使用配置文件来获取更多信息。

-
--stop-on-error -

即使测试失败,jpm test 默认还会继续运行测试。指定 --stop-on-error 的话,会在第一次失败后停止运行测试

- -
-jpm test --stop-on-error
-
--tbplTreeherder 格式打印 test 的输出
--times NUMBER -

运行几遍 test:

- -
-jpm test --times 2
-
-v --verbose详细操作。
--no-copy -

小心使用,因为 jpm run|test 会修改许多首选项,这些首选项在你的主配置文件中从未用过。

- -

这仅仅在使用 --profile 时生效。

- 禁用配置未经的拷贝,允许用户重用配置文件。
- -

jpm xpi

- -

这个命令将 add-on 打包为一个 XPI 文件,这是 Mozilla 附加组件的安装文件的格式。

- -
jpm xpi
- -

它会在当前目录(或者 --addon-dir 指定的目录)查找 package.json 文件,并创建相关的 XPI 文件。它忽略任何 ZIP 或 XPI文件(译者注:OSX 上测试下来不会默认忽略这些文件,若要忽略请编辑.jpmignore文件),以及任何测试文件。它会包含其他所有文件。如果你想排除其他文件,查看 .jpmignore 文件

- -

一旦你构建了一个 XPI 文件,你可以通过提交到 addons.mozilla.org 来分发你的附加组件。

- -

jpm xpi 接受下列选项:

- - - - - - - - -
-v --verbose -

打印详细操作:

- -
-jpm xpi -v
-
- -

jpm post

- -

这个命令把附加组件打包为 XPI 后 post 到某个URL。

- -
jpm post
- -

查找当前目录(或 --addon-dir)下的package.json 文件,创建 XPI 文件,post 到 --post-url

- -

jpm post 接受以下选项:

- - - - - - - - - - - - -
--post-url URL -

创建 XPI 文件后,将扩展 post 到这个URL。

- -
-jpm post --post-url http://localhost:8888/
- -

查看使用 Post 和 Watchpost 获取更多信息。

-
-v --verbose -

打印详细操作:

- -
-jpm post --post-url http://localhost:8888/ -v
-
- -

jpm watchpost

- -

这个命令在打包附件组件为 XPI 文件后,无论文件是否改变都将其 post 到某个URL。

- -
jpm watchpost
- -

无论文件是否改变,在当前目录(或 --addon-dir)下创建一个 XPI并将其post到 --post-url

- -

jpm watchpost 接受以下选项:

- - - - - - - - - - - - -
--post-url URL -

创建 XPI 文件后,将扩展 post 到这个URL。

- -
-jpm watchpost --post-url http://localhost:8888/
- -

查看 Using Post 和 Watchpost 获取更多信息。

-
-v --verbose -

打印详细信息:

- -
-jpm watchpost --post-url http://localhost:8888/ -v
-
- -

jpm sign

- -

此特性仅从 jpm 1.0.4 起被支持。

- -

此命令为你的附加组件重新生成一个新的被Mozilla签名的 XPI 文件。这就允许你自己托管你的 add-on,这样用户可以在安装时避免 signed add-ons are required 错误。在用这个命令之前,你需要在 addons.mozilla.org 创建 API 证书

- -

你可以为你已经生成的 XPI 文件签名,就像如下,通过传递 XPI 文件给 --xpi参数:

- -
jpm sign --api-key ${AMO_API_KEY} --api-secret ${AMO_API_SECRET} --xpi <xpi file>
- -

或者,你可以省略 --xpi 参数,这样 jpm sign 会从当前目录(或者 --addon-dir)生成一个XPI文件。

- -
jpm sign --api-key ${AMO_API_KEY} --api-secret ${AMO_API_SECRET}
- -

上面提交了一个 XPIaddons.mozilla.org 签名g API,如果通过验证,然后下载一个签名后的 XPI 文件到工作目录。

- -

下面是一些运行 sign 命令的结果:

- - - -

在底层,jpm signaddons.mozilla.org里创建了一个不会被列出的附加组件,这就意味着你必须自己把XPI文件分发给你的用户来安装。如果你需要创建一个在列表中的附加组件,只要直接将它提交到 addons.mozilla.org,在那里它自动会被签名。如果你在安装一个已签名的附加组件时遇到困难,参看调试一节。

- -

jpm sign 接收以下参数:

- - - - - - - - - - - - - - - - - - - - -
--api-key=API_KEY -

addons.mozilla.org key管理页面生成的API访问key(字符串)。

-
--api-secret=API_SECRET -

addons.mozilla.org key 管理页面生成的API访问密钥(字符串)。这个值应该被小心保密并且永远不要记录到版本控制中。如果你的密钥被破解,另一个开发者就能上传附加组件到你的账号上。你应该立即撤销泄露的API证书并且重新生成一份。

-
--api-url-prefix=http://.../api -

可选的API URL前缀,如果你想使用一个试用签名的API。

- -

例如,你可以通过https://addons-dev.allizom.org/api/v3的认证来使用addons.mozilla.org的开发者版本。

-
--xpi=/path/to/file.xpi -

需要签名的XPI文件。如果没指定文件,一个新的XPI会在当前目录(或者--addon-dir)中生成。

-
- -

一些技巧

- -

选择浏览器版本

- -

默认地,jpm runjpm test 运行 release 版本的 FireFox。你可以有一两种办法来告诉 jpm 使用一个不同的版本:

- - - -

使用 .jpmignore 来忽略文件

- -

使用 .jpmignore 就像使用 git.gitignore,Mercurial 的 .hgignore,或者 npm 的 .npmignore。通过使用这个文件,你可以在使用 jpm xpi 编译 .xpi 文件时,让 jpm 知道你想要忽略哪些文件。

- -

这是个例子:

- -
# Ignore .DS_Store files created by mac
-.DS_Store
-
-# Ignore any zip or xpi files
-*.zip
-*.xpi
- -

有着以上内容的 .jpmignore 文件会忽略所有的 zip 文件和 .DS_Store 文件,这些文件不会包括在 jpm xpi 所生成的 xpi 文件中。

- -

使用配置

- -

默认地,jpm run 每次都会使用一个新的配置。这就意味着前一次运行 jpm 时的任何配置,默认都不会在下一次中使用。

- -

这其中包括,比如你安装的任何附加组件,或者你的历史记录,或者任何使用 simple-storage API 存储的数据。

- -

为了让 jpm 使用一个特定的配置,传递 --profile 选项,设定你想使用的配置文件的名字,或者是配置文件的路径。

- -
jpm run --profile boogaloo
- -
jpm run --profile path/to/boogaloo
- -

如果你提供了 --profile 但是它的参数不是一个已有配置文件的名字或路径,jpm 会打开 配置文件管理器 让你选择一个已有的配置文件或者创建一个新的配置文件:

- -
jpm run --profile i-dont-exist
- -

开发时不用重启浏览器

- -

因为每次调用 jpm run 时都会重启浏览,如果你十分频繁地修改附加组件,这就可能有点笨重了。一个替代的开发模型是使用 扩展自动安装器附加组件:它会在特定端口监听新 XPI 文件并且自动安装它们。这样,你就能测试新的改动,而不用重启浏览器:

- - - -

你甚至可以用一个简单的脚本来自动化这一工作流程。例如:

- -
jpm watchpost --post-url http://localhost:8888/
- -

注意,比起使用 jpm run 运行附加组件时的日志级别,你在使用这个方法时控制台定义的日志级别是不一样的。这意味着,如果你想看到 console.log() 消息的输出,你必须微调一下配置。查看 logging levels 文档以获取这方面的详细信息。

- -

重载内建模块

- -

你用来实现你的附加组件的SDK模快是 Firefox 内建的。当你使用 jpm runjpm xpi 来运行或者打包附加组件时,附加组件使用其所在的 Firefox 版本中的模块版本。

- -

作为附件组件开发者,这一般就是你想要的。但是如果你在开发 SDK 模块本身,这就不合适了。这时你需要:

- - - -
jpm run -o
- -

这会通知 jpm 去使用 SDK 模块的本地拷贝,而不是 Firefox 内部的模块。如果你不想设置 JETPACK_ROOT 环境变量,你可以使用 -o 传递SDK模块本地拷贝的位置:

- -
jpm run -o "/path/to/addon-sdk/"
- -

路径必须是一个绝对路径并且指向 SDK 的根目录(不是 addon-sdk/sdk 或 addon-sdk/sdk/lib)。

- -

支持自托管附加组件的更新

- -

此特性仅被 jpm 1.0.3 及之后版本支持,

- -

当你给你的附加组件来添加特性或者修复 bug 时,你想让之前安装好的附加组件将自己从老版本更新到新版本。

- -

如果你在 addons.mozilla.org 上列出你的附加组件,那么你要做的只是提交一个新的版本;附加组件默认会检查它们在 addons.mozilla.org 上的新版本。好了,你不用继续往下看这一节了。

- -

如果你没有在 addons.mozilla.org 上列出你的附加组件,你需要生成一个 Mozilla 签名的 XPI 文件并告诉 Firefox 哪里可以找到这个附加组件的新版本。方法就是:

- - - -

为了达到这个目的,package.json中需要包含两个额外的key :

- - - -

- -

如果你设置了 updateURLupdateLink(如果 updateKey 不是 HTTPS 的,那也要包括 updateKey),那么 jpm xpi 会:

- - - -

然后你将更新清单托管到 updateURL,并且将新版 XPI 托管到 updateLink

- -

获取更多这方面的详细信息,参看自动检查附件组件更新

- -
 
- -
 
diff --git a/files/zh-cn/mozilla/add-ons/sdk/tools/package_json/index.html b/files/zh-cn/mozilla/add-ons/sdk/tools/package_json/index.html deleted file mode 100644 index cd08ff2b64..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tools/package_json/index.html +++ /dev/null @@ -1,312 +0,0 @@ ---- -title: package.json -slug: Mozilla/Add-ons/SDK/Tools/package_json -translation_of: Archive/Add-ons/Add-on_SDK/Tools/package_json ---- -

{{AddonSidebar}}

- -

The package.json file contains manifest data for your add-on, providing not only descriptive information about the add-on for presentation in the Add-ons Manager, but other metadata required of add-ons.

- -

一些条目, 比如icon, namedescription, 有类似install manifest的格式, 并且package.json会写入install manifest, 当使用jpm xpi的时候.

- -

Others, such as lib, permissions, and preferences, represent instructions to the jpm tool itself to generate and include particular code and data structures in your add-on.

- -

其他如lib, permissionspreferences表示使用jpm工具的步骤, 生成你扩展包含的特殊代码和数据结构.

- -

创建manifest

- -

package.json起初是通过运行jpm init生成的,通常在扩展的根目录.比如下面(假设扩展目录是"my-addon")

- -
{
-  "name": "my-addon",
-  "title": "my-addon",
-  "id": "jid1-1FERGV45e4f4f",
-  "description": "a basic add-on",
-  "author": "",
-  "license": "MPL-2.0",
-  "version": "0.1"
-}
- -

如果你使用新的jpm tool话,可以方便的从package.json获取manifest数据, 通过require其他模块的方式:

- -
var title = require("./package.json").title;
- -

Key reference

- -

package.json may contain the following keys:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
author -

The name of the package's original author; this could be the name of a person or a company. Defaults to an empty string. It may include a optional URL in parentheses and an email address in angle brackets.

- -

This value will be used as the add-on's em:creator element in the install.rdf file generated by cfx.

- -
Note: jpm supports NodeJS people fields.
-
contributors -

An array of additional author strings, identifying other contributors to the add-on.

- -

These values will be used as the add-on's em:contributor elements in its install.rdf.

- -
Note: This is deprecated along with cfx; it's not available when using jpm.
-
dependencies -

A string or an array of strings specifying the names of packages that this add-on requires in order to function properly.

-
description -

The add-on's description; this is a human-readable message describing what the add-on does. This defaults to the text "a basic add-on".

- -

This value will be used as the add-on's em:description element in its install.rdf.

-
engines -

Object with supported applications (key) and required version numbers (value).

- -
    -
  • firefox: Firefox Desktop
  • -
  • fennec: Firefox for Android
  • -
- -

Example:

- -
-  "engines": {
-    "firefox": ">=38.0a1",
-    "fennec": ">=38.0a1"
-  }
-
fullName {{deprecated_inline}} -
Note: This is deprecated along with cfx; it's not available when using jpm.
- -

The full name of the package. It can contain spaces.

- -

If this key is present its value will be used as the add-on's em:name element in its install.rdf.

-
harnessClassID {{deprecated_inline}} -
Note: This is deprecated along with cfx; it's not available when using jpm.
- -

String in the GUID format.

- -

This is used as a classID of the "harness service" XPCOM component. Defaults to a random GUID generated by cfx.

-
homepage -

The URL of the add-on's website.

- -

This value will be used as the add-on's em:homepageURL element in its install.rdf.

-
icon -

The path to an image file containing the icon for the add-on. Defaults to icon.png. If no icon is specified, the standard add-on icon will be used by default.

- -
-

When using jpm, relative path to the data directory (to make it re-usable for add-on HTML content) does not currently work. Instead you have to use following syntax:

- -

resource://ID/data/icon-name.png

- -

ID is the value from the id field. If it does not begin with the @-character, then @ has to be escaped as -at- and . as -dot-. If the ID is a GUID, the curly braces used in the id field are not included.

-
- -

This value will be used as the add-on's em:iconURL element in its install.rdf.

- -

The icon may be up to 48x48 pixels in size (although a bigger icon is tolerated here too)

-
icon64 {{deprecated_inline}} -
-

Note: This is deprecated along with cfx; it's not available when using jpm.

-
- -

The path to an image containing the large icon for the add-on. Defaults to icon64.png. If you don't provide an icon here, the same icon as specified by icon will be used.

- -

This value will be used as the add-on's em:icon64URL element in its install.rdf.

- -

The icon may be up to 64x64 pixels in size.

-
id -

A globally unique identifier for the add-on.

- -

This value will be used as the add-on's em:id element in its install.rdf.

- -

See the Program ID documentation.

-
lib -

String representing the top-level module directory provided in this add-on. Defaults to "lib".

- -
-

Note: This is deprecated along with cfx and is not available when using jpm.

-
-
license -

The name of the license under which the add-on is distributed, with an optional URL in parentheses. Defaults to "MPL-2.0".

- -
-

Note: It is recommend that you use an SPDX license ID.

-
-
main -

A string representing the name of a program module that is located in one of the top-level module directories specified by lib. Defaults to "main".

-
name -

The add-on's name. This name cannot contain spaces or periods, and defaults to the name of the parent directory.

- -

When the add-on is built as an XPI, if the fullName and title keys are not present, name is used as the add-on's em:name element in its install.rdf.

-
packages -
-

Note: This is deprecated along with cfx and is not available when using jpm.

-
- -

A string pointing to a directory containing additional packages. Defaults to "packages".

-
permissions -

A set of permissions that the add-on needs.

- -

private-browsing: a boolean indicating whether or not the add-on supports private browsing. If this value is not true or is omitted, then the add-on will not see any private windows or objects, such as tabs, that are associated with private windows. See the documentation for the private-browsing module.

- -

cross-domain-content: a list of domains for which content scripts are given cross-domain privileges to access content in iframes or to make XMLHTTPRequests. See the documentation for enabling cross-domain content scripts.

- -

multiprocess: a Boolean value declaring whether this add-on is, or is not, compatible with multiprocess Firefox.

- -
-

Note the multiprocess permission is not supported by cfx.

-
-
preferences -

An array of JSON objects that use the following keys: name,type, value, title, and description. These JSON objects will be used to create a preferences interface for the add-on in the Add-ons Manager.

- -

See the documentation for the simple-prefs module.

-
preferences-branchUse this to specify an alternative branch for your add-on's simple-prefs. See "Simple-prefs in the preferences system" for more details.
title -

The human-readable title of the package; this can contain spaces.

- -

If this key is present its value will be used as the add-on's em:name element in its install.rdf.

-
translators -

An array of strings listing the people who contributed to the localization of this add-on.

- -

These values will be used as the add-on's em:translator elements in its install.rdf.

- -
Note: jpm supports NodeJS people fields.
-
unpack -

Same as the unpack in an install.rdf file.

- -

Useful when the extension contains binaries.

-
updateKey -

Same as the updateKey in an install.rdf file.

- -

See Supporting updates for self-hosted add-ons.

- -
-

Note: This key is only available with jpm.

-
-
-

Same as the updateLink for an update.rdf file. Previously was --update-link in cfx.

- -

See Supporting updates for self-hosted add-ons.

- -
-

Note: This key is only available with jpm.

-
-
updateURL -

Same as the updateURL for an install.rdf file.

- -

See Supporting updates for self-hosted add-ons.

- -
-

Note: This key is only available with jpm.

-
-
version -

String representing the version of the add-on. Defaults to "0.0.1".

- -

This value is used as the add-on's em:version element in its install.rdf.

- -
-

Note: For jpm the version must be a valid semver.

-
-
- -

 

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/add_a_menu_item_to_firefox/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/add_a_menu_item_to_firefox/index.html deleted file mode 100644 index 29348bbabb..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/add_a_menu_item_to_firefox/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Add a Menu Item to Firefox -slug: Mozilla/Add-ons/SDK/Tutorials/Add_a_Menu_Item_to_Firefox -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Add_a_Menu_Item_to_Firefox ---- -
-

学习本模块你需要 安装SDK 学习基础工具cfx.

-
-
-

如果你使用 jpm 替代cfx, 使用第三方模块的方式是不同的, 你应该阅读 jpm的相应版本替代本教程.

-

给予Python可能未来废弃,使用JPM基于nodejs(译者备注).

-
-

SDK还不能为火狐浏览器提供一个API添加新的菜单项。但它是可扩展的设计,所以任何人都可以建立和发布模块,使用插件开发者。幸运的是埃里克沃尔德写的MenuItems模块,能够使我们添加菜单项

-

本教程有双重的责任。它描述的一般方法,使用一个外部的在你的插件的第三方模块描述了如何使用特别的MenuItems模块添加一个菜单项

-

首先,创建一个新的扩展程序。创建一个目录名称为clickme(名称随意)找到它并运行cfx init初始化

-
mkdir clickme
-cd clickme
-cfx init
-
-

通常将创建目录结构:

- -
-  
-

安装 menuitems

-

在 "clickme"下创建一个名称为"packages"的目录. 从 https://github.com/mykmelez/menuitems-jplib  下载 menuitems 并展开到刚才创建的"packages" 目录下:

-
mkdir packages
-cd packages
-tar -xf ../erikvold-menuitems-jplib-d80630c.zip
-
-

模块依赖

-

如果第三方模块取决于SDK模块可以马上使用它们但如果他们依赖于其他第三方模块你需要安装依赖以及

-

在软件包的主目录,你会发现一个叫做 "package.json"的文件.  打开它,看看一个名称"dependencies"的入口.  menuitems 包的入口:

-
"dependencies": ["vold-utils"]
-
-

这告诉我们需要安装 vold-utils 包, 我们可以从https://github.com/mykmelez/vold-utils-jplib 下载,并添加到 packages 目录下的旁边的menuitems.

-

使用menuitems

-

 Menuitems模块文档 告诉使用MenuItem()创建一个新的菜单项. MenuItem()可接受的附加选项, 我们将使用最迷你的配置:

- -
-
-
var menuitem = require("menuitems").Menuitem({
-  id: "clickme",
-  menuid: "menu_ToolsPopup",
-  label: "Click Me!",
-  onCommand: function() {
-    console.log("clicked");
-  },
-  insertbefore: "menu_pageInfo"
-});
-
-  
-
-
-

接下来, 我们将声明menuitems的依赖包. 在你的add-on's package.json文件添加一行:

-
"dependencies": "menuitems"
-
-

Note that due to bug 663480, if you add a dependencies line to package.json, and you use any modules from the SDK, then you must also declare your dependency on that built-in package, like this:

-
"dependencies": ["menuitems", "addon-sdk"]
-
-

现在我们要做的。运行插件你会看到新的项目出现在工具菜单:选择它,你会看到info: clicked 出现在控制台

-

Caveats

-

第三方模块使用不直接支持的SDK功能的好方法,但由于第三方模块通常使用低级别的API它们可以通过Firefox的新版本

-

 

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/adding_a_button_to_the_toolbar/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/adding_a_button_to_the_toolbar/index.html deleted file mode 100644 index 8e4438f818..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/adding_a_button_to_the_toolbar/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 在工具栏上添加按钮 -slug: Mozilla/Add-ons/SDK/Tutorials/Adding_a_Button_to_the_Toolbar -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Adding_a_Button_to_the_Toolbar ---- -
-

动手之前,必须先安装SDK并学习cfx基础.

- -

这篇教程使用动作按钮API,需要Firefox 29或更新版本。

-
- -

如果要给工具栏添加一个按钮,需要使用动作按钮切换按钮模块。

- -

新建一个目录,打开它,执行cfx init

- -

然后,把这三个图标保存到data文件夹:

- - - - - - - - - - - - - - - - -
icon-16.png
icon-32.png
icon-64.png
- -

随后打开lib目录下的main.js文件,添加如下代码:

- -
var buttons = require('sdk/ui/button/action');
-var tabs = require("sdk/tabs");
-
-var button = buttons.ActionButton({
-  id: "mozilla-link",
-  label: "Visit Mozilla",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onClick: handleClick
-});
-
-function handleClick(state) {
-  tabs.open("https://www.mozilla.org/");
-}
- -

现在输入cfx run来执行附加组件。按钮添加到了浏览器顶部的工具栏上:

- -

你无法设置按钮的初始位置,但是用回可以使用浏览器的自定义功能移动它。其中的id属性是必需的,用来记录按钮的位置,因此,你最好不要在后续版本中修改它。

- -

单击按钮,https://www.mozilla.org/将会在新的标签页中加载。

- -

设定图标

- -

icon属性可以设定单个或是一组不同大小图标。如果你用的是一组不同大小的图标,浏览器将会自动选择最适合当前屏幕分辨率的,然后显示在浏览器界面的按钮上。更多内容,参考设定多个图标

- -

图标文件必须打包在附加组件内:它不可以指向一个远程文件。

- -

你只要正确地设置了按钮的icon属性,它就会立刻生效。你可以改变全局的,在特定窗口的或者是特定标签页中显示的图标或者是其他状态属性。更多内容,参考更新状态

- -

附加一个面板

- -

如果你想把一个面板附加到按钮上,使用切换按钮API。这就和动作按钮API类似,只不过多了一个boolean值属性,表示按钮是否被checked。附加面板,要把按钮传递给面板的show()方法。更多细节,参考切换按钮文档

- -

显示更多样的内容

- -

添加按钮做不到的复杂界面功能,需要使用工具栏API。 使用工具栏API你可以得到一个用户界面内容的水平条。可以添加按钮或者是可以包含HTML,CSS,javaScript的frame到工具栏上。

- -

进一步学习

- - diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/implementing_the_widget/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/implementing_the_widget/index.html deleted file mode 100644 index 04e4a75d23..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/implementing_the_widget/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: 实现控件 -slug: Mozilla/Add-ons/SDK/Tutorials/Annotator/Implementing_the_widget -tags: - - 附加组件 -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Annotator/Implementing_the_widget ---- -

我们想要控件做两件事:

- - - -

因为控件无法区分鼠标左右键的点击,我们应当使用内容脚本来捕获单击事件并发送相应的消息到附加组件。

- -

控件将有两个图标:一个在注释器启用时显示,一个在禁用时显示。

- -

因此,我们需要创建三个文件:控件的内容脚本和两个图标。

- -

在data子目录创建一个widget子目录,我们将把控件的文件保存在这里(注意,这个不是强制性的:你可以仅仅把它们放在data里,但分类放置会更加整洁)。

- -

控件的内容脚本

- -

控件的内容脚本仅仅监听鼠标的左右单击并发送相应的消息到附加组件代码:

- -
this.addEventListener('click', function(event) {
-  if(event.button == 0 && event.shiftKey == false)
-    self.port.emit('left-click');
-
-  if(event.button == 2 || (event.button == 0 && event.shiftKey == true))
-    self.port.emit('right-click');
-    event.preventDefault();
-}, true);
- -

把它保存在data/widget并命名为widget.js。

- -

控件图标

- -

你可以从这里复制图标:

- -

- -

或者自己动手做你觉得有创造性的图标。把它们保存在data/widget目录。

- -

main.js

- -

现在在lib目录创建main.js并添加下列内容:

- -
var widgets = require('sdk/widget');
-var data = require('sdk/self').data;
-
-var annotatorIsOn = false;
-
-function toggleActivation() {
-  annotatorIsOn = !annotatorIsOn;
-  return annotatorIsOn;
-}
-
-exports.main = function() {
-
-  var widget = widgets.Widget({
-    id: 'toggle-switch',
-    label: 'Annotator',
-    contentURL: data.url('widget/pencil-off.png'),
-    contentScriptWhen: 'ready',
-    contentScriptFile: data.url('widget/widget.js')
-  });
-
-  widget.port.on('left-click', function() {
-    console.log('activate/deactivate');
-    widget.contentURL = toggleActivation() ?
-              data.url('widget/pencil-on.png') :
-              data.url('widget/pencil-off.png');
-  });
-
-  widget.port.on('right-click', function() {
-      console.log('show annotation list');
-  });
-}
- -

注释器默认禁用。它创建控件并通过切换注释器的活动状态来回应来自控件内容脚本的消息。注意,由于bug 626326,附加组件状态栏的环境菜单会显示,尽管在控件的内容脚本中调用了event.preventDefault()。由于我们没有任何代码来显示注释,所以我们们仅仅记录右击事件到控制台。

- -

现在在注释器目录输入cfx run,你应该看见在附加组件状态栏的控件:

- -

- -

左击和右击应当产生合适的调试输出,同时左击应当改变控件的图标为启用状态。

- -

 

- -

下一步,我们将添加代码来创建注释器

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/index.html deleted file mode 100644 index 4f76d67802..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/index.html +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: 注释器(Annotator) -slug: Mozilla/Add-ons/SDK/Tutorials/Annotator -tags: - - 附加组件 -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Annotator ---- -
-

请注意教程中Widget API适合的浏览器版本。(译者注)

-
- -

在这个教程中,我们将构建一个使用许多SDK高级API的附加组件.

- -

这个附加组件是一个注释器:它可以让用户选择网页的元素并输入有关的笔记(注释).注释器储存笔记.无论用户何时载入包含被注释元素的页面,这些元素都将会高亮显示,并且用户若把鼠标移动到被注释元素的上面,将会显示它的注释.

- -

接着我们将给出这个注释器设计的快速简介,然后一步步的讨论如何实现.

- -

如果你想参阅完整的附加组件,你可以在SDK例子目录找到它.

- - diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/overview/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/overview/index.html deleted file mode 100644 index da94f8142a..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/annotator/overview/index.html +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: 概述 -slug: Mozilla/Add-ons/SDK/Tutorials/Annotator/Overview -tags: - - addon sdk example - - annotator example - - 附加组件 -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Annotator/Overview ---- -

注释器使用内容脚本(content scripts)来构建用户界面,得到用户输入,并检查用户载入页面的DOM。

- -

同时,主要模块包括程序逻辑和调节不同SDK对象的交互。

- -

我们可以描述在主要模块和不同内容脚本的交互,像这样:

- -

- -

用户界面

- -

注释器的主要用户界面由一个控件和三个面板组成。

- - - -

除此之外,我们使用 notifications 模块来告知用户附加组件的储存限额已满。

- -

用DOM工作

- -

我们将使用 page-mods 来和用户打开的网页的DOM进行交互。

- - - -

处理数据

- -

我们将使用simple-storage模块来储存数据。

- -

由于我们将记录潜在的敏感信息,我们想阻止用户在隐私浏览模式下创建注释,最简单的方式是删除附加组件中“package.json“文件的”private-browsing"键。这样,附加组件就不能看见任何隐私浏览窗口,同时注释器的控件也将不再出现。

- -

开始行动

- -

现在让我们来创建叫“注释器”的目录。Navigate to it and type cfx init.

- -

下一步,我们将实现控件

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/display_a_popup/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/display_a_popup/index.html deleted file mode 100644 index 9bec4966d4..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/display_a_popup/index.html +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: 显示弹出对话框 -slug: Mozilla/Add-ons/SDK/Tutorials/Display_a_Popup -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Display_a_Popup ---- -
-

动手之前,必须先安装SDK并学习cfx基础知识.

-

T这篇教程使用动作按钮API需要Firefox 29或更新版本。

-
-

可以使用面板(panel)模块来显示弹出对话框。面板的内容通过HTML编写。你可以在面板上运行content script:尽管在面板里的脚本无法直接访问插件代码,但是你可以在面板脚本和插件代码间交换信息。

-

这里,我们做了一个会在单击时显示面板的动作按钮。面板上有一个<textarea>元素:用户按下return键时,<textarea>的内容会被发送给插件代码主程序。插件代码主程序会在控制台输出日志。.

-

The add-o插件由六个文件组成n consists of six files:

- -

"main.js"像这样:

-
var data = require("sdk/self").data;
-// 构造面板,从"data"目录的"text-entry.html"加载
-// 内容,然后加载"get-text.js"脚本。
-var text_entry = require("sdk/panel").Panel({
-  contentURL: data.url("text-entry.html"),
-  contentScriptFile: data.url("get-text.js")
-});
-
-// 创建按钮
-require("sdk/ui/button/action").ActionButton({
-  id: "show-panel",
-  label: "Show Panel",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onClick: handleClick
-});
-
-// 在用户点击按钮时显示面板。
-function handleClick(state) {
-  text_entry.show();
-}
-
-// When the panel is displayed it generated an event called
-// "show": we will listen for that event and when it happens,
-// send our own "show" event to the panel's script, so the
-// script can prepare the panel for display.
-text_entry.on("show", function() {
-  text_entry.port.emit("show");
-});
-
-// 监听来自content脚本的text-entered消息。消息主体L是用户输入的文本。
-// 此实现,我们只在控制台显示日志。
-text_entry.port.on("text-entered", function (text) {
-  console.log(text);
-  text_entry.hide();
-});
-

content脚本"get-text.js"像这样:

-
-
// 用户按下回车,发送text-entered消息给main.js。
-// 消息主体是编辑框的内容。
-var textArea = document.getElementById("edit-box");
-textArea.addEventListener('keyup', function onkeyup(event) {
-  if (event.keyCode == 13) {
-    // Remove the newline.
-    text = textArea.value.replace(/(\r\n|\n|\r)/gm,"");
-    self.port.emit("text-entered", text);
-    textArea.value = '';
-  }
-}, false);
-// 监听由插件主程序发送的show事件。表示面板将要显示。
-//
-// 焦点放在textarea上,这样用户可以直接开始输入。
-self.port.on("show", function onShow() {
-  textArea.focus();
-});
-
-  
-
-

最后,"text-entry.html"文件定义了<textarea>元素:

-
-
-
<html>
-<head>
-    <style type="text/css" media="all">
-      textarea {
-        margin: 10px;
-      }
-      body {
-        background-color: gray;
-      }
-    </style>
-  </head>
-<body>
-    <textarea rows="13" cols="33" id="edit-box"></textarea>
-  </body>
-</html>
-
-  
-
-
-

最后,把这三个图标文件保存在"data"目录:

- - - - - - - - - - - - - - - -
icon-16.png
icon-32.png
icon-64.png
-

试用以下:保存在lib目录,其他五个文件存放在插件的data目录:

-
my-addon/
-         data/
-              get-text.js
-              icon-16.png
-              icon-32.png
-              icon-64.png
-              text-entry.html
-         lib/
-             main.js
-
-

运行插件,点击按钮,你就会看见一个面板。输入几行文本,然后按下回车,你就会看见控制台里的输出。

-

自Firefox 30起,如果你使用切换按钮,就可以给它附加一个面板

-

进一步学习

-

学习panel模块的更多内容,见panel API参考

-

学习关于按钮的更多内容,见动作按钮切换按钮API参考。

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/getting_started/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/getting_started/index.html deleted file mode 100644 index 225739de76..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/getting_started/index.html +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: 快速入门 -slug: Mozilla/Add-ons/SDK/Tutorials/Getting_started -tags: - - add-on sdk开发 - - cfx工具基础使用教程 - - 火狐扩展程序 -translation_of: Mozilla/Add-ons/SDK/Tutorials/Getting_Started_%28jpm%29 ---- -

{{AddonSidebar}}

- -
-

Add-on SDK 里包含了一个命令行工具,你可以用此工具来初始化、运行、测试以及打包 add on。 这个工具称为 jpm,基于 Node.js 。它替代了以前的cfx工具。

- -

你可以在 Firefox 38或之后的版本中使用。

- -

本文阐述如何使用 jpm 开发。

-
- -

本教程会过一遍使用 SDK 创建一个简单 add-on 的过程。

- -

准备

- -

要使用 SDK 创建 add-on,你需要:

- - - -

初始化空的 add-on

- -

在命令行提示符下,创建一个新目录。进入新文件夹,键入 jpm init,然后敲回车

- -
mkdir my-addon
-cd my-addon
-jpm init
-
- -

接着你会被要求提供一些关于你的 add-on 的信息:这会用来创建 package.json 文件。如果光按回车的话,就表示接受属性的默认值。关于 jpm init 的更多信息,参看 jpm command reference.

- -

一旦你设置了这些属性的值或者接受默认值,你会看到 "package.json" 的完整内容并被询问是否接受这些设置。

- -

实现 add-on

- -

现在你可以写 add-on 的代码了。除非你修改了"entry point"的值(package.json 中的 "main"),一般情况将从你的 add-on 的根目录下的"index.js"文件开始。这个文件就是在之前步骤中创建的。打开这个文件并且添加以下代码:

- -
var buttons = require('sdk/ui/button/action');
-var tabs = require("sdk/tabs");
-
-var button = buttons.ActionButton({
-  id: "mozilla-link",
-  label: "Visit Mozilla",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onClick: handleClick
-});
-
-function handleClick(state) {
-  tabs.open("http://www.mozilla.org/");
-}
-
- -
-

注意在jpm中"entry point"的默认值为"index.js",意思是你的主文件是"index.js",且在你的 add-on的根目录下。

- -

cfx中,入口默认是"main.js",并且在"lib"目录下

-
- -

保存文件

- -

接下来,在根目录下创建目录"data"

- -
mkdir data
-
- -

并保存这三个图标文件到"data"目录:

- - - - - - - - - - - - - - - - -
icon-16.png
icon-32.png
icon-64.png
- -

返回命令行,键入:

- -
jpm run
- -

这个 jpm 命令会运行一个带有你的 add-on 的 Firefox 的新实例。

- -

如果找不到 Firefox,你可能要为它提供一个路径(如在Ubuntu中):

- - -
jpm run -b /usr/bin/firefox
- -

Firefox 启动以后,在浏览器右上角你能看到一个 Firefox logo 的图标。点击该图标,就会打开一个新标签页 http://www.mozilla.org/

- -

这就是这个 add-on 的全部功能了。它用到了 SDK 的两个模块:action button 模块,使你能加个按钮到浏览器上,以及 tabs 模块,使你能完成对标签页的基本操作。本例中,我们以及创建了一个图标是Firefox图标的按钮,并添加一个点击处理程序,可以在新标签页中打开 Mozilla 页面。

- -

试着编辑这个文件。例如,我们可以改变加载的页面:

- -
var buttons = require('sdk/ui/button/action');
-var tabs = require("sdk/tabs");
-
-var button = buttons.ActionButton({
-  id: "mozilla-link",
-  label: "Visit Mozilla",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onClick: handleClick
-});
-
-function handleClick(state) {
-  tabs.open("https://developer.mozilla.org/");
-}
- -

在命令行提示符下,再次执行 jpm run。这次点击按钮,它会带你到 https://developer.mozilla.org/ 页面。

- -

打包 add-on

- -

当你完成了 add-on 并准备发布它,你会需要把它打包为 XPI 文件。你能自己分发 XPI 文件,也可以把它们发布到 https://addons.mozilla.org,这样其他用户就能下载并按照它们。

- -

要构建 XPI,只要在 add-on 的根目录下运行命令 jpm xpi

- -
jpm xpi
-
- -

你应该看到像这样的信息:

- -
JPM info Successfully created xpi at /path/to/my-addon/@my-addon-0.0.1.xpi
-
- -

要测试附加组件是否能正常运行,可以尝试在你自己的火狐中安装 XPI 文件。你可以在 Firefox 中按 Ctrl+O 组合键(Mac 中是 Cmd+O),或者选择"文件"菜单里的“打开”。这样会弹出一个文件选择对话框:转到"@my-addon.xpi"文件,打开并按照提示安装 add-on。

- -

注意 Firefox 默认需要 add-on 有签名,即使是本地开发的 add-on。安装完后他们会在已安装的 add-on 列表中出现,只因没有签名而被禁用。开发的时候,又或者你不准备发布,你可以打开 about:config 设置 xpinstall.signatures.requiredfalse 来运行未经签名的组件。这个设置会应用到所有的 add-on,所以要十分小心,不要一不当心从别的地方安装了恶意组件。

- -

要发布你的 add-on,请提交 XPI 文件到 addons.mozilla.org 或者如果你想在你自己的服务器上发布,运行 jpm sign

- -

总结

- -

本教程中我们使用了下面三个命令来构建和打包 add-on :

- - - -

这是你在开发SDK add-on会用到的三个主要命令。完全的参考文档包含了所以你能使用的命令,以及这些命令的可选项。

- -

这次开发的add-on 的代码用到了两个 SDK 模块,action buttontabs。这儿有参考文档,描述 SDK 中所有高层次低层次的 API。

- -

下一步?

- -

要了解你能用 SDK API 做些什么,试着继续阅读教程

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html deleted file mode 100644 index e09d6d4e55..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html +++ /dev/null @@ -1,162 +0,0 @@ ---- -title: JPM 入门! -slug: Mozilla/Add-ons/SDK/Tutorials/Getting_Started_(jpm) -tags: - - JPM - - add-on -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Getting_Started_(jpm) ---- -
-

该附加SDK包含一个用于初始化,运行,测试和打包加载项的命令行工具。当前工具称为jpm,并且基于  Node.js .它替代了旧的cfx工具。

- -

Firefox 38 以上的版本才可以使用jpm。

- -

本文介绍如何使用jpm开发。

-
- -

本教程将介绍使用SDK创建一个简单的附加组件。

- -

先决条件

- -

要使用SDK为Firefox创建附加组件,您需要:

- - - -

初始化一个空的附加组件

- -

在命令提示符下,创建一个新目录。导航到它,键入 jpm init, 然后按Enter键

- -
mkdir my-addon
-cd my-addon
-jpm init
-
- -

You'll then be asked to supply some information about your add-on: this will be used to create your add-on's package.json file. For now, just press Enter to accept the default for each property. For more information on jpm init, see the jpm command reference.

- -

Once you've supplied a value or accepted the default for these properties, you'll be shown the complete contents of "package.json" and asked to accept it.

- -

实现附加组件

- -

Now you can write the add-on's code. Unless you've changed the value of "entry point" ("main" in package.json), this goes in "index.js" file in the root of your add-on. This file was created for you in the previous step. Open it and add the following code:

- -
var buttons = require('sdk/ui/button/action');
-var tabs = require("sdk/tabs");
-
-var button = buttons.ActionButton({
-  id: "mozilla-link",
-  label: "Visit Mozilla",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onClick: handleClick
-});
-
-function handleClick(state) {
-  tabs.open("http://www.mozilla.org/");
-}
-
- -
-

Note that "entry point" defaults to "index.js" in jpm, meaning that your main file is "index.js", and it is found directly in your add-on's root.

- -

In cfx, the entry point defaults to "main.js", and is located in the "lib" directory under the add-on's root.

-
- -

Save the file.

- -

Next, create a directory called "data" in your add-on's root, and save these three icon files to the "data" directory:

- - - - - - - - - - - - - - - - -
icon-16.png
icon-32.png
icon-64.png
- -

Back at the command prompt, type:

- -
jpm run
- -

This is the jpm command to run a new instance of Firefox with your add-on installed.

- -

If Firefox can not be located, you may need to provide the path to it (example in Ubuntu):

- - -
jpm run -b /usr/bin/firefox
- -

When Firefox launches, in the top-right corner of the browser you'll see an icon with the Firefox logo. Click the icon, and a new tab will open with http://www.mozilla.org/ loaded into it.

- -

That's all this add-on does. It uses two SDK modules: the action button module, which enables you to add buttons to the browser, and the tabs module, which enables you to perform basic operations with tabs. In this case, we've created a button whose icon is the Firefox icon, and added a click handler that loads the Mozilla home page in a new tab.

- -

Try editing this file. For example, we could change the page that gets loaded:

- -
var buttons = require('sdk/ui/button/action');
-var tabs = require("sdk/tabs");
-
-var button = buttons.ActionButton({
-  id: "mozilla-link",
-  label: "Visit Mozilla",
-  icon: {
-    "16": "./icon-16.png",
-    "32": "./icon-32.png",
-    "64": "./icon-64.png"
-  },
-  onClick: handleClick
-});
-
-function handleClick(state) {
-  tabs.open("https://developer.mozilla.org/");
-}
- -

At the command prompt, execute jpm run again. This time clicking it takes you to https://developer.mozilla.org/.

- -

Packaging the add-on

- -

When you've finished the add-on and are ready to distribute it, you'll need to package it as an XPI file. This is the installable file format for Firefox add-ons. You can distribute XPI files yourself or publish them to https://addons.mozilla.org so other users can download and install them.

- -

To build an XPI, just execute the command jpm xpi from the add-on's directory:

- -
jpm xpi
-
- -

You should see a message like:

- -
JPM info Successfully created xpi at /path/to/getting-started/@getting-started.xpi
-
- -

To test that this worked, try installing the XPI file in your own Firefox installation. You can do this by pressing the Ctrl+O key combination (Cmd+O on Mac) from within Firefox, or selecting the "Open" item from Firefox's "File" menu. This will bring up a file selection dialog: navigate to the "@getting-started.xpi" file, open it and follow the prompts to install the add-on.

- -

Summary

- -

In this tutorial we've built and packaged an add-on using three commands:

- - - -

These are the three main commands you'll use when developing SDK add-ons. There's comprehensive reference documentation covering all the commands you can use and all the options they take.

- -

The add-on code itself uses two SDK modules, action button and tabs. There's reference documentation for all the high-level and low-level APIs in the SDK.

- -

What's next?

- -

To get a feel for some of the things you can do with the SDK APIs, try working through some of the tutorials.

- -

 

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/index.html deleted file mode 100644 index 03173c3219..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/index.html +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: 教程 -slug: Mozilla/Add-ons/SDK/Tutorials -tags: - - 插件SDK -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials ---- -

{{LegacyAddonsNotice}}{{AddonSidebar}}

- -

本文列出了许多关于如何通过SDK完成特定任务要求的实际动手的文章。

- -
-

开发之旅

- -
-
-
-
安装
-
在Windows, OS X和Linux上下载,安装,初始化SDK工具。
-
- -
-
常见问题
-
解决常见问题的建议和获取更多帮助。
-
-
- -
-
-
快速开始
-
走马观花地使用SDK开发一个简单的扩展
-
-
-
- -
-

创建用户交互界面

- -
-
-
-
添加一个工具按钮
-
添加一个按钮到火狐Add-on工具栏。
-
添加一个菜单选项到火狐
-
添加多个菜单选项到火狐主菜单。
-
-
- -
-
-
显示一个弹出对话框
-
通过HTML和JavaScript实现并显示一个弹窗对话框。
-
添加一个上下文菜单
-
添加一个上下文菜单(一般都是右键菜单)到火狐浏览器
-
-
-
- -
-

与浏览器交互

- -
-
-
-
打开Web页面
-
在一个新的浏览器选项卡里打开一个Web页面或窗口使用tabs模块并获取内容。
-
监听页面加载
-
当新页面载入时使用tabs模块得到通知并获取页面内容。
-
-
- -
-
-
获取打开的选项卡(Tab)列表
-
使用tabs模块遍历当前打开的tab,并获取其内容。
-
-
-
- -
-

更改网页

- -
-
-
-
更改网页通过URL
-
基于URL过滤网页:当载入的页面的URL与过滤器匹配时执行特定的脚本。
-
-
- -
-
-
修改页面内容
-
动态加载脚本到当前页面。
-
-
-
- -
-

开发技术

- -
-
-
-
日志
-
在终端中记录日志以便调试。
-
创建可复用的模块
-
拆分扩展程序为多个分离的模块,可以使开发调试和维护更加简单。封装你的模块使其成为可复用的包,以便其他开发者可以再次使用。
-
单元测试
-
使用SDK的测试框架书写和进行单元测试。
-
Chrome授权
-
获得Components对象,使你的扩展程序能够加载和使用任何XPCOM对象。
-
创建事件目标
-
使你定义的对象能够响应相关事件。
-
-
- -
-
-
监听载入和卸载
-
当你的扩展程序被加载和卸载时获得通知,并从终端传递参数给扩展程序。
-
使用第三方模块
-
安装和使用与SDK无关额外的模块
-
本地化
-
书写本地化代码.
-
移动开发
-
为Andriod上的火狐浏览器开发扩展程序。
-
扩展调试
-
调试扩展应用的JavaScript。
-
-
-
- -
-

打包

- -
-
-
-
扩展应用:Annotator
-
一起开发一个相对复杂的扩展应用。
-
-
-
diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/installation/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/installation/index.html deleted file mode 100644 index 4313836979..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/installation/index.html +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: 安装 -slug: Mozilla/Add-ons/SDK/Tutorials/Installation -tags: - - cfx安装 - - 配置cfx环境 -translation_of: Mozilla/Add-ons/SDK/Tools/jpm#Installation ---- -

先决条件

- -

请不要把任何相关的开发工具和扩展程序(命名推荐小写英文和数字,不推荐特殊符号等),放到有空格的目录(如Progaram Files\Python),会导致意想不到的错误,无法进行后续操作。(最新开发SDK可能修复了该错误,参见https://github.com/mozilla/addon-sdk/pull/1738)

- -

开发 Add-on SDK,你需要:

- - - -

另外,可以从它GitHub repository库中得到最新的开发版本

- -

为AMO开发扩展

- -

如果提交到AMO只有最新发布或许使用。

- -

git archive 需要扩展一些Git属性占位符

- -
git checkout 1.16
-
-git archive 1.16 python-lib/cuddlefish/_version.py | tar -xvf -
- -

通过Homebrew自动安装到Mac OS X

- -

使用以下命令通过 homebrew来安装SDK插件工具:

- -
brew install mozilla-addon-sdk
- -

安装到Mac OS X/Linux

- -

无论你选择哪个方式都要解压缩文件的内容作为根路径,并通过shell/命令提示符切换到SDK的根目录下例如:

- -
tar -xf addon-sdk.tar.gz
-cd addon-sdk
-
- -

如果你是Bash的用户,则继续运行(大多数人都是的):

- -
source bin/activate
-
- -

如果你是一个非Bash的用户你应该运行

- -
bash bin/activate
-
- -

命令提示符现在应该有一个包含SDK的目录名称的新的前缀

- -
(addon-sdk)~/mozilla/addon-sdk >
-
- -

安装到Windows

- -

同样解压缩文件,并通过命令符进入到SDK根目录下,例如:

- -
7z.exe x addon-sdk.zip
-cd addon-sdk
-
- -

接着运行激活命令:

- -
bin\activate
-
- -

同样可以看到命令提示符现在应该有一个包含SDK的目录名称新的前缀

- -
(C:\Users\mozilla\sdk\addon-sdk) C:\Users\Work\sdk\addon-sdk>
-
- -

SDK 的虚拟环境

- -

当命令提示符出现新的前缀表明你的已经搭建好了SDK的运行环境,那么你就可以使用Add-on SDK来开发命令行工具

- -

任何时候,你都可以通过运行 deactivate 命令停用虚拟环境.

- -

配置好的虚拟环境是特定于这个特定的命令提示符。如果您关闭命令提示符, 它会关闭运行环境,你需要source bin/activate bin\activate 在一个新的命令提示符重新激活它。如果你打开一个新命令提示符SDK将不会被激活在新的提示

- -

可以将SDK的多个副本拷贝在磁盘上的不同位置,并在它们之间切换,甚至可以让他们同时激活运行在不同的命令提示

- -

制作启动项

- -

所有 activate 的作用是通过设置环境变量,使位于顶层 bin 目录下的脚本 位于当前命令符下,制作的启动项 ,通过永久环境中的这些变量设置,以便每一个新的命令提示符下都能读取它们那么就不需要每次都去打开新的命令提示符来激活 activate

- -

因为变量精确设置可能随SDK发布新版本的变化,所以最好是指激活脚本来确定哪些变量需要设置。激活使用不同的脚本设置bash环境不同的变量LinuxMAC OS X和Windows环境

- -

Windows

- -

在Windows上,使用 bin\activate\activate.bat批处理脚本,也可以使用命令行setx工具或控制面板激活永久使用

- -

Linux/Mac OS X

- -

在 Linux 和 Mac OS X,使用source bin/activate/activate bash 脚本, 你可以 ~/.bashrc ( Linux) 或~/.bashprofile (Mac OS X) 来激活。

- -

作为替代,你可以在 ~/bin 目录中创建到cfx 程序的符号链接

- -
ln -s PATH_TO_SDK/bin/cfx ~/bin/cfx
-
- -

完整性检查

- -

在shell提示符运行:

- -
cfx
-
- -

它会产生下面信息,这里是第一行内容,后面大量的使用信息

- -
Usage: cfx [options] [command]
-
- -

这是 CFX命令行程序界面加载项的SDK可以使用它来启动Firefox和测试插件,打包附加分发,查看​​文档和运行单元测试

- -

出现问题?

- -

尝试通过故障排除页面来解决遇到的问题。

- -

下一步

- -

接下来, 开始学习 cfx 教程, 其中介绍了如何使用CFX的工具来创建附加组件

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/l10n/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/l10n/index.html deleted file mode 100644 index 5083be5b5c..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/l10n/index.html +++ /dev/null @@ -1,381 +0,0 @@ ---- -title: Localization -slug: Mozilla/Add-ons/SDK/Tutorials/l10n -tags: - - Add-on SDK - - 本地化 -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/l10n ---- -

该SDK支持本地化字符串出现在:

- - - -

目前为止还不支持本地化CSS和content scripts。

- -

本地化字符串

- -

翻译后的字符串都保存在你的add-on扩展目录下一个名为 "locale"的目录 ,每个本地化地域对应一个文件。这些文件:

- - - -

假设你的附加组件包含一个单一的本地化字符串,用英语表示为“Hello!”,你想提供英语和法语的本地化支持。

- -

你需要添加两个文件到"locale"目录:

- -
my-addon/
-         data
-         lib
-         locale/
-                en-US.properties
-                fr-FR.properties
-
- -

"en-US.properties" 文件中内容:

- -
hello_id= Hello!
-
- -

"fr-FR.properties" 文件中内容:

- -
hello_id= Bonjour !
-
- -

现在,每当你的JavaScript或HTML向本地化系统请求hello_id标识的翻译,它将获得与当前区域语言一致的翻译。

- -

在HTML中使用本地化字符串

- -
-

本例使用的 action button API需要 Firefox 29 或者更高版本。

-
- -

要从HTML中引用本地化字符串,需要添加一个 data-l10n-id 的属性,到你想本地化的字符串所属的HTML标签中,然后为该属性指定一个ID值(To reference localized strings from HTML, add a data-l10n-id attribute to the HTML tag where you want the localized string to appear, and assign the identifier to it):

- -
<html>
-  <body>
-    <h1 data-l10n-id="hello_id"></h1>
-  </body>
-</html>
-
- -

然后你就可以使用这个HTML文件来建立你的界面, 比如插入一个 panel 面板:

- -
var button = require("sdk/ui/button/action").ActionButton({
-  id: "localized-hello",
-  label: "Localized hello",
-  icon: "./icon-16.png",
-  onClick: function() {
-    hello.show();
-  }
-});
-
-var hello = require("sdk/panel").Panel({
-  height: 75,
-  width: 150,
-  contentURL: require("sdk/self").data.url("my-panel.html")
-});
- -

“en-US”和“fr-FR”提供了翻译标识为hello_id字符串的本地化文件,面板将根据当前区域语言设置,显示“Hello!”或者“Bonjour!”:

- -

- -

翻译文本会插入到具有data-l10n-id属性集的节点中。任何之前存在的内容只是被替换掉了。(The translation is inserted into the node which has the data-l10n-id attribute set. Any previously existing content is just replaced.)

- -

本地化字符串只能作为text文本插入, 所以你不能使用下面的语句插入HTML:

- -
hello_id= <blink>Hello!</blink>
-
- -

Localizing Element Attributes

- -
这是 Firefox 39 上的新功能
- -


- 你可以在properties文件中,通过设置 l10n-id.attributeName 的值,本地化某些具有 l10n-id属性的元素的属性值。像这样(You can localize certain attributes of elements with an l10n-id by setting its value with l10n-id.attributeName in the properties file like):
-  

- -
hello_id.accesskey= H
- -

可以支持以下几个属性:

- - - -

更多的 ARIA 属性aria-label, aria-valuetextaria-moz-hint 的本地化将通过在Firefox OS上同样的别名被支持(Further the localization of the ARIA attributes aria-label, aria-valuetext and aria-moz-hint are supported with the same aliases as on Firefox OS):

- - - -

在JavaScript代码中使用本地化字符串

- -

为了在主附加组件代码中引用本地化字符串,你需要这样做:

- -
var _ = require("sdk/l10n").get;
-console.log(_("hello_id!"));
- -

指定的 "_" 并不是必需的,但是作为 gettext 工具的默认约定,这能更好的配合其他默认使用 "_" 来表示本地化字符串的现有工具。

- -
    -
  1. 导入 l10n 模块,然后指定 "_" (下划线)为模块的 get 函数。
  2. -
  3. 把所有涉及本地化的字符串放到 _() 函数中包括起来。
  4. -
- -

如果你运行它,你会看到输出为预期的当前设置的区域语言:

- -
info: Hello!
-
- -
info: Bonjour !
-
- -

注意你不能在content scripts中 require() 一个模块,所以目前还不能在content script 中引用本地化字符串。

- -

复数

- -

 l10n 模快支持复数形式,不同的语言有不同的复数形态。例如,英语有两种形式:相对于"one"的单数形式,和对于"everything else, including zero"的复数形式:

- -
one tomato
-no tomatoes
-two tomatoes
-
- -

但是俄罗斯语对于以 1 结尾(除了11)的数字、以 2-4 结尾(除了12-14)的数字和其他数字,有着不同的复数形态:

- -
один помидор     // one tomato
-два помидора     // two tomatoes
-пять помидоров   // five tomatoes
-
- -

SDK使用 Unicode CLDR 数据描述由不同的语言使用的不同复数形式。

- -

Unicode CLDR 复数形式

- -

Unicode CLDR项目定义了用于描述一个特定语言的多个规则的一种方案。在这个方案中一种语言对应最多有六种不同的范围的数字,有以下类别区分:zero(零个),one(一个),two(两个),few(几个),many(很多),other(其他)。(The Unicode CLDR project defines a scheme for describing a particular language's plural rules. In this scheme a language maps each distinct range of numbers on to one of up to six forms, identified by the following categories: zero, one, two, few, many, and other.)

- -

英语有两种复数形式,可以表示为 "1" 映射到 "one" 和 "everything else" 映射到 "other"的形式(English has two forms, which can be described by mapping "1" to "one" and "everything else" to "other"):

- -
one   → n is 1;
-other → everything else
-
- -

俄罗斯语有四种形式,可以使用以下方式表示:

- -
one   → n mod 10 is 1 and n mod 100 is not 11;
-few   → n mod 10 in 2..4 and n mod 100 not in 12..14;
-many  → n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14;
-other → everything else
-
- -

所有语言的多个规则可以在CLDR的 语言复数规则 页面查到 (即使这个规则表相对于 CLDR XML source 已经过时了).

- -

SDK中的复数形式

- -

代码中,在 _()函数中的本地化ID参数之后提供一个额外的参数,用来表示代表多少个项的本地化字符串(In the code, you supply an extra parameter alongside the identifier, describing how many items there are):

- -
var _ = require("sdk/l10n").get;
-console.log(_("tomato_id"));
-console.log(_("tomato_id", 1));
-console.log(_("tomato_id", 2));
-console.log(_("tomato_id", 5));
-console.log(_("tomato_id", .5));
- -

.properties 文件中通过使用 CLDR 关键字,对于每种语言可能的复数形式你可以自定义不同的本地化字符串。所以对于英语可以有两种本地化(注意"other" 分类不是 CDLR 关键字)。(In the .properties file for each language you can define a different localization for each plural form possible in that language, using the CLDR keywords. So in English we could have two plural localizations (note that the "other" category does not take the CLDR keyword))

- -
# en-US translations
-tomato_id[one]= %d tomato
-tomato_id= %d tomatoes
-
- -

俄罗斯语中可以定义四种本地化的复数形式:

- -
# ru-RU translations
-tomato_id[one]= %d помидор
-tomato_id[few]= %d помидора
-tomato_id[many]= %d помидоров
-tomato_id= %d помидоры
-
- -

The localization module itself understands the CLDR definitions for each language, enabling it to map between, for example, "2" in the code and "few" in the ru-RU.properties file. Then it retrieves and returns the localization appropriate for the count you supplied.

- -

Placeholders

- -

The l10n module supports placeholders, allowing you to insert a string which should not be localized into one which is. The following "en-US" and "fr-FR" ".properties" files include placeholders:

- -
# en-US translations
-hello_id= Hello %s!
-
- -
# fr-FR translations
-hello_id= Bonjour %s !
-
- -

To use placeholders, supply the placeholder string after the identifier:

- -
var _ = require("sdk/l10n").get;
-console.log(_("hello_id", "Bob"));
-console.log(_("hello_id", "Alice"));
- -

In the "en-US" locale, this gives us:

- -
info: Hello Bob!
-info: Hello Alice!
-
- -

In "fr-FR" we get:

- -
info: Bonjour Bob !
-info: Bonjour Alice !
-
- -

Ordering Placeholders

- -

When a localizable string can take two or more placeholders, translators can define the order in which placeholders are inserted, without affecting the code.

- -

Primarily, this is important because different languages have different rules for word order. Even within the same language, though, translators should have the freedom to define word order.

- -

For example, suppose we want to include a localized string naming a person's home town. There are two placeholders: the name of the person and the name of the home town:

- -
var _ = require("sdk/l10n").get;
-console.log(_("home_town_id", "Bob", "London"));
- -

An English translator might want to choose between the following:

- -
"<town_name> is <person_name>'s home town."
-
- -
"<person_name>'s home town is <town_name>"
-
- -

To choose the first option, the .properties file can order the placeholders as follows:

- -
home_town_id= %2s is %1s's home town.
-
- -

This gives us the following output:

- -
info: London is Bob's home town.
-
- -

在首选项设置中的本地化字符串

- -

通过加入一个 "preferences" 字段的结构到你的附加组件的 "package.json" 文件中,你可以为你的附加组件定义首选项选项,用户可以在Firefox的 Add-ons Manager 看到和编辑它。

- -

Preferences (首选项)有一个必需的title标题项和一个可选的description描述项 这些字符串将出现在 Add-ons Manager中,来帮助向用户解释各个首选项设置的意义。

- - - -

例如, 假设你的 "package.json" 中只定义了一个设置选项:

- -
{
-    "preferences": [
-        {
-            "type": "string",
-            "name": "monster_name",
-            "value": "Gerald",
-            "title": "Name"
-        }
-    ],
-    "name": "monster-builder",
-    "license": "MPL 2.0",
-    "author": "me",
-    "version": "0.1",
-    "fullName": "Monster Builder",
-    "id": "monster-builder@me.org",
-    "description": "Build your own monster"
-}
-
- -

在你的"en-US.properties"文件中, 应该包括下面两个项:

- -
monster_name_title= Name
-monster_name_description= What is the monster's name?
-
- -

在你的"fr-FR.properties"文件中, 应该包括下面两个法语的翻译项:

- -
monster_name_title= Nom
-monster_name_description= Quel est le nom du monstre ?
-
- -

现在,当浏览器的区域设置为 "en-US", 用户会在 Add-ons Manager看到这样:

- -

- -

当浏览器区域设置为 "fr-FR", 用户会看到:

- -

- -

下拉菜单menulist和单选按钮radio的类型有多个选项,每一个选项的标签属性都会展示给用户。如果本地化文件中有一项是以前缀是"{name} _options" 为键的键值对,其中"{name}"是选项的标签名字,该键值对的值就是一个选项标签的本地化字符串。(The menulist and the radio preference types have options. The label attribute of each option is displayed to the user. If the locale file has a entry with the value of the label attribute prefixed with "{name}_options." as its key, where {name} is the name of the preference, its value is used as a localized label.)

- -

Using Identifiers

- -

If the localization system can't find an entry for a particular identifier using the current locale, then it just returns the identifier itself.

- -

This has the nice property that you can write localizable, fully functional add-ons without having to write any locale files. You can just use the default language strings as your identifier, and subsequently supply .properties files for all the additional locales you want to support.

- -

For example, in the case above you could use "Hello!" as the identifier, and just have one .properties file for the "fr-FR" locale:

- -
Hello!= Bonjour !
-
- -

Then when the locale is "en-US", the system would fail to find a .properties file, and return "Hello!".

- -

However, this approach makes it difficult to maintain an add-on which has many localizations, because you're using the default language strings both as user interface strings and as keys to look up your translations. This means that if you want to change the wording of a string in the default language, or fix a typo, then you break all your locale files.

- -

Locale Updater

- -

The locale updater add-on makes it easier to update locale files. Once you've installed it, open the Add-on Manager, and you'll see a see a new button labeled "Update l10n" next to each add-on you've installed:

- -

- -

Click the button and you'll be prompted for a new .properties file for that add-on. If you provide a new file, the add-on's locale data will be updated with the new file.

- -

Limitations

- -

The current localization support is a first step towards full support, and contains a number of limitations.

- - - -

See Also - for developers looking to localize non-SDK add-ons

- - diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/list_open_tabs/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/list_open_tabs/index.html deleted file mode 100644 index 8a4985806e..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/list_open_tabs/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: 列出打开的标签页 -slug: Mozilla/Add-ons/SDK/Tutorials/List_Open_Tabs -tags: - - Add-on SDK -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/List_Open_Tabs ---- -

{{AddonSidebar}}

- -
-

学习本教程之前你需要学习 jpm 基础

-
- -

列出打开的标签页,你可以遍历 tabs 对象本身。

- -

下面的 add-on 添加一个 action button 当用户单击该按钮时,该日志将在打开的标签页中记录:

- -
require("sdk/ui/button/action").ActionButton({
-  id: "list-tabs",
-  label: "List Tabs",
-  icon: "./icon-16.png",
-  onClick: listTabs
-});
-
-function listTabs() {
-  var tabs = require("sdk/tabs");
-  for (let tab of tabs)
-    console.log(tab.url);
-}
-
- -
-

注意:为此你需要一个按钮图标,以"icon-16.png"的文件名保存到你的 add-on 的"data"目录下。你可以从这里下载图标:

-
- -

运行该 add-on,加载一对标签页,并点击按钮,你会看到在控制台输出如下的内容:

- -
info: http://www.mozilla.org/en-US/about/
-info: http://www.bbc.co.uk/
-
- -
-

你不能直接访问到标签页中的任何宿主内容(具体概念请查阅相关内容:JavaScript 本地对象、内置对象、宿主对象 )。

- -

为了访问标签页的内容,你需要使用 tab.attach() 添加一个脚本,此 add-on 加载加载一个页面,然后将一个脚本附加到所有打开的标签页,该脚本将向标签页的文档添加红色边框:

-
- -
require("sdk/ui/button/action").ActionButton({
-  id: "list-tabs",
-  label: "List Tabs",
-  icon: "./icon-16.png",
-  onClick: listTabs
-});
-
-function listTabs() {
-  var tabs = require("sdk/tabs");
-  for (let tab of tabs)
-    runScript(tab);
-}
-
-function runScript(tab) {
-  tab.attach({
-    contentScript: "document.body.style.border = '5px solid red';"
-  });
-}
-
- -

学习更多

- -

要了解更多关于SDK中标签如何工作, 查看 tabs API reference

- -

要了解更多关于在标签中运行脚本, 查看 tutorial on using tab.attach()

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/listen_for_page_load/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/listen_for_page_load/index.html deleted file mode 100644 index 815cfd42c5..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/listen_for_page_load/index.html +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: 监听页面加载 -slug: Mozilla/Add-ons/SDK/Tutorials/Listen_for_Page_Load -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Listen_for_Page_Load ---- -

{{AddonSidebar}}

- -
学习本教程之前你需要了解 jpm 基础
- -

你可以使用 tabs 模块来获取关于新页面加载的通知。下面的附加组件监听标签页内建的 ready 事件,并且记录下每一个标签加载时的URL:

- -
require("sdk/tabs").on("ready", logURL);
-
-function logURL(tab) {
-  console.log(tab.url);
-}
-
- -
-

你会在浏览器控制台,而非 Web 控制台中,找到这些输出的内容。

-
- -

你不能直接访问标签页里面的内容。

- -

为了访问标签页内容,你需要使用 tab.attach() 把一个脚本附到标签页上。这个示例给每一个打开后的标签页附上了一个脚本。这个脚本给标签页的 document 加上了一个红色边框:

- -
require("sdk/tabs").on("ready", runScript);
-
-function runScript(tab) {
-  tab.attach({
-    contentScript: "if (document.body) document.body.style.border = '5px solid red';"
-  });
-}
-
- -

(本示例仅仅表示:可以像这样实现一些功能,而你应当使用 page-mod,并且指定匹配模式为 "*"。)

- -

了解更多

- -

想要了解更多关于如何在SDK中处理标签页的内容,请看 tabs API 参考。你能够监听其他一些标签页事件,包括 openclose、和 activate

- -

想要了解更多关于在标签页中运行脚本的事情,请看 tab.attach() 使用教程

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/modifying_the_page_hosted_by_a_tab/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/modifying_the_page_hosted_by_a_tab/index.html deleted file mode 100644 index 5fd51fd8f7..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/modifying_the_page_hosted_by_a_tab/index.html +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: 修改标签页中页面 -slug: Mozilla/Add-ons/SDK/Tutorials/Modifying_the_Page_Hosted_by_a_Tab -tags: - - Add-on SDK -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Modifying_the_Page_Hosted_by_a_Tab ---- -
-

为了进一步学习本教程,你需要安装 Add-on SDK 和学习 cfx的基本使用

- -

这篇教程使用动作按钮API,需要Firefox 29或更新版本。

-
- -

为了修改特定标签页中的页面, 可以使用 tab对象的attach() 方法加载一个script脚本到页面中。因为他们的工作是和Web内容进行交互,所以这些脚本被称为content scripts(内容脚本)。

- -

这是个简单的示例:

- -
var button = require("sdk/ui/button/action").ActionButton({
-  id: "style-tab",
-  label: "Style Tab",
-  icon: "./icon-16.png",
-  onClick: function() {
-    require("sdk/tabs").activeTab.attach({
-      contentScript: 'document.body.style.border = "5px solid red";'
-    });
-  }
-});
- -

要运行这个示例你必须保存一个名为”icon-16.png“的图标文件在你的Add-on目录下的”data”目录下。你可以下载这个图标:

- -

这个插件创建一个按钮,其中包含Mozilla的图标作为一个图标。这个按钮产生一个点击事件处理程序,处理事件中将获取当前活动标签页和加载一个脚本到该标签页中的页面。使用contentscript选项指定加载的脚本,该脚本只绘制一个红色边框页。

- -

然后在浏览器窗口中打开任何网页,点击按钮 。你会看到一个红色的边界出现在页面中, 就像这样:

- -

- -

保持Content Script在一个单独的文件中

- -

在上面的例子中我们的content script作为一个字符串来直接使用.除非脚本非常简单,你应该保持脚本作为一个单独的文件。这使得代码更容易维护、调试和审查。

- -

比如,我们把上面的脚本代码保存在Add-on目录下的data目录中并取名为my-script.js,在代码中可以这样加载脚本:

- -
var self = require("sdk/self");
-
-var button = require("sdk/ui/button/action").ActionButton({
-  id: "style-tab",
-  label: "Style Tab",
-  icon: "./icon-16.png",
-  onClick: function() {
-    require("sdk/tabs").activeTab.attach({
-      contentScriptFile: self.data.url("my-script.js")
-    });
-  }
-});
-
- -

你可以加载多个脚本,同时这些脚本可以直接相互作用。所以你可以加载 jQuery, 然后在你的其他 content script使用它。

- -

与Content Script传递信息

- -

你的扩展插件脚本Add-on script和内容脚本content script 不能直接访问对方的变量和函数,但他们之间可以互相发送消息。

- -

从一方发送消息到另外一方, 发送方需要调用 port.emit()发送消息, 同时接收方使用port.on()接收消息。

- - - -

让我们重写上面的例子来从附加内容脚本 content script 传递一个消息。现在content script 需要像下面这样:

- -
// "self" is a global object in content scripts
-// Listen for a "drawBorder"
-self.port.on("drawBorder", function(color) {
-  document.body.style.border = "5px solid " + color;
-});
-
- -

在 add-on script 扩展脚本中,我们使用 attach()方法返回的对象向 content script 中发送一个“drawBorder”消息:

- -
var self = require("sdk/self");
-var tabs = require("sdk/tabs");
-
-var button = require("sdk/ui/button/action").ActionButton({
-  id: "style-tab",
-  label: "Style Tab",
-  icon: "./icon-16.png",
-  onClick: function() {
-    var worker = tabs.activeTab.attach({
-      contentScriptFile: self.data.url("my-script.js")
-    });
-    worker.port.emit("drawBorder", "red");
-  }
-});
-
- -

名为 drawBorder 的消息并不是一个内置的消息, 而是通过 port.emit()方法自定义的。

- -

注入 CSS

- -

不像 page-mod API, tab.attach() 不允许你直接注入CSS到页面中。

- -

你需要使用 JavaScript 来修改页面的样式,就像前面的示例那样。

- -

学习更多

- -

要了解更多关于在SDK中标签页的使用, 可以查看打开一个网页教程,  列出打开的标签页教程, 和tabs API 参考手册.

- -

要学习更多关于content scripts, 查看 content scripts guide.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/modifying_web_pages_based_on_url/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/modifying_web_pages_based_on_url/index.html deleted file mode 100644 index 6e5e46c532..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/modifying_web_pages_based_on_url/index.html +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: Modifying Web Pages Based on URL -slug: Mozilla/Add-ons/SDK/Tutorials/Modifying_Web_Pages_Based_on_URL -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Modifying_Web_Pages_Based_on_URL ---- -
开始本教程之前,您必须安装好 SDK,并且学习 cfx 的基本的使用方法。
- -

要修改任何页面匹配特定的模式(比如,“http://example.org/”)当它们加载后,使用page-mod模块。

- -

要创建 page-mod,您必须指定两件事:

- - - -
-

content scripts为内容脚本,只能使用普通浏览器支持的 JS,不能使用 add-on 的API

-
- -

这里有一个范例。内容脚本提供contentScript选项,地址样本提供include选项:

- -
// Import the page-mod API
-var pageMod = require("sdk/page-mod");
-
-// Create a page mod
-// It will run a script whenever a ".org" URL is loaded
-// The script replaces the page contents with a message
-pageMod.PageMod({
-  include: "*.org",
-  contentScript: 'document.body.innerHTML = ' +
-                 ' "<h1>Page matches ruleset</h1>";'
-});
-
- -

试试吧:

- - - -

您将看到:

- -

- -

指定匹配模式

- -

匹配模式使用 match-pattern 语法。您可以通过单一的匹配字符串,或者数组。

- -

把内容脚本放在独立的文件中

- -

在上面的范例中我们通过字符串来实现内容脚本。除非是用作简单的例子,通常情况下您应该将内容脚本放在独立文件中,这将使您的代码更易维护、调式和查看。

- -

要这样做,您需要:

- - - -

例如,如果我们将内容脚本保存在 data 目录下,命名为 my-script.js,在main.js中,我们应该这么写:

- -
// Import the page-mod API
-var pageMod = require("sdk/page-mod");
-// Import the self API
-var self = require("sdk/self");
-
-// Create a page mod
-// It will run a script whenever a ".org" URL is loaded
-// The script replaces the page contents with a message
-pageMod.PageMod({
-  include: "*.org",
-  contentScriptFile: self.data.url("my-script.js")
-});
- -

加载多个Content Scripts

- -

您可以加载更多脚本,且脚本可以相互交互。所以,您可以使用jQuery重写 my-script.js:

- -
$("body").html("<h1>Page matches ruleset</h1>");
-
- -

然后下载 jQuery 库到您的扩展开发目录的 data 目录下,并且将 jQuery 和 my-script 一起加载(确保先加载 jQuery 库):

- -
// Import the page-mod API,加载 add-on 的 page-mod API
-var pageMod = require("sdk/page-mod");
-// Import the self API, 加载 add-on 的 self API
-var self = require("sdk/self");
-
-// Create a page mod
-// It will run a script whenever a ".org" URL is loaded
-// The script replaces the page contents with a message
-// 创建 page mod,匹配 “.org” URL
-pageMod.PageMod({
-  include: "*.org",
-  contentScriptFile: [self.data.url("jquery-1.7.min.js"), self.data.url("my-script.js")]
-});
-
- -

您也可以在同一 page-mod 中同时使用 contentScriptcontentScriptFile 。如果您这么做的话,contentScript的脚本将会先加载。(应该是contentScriptFile的先加载吧?)

- -
// Import the page-mod API
-var pageMod = require("sdk/page-mod");
-// Import the self API
-var self = require("sdk/self");
-
-// Create a page mod
-// It will run a script whenever a ".org" URL is loaded
-// The script replaces the page contents with a message
-pageMod.PageMod({
-  include: "*.org",
-  contentScriptFile: self.data.url("jquery-1.7.min.js"),
-  contentScript: '$("body").html("<h1>Page matches ruleset</h1>");'
-});
-
- -

注意,您不能直接加载网站上的脚本。脚本必须从 data 目录中加载。

- -

与 Content Script 通信

- -

Your add-on script and the content script can't directly access each other's variables or call each other's functions, but they can send each other messages.

- -

从 Content Script 与 main.js 通信,发送方使用 port.emit() ,接收方使用 port.on() 监听.

- - - -

Let's rewrite the example above to pass a message from the add-on to the content script. The message will contain the new content to insert into the document. The content script now needs to look like this:

- -
// "self" is a global object in content scripts
-// Listen for a message, and replace the document's
-// contents with the message payload.
-self.port.on("replacePage", function(message) {
-  document.body.innerHTML = "<h1>" + message + "</h1>";
-});
-
- -

In the add-on script, we'll send the content script a message inside onAttach:

- -
// Import the page-mod API
-var pageMod = require("sdk/page-mod");
-// Import the self API
-var self = require("sdk/self");
-
-// Create a page mod
-// It will run a script whenever a ".org" URL is loaded
-// The script replaces the page contents with a message
-pageMod.PageMod({
-  include: "*.org",
-  contentScriptFile: self.data.url("my-script.js"),
-  // Send the content script a message inside onAttach
-  onAttach: function(worker) {
-    worker.port.emit("replacePage", "Page matches ruleset");
-  }
-});
-
- -

The replacePage message isn't a built-in message: it's a message defined by the add-on in the port.emit() call.

- -

注入 CSS

- -
-

请注意,本节中描述的功能是实验性的:我们很可能继续支持的功能,但可能需要改变的细节。

-
- -

Rather than injecting JavaScript into a page, you can inject CSS by setting the page-mod's contentStyle option:

- -
var pageMod = require("sdk/page-mod").PageMod({
-  include: "*",
-  contentStyle: "body {" +
-                "  border: 5px solid green;" +
-                "}"
-});
-
- -

As with contentScript, there's a corresponding contentStyleFile option that's given the URL of a CSS file in your "data" directory, and it is good practice to use this option in preference to contentStyle if the CSS is at all complex:

- -
var pageMod = require("sdk/page-mod").PageMod({
-  include: "*",
-  contentStyleFile: require("sdk/self").data.url("my-style.css")
-});
-
- -

You can't currently use relative URLs in style sheets loaded with contentStyle or contentStyleFile. If you do, the files referenced by the relative URLs will not be found.

- -

To learn more about this, and read about a workaround, see the relevant section in the page-mod API documentation.

- -

Learning More

- -

To learn more about page-mod, see its API reference page. In particular, the PageMod constructor takes several additional options to control its behavior:

- - - -

To learn more about content scripts in general, see the content scripts guide.

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/open_a_web_page/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/open_a_web_page/index.html deleted file mode 100644 index 7ff9ba7883..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/open_a_web_page/index.html +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: 打开Web页面 -slug: Mozilla/Add-ons/SDK/Tutorials/Open_a_Web_Page -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Open_a_Web_Page ---- -{{AddonSidebar}} - -
学习本教程之前你需要学习 jpm 基础
- -

打开一个新的网页,你可以使用 tabs 模块:

- -
var tabs = require("sdk/tabs");
-tabs.open({
-"http://www.example.com");
-
- -

这个函数是异步的,所以你不能立即获取一个可以检查的标签对象。要做到这一点,通过一个回调函数为open()。将回调函数赋值给 onready 属性,并将通过标签作为参数:

- -
var tabs = require("sdk/tabs");
-tabs.open({
-  url: "http://www.example.com",
-  onReady: function onReady(tab) {
-    console.log(tab.title);
-  }
-});
-
- -
-

尽管这样,你还是不能直接访问到标签页中的任何宿主内容(具体概念请查阅相关内容:JavaScript 本地对象、内置对象、宿主对象 )。

-
- -

-要访问标签页的内容,你需要使用 tab.attach()把一个脚本添加到该标签页。此add-on加载加载一个页面,然后将一个脚本附加到该页,该将向页面添加红色边框:

- -
var tabs = require("sdk/tabs");
-tabs.open({
-  url: "http://www.example.com",
-  onReady: runScript
-});
-
-function runScript(tab) {
-  tab.attach({
-    contentScript: "document.body.style.border = '5px solid red';"
-  });
-}
-
- -

学习更多

- -

要了解更多关于SDK中标签如何工作, 查看 tabs API reference.

- -

要了解更多关于在标签中运行脚本, 查看 tutorial on using tab.attach().

diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/troubleshooting/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/troubleshooting/index.html deleted file mode 100644 index afa3cc0cd3..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/troubleshooting/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Troubleshooting -slug: Mozilla/Add-ons/SDK/Tutorials/Troubleshooting -tags: - - add-on sdk 安装指南 - - add-on sdk安装解惑 -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Troubleshooting ---- -

{{AddonSidebar}}

- -

如果你的SDK安装和运行遇到了问题,不要慌!本页面列出了一些基本点,来帮助你追踪你的问题。

- -

检查你的 Firefox

- -

jpm 会搜索你系统中 Firefox 常见的地址,jpm 也许不能找到火狐安装在哪,或者你有多个地方安装了火狐,jpm 也许找错了地方。这种情况下,你需要使用 jpm--binary 选项。参看 jpm 指南以获取更多信息

- -

当你运行 jpm 来测试你的 add-on 或者运行单元测试时,它会打印出 Firefox 或 XULRunner 二进制文件的地址,所有你可以检查一下它的输出内容来做确认。

- -

检查你的文本控制台

- -

当你的代码代码和SKD的API产生错误时,他们会被记录到文本控制台。这应该和你运行 jpm 命令的是同一控制台或shell

- -

搜索已知的问题

- -

也许有人已经遇到过和你一样的问题了。其他用户经常发布问题到 项目邮件列表。你也可以浏览已知问题列表或者搜索特定的关键词。

- -

与项目团队和用户组交流

- -

SDK的用户和项目团队成员对问题和建议在 项目的邮件列表.  别人可能有与你相同的问题,所以试着搜索列表。也欢迎你发表问题.

- -

你也可以与其他SDK用户在 Mozilla的 IRC 网络#jetpack 聊天室聊天.

- -

如果你想报告SDK的bug,我们非常欢迎!您将需要创建一个 Bugzilla 的帐号,Bugzilla 是 Mozilla 的 bug 追踪系统。

- -
 
- -
 
- -
 
diff --git a/files/zh-cn/mozilla/add-ons/sdk/tutorials/unit_testing/index.html b/files/zh-cn/mozilla/add-ons/sdk/tutorials/unit_testing/index.html deleted file mode 100644 index 63cd86da13..0000000000 --- a/files/zh-cn/mozilla/add-ons/sdk/tutorials/unit_testing/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Unit Testing -slug: Mozilla/Add-ons/SDK/Tutorials/Unit_testing -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Unit_testing ---- -
-

学习本教程你将需要安装SDK, 学习 基本操作cfx,和学习过编写可重复模块(writing reusable modules).

-
-
-

如果你在使用 jpm 而不是 cfx, 请看关于cfx, 而且重点看加载测试模块(loading modules from test code).

-
-

SDK提供了一个框架,为你的代码创建和运行单元测试.接下来我们将演示如何写一个关于Base64 模块的单元测试.

-

一个Base64模块例子

-

在一个网页中, 你可以进行Base64的加密和解密,通过使用函数btoa() and atob() .不幸的是这些函数依附在window对象: 由于这个对象在你的add-on(插件) main 的代码里不是有效对象,所以 atob() and btoa() 也不是有效的. 因此我们将展示如何在这个平台上创建一个base64模块 .

-

To begin with, create a new directory, navigate to it, and run cfx init. Now create a new file in "lib" called "base64.js", and give it the following contents:

-
const { atob, btoa } = require("chrome").Cu.import("resource://gre/modules/Services.jsm", {});
-
-exports.atob = a => atob(a);
-exports.btoa = b => btoa(b);
-
-

This code exports two functions, which just call the platform's btoa() and atob() functions. To show the module in use, edit the "main.js" file as follows:

-
var base64 = require("./base64");
-
-var button = require("sdk/ui/button/action").ActionButton({
-  id: "base64",
-  label: "base64",
-  icon: "./icon-16.png",
-  onClick: function() {
-    encoded = base64.btoa("hello");
-    console.log(encoded);
-    decoded = base64.atob(encoded);
-    console.log(decoded);
-  }
-});
-

To run this example you'll also have to have an icon file named "icon-16.png" saved in your add-ons "data" directory. You could download this icon: .

-

Now "main.js" imports the base64 module and calls its two exported functions. If we run the add-on and click the button, we should see the following logging output:

-
info: aGVsbG8=
-info: hello
-
-

Testing the Base64 Module

-

Navigate to the add-on's test directory and delete the test-main.js file. In its place create a file called test-base64.js with the following contents:

-
var base64 = require("./base64");
-
-exports["test atob"] = function(assert) {
-      assert.ok(base64.atob("aGVsbG8=") == "hello", "atob works");
-}
-
-exports["test btoa"] = function(assert) {
-  assert.ok(base64.btoa("hello") == "aGVsbG8=", "btoa works");
-}
-
-exports["test empty string"] = function(assert) {
-  assert.throws(function() {
-                  base64.atob();
-                },
-                "empty string check works");
-}
-
-require("sdk/test").run(exports);
-
-

This file: exports three functions, each of which expects to receive a single argument which is an assert object. assert is supplied by the test/assert module and implements the CommonJS Unit Testing specification.

- -

At this point your add-on ought to look like this:

-
  /base64
-      package.json
-      README.md
-      /doc
-          main.md
-      /lib
-          main.js
-          base64.js
-      /test
-          test-base64.js
-
-

Now execute cfx --verbose test from the add-on's root directory. You should see something like this:

-
Running tests on Firefox 13.0/Gecko 13.0 ({ec8030f7-c20a-464f-9b0e-13a3a9e97384}) under darwin/x86.
-info: executing 'test-base64.test atob'
-info: pass: atob works
-info: executing 'test-base64.test btoa'
-info: pass: btoa works
-info: executing 'test-base64.test empty string'
-info: pass: empty string check works
-
-3 of 3 tests passed.
-Total time: 5.172589 seconds
-Program terminated successfully.
-
-

What happens here is that cfx test:

-

Note the hyphen after "test" in the module name. cfx test will include a module called "test-myCode.js", but will exclude modules called "test_myCode.js" or "testMyCode.js".

- -

Obviously, you don't have to pass the --verbose option to cfx if you don't want to; doing so just makes the output easier to read.

diff --git "a/files/zh-cn/mozilla/add-ons/sdk/tutorials/\346\227\245\345\277\227/index.html" "b/files/zh-cn/mozilla/add-ons/sdk/tutorials/\346\227\245\345\277\227/index.html" deleted file mode 100644 index e581a0811c..0000000000 --- "a/files/zh-cn/mozilla/add-ons/sdk/tutorials/\346\227\245\345\277\227/index.html" +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: 日志 -slug: Mozilla/Add-ons/SDK/Tutorials/日志 -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Logging ---- -

{{AddonSidebar}}

- -
学习本教程之前你需要学习 jpm 基础.
- -

DOM console 对象对调试 Javascript 非常有帮助。但是由于扩展程序无法访问 DOM 对象,sdk 提供了一个拥有大部分 DOM console 对象方法的全局 console 对象,包括打印错误日车、警告和数据信息的方法。你无需 require() 任何模块,就可以直接使用 console 对象。

- -

使用 console.log() 方法来打印信息:

- -
console.log("Hello World");
-
- -

尝试:

- - - -

Firefox 将会启动,并在你执行 jpm run 的命令行窗口显示下面的信息:

- -
console.log: console: Hello world
-
- -

在内容脚本(conent script)中使用 console

- -

与 addon 主代码一样,你可以在内容脚本中直接使用 console 对象。下面这个扩展在内容脚本中调用了 console.log() 方法,作用是在控制台打印出每个打开的标签页内的 HTML 内容:

- -
require("sdk/tabs").on("ready", function(tab) {
-  tab.attach({
-    contentScript: "console.log(document.body.innerHTML);"
-  });
-});
-
- -

控制台输出

- -

如果你是在命令行启动你的扩展(例如:执行 jpm runjpm test),那么控制台信息将在你使用的命令行界面中显示。

- -

如果你将扩展安装到了 Firefox 中,控制台信息将显示在 Firefox 浏览器控制台中。

- -

但请注意,默认情况下,任何已经安装的扩展不会在错误控制台中输出任何信息,包括使用扩展构建程序安装的扩展或者使用其它工具例如:Extension Auto-installer

- -

关于此项内容的更多信息请参阅控制台参考文档 “日志等级”。

- -

更多

- -

完整的 console API,请看 API 参考文档

diff --git "a/files/zh-cn/mozilla/add-ons/sdk/tutorials/\346\267\273\345\212\240\344\270\200\344\270\252\350\217\234\345\215\225\351\241\271/index.html" "b/files/zh-cn/mozilla/add-ons/sdk/tutorials/\346\267\273\345\212\240\344\270\200\344\270\252\350\217\234\345\215\225\351\241\271/index.html" deleted file mode 100644 index 77d743e806..0000000000 --- "a/files/zh-cn/mozilla/add-ons/sdk/tutorials/\346\267\273\345\212\240\344\270\200\344\270\252\350\217\234\345\215\225\351\241\271/index.html" +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: 添加菜单项 -slug: Mozilla/Add-ons/SDK/Tutorials/添加一个菜单项 -translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Add_a_Context_Menu_Item ---- -
-

学习本章前,您要先 安装SDK 和学习 cfx的基本用法

-
-

右键菜单模块添加右键菜单项或子菜单

-

下面的例子是增加了一个新的上下文菜单项。当页面被选中时才会显示该菜单项,选择的部分会被发送到main.js的add-on代码中,它只是记录:

-
var contextMenu = require("sdk/context-menu");
- var menuItem = contextMenu.Item({
-  label: "Log Selection",
-  context: contextMenu.SelectionContext(),
-  contentScript: 'self.on("click", function () {' +
-                 '  var text = window.getSelection().toString();' +
-                 '  self.postMessage(text);' +
-                 '});',
-  onMessage: function (selectionText) {
-    console.log(selectionText);
-  }
-});
-

Try it: run the add-on, load a web page, select some text and right-click. You should see the new item appear:

-

试一试:运行该扩展,加载一个网页,选中一些文本并右键单击。你应该能看到新的项目出现:

-

-

点击,选中的文本记录到控制台:

-
info: elephantine lizard
-
-

细节

-


- 这个add-on所有的操作是构建一个上下文菜单项。你不需要添加它:一旦你已经建立了项目,它会自动添加在正确的上下文。在这种情况下,构造函数接受四个选项:labelcontext,和contentscript,onMessage。

-

label

-


- 标签是字符串的显示。

-

context

-


- 上下文应该在不同的情境中显示它该做的显示。上下文菜单模块提供了一些简单的内置的上下文,包括selectioncontext(),这意味着:当页面被选中的时候将会显示菜单项。
- 如果这些简单的背景是不够的,你可以使用脚本定义更复杂的环境。

-

contentScript

-

这将一个脚本项目。在这种情况下,脚本侦听用户点击该项目,然后选定文本用消息发送到add-on。

-

onMessage

-

onMessage属性提供附加的代码来响应来自连接到上下文菜单项脚本报文的一种方法。在这种情况下,它只是记录选定的文本。

-

所以:
- 用户点击项目
- 内容脚本的点击事件触发,和内容脚本检索选定的文本和发送邮件的附件
- 附加的消息事件触发,并附加代码的处理函数是通过选定的文本,它的日志
-  

-

获取更多

-

如果想获取更多信息关于context-menu模块,查看context-menu API reference.

diff --git a/files/zh-cn/mozilla/add-ons/setting_up_extension_development_environment/index.html b/files/zh-cn/mozilla/add-ons/setting_up_extension_development_environment/index.html deleted file mode 100644 index 9790442e3c..0000000000 --- a/files/zh-cn/mozilla/add-ons/setting_up_extension_development_environment/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: 扩展开发环境设置 -slug: Mozilla/Add-ons/Setting_up_extension_development_environment -tags: - - Extensions -translation_of: Archive/Add-ons/Setting_up_extension_development_environment ---- -

本文给出了关于如何为扩展开发配置Mozilla应用程序的建议.

-

开发配置

-

为了避免由于设置了开发相关的预定义选项导致的性能上的问题,以及避免破坏你的个人数据,建议你可以创建一个新的Profile,而不是使用默认的进行开发工作.

-

如果你使用-no-remote参数启动Firefox,你可以用不同的Profile运行两个Firefox实例.例如,不管是否"正常"的Firefox是否运行,下面的命令将运行你的开发Profile(假设你的开发Profile命名为"dev").

-
start "" "%ProgramFiles%\Mozilla Firefox\firefox.exe" -no-remote -P dev
-
-

用默认的Profile允许Firefox通常仅仅是"firefox"或者"firefox -P default".

-

你可以使用Firefox稳定版本和开发版本来检查扩展的兼容性(Installing Firefox 3 or Minefield while keeping Firefox 2).

-

开发预定义选项

-

这些已定义参数使在低性能的情况下使调试更容易.

-

查看编辑配置文件关于设置预定义选项的信息.注意某些设置默认不存在与abount:config中.所以你需要创建一个新的(boolean)的项.

-

要这样做, 添加下面的代码行到你的Profile目录的 user.js 文件中,如果文件不存在,创建之:

-
user_pref("nglayout.debug.disable_xul_cache",true);
-user_pref("browser.dom.window.dump.enabled",true);
-
-

注意: 对于Firefox 版本 3.0"user.js" 已被 "prefs.js" 替换.

-

See below under "Development Profile" to setup a separate development profile before you make these changes.

- -

开发扩展

-

这些扩展可以帮组你进行扩展开发.

- -

扩展开发目录设定

-

每次因遇到某些变更而不得不重新添加扩展部分的时候,以及,为了保护您的"扩展源文件"不受到卸载过程中被意外删除的风险,其实您可以把"扩展插件目录"从"标准用户配置目录"中移出到你自己想要的文件目录中进行开发。具体操作步骤如下:

-
    -
  1. 找到扩展ID:从install.rdf中找到你的扩展ID号,install.rdf就安装在扩展插件的根目录中;
  2. -
  3. 建立文件:在“用户配置目录/extensions/”目录下,用你的扩展插件ID号作为文件名新建一个文件。 (比如: `用户配置目录/extensions/{46D1B3C0-DB7A-4b1a-863A-6EE6F77ECB58}`) (找到你的用户配置目录所在位置),记得没有文件扩展名。(为了方便说明暂把这个文件称作“扩展外链定位文件” )
  4. -
  5. 设定文件内容:“扩展外链定位文件”里要包含一个路径,这个路径是指向扩展程序的install.rdf所在目录的路径。(例如:`/full/path/to/yourExtension`. Windows用户注意,用大写书写驱动器名以及反斜杠而不是正斜杠,比如:`C:\full\path\to\yourExtension` Here is an example 'C:\sam\workspace\toolbar\helloWorldtoolbar\'). 在Firefox3中, 如果你是通过XPI包安装的扩展,`用户配置目录`下部分或者所有extensions.*的文件可能会被重新设置。虽然这些文件系统会自动重新生成的,还是备份一下先。
  6. -
  7. 把“扩展外链定位文件”放在你的用户配置目录中的扩展目录(`用户配置目录/extension`)下,重启Firefox。
  8. -
-

使用目录而非JAR

-

无论你是否选择将你的扩展 chrome打包成JAR或是目录,在目录下开发会更简单。如果你选择了一个用于分发的JAR,你仍然可以通过编辑chrome.manifest工作在目录形式下。比如下面的例子

-
content	myExtension	jar:chrome/myExtension.jar!/content/
-
-

不如

-
content	myExtension	chrome/content/
-
diff --git a/files/zh-cn/mozilla/add-ons/submitting_an_add-on_to_amo/index.html b/files/zh-cn/mozilla/add-ons/submitting_an_add-on_to_amo/index.html deleted file mode 100644 index 5ffb14d889..0000000000 --- a/files/zh-cn/mozilla/add-ons/submitting_an_add-on_to_amo/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 向AMO提交一个附加组件 -slug: Mozilla/Add-ons/Submitting_an_add-on_to_AMO -translation_of: Mozilla/Add-ons/Distribution ---- -

当你为基于Mozilla的软件(如Firefox,Thunderbird等)制作出了一个全新的附加组件时,你一定希望其他人能够找,到下载并使用它。

-

Mozilla provides the http://addons.mozilla.org (AMO) web site to provide a repository for add-ons for Mozilla software. When users click the "Get Extensions" link in the Add-ons window in Firefox, for example, they are directed to this site.

-

That makes AMO a great way to get your add-ons to the public. This article provides details on how to submit your article to AMO for distribution.

-
- Note: Attaching your add-on to articles on the Mozilla Developer Center web site won't do you a lot of good, as we delete them.  This is not the right place to post your add-ons; please follow the instructions here instead.
-

第一步:编写你的附加组件

-

This is important. It's hard to get an add-on accepted into AMO if you don't write it first. Really hard.

-

第二步:测试你的附加组件

-

Make sure it works before you submit it. You should try it out on every product you claim to support. In other words, you don't want to advertise that it works in both Firefox and Thunderbird if you haven't tested it in both. Make sure it works in every version you claim to support, too.

-

第三步:打包你的附加组件

-

Add-ons distributed by AMO need to be packaged properly as XPI files. See Extension Packaging for information on how to do this.

-

第四部:注册一个AMO账户

-

You'll need to have an AMO account so that you can make submissions. To get one, visit the Register link at the top of any page on the AMO website. Fill out the form and follow the instructions to activate your account.

-

Obviously, you can skip this step if you already have an AMO account.

-

第五步:提交你的附加组件

-

To submit an add-on, go to the Developer Control Panel.

-

You will then be asked to supply a file, as well as information about the add-on.

-

Once the add-on has been reviewed, it will be made available for downloading. Reviews can take a varying amount of time depending on how many pending submissions there are and the availability of people to perform the reviews.

-

{{ languages( { "fr": "fr/Soumettre_un_module_sur_AMO" } ) }}

diff --git a/files/zh-cn/mozilla/add-ons/themes/index.html b/files/zh-cn/mozilla/add-ons/themes/index.html deleted file mode 100644 index e7c28ba50c..0000000000 --- a/files/zh-cn/mozilla/add-ons/themes/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: 主题 -slug: Mozilla/Add-ons/Themes -tags: - - Themes -translation_of: Mozilla/Add-ons/Themes ---- -

-

-
Getting Started
-介绍如何为Firefox开发主题。
-
主题指的是程序的皮肤,通过它可以改变程序的外观,满足不同人的不同需要。一个主题可以只改变界面的颜色,也可以改变界面相关的所有元素。
- - -
-

Documentation

-
创建一套 Firefox 皮肤 -
介绍如何为Firefox创建新的主题。 -
-

一般style翻译成样式 -

-
主题打包 -
如何将Firefox和Thunderbird的主题打包。 -
-
Firefox 2.0 和 3.0 间的主题变更 -
-
Firefox 1.5 和 2.0 间的主题变更 -
Firefox 发行版1.5和2.0之间的主题全部变更清单。 -
-
Firefox 1.5 和 2.0 间的主题变更 (forum post) -
A forum post at MozillaZine outlining the basic theme-related changes between Firefox 1.0 and 1.5. -
-
主题设计的第一步 -
A somewhat aged article discussing theme design for Firefox. -
-

View All... -

-
-

Community

-
  • View Mozilla forums... -
-

{{ DiscussionList("dev-themes", "mozilla.dev.themes") }} -

- -

Tools

- -

View All... -

- -
CSS -
-
-

Categories -

Interwiki Language Links -


-


-

-
-
-{{ languages( { "de": "de/Themes", "en": "en/Themes", "es": "es/Temas", "fr": "fr/Th\u00e8mes", "ja": "ja/Themes", "pl": "pl/Motywy", "zh-tw": "zh_tw/\u4f48\u666f\u4e3b\u984c" } ) }} diff --git a/files/zh-cn/mozilla/add-ons/themes/obsolete/creating_a_skin_for_firefox/index.html b/files/zh-cn/mozilla/add-ons/themes/obsolete/creating_a_skin_for_firefox/index.html deleted file mode 100644 index 2301b757e7..0000000000 --- a/files/zh-cn/mozilla/add-ons/themes/obsolete/creating_a_skin_for_firefox/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: 创建一套_Firefox_皮肤 -slug: Mozilla/Add-ons/Themes/Obsolete/Creating_a_Skin_for_Firefox -tags: - - Themes -translation_of: Archive/Themes/Creating_a_Skin_for_Firefox ---- -

 

-

说明

-

为了为 Firefox 创建一套皮肤, 你必须知道三件事:如何编辑图像、如何释放zip文件、以及如何更改CSS。Firefox 的按钮图标使用标准的gif、png、和 jpeg 图像并使用 CSS 来定义界面上的一切。

-

什么是皮肤?

-

皮肤不会改版总体的界面;相反的,它仅仅定义了界面看上去的样子。你无法改版用户右击一个图像时发生什么事情,但你可以改版右键菜单的外观(例如使其变为带有粉色圆点装饰)。如果你想更改Firefox的功能,你不得不去改变chrome,这不在本文讨论的范围之内。

-

内容

- -
-

文章原始信息

- -
-
-  
-

{{ languages( { "de": "de/Theme_erstellen", "es": "es/Creando_un_tema_para_Firefox", "fr": "fr/Cr\u00e9er_un_th\u00e8me_pour_Firefox", "ja": "ja/Creating_a_Skin_for_Firefox", "pl": "pl/Tworzenie_sk\u00f3rek_dla_Firefoksa" } ) }}

diff --git a/files/zh-cn/mozilla/add-ons/themes/obsolete/creating_a_skin_for_firefox/uuid/index.html b/files/zh-cn/mozilla/add-ons/themes/obsolete/creating_a_skin_for_firefox/uuid/index.html deleted file mode 100644 index 37280321a1..0000000000 --- a/files/zh-cn/mozilla/add-ons/themes/obsolete/creating_a_skin_for_firefox/uuid/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: 创建一套Firefox皮肤 -slug: Mozilla/Add-ons/Themes/Obsolete/Creating_a_Skin_for_Firefox/UUID -translation_of: Archive/Themes/Creating_a_Skin_for_Firefox/UUID ---- -

{{wiki.localize('System.API.page-generated-for-subpage')}}

diff --git a/files/zh-cn/mozilla/add-ons/themes/obsolete/index.html b/files/zh-cn/mozilla/add-ons/themes/obsolete/index.html deleted file mode 100644 index d420b6ebf0..0000000000 --- a/files/zh-cn/mozilla/add-ons/themes/obsolete/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Obsolete -slug: Mozilla/Add-ons/Themes/Obsolete -tags: - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Add-ons/Themes/Obsolete ---- -

This page collects theme docs that we don't expect will ever be updated, but which we're keeping for the time being as potential source material for updated docs.

-

{{ ListSubPages ("/en-US/Add-ons/Themes/Obsolete", 5) }}

diff --git a/files/zh-cn/mozilla/add-ons/themes/obsolete/theme_changes_in_firefox_3/index.html b/files/zh-cn/mozilla/add-ons/themes/obsolete/theme_changes_in_firefox_3/index.html deleted file mode 100644 index 595058f253..0000000000 --- a/files/zh-cn/mozilla/add-ons/themes/obsolete/theme_changes_in_firefox_3/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Firefox 3 的界面改动 -slug: Mozilla/Add-ons/Themes/Obsolete/Theme_changes_in_Firefox_3 -tags: - - Themes -translation_of: Archive/Themes/Theme_changes_in_Firefox_3 ---- -

{{ Fx_minversion_header(3) }} {{ Draft() }}

-

本文包含了更新FireFox主题以使其可以在Firefox 3下良好表现所需进行的一些改动。

-
- Note: We could use an article called Updating themes for Firefox 3 that would serve as a how-to guide for updating themes. If anyone with theming experience would like to write one, please do!
-

默认主题的改动

-

下表列出了Firefox 3默认主题的一些改动。你可以对照此表,确认你所需要做出的改动。

-

所有文件

-

所有平台

- - - - - - - - - - - -
文件变更
<tt>browser/themes/*/browser/browser.css</tt>The width of the drag and drop indicator is no longer calculated during the drag (tabbrowser.xml). Instead a '-moz-margin-start' property must be added to .tab-drop-indicator-bar, with a value that is half of the width of the indicator image. Also, the visibility of the indicator is now controlled by setting collapsed in tabbrowser.xml. As a result, the 'display' property should be removed from .tab-drop-indicator-bar (including for dragging="true").
-

Mac OS X

- - - - - - - - - - - - - - - -
文件变动信息
<tt>browser/themes/pinstripe/browser/tabbrowser/tabDragIndicator.png</tt>删除了图片边缘多余的空白,现在图片尺寸变小。也许会对其他使用此图片的Mac平台下的主题产生影响。
<tt>browser/themes/pinstripe/browser/browser.css</tt>.tabbrowser-tab{{ mediawiki.external('first-tab=\"true\"') }} > .tab-image-left不再具有margin-left属性,现在使用定义了相同宽度的.tabs-left元素来替代。在FireFox 2的默认皮肤Winstripe中已经作此处理。
-

<tt>browser</tt>的改动

-

<tt>global</tt>的改动

-

所有平台

-

“跳转到”按钮现在被放置在地址栏内部,所以此按钮所用的图片(<tt>chrome://browser/skin/Go-arrow.png</tt>)需要设计的小一些。控制“跳转到”及其他地址栏中所用到的按钮的显示及隐藏的CSS规则为:

-
#urlbar[pageproxystate="invalid"] > #urlbar-icons > :not(#go-button) ,
-#urlbar[pageproxystate="valid"] > #urlbar-icons > #go-button {
-  visibility: collapse;
-}
-
-
增加的图片
-

增加了以下图片:

-
-
- <tt>chrome://global/skin/icons/information-16.png</tt>
-
- Used when presenting information notices。
-
- <tt>chrome://global/skin/icons/warning-16.png</tt>
-
- 用作显示警告窗口。
-
-
移除的图片
-

以下图片被移除:

-
-
- <tt>chrome://mozapps/skin/extensions/question.png</tt>
-
- 不再使用。
-
-

Mac OS X

-

为Mac OS X平台上的Firefox 3制作的皮肤需要在<tt>chrome://global/skin/wizard.css</tt>末尾增加两条CSS规则:

-
.wizard-buttons-btm {
-  padding:Xpx;
-}
-
-.wizard-label-box {
-  display: none;
-}
-
-

此处的数字 - - X - ,即<tt>.wizard-buttons-btm</tt>中的padding值,需要和<tt>.wizard-buttons-box-2</tt>中的margin值相同。

-
图片变动
-

chrome://global/skin/icons/loading_16.gif 被chrome://global/skin/icons/loading_16.png 替代。

-

<tt>mozapps</tt>的改动

-

参考文章

-

Theme changes in Firefox 2

diff --git a/files/zh-cn/mozilla/add-ons/webextensions/embedded_webextensions/index.html b/files/zh-cn/mozilla/add-ons/webextensions/embedded_webextensions/index.html deleted file mode 100644 index 834125bb32..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/embedded_webextensions/index.html +++ /dev/null @@ -1,205 +0,0 @@ ---- -title: Embedded WebExtensions -slug: Mozilla/Add-ons/WebExtensions/Embedded_WebExtensions -translation_of: Archive/Add-ons/Embedded_WebExtensions ---- -
{{AddonSidebar}}
- -
-

嵌入一个 WebExtension 需要使用 Firefox 51 或更高版本。在 SDK 附加组件中嵌入一个 WebExtension 还需要 jpm 1.2.0

-
- -

从 Firefox 51 开始,你可以在传统附加组件类型中嵌入一个 WebExtension。

- -

传统附加组件可以是经典的自举扩展或者Add-on SDK 附加组件。嵌入式 WebExtension 的文件打包在传统附加组件中。嵌入式 WebExtension 并不直接与嵌入的附加组件共享范围,但可以使用 {{WebExtAPIRef("runtime")}} API 中定义的消息函数交换消息。

- -

- -

这意味着您可以一次性迁移传统附加组件到 WebExtensions,并且在此期间附加组件的功能完全保留。尤其是它可以让您从旧版附加组件迁移存储数据到 WebExtension,通过撰写一个中间的混合式附加组件,使用旧版 API 读取数据(例如 simple-prefs 或 preferences 服务)并使用 WebExtension API 写入它(例如 {{WebExtAPIRef("storage")}})。

- -

连同本指南,我们撰写了两个例子展示如何使用嵌入式 WebExtensions 来帮助从传统附加组件迁移。如何从自举式附加组件迁移以及如何从 SDK 附加组件迁移

- -

嵌入 WebExtension

- -

如果传统附加组件是一个带有install.rdf 的自举式扩展,在该 RDF 中加入 "hasEmbeddedWebExtension" 并设为 "true":

- -
<em:hasEmbeddedWebExtension>true</em:hasEmbeddedWebExtension>
- -
如果旧式附加组件是一个 SDK 附加组件,在 package.json 中包含 "hasEmbeddedWebExtension" 并设为 true
- -
 
- -
"hasEmbeddedWebExtension": true
-
- -
WebExtension 本身放在附加组件中的 "webextension" 顶层目录。例如:
- -
 
- -
my-boostrapped-addon/
-    chrome/
-    webextension/
-        manifest.json
-        background.js
-        ...
-    bootstrap.js
-    chrome.manifest
-    install.rdf
- -
 
- -
-
my-sdk-addon/
-    index.js
-    package.json
-    webextension/
-        manifest.json
-        background.js
-        ...
-
- -

Firefox 不将嵌入式 WebExtension 视为一个独立的附加组件。因此,您不应该为它指定一个附加组件 ID。如果你这样做,那只会被忽略。

- -

但是,在您完成附加组件的迁移并移除旧式嵌入代码后,您必须添加一个 applications 键,设置 ID 为旧式附加组件的 ID。通过此方式,addons.mozilla.org 可以识别 WebExtension 是旧式附加组件的一个更新。

- -

启动 WebExtension

- -

嵌入式 WebExtension 必须由被嵌入的附加组件明确启动。

- -

如果被嵌入的附加组件是一个自举式附加组件,那么传递到自举式扩展的 startup() 函数的 data 将获得一个明确的 webExtension

- -
// bootstrapped add-on
-
-function startup({webExtension}) {
-
-...
- -

如果被嵌入的附加组件是一个 SDK 附加组件,它可以使用 sdk/webextension 模块访问一个 WebExtension 对象:

- -
// SDK add-on
-
-const webExtension = require("sdk/webextension");
- -

无论哪种方式,此对象都有一个 startup() 函数,它返回一个 Promise。该 promise 使用一个 browser 属性解决一个对象:这包括 {{WebExtAPIRef("runtime")}} API,被嵌入的附加组件可以用它来与嵌入式 WebExtension 交换消息:

- - - -

例如:

- -
// bootstrapped add-on
-
-function startup({webExtension}) {
-  webExtension.startup().then(api => {
-    const {browser} = api;
-    browser.runtime.onMessage.addListener(handleMessage);
-  });
-}
- -
// SDK add-on
-
-const webExtension = require("sdk/webextension");
-
-webExtension.startup().then(api => {
-  const {browser} = api;
-  browser.runtime.onMessage.addListener(handleMessage);
-});
-
- -

应注意的是,嵌入的附加组件不能启动通信,它可以使用 onMessage 接收(并可选响应)一次性消息,并可以使用 onConnect 接受连接请求。

- -

如果嵌入式 WebExtension 缺少一个 manifest,或者如果 manifest 无效,该 promise 会被拒绝。这种情况下,您可以在浏览器工具箱的控制台中看到更多细节。

- -

交换消息

- -

一旦嵌入式 WebExtension 处在运行,它可以使用 {{WebExtAPIRef("runtime")}} API 的子集与旧式附加组件交换消息:

- - - -

无需连接的消息

- -

要发送一条消息,WebExtension 可以使用 {{WebExtAPIRef("runtime.sendMessage()")}}。您可以省略 extensionId 参数,因为浏览器认为嵌入式 WebExtension 是被嵌入附加组件的一部分:

- -
browser.runtime.sendMessage("message-from-webextension").then(reply => {
-  if (reply) {
-    console.log("response from legacy add-on: " + reply.content);
-  }
-});
- -

被嵌入的附加组件可以使用 {{WebExtAPIRef("runtime.onMessage")}} 对象接收消息(并可选响应):

- -
// bootstrapped add-on
-
-function startup({webExtension}) {
-  // Start the embedded webextension.
-  webExtension.startup().then(api => {
-    const {browser} = api;
-    browser.runtime.onMessage.addListener((msg, sender, sendReply) => {
-      if (msg == "message-from-webextension") {
-        sendReply({
-          content: "reply from legacy add-on"
-        });
-      }
-    });
-  });
-}
- -

基于连接的消息

- -

要在 WebExtension 与传统附加组件间设置一个长寿命连接,WebExtension 可以使用 {{WebExtAPIRef("runtime.connect()")}}。

- -
var port = browser.runtime.connect({name: "connection-to-legacy"});
-
-port.onMessage.addListener(function(message) {
-  console.log("Message from legacy add-on: " + message.content);
-});
-
- -

旧式附加组件可以使用 {{WebExtAPIRef("runtime.onConnect")}} 监听连接尝试,双方可以使用得到的 {{webExtAPIRef("runtime.Port")}} 来交换消息:

- -
function startup({webExtension}) {
-  // Start the embedded webextension.
-  webExtension.startup().then(api => {
-    const {browser} = api;
-    browser.runtime.onConnect.addListener((port) => {
-      port.postMessage({
-        content: "content from legacy add-on"
-      });
-    });
-  });
-}
- -

从传统附加组件迁移数据

- -

嵌入式 WebExtensions 的一项主要用途是迁移附加组件的存储数据。

- -

人们从旧式附加组件类型迁移的一个主要问题是存储数据,因为旧式附加组件不能使用 WebExtension 存储 API,WebExtensions 也不能使用旧式存储 API。例如,如果一个 SDK 附加组件使用了 SDK 的 simple-prefs API 来存储首选项,WebExtension 版本不可能访问这项数据。

- -

使用嵌入式 WebExtensions,您可以创建一个嵌入了 WebExtension 的附加组件中间版本来迁移数据。中间版本使用旧式 API 读取存储的数据,然后使用 WebExtension API 写入数据。

- - - -

我们提供了两个例子说明此模式:"embedded-webextension-bootstrapped" 展示了从一个自举式附加组件迁移,而 "embedded-webextension-sdk" 展示了从一个 SDK 附加组件迁移。

- -

限制

- -

调试

- -

如果您有一个嵌入了 WebExtension 的旧式附加组件,您不能使用新的附加组件调试器来调试它。您必须使用基于浏览器工具箱的旧版调试工具

diff --git a/files/zh-cn/mozilla/add-ons/working_with_multiprocess_firefox/index.html b/files/zh-cn/mozilla/add-ons/working_with_multiprocess_firefox/index.html deleted file mode 100644 index 152a15de20..0000000000 --- a/files/zh-cn/mozilla/add-ons/working_with_multiprocess_firefox/index.html +++ /dev/null @@ -1,296 +0,0 @@ ---- -title: 编写适合多进程 Firefox 的扩展 -slug: Mozilla/Add-ons/Working_with_multiprocess_Firefox -translation_of: Archive/Add-ons/Working_with_multiprocess_Firefox ---- -
-

致 Firefox 开发者:本文描述如何使你开发的扩展能在多进程 Firefox 中运行。

-
- -

目前,在桌面版 Firefox 中,Chrome 代码(Chrome Code)和内容(Content)运行在同一个进程里。因此扩展可以直接访问网页内容:

- -
gBrowser.selectedBrowser.contentDocument.body.innerHTML = "replaced by chrome code";
- -

不过呢,在多进程 Firefox(又称 Electrolysis 或 E10S)中,扩展代码(Add-on Code)和内容则在不同的进程中运行,所以上述直接访问就不一定可行了。

- -

在多进程 Firefox 中,扩展需要将触及内容的代码分解成单独分离的脚本,也就是所谓的框架脚本(Frame Scripts)。框架脚本在内容进程中运行,可以直接访问内容。框架脚本通过消息传递接口(Message-passing API)与扩展的剩余部分进行通讯。

- -

运行在 Chrome 进程中的扩展代码必须向框架脚本发送异步消息。这样做可以确保 Firefox 的用户界面不会被内容进程卡死。

- -

内容进程则可以向 Chrome 进程发送同步或异步消息,不过使用异步消息是再好不过了。

- -

关于使用消息管理器的更多细节,请参阅:消息管理器指南。接下来,本文将告诉你如何判断你开发的扩展是否会受到这方面的影响,同时简要说明需要如何进行修改。最后,通过对一些简单的样板扩展进行修改,让它们能在多进程 Firefox 中运行。

- -

检查你的扩展是否受到影响

- -

总体规则如下:

- - - -

为了证实是否受到影响,你还需要进一步测试,这个测试过程由两步过程构成:

- - - -

现在,你可以在多进程 Firefox 中禁用兼容性管理工具来测试你的扩展的兼容性了。可惜你还不能在开启多进程功能的时候安装新扩展,因此你必须先安装好扩展再开启多进程功能。关于这个问题,详见 bug 1055808

- -

更新你的代码

- -

更新代码的一般方法是:

- - - -

更多细节,请参见 message manager 文档。

- -

新应用程序接口的向前兼容能力

- -

新的多进程 Firefox 的消息接口在多进程模式没有开启的情况下仍然可用。实际上它们从 Firefox 4开始就在某种程度上可用了。不过呢,最初的应用程序接口和现在的并不相同。一些已知的差异如下:

- - - -

你不仅应该在开启了多进程支持的每夜版Firefox上测试你的扩展的变化,而且应该在你打算支持的没有开启多进程支持的发行版(Release Build)中测试。

- -

举几个例子

- -

这部分将演示修改几种不同的扩展的过程。这些扩展都是很简易的,意在展示基础的扩展模式在多进程Firefox中需要的不同处理方式。

- -

你可以在 e10s-example-addons GitHub repository 中找到这些例子的所有源代码。

- -

在所有页面运行一个脚本

- -
-

查看这个例子的源代码

-
- -

第一个扩展在每一个页面加载的时候运行一些代码。这些代码不和扩展的其他部分交互,它们只是对页面进行一些预设的修改。在这个例子中,扩展向文档的主体(body)添加了一个边界。

- -

这个扩展通过将一种“页面加载中”代码碎片("On page load" code snippet)附加于可扩展用户界面语言层来实现此修改。

- -
var myExtension = {
-    init: function() {
-        // The event can be DOMContentLoaded, pageshow, pagehide, load or unload.
-        if(gBrowser) gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad, false);
-    },
-    onPageLoad: function(aEvent) {
-        var doc = aEvent.originalTarget; // doc is document that triggered the event
-        if (doc.nodeName != "#document") return; // only documents
-        // make whatever modifications you want to doc
-        doc.body.style.border = "5px solid blue";
-    }
-}
-
-window.addEventListener("load", function load(event){
-    window.removeEventListener("load", load, false); //remove listener, no longer needed
-    myExtension.init();
-},false);
- -

因为这段代码直接访问网络内容,所以它不能在多进程 Firefox 中运行。
-

- -

移植到消息管理器

- -

为了使用消息管理器移植这个例子,我们可将这个扩展全部的主体部分放入一个框架脚本:

- -
// frame-script.js
-// will run in the content process
-
-addEventListener("DOMContentLoaded", function(event) {
-  var doc = event.originalTarget;
-  if (doc.nodeName != "#document") return; // only documents
-  doc.body.style.border = "5px solid red";
-});
-
- -

我们将为这个框架脚本注册一个 chrome:// URL :

- -
// chrome.manifest
-
-content    modify-all-pages    chrome/content/
-
- -

我们附加到XUL overlay的主体脚本,只是一个使用全局消息管理器来在每个标签页中加载框架脚本的 stub。

- -
// chrome script
-// will run in the chrome process
-
-var globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
-  .getService(Ci.nsIMessageListenerManager);
-
-globalMM.loadFrameScript("chrome://modify-all-pages/content/frame-script.js", true);
- -

- -

移植到 Add-on SDK

- -

一个好的替代这样的一个扩展的思路是将其移植到 Add-on SDK。Add-on SDK 包括一个名为 page-mod 的设计为在网页中加载脚本的模块。Add-on SDK 称这些脚本为内容脚本。

- -

这种情况下扩展的主要代码创建一个 page-mod 来加载内容脚本到用户载入的每个页面:

- -
// main.js
-
-var pageMod = require("sdk/page-mod");
-var self = require("sdk/self");
-
-pageMod.PageMod({
-  include: "*",
-  contentScriptFile: self.data.url("modify-all-pages.js")
-});
- -

内容脚本可以直接修改页面:

- -
// modify-all-pages.js - content script
-
-document.body.style.border = "5px solid green";
- -

在活动标签中运行一个脚本

- -
-

查看这个例子的代码。

-
- -

这个例子说明了一个扩展如何:

- - - -

这个例子是一个无需重启的扩展,它使用 CustomizableUI 模块添加了一个按钮。当用户点击这个按钮,这个扩展运行一些代码来改变当前标签。其基础构造取自 Jorge Villalobos 的 Australis "Hello World" 扩展 .
-
- 代码实际做的事是:找到任意 <img> 元素并将其 src 替换为从硬编码于扩展中的列表中随机抽取的无意义的 GIF 图像。 无意义的 gifs 从Whimsy extension 获取。

- -

第一个版本直接访问页面,因此其不是多进程兼容的:

- -
// bootstrap.js
-
-let Gifinate = {
-  init : function() {
-    let io =
-      Cc["@mozilla.org/network/io-service;1"].
-        getService(Ci.nsIIOService);
-
-    // the 'style' directive isn't supported in chrome.manifest for bootstrapped
-    // extensions, so this is the manual way of doing the same.
-    this._ss =
-      Cc["@mozilla.org/content/style-sheet-service;1"].
-        getService(Ci.nsIStyleSheetService);
-    this._uri = io.newURI("chrome://gifinate/skin/toolbar.css", null, null);
-    this._ss.loadAndRegisterSheet(this._uri, this._ss.USER_SHEET);
-
-    // create widget and add it to the main toolbar.
-    CustomizableUI.createWidget(
-      { id : "gifinate-button",
-        defaultArea : CustomizableUI.AREA_NAVBAR,
-        label : "Gifinate",
-        tooltiptext : "Gifinate!",
-        onCommand : function(aEvent) {
-          Gifinate.replaceImages(aEvent.target.ownerDocument.defaultView.content.document);
-        }
-      });
-  },
-
-  replaceImages : function(contentDocument) {
-      let images = contentDocument.getElementsByTagName("img");
-      for (var i = 0; i < images.length; ++i) {
-        let gif = this.gifs[Math.floor(Math.random() * this.gifs.length)];
-        images[i].src = gif;
-      }
-    },
- -

- -

移植到消息管理器

- -

为了移植这个例子到消息管理器,我们将使 onCommand 加载一个框架脚本到当前的 <browser>,然后监听来自框架脚本的 "request-gifs" 信息。这些 "request-gifs" 信息应当包含我们在此页面上需要的 GIFs :信息监听器取回并返回这个数量的 GIFs。

- -
// bootstrap.js
-// will run in the chrome process
-
-let Gifinate = {
-  init : function() {
-    let io =
-      Cc["@mozilla.org/network/io-service;1"].
-        getService(Ci.nsIIOService);
-
-    // the 'style' directive isn't supported in chrome.manifest for bootstrapped
-    // extensions, so this is the manual way of doing the same.
-    this._ss =
-      Cc["@mozilla.org/content/style-sheet-service;1"].
-        getService(Ci.nsIStyleSheetService);
-    this._uri = io.newURI("chrome://gifinate/skin/toolbar.css", null, null);
-    this._ss.loadAndRegisterSheet(this._uri, this._ss.USER_SHEET);
-
-    // create widget and add it to the main toolbar.
-    CustomizableUI.createWidget(
-      { id : "gifinate-button",
-        defaultArea : CustomizableUI.AREA_NAVBAR,
-        label : "Gifinate Button",
-        tooltiptext : "Gifinate!",
-        onCommand : function(aEvent) {
-          Gifinate.replaceImages(aEvent.target.ownerDocument);
-        }
-      });
-  },
-
-  replaceImages : function(xulDocument) {
-    var browserMM = xulDocument.defaultView.gBrowser.selectedBrowser.messageManager;
-    browserMM.loadFrameScript("chrome://gifinate/content/frame-script.js", false);
-    browserMM.addMessageListener("request-gifs", Gifinate.getGifs);
-  },
-
-  getGifs : function(message) {
-    var gifsToReturn = new Array(message.data);
-    for (var i = 0; i < gifsToReturn.length; i++) {
-      let gif = this.gifs[Math.floor(Math.random() * this.gifs.length)];
-      gifsToReturn[i] = gif;
-    }
-    return gifsToReturn;
-  },
-
- -

再次地,我们需要为这个框架脚本注册一个 chrome:// URL:

- -
// chrome.manifest
-
-content gifinate frame-script.js
- -

在框架脚本中,我们获取所有的 <img> 元素并发送 "request-gifs" 信息给扩展主体代码。 由于这是框架脚本我们可以将其变为一个同步信息,并使用其返回值更新 src 属性:

- -
// frame-script.js
-// will run in the content process
-
-var images = content.document.getElementsByTagName("img");
-var response = sendSyncMessage("request-gifs", images.length);
-var gifs = response[0];
-
-for (var i = 0; i < images.length; ++i) {
-  images[i].src = gifs[i];
-}
- -

整个扩展的流程现在像这样:
-

- -

已知问题

- -

这里是可能影响扩展开发者移植到多进程firefox的开放的bug列表:

- - diff --git "a/files/zh-cn/mozilla/add-ons/\351\233\267\351\270\237/index.html" "b/files/zh-cn/mozilla/add-ons/\351\233\267\351\270\237/index.html" deleted file mode 100644 index c46b242f7e..0000000000 --- "a/files/zh-cn/mozilla/add-ons/\351\233\267\351\270\237/index.html" +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: 雷鸟扩展 -slug: Mozilla/Add-ons/雷鸟 -translation_of: Mozilla/Thunderbird/Thunderbird_extensions ---- -
Building a Thunderbird extension
-Step-by-step explanation on how to build an extension for Thunderbird.
- -
-

{{AddonSidebar}}

-本文档是为Mozilla公司的雷鸟邮件客户端开发扩展的教程。Although there are many similarities with Firefox extensions there are also some differences that may confound the starting developer.
- -

-Please help! You can add a how-to (a question or an answer or a code snippet), summarize and link to a relevant newsgroup discussion, or create a tutorial. Need help? Contact jenzed.
- - - - - - - - -
-

Documentation

- -

Getting started with Thunderbird

- -

A brave, young developer wants to develop an add-on for Thunderbird. Here's a few links to help them through this journey.

- -
    -
  • Start by reading the tutorial and learn how to build a Thunderbird extension (Outdated, still talks about overlays and the add-on builder is no longer available but the tutorial has not been updated.)
  • -
  • Read about the main windows so that you know what one means when they say « thread pane », « preview pane », and « folder pane ».
  • -
  • Read an overview of how the various parts of Thunderbird fit together, this really helps get a better understanding of Thunderbird.
  • -
  • Want to do some real stuff? See how to inspect a message (demo add-on included!)
  • -
  • Play with our other demo add-on that exercises some more advanced Thunderbird-specific features
  • -
  • Want to do even more stuff? Don't reinvent the wheel: steal functions from the thunderbird-stdlib project (doc here). Functions for dealing with messages (delete them, archive them, change their tags, etc.) are included.
  • -
  • Haven't found what you're looking for? Read the Thunderbird how-tos; they contain a lot of recipes for things extensions want to do.
  • -
  • Still haven't managed to do what you wanted? See the list of all Thunderbird communication channels so that you know where to ask when you get stuck :-).
  • -
  • Feeling really brave? Read the source using a fancy interface; you can often find tests that demonstrate how to do what you're trying to achieve.
  • -
- -

The Gloda database

- -

Thunderbird has a subsystem called Gloda. Gloda stands for « Global Database », and creates Thunderbird-wide relations between objects. Gloda provides concepts such as Conversations, Messages, Identities, Contacts. All these concepts are related together: a Conversation contains Messages which are linked to Identities (from field, to field) which are themselves part of a Contact: indeed, a contact has multiple identities.

- -

Typical use cases for Gloda: find all messages whose subject matches [search term], find all messages from [person], find all messages in the same thread as [a given message], find all messages involving [person], etc. etc.

- -

Gloda is extremely powerful and is used heavily by add-ons such as Thunderbird Conversations. Learn more about Gloda:

- - - - - -

Some of these links may be wildly out of date, but they still provide valuable information on the codebase.

- - - - - - -
-

Community

- - - -

{{ DiscussionList("dev-extensions", "mozilla.dev.extensions") }}

- - - -

Tools

- - - -

... more tools ...

- -

View All...

- - - -
-
XUL, JavaScript, XPCOM, Themes, Developing Mozilla
-
-
- -

Categories

- -

{{ languages( { "ja": "ja/Extensions/Thunderbird" } ) }}

diff --git a/files/zh-cn/mozilla/adding_a_new_event/index.html b/files/zh-cn/mozilla/adding_a_new_event/index.html deleted file mode 100644 index 1cd964fe0e..0000000000 --- a/files/zh-cn/mozilla/adding_a_new_event/index.html +++ /dev/null @@ -1,186 +0,0 @@ ---- -title: Adding a new event -slug: Mozilla/Adding_a_new_event -translation_of: Mozilla/Adding_a_new_event ---- -
-

This document is a working draft.

-
- -

What type of event do you want?

- -

大体上,有三种类型的事件。 First, you need to choose which type you need.

- -

Case 1: 简单DOM事件。通过WebIDL、WidgetEvent等机制实现. This type of event is useful if the event isn't handled by C++ code.

- -

Case 2: DOM事件。表达诸如键盘、鼠标等用户操作的本地事件。这种类型的事件能够方便的使用C++代码来处理。

- -

Case 3: 非DOM事件。However, C++ 代码需要分派事件到DOM树,然后在使用C++代码来处理。This is useful for widget notifying DOM tree of something or retrieving something from DOM tree.

- -

How to implement an internal event class

- -
-

If you're in the case 1, you can skip this section.

-
- -

Add event messages

- -

You need to add event messages which are stored by WidgetEvent::message. All messages are defined by macro in "messages" section of BasicEvents.h.

- -

Define event class name

- -

You need to add an event class name in EventClassList.h.

- -

Use NS_EVENT_CLASS macro for adding it. The macro takes two arguments, aPrefix and aName.

- -

aPrefix defines prefix of event class name which should be Widget or Internal. Widget should be used if the event class is dispatched from widget. Otherwise, i.e., the event class is just used for internal event class of a DOM event class, it should be Internal.

- -

aName defines its event class specific name and it must end with "Event" or "EventBase". The latter is used only for abstruct super event class whose instance will never be created.

- -

Please note that aName must not be same as other event classes even if aPrefix is different. I.e., defining both WidgetFooEvent and InternalFooEvent is invalid.

- -

Define and implement an event class

- -

Then, you need to define and implement an event class. You should choose a good header file from what your event class represents.

- -
-
BasicEvents.h
-
This header file should be used only for defining generic purpose event class such as a common super class of various event classes. Probably, you shouldn't use this for your class.
-
ContentEvents.h
-
This header file should be used for defining internal event classes which are dispatched in content and do not represent user action. Typically, events in this header file never cross process boundary.
-
MouseEvents.h
-
This header file should be used for defining input events from pointing devices such as mouse.
-
TextEvents.h
-
This header file should be used for defining input events from keyboard or IME and also other text edit related events like querying focused content information.
-
TouchEvents.h
-
This header file should be used for defining input events from touch devices.
-
MiscEvents.h
-
If the new event class isn't proper any header files above, you should use this.
-
- -

Each event class should implement following methods manually.

- -
-
virtual InternalFooEvent* AsFooEvent() MOZ_OVERRIDE
-
This method should just return this. This method is used for retrieving sub class pointer avoiding to use static_cast.
-
virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
-
This method should create a new instance with copying its members except widget. For copying the members, this should use AssignFooEventData() with true for aCopyTargets. And also, mFlags should be just copied since AssignFooEventData() doesn't copy mFlags. This method is basically used for duplicating an internal event class instance of a DOM event when the DOM event is stored by content.
-
void AssignFooEventData(const InternalFooEvent* aEvent, bool aCopyTargets)
-
This method should copy members from aEvent. First, this method should call its super class's this method. Then, copy the additional members which are defined in the class. If aCopyTargets is false, don't copy its event target related members.
-
- -

All new member variables of event classes must be with "m" prefix. Although, a lot of existing members don't have "m" prefix, but you shouldn't use the legacy local rules.

- -

If you need to add methods, it's okay to implement them as inline methods. I.e., you can implement new methods in the header files directly.

- -

However, if implementing method isn't small and called from a lot of places, implementing it as inline causes to increase binary size. In this case, you should implement the method in WidgetEventImple.cpp. And also, if implementing a method needs to include other header files, you should implement it in WidgetEventImple.cpp too for avoiding include hell.

- -

Make new event class IPC aware

- -

For example, new class is caused by native user input event and needed to be dispatch to content, the class should be able to cross process boundary. In such cases, you may need to add new ParamTraits for the new event class in nsGUIEventIPC.h.

- -

Modify utility methods of WidgetEvent

- -

WidgetEvent class has some utility mehtods and all of them are implemented in WidgetEventImple.cpp. E.g., if your event shouldn't cause DOM event, you need to modify WidgetEvent::IsAllowedToDispatchDOMEvent(). If your event should be fired on focused node, you need to modify WidgetEvent::IsTargetedAtFocusedContent().

- -

How to implement a DOM event class

- -
-

If you're in the case 3, you can skip this section.

-
- -

Create WebIDL of the event

- -

Write a DOM event definition with WebIDL. It should be created under dom/webidl/. See WebIDL bindings for the detail.

- -

If your new event shouldn't be created with event constructor such as:

- -
var event = new FooEvent("bar", { bubbles: true, cancelable: true, detail: 5 });
- -

you shouldn't define construnctor in it.

- -

Create XPCOM interface for the DOM event

- -

If your event class should be accessible via XPCOM interface, you should create a new nsIDOMFooEvent interface in dom/interfaces/events/. However, in these days, this is not necessary. If all information of the event is stored by its internal event, C++ event handlers can acess them with following code:

- -
NS_IMETHODIMP
-AnEventListener::HandleEvent(nsIDOMEvent* aEvent)
-{
-  InternalFooEvent* internalEvent =
-    aEvent->GetInternalNSEvent()->AsFooEvent();
-  if (NS_WARN_IF(!internalEvent)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-  DoSomethingWith(internalEvent->mBar);
-  aEvent->PreventDefault();
-  return NS_OK;
-}
-
- -

Implement DOM event class

- -

Generate DOM event implementation if it's possible

- -

If you're creating simple DOM event class, it might be generated automatically. If it's possible, you just need to add an entry to GENERATED_EVENTS_WEBIDL_FILES in dom/webidl/moz.build.

- -

Define and create DOM event class manually

- -

Otherwise, you need to implement a DOM event class yourself. The best place to create FooEvent.h and FooEvent.cpp is in dom/events/. Otherwise, you need to specify the path to the header file in dom/bindings/Bindings.conf.

- -

When you create a DOM event class, its name should be same as the name defined in its standard specification. And it should be in mozilla::dom namespace. For example, KeyboardEvent which is defined in DOM Level 3 Events should be implemented as mozilla::dom::KeyboardEvent.

- -

And the header file should be exported as "mozilla/dom/FooEvent.h". Add the header file to EXPORTS.mozilla.dom in dom/events/moz.build.

- -

You probably need to implement a lot of methods to the event class, but this document doesn't explain all of them. Please refer existing DOM event implementation for example.

- -

However, there are some hints:

- -
    -
  1. Set mEventIsInternal in the constructor of the most descendant class because each constructor creates dummy internal event instance at calling constructors of its super class. Therefore, super classes always set it false.
  2. -
  3. Don't override methods of its super classes as far as possible since overriding the method may cause harder to maintain.
  4. -
  5. When you need to check if the caller content or chrome, you can use implicitJSContext attribute in dom/bindings/Bindings.conf. Then, the method can have a pointer of JSContext in its argument.
  6. -
- -

Create DOM event factory method

- -
-

If your DOM event implementation is generatable, you can skip this section.

-
- -

In nsIDOMEvent.idl, you need to define NS_NewDOMFooEvent(). It's last argument should be the most subclass. Then, the implementation of the DOM event can access internal event class instance safer.

- -

Then, the factory method should be implemented at the bottom of FooEvent.cpp in the global namespace.

- -

Modify EventDispatcher::CreateEvent()

- -
-

If your DOM event implementation is generatable or you're in case 3, you can skip this section.

-
- -

The first half of EventDispatcher::CreateEvent() is a factory to create a DOM event instance from internal event instance. You need to modify this.

- -

The last half of it is the implementation of legacy event creator of Javascript such as:

- -
var event = document.createEvent("FooEvent");
- -

If you support this feature, you need to modify here. However, this feature shouldn't be implemented for compabitility with other browsers since web applications should use event constructor.

- -

Register each event into EventNameList.h

- -
-

If you're in case 3, you can skip this section.

-
- -

EventNameList.h defines mapping between DOM event name, internal event message, event handler attribute owner and internal event class. See the comments of the head of the file for the detail.

- -

Modify tests

- -
-

If you're in case 3, you can skip this section.

-
- -

You need to modify test_all_synthetic_events.html which tests if calling getModifierState() doesn't cause crash.

- -

You need to modify test_assign_event_data.html which tests if each attribute of DOM event is copied by AssignFooEventData() properly. If your event cannot be fired easy, you should add the test but canRun should return false and call todo().

- -

If the new DOM event is creatable with constructor, you need to modify test_eventctors.html or test_eventctors.xul which tests the behavior of event constructor.

diff --git a/files/zh-cn/mozilla/bugzilla/index.html b/files/zh-cn/mozilla/bugzilla/index.html deleted file mode 100644 index 83c9832732..0000000000 --- a/files/zh-cn/mozilla/bugzilla/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Bugzilla -slug: Mozilla/Bugzilla -tags: - - Bugzilla - - Developing Mozilla - - 'Developing_Mozilla:Tools' - - NeedsTranslation - - QA - - Tools - - TopicStub -translation_of: Mozilla/Bugzilla ---- -

bugzilla.mozilla.org (often abbreviated b.m.o) is Mozilla.org's bug-tracking system, a database for recording bugs and enhancement requests for Firefox, Thunderbird, SeaMonkey, Camino, and other mozilla.org projects.

- -
-
-

Documentation about B.m.o.

- -
-
What to do and what not to do in Bugzilla
-
Tips for how to use Bugzilla, as well as things you should avoid.
-
Bugzilla etiquette
-
A guide to etiquette; this guide will help you understand how best to conduct yourself on b.m.o. and how using proper manners and civility will help ensure your problem gets solved sooner rather than later.
-
How to tell if a bug has already been reported
-
It's useful (but not mandatory) for you to check if the problem you're reporting has been already tracked. This guide will help you do so.
-
Quality assurance
-
Documentation about quality assurance at Mozilla.
-
Bug writing guidelines
-
A guide to writing a good, understandable, bug that will be easily followed by the development team.
-
How to submit a patch
-
If you've fixed a bug, or have implemented a new feature, you'll need to get your patch into the tree so it can become part of the product. This guide will teach you how!
-
- -

View All...

-
- -
-

Other materials

- - - -

Tools

- -
    -
  • Bugzilla Todos lists review and flag requests, patches to check in, unfulfilled requests you made of other people, and assigned bugs.
  • -
  • Bz Kanban is a board to visualize the status of bugs within a milestone.
  • -
-
-
diff --git a/files/zh-cn/mozilla/bugzilla/testopia/index.html b/files/zh-cn/mozilla/bugzilla/testopia/index.html deleted file mode 100644 index 638ecf9630..0000000000 --- a/files/zh-cn/mozilla/bugzilla/testopia/index.html +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: Testopia -slug: Mozilla/Bugzilla/Testopia -translation_of: Mozilla/Bugzilla/Testopia ---- -

Testopia 是bugzilla测试用例管理扩展工具。它可以帮助测试人员跟踪管理测试用例,并将测试用例运行结果整合进bug报告。testopia设计以软件测试为核心,使之可以跟踪软件工程中的几乎任何测试。

-

Testopia 2.5

-

此版本直接支持bugzilla4.2,并且不在需要bugzilla 补丁。如果用户需要升级至2.5

-

在安装前,请卸载已安装的bugzilla补丁。安装之需要直接将tar包解压在bugzilla的根目录下,并运行checksetup即可。感谢来自bugzilla团队的LpSolit,没有它就没有这些变化。

-

Testopia 2.4 - 重要通知!

-

如果用户在大小写敏感的文件系统中升级,请一定要从扩展目录中删除已有的testopia文件夹。

-

如果用户已经修改了testopia 的源代码,用户需要将他们合并到Testopia文件夹(capital T)。如果用户使用windows系统或其它大小写不敏感的文件系统,用户仅需要重命名已有文件夹即可,例如:testopia-old ,然后解压缩tar包。在删除老版本前,用户可以合并两个文件夹。

-

API USERS 请注意: 不再赞成使用Positional parameters。所有参数变量现在都应形成哈希对 (struct, dict, hashmap or whatever your language of choice calls key, value pairs).

-

虽然,努力尝试继续支持positional parameters,但请注意有些api直到用户调用时才会失败。在后续版本中也许会完全去除对它的支持。

-

一如既往,请在安装或升级前备份你已安装的系统。

-

Integration Points

- -

Features for version 2.4 (Bugzilla 3.6.x)

- -

Features for version 2.3 (Bugzilla 3.4.x)

- -

Features for version 2.2 (Bugzilla 3.2 and 3.0.x)

-

此版本主要是修复了一些bug,使之更好的兼容bugzilla 3.2 和 3.0.6。请确认根据自己的bugzilla版本下载正确的安装包。

-

To install, do the following (see the README for more detailed instructions):

-
    -
  1. 解压Testopia 2.4 tar包到用户的Bugzilla目录.
  2. -
  3. 打Bugzilla补丁.
    - On Linux systems it should look something like: -

    patch -p0 -i extensions/testopia/patch-3.6

    -
  4. -
  5. Run checksetup.pl
  6. -
-

升级Testopia步骤同上。只是需要先卸载以前的老补丁即可。如果同时升级bugzilla,请先升级bugzilla,再升级testopia。

-

patch -p0 -R -i extensions/testopia/patch-<version>

-

命令中<version> 代表Bugzilla版本号

-

Requirements

-

我们决定尝试紧跟bugzilla最新稳定版本3.4,来完成自己的开发。这给我们提供稳定的代码。为任何软件开发插件或扩展,就像射击移动目标一样。这个决定使得我们可以集中更多时间在新特性上,而不是旧特性。因此,这就意味着新特性不会再支持早先的版本,除非我们有时间这么做。当然,任何想这么做的人,都是无上欢迎的。

- -

TODO

- -

See the Roadmap and Bug List for more details.

- - -

Downloads

- -

Developers

-

Greg Hendricks
- Vance Baarda (former developer)
- Ed Fuentetaja (former developer)

diff --git a/files/zh-cn/mozilla/chrome_registration/index.html b/files/zh-cn/mozilla/chrome_registration/index.html deleted file mode 100644 index 8e7fd85b41..0000000000 --- a/files/zh-cn/mozilla/chrome_registration/index.html +++ /dev/null @@ -1,229 +0,0 @@ ---- -title: Chrome Registration -slug: Mozilla/Chrome_Registration -tags: - - NeedsEditorialReview - - Toolkit API -translation_of: Mozilla/Chrome_Registration ---- -

 

- -

Chrome是什么?

- -

Chrome 是应用程序内容窗口以外一系列用户接口元素。工具栏,如菜单栏,进度栏和标题栏这些都是chrome典型的元件。

- -

Chrome Providers

- -

A supplier of chrome for a given window type (e.g. for the browser window) is called a chrome provider. The providers work together to supply a complete set of chrome for a particular window, from the images on the toolbar buttons to the files that describe the text, content and appearance of the window itself.

- -

There are three basic types of chrome providers:

- -

Content

- -

The main source file for a window description comes from the content provider, and it can be any file type viewable from within Mozilla. It will typically be a XUL file, since XUL is designed for describing the contents of windows and dialogs. The JavaScript files that define the user interface are also contained within the content packages, as well as most XBL binding files.

- -

Locale

- -

Localizable applications keep all their localized information in locale providers. This allows translators to plug in a different chrome package to translate an application without altering the rest of the source code. The two main types of localizable files are DTD files and Java-style properties files.

- -

Skin

- -

A skin provider is responsible for providing a complete set of files that describe the visual appearance of the chrome. Typically a skin provider will provide CSS files and images.

- -

Note: Scripts (including those found in XBL) loaded from skin packages will not execute.

- -

The Chrome Registry

- -

The gecko runtime maintains a service known as the chrome registry that provides mappings from chrome package names to the physical location of chrome packages on disk.

- -

This chrome registry is configurable and persistent, and thus a user can install different chrome providers, and select a preferred skin and locale. This is accomplished through xpinstall and the extension manager.

- -

In order to inform the chrome registry of the available chrome, a text manifest is used: this manifest is "chrome.manifest" in the root of an extension, or theme, and chrome/*.manifest in a XULRunner application.

- -

The plaintext chrome manifests are in a simple line-based format. Each line is parsed individually; if the line is parseable the chrome registry takes the action identified by that line; otherwise the chrome registry ignores that line (and prints a warning message in the runtime error console).

- -
locale packagename localename path/to/files
-skin packagename skinname path/to/files
-
- -

Manifest Instructions

- -

comments

- -

A line is a comment if it begins with the character '#'; any other characters on the line are ignored.

- -
# this line is a comment - you can put whatever you want here
-
- -

content

- -

A content package is registered with the line

- -
contentpackagenameuri/to/files/[flags]
-
- -

This will register a location to use when resolving the URI chrome://packagename /content/.... The URI may be absolute or relative to the location of the manifest file. Note, that it must end with an '/'.

- -

locale

- -

A locale package is registered with the line

- -
localepackagenamelocalenameuri/to/files/[flags]
-
- -

This will register a locale package when resolving the URI chrome://packagename /locale/... . Thelocalename is usually a plain language identifier "en" or a language-country identifier "en-US". If more than one locale is registered for a package, the chrome registry will select the best-fit locale using the user's preferences.

- -

skin

- -

A skin package is registered with the line

- -
skinpackagenameskinnameuri/to/files/[flags]
-
- -

This will register a skin package when resolving the URI chrome://packagename/skin/... . Theskinname is an opaque string identifying an installed skin. If more than one skin is registered for a package, the chrome registry will select the best-fit skin using the user's preferences.

- -

style

- -

Style overlays (custom CSS which will be applied to a chrome page) are registered with the following syntax:

- -
style chrome://URI-to-style chrome://stylesheet-URI[flags]
-
- -
Note that only stylesheets at chrome URIs can be applied in this way.
- -

override

- -

In some cases an extension or embedder may wish to override a chrome file provided by the application or XULRunner. In order to allow for this, the chrome registration manifest allows for "override" instructions:

- -
override chrome://package/type/original-uri.whatevernew-resolved-URI[flags]
-
- -

Note: overrides are not recursive (so overriding chrome://foo/content/bar/ with file:///home/john/blah/ will not usually do what you want or expect it to do).

- -
-

There is a currently a bug in the Firefox 2.0.0.* series, as well as previous builds, where if you use a relative URL for thenew-resolved-URI parameter, the override will not work. You need to provide a fully qualified URL (ie, one that is resolvable anywhere, not just in the directory the chrome manifest resides in). Given that the extension or application developer usually is unable to predict what the full path to such a file might be, currently one would normally only use this directive using another chrome:// URL as thenew-resolved-URI parameter. See {{ Bug(323455) }}.

-
- -

resource

- -

{{ Fx_minversion_inline(3) }}

- -

When using JavaScript code modules it may be necessary to create resource protocol aliases so extensions and applications can load modules using Components.utils.import. Aliases can be created using the resource instruction:

- -
resourcealiasnameuri/to/files/[flags]
-
- -

This will create an mapping for the res://<aliasname>/ to the path given.

- -
-

Note that there are no security restrictions preventing web content from including content at resource uris so take care with what you make visible there.

-
- -

Manifest Flags

- -

Manifest lines can have multiple, space-delimited flags added at the end of the registration line. These flags mark special attributes of chrome in that package, or limit the conditions under which the line is used.

- -

application

- -

Extensions may install into multiple applications. There may be chrome registration lines which only apply to one particular application. The flag

- -
application=app-ID
-
- -

indicates that the instruction should only be applied if the extension is installed into the application identified byapp-ID is running. Multiple application flags may be included on a single line, in which case the line is applied if any of the flags match.

- -

appversion

- -

Extensions may install into multiple versions of an application. There may be chrome registration lines which only apply to a particular application version. The flag

- -
appversion=version
-appversion<version
-appversion<=version
-appversion>version
-appversion>=version
-
- -

indicates that the instruction should only be applied if the extension is installed into the application version identified. Multiple appversion flags may be included on a single line, in which case the line is applied if any of the flags match. The version string must conform to the Toolkit version format.

- -
-

Versions of Gecko before 1.8.0.13 and 1.8.1.5 contained a bug where if you use the comparisons <, > or = then the version string had be 2 characters or more long. If not you would get a message in the error console that the appversion flag was not recognized. See {{ Bug(380398) }}.

-
- -

contentaccessible

- -

{{ Fx_minversion_inline(3) }} Untrusted content is no longer allowed to reference resources in chrome packages. If this needs to be explicitly allowed, set the contentaccessible flag to yes for behavior as found in older versions.

- -

The contentaccessible flag applies only to content packages: it is not recognized for locale or skin registration. However, the matching locale and skin packages will also be exposed to content. Changed for Firefox 3 RC 1 for {{ bug(292789) }}.

- -

os

- -

{{ Fx_minversion_inline(3) }} Extensions (or themes) may offer different features depending on the operating system on which Firefox is running. The value is compared to the value of OS_TARGET for the platform.

- -
os=WINNT
-os=Darwin
-
- -

See OS_TARGET for a more complete list of os names. The os name is case insensitive.

- -

osversion

- -

{{ Fx_minversion_inline(3) }} An extension or theme may need to operate differently depending on which version of an operating system is running. For example, a theme may wish to adopt a different look on Mac OS X 10.5 than 10.4:

- -
osversion>=10.5
-
- -

platform (Platform-specific packages)

- -

Some packages are marked with a special flag indicating that they are platform specific. Some parts of content, skin, locales may be different based on the platform being run. These packages contain three different sets of files, for Windows and OS/2, Macintosh, and Unix-like platforms. For example, the order of the "OK" and "Cancel" buttons in a dialog is different, as well as the names of some items.

- -

The "platform" modifier is only parsed for content registration, it is not recognized for locale or skin registration. However it applies to content, locale, and skin parts of the package, when specified.

- -

To indicate that a package is platform-specific, add the "platform" modifier to the "content" line after the path, for example:

- -
content global-platform jar:toolkit.jar!/toolkit/content/global-platform/ platform
-
- -

Once that is specified in your manifest you then ensure that under the directory global-platform are subdirectories win (Windows/OS2), mac (OS9/OSX), or unix (Everything Else). Anything residing outside of these subdirectories will be ignored.

- -

xpcnativewrappers

- -

Chrome packages can decide whether to use the xpcnativewrappers security mechanism to protect their code against malicious content that they might access. See Safely accessing content DOM from chrome for details.

- -

As of Firefox 1.5 alpha releases (Deer Park alphas), this flag is *off* by default, and must be explicitly enabled by specifying xpcnativewrappers=yes.

- -

As of the first Firefox 1.5 beta release, this flag will be enabled by default, and extensions that need insecure access to the content objects will be required to specify xpcnativewrappers=no.

- -

The xpcnativewrappers flag applies only to content packages: it is not recognized for locale or skin registration.

- -

 

- -

Example Chrome Manifest

- -
content       necko                   jar:comm.jar!/content/necko/ xpcnativewrappers=yes
-locale	       necko       en-US       jar:en-US.jar!/locale/en-US/necko/
-content       xbl-marquee             jar:comm.jar!/content/xbl-marquee/
-content       pipnss                  jar:pipnss.jar!/content/pipnss/
-locale        pipnss      en-US       jar:en-US.jar!/locale/en-US/pipnss/
-# Firefox-only
-overlay chrome://browser/content/pageInfo.xul           chrome://pippki/content/PageInfoOverlay.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
-overlay chrome://communicator/content/pref/preftree.xul chrome://pippki/content/PrefOverlay.xul
-overlay chrome://navigator/content/pageInfo.xul         chrome://pippki/content/PageInfoOverlay.xul application=seamonkey@applications.mozilla.org
-content       pippki                  jar:pippki.jar!/content/pippki/ xpcnativewrappers=yes
-locale        pippki      en-US       jar:en-US.jar!/locale/en-US/pippki/
-content       global-platform         jar:toolkit.jar!/content/global-platform/ platform
-skin          global      classic/1.0 jar:classic.jar!/skin/classic/global/
-override chrome://global/content/netError.xhtml jar:embedder.jar!/global/content/netError.xhtml
-content       inspector               jar:inspector.jar!/content/inspector/ xpcnativewrappers=no
-
- -

Debugging a Chrome Manifest file

- -

The Chrome List extension shows all registered chrome. This is very helpful when trying to write a chrome.manifest file as you can inspect where the files are being mapped from (jar files, local directory, etc.)

- -

Old-style contents.rdf manifests

- -

Before the plaintext manifests were introduced (which happened in Firefox 1.5, Toolkit 1.8), RDF manifests named "contents.rdf" were used to register chrome. This format is deprecated; however, the Mozilla Suite (SeaMonkey) does not support the plaintext manifest format yet, so contents.rdf manifests are required for extensions that wish to maintain backwards compatibility with Firefox 1.0 or the suite.

- -

Official References for Toolkit API

- -

{{ page("zh-CN/docs/Toolkit_API/Official_References") }}

diff --git a/files/zh-cn/mozilla/command_line_options/index.html b/files/zh-cn/mozilla/command_line_options/index.html deleted file mode 100644 index 347a35bdb1..0000000000 --- a/files/zh-cn/mozilla/command_line_options/index.html +++ /dev/null @@ -1,407 +0,0 @@ ---- -title: 命令行选项 -slug: Mozilla/Command_Line_Options -translation_of: Mozilla/Command_Line_Options ---- -

命令行选项用于为 Mozilla 应用程序指定各种启动选项。例如,您可以使用命令行配置选项来绕过配置档管理器并打开一个特定的配置档(如果您有多个配置档)。您也可以控制 Mozilla 应用程序如何打开,初始打开哪个组件以及当组件打开时要做什么。这个页面描述常用的选项和如何使用它们。

- -

语法规则

- -

首先,让我们描述一下适用于所有选项的语法规则。

- - - -

使用命令行选项

- -

命令行选项在启动应用程序的命令后输入。某些选项选项有参数。它们在命令行选项后输入。某些选项有缩写替代。例如,命令行选项 "-editor" 可以缩写为 "-edit"。(其中可用的缩写将会在下面的文本中阐述) 在某些情况下,选项参数必须用引号括起。(这会在以下的选项描述中注明。) 可以指定多个命令行选项。通常,语法如下:

- -
应用程序 -选项 -选项 "参数" -选项 参数
-
- -

示例

- -

下列示例显示 "-ProfileManager" 命令的使用,它将会在启动 Firefox 或 Thunderbird 前打开配置档管理器:

- -
Windows
- -

从 Windows 开始菜单中选择运行,输入:

- -
firefox -ProfileManager
-
- -
Mac OS X
- -

转到 Applications > Utilities,打开终端并输入:

- -
cd /Applications/Firefox.app/Contents/MacOS
-./firefox -ProfileManager
-
- -
Linux
- -

打开终端并输入:

- -
cd Thunderbird 安装目录
-./thunderbird -ProfileManager
-
- -

以上示例调用 "-ProfileManager" 命令行选项用于 Mozilla 的 Thunderbird 邮件客户端。

- -

用户配置档

- -

-CreateProfile profile_name

- -

创建一个名为profile_name 的配置档,而不启动程序。profile_name 一定不能包含空格( )。

- -
firefox -CreateProfile JoelUser
-
- -

-CreateProfile "profile_name profile_dir"

- -

在目录 profile_dir 中创建一个名为 profile_name 的配置档而不启动应用程序。注意 profile_nameprofile_dir 必须括在一起。(在 SeaMonkey1.x 中未有)

- -

注: profile_dir 必须存在而且您必须还未有称为 profile_name 的配置档。

- -
firefox -CreateProfile "JoelUser c:\internet\moz-profile"
-
- -

-ProfileManager

- -

使用配置档管理器启动。

- -

-SelectProfile

- -

使用配置档选择对话框启动。仅用于 SeaMonkey1.x

- -

-ProfileWizard

- -

使用配置档向导启动。仅用于 SeaMonkey1.x

- -

-P "profile_name"

- -

绕过配置档管理器并使用名为profile_name 的配置档启动。对于处理多个配置档很有用。注意profile_name 是区分大小写的。如果您未指定一个配置档名称,那么就会打开配置档管理器。在 L:inux 上,您必须使用大写字母 P,因为小写调用 Purify 模式(内存和泄露探测)。其它平台大小写都接受。

- -
firefox -P "Joel User"
-
- -

-profile "profile_path"

- -

使用给出路径的配置档启动。仅用于 FirefoxThunderbirdSeaMonkey2.x

- -

"profile_path" 可以是一个绝对路径("/path/to/profile") 或一个相对路径("path/to/profile").

- -
在 Mac OS X 上,从 Firefox 4.0 和以上,由于 regression 的原因,不在支持给出相对路径,查看{{ bug(673955) }}.
- -

-no-remote

- -

允许同一事件打开多个应用程序副本。(在 SeaMonkey1.x 中无效,它仅支持 MOZ_NO_REMOTE=1)。

- -
firefox -no-remote -P "另一个配置档"
-
- -

-migration

- -

使用导入向导启动。(SeaMonkey1.x 中无效)

- -

-installer

- -

使用 Netscape 4.x 迁移窗口启动。仅用于 SeaMonkey1.x

- -

-resetPref preference

- -

重置指定的首选项(逗号间隔)为默认值。仅用于 SeaMonkey1.x

- -
seamonkey -resetPref browser.startup.homepage
-
- -

-override /path/to/override.ini

- -

加载指定的 override.ini 文件以覆盖 application.ini ({{ Source("browser/app/application.ini") }})中的配置。通过加载下列 override.ini 可以抑制在启动时的迁移向导。仅用于 Firefox

- -
[XRE]
-EnableProfileMigrator=0
-
- -

浏览器

- -

-browser

- -

使用 browser(浏览器)组件启动。仅用于 FirefoxSeaMonkey

- -

-url URL

- -

根据浏览器选项,在新标签页或窗口中打开 URL-url 可以省略。仅用于 FirefoxSeaMonkey。注: 当打开多个 URLs 时,Firefox 总是把它们打开为一个新窗口中的选项页。

- -
firefox www.mozilla.com
-
- -

-private

- -

以私密浏览模式打开 Firefox,而不考虑当前的用户首选项。仅用于 Firefox 3.6 和以后版本。

- -

-new-tab URL

- -

在新标签页中打开 URL。仅用于 FirefoxSeaMonkey2.x

- -

-new-window URL

- -

在新窗口中打开 URL。仅用于 FirefoxSeaMonkey2.x

- -

-search term

- -

使用您的默认搜索引擎搜索 term。仅用于 FirefoxSeaMonkey2.x 及以后的版本。

- -

-preferences

- -

打开选项/首选项窗口。仅用于 FirefoxSeaMonkey2.x

- -

-setDefaultBrowser

- -

设置应用程序为默认的浏览器。仅用于 Firefox

- -

邮件/新闻

- -

-mail

- -

使用邮件客户端启动。仅用于 ThunderbirdSeaMonkey

- -

-mail mailto_URL

- -

为给出的 mailto_URL 启动撰写消息的窗口。仅用于 Thunderbird

- -
thunderbird -mail mailto:me@isp.net?subject=hi
-
- -

-news news_URL

- -

使用新客户端启动。如果给出了 news_URL (可选),则打开指定的新闻组。仅用于 ThunderbirdSeaMonkey

- -
thunderbird -news news://server/group
-
- -

-compose message_options

- -

使用邮件撰写器启动。查看语法规则。仅用于 ThunderbirdSeaMonkey

- -
thunderbird -compose "to=foo@nowhere.net"
-
- -

-addressbook

- -

使用地址簿启动。仅用于 ThunderbirdSeaMonkey

- -

-options

- -

打开选项/首选项窗口。仅用于 Thunderbird

- -

-offline

- -

以离线模式启动。仅用于 ThunderbirdSeaMonkey

- -

-setDefaultMail

- -

设置应用程序为默认的邮件客户端。仅用于 Thunderbird

- -

日历

- -

-calendar

- -

使用日历客户端启动。仅用于 Sunbird

- -

-subscribe URL-url URL

- -

订阅到给出的 URL。仅用于 Sunbird

- -

-showdate 日期

- -

显示给出的日期的您的计划安排。仅用于 Sunbird

- -
sunbird -showdate 08/04/2008
-
- -

其它组件

- -

-editor URL-edit URL

- -

为给出的 URL 使用编辑器(撰写器)启动(其中 URL 是可选的)。仅用于 SeaMonkey

- -
seamonkey -edit www.mozilla.org
-
- -

-jsconsole

- -

使用错误控制台启动应用程序.

- -

-inspector URL

- -

使用 DOM Inspector 启动(如果已安装的话),并观察给出的 URL (其中 URL 是可选的)。

- -

-venkman

- -

使用 JavaScript 调试器 Venkman 启动(如果已安装的话)。

- -

-chat

- -

使用 IRC 客户端 ChatZilla 启动(如果已安装的话)。

- -

XULRunner

- -

-app /path/to/application.ini

- -

启动一个新进程运行在指定路径 path/to 处的 XULRunner 应用程序。仅用于 Firefox 版本 3 和以上。

- -

Chrome

- -

-chrome chrome_URL

- -

加载指定的 chrome。

- -
firefox -chrome chrome://inspector/content
-
- -

-register chrome_URL

- -

注册指定的 chrome,而不启动应用程序。

- -

扩展附件

- -

{{ gecko_minversion_note("1.9.2", "-install-global-extension 和 -install-global-theme 已经从 Gecko 1.9.2 和以上的版本移除。") }}

- -

-install-global-extension /path/to/extension

- -

安装扩展到应用程序目录。参数是扩展的路径。您必须有管理权限。(在 SeaMonkey1.x 中无效,但是某些扩展已经把这个作为一个安装时的选项)。

- -

-install-global-theme /path/to/theme

- -

和上面类似,但是只用于主题。您必须有管理权限。(在 SeaMonkey1.x 中无效,但是某些扩展已经把这个作为一个安装时的选项)。

- -
-

从 Firefox 2.0.0.7 开始,-install-global-extension-install-global-theme 命令行参数选项的使用被限制为只允许安装在本地磁盘或映射的驱动器上的附加组件。从网络共享直接安装将不再成功。

-
- -

-safe-mode

- -

禁用所有的扩展启动应用程序,仅用于启动。(扩展不会加载,但是不会在扩展管理器数据源中永久禁用)。(在 SeaMonkey1.x 中无效)

- -

语种

- -

-UILocale locale

- -

locale 资源作为用户界面的语种。

- -
firefox -UILocale en-US
-
- -

启动

- -

-turbo

- -

Launch application in Quick Launch mode. SeaMonkey1.x only.

- -

-nosplash or -quiet

- -

Suppresses display of the splash screen. To show splash screen, use the -splash command. Note the splash screen is disabled by default on some systems. SeaMonkey1.x only.

- -

远程控制

- -

-remote 远程命令

- -

在一个已经运行的应用程序进程中执行远程命令(查看远程控制)。注: Unix/Linux 仅适用于 SeaMonkey1.x

- -
firefox -remote "openURL(www.mozilla.org, new-tab)"
-
- -

其它

- -

-silent

- -

不打开默认窗口。对于那些打开它们自己窗口但是未防止默认窗口打开的那些命令行参数很有用。仅适用于 FirefoxThunderbird3.xSeaMonkey2.x

- -

-console

- -

使用一个调试控制台启动应用程序。注:仅适用于 Windows。

- -

-h-help-?

- -

显示所有可用的命令行参数的列表。注意,在 Windows 上仅对调试构建版本({{ Bug(355889) }})有效。这个选项仅在命令行控制台中可用。

- -

-v-version

- -

打印应用程序版本。注意,在 Windows 上仅对调试构建版本({{ Bug(355889) }})有效。

- -

-osint

- -

告诉应用程序它是被 OS SHell 启动的。这个不应该指定,除非调用者在启动应用程序时,提供了 OS  Shell 的所有功能。({{ Bug(384384) }}).

- -

-requestPending

- -

Tells the application that there will be a Windows DDE request to open the same url specified on the command line. This should not be specified unless the caller provides all of the functionality provided by the OS shell when launching the application ({{ Bug(354005) }}).

- -

X11 options

- -

These options are only available for an application build for and running atop the X11/X.org display and window system to be found on Linux and other Unices.

- -
--display=DISPLAY
- -

设置要使用的 X display

- -
--sync
- -

使 X 调用同步

- -
--g-fatal-warnings
- -

使所有警告视为严重

- -

其它需要编写文档的选项

- - - -

参考

- - - -
-

原始文档信息

- - -
- -

{{ languages( { "ja": "ja/Command_Line_Options" } ) }}

diff --git a/files/zh-cn/mozilla/connect/index.html b/files/zh-cn/mozilla/connect/index.html deleted file mode 100644 index 7e75bb5c62..0000000000 --- a/files/zh-cn/mozilla/connect/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Mozilla 开发者计划 -slug: Mozilla/Connect -translation_of: Mozilla/Connect ---- -
-

采取行动、互相激励并共同协作,使网络成为创建跨联网设备体验的主要平台。

-
- -
-
-
- -
- -
- -
- -
- -
-
- -
-

联系Mozilla

- -

开发商为全世界的人们创造未来的建筑服务和应用程序。Mozilla开发者关系的目标是帮助开发人员使用开放标准的Web技术,成功实现自己的目标。除了文件在MDN,我们提供的帮助和其他资源来实现这一目标,通过各种渠道。我们邀请您来连接、学习和分享自己的知识。

- -

我们提供的帮助下通过Stack Overflow的Q&A解决你可能有的特定技术问题和挑战。我们也有一个简讯让您了解在Web场景周围的Web应用程序的最新动态和更多资讯。订阅 Apps & Hacks newsletter

- -

If you share Mozilla's mission and principles and want to help spread them to more developers, check out the ways you can get involved with technical evangelism, and join our evangelism discussion group.

- -

我们有很多计划和点子去反复扩展我们的开发者关系,我们希望你也参与我们!因此,在Stack Overflow上关注这个标签订阅这个Hacks博客,和订阅邮件

- -

Join Mozilla

- -

If you want to go beyond connecting with Mozilla, you can join Mozilla and help realize Mozilla's mission of building a better Internet. As a developer, you have skills to contribute in many areas, as well as the opportunity to enhance your skills. Mozilla is an open source project, so we "default to open." You can "view source" and contribute to our software development projects, like the Firefox browser for desktop and Android, Firefox OS, and Mozilla's websites. You can become part of an international community and get recognition for your efforts. Here are some of the advantages of contributing to the Mozilla project.

- -

Opportunity to learn something new

- -
-

In writing code for an open source project, you may face problems you have not encountered before, which present learning opportunities for you. You can try out new tools and techniques in an open source project. If for example, if you have never done unit testing, and cannot get permission to do so at work then coding for an open source project would be an excellent place to learn more about it. Contributing to open source gives you the opportunity to collaborate with and get to know many people around the world who have similar interests. Moreover, an open source organization like Mozilla has many contributors who can help you in solving problems you encounter. If you're just getting started contributing, you can look for "mentored" bugs, where an experienced contributor has offered to help a newcomer fix them.

- -

What can I get by contributing?

- -

Exploring many things and gaining recognition in the community -- these are the intangible benefits of contributing to Mozilla. While we can't guarantee specific tangible benefits, many valued contributors receive free Mozilla gear and invitations to Mozilla-related events, and are first in line to be considered for internships. Moreover, your experience in contributing to an open source project might help you find a job. More and more employers of developers are looking at open source contributions. They like to see that you're blogging and contributing to mailing lists, and they like to see you listed as a contributor to an open source project. It may also help with the work experience section of your CV/resumé.

- -

How you can contribute to Mozilla

- -

There are many project area for which you can contribute to Mozilla. You can find a current, complete list on the main Mozilla Get Involved page. Some areas that may interest you as a developer include:

- - -
-
-
- -
-
-

Stack Overflow 上的常见问题解答 查看所有问与答...

- -

在开发时我们有问与答去讨论挑战和问题,特别是Firefox OS和移动开放的互联网。在堆栈溢出上可用的简单URL http://stackoverflow.com/r/mozilla.

- -
- -

最新常见问题解答主题

-
- -
 
-
- -

Developers at a Firefox OS workshop in Madrid.

- -
- - - -
diff --git a/files/zh-cn/mozilla/debugging/existing_tools/index.html b/files/zh-cn/mozilla/debugging/existing_tools/index.html deleted file mode 100644 index 055f003c2b..0000000000 --- a/files/zh-cn/mozilla/debugging/existing_tools/index.html +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Existing Tools -slug: Mozilla/Debugging/Existing_Tools -translation_of: Mozilla/Debugging/Existing_Tools ---- -

下面列出的工具可以帮助你调试Firefox中因性能和内存引发的问题

-

SPS - Built-in profiler

-

profiler.png描述: Add-on that runs the built-in profiler, retrieves the data and parses it on a web service, displaying a call tree and a timeline with responsiveness measurements.
用处: Figuring out where time is being spent in the code / what is hanging Firefox
URL: geckoprofiler.xpi on GitHub
用法: After installing the add-on, click on the icon in the Add-ons bar (status bar) to open an widget with Start/Stop and Analyze buttons. More details at Profiling with the built-in profiler. The profiling build can be used to get accurate call stacks (currently Mac only).

-

 

-

about:jank

-

aboutjank.PNG描述: 运行内置的分析器并将检索到的数据显示在about:jank页面.
用处: 找出哪些代码在消耗时间,哪些代码让Firefox运行受阻.
URL: about:jank AMO下载
用法: 首次打开about:jank页面激活分析器,然后刷新页面查看分析的数据.

-

 

-

 

-

 

-

about:telemetry

-

aboutelemetry.png描述: 显示当前配置文件性能数据:直方图,缓慢的SQL语句和启动时间线.
用处: 获取当前配置文件性能数据.
URL: about:telemetry  AMO下载
用法: 确保选项"提交性能数据"已经开启 (选项 -> 高级 ->提交性能数据)然后打开about:telemetry.

-

 

-

 

-

about:startup

-

aboutstartup.PNG描述: 在about:startup页面显示Firefox的启动计时.
用处: 获取当前配置文件的启动性能信息.
URL: about:startup AMO下载
用法: 安装扩展后打开about:startup.

-

 

-

 

-

about:cc

-

aboutcc.PNG描述: Analyzes the cycle collection graphs and helps find leaks (specially documents) and missing CC optimizations.
用处: 找出内存泄漏的页面.
URL: about:cc bugzilla下载
用法: 安装该扩展,重启, 打开about:cc.首先点击Run Cycle Collector,然后点击 Find Documents.

about:ccdump

-

aboutccdump.png描述: More graphical interface to about:cc. Helps analyze cycle collection graphs and finding leaks
用处: 找出引起内存泄漏的死循环.
URL: about:ccdump  AMO下载
用法: 查看 Jan Odvarko's post 了解更多信息.

-

 

-

about:nosy

-

about-nosy-overview-scaled.png描述: 图形界面的jsprobes,帮助分析哪个标签最消耗资源.
用处: 查看各标签和扩展的内存以及cpu使用情况.
URL: about:nosy Github下载
用法: 查看 Andrew Sutherland's post获得更多详情. 注意: https://clicky.visophyte.org/files/labs/about-nosy/ 上已有的版本只适合Firefox "Aurora" 12的早期版本使用.

MemChaser

-

memchaser.png描述: 在附加组件栏(状态栏)显示GC/CC和内存使用等信息. 还可以切换内存报告记录.
用处: 在一个标准的浏览会话里跟踪记录垃圾回收和内存占用等信息
URL: MemChaser AMO下载
用法: 安装扩展并打开附加组建栏

-

MozRegression

-

描述: Python script that greatly helps you binary-search a regression bug through the nightly builds by automatically downloading and running each build with a fresh profile.
用处: Finding the nightly regression range for a bug that you're not sure when was introduced.
URL: MozRegression on GitHub
用法: First find a nightly build date that you're sure the problem exists, and one where you're sure it doesn't. Then run mozregression --good=yyyy-mm-dd --bad=yyyy-mm-dd and the script will guide you on finding the regression.

-

 

-

Layout painting flash

-

描述: 打开该选项后, Firefox中每次被重绘的元素都会以随机的背景颜色显示出来.
用处: 查找不必要的页面重绘失效问题
URL: 在about:config中将nglayout.debug.paint_flashing 设置为true
用法: 在about:config页面中配置, 更多信息请参考 这篇文章.

Logging GC/CC times

-

描述: 在错误控制台上显示GC/CC运行的时间.
用处: 查看垃圾回收/循环回收是否运行太长时间.
URL: 在about:config中将javascript.options.mem.log 设置为true
用法: 在about:config页面中配置, 打开错误控制台查看记录的信息.

-

{{ languages( { "en": "en/Debugging/Existing_Tools"} ) }}

diff --git a/files/zh-cn/mozilla/debugging/index.html b/files/zh-cn/mozilla/debugging/index.html deleted file mode 100644 index d3c90b5685..0000000000 --- a/files/zh-cn/mozilla/debugging/index.html +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: 调试 -slug: Mozilla/Debugging -translation_of: Mozilla/Debugging ---- -

Debugging a project as large as Mozilla can be a daunting task. Fortunately, over the years, Mozilla developers have come up with not just technologies and features to help you debug code, but have devised tips and techniques that can help too. Also available are assorted tools that you can use when debugging.

- - - - - - - -
-

Documentation topics

-

Debugging on top of the Mozilla platform

-
-
- Debugging JavaScript code
-
- How to debug JavaScript code, with a focus on debugging code in the Mozilla project itself.
-
- Debugging a XULRunner application
-
- Tips and suggestions that will help you debug your XULRunner based application.
-
- Debugging on Boot to Gecko
-
- Debugging Firefox OS (apps and the platform itself)
-
- Debugging update problems
-
- Learn how to debug update problems in Mozilla-based applications.
-
-

Debugging the Mozilla platform

-

Using debuggers with Mozilla

-
-
- Debugging Mozilla on Windows FAQ
-
- Questions (and answers) about debugging Mozilla on Windows.
-
- Debugging Mozilla on Mac OS X
-
- Questions (and answers) about debugging Mozilla on Mac OS X.
-
- Debugging Mozilla with gdb
-
- gdb is our primary debugger on Mac and Linux.
-
- Debugging Mozilla with lldb
-
- lldb is the new debugger on Mac.
-
-

Advanced debugging techniques

-
-
- Debugging Mozilla with valgrind
-
- valgrind is a memory debugger for Mac and Linux. It is slow, but good for tracking down difficult memory safety bugs.
-
- Replay debugging Firefox with VMWare Workstation
-
- How to setup record and replay debugging on Firefox, to help debug intermittent mochitest failures.
-
-

Debugging specific parts of the Mozilla codebase

-
-
- Debugging OpenGL {{gecko_minversion_inline("2.0")}}
-
- If you're working on code that involves OpenGL calls, and need to debug it, you can turn on a special OpenGL debugging mode.
-
- Debugging frame reflow and Debugging table reflow
-
- Notes on debugging issues in Gecko's layout engine.
-
-

Miscellaneous

-
-
- Debugging Safari
-
- Some tips for debugging Safari
-
- Debugging Chrome
-
- Some tips for debugging Chrome
-
- Debugging Internet Explorer
-
- Some tips for debugging Internet Explorer
-
-
-

Providing useful information to the Mozilla developers

-
-
- How to get a stacktrace for a bug report
-
- Useful information you can provide about a crash.
-
- Reporting a Performance Problem
-
- ...using the Gecko Profiler extension.
-
- Debugging a hang on Mac OS X
-
- Collecting "samples" to attach to a bug.
-
- Remote debugging
-
- Core dumps and examples of remote debugging. Useful if a developer can't reproduce your crash.
-
- HTTP logging
-
- How to log HTTP network traffic for debugging purposes.
-
-

Debugging tools

-
-
- Tools
-
- Assorted tools that will help you debug your code or web site.
-
- Download a debug build
-
- Recent automatically compiled debug builds are available. Note that these are replaced frequently by our tinderboxes. The debug builds have "-debug" at the end of their file names.
-
- -
-
- Performance and profiling
-
- Troubleshooting performance problems.
-
- Debugging memory leaks
-
- Learn about tools and techniques that will help you debug memory leaks.
-
-
-

 

diff --git a/files/zh-cn/mozilla/firefox/australis_add-on_compat/index.html b/files/zh-cn/mozilla/firefox/australis_add-on_compat/index.html deleted file mode 100644 index 0f0031c0f1..0000000000 --- a/files/zh-cn/mozilla/firefox/australis_add-on_compat/index.html +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: Australis and add-on compatibility -slug: Mozilla/Firefox/Australis_add-on_compat -tags: - - 扩展 -translation_of: Mozilla/Firefox/Australis_add-on_compat ---- -
{{FirefoxSidebar}}
- -

扩展程序的改变

- -

我们已经移除了扩展程序的工具栏(包括状态栏)。您不应再依赖它的存在。已有一个填隙片会尝试迁移您的图标,但它可能不起作用或只能部分起作用。 最好的解决方案是更改按钮的位置。 这也许是一个很好的时机去考虑您的扩展程序是否真的需要在默认情况下对所有用户可见的工具栏按钮。使用扩展程序SDK开发的扩展程序不需要注意这次改变。

- -

我们已经移除了应用(Firefox)菜单。 取而代之的是一个新的基于面板的菜单,可以用导航栏远端的一个按钮打开它。可以将工具栏项目拖进/拖出这个面板。

- -

一些默认的工具栏按钮ID已更改,我们添加了一些新的ID,并且后退/前进按钮,URL栏,停止/重新加载按钮的顺序将不再可自定义。这也意味着用户不能用常规的自定义流程在这些按钮中添加新的(扩展程序提供的)按钮。

- -

独立的暂停刷新按钮已被移除

- -

我们正在更改工具栏按钮的添加方式。 虽然我们尝试保持某种向后兼容性,但是以下的 the following are deprecated and will be removed in the near future: the toolbar.insertItem 方法, toolbar.currentSet 属性, and the currentset 属性 on toolbars. If possible, please stop relying on them. Instead, you should use the CustomizableUI module.

- -

CustomizableUI introduces a new API to insert, move and remove toolbar buttons and other toolbar items, as well as creating panels that are anchored to these toolbarbuttons. We believe this will be simpler and more powerful than the previous mix of APIs.

- -

Because of the new customization APIs, your toolbar buttons may not be direct children of a XUL <toolbar>; they might still be in a toolbar, or they might be in the "customization target" of a toolbar (a descendant node in a toolbar), or they might be in the new menu panel. The customization target of any toolbar (whether the target is a child node, or the toolbar itself) via toolbar.customizationTarget.

- -

Icon sizes in toolbars have changed, and you should ideally provide a larger icon for your add-on's buttons, should they exist, for use in the menu panel and customization area (palette). The new icon sizes are the same on all platforms and are:

- - - -

When in the customization area (palette), the button will be wrapped in a toolbarpaletteitem with a place attribute set to palette. Putting it all together, your updated CSS might look like this:

- -
#my-addon-button {
-    list-style-image: url(icon16.png);
-}
-#my-addon-button[cui-areatype="menu-panel"],
-toolbarpaletteitem[place="palette"] > #my-addon-button {
-    list-style-image: url(icon32.png);
-}
-
-/* High-resolution displays */
-@media (min-resolution: 2dppx) {
-    #my-addon-button {
-        list-style-image: url(icon32.png);
-    }
-    #my-addon-button[cui-areatype="menu-panel"],
-    toolbarpaletteitem[place="palette"] > #my-addon-button {
-        list-style-image: url(icon64.png);
-    }
-}
-
- -

Tab markup and styling have changed. If your add-on affects the tabstrip or provides alternative visualizations of the tabstrip, changes tab colors, or anything else related to the tabstrip, you may want to verify that it still works.

- -

The navigation toolbar is always visible (except in popup windows where a reduced navigation toolbar with the urlbar is visible) and can no longer be hidden e.g. for update pages or in-content UI. The related Add-on SDK module addon-page has been removed as it no longer has any effect.

- -

Items in the navigation toolbar can be overflowed if the browser window is made too small. Items in the toolbar will be moved into the new "overflow panel" when this occurs. The overflow panel is anchored to a button that appears in the navigation toolbar when one or more items are overflowed. If your item should never be overflowed, set an overflows attribute to false on the item. The urlbar-container is not overflowable by default, for example. Items that are overflowed have the overflowedItem attribute set to true.

- -

The menu panel uses a 3-column grid layout. Items should either fit in a single grid column (toolbarbuttons will be styled to do so automatically) or span the entire width of the panel if they wouldn't fit in a single grid column, e.g. for wide toolbaritems. In order to have the latter work correctly, you should use the panel-wide-item class on your toolbaritem.

- -

If your add-on provides a <toolbarbutton type="menu"/> or <toolbarbutton type="menu-button"/>, consider moving to a subview-based design, which will work much better in the menu panel. There's some documentation you can look at, as well as the implementation of the history widget.

- -

If your add-on provides a simple toolbarbutton then it should automatically be styled correctly in the menu panel, overflow panel and palette. If it provides a toolbaritem it is likely you will need to do additional work to make it look nice in places other than a toolbar.

- -

All items will have context menus allowing users to move the items between the palette, panel and the navigation toolbar. If your add-on uses the contextmenu itself, we will not override or change it (see this bug for a lengthy discussion as to why). You are requested, however, to update your menus yourself so that users do have the possibility of using these options even for your add-on's button.

- -

The class attribute on tab close buttons has been changed. Extensions shouldn't be relying on the class attribute value since it is a list of tokens and should instead look for the anonid attribute with value "close-button".

- -

The close-icon class now works cross-platform to provide a close icon with a default, hover, and active state. Previously, this wasn't available on Linux and the GTK close icon (gtk-close) was used instead.

- -

The BrowserToolboxCustomizeDone, BrowserToolboxCustomizeChange, and BrowserCustomizeToolbar global window functions have been removed. The customize events fired from the toolbox are now the preferred mechanism for hooking new logic into the customization feature.

- -

Add-on SDK Australis APIs

- -

If you're using the Add-on SDK, there are several new APIs for building your add-on's user interface in Australis. See the reference documentation. Also note that the widget module has been deprecated in favor of the new APIs.

- -

Changes for themes

- -

We've changed the tab markup. If you style these differently, you'll need to check whether it still works.

- -

We'll be drawing tabs in the titlebar and on top, on all platforms (currently implemented on Windows and OS X), except when not showing tabs at all (in popup windows).

- -

Support for small icons mode as well as text and icons mode have been removed.

- -

We've changed the default iconsets, and there are new icon sizes for the menupanel. If you're building on the default theme with new icons, you'll need to rearrange your icons in your Toolbar icon files. In both this case and if you supply a complete theme, you will also need to provide icons for the menu panel. The new icon sizes are the same on all platforms and are:

- - - -

We've removed the add-on bar, but have a shim in place to migrate icons to other places. Any styles pertaining to should be removed so as not to disturb the migration work.

- -

We've changed a few toolbarbutton IDs, such as those for the bookmark and history buttons. We also added new ones.

- -

The application (Firefox) menu has been removed.

- -

The back, forward, stop and refresh buttons will no longer be movable. They will always remain in their current position next to the urlbar. Your CSS rules can probably be simplified now that this is the case.

- -

The navigation toolbar can no longer be hidden e.g. for update pages or in-content UI.
-  

- - - - - -

See Also

- - diff --git a/files/zh-cn/mozilla/firefox/developer_edition/index.html b/files/zh-cn/mozilla/firefox/developer_edition/index.html deleted file mode 100644 index 8764178a14..0000000000 --- a/files/zh-cn/mozilla/firefox/developer_edition/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: 开发者版本 -slug: Mozilla/Firefox/Developer_Edition -translation_of: Mozilla/Firefox/Developer_Edition ---- -
{{FirefoxSidebar}}

- -

一个为网页开发者量身定制的 Firefox。

- -

下载 Firefox 开发者版本

- -
-
-
-

最新的 Firefox 特性

- -

Firefox 开发者版本会在 Firefox 发布流程中取代 Aurora 通道。像 Aurora 通道一样, 每 6 周新特性当它们在 Nightly 版本中稳定后,会登录到开发者版本中。

- -

通过使用开发者版本,你将会比常规发布的 Firefox 提前至少 12 周体验到新的工具以及平台特性。

- -

来看看开发者版本中有什么新的内容

-
- -
-

实验性开发工具

- -

我们还包含了一系列没有足够测试的实验性工具。

- -

例如,开发者版本包含了 Firefox Tools Adapter,它可以帮你将 Firefox 开发工具 连接到其他平台的浏览器上,像 Android 上的 Chrome 以及 iOS 上的 Safari。

-
-
- -
-
-

单独的配置文件

- -

Firefox 开发版有自己一套单独的配置文件,这就意味着它不会影响你电脑里已经安装了的稳定版或者 Beta 版的 Firefox。

-
- -
-

专为网页开发者而设

- -

我们为网页开发者提供了量身的默认设置。例如,默认开启了 Chrome 以及远程调试功能。

-
-
- -
-
-

一个独特的主题

- -

这将让你更迅速地进入开发工具中。

-
- -
 
-
- -

 

diff --git a/files/zh-cn/mozilla/firefox/enterprise_deployment/index.html b/files/zh-cn/mozilla/firefox/enterprise_deployment/index.html deleted file mode 100644 index 13d68ed3ce..0000000000 --- a/files/zh-cn/mozilla/firefox/enterprise_deployment/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: 将火狐部署到企业环境下 -slug: Mozilla/Firefox/Enterprise_deployment -tags: - - 发布 企业环境 火狐 管理员手册 -translation_of: Mozilla/Firefox/Enterprise_deployment_before_60 ---- -
{{FirefoxSidebar}}

本页将为您介绍在企业配置环境下针对Mac OS X、Windows系统中火狐管理的整个流程。如您遇有不清楚的地方,请发送邮件至enterprise@mozilla.org

- -

选择一个火狐的版本

- -

 

- -

快速发布版(RR)

- -

火狐发布的每一个更新都会将主版本号增加,每6周便会发布新功能、Bug修复信息,如有必要,更新中也会加入额外的安全更新信息。当主版本更新后,Mozilla将不再提供上一版本的Bug修复。

- -

具体更新发布计划请关注Mozilla wiki的版本更新日程表中的”发布日程”。

- -

稳定版 (ESR)

- -

火狐每隔7个主版本都会释出一个稳定版的发布内容。这些稳定发布的版本会将54周(9个“六周”一次的更新周期)以来一系列的bug进行修复。这两个版本中都会共同包含第12周(两个发布版本周期)的ESR更新内容。

- -

到目前为止,扩展支持发布版本的版本号有10、17、24和31。

- -

绝大多数企业以及组织机构更倾向与选择ESR版本,主要是因为稳定版发布间隔较长,以让各企业用户有充裕的时间对兼容性进行考核(ESR为42周,而RR则仅为6周),一旦在测试期间发现问题,用户也将拥有12周时间建立解决方案(每12周ESR版本会有重复发布)。

- -

需要注意的是,如果您先使用RR后转为ESR较旧的版本时,将可能受到一些不利因素的影响。即便假设您此前使用的26RR版本火狐,和现改用24.2ESR版本发布于统一天,不同版本差异也会产生不利的因素。这是因为新功能仅会在RR版本发布前加入快速发布版进行评测,但由于一些原因Mozilla决定待功能到某一特定版本后才触发使用,在这之前都会在用户配置文件重将对应功能关闭。一旦您选择了旧版本火狐,用户文档保存的将是最后一次保存的文件,其中即可能设定新功能为启用的状态,进而导致在ESR版中功能失效。如果您执意要从RR过度到ESR版本,您需要等到最新的ESR发布版本释出后再这样做。

- -

安装

- -
    -
  1. http://www.mozilla.org/firefox/all/ (RR)或 https://www.mozilla.org/firefox/organizations/all.html (ESR)处获取发布版本安装包,单击“下载”按钮获取软件包或下载器;
  2. -
  3. 根据您选择的安装模式进行安装,命令行下静默安装的参数为 -ms;
  4. -
  5. 您也可以额外指定一个INI文件用以指定建立快捷方式等维护服务;具体请参照命令行安装参数章节中的相关内容.
  6. -
- -

设置

- -
    -
  1. 找到火狐的程序主文件夹,(Win7 64位操作系统默认安装位置是 C:\Program Files (x86)\Mozilla Firefox; OSX 10.8 则是默认安装在 /Applications/Firefox.app/Contents/MacOS。下文提到的这些子文件夹都在此程序主文件夹下;
  2. -
  3. 在defaults/pref子文件夹中新建一个Javascript文件 autoconfig.js 或者别的名字,但是建议您还是选用英文字母组合命名文件。该文件将告诉火狐查询对应的配置信息(具体请参考 自定义火狐的默认选项文件章节重的相关内容),您需要至少写入以下两行:
  4. -
  5. -
    pref("general.config.filename", "mozilla.cfg");
    -pref("general.config.obscure_value", 0);
    -
  6. -
  7. 新建.cfg文件,一般命名为mozilla.cfg,同样的它的文件名也可以用其它名字。它用于匹配识别general.config.filename的内容。将第一个语句跳过或注释掉后便可设置您的选项。具体都有哪些选项,您可参考about:config中的内容写入、或者您也可以参考后面的示例配置选项内容。任何about:config选项都可以通过以下函数之一进行设置: -
    -
     
    -
    pref
    -
    此选项可设置每次打开浏览器都按照此配置内容指定用户使用习惯。因此,即便用户在使用过程中可以随意更改偏好,但每次重新启动浏览器,用户之前的配置都将被抹消。如果您需要此方面的相关设置,请在about:config中查找“user set”。
    -
    defaultPref
    -
    此选项可用于修改默认值,但用户通常可以将其更改并将修改内容保存到用户会话中。如果用户偏好被重置,重置的内容将变为此设定值。此项目在about:config的“default”中。
    -
    lockPref
    -
    此选项可用于锁定指定项目,以防止用户在使用过程中通过界面或about:config对指定的配置选项进行修改。 通常锁定项的表现方式是变灰或移除选项内容。在about:config中则显示为“locked”。有一些选项必须通过lockPref设置比如app.update.enabled。如果只用pref设置该内容,该设置无效。
    -
    clearPref
    -
    此选项可以将某些指定的内容“放空”。此选项可以便于跳过某些网站的浏览器版本号检查功能。
    -
    -
  8. -
- -

相关内容请您参考自定义火狐的自动配置文件以及继续自定义火狐的自动配置文件中的内容。如果您是倾向于零UI操作的狂热者,您可能需要用到CCK2这个扩展。

- -

配置文件示例

- -

如果您倾向于配置“极为复杂的用户偏好”,就请跳过这里。自火狐31版发布起,以下示例为您展示了常用的设置选项示例。如果您有某些指定的配置需求,请自行查询知识库中的信息。

- -
//关闭更新器
-lockPref("app.update.enabled", false);
-//确认更新起已经绝对关闭
-lockPref("app.update.auto", false);
-lockPref("app.update.mode", 0);
-lockPref("app.update.service.enabled", false);
-
-//取消插件兼容性检查
-clearPref("extensions.lastAppVersion");
-
-//第一次运行火狐时不再提示“了解您的权益”
-pref("browser.rights.3.shown", true);
-
-//每次更新后不再显示更新发布注记
-pref("browser.startup.homepage_override.mstone","ignore");
-
-//修改主页地址(用户可改)
-defaultPref("browser.startup.homepage", "http://home.example.com");
-
-//关闭浏览器内默认的PDF阅读器
-pref("pdfjs.disabled", true);
-
-//关闭flash、js转换
-pref("shumway.disabled", true);
-
-//不再提示安装flash插件
-pref("plugins.notifyMissingFlash", false);
-
-//关闭插件提示
-lockPref("plugins.hide_infobar_for_outdated_plugin", true);
-clearPref("plugins.update.url");
-
-//关闭健康诊断报告
-lockPref("datareporting.healthreport.service.enabled", false);
-
-// Disable all data upload (Telemetry and FHR)
-lockPref("datareporting.policy.dataSubmissionEnabled", false);
-
-//关闭崩溃报告
-lockPref("toolkit.crashreporter.enabled", false);
-Components.classes["@mozilla.org/toolkit/crash-reporter;1"].getService(Components.interfaces.nsICrashReporter).submitReports = false; 
-
- -

扩展包

- -
    -
  1. 安装扩展,通过about:support找到该拓展对应的GUID;
  2. -
  3. 找到用户配置文件目录 (如win7的是:%APPDATA%\Mozilla\Firefox\Profiles , 在about:support中单击显示文件夹,然后在“扩展”下找到你需要的插件。插件文件可能是单独的xpi文件,或者是一个包含多个文件的目录。
  4. -
  5. 确定如何发布此扩展。最简单的方式是将xpi直接拽到程序主文件夹/distribution/extensions目录下,但是这仅限于用户配置文件已记录该插件的安装情况。您另外还可以手动打开火狐重新安装。具体请参考让插件与火狐合二为一的相关章节。
  6. -
- -

Also keep in mind: Add-on scopes redux/

- -

随时变化

- -

目录结构的变化

- -

到目前为止,火狐的目录结构已经变更过两次。如果您需要使用21版本以前的火狐,请注意以下的变化:

- - - -

自动配置general.config.filenamegeneral.config.obscure_value可以在defaults/pref中完成,但文件名应该以英文字母‘a’开头,比如“autoconfig.js”

- -

如果您的版本defaults/pref与插件设置相悖,您可以尝试将目录结构改为和新版一样。

- -

ESR 24.x的变化(有Adobe PDF支持)

- -

火狐RR19.x起将PDF查看器嵌入到自己内部来, 即便您已经将火狐配置了其它PDF视图软件,但嵌入支持直到24.x版本以后才开始启用。而内容类型描述也与Adobe文档的PDF文件不同,若要取消此功能,请您将前面示例中的pdfjs.disabled改为true即可。

diff --git a/files/zh-cn/mozilla/firefox/headless_mode/index.html b/files/zh-cn/mozilla/firefox/headless_mode/index.html deleted file mode 100644 index 855339e6d1..0000000000 --- a/files/zh-cn/mozilla/firefox/headless_mode/index.html +++ /dev/null @@ -1,270 +0,0 @@ ---- -title: Headless mode -slug: Mozilla/Firefox/Headless_mode -translation_of: Mozilla/Firefox/Headless_mode ---- -
{{FirefoxSidebar}}
- -

Headless模式是运行Firefox的一种非常有用的方式。就像听起来一样,Firefox正常运行,但没有任何可见UI组件。虽然不太适合浏览网页,但它对自动化测试非常有用。本文提供了有关运行 headless Firefox 的所有知识。

- -

Using headless mode

- -

This section provide usage instructions for headless mode.

- -

Basic usage

- -

You can run Firefox in headless mode from the command line, by including the -headless flag. For example:

- -
/path/to/firefox -headless
- -

Taking screenshots

- -

Since Firefox 57, the -screenshot flag allows you to take screenshots of websites. The basic usage:

- -
/path/to/firefox -headless -screenshot https://developer.mozilla.com
- -

This creates a full-height screenshot of https://developer.mozilla.com, in the active directory called screenshot.png, with a viewport width of 800px.

- -

You can omit -headless when using -screenshot, as it is implied:

- -
/path/to/firefox -screenshot https://developer.mozilla.com
- -

To override the default values, mentioned above, you can use the following flags/features:

- - - -

For example, the following command creates a screenshot of https://developer.mozilla.com, in the active directory called test.jpg, with a viewport width of 800px, and a height of 1000px:

- -
/path/to/firefox -screenshot test.jpg  https://developer.mozilla.com --window-size=800,1000
- -

Browser support

- -

Headless Firefox works on Fx55+ on Linux, and 56+ on Windows/Mac.

- -

Automated testing with headless mode

- -

The most useful way to use headless Firefox, is to run automated tests. You can make your testing process much more efficient.

- -

Selenium in Node.js

- -

Here we'll create a Selenium test, using Node.js and the selenium-webdriver package. For this guide, we'll assume that you already have basic familiarity with Selenium, Webdriver, and Node, and you already have a testing environment created. If now, work through our Setting up Selenium in Node guide, and return when you have.

- -

First, confirm you've installed Node and the selenium-webdriver on your system. Then create a new file, called selenium-test.js, and follow the steps below to populate it with test code.

- -
-

Note: Alternatively, you could clone our headless-examples repo. This also includes a package file, so you can just use npm install to install necessary dependencies.

-
- -
    -
  1. -

    Let's add some code. Inside this file, start by importing the main selenium-webdriver module, and the firefox submodule:

    - -
    var webdriver = require('selenium-webdriver'),
    -    By = webdriver.By,
    -    until = webdriver.until;
    -
    -var firefox = require('selenium-webdriver/firefox');
    -
  2. -
  3. -

    Next, we create a new binary object representing Firefox Nightly, and add the -headless argument, so it will run in headless mode:

    - -
    var binary = new firefox.Binary(firefox.Channel.NIGHTLY);
    -binary.addArguments("-headless");
    -
  4. -
  5. -

    Now let's create a new driver instance for Firefox, using setFirefoxOptions() to include an options object, which specifies that we want to run the test using the above binary. This step will be unnecessary on Linux, and after headless mode lands in the release channel on Windows/Mac, but it is still useful if you want to test Nightly-specific features:

    - -
    var driver = new webdriver.Builder()
    -    .forBrowser('firefox')
    -    .setFirefoxOptions(new firefox.Options().setBinary(binary))
    -    .build();
    - -

    Alternatively, you can use options to set the binary and the headless arguments:

    - -
    var firefoxOptions = new firefox.Options();
    -firefoxOptions.setBinary('/path/to/binary');
    -firefoxOptions.headless();
    -
    -const driver = new webdriver.Builder()
    -   .forBrowser('firefox')
    -   .setFirefoxOptions(firefoxOptions)
    -   .build();
    -
    -
  6. -
  7. -

    Finally, add the following code, which performs a simple test on the Google search homepage:

    - -
    driver.get('https://www.google.com');
    -driver.findElement(By.name('q')).sendKeys('webdriver');
    -
    -driver.sleep(1000).then(function() {
    -  driver.findElement(By.name('q')).sendKeys(webdriver.Key.TAB);
    -});
    -
    -driver.findElement(By.name('btnK')).click();
    -
    -driver.sleep(2000).then(function() {
    -  driver.getTitle().then(function(title) {
    -    if(title === 'webdriver - Google Search') {
    -      console.log('Test passed');
    -    } else {
    -      console.log('Test failed');
    -    }
    -  });
    -});
    -
    -driver.quit();
    -
  8. -
  9. -

    Finally, run your test with following command:

    - -
    node selenium-test
    -
  10. -
- -

That's it! After a few seconds, you should see the message "Test passed" returned in the console.

- -

Headless Firefox in Node.js with selenium-webdriver, by Myk Melez, contains additional useful tips and tricks for running Node.js Selenium tests with headless mode.

- -

Selenium in Java

- -
-

Note: Thanks a lot to nicholasdipiazza for writing these instructions!

-
- -

This guide assumes you already have Geckodriver on your machine, as explained in  Setting up Selenium in Node, and an IDE set up which supports Gradle projects.

- -
    -
  1. -

    Download our headlessfirefox-gradle.zip archive (see the source here). Extract it, and import the headlessfirefox folder into your IDE, as a gradle project.

    -
  2. -
  3. -

    Edit the build.gradle file, to set selenium to a later version, if needed. At the time of writing, we used 3.5.3.

    - -
    group 'com.mozilla'
    -version '1.0'
    -
    -apply plugin: 'java'
    -
    -sourceCompatibility = 1.8
    -
    -repositories {
    -   mavenCentral()
    -}
    -
    -dependencies {
    -   compile('org.seleniumhq.selenium:selenium-api:3.5.3')
    -   compile('org.seleniumhq.selenium:selenium-remote-driver:3.5.3')
    -   compile('org.seleniumhq.selenium:selenium-server:3.5.3')
    -
    -   testCompile group: 'junit', name: 'junit', version: '4.12'
    -}
    -
  4. -
  5. -

    Edit the webdriver.gecko.driver property, in the HeadlessFirefoxSeleniumExample.java file, to equal the path where you installed geckodriver (see line 15 below).

    - -
    package com.mozilla.example;
    -
    -import org.openqa.selenium.By;
    -import org.openqa.selenium.WebElement;
    -import org.openqa.selenium.firefox.FirefoxBinary;
    -import org.openqa.selenium.firefox.FirefoxDriver;
    -import org.openqa.selenium.firefox.FirefoxOptions;
    -
    -import java.util.concurrent.TimeUnit;
    -
    -public class HeadlessFirefoxSeleniumExample {
    - public static void main(String [] args) {
    -   FirefoxBinary firefoxBinary = new FirefoxBinary();
    -   firefoxBinary.addCommandLineOptions("--headless");
    -   System.setProperty("webdriver.gecko.driver", "/opt/geckodriver");
    -   FirefoxOptions firefoxOptions = new FirefoxOptions();
    -   firefoxOptions.setBinary(firefoxBinary);
    -   FirefoxDriver driver = new FirefoxDriver(firefoxOptions);
    -   try {
    -     driver.get("http://www.google.com");
    -     driver.manage().timeouts().implicitlyWait(4,
    -         TimeUnit.SECONDS);
    -     WebElement queryBox = driver.findElement(By.name("q"));
    -     queryBox.sendKeys("headless firefox");
    -     WebElement searchBtn = driver.findElement(By.name("btnK"));
    -     searchBtn.click();
    -     WebElement iresDiv = driver.findElement(By.id("ires"));
    -     iresDiv.findElements(By.tagName("a")).get(0).click();
    -     System.out.println(driver.getPageSource());
    -   } finally {
    -     driver.quit();
    -   }
    - }
    -}
    -
  6. -
  7. -

    Run the java class, and you should see the HTML content of this page printed in your console/terminal.

    -
  8. -
- -

Selenium in Python

- -

This guide assumes you already have geckodriver on your machine, as explained in Setting up Selenium in Node.

- -
    -
  1. -

    Install the latest version of the Python client for Selenium.

    -
  2. -
  3. -

    Edit the following, to set the executable_path on line 11, to the path where you installed geckodriver:

    - -
    from selenium.webdriver import Firefox
    -from selenium.webdriver.common.by import By
    -from selenium.webdriver.common.keys import Keys
    -from selenium.webdriver.firefox.options import Options
    -from selenium.webdriver.support import expected_conditions as expected
    -from selenium.webdriver.support.wait import WebDriverWait
    -
    -if __name__ == "__main__":
    -    options = Options()
    -    options.add_argument('-headless')
    -    driver = Firefox(executable_path='geckodriver', firefox_options=options)
    -    wait = WebDriverWait(driver, timeout=10)
    -    driver.get('http://www.google.com')
    -    wait.until(expected.visibility_of_element_located((By.NAME, 'q'))).send_keys('headless firefox' + Keys.ENTER)
    -    wait.until(expected.visibility_of_element_located((By.CSS_SELECTOR, '#ires a'))).click()
    -    print(driver.page_source)
    -    driver.quit()
    -
  4. -
  5. -

    Run the Python script, and you should see the HTML content of this page printed in your console/terminal.

    -
  6. -
- -

Other testing solutions

- - - -

In addition, you can use headless Firefox to run automated tests written in most other popular testing apps, as long as you are able to set environment variables.

- -

Troubleshooting and further help

- -

If you are having trouble getting headless mode to work, then do not worry — we are here to help. This section is designed to be added to as more questions arise, and answers are found.

- - - -

If you want to ask the engineers a question, the best place to go is the #headless channel on Mozilla IRC. If you are pretty sure you've found a bug, file it on Mozilla Bugzilla.

- -

See also

- - diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/cross_process_object_wrappers/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/cross_process_object_wrappers/index.html deleted file mode 100644 index 38fde2acbf..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/cross_process_object_wrappers/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: 跨进程对象包装器 -slug: Mozilla/Firefox/Multiprocess_Firefox/Cross_Process_Object_Wrappers -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Cross_Process_Object_Wrappers ---- -
{{FirefoxSidebar}}
-

本文档介绍了 Cross Process Object Wrappers (CPOWs),这使 chrome 代码能够同步访问多进程 Firefox 中的内容。

-
- -

在多进程 Firefox 中,chrome 代码运行在与 Web 内容不同的另一个进程中。因此 chrome 代码不能直接与 Web 内容交互;相反,它必须考虑将与 Web 内容交互的脚本放在单独的脚本中,这被称为框架脚本(frame scripts),也称帧脚本。

- -

Chrome 代码可以使用消息管理器加载框架脚本到内容进程,然后可以使用消息传递 API 与它们通信。有关于此的更多信息,详见 消息管理器 的使用文档。

- -

Chrome 到内容的通信必须是异步的。这是因为 chrome 进程运行着 Firefox UI,因此如果被内容进程所影响,缓慢的内容进程可能致使 Firefox 对用户无响应。
-
- 将同步代码转换成异步可能是困难并且耗时的。作为一个迁移的辅助,消息框架使框架脚本变成了内容对象,通过一个被称为 Cross Process Object Wrapper(简称 CPOW)的包装器,使其在 chrome 中可用。但是,尽管 CPOWs 很方便,它们存在严重的局限性并且可能导致响应性问题,因此只应在必要时使用,并仅作为迁移的辅助。

- -

从框架脚本传递 CPOWs

- -

框架脚本可以发送消息到 chrome,使用两个全局函数之一:sendAsyncMessage() 或者 sendSyncMessage()。这些函数的第三个可选参数是被包装的属性对象。举例来说,框架脚本在用户点击它时发送一个 DOM 节点到 chrome,并将 clicked 属性作为第三个参数:

- -
// frame script
-addEventListener("click", function (event) {
-  sendAsyncMessage("my-e10s-extension-message", {}, { clicked : event.target });
-}, false);
- -

在 chrome 脚本中,DOM 节点现在是通过 Cross Process Object Wrapper 访问,作为该消息的 objects  属性的个属性。chrome 脚本可以获得和设置包装的对象属性,以及调用它的函数:

- -
// chrome script
-windowMM.addMessageListener("my-e10s-extension-message", handleMessage);
-
-function handleMessage(message) {
-  let wrapper = message.objects.clicked;
-  console.log(wrapper.innerHTML);
-  wrapper.innerHTML = "<h2>已被 chrome 修改!</h2>"
-  wrapper.setAttribute("align", "center");
-}
- -

自动生成的 CPOWs

- -

没有自我声明多进程兼容的附加组件会加载一些兼容性垫片。其中一个垫片提供了以下行为:每当 chrome 代码尝试直接访问内容(例如通过 window.content 或者 browser.contentDocument),提供一个包装了内容的 CPOW。这意味着下面这样的例子在多进程 Firefox 中也能正常工作。

- -
gBrowser.selectedBrowser.contentDocument.body.innerHTML = "被 chrome 代码替换";
- -

但仍然要记住,这是通过 CPOW 访问,并不是直接访问内容。

- -

双向 CPOWs

- -

一个常见的模式是 chrome 代码访问内容对象并添加事件监听器到那里。为了解决这个问题,CPOWs 是双向的。这意味着如果内容传递了一个 CPOW 到 chrome 进程,chrome 进程可以同步传递对象(如事件监听器函数)到 CPOW 中定义的函数。

- -

这意味着你可以写这样的代码:

- -
// frame script
-
-/*
-在 mouseover,发送 button 到 chrome 脚本,以一个CPOW形式。
-*/
-
-var button = content.document.getElementById("click-me");
-
-button.addEventListener("mouseover", function (event) {
-  sendAsyncMessage("my-addon-message", {}, { element : event.target });
-}, false);
- -
// chrome script
-
-/*
-载入框架脚本,然后监听消息。
-在我们得到消息时,提取 CPOW 并添加一个函数作为监听器到按钮的 "click" 事件。
-*/
-
-  browserMM.loadFrameScript("chrome://my-addon/content/frame-script.js", false);
-  browserMM.addMessageListener("my-addon-message", function(message) {
-    let wrapper = message.objects.element;
-    wrapper.addEventListener("click", function() {
-      console.log("被点击了");
-    });
-  });
-
- -

映射内容文档到 XUL 浏览器

- -

一个常见的模式是获取 XUL <browser>,它对应一个内容文档。要做到这点, gBrowser.getBrowserForDocument  和 gBrowser.getBrowserForContentWindow 分别可以传递一个内容文档和内容窗口的 CPOW,并且返回这些文档 / 窗口所属的 XUL  <browser>。如果没有找到这样的浏览器,两者都是返回 null。

- -

CPOWs 的限制

- -

尽管 CPOWs 可以方便的使用,但它有几个主要的局限性,在下面列出。

- -

CPOWs 与平台 API

- -

你不能传递 CPOWs 到预期会收到 DOM 对象的平台 API。举例来说,你不能传递一个 CPOW  nsIFocusManager.setFocus()

- -

Chrome 响应性

- -

在 chrome 这边缺少同步 API 是有意的:因为 chrome 进程运行着 Firefox UI,任何响应性问题都将影响整个浏览器。在制成 chrome 进程与内容进程的过程中,CPOWs 打破了这个原则,并且致使内容进程可能使整个浏览器陷入无响应状态。

- -

性能

- -

尽管包装器看起来像是一个完全在 chrome 脚本范围下管控的对象,但它实际上只是一个到内容进程中一个对象的引用。在你访问一个包装器的属性时,它发送一个同步消息到内容进程及返回结果。这意味着它比使用一个对象慢很多倍。

- -

消息顺序

- -

CPOWs 可能违反你做出的有关消息排序的假设。考虑以下代码:

- -
mm.addMessageListener("GotLoadEvent", function (msg) {
-  mm.sendAsyncMessage("ChangeDocumentURI", {newURI: "hello.com"});
-  let uri = msg.objects.document.documentURI;
-  dump("收到加载事件: " + uri + "\n");
-});
-
- -

这发送了一个消息,要求框架脚本更改当前文档的 URI,然后通过一个 CPOW 访问当前的文档 URI。你可能预期 uri 的值得到设置的 "hello.com"。但这不一定:为了避免死锁,CPOW 消息可以绕过正常的消息并且被优先处理。对 documentURI 属性的请求有可能在 "ChangeDocumentURI" 的消息之前被处理,并因而 uri 持有它在更改之前的值。
-
- 出于这个原因,最好不要混用 CPOWs 和正常的消息管理器消息。还有一个坏主意是将 CPOWs 用于任何安全相关,因为你可能获得不一致的结果,与使用消息管理器的相关代码。

diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/debugging_frame_scripts/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/debugging_frame_scripts/index.html deleted file mode 100644 index 57c1b3412a..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/debugging_frame_scripts/index.html +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: 调试框架脚本 -slug: Mozilla/Firefox/Multiprocess_Firefox/Debugging_frame_scripts -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Debugging_frame_scripts ---- -
{{FirefoxSidebar}}
-

浏览器内容工具箱仅在 Firefox Nightly 中可用,并且仅在多进程模式下可用。

-
- -

你可以使用浏览器内容工具箱来调试框架脚本。浏览器内容工具箱是一个单独的窗口,它包括一些共享的 Firefox 开发者工具,具体来说:控制台JavaScript 调试器,以及代码草稿纸 —— 但它们着重于浏览器的内容进程。这意味着你可以调试你的附加组件中的框架脚本。

- -

打开浏览器内容工具箱

- -

{{EmbedYouTube("Cg6X_zIu7Xk")}}

- -

要打开浏览器内容工具箱,你需要:

- - - -

你应该已经在 Firefox 菜单中 ”Web 开发者“的子菜单中看到”浏览器内容工具箱“(或者工具菜单,如果你显示了菜单栏,或者在 OS X)。它会打开一个单独的窗口:

- -

If you've used the Firefox Developer Tools before, this should look pretty familiar.

- -

Along the top is a row of tabs that you can use to switch the active tool. Currently we only support the Console, the Debugger, and Scratchpad in the Browser Content Toolbox. At the right of this row are three buttons that activate the split console, open settings, and close the toolbox.

- -

The rest of the toolbox is taken up with the tool you've currently selected.

- -

使用

- -

{{EmbedYouTube("XF0ULNnNOxg")}}

- -

调试器

- -

The Debugger lists all the scripts that are loaded into the content process. You'll find your frame scripts listed under the chrome:// URL you registered for them:

- -

You can set breakpoints, of course, and do all the other things supported by the debugger.

- -

控制台

- -

The Console logs output from your frame scripts. If you want to use it to evaluate JavaScript in your frame script's scope, there's a trick you need to know:

- - - -

Now the console's scope is your frame script's scope, and you can interact directly with it:

- -

diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/faq/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/faq/index.html deleted file mode 100644 index 3299dd0856..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/faq/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: FAQ -slug: Mozilla/Firefox/Multiprocess_Firefox/FAQ -translation_of: Mozilla/Firefox/Multiprocess_Firefox/FAQ ---- -
{{FirefoxSidebar}}

使命

- -

 

- -

历史

- -

 

- -

方式

- -

 

- -

影响

diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/index.html deleted file mode 100644 index 2936128948..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: 多进程 Firefox -slug: Mozilla/Firefox/Multiprocess_Firefox -tags: - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Firefox/Multiprocess_Firefox ---- -
{{FirefoxSidebar}}

在目前版本的桌面版 Firefox 中,整个浏览器运行在单个操作系统进程中。尤其是 JavaScript 在同一进程中运行着用户界面(UI,也称 "chrome 代码"),它还搭载着所有网页(也称“内容”,即“标签页”)。
-
- 未来版本的 Firefox 将在单独的进程中运行浏览器界面,与网页内容的进程分离。这种架构的第一次迭代是所有浏览器标签页在同一个进程中运行,浏览器界面运行在另一个进程中。在未来的迭代中,我们期望有一个以上的内容进程。提供多进程 Firefox 的项目名为 Electrolysis,有时被简称为 e10s。

- -

普通的网页不会受到多进程 Firefox 的影响。Firefox 本身和 Firefox 附加组件的开发者将受到影响,如果他们的代码依赖于能直接访问 Web 内容。

- -

不同于此前的直接访问内容,chrome JavaScript 将使用消息管理器来访问内容。为了帮助缓解过渡期,我们实现了跨进程对象包装器(CPOW)和一些面向附加组件开发者的兼容性垫片。如果你是一名附加组件开发者并且想知道自己是否受到影响,参见多进程 Firefox 工作指南

- -

多进程 Firefox 目前在 开发者版本 默认启用。

- -
-
-
-
-
技术概述
-
高等层面看待多进程 Firefox 如何被实现。
-
术语表
-
多进程 Firefox 领域相关的术语参考。
-
消息管理器
-
完整的指南,在 chrome 与内容之间通信的对象。
-
基于 SDK 的附加组件
-
如何迁移使用 Add-on SDK 开发的附加组件。
-
各类 URI 在哪里加载
-
各类 URI 的快速指南:chrome:, about:, file:, resource: - 在哪个进程被加载。
-
-
- -
-
-
动机
-
为什么我们要实现多进程的 Firefox:性能、安全和稳定性。
-
附加组件迁移指南
-
如果你是一名附加组件开发者,看看你的影响,以及如何更新你的代码。
-
跨进程对象包装器(CPOW)
-
Cross Process Object Wrappers 是一个迁移辅助,使 chrome 代码能够访问内容。
-
调试内容进程
-
如何调试运行在内容进程中的代码,包括框架和进程脚本。
-
多进程 Firefox 中的标签选择
-
多进程 Firefox 中如何切换标签页。
-
-
-
- -
-
-
-
-
chrome 脚本的限制
-
哪些 chrome 代码的做法将不再有效,以及如何解决。
-
-
- -
-
-
框架脚本的限制
-
哪些框架脚本的做法将不再有效,以及如何代替。
-
-
-
- -
-

联系我们

- -

有关此项目的更多信息、参与或提问。

- - diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/limitations_of_chrome_scripts/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/limitations_of_chrome_scripts/index.html deleted file mode 100644 index 130ce276e3..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/limitations_of_chrome_scripts/index.html +++ /dev/null @@ -1,197 +0,0 @@ ---- -title: chrome 脚本的限制 -slug: Mozilla/Firefox/Multiprocess_Firefox/Limitations_of_chrome_scripts -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Limitations_of_chrome_scripts ---- -
{{FirefoxSidebar}}

This page describes patterns that used to work in the chrome process that will no longer work in multiprocess Firefox. These are the sorts of things that will break an old add-on in multiprocess Firefox. The fix is generally some variant of "do that in a frame script loaded into the content process".

- -

This is one of a pair of articles: the other one lists limitations of frame scripts.

- -

兼容性垫片

- -

For many of the patterns described here we've implemented compatibility shims so the patterns still work. For example: whenever extensions try to access web content from the chrome process, the browser will return a Cross Process Object Wrapper that gives the chrome code synchronous access to the content.

- -

You'll get the shims for your add-on by default, unless you set the multiprocessCompatible flag in your add-on's install manifest.

- -

However, these shims are not a substitute for migrating extensions:

- - - -

For each pattern we've noted:

- - - -

gBrowser.contentWindow, window.content...

- -

如果没有垫片

- -

所有在 chrome 进程中的 API 提供的直接访问内容对象将不再工作。例如:

- -
// chrome code
-
-gBrowser.contentWindow;                    // null
-
-gBrowser.contentDocument;                  // null
-
-gBrowser.selectedBrowser.contentWindow;    // null
-
-window.content;                            // null
-
-content;                                   // null
-
- -

特别说明,docshells 存在于内容进程,因此它们也无法访问:

- -
gBrowser.docShell;                         // null
-
-gBrowser.selectedBrowser.docShell;         // null
- -

如果有垫片

- -

在这些情况下,垫片为你通过一个 CPOW 提供内容对象。

- -

In some situations, the content process may not be initialized when an add-on asks for access to its content. In this case, the shim will return a JavaScript object that looks somewhat like a window or a document for about:blank. However, this "dummy" object is completely static and only exposes a few of the normal properties that windows and documents have. For this reason, add-ons that try to access content objects in fresh <browser> elements may run into trouble.

- -

To make the shim unnecessary: factor the code that needs to access content into a separate script, load that script into the content process as a frame script, and communicate between the chrome script and the frame script using the message-passing APIs. See the article on using the message manager.

- -

CPOW 的限制

- -

跨进程对象包装器 (CPOWs) 是一个迁移辅助,给 chrome 代码带来同步访问内容对象的能力。但是,在使用它时也有各种限制

- -

nsIContentPolicy

- -

如果没有垫片

- -

在多进程的 Firefox 上,你无法在 chrome  进程中使用 nsIContentPolicy,因为它需要接触网络内容。

- -

如果有垫片

- -

The shim enables you to add content policies in the chrome process. It transparently registers an nsIContentPolicy in the content process, whose shouldLoad just forwards to the chrome process. The content to check is forwarded as a CPOW. The chrome process then checks the content against the policy supplied by the add-on, and forwards the response back to the child to be enforced.

- -

为了使垫片不再必要,在内容进程中定义和注册 nsIContentPolicy。如果你需要确保该政策只注册一次,使用一个 process 脚本 来注册该政策。

- -

nsIWebProgressListener

- -

这个 API 在 chrome 进程中工作。有一个垫片让你可以访问传递到 onStateChange nsIWebProgress  对象的 DOMWindow 属性。但是,该 DOMWindow 是异步传递,因此在 chrome 进程收到时,DOM 可能已经改变了(例如,因为代码运行的内容进程已经修改它,或者我们已经导航到另一个页面)。

- -

还要注意,不同于其他垫片,这个垫片始终有效。

- -

我们正在努力修复此问题,见 bug 1118880

- -

另外,你可以在内容进程中使用 nsIWebProgressListener

- -

chrome 进程中的 Observers

- -

根据不同的主题,你需要在 chrome 进程或者一个框架脚本中注册 observers。

- -

对于大多数主题,你需要在 chrome 进程中注册 observers。

- -

但是,你必须在一个框架脚本中监听 content-document-global-created and document-element-inserted。这些主题的 Observers 获取内容对象并作为 aSubject 参数到 observe(),因此通知不会发送到 chrome 进程。

- -

有一个垫片会将两个主题转发到 chrome 进程,将 CPOWs 发送为 aSubject 参数。

- -

HTTP 请求

- -

你不能观测(observe)内容进程中的 HTTP 请求。如果这样做,你将得到一个错误。
-
- 如果你在 chrome 进程中这样做,它一般会工作。observer 通知的主题将是一个 nsIHttpChannel,正如你所期望的。

- -

A common pattern here is to use the notificationCallbacks property of the nsIHttpChannel to get the DOM window that initiated the load, like this:

- -
observe: function (subject, topic, data) {
-  if (topic == "http-on-modify-request") {
-    var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
-    var domWindow = httpChannel.notificationCallbacks.getInterface(Ci.nsIDOMWindow);
-  }
-}
- -

或者这样:

- -
observe: function (subject, topic, data) {
-  if (topic == "http-on-modify-request") {
-    var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
-    var domWindow = httpChannel.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
-  }
-}
- -

In multiprocess Firefox these patterns will no longer work: the getInterface call will fail.

- -

In multiprocess Firefox, notificationCallbacks is a special object that tries to emulate the single-process notificationsCallbacks object as best it can. It will return a dummy nsILoadContext when asked, but any attempt to get a window out of it will fail.
-
- There is an outstanding bug (bug 1108827) to implement a shim here that will make notificationCallbacks a CPOW for the objects in the content process.

- -

The correct way to access the DOM window is through a message manager. In an HTTP observer, you can get the browser message manager for the window using code like this:

- -
observe: function (subject, topic, data) {
-  if (topic == "http-on-modify-request") {
-    var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
-    var loadContext = httpChannel.notificationCallbacks.getInterface(Ci.nsILoadContext);
-    // topFrameElement is the <browser> element
-    var topFrameElement = loadContext.topFrameElement;
-    var browserMM = topFrameElement.messageManager;
-    console.log("browserMM: " + browserMM);
-  }
-}
- -

However, before Firefox 38, this technique will not work if multiprocess Firefox is disabled: specifically, topFrameElement will be null. This means that if you need to write code that works before Firefox 38 and on both multiprocess and non-multiprocess variants, you need to implement both paths:

- - - -

From Firefox 38 onwards, the topFrameElement approach always works.

- -

DOM 事件

- -

如果没有垫片

- -

In multiprocess Firefox, if you want to register an event listener on some content DOM node, that needs to happen in the content process.

- -

It used to be that if you registered a listener on the XUL <browser>  or <tab> element that hosted some DOM content, then events in the content would bubble up to the XUL and you could handle them there. This no longer happens in multiprocess Firefox.

- -

如果有垫片

- -

The shim intercepts chrome process code that adds listeners to XUL elements and sets up listeners in the content process, relaying the result back to the chrome process. The Event object itself is relayed to the chrome process as a CPOW.

- -

To make the shim unnecessary: register event listeners on the global object inside a frame script. For example:

- -
addEventListener("load", handler, true) // for example
- -
如果你需要在这时联系 chrome 进程,发送一个消息。
- -
 
- -

沙盒

- -
You can create sandboxes in the chrome or the content process. Sandboxes are often used as a safe way to manipulate web content, and if that's your goal, create the sandbox in the content process.
- -
 
- -
There is a shim for sandboxes: if you make a sandbox in the chrome process and give it content principals (by passing a CPOW as the first argument to Components.utils.Sandbox) then we'll actually make it in the content process.
- -
 
- -
-

nsIAboutModule

- -

By default, custom about: pages registered using nsIAboutModule are loaded in the chrome process. This means that you can't access their content from the content process (via XHR, for example).

- -

你可以在你注册 about: URI 的代码中改变这个默认值。见 about: 和 chrome: URI

-
- -

JavaScript 代码模块 (JSM)

- -
在单进程的 Firefox 中,你可以使用 JavaScript 代码模块 (JSM) 来维持全局状态。在多进程的 Firefox 中,一个加载到某个进程的 JSM 不与加载到另一个进程的同样 JSM 共享状态:因此你不能使用一个 JSM 在 chrome 和内容进程之间共享状态。
- -
 
- -
If an add-on wants to use a JSM to share state in this way, it's best to load the JSM in the chrome process, and have frame scripts store and access the JSM's state by sending messages to the chrome process using the message manager.
diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/limitations_of_frame_scripts/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/limitations_of_frame_scripts/index.html deleted file mode 100644 index d942067bd3..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/limitations_of_frame_scripts/index.html +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: 框架脚本的限制 -slug: Mozilla/Firefox/Multiprocess_Firefox/Limitations_of_frame_scripts -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Limitations_of_frame_scripts ---- -
{{FirefoxSidebar}}

框架脚本使用系统特权运行,并且能够访问 Components 对象,使它们能够使用 XPCOM 对象和 JSM。许多特权的 API 在内容进程中仍然工作。数据结构的处理仍将工作。XHR 和 Workers 仍将工作。但是,某些 API 在 chrome 进程中工作,但在框架脚本中将不工作。本文列出最重要的那些 API。

- -

这是一对文章之一,另一篇是:chrome 脚本的限制

- -

文件 I/O

- -

你不应该从内容脚本写入或者读取磁盘,特别是配置文件目录。即使这是可能的,你也不应该这样做,应该预期它可能在任何时间停止工作。文件 I/O 应该全部放在 chrome 进程完成。例如:

- - - -

XUL 和浏览器界面

- -

任何试图接触界面或者与 XUL 相关的东西都很可能在内容进程中不工作。例如:

- - - -

Services

- -

某些服务不能在框架脚本中工作。

- - - -

Chrome 窗口

- -

任何需要使用 chrome 窗口的东西都不能在内容进程中工作。例如:

- - - -

Places API

- -

Places API 不能在框架脚本中使用。例如:

- - - -

内容进程中的 Observers

- -

As noted in Observers in the chrome process, most observers should be registered in the chrome process and will not work in the content process. The exceptions are:

- - - -

这些必须在内容进程中注册。

- -

内容窗口到 chrome 窗口的 QI

- -
There's a particular pattern often used to get from a content window to the associated chrome window. It looks something like this:
- -
 
- -
window.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIWebNavigation)
-                         .QueryInterface(Ci.nsIDocShellTreeItem)
-                         .rootTreeItem
-                         .QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIDOMWindow);
- -
This will no longer work. In the content process the root tree item is an nsITabChild, that cannot be converted to an nsIDOMWindow, so the second getInterface call here will fail.
- -
 
- -

If you want a chrome window: send a message from the content process using the message manager. The target property of the object passed into the message handler in the chrome process is the XUL <browser> receiving the message, and you can get the chrome window from that (Note: I'm not really sure how...).

- -

nsIAboutModule

- -

默认情况下,使用 nsIAboutModule  注册的自定义的 about: 页面在 chrome 进程中加载。这意味着你不能从内容进程访问它们的内容(比如通过 XHR)。

- -

你可以在注册 about: URI 的代码中更改这个默认值。见 about: 和 chrome: URI

- -

JavaScript 代码模块 (JSM)

- -
在多进程的 Firefox 中,一个加载到内容进程的 JSM 不予加载到 chrome 进程的同一个 JSM 共享任何状态。参考 chrome 脚本的限制 页面中的内容。
diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/communicating_with_frame_scripts/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/communicating_with_frame_scripts/index.html deleted file mode 100644 index 9c8abfa1c9..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/communicating_with_frame_scripts/index.html +++ /dev/null @@ -1,205 +0,0 @@ ---- -title: 与框架脚本通信 -slug: >- - Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Communicating_with_frame_scripts -translation_of: >- - Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Communicating_with_frame_scripts ---- -
{{FirefoxSidebar}}

Chrome 的代码与框架脚本的往来通信采用消息 API,它可以包含可 JSON 序列化的对象作为参数。

- -

这个 API 大多是对称的,但有一个主要的例外:框架脚本可以发送同步或者异步消息到 chrome,但 chrome 只能发送异步消息到内容。这是一种有意的设计,是为了防止内容不响应而导致的 chrome 失去响应。
-
- 在绝对必要时,框架脚本可以通过被称为 跨进程对象包装器(也称 CPOWs)的东西到达 chrome,并且 chrome 可以使用这些包装器来获得到内容对象的同步访问。

- -

内容到 chrome

- -

框架脚本可以选择发送同步消息或者异步消息到 chrome 代码。

- -

异步消息

- -

要发送异步消息,内容脚本应使用 sendAsyncMessage() 函数:

- -
// frame script
-sendAsyncMessage("my-addon@me.org:my-e10s-extension-message");
- -

sendAsyncMessage() takes one mandatory parameter, which is the name of the message. All messages share the same namespace, so to avoid conflicts with other code, you'll need to ensure that the names you use are unique. If you're using the message manager in an add-on, a good way to do that is to prefix messages with your add-on's ID.

- -

After the name, you can pass detailed data as a string or a JSON-serializable object, and after that you can pass any objects it wants to pass to content as CPOWs.

- -

The example below sends a message named "my-e10s-extension-message", with a data payload containing details and tag properties, and exposes the event.target object as a CPOW:

- -
// frame script
-addEventListener("click", function (event) {
-  sendAsyncMessage("my-addon@me.org:my-e10s-extension-message", {
-    details : "they clicked",
-    tag : event.target.tagName
-  },
-  {
-     target : event.target
-  });
-}, false);
- -

要接收来自内容的消息,一个 chrome 脚本需要使用消息管理器的 addMessageListener() API 添加消息监听器:
-
- 传递给监听器的消息是一个对象,包含下列属性:

- - - - - - - - - - - - - - - - - - - - - - - - -
name字符串,包含消息的名称。
sync布尔值,表示消息是否为同步发送,或者是异步发送。
dataJSON 对象,作为传递给 sendAsyncMessage() 的第二个参数。
target这是 XUL 的 <browser> 元素,来自消息发送的位置。
objectsAn object whose properties are any CPOWs exposed by the sender as the third argument to sendAsyncMessage()
- -

在下面的例子中,监听器只是记录所有的消息细节;

- -
// chrome script
-messageManager.addMessageListener("my-addon@me.org:my-e10s-extension-message", listener);
-
-function listener(message) {
-  console.log(message.name);
-  console.log(message.sync);
-  console.log(message.data);
-  console.log(message.target);
-  console.log(message.objects);
-}
-
- -

So combining this message listener with the message above will give console output somewhat like this, when the user clicks a <div>:

- -
"my-addon@me.org:my-e10s-extension-message"
-false
-Object { details: "they clicked", tag: "div" }
-<xul:browser anonid="initialBrowser" ... >
-{ target: <div#searchContainer> }
-
- -

If your code requires access to a window (for example to run window.openDialog), and your message listener is run from somewhere without access to a window (e.g. an XPCOM component), you can access the window of the browser that sent the message with message.target.ownerDocument.defaultView.

- -

同步消息

- -

要发送一个同步消息,框架脚本应使用全局的 sendSyncMessage()  函数:

- -
// frame script
-sendSyncMessage("my-addon@me.org:my-e10s-extension-message");
- -

在一个 chrome 脚本收到一个同步消息时,它应该从它的消息监听器返回一个值:

- -
// chrome script
-messageManager.addMessageListener("my-addon@me.org:my-e10s-extension-message", listener);
-
-function listener(message) {
-  return "value from chrome";
-}
- -

This value is then presented to the frame script in the return value of sendSyncMessage(). Because a single message can be received by more than one listener, the return value of sendSyncMessage() is an array of all the values returned from every listener, even if it only contains a single value:

- -
// frame script
-addEventListener("click", function (event) {
-  var results = sendSyncMessage("my-addon@me.org:my-e10s-extension-message", {
-    details : "they clicked",
-    tag : event.target.tagName
-  });
-  content.console.log(results[0]);    // "value from chrome"
-}, false);
- -

Like arguments, return values from sendSyncMessage() must be JSON-serializable, so chrome can't return functions.

- -

removeMessageListener()

- -

要停止监听来自内容的消息,使用消息管理器的 removeMessageListener() 方法:

- -
// chrome script
-messageManager.removeMessageListener("my-addon@me.org:my-e10s-extension-message", listener);
- -

Chrome 到内容

- -

要从 chrome 发送一个消息到内容,你需要知道你正在使用什么类型的消息管理器。如果它是一个浏览器消息管理器,你可以使用消息管理器的 sendAsyncMessage  方法:

- -
// chrome script
-browser.messageManager.sendAsyncMessage("my-addon@me.org:message-from-chrome");
- -

如果你有一个窗口或者全局消息管理器,你需要使用 broadcastAsyncMessage 方法:

- -
// chrome script
-window.messageManager.broadcastAsyncMessage("my-addon@me.org:message-from-chrome");
- -

These methods takes one mandatory parameter, which is the message name. All messages share the same namespace, so to avoid conflicts with other code, you'll need to ensure that the names you use are unique. If you're using the message manager in an add-on, a good way to do that is to prefix messages with your add-on's ID.

- -

在消息名称后,你可以将详细的数据传递为一个字符串或者一个可 JSON 序列化的对象:

- -
// chrome script
-messageManager.sendAsyncMessage("my-addon@me.org:message-from-chrome", {
-  details : "some more details"
-});
- -

To receive a message from chrome, a frame script uses the global addMessageListener() function. This takes two parameters: the name of the message and a listener function. The listener will be passed a message object whose data property is the message payload:

- -
// frame script
-function handleMessageFromChrome(message) {
-  var payload = message.data.details;      // "some more details"
-}
-
-addMessageListener("my-addon@me.org:message-from-chrome", handleMessageFromChrome);
- -

message-manager-disconnect

- -

If you're using a message manager to communicate with a script that may be running in a different process, you can listen for the message-manager-disconnect observer notification to know when the message manager has disconnected from the other end of the conversation, so you can stop sending it messages or expecting to receive messages.

- -

For example, suppose we load a script into the current <browser> on some event, and keep the browser message manager in an array, so we can send it messages:

- -
var messageManagers = [];
-
-...
-
-// on some event
-var browserMM = gBrowser.selectedBrowser.messageManager;
-browserMM.loadFrameScript("chrome://my-addon@me.org/content/frame-script.js", false);
-messageManagers.push(browserMM);
-console.log(messageManagers.length);
- -

We can listen for message-manager-disconnect to update the array when the message managers disconnect (for example because the user closed the tab):

- -
function myObserver() {
-}
-
-myObserver.prototype = {
-  observe: function(subject, topic, data) {
-    var index = messageManagers.indexOf(subject);
-    if (index != -1) {
-      console.log("one of our message managers disconnected");
-      mms.splice(index, 1);
-    }
-  },
-  register: function() {
-    var observerService = Cc["@mozilla.org/observer-service;1"]
-                          .getService(Ci.nsIObserverService);
-    observerService.addObserver(this, "message-manager-disconnect", false);
-    console.log("listening");
-  },
-  unregister: function() {
-    var observerService = Cc["@mozilla.org/observer-service;1"]
-                            .getService(Ci.nsIObserverService);
-    observerService.removeObserver(this, "message-manager-disconnect");
-  }
-}
-
-var observer = new myObserver();
-observer.register();
diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/frame_script_environment/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/frame_script_environment/index.html deleted file mode 100644 index 8d5e9d287b..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/frame_script_environment/index.html +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: 框架脚本环境 -slug: Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Frame_script_environment -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Frame_script_environment ---- -
{{FirefoxSidebar}}

框架脚本的全局是 ContentFrameMessageManager,提供下列环境:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
contentThe DOM window of the content loaded in the browser. may be null (see below)
docShellThe nsIDocShell associated with the browser.
addEventListener()Listen to events from content.
removeEventListener()Stop listening to events from content.
addMessageListener()Listen to messages from chrome.
removeMessageListener()Stop listening to messages from chrome.
sendAsyncMessage()Send an asynchronous message to chrome.
sendSyncMessage()Send a synchronous message to chrome.
dump()Print a message to the console.
atob()Base64 decode.
btoa()Base64 encode.
ComponentsThe usual Components object.
- -

特别注意,框架脚本使用 content 访问 DOM 窗口,而不是 window

- -
// frame script
-var links = content.document.getElementsByTagName("a");
- -

All the frame scripts running in a tab share this global. However, any top-level variables defined by a script are not stored on the global: instead, top-level variables are stored in a special per-script object that delegates to the per-tab global. This means you don't have to worry about global variables you define conflicting with global variables defined by another frame script. You can still access the global directly via this.

- -

框架脚本使用系统主体运行。如果你想使用其他主题,可以使用 Sandbox

- -

Frame scripts run with system privileges and have access to the Components object, enabling them to use XPCOM objects and JSMs. However, some APIs  that work in the chrome process will not work in a frame script. See Limitations of frame scripts for more details.

- -

事件

- -

Besides the regular DOM events being captured/bubbling up from content the current content object the following additional events get fired in a frame script environment:

- - - - - - - - - - - - -
unload -
-
Bubbles
-
No
-
- -

Fires when the frame script environment is shut down, i.e. when a tab gets closed.

- -

If you use a capturing event listener on the ContentFrameMessageManager, you should verify that its event.target is set to the ContentFrameMessageManager global object in order to avoid handling unload events from content.

-
DOMWindowCreated -

Fires when a new content object is created.
-
- This can be used if a framescript needs to interact with individual DOM windows instead of simply listening for events bubbling up from content.
- Another use is to interact with the content very early in the page load process, long before DOMContentLoaded event is fired.
-  

-
- -

 

diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/frame_script_loading_and_lifetime/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/frame_script_loading_and_lifetime/index.html deleted file mode 100644 index ee53fe52e2..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/frame_script_loading_and_lifetime/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: 框架脚本的加载与寿命 -slug: >- - Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Frame_script_loading_and_lifetime -translation_of: >- - Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Frame_script_loading_and_lifetime ---- -
{{FirefoxSidebar}}

加载框架脚本

- -

要加载一个框架脚本,使用 loadFrameScript() 函数。

- -

这行代码加载一个框架脚本到当前选中的标签页。该框架脚本只是将 "foo" 写入到命令行:

- -
// chrome script
-var mm = gBrowser.selectedBrowser.messageManager;
-mm.loadFrameScript('data:,dump("foo\\n")', true);
- -

loadFrameScript() 有两个强制性参数:

- - - -

Note that if the message manager is a global frame message manager or a window message manager then loadFrameScript() may load the script multiple times, once into each applicable frame.

- -

chrome: URL

- -

扩展开发者通常会使用 chrome:// URL 来指向一个框架脚本。

- -

要定义 chrome:// URL 的映射和将一个框架脚本打包到扩展中,使用 "chrome.manifest" 文件来 注册一个chrome URL

- -
// chrome.manifest
-content my-e10s-extension content.js
- -
// chrome script
-mm.loadFrameScript("chrome://my-e10s-extension/content/content.js", true);
- -

allowDelayedLoad

- -

如果消息管理器是一个 全局框架消息管理器 或者一个 窗口消息管理器,那么:

- - - -

如果消息管理器是一个 浏览器消息管理器,你应该始终在这里传递 true。因为一个浏览器消息管理器永远只对应一个浏览器标签页,它的 loadFrameScript() 函数只加载框架脚本到一个标签页。因此传递 allowDelayedLoad 仅仅是一个方法来确保脚本被正确加载,在你的标签页在执行后还没有准备好时。

- -

如果你使用 allowDelayedLoad,你可以使用 removeDelayedFrameScript 取消它:

- -
var mm = window.messageManager;
-mm.removeDelayedFrameScript("chrome://my-e10s-extension/content/frame-script.js");
- -

这意味着我们将停止加载脚本到新的标签页。请注意,此函数不会移除已经加载的任何脚本。

- -

框架脚本的寿命

- -

框架脚本将在 loadFrameScript() 被调用后尽快加载。如果你设置了 allowDelayedLoad,脚本将加载到一个新的标签页,一旦其已被创建。

- -

框架脚本与浏览器的标签页相关联,而不是与页面。因此一旦你加载它们,它们就会持续存在,直至标签页被关闭,因此即便你重新加载或者文档重新导航也不会丢失。

- -

如果你想一个框架脚本在每次新文档被加载后执行操作,你需要监听一个适当的 DOM 事件,通常是 DOMWindowCreated, DOMContentLoaded,  或者 load

- -

卸载框架脚本

- -

框架脚本会在托管它们的标签页被关闭时自动卸载。目前还没有办法在已加载它们的标签页之中卸载它们,除了关闭标签页。

- -

若要监听你的框架脚本被卸载的事件(例如由于标签页被关闭),你必须将 addMessageListener 的第三个参数设置为 true,例如下面的 bootstrap.js 的代码:

- -
Services.mm.addMessageListener(
-    'my-addon-id',
-    {
-        receiveMessage: function() {
-            console.log('incoming message from frame script:', aMsg.data);
-        }
-    },
-    true // must set this argument to true, otherwise sending message from framescript will not work during and after the unload event on the ContentMessageManager triggers
-);
- -

and then in your frame script listen for the unload event of the message manager (which is the global this), and then send a message. If you did not set third argument to true in bootstrap.js on Services.mm.addMessageListener, then this send message during and after unload event, will do nothing.

- -
var gContentFrameMessageManager = this;
-
-addEventListener('unload', function(aEvent) {
-    if (aEvent.target == gContentFrameMessageManager) {
-        sendAsyncMessage('my-addon-id', 'framescript-died'); // if you did not set third argument of `Services.mm.addMessageListener` to `true`, then this will fail to send a message
-    }
-}, false);
- -

有关卸载/升级操作时的卸载

- -

在你的附加组件被卸载或禁用时,你应该:

- - - -
-
-

There is a bug in non-e10s where this oder is not true. In e10s framescripts work fine on updating. For non-e10s waiting for Bug 1202125 - framescripts are not backwards loaded in message order in non-e10s.

-
- -

Note: you might think that there is a race condition here due to the asynchronous nature of the message passing:

- - - -

In fact, the message manager guarantees that loadFrameScript and broadcastAsyncMessage are guaranteed to affect frame scripts in the order that they are called, so in this case "disable" will be received and consumed before the new frame scripts are loaded.

-
- -

At the moment frame scripts are cached until the browser restarts: this problem is tracked as bug 1051238. This is especially a problem for restartless add-ons, because when a new version of the add-on is installed, the old frame scripts will not be unloaded. The workaround here is to randomize the frame script's URL, for example by appending "?" + Math.random() to it.

diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/index.html deleted file mode 100644 index be6ba855c9..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: 消息管理器 -slug: Mozilla/Firefox/Multiprocess_Firefox/Message_Manager -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Message_Manager ---- -
{{FirefoxSidebar}}

消息管理器为 chrome 特权的 JavaScript 代码提供了跨进程边界的通信方式。它非常有用,可以允许 chrome 代码(包括浏览器自身的代码和外部代码)访问在单独的进程中运行的网页内容。

- -

这些指南介绍了如何在多进程 Firefox 中使用消息管理器。

- -

请注意,多进程 Firefox 的环境并非是必须的:这里描述的一切对单进程 Firefox 也同样有效,所以相同的代码在两个环境下都可以正常工作。

- -
-

指南

- -
- - - -
- -
-

API 参考资料

- -
- - - -
diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/message_manager_overview/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/message_manager_overview/index.html deleted file mode 100644 index fb85fa5e79..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/message_manager_overview/index.html +++ /dev/null @@ -1,442 +0,0 @@ ---- -title: 消息管理器概述 -slug: Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Message_manager_overview -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Message_manager_overview ---- -
-

在多进程 Firefox 中有两个进程:

- - - -

消息管理器的设计目的是使运行在一个进程中的 chrome 特权的 JavaScript 代码能够与不同进程中的 chrome 特权的 JavaScript 代码通信。

- -

本文介绍了几种类型的消息管理器,如何访问它们,以及在一个较高层面你可以使用什么。

-
- -

在顶层,有两种不同类型的消息管理器:

- - - -

框架消息管理器

- -

在多进程 Firefox 中,当 chrome 代码需要与网页内容交互时,它需要:

- - - -
-

Some older articles on multiprocess Firefox and the message manager might refer to "content scripts" instead of "frame scripts", but this usage is deprecated because the Add-on SDK uses "content script" to refer to a similar but different kind of script.

-
- -

因此从根本上,框架消息管理器使 chrome 代码能够:

- - - -

有多种类型的框架消息管理器,如图所示:

- -

- -

This diagram shows the setup when there are 2 browser windows open, one with 2 tabs open and one with 1 tab open.

- -

Chrome 进程

- -

In the chrome process, there's a hierarchy of frame message managers: the global frame message manager, window message managers, and browser message managers.

- -

全局框架消息管理器

- - - - - - - - - - - - - - - - -
Description -

There's a single global frame message manager in the chrome process.

- -

This operates on all frames, in all content tabs. If you load a frame script using the global frame message manager, the script gets loaded separately into every open tab: three times, in the diagram above. Similarly, if you send a message using the global frame message manager, it's received by all content tabs, and is then delivered to any frame scripts that are listening for it.

- -

Its most important functions and attributes are:

- -

childCount : contains the number of children (typically, browser windows)

- -

getChildAt() : get the child at the given index

- -

loadFrameScript() : load a frame script into every tab in the browser

- -

broadcastAsyncMessage() : send a message to frame scripts

- -

addMessageListener() : start listening to a specific message from all frame scripts

- -

removeMessageListener() : stop listening to a specific message

-
Interfaces -

nsIFrameScriptLoader

- -

nsIMessageListenerManager

- -

nsIMessageBroadcaster

-
How to access -

Access it using Components.classes:

- -
-// chrome script
-let globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
-  .getService(Ci.nsIMessageListenerManager);
-
- -

窗口消息管理器

- - - - - - - - - - - - - - - - -
Description -

There's a window message manager for every browser window: two, in the diagram above.

- -

It operates on all content tabs in a given window. If you load a frame script using the window message manager it gets loaded separately into each tab open in that particular window. If you send a message using the window message manager, it gets sent to all content tabs in that window.

- -

Its most important functions and attributes are:

- -

childCount : contains the number of children (typically, browser tabs)

- -

getChildAt() : get the child at the given index

- -

loadFrameScript() : load a frame script into every tab in this window

- -

broadcastAsyncMessage() : send a message to all frame scripts in this window

- -

addMessageListener() : start listening to a specific message from frame scripts

- -

removeMessageListener() : stop listening to a specific message

-
Interfaces -

nsIFrameScriptLoader

- -

nsIMessageListenerManager

- -

nsIMessageBroadcaster

-
How to access -

You can access it as a property of the browser window:

- -
-// chrome script
-let windowMM = window.messageManager;
-
- -

浏览器消息管理器

- -
-

Note that in this context, "browser" refers to the XUL <browser> object, which is a frame that hosts a single Web document. It does not refer to the more general sense of a Web browser.

-
- - - - - - - - - - - - - - - - -
Description -

Finally, there's a browser message manager for every open content tab: three, in the diagram above.

- -

This corresponds one-to-one with a content tab. Scripts you load using a browser message manager are loaded only into that content tab, and messages you send are delivered only to that content tab.

- -

You can mix and match: so for example, you could load a script into every tab using the global message manager, but then send a message to the script instance loaded into a specific tab by using the browser message manager.

- -

Its most important functions are:

- -

loadFrameScript() : load a frame script into this browser frame (tab)

- -

sendAsyncMessage() : send a message to all frame scripts in this browser frame

- -

addMessageListener() : start listening to a specific message from frame scripts

- -

removeMessageListener() : stop listening to a specific message

-
Interfaces -

nsIProcessChecker

- -

nsIFrameScriptLoader

- -

nsIMessageListenerManager

- -

nsIMessageSender

-
How to access -

The browser message manager can be accessed as a property of the XUL <browser> element:

- -
-// chrome script
-let browserMM = gBrowser.selectedBrowser.messageManager;
-
- -

内容进程

- -

内容框架消息管理器

- - - - - - - - - - - - - - - - -
Description -

There's a content frame message manager for every open tab. It's the content-side end of frame message manager conversations.

- -

Frame scripts are loaded into the content frame message manager scope, and messages from chrome message managers end up here.

- -

The content frame message manager provides the global object for frame scripts (but note that there is trickery to ensure that top-level variables defined by frame scripts are not shared).

- -

Frame scripts can use this object to send messages to the chrome process, and to receive messages from the chrome process.

- -

Its most important attributes and functions are:

- -

content : access the DOM window hosted by the tab

- -

docShell : access the top-level docshell

- -

Components : access privileged objects and APIs

- -

addEventListener() : listen to DOM events

- -

addMessageListener() : receive messages from the chrome process

- -

sendAsyncMessage() : send asynchronous messages to the chrome process

- -

sendSyncMessage() : send synchronous messages to the chrome process

-
Interfaces -

nsIDOMEventTarget

- -

nsIMessageListenerManager

- -

nsIMessageSender

- -

nsISyncMessageSender

- -

nsIContentFrameMessageManager

-
How to accessThe content frame message manager is the global object in frame scripts.
- -

进程消息管理器

- -

Process message managers correspond to process boundaries, and enable code running in different processes to communicate. Multiprocess Firefox has the concept of:

- - - -

For practical purposes, in multiprocess Firefox the parent process is the chrome process, and child processes are content processes. 

- -

In each child process, there's a single child process message manager (CPMM). There's also an additional child-in-process message manager (CIPMM) in the parent process.

- -

For each child process message manager, there's a parent process message manager (PPMM) in the parent process.

- -

There's also a single global parent process message manager (GPPMM) in the parent process, that provides access to all the parent process message managers. The diagram below shows the setup that would result from having two child processes:

- -

- -

With the GPPMM, you can broadcast messages to the CIPMM and all CPMMs. With a PPMM, you can send a message to its corresponding CPMM. With a CPMM, you can send messages to the parent process: these messages are received first by the corresponding PPMM, then by the GPPMM.

- -

From Firefox 38 onwards, you can also use a parent process message manager to load a script into a child process. This is the recommended way to load a script that executes just once per child process, which is something you might want to do if you are interacting with some global service (for example, adding listeners to observer notifications or registering a content policy).

- -

父消息管理器

- -

全局父进程消息管理器

- - - - - - - - - - - - - - - - -
Description -

The global parent process message manager (GPPMM) is global to the parent process.

- -
    -
  • Messages sent using the GPPMM get sent to all CPMMs in all child processes.
  • -
  • Process scripts loaded using the GPPMM get loaded in all child processes.
  • -
- -

Its most important functions and attributes are:

- -

childCount : contains the number of children (child processes, plus the in-content child)

- -

getChildAt() : get the child at the given index

- -

loadProcessScript() : load a process script into every content process

- -

broadcastAsyncMessage() : send a message to all process scripts

- -

addMessageListener() : start listening to a specific message from process scripts

- -

removeMessageListener() : stop listening to a specific message

-
Interfaces -

nsIProcessScriptLoader

- -

nsIMessageListenerManager

- -

nsIMessageBroadcaster

-
How to access -

You can access the GPPMM with code like this:

- -
-// parent process
-let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-           .getService(Ci.nsIMessageBroadcaster);
- -

You can also access it as the ppmm property of Services.jsm, if you are in the parent process.

-
- -

父进程消息管理器

- - - - - - - - - - - - - - - - -
Description -

There's one parent process message manager (PPMM) in the parent process for every child process, and its API is oriented to that one child process.

- -
    -
  • Messages sent using the PPMM are received only by the corresponding CPMM
  • -
  • Scripts loaded using the PPMM are loaded only into the corresponding child process.
  • -
- -

Its most important functions are:

- -

loadProcessScript() : load a process script into the content process

- -

broadcastAsyncMessage() : send a message to process scripts

- -

addMessageListener() : start listening to a specific message from process scripts

- -

removeMessageListener() : stop listening to a specific message

-
Interfaces -

nsIProcessChecker

- -

nsIProcessScriptLoader

- -

nsIMessageListenerManager

- -

nsIMessageSender

-
How to access -

You can access a PPMM using the getChildAt() function in the GPPMM:

- -
-// parent process
-let ppmm = Services.ppmm.getChildAt(1);
-
- -

子进程

- -

子进程消息管理器

- - - - - - - - - - - - - - - - -
Description -

There's one child process message manager (CPMM) in each child process. Messages sent using the CPMM are sent to the corresponding PPMM and are also relayed to the GPPMM.

- -

Its most important attributes and functions are:

- -

Components : access privileged objects and APIs

- -

addMessageListener() : receive messages from the parent process

- -

sendAsyncMessage() : send asynchronous messages to the parent process

- -

sendSyncMessage() : send synchronous messages to the parent process

-
Interfaces -

nsIMessageListenerManager

- -

nsIMessageSender

- -

nsISyncMessageSender

- -

nsIContentProcessMessageManager

-
How to access -

Code running in a child process can access the CPMM with code like this:

- -
-// child process script
-let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-           .getService(Ci.nsISyncMessageSender);
- -

You can also access it as the cpmm property of Services.jsm, if you are in the child process.

-
diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/performance/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/performance/index.html deleted file mode 100644 index 3bcb04d88e..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/message_manager/performance/index.html +++ /dev/null @@ -1,292 +0,0 @@ ---- -title: 性能 -slug: Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Performance -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Message_Manager/Performance ---- -
{{FirefoxSidebar}}

着重讲几点框架脚本/消息管理器的使用方式和替代方法,以避免相关的性能缺陷。

- -

要牢记几点:

- - - -
-

下面的例子为了简洁,省略了一些样板代码

- -

“更好”的例子还省略了一些最佳实践。只是为了演示如何解决各子主题中描述的问题。

-
- -

性能的最佳实践

- -

每个进程中声明无状态函数

- -

不良:

- -
// addon.js
-Services.mm.loadFrameScript("framescript.js", true)
-
- -
// framescript.js
-
-const precomputedConstants = // ...
-
-function helper(window, action) {
-  // ...  do some work on the window
-}
-
-function doSomething(message) {
-  result = helper(content, message.data)
-  sendAsyncMessage("my-addon:response-from-child", {something: result})
-}
-
-addMessageListener("my-addon:request-from-parent", doSomething)
-
- -

 

- -

Why is this bad? Because declared functions are also objects. And since frame scripts get evaluated for each tab this means new function objects get instantiated, new constants get computed, block scopes must be set up etc.

- -

While it may seem fairly innocencous in this toy example, real scripts often have a lot more functions and initialize some fairly heavyweight objects.

- -

更好:

- -

addon.js 如上

- -
// framescript.js
-Components.utils.import("resource://my-addon/processModule.jsm", {}).addFrame(this)
-
- -
// processModule.jsm
-
-const EXPORTED_SYMBOLS = ['addFrame'];
-
-const precomputedConstants = // ...
-
-function helper(window, action) {
-  // ... do some work on the window
-}
-
-function doSomething(message) {
-  frameGlobal = message.target
-  result = helper(frameGlobal.content, message.data)
-  frameGlobal.sendAsyncMessage("my-addon:response-from-child", {something: result})
-}
-
-function addFrame(frameGlobal) {
-  frameGlobal.addMessageListener("my-addon:request-from-parent", doSomething)
-}
-
- -

Javascript modules are per-process singletons and thus all their objects are only initialized once, which makes them suitable for stateless callbacks.
-
- But care must be taken to not leak references to the frame script global when it is passed into a JSM. Alternatively the frame's unload event or weak maps can be used to ensure that frames can be cleaned up when their respective tab is closed.

- -

每个进程中存放重量级的状态

- -

不良:

- -
// addon.js
-var main = new MyAddonService();
-
-main.onChange(stateChange);
-
-function stateChange() {
-  Services.mm.broadcastAsyncMessage("my-addon:update-configuration", {newConfig: main.serialize()})
-}
-
- -
// framescript.js
-var mainCopy;
-
-function onUpdate(message) {
-   mainCopy = MyAddonService.deserialize(message.data.newConfig);
-}
-
-addMessageListener("my-addon:update-configuration", onUpdate)
-
-
-// mainCopy used by other functions
-
- -

The main issue here is that a separate object is kept for each tab. Not only does that increase memory footprint but the deserialization also has to be executed seperately for each tab, thus requiring more CPU time.

- -

不良:

- -
// addon.js
-var main = new MyAddonService();
-
-main.onChange(stateChange);
-
-function stateChange() {
-  Services.ppmm.broadcastAsyncMessage("my-addon:update-configuration", {newConfig: main.serialize()})
-}
- -
// processModule.jsm
-const EXPORTED_SYMBOLS = ['getMainCopy'];
-
-var mainCopy;
-
-Services.cpmm.addMessageListener("my-addon:update-configuration", function(message) {
-  mainCopy = message.data.newConfig;
-})
-
-funtion getMainCopy() {
-  return mainCopy;
-}
-
-
- -
// framescript.js
-Components.utils.import("resource://my-addon/processModule.jsm")
-
-// getMainCopy() used by other functions
-
- -

 

- -

不要在框架脚本中注册观察者(及其他到全局服务的回调)

- -

不良:

- -
//framescript.js
-Services.obs.addObserver("document-element-inserted", {
-  observe: function(doc, topic, data) {
-     if(doc.ownerGlobal.top != content)
-        return; // bail out if  this is for another tab
-     decorateDocument(doc);
-  }
-})
- -

Observer notifications get fired for events that happen anywhere in the browser, they are not scoped to the current tab. If each framescript registers a seperate listener then the observed action will trigger the callbacks in all tabs.

- -

Additionally the example above does not clean unregister itself, thus leaking objects each time a tab is closed. Frame message manager  message and event listeners are limited in their lifetime to that of the frame itself, this does not apply  to observer registrations.

- -

更好:

- -

     

- -
-
content-document-global-created 通知
-
可以用 DOMWindowCreated 事件取代
-
其他观察者和服务
-
应该在 进程脚本 中注册,或者用 JSM 代替
-
- -

 

- -

根据需要加载框架脚本

- -

不良:

- -
// addon.js
-Services.mm.loadFrameScript("framescript.js", /*delayed:*/ true)
-
-// stuff communicating with the framescript
-
- -
// framescript.js
-function onlyOnceInABlueMoon() {
-   // we only need this during a total solar eclipse while goat blood rains from the sky
-   sendAsyncMessage('my-addon:paragraph-count', {num: content.document.querySelectorAll('p').length})
-}
-addMessageListener("my-addon:request-from-parent", onlyOnceInABlueMoon)
-
- -

更好:

- -
// addon.js
-function onToolbarButton(event) {
-  let tabMM = gBrowser.mCurrentBrowser.frameLoader.messageManager;
-  let button = event.target;
-  let callback = (message) => {
-    tabMM.removeMessageListener("my-addon:paragraph-count", callback)
-    decorateButton(button, message.data.num)
-  }
-  tabMM.addMessageListener("my-addon:paragraph-count", callback);
-  tabMM.loadFrameScript("data:,sendAsyncMessage('my-addon:paragraph-count', {num: content.document.querySelectorAll('p').length})", false)
-}
-
-function decorateButton(button, count) {
-  // do stuff with result
-}
-
- -

This executes the script only when it is needed and only in one tab and allows it to be garbage-collected immediately after execution.  As long as it the action does not happen frequently the memory and startup savings should outstrip the added cost of script evaluation.

- -

Delaying the script registration until the session is restored my provide some middle ground for some addons. It does not provide the same memory footprint reductions but it improves application startup.

- -

 

- -

向下推进信息,避免到父进程的调用

- -

不良:

- -
// processscript.js
-
-function ContentPolicy() {
-  // ...
-}
-
-Object.assign(ContentyPolicy.prototype, {
-    classDescription: ..., classID: ..., contractID: ...,
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy]),
-
-    shouldLoad: function(type, location, origin, context) {
-
-       let resultList = Services.cpmm.sendSyncMessage("my-addon:check-load", {destination: location, source: origin}) // <=== SYNC MESSAGE!
-
-       if(resultList.every((r) => r == true))
-           return Ci.nsIContentPolicy.ACCEPT;
-
-       return Ci.nsIContentPolicy.REJECT_REQUEST;
-    }
-});
-
-// more boilerplate code here
-
- -

This example is a (somewhat condensed) content policy which gets triggered for every network request in a child process to either allow or deny the request. Since the code calls to the parent process to check whether a specific request can be allowed it would slow down all page loads, as web pages generally issue dozens of requests.

- -

更好:

- -

Instead of only keeping the state in the parent an addon can employ a master-slave architecture where the parent has the authoritative state and replicates it to the child processes in advance so they can act based on their local copy.

- -

See the previous chapter on how to efficiently replicate addon state to each process.

- -

 

- -

 

- -

附加组件卸载时的清理

- -

 

- -

不良:

- -

包括上述所有例子,*包括上述的“更好”*

- -

If your addon is restartless or uses the SDK then updates or the user turning it off and on will load to unload/reload events. Not handling those properly can lead to duplicate or conflicting code execution, especially when messages are sent. It can also lead to conflicts between the old and new code. Under some circumstances it may even cause exceptions when attempting to register something twice under the same ID.

- -

更好:

- -
// addon.js
-function onUnload() {
-  Services.mm.removeDelayedFrameScript("resources://my-addon/framescript.js");
-  Services.ppmm.removeDelayedProcessScript("resources://my-addon/processcript.js");
-  Services.mm.broadcastAsyncMessage("my-addon:unload");
-  Services.ppmm.broadcastAsyncMessage("my-addon:unload");
-}
-
- -

在框架/进程脚本中:

- - diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/motivation/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/motivation/index.html deleted file mode 100644 index 7ae3c2aaef..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/motivation/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: 动机 -slug: Mozilla/Firefox/Multiprocess_Firefox/Motivation -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Motivation ---- -
{{FirefoxSidebar}}

使 Firefox 在单独的进程中运行内容的主要原因:性能、安全和稳定性。

- -

性能

- -

Mozilla 在过去两年对性能的工作重点是浏览器的响应速度。目标是减少 “jank”—在加载大的页面时、表单中输入、或者滚动时,浏览器暂时性失去响应。响应问题在当今较高吞吐量的网络上日益显著。这些工作大部分已被 Snappy 项目完成。主要的重点在:

- - - -

大部分能轻易做到的事情在这些领域已经完成。剩下的问题比较难以解决。举例来说,JavaScript 执行和布局都发生在主线程,并且阻挡着事件循环。在单独的线程中运行这些组件是困难的,因为它们访问数据,像是 DOM,它们不是线程安全的。作为替代方案,我们已经考虑让事件循环运行在 JavaScript 执行的中间,但这样做会毁掉大量 Firefox 其他地方做出的假设(更不用提附加组件)。

- -

在一个单独的进程中运行网络内容,是这些方法的一个不错的替代品。类似线程的方式,Firefox 可以在 JavaScript 和布局在内容进程中运行时运行事件循环。但是不同于线程,用户界面(UI)的代码不能访问内容 DOM 或者其他内容的数据结构,因此没有必要进行锁定或者线程安全。而不足之处是,理所当然的,任何在 Firefox UI 进程中运行的需要访问内容数据的代码,都必须明确的通过消息传递的方式来访问内容数据。

- -

我们觉得这种权衡有道理,有几个原因:

- - - -

安全

- -

目前来说,如果某人发现了一个 Firefox 中的可利用漏洞,他们能够接管用户的计算机。有很多种技术来缓解这种问题,但其中最强大的是沙盒。从技术上讲,沙盒不需要多个进程。但是,涵盖沙盒的单进程 Firefox 并不会很有用。沙盒能阻止进程执行,一个乖巧进程绝不会做的操作。遗憾的是,乖巧的 Firefox 进程(尤其是已安装附加组件的 Firefox)会访问很多网络和文件系统。因此,对单进程的 Firefox 沙盒不能限制太多。

- -

在多进程 Firefox 中,内容进程将被沙盒化。一个乖巧的内容进程不会直接访问文件系统;它必须询问主线程来执行请求。在那时,主进程可以验证请求是否安全和合理。因此,对内容进程的沙盒化可以是相当严格的。我们希望这样的布局可以使 Firefox 更难被安全漏洞所利用。

- -

稳定性

- -

目前来说,在网页中运行的代码出现崩溃将导致整个浏览器崩溃。而多进程 Firefox 中,只有崩溃的内容进程会被终止。

- -
-

此页面整合了很多 Bill McCloskey 的有关多进程 Firefox 的文章: http://billmccloskey.wordpress.com/2013/12/05/multiprocess-firefox/

-
- -

 

diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/tab_selection_in_multiprocess_firefox/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/tab_selection_in_multiprocess_firefox/index.html deleted file mode 100644 index f396b7dcb5..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/tab_selection_in_multiprocess_firefox/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: 多进程 Firefox 中的标签选择 -slug: Mozilla/Firefox/Multiprocess_Firefox/Tab_selection_in_multiprocess_Firefox -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Tab_selection_in_multiprocess_Firefox ---- -
{{FirefoxSidebar}}

在单进程的 Firefox 中,当用户切换标签页时,这是同步操作。当浏览器加载新选择的标签页时,浏览器会阻塞,然后切换到该标签页。这表示标签页选定是通过设置 XUL 的 tab 对象的 selected 属性。代码(包括浏览器代码、扩展或主题)想要更改选定标签页的外观时,可以使用 selected  属性来应用 CSS 到该标签页。

- -

在多进程的 Firefox 中,标签页切换是异步的。在用户切换标签页时,chrome 进程发送一个请求到内容进程来加载该页面到新选择的标签页。chrome 进程中的函数会立即返回,以便其他代码可以运行。一旦内容进程准备就绪,它发回一个消息到 chrome 进程,然后在用户界面中切换标签页。

- -

还有 chrome 进程中的计时器:如果内容进程在计时器到期前没有响应,那么浏览器虽然继续切换标签页,但也显示一个包含标识的空标签页,直到目前的内容进程完成页面的加载。目前的计时器被设定为300毫秒。

- -

还有,相应的,两个属性用于指示标签页选择:

- - - -

这意味着想要对当前选中标签页应用的样式需要使用 visuallyselected 属性。如果使用 selected 属性,那么在新选择的标签页的样式被更新时会有一个短暂的断层,浏览器仍然在显示旧的标签页的内容。

- - diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/technical_overview/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/technical_overview/index.html deleted file mode 100644 index 18917fabc4..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/technical_overview/index.html +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: 技术概述 -slug: Mozilla/Firefox/Multiprocess_Firefox/Technical_overview -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Technical_overview ---- -
{{FirefoxSidebar}}
-

这个页面主要是 Bill McCloskey 的关于多进程 Firefox 的摘要: http://billmccloskey.wordpress.com/2013/12/05/multiprocess-firefox/

-
- -

从总体上来看,多进程 Firefox 的运行方式如下。当 Firefox 启动时的进程被称为父进程。起初和单程 Firefox 一样:打开一个窗口用于显示browser.xul,它包含主要的 UI 元素。XUL是Firefox的GUI工具箱, 由它提供了类似Web HTML的方式来声明定义UI元素。Firefox 的 UI也有一个window 对象。它有一个document 属性,并含了在 browser.xul 中所有的XML元素。所有的菜单,工具栏,侧边栏和标签页都是 document 下的 XML 元素。每一个标签页(tab)都包含一个 <browser> 元素用来显示网页内容.

- -

多进程与单进程的最主要区别是每个 <browser> 都有一个remote="true" 的属性。当这个 browser 元素被添加到 document 时,将会启动一个新的内容进程,也称为子进程。同时创建一个跨进程通信的IPC通道。开始时子进程显示 about:blank,父进程通过给子进程发送命令来导航显示的内容。

- -

绘制

- -

有时,显示的网页内容需要从子进程传递到父进程然后再显示到屏幕。多进程模式依赖于一个新的特性(off main thread compositing ,OMTC)。简单来说,每个窗口被分成若干层,概念上类似于photoshop中的层。每一次Firefox进行渲染时,这些层被提交到合成线程来构建为一个图片。

- -

层是树状结构。树的根节点对应一个Firefox窗口。根节点层包其他子层,如绘制菜单和标签页。一个子树对应所有网页内容。网页内容可被分成更多的层,这些层都以同一个内容层为根节点。

- -

在多进程Firefox中,内容层的子树是一个垫片(shim)。在大多数时间,它包含一个能够简单地保持到子进程的通信链接的引用的占位符节点。内容进程包括网页内容的层树。它构建并且描绘这个层树。当描绘完成时,它通过IPC将层数的结构发送给父进程。当父进程受到这个层树时,它删除这个占位符内容节点并且将其替换为源于内容的实际树。然后它正常地合成并且绘制。当它完成后,它将占位符放回。

- -

因为Firefox OS的需要,OMTC怎样于多进程一起工作的基本构架已经存在了一段时间。然而,Matt Woodrow和 David Anderson已经完成了大量工作来使得其在Windows,Mac和Linux正常工作。一个巨大的挑战是使多进程Firefox能够在所有平台下都能使OMTC启动。现在,只有Macs默认使用OMTC。

- -

用户输入

- -

Events in Firefox work the same way as they do on the web. Namely, there is a DOM tree for the entire window, and events are threaded through this tree in capture and bubbling phases. Imagine that the user clicks on a button on a web page. In single-process Firefox, the root DOM node of the Firefox window gets the first chance to process the event. Then, nodes lower down in the DOM tree get a chance. The event handling proceeds down through to the XUL <browser> element. At this point, nodes in the web page’s DOM tree are given a chance to handle the event, all the way down to the button. The bubble phase follows, running in the opposite order, all the way back up to the root node of the Firefox window.

- -

With multiple processes, event handling works the same way until the <browser> element is hit. At that point, if the event hasn’t been handled yet, it gets sent to the child process by IPC, where handling starts at the root of the content DOM tree. The parent process then waits to run its bubbling phase until the content process has finished handling the event.

- -

进程间通信

- -

所有 IPC 使用 Chromium IPC 程序库。每个子进程都有单独的与父进程的 IPC 链接。子进程之间不能直接通信。为了避免死锁和确保响应能力,父进程不允许坐等子进程的消息。但是,子进程可以阻塞等待父进程的消息。

- -

相比于人们预期的直接通过 IPC 发送数据包,我们使用代码生成使这个过程更漂亮。IPC 协议在 IPDL 中定义, which sort of stands for “inter-* protocol definition language”. A typical IPDL file is PNecko.ipdl. It defines a set messages and their parameters. Parameters are serialized and included in the message. To send a message M, C++ code just needs to call the method SendM. To receive the message, it implements the method RecvM.

- -

IPDL is used in all the low-level C++ parts of Gecko where IPC is required. In many cases, IPC is just used to forward actions from the child to the parent. This is a common pattern in Gecko:

- -
void AddHistoryEntry(param) {
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    // If we're in the child, ask the parent to do this for us.
-    SendAddHistoryEntry(param);
-    return;
-  }
-
-  // Actually add the history entry...
-}
-
-bool RecvAddHistoryEntry(param) {
-  // Got a message from the child. Do the work for it.
-  AddHistoryEntry(param);
-  return true;
-}
-
- -

When AddHistoryEntry is called in the child, we detect that we’re inside the child process and send an IPC message to the parent. When the parent receives that message, it calls AddHistoryEntry on its side.

- -

For a more realistic illustration, consider the Places database, which stores visited URLs for populating the awesome bar. Whenever the user visits a URL in the content process, we call this code. Notice the content process check followed by the SendVisitURI call and an immediate return. The message is received here; this code just calls VisitURI in the parent.

- -

The code for IndexedDB, the places database, and HTTP connections all runs in the parent process, and they all use roughly the same proxying mechanism in the child.

- -

框架脚本

- -

IPDL takes care of passing messages in C++, but much of Firefox is actually written in JavaScript. Instead of using IPDL directly, JavaScript code relies on the message manager to communicate between processes. To use the message manager in JS, you need to get hold of a message manager object. There is a global message manager, message managers for each Firefox window, and message managers for each <browser> element. A message manager can be used to load JS code into the child process and to exchange messages with it.

- -

As a simple example, imagine that we want to be informed every time a load event triggers in web content. We’re not interested in any particular browser or window, so we use the global message manager. The basic process is as follows:

- -
// Get the global message manager.
-let mm = Cc["@mozilla.org/globalmessagemanager;1"].
-         getService(Ci.nsIMessageListenerManager);
-
-// Wait for load event.
-mm.addMessageListener("GotLoadEvent", function (msg) {
-  dump("Received load event: " + msg.data.url + "\n");
-});
-
-// Load code into the child process to listen for the event.
-mm.loadFrameScript("chrome://content/content-script.js", true);
-
- -

For this to work, we also need to have a file content-script.js:

- -
// Listen for the load event.
-addEventListener("load", function (e) {
-  // Inform the parent process.
-  let docURL = content.document.documentURI;
-  sendAsyncMessage("GotLoadEvent", {url: docURL});
-}, false);
-
- -

This file is called a frame script. When the loadFrameScript function call runs, the code for the script is run once for each <browser> element. This includes both remote browsers and regular ones. If we had used a per-window message manager, the code would only be run for the browser elements in that window. Any time a new browser element is added, the script is run automatically (this is the purpose of the true parameter to loadFrameScript). Since the script is run once per browser, it can access the browser’s window object and docshell via the content and docShell globals.

- -

The great thing about frame scripts is that they work in both single-process and multiprocess Firefox. To learn more about the message manager, see the message manager guide.

- -

跨进程 API

- -

There are a lot of APIs in Firefox that cross between the parent and child processes. An example is the webNavigation property of XUL <browser> elements. The webNavigation property is an object that provides methods like loadURI, goBack, and goForward. These methods are called in the parent process, but the actions need to happen in the child. First I’ll cover how these methods work in single-process Firefox, and then I’ll describe how we adapted them for multiple processes.

- -

The webNavigation property is defined using the XML Binding Language (XBL). XBL is a declarative language for customizing how XML elements work. Its syntax is a combination of XML and JavaScript. Firefox uses XBL extensively to customize XUL elements like <browser> and <tabbrowser>. The <browser> customizations reside in browser.xml. Here is how browser.webNavigation is defined:

- -
<field name="_webNavigation">null</field>
-
-<property name="webNavigation" readonly="true">
-   <getter>
-   <![CDATA[
-     if (!this._webNavigation)
-       this._webNavigation = this.docShell.QueryInterface(Components.interfaces.nsIWebNavigation);
-     return this._webNavigation;
-   ]]>
-   </getter>
-</property>
-
- -

This code is invoked whenever JavaScript code in Firefox accesses browser.webNavigation, where browser is some <browser> element. It checks if the result has already been cached in the browser._webNavigation field. If it hasn’t been cached, then it fetches the navigation object based off the browser’s docshell. The docshell is a Firefox-specific object that encapsulates a lot of functionality for loading new pages, navigating back and forth, and saving page history. In multiprocess Firefox, the docshell lives in the child process. Since the webNavigation accessor runs in the parent process, this.docShell above will just return null. As a consequence, this code will fail completely.

- -

One way to fix this problem would be to create a fake docshell in C++ that could be returned. It would operate by sending IPDL messages to the real docshell in the child to get work done. We may eventually take this route in the future. We decided to do the message passing in JavaScript instead, since it’s easier and faster to prototype things there. Rather than change every docshell-using accessor to test if we’re using multiprocess browsing, we decided to create a new XBL binding that applies only to remote <browser> elements. It is called remote-browser.xml, and it extends the existing browser.xml binding.

- -

The remote-browser.xml binding returns a JavaScript shim object whenever anyone uses browser.webNavigation or other similar objects. The shim object is implemented in its own JavaScript module. It uses the message manager to send messages like "WebNavigation:LoadURI" to a content script loaded by remote-browser.xml. The content script performs the actual action.

- -

The shims we provide emulate their real counterparts imperfectly. They offer enough functionality to make Firefox work, but add-ons that use them may find them insufficient. I’ll discuss strategies for making add-ons work in more detail later.

- -

跨进程对象包装器

- -

The message manager API does not allow the parent process to call sendSyncMessage; that is, the parent is not allowed to wait for a response from the child. It’s detrimental for the parent to wait on the child, since we don’t want the browser UI to be unresponsive because of slow content. However, converting Firefox code to be asynchronous (i.e., to use sendAsyncMessage instead) can sometimes be onerous. As an expedient, we’ve introduced a new primitive that allows code in the parent process to access objects in the child process synchronously.

- -

These objects are called cross-process object wrappers, frequently abbreviated to CPOWs. They’re created using the message manager. Consider this example content script:

- -
addEventListener("load", function (e) {
-  let doc = content.document;
-  sendAsyncMessage("GotLoadEvent", {}, {document: doc});
-}, false);
-
- -

In this code, we want to be able to send a reference to the document to the parent process. We can’t use the second parameter to sendAsyncMessage to do this: that argument is converted to JSON before it is sent up. The optional third parameter allows us to send object references. Each property of this argument becomes accessible in the parent process as a CPOW. Here’s what the parent code might look like:

- -
let mm = Cc["@mozilla.org/globalmessagemanager;1"].
-         getService(Ci.nsIMessageListenerManager);
-
-mm.addMessageListener("GotLoadEvent", function (msg) {
-  let uri = msg.objects.document.documentURI;
-  dump("Received load event: " + uri + "\n");
-});
-mm.loadFrameScript("chrome://content/content-script.js", true);
-
- -

It’s important to realize that we’re send object references. The msg.objects.document object is only a wrapper. The access to its documentURI property sends a synchronous message down to the child asking for the value. The dump statement only happens after a reply has come back from the child.

- -

Because every property access sends a message, CPOWs can be slow to use. There is no caching, so 1,000 accesses to the same property will send 1,000 messages.

- -

Another problem with CPOWs is that they violate some assumptions people might have about message ordering. Consider this code:

- -
mm.addMessageListener("GotLoadEvent", function (msg) {
-  mm.sendAsyncMessage("ChangeDocumentURI", {newURI: "hello.com"});
-  let uri = msg.objects.document.documentURI;
-  dump("Received load event: " + uri + "\n");
-});
-
- -

This code sends a message asking the child to change the current document URI. Then it accesses the current document URI via a CPOW. You might expect the value of uri to come back as "hello.com". But it might not. In order to avoid deadlocks, CPOW messages can bypass normal messages and be processed first. It’s possible that the request for the documentURI property will be processed before the "ChangeDocumentURI" message, in which case uri will have some other value.

- -

For this reason, it’s best not to mix CPOWs with normal message manager messages. It’s also a bad idea to use CPOWs for anything security-related, since you may not get results that are consistent with surrounding code that might use the message manager.

- -

Despite these problems, we’ve found CPOWs to be useful for converting certain parts of Firefox to be multiprocess-compatible. It’s best to use them in cases where users are less likely to notice poor responsiveness. As an example, we use CPOWs to implement the context menu that pops up when users right-click on content elements. Whether this code is asynchronous or synchronous, the menu cannot be displayed until content has responded with data about the element that has been clicked. The user is unlikely to notice if, for example, tab animations don’t run while waiting for the menu to pop up. Their only concern is for the menu to come up as quickly as possible, which is entirely gated on the response time of the content process. For this reason, we chose to use CPOWs, since they’re easier than converting the code to be asynchronous.

- -

It’s possible that CPOWs will be phased out in the future. Asynchronous messaging using the message manager gives a user experience that is at least as good as, and often strictly better than, CPOWs. We strongly recommend that people use the message manager over CPOWs when possible. Nevertheless, CPOWs are sometimes useful.

diff --git a/files/zh-cn/mozilla/firefox/multiprocess_firefox/which_uris_load_where/index.html b/files/zh-cn/mozilla/firefox/multiprocess_firefox/which_uris_load_where/index.html deleted file mode 100644 index df24c59988..0000000000 --- a/files/zh-cn/mozilla/firefox/multiprocess_firefox/which_uris_load_where/index.html +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: 各类 URI 在哪里加载 -slug: Mozilla/Firefox/Multiprocess_Firefox/Which_URIs_load_where -translation_of: Mozilla/Firefox/Multiprocess_Firefox/Which_URIs_load_where ---- -
{{FirefoxSidebar}}

浏览器加载一个页面到 chrome 或者内容进程,基于它的 URI 方案(URI scheme)。对于某些方案,你可以改变默认行为。

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SchemeBehavior
about: -

默认情况下,about: 页面始终在 chrome 进程加载。但是,在你注册新的 about: 页面时,你可以改变此默认值。

- -

两个新标志定义在 nsIAboutModule:

- -
    -
  • URI_CAN_LOAD_IN_CHILD: 页面将加载在加载它的 browser 所在的进程。
  • -
  • URI_MUST_LOAD_IN_CHILD: 页面将始终加载在一个子进程
  • -
- -

要使用上述任一标志,在你的 注册 about: URI 的代码getURIFlags 实现中返回它。

-
chrome: -

默认情况下,chrome: 页面始终加载在 chrome 进程。但是,在你注册新的 chrome: 页面时,你可以改变此默认值。

- -

两个新标志定义在 chrome.manifest 文件

- -
    -
  • remoteenabled: 页面将加载在加载它的 browser 所在的进程。
  • -
  • remoterequired: 页面将始终加载在一个子进程
  • -
-
file:始终在内容进程中加载。
resource:始终在内容进程中加载。
diff --git a/files/zh-cn/mozilla/firefox/privacy/index.html b/files/zh-cn/mozilla/firefox/privacy/index.html deleted file mode 100644 index e9a4126aa6..0000000000 --- a/files/zh-cn/mozilla/firefox/privacy/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: 隐私 -slug: Mozilla/Firefox/Privacy -tags: - - 安全 - - 隐私 -translation_of: Mozilla/Firefox/Privacy ---- -
{{FirefoxSidebar}}
- -

本文档是所有隐私相关的文档的列表。

- -

{{ ListSubpages () }}

- -

参见

- - diff --git a/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/errors/index.html b/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/errors/index.html deleted file mode 100644 index a1e1f54a75..0000000000 --- a/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/errors/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Errors -slug: Mozilla/Firefox/Privacy/Storage_access_policy/Errors -tags: - - Cookies - - Errors - - NeedsTranslation - - Storage - - TopicStub - - storage access policy -translation_of: Mozilla/Firefox/Privacy/Storage_access_policy/Errors ---- -
{{FirefoxSidebar}}
- -

This page lists the errors that can be raised due to Firefox's anti-tracking functionality, governed by the Storage access policy. You can find further information about them by clicking on the links below:

- -

A request to access cookies or storage was blocked because

- - diff --git "a/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/errors/\347\246\201\347\224\250\345\244\226\351\203\250cookie/index.html" "b/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/errors/\347\246\201\347\224\250\345\244\226\351\203\250cookie/index.html" deleted file mode 100644 index d2c05cd375..0000000000 --- "a/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/errors/\347\246\201\347\224\250\345\244\226\351\203\250cookie/index.html" +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: 禁用:所有第三方存储访问请求 -slug: Mozilla/Firefox/Privacy/Storage_access_policy/Errors/禁用外部Cookie -tags: - - cookie - - 存储 - - 存储访问策略 - - 跟踪 - - 错误 -translation_of: Mozilla/Firefox/Privacy/Storage_access_policy/Errors/CookieBlockedForeign ---- -
{{FirefoxSidebar}}
- -

消息

- -

Firefox:

- -
禁用外部Cookie:由于浏览器禁用第三方内容展示及存储访问请求,Cookie和存储访问被拦截无法使用。
- -

出现此类情形的原因?

- -

由于浏览器禁用第三方内容的选项被开启,因此第三方Cookie使用请求和存储请求被拦截了。

- -

通过以下操作可以修改权限或移除站点:

- - - -

如果被拦截的资源不需要进行身份验证,你也可以给相关元素添加 crossorigin="anonymous" 属性来达到消除警告的目的。

- -

相关资料

- - diff --git a/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/index.html b/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/index.html deleted file mode 100644 index 801d5bfad1..0000000000 --- a/files/zh-cn/mozilla/firefox/privacy/storage_access_policy/index.html +++ /dev/null @@ -1,261 +0,0 @@ ---- -title: 'Storage access policy: Block cookies from trackers' -slug: Mozilla/Firefox/Privacy/Storage_access_policy -tags: - - NeedsTranslation - - Privacy - - TopicStub - - storage access policy - - tracking protection -translation_of: Mozilla/Firefox/Privacy/Storage_access_policy ---- -
{{FirefoxSidebar}}
- -

Firefox includes a new storage access policy that blocks cookies and other site data from third-party tracking resources. This policy is designed as an alternative to the older cookie policies, which have been available in Firefox for many years. This policy protects against cross-site tracking while minimizing the site breakage associated with traditional cookie blocking. This article explains how the policy works and how you can test it.

- -

Testing in Firefox

- -

This cookie policy has been available in Firefox since version 63. This documentation describes the policy that we intend to ship to Firefox Release users, but may not match what is implemented in the current Release version of Firefox. That's because we document new aspects of the policy as soon as they land in Firefox Nightly, our pre-release channel. Firefox Nightly may also contain experimental features that we don't yet plan to ship to Release users; experimental features will not be included in this documentation, but may nevertheless impact the functionality of domains classified as trackers.

- -

We recommend sites test with Firefox Nightly, as this includes the newest version of our protections. As described above, note that Nightly may include additional protections that end up getting removed or changed before they reach our Release users. We’ll keep this page updated with the newest information as we strengthen our protections.

- -

These protections are on by default in Nightly. The cookie policy can be enabled in other versions of Firefox through the Content Blocking settings (these steps will vary by version; the linked documentation includes a dropdown to select the appropriate Firefox version).

- -

Report Broken Sites

- -

If you find a website broken as a result of this change, file a bug under the Tracking Protection component within the Firefox product on Bugzilla. Alternatively you can report broken sites directly in Firefox by clicking "Report a Problem" in the Content Blocking section of the Control Center (this shortcut may not be available in all versions of Firefox).

- -

Tracking protection explained

- -

How does Firefox determine which resources are tracking resources?

- -

Firefox uses the Tracking Protection list to determine which resources are tracking resources. The Tracking Protection list is maintained by Disconnect. When the list is applied in Firefox, we make two important changes:

- - - -

Firefox uses the built-in Tracking Protection URL classifier to determine which resources match the tracking protection list. Domains are matched against the list in accordance with the SafeBrowsing v4 specification. Specifically, we check the exact hostname of the resource against the list, as well as the last four hostnames formed by starting with the last five components and successively removing the leading component. Consider the following examples:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Hostname on the listHostname of resourceMatched
example.comexample.comYes
example.coma.b.example.comYes
blah.example.comexample.comNo
a.b.example.comc.d.example.comNo
blah.example.comfoo.blah.example.comYes
- -

What does the storage access policy block?

- -

The storage access policy blocks resources identified as trackers from accessing their cookies and other site storage when they are loaded in a third-party context. This prevents those resources from retrieving tracking identifiers stored in cookies or site storage and using them to identify users across visits to multiple first parties. Specifically, Firefox does this by imposing the following restrictions:

- -

Cookies:

- - - -

DOM Storage:

- - - -

Messaging and Workers:

- - - -

DOM Cache:

- - - -

Browser caches:

- - - -

Network connections:

- - - -

What is not blocked by the policy?

- -
    -
  1. This policy does not currently restrict third-party storage access for resources that are not classified as tracking resources. We may choose to apply additional restrictions to third-party storage access in the future.
  2. -
  3. The restrictions applied by the policy will not prevent third-party scripts classified as tracking resources from accessing storage in the main context of the page. These scripts can continue to use storage scoped to the top-level origin.
  4. -
  5. Origins classified as trackers will have access to their own storage when they are loaded in a first-party context.
  6. -
  7. Cross-origin resources loaded from the same eTLD+1 as the top-level context will still have access to their storage.
  8. -
  9. Origins normally classified as trackers will not be blocked if the top-level page origin is determined to be from the same organization as them.
  10. -
- -

Storage access grants

- -

In order to improve web compatibility and permit third-party integrations that require storage access, Firefox will grant storage access scoped to the first party for a particular third-party origin as described in this section. Currently, Firefox includes some web compatibility heuristics that grant storage access to third-party resources classified as trackers when a user interacts with those third parties. We do this when we expect that not granting access would cause the web page to break. We also support an initial implementation of the Storage Access API, through which embedded {{htmlelement("iframe")}}s can request storage access by calling {{domxref("Document.requestStorageAccess()")}}. Although both of these approaches provide the same level of storage access, we recommend third parties switch to using the Storage Access API in order to guarantee their access to storage.

- -

Automatic storage access upon interaction

- -

In order to improve web compatibility, Firefox currently includes some heuristics to grant storage access automatically to third parties that receive user interaction. These heuristics are intended to allow some third-party integrations that are common on the web to continue to function. They are intended to be temporary and will be removed in a future version of Firefox. They should not be relied upon for current and future web development.

- -

Third-party storage access may be granted to resources that have been classified as tracking resources when a user gesture triggers a pop-up window that has opener access to the originating document. When that occurs, there are two possible ways a third-party origin can be granted access:

- - - -

Scope of storage access

- -

When storage access is granted, it is scoped to the origin of the opener document or subdomains of that origin. Access that is granted on the subdomain of an origin does not extend to the top-level origin. As an example, if a resource from tracker.example is granted storage access on foo.example.com, then tracker.example will be able to access its cookies on bar.foo.example.com but not example.com. Instead, if tracker.example were granted access on example.com it would be able to access its storage on bar.foo.example.com, foo.example.com, and example.com.

- -

When storage access is granted to tracker.example on example.com, all resources loaded from tracker.example on any top-level document loaded from example.com are immediately given storage access. This includes all resources loaded in the main context of the page, embedded <iframe>s, and resources loaded within embedded <iframe>s. Storage access is not extended to other resources loaded on example.com (e.g. other-tracker.example), nor to other first parties on which tracker.example is embedded (e.g. example.org).

- -

Storage access grants extend into the first level of nested contexts, but no further. This means that <iframe>s embedded in the main context of the page and loaded from a domain classified as a tracker will have full access to all storage locations accessible through JavaScript. Similarly, requests for resources loaded in <iframe>s embedded in the main context of the page will have access to HTTP cookies. However, further nested contexts, including but not limited to those from the origin classified as a tracker, will not be granted storage access.

- -

Consider the following embedding scenarios on a top-level page loaded from example.com on which tracker.example has been granted storage access.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Embeddingtracker.example resource storage access
An image is loaded from tracker.example and embedded in the main context of example.com.HTTP: Yes
- JS: N/A
example.com embeds an <iframe> from example.org. That <iframe> goes on to load an image from tracker.example.HTTP: Yes
- JS: N/A
example.com embeds an <iframe> from example.org. That <iframe> goes on to embed an <iframe> from tracker.example.HTTP: Yes
- JS: No
example.com embeds an <iframe> from tracker.example.HTTP: Yes
- JS: Yes
example.com embeds an <iframe> from example.com (same origin). The nested <iframe> embeds an <iframe> from tracker.example.HTTP: Yes
- JS: No
- -

Storage access expiration

- -

The storage access grant expires after 30 days. Domains classified as tracking resources may be granted third-party storage access on multiple first parties, and the storage permission for each party expires independently. The above heuristics will also serve to extend the lifetime of a third-party storage permission on origins that have already been granted access.  Each time the heuristic is activated, or a success call to the Storage Access API is made, the pre-existing storage access expiration will be extended by 30 days, counting from the time the previous access was granted.

- -

Please note that in the future we expect to make changes to how long storage access will remain valid for.  As mentioned before, the way to know that you will be able to use storage as a third-party going forward will be using the Storage Access API.

- -

Debugging

- -

We encourage site owners to test their sites, particularly those that rely on third-party content integrations. We’ve added several new features to Firefox to make testing easier.

- -

Developer Tools notifications

- -

The Network Monitor in Firefox Developer Tools now includes an indicator for all resource requests that have been classified as tracking resources. This indicator is shown as a shield icon in the domain column. In the sample image below, trackertest.org is classified as a tracking resource, while the request to example.com is not.

- -

network requests in Firefox devtools indicating which ones are tracking resources with a small shield icon

- -

Adding custom domains to the Tracking Protection list

- -

Curious how things will work if a third-party domain on your site were classified as a tracker? We’ve added a preference that allows you to add custom domains to the Tracking Protection URL classifier. To do so:

- -
    -
  1. Type about:config in your address bar. If you are presented with a page that warns you "This may void your warranty!", click "I accept the risk!"
  2. -
  3. Right click on the next page and click "New" > "String".
  4. -
  5. For the preference name enter "urlclassifier.trackingAnnotationTable.testEntries".
  6. -
  7. For the preference value enter comma separated origins that you’d like to have classified as trackers. E.g. "example.net,example.org".
  8. -
- -
-

Warning: Be sure to remove these entries after you have finished testing.

-
- -

FAQ

- -

This cookie policy has the potential to lead to site breakage, but has been designed to allow common third-party integrations to continue to work while preventing cross-site tracking. In this section we describe the functionality you can expect in different integration scenarios.

- -

Will this storage access policy block ads from displaying on my website?

- -

No — this feature only restricts access to cookies and site data that can be used to track users across websites. Blocking tracking identifiers does not prevent the display of advertisements.

- -

I use a third-party analytics service that is classified as a tracker. Will I still receive analytics data?

- -

This depends on how the third-party analytics service is implemented. Third-party analytics providers will no longer be able to user their third-party storage to collect data. This means that providers using cookies which are scoped to their third-party domain, or local storage and other site data stored under their origin, will no longer have access to those identifiers across other websites.

- -

If these services are embedded into the main context of the page, they can continue to use first-party cookies and site storage to track users across page visits on that specific first-party domain.

- -

I use third-party services for social login, like, and share button integration. Will my users still be able to make use of these services?

- -

This depends on how the social integration is implemented. We expect that many of the popular social integrations will continue to function as they do under Firefox’s current cookie policy with some minor differences in the user experience.

- -

A social content provider that is classified as a tracker will not have access to their third-party cookies when the user first visits a new first party. Thus, the user may appear logged out to the service despite being logged in when they visit the provider’s website directly. Depending on the type of integration, the user may have to take some action to interact with the social content provider before the provider is given access to their cookies. For example:

- - - -

After these interactions, the provider will receive third-party storage access if they prompt the user in a way that is captured by the storage access activation heuristics described above. These providers should consider switching to explicitly request storage access through the Storage Access API as soon as possible. An initial implementation of this API is currently available in Nightly.

- -

I use third-party pixels and other tools to measure the effectiveness of my ad campaigns. Will I still be able to measure the conversion rate of my ads?

- -

This depends on how the third party has implemented the measurement tool, but generally ad conversion measurement will be more difficult. Consider the following examples:

- -
    -
  1. You run an ad on a social media website that is seen several times by a user, but never clicked. That user later visits your website, which includes a conversion tracking tag from the same social media website. This type of conversion is often referred to as a “view-through conversion.” Since the social media website does not have access to their third-party storage, they will not recognize the user as the same user that saw the advertisements on their website and the conversion will not be tracked. We expect that most view-through conversion tracking techniques will no longer work, including those offered by display networks.
  2. -
  3. You run an ad on a display network or social media website that is clicked by a user. That user lands on your website, which includes a conversion tracking tag from the same website that displayed your ad. This type of conversion is often referred to as a “click-through conversion.” Since the social media site or display network will not have access to their third-party storage, they will not recognize the user as the same user that saw the advertisements on their website and the conversion will not be tracked. We expect that this version of click-through conversion will no longer work.
  4. -
  5. You run an ad that appears on a social media website. A user clicks on your advertisement and is taken to a landing page that contains a conversion tracking tag from the third-party network. On the social media website, the network annotates the advertisement landing page URL with a query parameter that signals that the visit was the result of a click on an advertisement. On your website, the display network’s tag checks the URL query parameters and saves any ad tracking parameters to first-party storage. If a user later completes a conversion event, the network’s tag checks first-party storage to determine which click (or clicks) was responsible for the visit. We expect that click-through conversion implemented in this way will continue to work.
  6. -
diff --git a/files/zh-cn/mozilla/firefox/privacy/tracking_protection/index.html b/files/zh-cn/mozilla/firefox/privacy/tracking_protection/index.html deleted file mode 100644 index 66620f47d9..0000000000 --- a/files/zh-cn/mozilla/firefox/privacy/tracking_protection/index.html +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Tracking Protection -slug: Mozilla/Firefox/Privacy/Tracking_Protection -tags: - - 隐私 -translation_of: Mozilla/Firefox/Privacy/Tracking_Protection ---- -
{{FirefoxSidebar}}
- -

什么是跟踪保护?

- -

Firefox 浏览器桌面版和 Android 移动版内置跟踪保护。在隐私窗口或标签页(Android移动版)内,Firefox会阻止跨网站的内容加载。

- -

如果拦截的内容是网页的一部分,用户可能会注意到网页排版出现问题。如果页面上的其它元素把拦截内容的空位给填补上时,用户完全不会注意到 Firefox 浏览器阻止了一些内容加载。

- -

当 Firefox 浏览器拦截到内容时,在控制台会有类似这样一条日志消息:

- -
位于“http://some/url”的资源已被内容拦截功能拦截。
- -

Firefox 浏览器 Android 移动版需要使用远程调试来看到控制台的输出内容。

- -

Page information showing possible blocked content.

- -

点下地址栏左侧这个标志ⓘ 可以查看当前页面的信息。按下第一行的按钮可以关闭对当前网站的跟踪保护。

- -

如果存在跟踪Cookie,您可以通过单击上图中的“阻止跟踪Cookie”查看以下弹出窗口来查看列表:

- -

- -

您可以单击“管理内容阻止”来更改阻止设置:

- -

- -

Firefox如何选择要阻止的内容?
- 基于要从中加载内容的域阻止内容。
- Firefox将提供一个站点列表,这些站点已经被确定为参与用户的跨站点跟踪。启用跟踪保护后,Firefox将阻止来自列表中站点的内容。
- 跟踪用户的网站通常是第三方广告和分析网站。

- -

这对你的网站意味着什么?
- 最明显的是,这意味着当启用跟踪保护时:
- 从第三方跟踪服务的内容将对用户不可见
- 您的网站将无法使用第三方广告或参与跟踪的分析服务
- 更微妙的是,如果站点的其他部分依赖于正在加载的跟踪器,那么当启用跟踪保护时,这些部分也将被破坏。例如,如果站点包含在加载跟踪站点的内容时运行的回调,则不会执行该回调。
- 例如,您不应以以下方式使用Google Analytics:

- -
<a href="http://www.example.com" onclick="trackLink('http://www.example.com', event);">
-  Visit example.com
-</a>
-
-<script>
-function trackLink(url,event) {
-    event.preventDefault();
-    ga('send', 'event', 'outbound', 'click', url, {
-     'transport': 'beacon',
-     'hitCallback': function() {
-       document.location = url;
-     }
-   });
-}
-</script>
- -

相反,您应该通过检查ga对象是否已初始化来解释Google Analytics丢失的情况:

- -
<a href="http://www.example.com" onclick="trackLink('http://www.example.com', event);">
-  Visit example.com
-</a>
-
-<script>
-function trackLink(url,event) {
-    event.preventDefault();
-    if (window.ga && ga.loaded) {
-         ga('send', 'event', 'outbound', 'click', url, {
-         'transport': 'beacon',
-         'hitCallback': function() { document.location = url; }
-       });
-    } else {
-        document.location = url;
-    }
-}
-</script>
-
- -

关于这项技术的更多信息可以在Google分析、隐私和事件跟踪上找到。

- -
-

注意:以这种方式依赖第三方并不是一个好的做法,因为如果第三方速度慢或不可用,或者跟踪器已被加载项阻止,则站点可能会被破坏。

-
diff --git a/files/zh-cn/mozilla/firefox/the_about_protocol/index.html b/files/zh-cn/mozilla/firefox/the_about_protocol/index.html deleted file mode 100644 index 9b889c3338..0000000000 --- a/files/zh-cn/mozilla/firefox/the_about_protocol/index.html +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: Firefox 与 "about" 协议 -slug: Mozilla/Firefox/The_about_protocol -translation_of: Mozilla/Firefox/The_about_protocol ---- -
{{FirefoxSidebar}}

Firefox 在 about: URL 协议中藏有很多隐藏的功能和有用的信息。最常用的 URL 就是 about:config,它提供首选项的显示和修改功能。以下是 about: 伪协议的完整列表:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
about: 页面描述
about:显示版本和构建信息,以及查阅贡献者、许可信息和构建配置的链接。
about:about提供 about: 页面的完整列表
about:accounts同步 功能使用的页面
about:addons附加组件管理器
about:app-manager应用管理器
about:buildconfig显示构建此 Firefox 所用的配置和平台
about:cache显示有关内存、磁盘和应用缓存的信息
about:compartments显示有关 compartments 的信息。从 Firefox 26 开始,此信息可在 about:memory 的 "Other Measurements"  部分找到
about:config允许查看和更改 Firefox 内部的首选项(偏好和设置)
about:crashes列出所有崩溃报告
about:credits列出所有参与 Firefox 产品的贡献者姓名
about:customizing切换到“定制”模式,允许用户定制 Firefox 的用户界面
about:downloads显示用 Firefox 进行的下载
about:healthreport显示 Firefox 的性能信息(如果用户已启用“健康报告”功能)
about:homeFirefox 原生的开始页(新窗口的第一个页面)
about:license显示许可信息
about:logoFirefox 标志
about:memory提供一种方法探查内存使用情况,以及保存为报告,还有运行 GC 和 CC
about:mozilla一个特殊页面,显示“Mozilla 之书”摘录
about:networking显示网络相关的信息
about:newtab新建一个标签页时显示的页面
about:permissions提供一种方法来显示和管理网站权限。在 Firefox 45 中已去除({{bug(933917)}})
about:plugins显示已安装插件的信息
about:preferencesFirefox 设置(也可通过 Firefox > 选项 来打开)
about:privatebrowsing打开新的隐私浏览窗口时显示的页面
about:reader指示在一个页面上开启了阅读视图。 参见Firefox 排除干扰的阅读视图
about:rights显示权利信息
about:robots显示有关机器人的信息,一个特殊的页面
about:sessionrestore会话恢复(Firefox 从崩溃恢复时显示)
about:support故障排除信息(也称“疑难解答”信息)。也可通过 Firefox 菜单 > ? (问号) > 故障排除信息 打开
about:sync-log显示 同步 功能所用的同步协议的日志
about:sync-progress这是 同步 功能设置完成后显示的页面
about:sync-tabs列出 同步 功能同步的标签页
about:telemetry显示在 Firefox 运行时已收集和将发送到 Mozilla 的遥测数据(如果用户已启用“遥测”功能)
about:webrtc有关 WebRTC 的使用情况
about:welcomeback在 Firefox 被重置后显示的信息页面
- -

这些 URL 在 {{source("docshell/base/nsAboutRedirector.cpp")}} 中的 kRedirMap 数组定义。该数组映射大部分 URL,比如 config 指向 chrome: 伪协议,例如 chrome://global/content/config.xul。about 的位置信息在 {{source("docshell/build/nsDocShellModule.cpp")}} 也存有副本。

diff --git a/files/zh-cn/mozilla/firefox_for_android/index.html b/files/zh-cn/mozilla/firefox_for_android/index.html deleted file mode 100644 index 955aa200c0..0000000000 --- a/files/zh-cn/mozilla/firefox_for_android/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Firefox for Android -slug: Mozilla/Firefox_for_Android -translation_of: Mozilla/Firefox_for_Android ---- -

对于越来越多的人来说,移动设备是他们上网的主要方式,甚至是唯一方式。Firefox Android版(代号 Fennec)是一个开放的,可定制的,基于标准的浏览器,就像桌面版的Firefox。

- -

Firefox Android版从原生的Android小部件构建用户界面而不是XUL:这极大的提高了性能,特别是启动时间和内存消耗上。

- -

有助于Firefox for Android

- -

关于Firefox for Android项目主要出发点的一些信息参见 “Get Involved” 页

- -

你可以帮助我们建立和改善 Firefox for Android:

- - - -

为移动web开发

- -

我们已经开始了一个移动设备设计网站的指南

- -

With Firefox for Android, you've got access a number of APIs that expose the underlying capabilities of the device, closing the gap between the Web and native applications:

- - - -

To test your web site on Firefox for Android, you can install it on an Android device or run it on your desktop using the Android Emulator.

- -

构建Mobile附加组件

- -

Firefox for Android supports add-ons using the exact same extension system used by all other Gecko-based applications. We did not invent a new add-on system. This means that building an add-on for Firefox on Android is the same process that would be used for desktop Firefox. Add-ons that work with desktop Firefox do not automatically work in Firefox on Android. The user interfaces are just too different.

- -
Firefox on Android has a unique application identifier which must be used in install.rdf. The identifier is {aa3c5121-dab2-40e2-81ca-7ea25febc110}
- -

Both classic restart-required and newer restartless add-on approaches are supported. Using the restartless approach is preferred whenever possible because the user experience is far superior to forcing an application restart when installing or removing an add-on.

- -

快速概览

- - - -

获取Firefox for Android的帮助

- -

Documentation and tutorials for using and troubleshooting Firefox for Android are available on the Mozilla Support website.

- -

 

diff --git a/files/zh-cn/mozilla/gecko/index.html b/files/zh-cn/mozilla/gecko/index.html deleted file mode 100644 index a5863d1b6d..0000000000 --- a/files/zh-cn/mozilla/gecko/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Gecko -slug: Mozilla/Gecko -tags: - - Gecko - - Mozilla -translation_of: Mozilla/Gecko ---- -
{{FirefoxSidebar}}
- -
-

Gecko 是由 Mozilla 工程开发出的布局引擎的名字。它的原名是 NGLayout。Gecko 的功能就是读取 web 内容,如HTMLCSSXULJavaScript, 之后将其渲染到用户界面上。在基于 XUL 的应用中,Gecko 也同样用来渲染应用程序的用户界面。

-
- -

Gecko 被使用在许多应用程序中,包括一些浏览器,如 Firefox,SeaMonkey等(要获取完整的列表,请参考 Wikipedia's article on Gecko)。使用相同 Gecko 版本的产品对标准则有同样的支持。

- - - - - - - - -
-

文档

- -
-
Gecko FAQ
-
关于 Gecko 常见的问题。
-
 Gecko DOM 参考文档
-
DOM参考文档。
-
Gecko event 参考文档
-
使用在 Gecko 和 Mozilla 应用中 event 的参考文档。要获取 web 标准的 DOM event, 请参考 DOM event reference.
-
Gecko 版本和应用程序版本
-
它们使用的Gecko和应用程序版本。
-
 Mozilla 中对布局的介绍
-
关于布局的技术性介绍。
-
嵌入 Mozilla
-
在您的应用中使用 Gecko。
-
由 Gecko 支持的字符集
-
Gecko所支持的字符集列表。
-
HTML 解析器线程
-
在 HTML 解析器中的多线程描述。
-
{{interwiki('wikimo', 'Gecko:Home_Page', 'Gecko Home Page on MozillaWiki')}}
-
活跃开发者之家。路线图以及最新的资源。
-
- -

View All...

-
-

社区

- -
    -
  • View Mozilla forums... {{DiscussionList("dev-tech-layout", "mozilla.dev.tech.layout")}}
  • -
- - - - - -
-
 
-
-
- -

 

- -

 

diff --git a/files/zh-cn/mozilla/gecko/versions/index.html b/files/zh-cn/mozilla/gecko/versions/index.html deleted file mode 100644 index cd2989399c..0000000000 --- a/files/zh-cn/mozilla/gecko/versions/index.html +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: Gecko版本和对应的应用程序版本 -slug: Mozilla/Gecko/Versions -tags: - - Gecko -translation_of: Mozilla/Gecko/Versions ---- -

下面的表格记录了 Gecko 的每个版本以及建立在该版本 Gecko 之上的应用程序的版本.

-

注意在 Gecko 2.0 之后(也就是 Gecko 5.0 开始), Firefox 和 Thunderbird 同 Gecko 采用同一个版本号.

-

另外从 Gecko 17开始, SpiderMoneky 也开始使用这个版本号, 比如 SpiderMonkey 17SpiderMonkey 24, 抛弃了之前使用的 1.8.x 小版本号方式, SpiderMoneky 最后一个小版本号是 1.8.8, 最后一个稳定版的小版本号是 1.8.5. 这些版本号也可以从 Mozilla 发布的 SpiderMonkey 源码包的文件名中看出 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Gecko  版本基于它的应用程序版本
Gecko 24Firefox 24, Thunderbird 24, SeaMonkey 2.21
Gecko 23Firefox 23, SeaMonkey 2.20
Gecko 22Firefox 22, SeaMonkey 2.19
Gecko 21Firefox 21, {{ interwiki('wikimo', 'SeaMonkey/Features/2.18', 'SeaMonkey 2.18') }}
Gecko 20Firefox 20, {{ interwiki('wikimo', 'SeaMonkey/Features/2.17', 'SeaMonkey 2.17') }}
Gecko 19Firefox 19, {{ interwiki('wikimo', 'SeaMonkey/Features/2.16', 'SeaMonkey 2.16') }}
Gecko 18Firefox 18, Firefox OS 1.0, {{ interwiki('wikimo', 'SeaMonkey/Features/2.15', 'SeaMonkey 2.15') }}
Gecko 17Firefox 17, Thunderbird 17, {{ interwiki('wikimo', 'SeaMonkey/Features/2.14', 'SeaMonkey 2.14') }}
Gecko 16Firefox 16, Thunderbird 16, {{ interwiki('wikimo', 'SeaMonkey/Features/2.13', 'SeaMonkey 2.13') }}
Gecko 15Firefox 15, Thunderbird 15, {{ interwiki('wikimo', 'SeaMonkey/Features/2.12', 'SeaMonkey 2.12') }}
Gecko 14Firefox 14, Thunderbird 14, {{ interwiki('wikimo', 'SeaMonkey/Features/2.11', 'SeaMonkey 2.11') }}
Gecko 13Firefox 13, Thunderbird 13, {{ interwiki('wikimo', 'SeaMonkey/Features/2.10', 'SeaMonkey 2.10') }}
Gecko 12Firefox 12, Thunderbird 12, {{ interwiki('wikimo', 'SeaMonkey/Features/2.9', 'SeaMonkey 2.9') }}
Gecko 11Firefox 11, Thunderbird 11, {{ interwiki('wikimo', 'SeaMonkey/Features/2.8', 'SeaMonkey 2.8') }}
Gecko 10Firefox 10, Thunderbird 10, {{ interwiki('wikimo', 'SeaMonkey/Features/2.7', 'SeaMonkey 2.7') }}
Gecko 9Firefox 9, Thunderbird 9, {{ interwiki('wikimo', 'SeaMonkey/Features/2.6', 'SeaMonkey 2.6') }}
Gecko 8Firefox 8, Thunderbird 8, {{ interwiki('wikimo', 'SeaMonkey/Features/2.5', 'SeaMonkey 2.5') }}
Gecko 7Firefox 7, Thunderbird 7, {{ interwiki('wikimo', 'SeaMonkey/Features/2.4', 'SeaMonkey 2.4') }}
Gecko 6Firefox 6, Thunderbird 6, {{ interwiki('wikimo', 'SeaMonkey/Features/2.3', 'SeaMonkey 2.3') }}
Gecko 5Firefox 5, Thunderbird 5, {{ interwiki('wikimo', 'SeaMonkey/Features/2.2', 'SeaMonkey 2.2') }}
Gecko 2Firefox 4, Thunderbird 3.3, {{ interwiki('wikimo', 'SeaMonkey/Features/2.1', 'SeaMonkey 2.1') }}
Gecko 1.9.2Firefox 3.6, Thunderbird 3.1
Gecko 1.9.1Firefox 3.5, Thunderbird 3, {{ interwiki('wikimo', 'SeaMonkey:New_for_2.0', 'SeaMonkey 2.0') }}
Gecko 1.9Firefox 3
Gecko 1.8.1Firefox 2, Thunderbird 2, SeaMonkey 1.1
Gecko 1.8Firefox 1.5, Thunderbird 1.5, SeaMonkey 1.0
Gecko 1.7Firefox 1.0, Thunderbird 1.0, Nvu 1.0, Mozilla Suite 1.7
older versions of Gecko match the Mozilla Suite versions
-

 

diff --git "a/files/zh-cn/mozilla/gecko/\345\265\214\345\205\245mozilla/index.html" "b/files/zh-cn/mozilla/gecko/\345\265\214\345\205\245mozilla/index.html" deleted file mode 100644 index e2e5daa728..0000000000 --- "a/files/zh-cn/mozilla/gecko/\345\265\214\345\205\245mozilla/index.html" +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: 嵌入 Mozilla -slug: Mozilla/Gecko/嵌入Mozilla -tags: - - 㠌入Mozilla -translation_of: Mozilla/Gecko/Embedding_Mozilla ---- -
Gecko允许第三方开发人员使用与Mozilla相同的技术。这意味着您可以将Web浏览器嵌入到第三方应用程序中,通过网络后端打开通道和流,遍历DOM等等。甚至可以使用用最新版chrome构建的应用程序。
- -
- - - - - - - - -
-

大纲

- -
-
Gecko 基础绑定
-
嵌入gecko渲染引擎的介绍.
-
嵌入提示
-
一些关于嵌入的常见问题。
-
Mozilla 㠌入 API 概述
-
Mozilla嵌入API简介.
-
嵌入编辑器
-
本文档描述了编辑器可嵌入性的当前状态、现有实现中的问题、我们需要处理的一些可能的嵌入场景,以及将满足这些情况的嵌入解决方案。
-
玩转你自己的浏览器-一个嵌入方法
-
关于嵌入Mozilla的简单介绍。
-
- -

View All...

-
-

社区

- -
    -
  • 查看Mozilla论坛.. {{ DiscussionList("dev-embedding", "mozilla.dev.embedding") }}
  • -
  • #绑定 IRC 信道
  • -
- - - - -
diff --git a/files/zh-cn/mozilla/how_mozilla_determines_mime_types/index.html b/files/zh-cn/mozilla/how_mozilla_determines_mime_types/index.html deleted file mode 100644 index fbe9917902..0000000000 --- a/files/zh-cn/mozilla/how_mozilla_determines_mime_types/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: How Mozilla determines MIME Types -slug: Mozilla/How_Mozilla_determines_MIME_Types -translation_of: Mozilla/How_Mozilla_determines_MIME_Types ---- -

Introduction

- -

All data handling in Mozilla is based on the MIME type of the content. This means that every time an URI is loaded, Mozilla must find out its MIME type. The several ways how this happens are described in this document.

- -

Content-Type "hints"

- -

Mozilla has a concept of "content-type hints". This means that, for example, if Mozilla encounters a <link type="text/css" rel="stylesheet" href="..."> element, a type of text/css will be assumed. This is, however, overridden by the actual MIME type the server sends (if any). (For this specific example, the server override only happens in standards-compliant mode. See Mozilla's Quirks Mode or Web Author FAQ).

- -

Similar handling happens for <a href="..." type="foo/bar">, starting in Mozilla 1.6alpha.

- -

HTTP

- -

For HTTP URIs Mozilla usually gets a MIME type sent from the server, and uses it. Contrary to Internet Explorer's MIME type guessing, Mozilla will generally not sniff the type of the document. However, starting in Mozilla 1.7alpha, Mozilla does do content sniffing, like this:

- -

When the Content-Type sent by the server is one of (case-sensitively)

- - - -

and the server did not send a Content-Encoding header, Mozilla will sniff the first block of data it gets and check for non-text bytes. Text bytes are 9-13, 27, and 31-255. When encountering a non-text byte, the helper app dialog will be shown, showing the MIME type corresponding to the extension of the file.

- -

Also, for images loaded via <img src>, Mozilla's image library will do content sniffing (never extension sniffing) to find out the real type of the image.

- -

If the server did not send a Content-Type header, Mozilla uses the unknown decoder to find a MIME type.

- -

File URIs

- -

For file: URIs, Mozilla will ask the ExternalHelperAppService for a MIME type.

- -

FTP

- -

Like HTTP URIs without a MIME type, FTP URIs go through the unknown decoder.

- -

Unknown Decoder

- -

Located at {{ Source("netwerk/streamconv/converters/nsUnknownDecoder.cpp") }}, the interesting part starts at {{ Source("netwerk/streamconv/converters/nsUnknownDecoder.cpp#287", "line 287") }}, the sSnifferEntries array together with the DetermineContentType function. It does the following:

- - - -

ExternalHelperAppService

- -

(located at {{ Source("uriloader/exthandler/nsExternalHelperAppService.cpp") }})

- -

The file->MIME type mapping works like this:

- - - -

Helper Applications

- -

A somewhat related issue are the helper applications. When loading an URI with a type that Mozilla can not handle, a helper app dialog shows up, and the displayed information comes from these sources:

- - - - - -

Document Loading - From Load Start to Finding a Handler

- -
-

Original Document Information

- - -
diff --git a/files/zh-cn/mozilla/how_to_get_a_process_dump_with_windows_task_manager/index.html b/files/zh-cn/mozilla/how_to_get_a_process_dump_with_windows_task_manager/index.html deleted file mode 100644 index 9833241199..0000000000 --- a/files/zh-cn/mozilla/how_to_get_a_process_dump_with_windows_task_manager/index.html +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: 怎样在任务管理器中获取进程的dump -slug: Mozilla/How_to_get_a_process_dump_with_Windows_Task_Manager -translation_of: Mozilla/How_to_get_a_process_dump_with_Windows_Task_Manager ---- -

介绍

- -

当追踪进程为何挂起的时候,获取运行进程的dump是很有用的。这篇文章描述怎样从任务管理器中提取进程dump。 (为了获取thunderbird或者其他产品的dump,用一些指令替换火狐中的一些名称)

- -

起因

- -

一个内存dump被创建代表了创建者文件时的火狐状态的快照,它包含了,活动tab的URL,历史信息,可能甚至包含密码,依赖于你获取快照的时机,当重现问题的时候,适当创建一个新的说明文件,并且抓取dump。请帮忙做这些。

- -

要求

- -
-
-
Windows
-
为了获取进程度dump,你需要Wndows Vista及以上系统
-
-
一个火狐日构建版本或发布版
-
你需要火狐的符号表 Mozilla symbol server. 你可以用 官方日构建版本 或者发布版本. 你可以获取最新的日构建版本在 http://ftp.mozilla.org/pub/mozilla.o.../latest-trunk/.
-
- -

创建dump文件

- -

确保火狐没有在运行.

- -

运行火狐,重现问题

- -

打开火狐,重现引起问题的步骤.  一旦出现,继续以下步骤

- -

挂起之后

- -
    -
  1. 打开任务管理器 (CTRL+SHIFT+ESC).
  2. -
  3. 在进程列表中查找 Firefox.exe
  4. -
  5. 右键 Firefox.exe 选择 "创建dump文件". 任务管理器需要dump写的位置.
  6. -
- -

其他

- - - - diff --git a/files/zh-cn/mozilla/implementing_pontoon_in_a_mozilla_website/index.html b/files/zh-cn/mozilla/implementing_pontoon_in_a_mozilla_website/index.html deleted file mode 100644 index 2964582ca0..0000000000 --- a/files/zh-cn/mozilla/implementing_pontoon_in_a_mozilla_website/index.html +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: 在 Mozilla 项目中使用 Pontoon -slug: Mozilla/Implementing_Pontoon_in_a_Mozilla_website -tags: - - 本地化 -translation_of: Mozilla/Implementing_Pontoon_in_a_Mozilla_website ---- -

Pontoon 是一个基于 web 的所见即所得(WYSIWYG)的本地化(l10n)工具。在 Mozilla ,我们都是使用 Pontoon 去本地化众多的 Mozilla 项目和被称为 Gaia 的 Firefox OS app 接口。Pontoon 是一个非常简单、直接的工具,本地化人员只需要很少甚至没有技术能力就可以使用它,这将减少项目本地化版本的发布时间。下面我们来谈谈怎么将 Pontoon 加入到你的 Mozilla 项目里。

- -
-

你想帮忙改进 Pontoon 吗?了解如何在 GitHub 上参与。

-
- -
-

只是开始你项目的 l10n? 查看 本地化你的项目 上的 wiki。

-
- -

A. 本地化你的项目

- -

我们意识到这些已经被认为是 Mozilla 本地化项目的标准最佳实践 ,但我们觉得还是应该在这里做个小小的提醒。

- -
    -
  1. 确保你的项目支持下列任一种 l10n 框架(gettextXLIFFL20nlangproperties等等).
  2. -
  3. 将可本地化的字符串提取到资源文件中。
  4. -
  5. 推送源文件到存储库中(SVN、HG、Git)。 -
      -
    • 各个区域的本地化文件夹必须位于同一级目录下。区域的本地化需要起名为 templatesen-USen-us 或者 en。如果存储库中存在同名的多个本地化文件夹,并且文件夹内的文件都是受支持的格式,则只会使用第一个文件夹。这样的话,你可能需要把所有的本地化文件夹都放在一个专用的 locales 目录下。 文件名中请务必不要包含本地化代码。
    • -
    • 正确的模式: -
      /locales/{本地化代码}/path/to/file.extension
      -
    • -
    • 错误模式: -
      /locales/{本地化代码}/path/to/file.{本地化代码}.extension
      -
    • -
    -
  6. -
  7. 确保 Pontoon 有存储库的写入权限。 - -
  8. -
- -

B. (optional) Enable in-page localization of your web project

- -
    -
  1. Link a script from your HTML <body> element, so Pontoon can talk to your site, detect content and make it localizable in place. You only need to do this in the environment that will be used for in-page localization, e.g. staging server: - - -
  2. -
  3. If your site uses CSP,  please make sure that the following is permitted for domain pontoon.mozilla.org: -
      -
    1. loading inside iframe
    2. -
    3. loading remote CSS
    4. -
    5. loading remote images
    6. -
    -
  4. -
  5. If your site uses the X-Frame-Options header, please make sure loading inside iframe is permitted for domain pontoon.mozilla.org.
  6. -
  7. Make sure your site supports HTTPS. It's free, automated and open. Let's encrypt!
  8. -
- -

C. Add your project to Pontoon

- -

Your project is now ready to be set up in Pontoon. Please file a bug in Localization Infrastructure and Tools :: Administration / Setup and provide the following information:

- - - -

For more details, please get in touch with the Project Management Team.

diff --git a/files/zh-cn/mozilla/instantbird/index.html b/files/zh-cn/mozilla/instantbird/index.html deleted file mode 100644 index 67c7285a5f..0000000000 --- a/files/zh-cn/mozilla/instantbird/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Instantbird -slug: Mozilla/Instantbird -translation_of: Mozilla/Instantbird ---- -

Instantbird(及时鸟) 是一个和Mozilla很有渊源的即时通讯软件.  当前文档指向的通讯内核文档同样被应用于Thunderbird(雷鸟)

- -

及时鸟和火狐浏览器基于相同的技术平台。它源自于谷歌的一个 夏日炎炎爱编程 项目。目的是为了给libpurple(Pidgin 的后端)创建一个 XUL界面。当时及时鸟并没有被认可 。尽管如此,从2007年开始,它不断发展壮大,有了自己的协议,并且已经不再局限于libpurple的前端。

- - - - - - - - - - -
-

文档

- -
-
-
-
创建及时鸟
-
从comm-central仓库创建及时鸟。
-
通讯内核
-
后端代码,包含了通讯协议的大体文档({{ Interface("prplIProtocol") }} 和 friends)。
-
消息格式
-
展示了消息的主题相关信息。
-
键盘快捷键
-
键盘快捷键列表
-
-

链接

-
-
Latest nightly builds最新创建
-
These are generally stable, but expect some breakage from time to time and file bugs.大体稳定,但有可能会有bug
-
- -

View All...

-
-

社区

- -
    -
  • #instantbird on irc.mozilla.org (for users and developers)
  • -
  • Support is handled on the support-instantbird mailing list or on IRC: {{ DiscussionList("support-instantbird", "mozilla.support.instantbird") }}
  • -
  • Extension questions can be discussed on the dev-chat group or on IRC: {{ DiscussionList("dev-chat", "mozilla.dev.chat") }}
  • -
  • a list of all Instantbird communication channels
  • -
- -

工具

- -
    -
  • DOM 监视器
  • -
- - - -
    -
  • 拓展
  • -
-
diff --git a/files/zh-cn/mozilla/introduction_to_layout_in_mozilla/index.html b/files/zh-cn/mozilla/introduction_to_layout_in_mozilla/index.html deleted file mode 100644 index 3a2df97afb..0000000000 --- a/files/zh-cn/mozilla/introduction_to_layout_in_mozilla/index.html +++ /dev/null @@ -1,360 +0,0 @@ ---- -title: Mozilla 中对布局的介绍 -slug: Mozilla/Introduction_to_Layout_in_Mozilla -tags: - - cn -translation_of: Mozilla/Introduction_to_Layout_in_Mozilla ---- -

概要

- - - -

基本数据流

- - - -

- -

关键数据结构

- -

- - - -

- -

关键数据结构

- - - -

详细执行步骤

- - - -

设置

- - - -

- -

内容模型的构建

- - - -

- -

框架Frame 的构建

- - - -

- -

Style 選定

- - - -

回流

- - - -

回流

- - - -

增量回流

- -

- - - -

增量回流

- -

- - - -

增量回流

- -

- - - -

增量回流

- -

- - - -

繪畫

- - - -

漸進

- - - -

- -

未来(?)技术讲座

- - - -

最后

- - - -
-

原始文档信息

- - -
diff --git a/files/zh-cn/mozilla/ipdl/creating_a_new_protocol/index.html b/files/zh-cn/mozilla/ipdl/creating_a_new_protocol/index.html deleted file mode 100644 index d256886913..0000000000 --- a/files/zh-cn/mozilla/ipdl/creating_a_new_protocol/index.html +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: 创建一个新的协议 -slug: Mozilla/IPDL/Creating_a_New_Protocol -translation_of: Mozilla/IPDL/Creating_a_New_Protocol ---- -

这是有关如何向构建中添加新IPDL协议的详细信息的快速入门。您应该首先了解IPDL的工作原理

- -

创建协议文件

- -

协议文件应与实现它的代码位于同一目录中。协议名称以P开头,并且协议文件必须命名为PProtocolName.ipdl。IPDL协议应位于mozilla命名空间或子命名空间中。

- -

要将文件连接到构建,需要将IPDL文件添加到最近的moz.build文件中的IPDL_SOURCES。有关示例,请参见 dom/ipc/moz.build 

- -

协议层次结构

- -

除非您正在从事某些特殊项目,否则您的协议将适合多进程插件或选项卡的协议层次结构。插件的顶级协议是PPluginModule。选项卡的顶级协议是PContent。您应该知道哪种协议将管理新协议,以及会导致哪些生存期问题。如有疑问,请在#content频道中询问IRC。

- -

建立新协议

- -

要构建新的协议声明并生成标头,请在ipc/ipdl中创建:

- -
make -C objdir/ipc/ipdl
- -

如果存在协议级别的错误,则IPDL编译器将打印相关的错误消息并停止。要查看生成的标题,请在中查看objdir/ipc/ipdl/_ipdlheaders

- -

创建实现

- -

C ++实现从IPDL生成的抽象类PNewProtocolParent和PNewProtocolChild继承。它必须实现抽象方法以在每一侧接收适当的消息。可以从生成的PNewProtocolParent.h和PNewProtocolChild.h标头中读取方法签名。

- -

编写测试

- -

PBrowser管理的协议必须使用带有的mochitest-chrome测试框架进行测试<browser remote="true">出于测试目的,可以在JPW包装器上使用同步调用。使用xpcshell测试框架可以测试与特定窗口无关的协议,该框架在Electrolysis中具有其他原语,用于在内容过程中启动和运行JS命令。

diff --git a/files/zh-cn/mozilla/ipdl/index.html b/files/zh-cn/mozilla/ipdl/index.html deleted file mode 100644 index 051c353f2c..0000000000 --- a/files/zh-cn/mozilla/ipdl/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: IPC Protocol Definition Language (IPDL) -slug: Mozilla/IPDL -tags: - - IPC - - IPDL - - NeedsTranslation - - PBackground - - TopicStub -translation_of: Mozilla/IPDL ---- -

IPDL是“IPC(进程间通信)协议定义语言”的缩写,是一种特定于Mozilla的语言,允许C++代码以有组织和安全的方式在进程或线程之间传递消息。Firefox中多进程插件和选项卡的所有消息都是用IPDL语言声明的。

- -

当前文档

- - - -

Future planned docs

- - diff --git "a/files/zh-cn/mozilla/ipdl/\345\205\245\351\227\250/index.html" "b/files/zh-cn/mozilla/ipdl/\345\205\245\351\227\250/index.html" deleted file mode 100644 index b710a91971..0000000000 --- "a/files/zh-cn/mozilla/ipdl/\345\205\245\351\227\250/index.html" +++ /dev/null @@ -1,670 +0,0 @@ ---- -title: IPDL入门 -slug: Mozilla/IPDL/入门 -translation_of: Mozilla/IPDL/Tutorial ---- -

IPDL – IPC Inter-process communication Protocol Definition Language,全称的意思是进程间通信协议定义语言。这是Mozilla特有的一种使C++代码能以有组织地、安全地在进程或者线程间传递信息的语言。Firefox中有关多进程插件和选项卡的所有消息均以IPDL语言声明。

- -
如果想尝试添加一个新的IPDL协议, 参考 创建一个新的协议.
- -

所有的IPDL信息都是由 父端 和 子端 发送,二者也被称为 角色。 IPDL 协议 声明了 角色间该如何进行通信:它声明了角色间可能发送的消息,以及描述了何时允许发送消息的状态机。

- -

父端角色通常是对话中更持久的一方:

- - - - - - - - - - - - - - - - - - - - - - -
父端/子端角色
父端子端
IPC 选项卡Chrome 进程Content 进程
IPC 插件Content 进程Plugin 进程
- -

每个协议都会在单独的文件中声明。IPDL 编译器会据每个IPDL 协议中生成一些 C++头文件。生成的代码帮忙解决了 底层通信层(套接字和管道)的一些细节、构造和发送消息,以及确保所有角色遵守其规范,并处理一些错误情况。以下 IPDL代码 定义了 浏览器角色 和 插件角色 的非常基本的交互:

- -
async protocol PPlugin
-{
-child:async Init(nsCString pluginPath);
-  async Shutdown();
-
-parent:
-  async Ready();
-};
-
- -

这段代码声明了 PPlugin 协议。 有两条消息从 父端发送到了子端, Init()Shutdown()。 另外还有一条消息从子端发送到了父端, Ready()

- -
IPDL 协议要以字母 P开头. 声明了该协议的文件也必须是对应的名称,如 PPlugin.ipdl.
- -

生成的 C++ 代码

- -

PPlugin.ipdl 被编译后会在构建树目录 ipc/ipdl/_ipdlheaders/ 生成头文件PPluginParent.h,和  PPluginChild.h。PPluginParent 和 PPluginChild 都是待实现的抽象类. 每个传出消息都是可以调用的C++方法。每个传入的消息都是必须实现的纯虚拟C++^方法:

- -
class PPluginParent
-{
-public:
-  bool SendInit(const nsCString& pluginPath) {
-    // generated code to send an Init() message
-  }
-
-  bool SendShutdown() {
-    // generated code to send a Shutdown() message
-  }
-
-protected:
-  /**
-   * A subclass of PPluginParent must implement this method to handle the Ready() message.
-   */
-  bool RecvReady() = 0;
-};
-
-class PPluginChild
-{
-protected:
-  bool RecvInit(const nsCString& pluginPath) = 0;
-  bool RecvShutdown() = 0;
-
-public:
-  bool SendReady() {
-    // generated code to send a Ready() message
-  }
-};
-
- -

这些父级和子级抽象类负责所有的 “协议层” 问题, 如序列化数据,发送和接收消息,以及检查协议安全性。实现者需要做的是创建子类来执行每条消息中涉及的实际工作。下面是浏览器实现者 使用 PPluginParent 的一个非常简单的方法示例。

- -
class PluginParent : public PPluginParent
-{
-public:
-  PluginParent(const nsCString& pluginPath) {
-    // launch child plugin process
-    SendInit(pluginPath);
-  }
-
-  ~PluginParent() {
-    SendShutdown();
-  }
-
-protected:
-  bool RecvReady() {
-    mObservers.Notify("ready for action");
-  }
-};
-
- -

下面是C++实现者在增加插件过程中如何使用PPluginChild的代码:

- -
class PluginChild : public PPluginChild
-{
-protected:
-  void RecvInit(const nsCString& pluginPath) {
-    mPluginLibrary = PR_LoadLibrary(pluginPath.get());
-    SendReady();
-  }
-  void RecvShutdown() {
-    PR_UnloadLibrary(mPluginLibrary);
-  }
-
-private:
-  PRLibrary* mPluginLibrary;
-};
-
- -

调用子流程并将这些协议角色 关联到我们的IPC “传输层” 超出了本文档的范围。有关更多详细信息,请参见 IPDL进程和线程
-
- 因为 协议消息 被表示为C++方法,所以很容易忘记它们实际上是异步消息:默认情况下,C++方法将在消息被分发之前立即返回。
-
- Recv* 方法的参数(本例中的 const nsCString& pluginPath) 是对临时对象的引用,因此如果需要保留它们的数据,请复制它们。

- -

方向

- -

每种消息类型都包括一个“方向”。消息方向 是指 消息是可以从父端 发送到 子端,抑或是从子端发送到父端,或者两种方式都可以。有三个关键字充当了方向说明符。上面介绍的 child,第二个是 parent,这意味着在 parent 标签下声明的消息只能从 子端发送到父端。第三个是both,这意味着声明的消息可以进行双向发送。下面的简要示例 显示了如何使用这些 说明符,以及这些说明符如何 影响 生成的 抽象角色类。

- -
// PDirection.ipdl
-async protocol PDirection
-{
-child:async Foo();  // can be sent from-parent-to-child
-parent:
-  async Bar();  // can be sent from-child-to-parent
-both:async Baz();  // can be sent both ways
-};
-
- -
// PDirectionParent.h
-class PDirectionParent
-{
-protected:
-  virtual void RecvBar() = 0;
-  virtual void RecvBaz() = 0;
-
-public:
-  void SendFoo() { /* boilerplate */ }
-  void SendBaz() { /* boilerplate */ }
-};
-
- -
// PDirectionChild.h
-class PDirectionChild
-{
-protected:
-  virtual void RecvFoo() = 0;
-  virtual void RecvBaz() = 0;
-
-public:
-  void SendBar() { /* boilerplate */ }
-  void SendBaz() { /* boilerplate */ }
-};
-
- -

您可以在协议规范中多次使用  childparent, 和 both标签。它们的行为类似于C++中的publicprotected, 和 private 标签。

- -

参数

- -

消息声明允许任意数量的 参数。参数指定与消息一起发送的数据。它们的值由 发送方 序列化,由 接收方 反序列化。IPDL支持内置 和 自定义基元类型,以及 联合union 和数组。

- -
-
-
-

内置的简单类型包括C++整型(bool,char,int,double) 和 XPCOM字符串类型(nsString,nsCString)。IPDL会自动导入这些类型,因为它们很常见,而且base IPC 库知道如何序列化和反序列化这些类型。有关自动导入类型的最新列表,请参见 ipc/ipdl/ipdl/builtin.py 。

- -

角色 可以作为参数传递。C++签名将在一侧接受 PProtocolParent*,在另一侧将其转换为PProtocolChild*。

- -

Maybe 类型

- -

如果要传递可能未定义的参数,可以在类型名称后添加? 后缀。接下来你就可以传递 mozilla::Maybe 对象而不是具体的值。

- -
protocol PMaybe
-{
-child:
-  async Maybe(nsCString? maybe);
-};
-
- -

自定义基本类型

- -

当需要发送 IPDL内置类型 之外的 类型数据 时,可以在IPDL规范中添加  using 声明。您的C++代码必须提供 自定义序列化程序和反序列化 程序。

- -
using mozilla::plugins::NPRemoteEvent;
-
-sync protocol PPluginInstance
-{
-child:async HandleEvent(NPRemoteEvent);
-};
-
- -

联合Union

- -

IPDL 内置支持声明 联合Union 类型。

- -
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
-
-union Variant
-{
-  void_t;
-  bool;
-  int;
-  double;
-  nsCString;
-  PPluginScriptableObject;
-};
- -

此 联合Union 生成一个C++接口,其内容如下:

- -
struct Variant
-{
-  enum Type {
-    Tvoid_t, Tbool, Tint, Tdouble, TnsCString, TPPlugionScriptableObject
-  };
-  Type type();
-  void_t& get_void_t();
-  bool& get_bool();
-  int& get_int();
-  double& get_double();
-  nsCString& get_nsCString();
-  PPluginScriptableObject* get_PPluginScriptableObject();
-};
-
- -

Union.type() 可用于确定 IPDL 消息处理程序中接收到的联合Union 类型,其余函数 给予对其内容的访问权限。要初始化 联合Union ,只需为其分配一个有效值,如下所示:

- -
aVariant = false;
-
- -

结构 Struct

- -

IPDL 具有对 可序列化数据类型 的 任意集合 的内置支持。

- -
struct NameValuePair
-{
-  nsCString name;
-  nsCString value;
-};
- -

在实现代码中,可以像这样创建和使用这些结构:

- -
NameValuePair entry(aString, anotherString);
-foo(entry.name(), entry.value()); // Named accessor functions return references to the members
-
- -

数组 Array

- -

IPDL具有简单的数组语法:

- -
InvokeMethod(nsCString[] args);
- -

·在C++中,这被转换为 nsTArray 引用:

- -
virtual bool RecvInvokeMethod(nsTArray<nsCString>& args);
-
-
-
-
- -

如果在单独的  .ipdlh 文件中定义了  IPDL生成的数据结构,则可以在多个 协议 中使用它们。这些文件必须像常规 .ipdl 文件一样添加到ipdl.mk  makefile中,并且它们使用相同的语法(除了它们不能声明协议)。要使用  Foo.ipdlh 中定义的结构,请按如下方式包含它。

- -
// in a .ipdl file
-include Foo;
-
- -

同步和RPC消息传递

- -

到目前为止,所有消息都是异步的。消息发送出去的同时,C++方法会立即返回。但是,如果我们希望等待消息被处理,或者从消息中获取返回值,该怎么办呢?

- -

在 IPDL 中,有三种不同的语义:

- -
    -
  1. 异步(asynchronous) 语义;发送方未被阻塞。
  2. -
  3. 等待,直到接收方确认它收到了消息。我们称之为 同步(synchronous 语义,因为发送方阻塞,直到接收方接收到消息并发回回复。消息可能具有返回值。
  4. -
  5.  rpc 语义是同步语义的变体,见下文。
  6. -
- -

请注意,父端 可以向 子端 发送消息,反之亦然,因此上述三种情况下的“发送者”和“接收者”可以是父端  或 子端 。消息传递语义以 同样的方式 应用于两个方向。因此,例如在从 子端 到 父端的同步语义中, 子端 将阻塞,直到 父端 接收到消息 和 响应到达为止,而在从父端 到 子端 的异步语义中,父端 不会阻塞。

- -

创建插件实例时,浏览器应该阻塞,直到实例创建完成,并且需要插件返回的一些信息:

- -
sync protocol PPluginInstance
-{
-child:
-    sync Init() returns (bool windowless, bool ok);
-};
-
- -

我们在插件协议中添加了两个新的关键字,sync returns 同步(sync)  将消息标记为正在同步发送。returns 关键字 标识了 在对消息的响应中 返回的值列表的开始。

- -

异步消息的返回值

- -

Bug 1313200 引入了 将 returns  与 async异步 消息一起使用的能力:

- -
protocol PPluginInstance
-{
-child:
-    async AsyncInit() returns (bool windowless, bool ok);
-    async OtherFunction() returns (bool ok);
-};
-
- -

对于调用方,每个带有 returns 块的 async 异步消息 MessageName 都将为 SendMessageName 生成两个重载。第一个重载将有一个 resolve回调 和 reject 回调 作为其最后两个参数;第二个重载将没有任何 额外 参数,但它将返回 PProtocol{Parent,Child}::MessageNamePromise ,这是一个 MozPromise类型。

- -

第一个重载的 resolve 回调 以及 MozPromise Then() 方法的成功回调都只有一个参数。如果消息只返回returns 一个值 (例如上面的OtherFunction),则对于resolve 和success回调,参数都是returns返回值本身(作为const常量引用);如果消息returns 返回多个值(例如上面的InitAsync),则对于resolve 和success 回调,参数都是返回值的元组(例如,Tuple<bool, bool>)。另一方面, reject/failure  回调接受 mozilla::ipc::ResponseRejectReason&&,并在发生致命错误(如IPC错误)时调用。因此,除了 callback/promise 样式响应处理之外,这两个重载在功能上是等效的。

- -

生成的C++代码如下:

- -
class PPluginInstanceParent
-{
- public:
-  typedef MozPromise<Tuple<bool, bool> ResponseRejectReason, true> AsyncInitPromise;
-  typedef MozPromise<bool, ResponseRejectReason, true> OtherFunctionPromise;
-
-  void
-  SendAsyncInit(mozilla::ipc::ResolveCallback<Tuple<bool, bool>>&& aResolve,
-                mozilla::ipc::RejectCallback&& aReject);
-
-  RefPtr<AsyncInitPromise>
-  SendAsyncInit();
-
-  void
-  SendOtherFunction(mozilla::ipc::ResolveCallback<bool>&& aResolve,
-                    mozilla::ipc::RejectCallback&& aReject);
-
-  RefPtr<OtherFunctionPromise>
-  SendOtherFunction();
-};
-
- -

在被调用方,除了声明的消息参数外,RecvMessageName 将有一个 MessageNameResolver&& 函数作为其最终(附加)参数。调用此函数将 初始化 调用传递给SendMessageName的回调 或 SendMessageName返回的promise解析。
-
- 生成的C++将产生如下所示的结果:

- -
class PPluginInstanceChild
-{
- public:
-  typedef std::function<void(Tuple<const bool&, const bool&>)> AsyncInitResolver;
-  typedef std::function<void(const bool&)> OtherFunctionResolver;
-
-  virtual mozilla::ipc::IPCResult
-  RecvAsyncInit(AsyncInitResolver&& aResolve) = 0;
-
-  virtual mozilla::ipc::IPCResult
-  RecvOtherFunction(OtherFunctionResolver&& aResolver) = 0
-};
-
- -

为了使程序员更容易注意到阻塞的本质,Synchronous和RPC消息的C++方法名称是不同的:

- - - - - - - - - - - - - - - - - - - - - -
发送方接收方
async/syncSendMessageNameRecvMessageName
rpcCallMessageNameAnswerMessageName
- -

消息语义强度

- -

IPDL协议 也像消息一样具有 “语义限定符”。这里的不同之处在于这里的语语义限定符是可选的; 默认语义是异步的。 必须指出的是 协议的语义至少与其 最强的消息语义 一样“强”,其中同步语义 “强于” 异步。这意味着异步协议无法在不违反 此类型规则 的情况下声明同步消息,而同步协议可以声明异步消息。下面显示了具有同步消息的恰当协议。

- -
sync protocol PPluginInstance
-{
-child:
-    sync Init() returns (bool windowless, bool ok);
-};
- -

该方法生成的C++代码将 外参指针 用于 返回值:

- -
class PPluginInstanceParent
-{
-  ...
-  bool SendInit(bool* windowless, bool* ok) { ... };
-};
-
-class PPluginInstanceChild
-{
-  ...
-  virtual bool RecvInit(bool* windowless, bool* ok) = 0;
-}
- -

RPC 语义

- -

“RPC” 代表“远程过程调用”,该第三种语义对 过程调用语义 进行建模。RPC 和 sync 语义之间的差别, 快速总结一下就是,RPC 允许“重入”消息处理程序:虽然参与者在等待RPC“调用”的“应答”时被阻塞,但它可以被 解除阻塞 以处理新的传入RPC调用

- -

在下面的示例协议中,子端角色 提供了一个 “CallMeCallYou()” RPC接口,父接口提供一个 “CallYou()” RPC接口。 rpc 限定符意味着,如果父对象对子参与者调用“CallMeCallYou()”,那么子参与者在服务这个调用时,可以回调到父参与者的 “CallYou()” 消息。

- -
rpc protocol Example {
-child:
-    rpc CallMeCallYou() returns (int rv);
-
-parent:
-    rpc CallYou() returns (int rv);
-};
-
- -

如果这是一个sync 同步协议,那么在为“CallMeCallYou()”消息提供服务时,将不允许 子端角色 调用 父端角色 的 “CallYou()” 方法。(子端角色 将被 极端“偏见” 终止。)

- -

首选语义

- -

尽可能使用异步async 语义。
-
- 不鼓励对 消息回复 进行阻塞。如果您真的需要阻塞 回复,请 非常小心 地使用sync 同步语义。不小心使用同步消息可能会陷入麻烦;虽然 IPDL 可以检查 和/或 保证您的代码不会死锁,但很容易通过阻塞导致严重的性能问题。
-
- 请不要使用RPC语义。RPC语义的存在主要是为了支持 远程插件(NPAPI),这我们别无选择。

- -
Chrome 对 content调用(用于IPC选项卡) 必须仅使用异步语义。为了保持响应性,chrome 进程需要永不阻塞 可能处于繁忙或挂起的 content 进程。
- -

消息分发顺序

- -

传递是“按顺序”的,也就是说,消息按照发送的顺序传递给接收者,而不考虑消息的语义。如果角色A发送消息M1,接着是M2来发送给角色B,B将被唤醒以处理M1,然后是M2。

- -

子协议和协议管理

- -

到目前为止,我们已经看到了一个单一的协议,但现实世界中没有一个孤立的情况会有一个单一的协议。相反,协议被安排在子协议的受管层次结构中。子协议绑定到追踪其生命周期并充当工厂的“管理器”。协议层次结构从一个顶级协议开始,所有的 子协议角色 最终都是从该协议创建的。在Mozilla中有两个主要的顶层协议:用于远程插件的 PPluginModule和用于远程选项卡的 PContent

- -

以下示例扩展了 顶级的 plugin协议来管理插件实例。

- -
// ----- file PPlugin.ipdl
-
-include protocol PPluginInstance;
-
-rpc protocol PPlugin
-{
-    manages PPluginInstance;
-child:
-    rpc Init(nsCString pluginPath) returns (bool ok);
-    // This part creates constructor messages
-    rpc PPluginInstance(nsCString type, nsCString[] args) returns (int rv);
-};
-
- -
// ----- file PPluginInstance.ipdl
-
-include protocol PPlugin;
-
-rpc protocol PPluginInstance
-{
-    manager PPlugin;
-child:
-    rpc __delete__();
-    SetSize(int width, int height);
-};
-
- -

这个例子有几个新元素:`include protocol`将另一个协议声明导入到这个文件中。请注意,这不是预处理器指令,而是IPDL语言的一部分。生成的C++代码将为 导入的协议 提供适当的#include预处理器指令。
-
- `manages`语句声明此协议管理PPluginInstance。PPlugin协议必须为PPluginInstance角色声明构造函数和析构函数消息。`manages`语句还意味着PPluginInstance角色与创建它们的插件角色的生命周期有关:如果此PPlugin实例被销毁,则与其关联的所有PPluginInstance都将失效或销毁。
-
- 令人困惑的是,强制 构造函数和析构函数消息(分别为PPluginInstance 和 __delete__ )存在于不同的位置。 构造函数必须位于管理协议中,而析构函数属于 被管理的子协议。·这些消息具有与C++构造函数相似的语法,但行为不同。构造函数和析构函数像其他IPDL消息一样具有参数、方向、语义和返回值。必须为每个托管协议声明构造函数和析构函数消息。

- -

每个子协议必须包含一个`manager`语句。
-
- 在C++层,子类和父类中的子类都必须实现用于allocate和deallocate子协议角色的方法。构造函数和析构函数被转换为消息的标准C++方法。
-
- 注意:__delete__是一个内置构造,并且是唯一不需要重写实现的IPDL消息(即Recv/Answer__delete__)。然而,当应该对协议的析构 进行某些操作而不是使用DeallocPProtocol功能时,鼓励被覆盖的实现。

- -
class PPluginParent
-{
-  /* Allocate a PPluginInstanceParent when the first form of CallPluginInstanceConstructor is called */
-  virtual PPluginInstanceParent* AllocPPluginInstance(const nsCString& type, const nsTArray<nsCString>& args, int* rv) = 0;
-
-  /* Deallocate the PPluginInstanceParent after PPluginInstanceDestructor is done with it */
-  virtual bool DeallocPPluginInstance(PPluginInstanceParent* actor) = 0;
-
-  /* constructor message */
-  virtual CallPPluginInstanceConstructor(const nsCString& type, const nsTArray<nsCString>& args, int* rv) { /* generated code */ }
-
-  /* alternate form of constructor message: supply your own PPluginInstanceParent* to bypass AllocPPluginInstance */
-  virtual bool CallPPluginInstanceConstructor(PPluginInstanceParent* actor, const nsCString& type, const nsTArray<nsCString>& args, int* rv)
-  { /* generated code */ }
-
-  /* destructor message */
-  virtual bool Call__delete__(PPluginInstanceParent* actor) { /* generated code */ }
-
-  /* Notification that actor deallocation is imminent, IPDL mechanisms are now unusable */
-  virtual void ActorDestroy(ActorDestroyReason why);
-
-  ...
-};
-
-class PPluginChild
-{
-  /* Allocate a PPluginInstanceChild when we receive the PPluginInstance constructor */
-  virtual PPluginInstanceChild* AllocPPluginInstance(const nsCString& type, const nsTArray<nsCString>& args, int* rv) = 0;
-
-  /* Deallocate a PPluginInstanceChild after we handle the PPluginInstance destructor */
-  virtual bool DeallocPPluginInstance(PPluginInstanceChild* actor) = 0;
-
-  /* Answer the constructor message. Implementing this method is optional: it may be possible to answer the message directly in AllocPPluginInstance. */
-  virtual bool AnswerPPluginInstanceConstructor(PPluginInstanceChild* actor, const nsCString& type, const nsTArray<nsCString>& args, int* rv) { }
-
-  /* Answer the destructor message. */
-  virtual bool Answer__delete__(PPluginInstanceChild* actor) = 0;
-
-  /* Notification that actor deallocation is imminent, IPDL mechanisms are now unusable */
-  virtual void ActorDestroy(ActorDestroyReason why);
-
-  ...
-};
- -

子协议角色的生命周期

- -

AllocPProtocol 和 DeallocPProtocol 是一对匹配的函数。这些功能的典型实现是使用' new '和' delete ':

- -
class PluginChild : PPluginChild
-{
- virtual PPluginInstanceChild* AllocPPluginInstance(const nsCString& type, const nsTArray<nsCString>& args, int* rv)
-  {
-    return new PluginInstanceChild(type, args, rv);
-  }
-
-  virtual bool DeallocPPluginInstanceChild(PPluginInstanceChild* actor)
-  {
-    delete actor; // actor destructors are always virtual, so it's safe to call delete on them!
-    return true;
-  }
-
-  ...
-};
- -

然而,在某些情况下,外部代码可能包含对需要引用计数或其他生命周期策略的角色实现的引用。在这种情况下,alloc/dealloc 可以执行不同的操作。以下是引用计数的示例:

- -
class ExampleChild : public nsIObserver, public PExampleChild { ... };
-
-virtual PExampleChild* TopLevelChild::AllocPExample()
-{
-  RefPtr<ExampleChild*> actor = new ExampleChild();
-  return actor.forget();
-}
-
-virtual bool TopLevelChild::DeallocPExample(PExampleChild* actor)
-{
-  NS_RELEASE(static_cast<ExampleChild*>(actor));
-  return true;
-}
-
- -

如果实现协议的对象不能在AllocPFoo内构造,先前已经构造,并且在其整个生命周期中不需要IPDL连接,或者实现引用计数的协议(第一种形式的构造函数不可用),则可以使用第二种形式的 SendPFooConstructor:

- -
class ExampleChild
-{
-public:
-    void DoSomething() {
-        aManagerChild->SendPExampleConstructor(this, ...);
-    }
-};
-
- -

在内部,第一个构造函数表单只需调用

- -
PExample(Parent|Child)* actor = AllocPExample(...);
-SendPExampleConstructor(actor, ...);
-return actor;
-
- -

效果一致。

- -

子协议删除

- -

值得了解协议删除过程。·考虑到简单的协议:

- -
// --- PExample.ipdl
-include protocol PSubExample;
-
-async protocol PExample
-{
-    manages PSubExample;
-
-parent:
-    async PChild();
-};
-
-// --- PSubExample.ipdl
-include protocol PExample;
-
-async protocol PSubExample
-{
-    manager PExample;
-
-child:
-    async __delete__();
-};
-
- -

我们假设存在 PSubExampleParent/Child,这样一些元素现在希望从父端触发协议的删除。

- -
aPSubExampleParent->Send__delete__();
- -

will trigger the following ordered function calls:

- -
PSubExampleParent::ActorDestroy(Deletion)
-/* Deletion is an enumerated value indicating
-   that the destruction was intentional */
-PExampleParent::DeallocPSubExample()
- -
PSubExampleChild::Recv__delete__()
-PSubExampleChild::ActorDestroy(Deletion)
-PExampleChild::DeallocPSubExample()
- -

ActorDestroy是一个生成的函数,它允许代码在知道参与者释放即将到来的情况下运行。·这对于生命周期在IPDL之外的角色很有用 。例如,可以设置一个标志,表明与IPDL相关的功能不再安全使用。

- -

从C++访问协议树

- -

The IPDL compiler generates methods that allow actors to access their manager (if the actor isn't top-level) and their managees (if any) from C++.  For a protocol PFoo managed by PManager, that manages PManagee, the methods are

- -

IPDL编译器生成允许参与者从C++访问其管理器(如果参与者不是顶级)和受管对象(如果有的话)的方法。对于协议PFoo,由 管理 PManagee的 PManager管理,这些方法是

- -
PManager* PFoo::Manager()
-const InfallibleTArray<PManagee*> PFoo::ManagedPManagee();
-void PFoo::ManagedPManagee(InfallibleTArray<PManagee*>&);
-
- -

关闭和错误处理

- -

实现IPDL消息的C++方法返回bool:true表示成功,false表示灾难性失败。如果数据已损坏或格式错误,则消息实现应从消息实现返回false。只要消息实现返回false,IPDL就会立即开始灾难性的错误处理:子进程(tab或plugin)的通信通道将被断开,并且进程将终止。对于“正常”错误条件,如无法加载网络请求,不要从消息处理程序返回false!正常的错误应该用消息或返回值发出信号。

- -

注意: 以下段落尚未实施. IPDL跟踪两个端点之间的所有活动协议。如果子侧崩溃或挂起::

- - - -

销毁管理器协议时,将通知所有子协议:

- - - -

当顶层协议被破坏时,这等同于关闭该连接的整个IPDL机制,因为不能再发送更多的消息,并且所有子协议都被销毁。

diff --git a/files/zh-cn/mozilla/javascript-dom_prototypes_in_mozilla/index.html b/files/zh-cn/mozilla/javascript-dom_prototypes_in_mozilla/index.html deleted file mode 100644 index 5136550830..0000000000 --- a/files/zh-cn/mozilla/javascript-dom_prototypes_in_mozilla/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: JavaScript-DOM Prototypes in Mozilla -slug: Mozilla/JavaScript-DOM_Prototypes_in_Mozilla -translation_of: Mozilla/JavaScript-DOM_Prototypes_in_Mozilla ---- -
-

Prototype setup on an XPConnect wrapped DOM node in Mozilla

-
- -

When a DOM node is accessed from JavaScript in Mozilla, the native C++ DOM node is wrapped using XPConnect and the wrapper is exposed to JavaScript as the JavaScript representation of the DOM node. When XPConnect wraps a C++ object it will create a JSObject that is unique to this C++ object. In the case where the C++ object has class info (nsIClassInfo), the JSObject is a more or less empty JSObject which is not really that special. All the methods that are supposed to show up on this JSObject are actually not properties of the object itself, but rather properties of the prototype of the JSObject for the wrapper (unless the C++ object's class info has the flag nsIXPCScriptable::DONT_SHARE_PROTOTYPE set, but lets assume that's not the case here).

- -

As an example of this let's look at an HTML image element in a document.

- -
var obj = document.images[0];
-
- -

Here, obj will not really have any properties (except for the standard JSObject properties such as constructor, and the non-standard __parent__, __proto__, etc.), all the DOM functionality of obj comes from obj's prototype (obj.__proto__) that XPConnect sets up when exposing the first image in document to JavaScript. Here are a few of the properties of obj's prototype:

- -
obj.__proto__
-  parentNode (getter Function)
-  src (getter and setter Functions)
-  getElementsByTagName (Function)
-  TEXT_NODE (Number property, constant)
-  ...
-
- -

All those properties come from the interfaces that the C++ image object (nsHTMLImageElement) implements and chooses to expose to XPConnect through the object's class info. One of these interfaces is nsIDOMHTMLImageElement, others are nsIDOMNSHTMLImageElement (Netscape extensions to the standard interface), nsIDOMEventTarget, nsIDOMEventListener, nsIDOM3Node, and so on.

- -

The prototype object that XPConnect creates for the classes that have class info are shared within a scope (window). Because of this, the following holds true (assuming img1 and img2 are two different image objects in the same document):

- -
img1.__proto__ === img2.__proto__
-
- -

If img1 would come from one document and img2 from another document, then the above would not be true. Both prototypes would look identical, but they would be two different JSObject's.

- -

This sharing of prototypes lets users do cool things like modify how all instances of a given class works by modifying the prototype of one instance. As an example:

- -
function bar() {
-  alert("Hello world!");
-}
-
-document.images[0].__proto__.foo = bar;
-
- -

This would make every image in this document have a callable foo property (i.e. a foo() method).

- -

Alternatively, one can access and modify the prototype of an HTMLImageElement through the prototype property of the constructor:

- -
HTMLImageElement.prototype.foo = bar;
-
- -

Modifying the prototype of a Host object is not guaranteed by ECMAScript specification. Moreover, no specification guarantees that there will be a globally available HTMLImageElement, or that such object will be the constructor for any arbitrary image's [[Prototype]].

- -

A third way through which one can access the prototype of an object is through the constructor property of the object, which itself points (initially) to the constructor:

- -
document.images[0].constructor.prototype.foo = bar;
-
- -

Note though, the above may or may not work in Mozilla.

- -

So far so good; we have shared prototypes, and XPConnect gives us most of this automatically. But this is not good enough, in addition to being able to share and represent each "class" with a constructor, we also want users to be able to extend interfaces, like Node. Node is a DOM interface, but there are no pure Node instances; there are lots of different classes that implement Node (HTMLImageElement, HTMLDocument, ProcessingInstruction, et c.).

- -

But the fact that an instance of a Node will never exist in Mozilla does not mean that the Node interface is useless, in fact, Node can be extended just as we've been doing. If you think back to the HTMLImageElement examples above, those examples let you define new properties on all image elements. By modifying the Node top-level object, you can do similar things to all objects that implement Node. This means you can add a property to every node in a DOM tree by doing something like this:

- -
Node.prototype.foo = bar;
-
- -

Again, modifying host objects is an unsafe practice. It is not guaranteed to work or be error-free in any implementation. It is not standard and cannot be expected to have any result.

- -

Here is an attempt to modify a host object:

- -
   (function(){
-       try {
-           Image.prototype.src = 1;
-       }
-       catch(ex){ alert(ex); }
-   })();
-
- -

This demonstrates that the Image constructor, a host object supported in nearly all browsers for Mac and Windows, has a prototype property, and that an attempt to modify the prototype's src - property results in an error.

- -

Another example would be modifying the pageX property of a MouseEvent instance. The pageX property actually needs a patch because it doesn't get set correctly in initMouseEvent {{ Bug(411031) }}.

- -

Here is a diagram that shows the prototype layout of a HTMLDivElement in Mozilla:

- -
   HTMLDivElement.prototype
-             |
-             |.__proto__
-             |
-    HTMLElement.prototype
-             |
-             |.__proto__
-             |
-      Element.prototype
-             |
-             |.__proto__
-             |
-       Node.prototype
-             |
-             |.__proto__
-             |
-      Object.prototype
-             |
-             |.__proto__
-             |
-           null
-
- -

If you have an instance of a HTMLDivElement in JavaScript, the following will hold true:

- -
div.__proto__ === HTMLDivElement.prototype
-
- -

which means that the following should also be true:

- -
div.__proto__ === div.constructor.prototype
-
- -

Non Standard

- -

No browser is required to provide modifiable __proto__, nor a global Node, nor provide any way to get at host objects nor their associated prototypes. If such objects are provided, they are not guaranteed by any specification to have any effect on the environment. Results in other browsers is not guaranteed.

- -

So how does all this work in the Mozilla DOM code?

- -

It all happens in XPConnect and nsDOMClassInfo.{cpp,h} in the DOM code. During startup, the nsDOMClassInfo code registers two different types of "global names", these are names of properties of the global object with special meaning to the DOM code. The two types of "global names" are class constructor names and class prototype names. What's the difference? Class constructor names are names of real classes, and class prototype names are names of "classes" that are inherited by real classes, but are not real classes. A few examples of class constructor names would be HTMLImageElement, HTMLDocument, Element, NodeList, and two examples of class prototype names would be Node and CharacterData.

- -

This registration is done with the nsScriptNameSpaceManager, which is in charge of keeping track of what names are registered in the global namespace, and what kinds of names those names are (i.e. class constructor name, class prototype name). When a class constructor name is registered (nsGlobalNameStruct::eTypeClassConstructor), the nsScriptNameSpaceManager is given a DOM class info ID (a 32 bit ID that identifies class info defined in nsDOMClassInfo). When a class prototype name is registered (nsGlobalNameStruct::eTypeClassProto), the nsScriptNameSpaceManager is given the nsIID of the interface that is inherited by the class which the registered name is a prototype of (e.g. NS_GET_IID(nsIDOMNode) for Node). nsScriptNameSpaceManager also deals with other types of names, but those are unrelated to the DOM object prototype setup, so we will ignore those here.

- -

Once the registration is done, the nsDOMClassInfo code uses the registry every time a named property is resolved on a global object (because of this, the nsScriptNameSpaceManager needs to be pretty fast at looking things up in its registry; that's why it is a hash table). When a property is resolved on the global object, the nsDOMClassInfo code will ask the nsScriptNameSpaceManager if the name is a known name (in nsWindowSH::GlobalResolve()), and if the name is known, the code will look at the type of the name and act accordingly.

- -

If a class constructor or class prototype name is resolved, the class info code will define the constructor for that class, and also define the prototype property of that constructor (i.e. HTMLImageElement.prototype). The prototype of a constructor will either be the prototype object that XPConnect creates for a class (if the name is the name of a real class) or simply an empty JSObject of a specific JSClass that is defined in nsDOMClassInfo.cpp (nsDOMClassInfo::sDOMConstructorProtoClass).

- -

As the prototype property of the constructor is being defined, the code also sets up the prototype of the prototype property of the constructor (i.e. HTMLImageElement.prototype.__proto__). To do this, the code figures out what the name of the immediate prototype of the class is by looking at the parent of the primary interface in the class info (if the name is a class constructor, such as HTMLImageElement) or by looking at the parent of the interface that the IID stored in the nsScriptNameSpaceManager for this name represents (if the name is a class prototype, such as Node). Once the name of the parent interface is known (and the name is not nsISupports) the code will look up a property by that name on the global object. This will cause the code to recurse down along the parent chain of the interface of interest for the name we started out resolving (i.e. nsWindowSH::GlobalResolve() will be called for every name on the parent chain). The result of this recursion is that by resolving the name HTMLImageElement, we'll create the constructor HTMLImageElement, HTMLElement, Element, and Node, and the prototype properties on all those constructor will be correctly set up. This means that the next time the name of a class constructor is resolved in the same scope, say HTMLAnchorElement, the code will resolve the name HTMLAnchorElement, find the parent name, which is HTMLElement, and resolve that, but since we've already resolved HTMLElement as a result of resolving the name HTMLImageElement earlier, the recursion will stop right there.

- -

Ok, so that's how class constructor and their prototype properties are set up, what about the actual prototype chain of a XPConnected DOM object? The beauty of this code is that the prototype property of a class constructor is the real XPConnect prototype for that class. When XPConnect wraps a DOM object (i.e. creates a XPConnect JavaScript wrapper for a DOM object), XPConnect will call the scriptable helper method nsDOMClassInfo::PostCreate() which will make sure the prototype chain of the wrapper JSObject is properly set up. In this call, the nsDOMClassInfo code just needs to resolve the name of the class on the global object, and the prototype will be set up by the resolving code (nsWindowSH::GlobalResolve()). This is also done only once per class, nsDOMClassInfo::PostCreate() checks if the prototype of the prototype of the wrapper JSObject (i.e. obj.__proto__.__proto__) has been set up already, if it has, then there's nothing left to do in nsDOMClassInfo::PostCreate().

- -
-

Original Document Information

- - -
diff --git a/files/zh-cn/mozilla/javascript_code_modules/assert.jsm/index.html b/files/zh-cn/mozilla/javascript_code_modules/assert.jsm/index.html deleted file mode 100644 index a9cbfe6aeb..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/assert.jsm/index.html +++ /dev/null @@ -1,448 +0,0 @@ ---- -title: Assert.jsm -slug: Mozilla/JavaScript_code_modules/Assert.jsm -translation_of: Mozilla/JavaScript_code_modules/Assert.jsm ---- -

{{ gecko_minversion_header("31") }}

- -

The Assert.jsm JavaScript code module implements the CommonJS Unit Testing specification version 1.1, which provides a basic, standardized interface for performing in-code logical assertions with optional, customizable error reporting. To use it, you first need to import the code module into your JavaScript scope:

- -
Components.utils.import("resource://testing-common/Assert.jsm");
-
- -

Assert 类提供了执行常见逻辑断言的方法。

- -

Method overview

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
undefined ok(value, message);
undefined equal(actual, expected, message);
undefined notEqual(actual, expected, message);
undefined deepEqual(actual, expected, message);
undefined notDeepEqual(actual, expected, message);
undefined strictEqual(actual, expected, message);
undefined notStrictEqual(actual, expected, message);
undefined throws(block, expected, message);
Promise rejects(promise, expected, message);
undefined greater(lhs, rhs, message);
undefined greaterOrEqual(lhs, rhs, message);
undefined less(lhs, rhs, message);
undefined lessOrEqual(lhs, rhs, message);
undefined setReporter(reporterFunc);
undefined report(failed, actual, expected, message, operator);
- -

Constructor

- -

Creates a new Assert object.

- -
let assert = new Assert(reporterFunc);
-
- -

The new Assert instance, assert, uses reporterFunc to report assertion results or throws an AssertionError when an assertion fails, as default behavior.

- -

ok, equal, notEqual, deepEqual, notDeepEqual, strictEqual, notStrictEqual, throws, setReporter, report

- -

Methods

- -

ok()

- -

Pure assertion tests whether a value is truthy, as determined by !!guard.
- This statement is equivalent to assert.equal(true, !!guard, message_opt);. To test strictly for the value true, use assert.strictEqual(true, guard, message_opt);.

- -
undefined ok(
-  actual,
-  message
-);
-
- -
Parameters
- -
-
actual
-
Test subject to be evaluated as truthy
-
message
-
Short explanation of the expected result
-
- -

equal()

- -

The equality assertion tests shallow, coercive equality with ==.

- -
undefined equal(
-  actual,
-  expected,
-  message
-);
-
- -
Parameters
- -
-
actual
-
Test subject to be evaluated as equivalent to expected
-
expected
-
Test reference to evaluate against actual
-
message
-
Short explanation of the expected result
-
- -

notEqual()

- -

The non-equality assertion tests for whether two objects are not equal with !=.

- -
undefined notEqual(
-  actual,
-  expected,
-  message
-);
-
- -
Parameters
- -
-
actual
-
Test subject to be evaluated as not equivalent to expected
-
expected
-
Test reference to evaluate against actual
-
message
-
Short explanation of the expected result
-
- -

deepEqual()

- -

The equivalence assertion tests a deep equality relation.
- We check using the most exact approximation of equality between two objects to keep the chance of false positives to a minimum.
- JSON.stringify is not designed to be used for this purpose; objects may have ambiguous toJSON() implementations that would influence the test.

- -
undefined deepEqual(
-  actual,
-  expected,
-  message
-);
-
- -
Parameters
- -
-
actual
-
Test subject to be evaluated as equivalent to expected, including nested properties
-
expected
-
Test reference to evaluate against actual
-
message
-
Short explanation of the expected result
-
- -

notDeepEqual()

- -

The non-equivalence assertion tests for any deep inequality.

- -
undefined notDeepEqual(
-  actual,
-  expected,
-  message
-);
-
- -
Parameters
- -
-
actual
-
Test subject to be evaluated as not equivalent to expected, including nested properties
-
expected
-
Test reference to evaluate against actual
-
message
-
Short explanation of the expected result
-
- -

strictEqual()

- -

The strict equality assertion tests strict equality, as determined by ===.

- -
undefined strictEqual(
-  actual,
-  expected,
-  message
-);
-
- -
Parameters
- -
-
actual
-
Test subject to be evaluated as strictly equivalent to expected
-
expected
-
Test reference to evaluate against actual
-
message
-
Short explanation of the expected result
-
- -

notStrictEqual()

- -

The strict non-equality assertion tests for strict inequality, as determined by !==.

- -
undefined notStrictEqual(
-  actual,
-  expected,
-  message
-);
-
- -
Parameters
- -
-
actual
-
Test subject to be evaluated as not strictly equivalent to expected
-
expected
-
Test reference to evaluate against actual
-
message
-
Short explanation of the expected result
-
- -

throws()

- -

Expected to throw an error.

- -
undefined throws(
-  block,
-  expected,
-  message
-);
-
- -
Parameters
- -
-
block
-
Function block to evaluate and catch eventual thrown errors
-
expected
-
Test reference to evaluate against the thrown result from block
-
message
-
Short explanation of the expected result
-
- -

rejects()

- -

Expected to reject a promise. Returns a Promise that resolves when the promise either resolves or rejects.

- -
Promise rejects(
-  promise,
-  expected,
-  message
-);
-
- -
Parameters
- -
-
promise
-
Promise promise to wait for rejection and catch eventual thrown errors
-
expected
-
Test reference to evaluate against the thrown result from block
-
message
-
Short explanation of the expected result
-
- -

greater()

- -

The greater than assertion tests two numbers with the > operator.

- -
undefined greater(
-  lhs,
-  rhs,
-  message
-);
-
- -
Parameters
- -
-
lhs
-
The left hand side of the operator
-
rhs
-
The right hand side of the operator
-
message
-
Short explanation of the expected result
-
- -

greaterOrEqual()

- -

The greater or equal than assertion tests two numbers with the >= operator.

- -
undefined greaterOrEqual(
-  lhs,
-  rhs,
-  message
-);
-
- -
Parameters
- -
-
lhs
-
The left hand side of the operator
-
rhs
-
The right hand side of the operator
-
message
-
Short explanation of the expected result
-
- -

less()

- -

The lesser than assertion tests two numbers with the < operator.

- -
undefined less(
-  lhs,
-  rhs,
-  message
-);
-
- -
Parameters
- -
-
lhs
-
The left hand side of the operator
-
rhs
-
The right hand side of the operator
-
message
-
Short explanation of the expected result
-
- -

lessOrEqual()

- -

The lesser or equal than assertion tests two numbers with the <= operator.

- -
undefined lessOrEqual(
-  lhs,
-  rhs,
-  message
-);
-
- -
Parameters
- -
-
lhs
-
The left hand side of the operator
-
rhs
-
The right hand side of the operator
-
message
-
Short explanation of the expected result
-
- -

setReporter()

- -

Set a custom assertion report handler function.

- -
undefined setReporter(
-  reporterFunc
-);
-
- -
Parameters
- -
-
reporterFunc
-
Reporter handler function.
- Arguments passed in to this function are: -
-
err
-
An error object when the assertion failed or null when it passed
-
message
-
Message describing the assertion
-
stack
-
Stack trace of the assertion function.
-
-
-
- -

report()

- -

All of the aforementioned functions must throw an AssertionError when a corresponding condition is not met, with a message that may be undefined if not provided.
- All assertion methods provide both the actual and expected values to the assertion error for display purposes.
-
- This report method only throws errors on assertion failures, as per spec, but consumers of this module (think: xpcshell-test, mochitest) may want to override this default implementation.

- -
undefined report(
-  failed,
-  actual,
-  expected,
-  message,
-  operator
-);
-
- -
Parameters
- -
-
failed
-
Indicates if the assertion failed or not
-
actual
-
The result of evaluating the assertion
-
expected
-
Expected result from the test author
-
message
-
Short explanation of the expected result
-
operator
-
Operation qualifier used by the assertion method (ex: '==')
-
- -

Examples

- -

Custom reporter example

- -
Components.utils.import("resource://testing-common/Assert.jsm");
-
-let assert = new Assert();
-
-assert.setReporter(function customReporter(err, message, stack) {
-  if (err) {
-    do_report_result(false, err.message, err.stack);
-  } else {
-    do_report_result(true, message, stack);
-  }
-});
-
- -

See also

- - diff --git a/files/zh-cn/mozilla/javascript_code_modules/dict.jsm/index.html b/files/zh-cn/mozilla/javascript_code_modules/dict.jsm/index.html deleted file mode 100644 index b27d445241..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/dict.jsm/index.html +++ /dev/null @@ -1,344 +0,0 @@ ---- -title: Dict.jsm -slug: Mozilla/JavaScript_code_modules/Dict.jsm -translation_of: Mozilla/JavaScript_code_modules/Dict.jsm ---- -

{{ gecko_minversion_header("5.0") }}

- -

{{ warning("This is obsolete - new code should use Map().") }}

- -

The Dict.jsm JavaScript code module offers routines for managing dictionaries of key/value pairs. To use it, you first need to import the code module into your JavaScript scope:

- -
Components.utils.import("resource://gre/modules/Dict.jsm");
-
- -

创建一个字典

- -

You can create a new, empty dictionary by simply calling the Dict() constructor:

- -
var newDict = new Dict();
-
- -

If you wish, you may also pass in an object literal of key/value pairs with which to initialize the dictionary:

- -
var someObj = {};
-var newDict = new Dict({key1: "foo", key2: someObj});
-
- -

Note that values may be any JavaScript object type.

- -
Note: You can actually specify non-strings as keys; these are converted to strings before being used, so they're documented here as if they were a string parameter.
- -

从Firefox 19开始,你可以通过传入一个JSON字符串来初始化字典对象:

- -
var someJSON = '{key1: "foo", key2: {}}';
-var newDict = new Dict(someJSON);
-
- -
注: 传入的任意字符串都会被当成JSON字符串来对待.
- -

方法概述

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Dict copy();
boolean del(String aKey);
Object get(String aKey, [optional] Object aDefault);
boolean has(String aKey);
Array listitems();
Array listkeys();
Array listvalues();
void set(String aKey, Object aValue);
{{ fx_minversion_inline("19") }} String toJSON();
String toString();
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性名类型描述
countNumber字典中键值对的个数
itemsIterator -

Returns an iterator over all of the items in the dictionary; each item is returned as a pair (a two-element array) with the first element being the key and the second being the value.

- -
Note: The order in which items are returned is arbitrary, and may change without notice. In addition, if the dictionary changes during iteration, no guarantees are made as to what will happen.
-
keysIterator -

Returns an iterator over all the keys in the dictionary.

- -
Note: The order in which items are returned is arbitrary, and may change without notice. In addition, if the dictionary changes during iteration, no guarantees are made as to what will happen.
-
valuesIterator -

Returns an iterator over all the values in the dictionary.

- -
Note: The order in which items are returned is arbitrary, and may change without notice. In addition, if the dictionary changes during iteration, no guarantees are made as to what will happen.
-
- -

构造器

- -

Dict()

- -

创建并返回一个新的字典对象.

- -
Dict Dict();
-
-Dict Dict(
-  Object initalKeysAndValues
-);
-
- -
参数
- -
-
initialKeysAndValues {{ optional_inline() }}
-
A object containing key/value pairs with which to initialize the dictionary.
-
- -
返回值
- -

一个新的字典对象,实现有下面这些方法.

- -

方法

- -

copy()

- -

返回一个字典对象的浅拷贝; that is, a copy of the dictionary including the items immediately included within the dictionary; however, any objects referenced by those top-level objects are not copied.

- -
Dict copy();
-
- -
参数
- -

- -
返回值
- -

A new dictionary object containing the same top-level items as the original dictionary on which the copy() method was called.

- -

del()

- -

根据指定的键,从该字典中删除一个键值对.

- -
boolean del(
-  String aKey
-);
-
- -
参数
- -
-
aKey
-
从该字典中要删除的键.
-
- -
返回值
- -

如果成功删除指定的键值对,则返回true,如果指定的键不存在,则返回false.

- -

get()

- -

返回该字典对象中指定键所对应的值.

- -
Object get(
-  String aKey,
-  [optional] Object aDefault
-);
-
- -
参数
- -
-
aKey
-
The key whose value should be returned.
-
aDefault {{ optional_inline() }}
-
The value to return if the specified key isn't found. If you don't specify a default value, undefined is returned for keys that aren't found.
-
- -
返回值
- -

The value of the specified key, or undefined if no matching key was found.

- -

has()

- -

判断指定的键是否存在与当前字典对象中.

- -
boolean has(
-  String aKey
-);
-
- -
参数
- -
-
aKey
-
判断该键是否存在与当前字典对象中..
-
- -
返回值
- -

如果指定的键存在与当前字典中,则返回true,否则返回false.

- -

listitems()

- -

返回一个由当前字典中所有键值对组成的数组.

- -
注: 数组中元素的排列顺序是任意的.
- -
Array listitems();
-
- -
参数
- -

- -
返回值
- -

一个由当前字典中所有键值对组成的数组.

- -

listkeys()

- -

返回一个由当前字典中所有键组成的数组.

- -
注: 数组中元素的排列顺序是任意的.
- -
Array listkeys();
-
- -
参数
- -

- -
返回值
- -

一个由当前字典中所有键组成的数组.

- -

listvalues()

- -

返回一个由当前字典中所有值组成的数组.

- -
注: 数组中元素的排列顺序是任意的.
- -
Array listvalues();
-
- -
参数
- -

- -
返回值
- -

一个由当前字典中所有值组成的数组.

- -

set()

- -

设置指定键所对应的值,如果该键不存在,则添加上这个新键.

- -
void set(
-  String aKey,
-  Object aValue
-);
-
- -
参数
- -
-
aKey
-
设置改建所对应的值.
-
aValue
-
为指定键所设置的新值.
-
- -

toJSON()

- -

返回一个代表当前字典的 JSON字符串.

- -
String toJSON();
-
- -
参数
- -

- -
返回值
- -

返回一个代表了该字典对象中所有键值对的JSON字符串,空字典将返回"{}".

- -

toString()

- -

返回一个代表该字典对象的字符串.

- -
String toString();
-
- -
参数
- -

- -
返回值
- -

返回一个代表了该字典对象中所有键值对的字符串,空字典将返回"{}".

- -

示例

- -

创建和填充字典

- -

下面的例子首先创建一个新的空字典,然后添加进一些键值对.

- -
var myDict = new Dict();
-myDict.set("name", "John Smith");
-myDict.set("email", "jsmith@example.com");
-myDict.set("phone", "650-555-1234");
-
- -

判断字典中指定的键是否存在

- -

接着上面的个例子,你可以检测某个键是否存在于myDict中:

- -
if (myDict.has("email")) {
-  /* an "email" key exists on the object */
-}
-
diff --git a/files/zh-cn/mozilla/javascript_code_modules/downloads.jsm/download/index.html b/files/zh-cn/mozilla/javascript_code_modules/downloads.jsm/download/index.html deleted file mode 100644 index 41230df3c4..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/downloads.jsm/download/index.html +++ /dev/null @@ -1,335 +0,0 @@ ---- -title: Download -slug: Mozilla/JavaScript_code_modules/Downloads.jsm/Download -translation_of: Mozilla/JavaScript_code_modules/Downloads.jsm/Download ---- -

 Download 对象仅仅表示下载,同时包含相关的状态和行为。这个对象是短时存在的,但是它可被包含在DownloadList 对象,因此它能够通过用户接口调用和跨sessions.

- -

调用Downloads.createDownload() 方法可以创建一个新的Download 对象。

- -

方法概览

- - - - - - - - - - - - - - - - - - - - - - - - - -
Promise start();
Promise launch();
Promise showContainingDirectory();
Promise cancel();
Promise removePartialData();
Promise whenSucceeded();
Promise finalize([optional] boolean aRemovePartialData);
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型描述
canceled {{ReadOnlyInline()}}boolean -

表示下载被取消。这个属性可设置为true,当被取消下载重新下载时被设置为false。

- -

This property becomes true as soon as the cancel() method is called, though the stopped property might remain false until the cancellation request has been processed. Temporary files or part files may still exist even if they are expected to be deleted, until the stopped property becomes true.

-
contentTypestring -

The MIME type of the download, for example "text/plain", or null if the MIME type is not available.

- -

This property may be populated or changed while the download is in progress, using the MIME type provided by the server.

-
currentBytes {{ReadOnlyInline()}}number -

Number of bytes currently transferred. This value starts at zero, and may be updated regardless of the value of hasProgress.

- -
Note: You shouldn't rely on this property being equal to totalBytes to determine whether the download is completed.  You should use the individual state properties instead, since this value may not be updated after the last piece of data is transferred.
-
error {{ReadOnlyInline()}}DownloadErrorWhen the download fails, this is set to a DownloadError instance indicating the cause of the failure. If the download has been completed successfully or has been canceled, this property is null. This property is reset to null when a failed download is restarted.
hasPartialData {{ReadOnlyInline()}}boolean -

Indicates whether, at this time, there is any partially downloaded data that can be used when restarting a failed or canceled download.

- -

This property is relevant while the download is in progress, and also if it failed or has been canceled. If the download has been completed successfully, this property is not relevant anymore.

- -

Whether partial data can actually be retained depends on the saver and the download source, and may not be known before the download is started.

-
hasProgress {{ReadOnlyInline()}}booleanIndicates whether this download's progress property is able to report partial progress while the download proceeds, and whether the value in totalBytes is relevant. This depends on the saver and the download source.
launchWhenSucceededbooleanIf this property is true when the download finishes successfully, the target file will be opened or executed automatically.
launcherPathstringLocal file path of the application to be used to launch the target file, or null if the file should be launched with the default application associated with the contentType property or the extension of the target file.
onchangeFunction -

This can be set to a function that is called after other properties change.

- -
-

Warning: This property cannot be used if the download is part of a DownloadList.

-
-
progress {{ReadOnlyInline()}}number -

Progress percent, from 0 to 100. Intermediate values are reported only if hasProgress is true.

- -
Note: You shouldn't rely on this property being equal to 100 to determine whether the download is completed. You should use the individual state properties (for example, the succeeded property) instead.
-
saver {{ReadOnlyInline()}}DownloadSaverSaver object associated with this download.
source {{ReadOnlyInline()}}DownloadSourceSource of this download.
startTime {{ReadOnlyInline()}}DateIndicates the start time of the download. When the download starts, this property is set to a valid Date object. The default value is null before the download starts.
stopped {{ReadOnlyInline()}}booleanIndicates that the download never started, has been completed successfully, failed, or has been canceled. This property becomes false when a download is started for the first time, or when a failed or canceled download is restarted.
succeeded {{ReadOnlyInline()}}booleanThis propery is true if the download has been completed successfully.
target {{ReadOnlyInline()}}DownloadTargetTarget of this download.
totalBytes {{ReadOnlyInline()}}number -

When hasProgress is true, this indicates the total number of bytes to be transferred before the download finishes; this value can be zero if the file is empty.

- -

Note: This property's value may not match the actual final size of the downloaded file if the download is encoded during the network transfer. You can use the DownloadTarget.size property to get the actual size of the completely-downloaded file once the download has succeeded.

- -

When hasProgress is false, this property is always zero.

-
tryToKeepPartialDataboolean -

Indicates whether any partially downloaded data should be retained, to use when restarting a failed or canceled download. The default is false.

- -

Whether partial data can actually be retained depends on the saver and the download source, and may not be known before the download is started.

- -

To have any effect, this property must be set before starting the download. Resetting this property to false after the download has already started will not remove any partial data.

- -
Note: If this property is set to true, care should be taken that partial data is removed before the reference to the download is discarded. This can be done using the removePartialData() or the finalize() methods.
-
- -

方法

- -

start()

- -

Starts the download for the first time, or restarts a download that failed or has been canceled.

- -

Calling this method when the download has been completed successfully has no effect, and the method returns a resolved promise. If the download is in progress, the method returns the same promise as the previous call.

- -

If the cancel() method was called but the cancellation process has not finished yet, this method waits for the cancellation to finish, then restarts the download immediately.

- -
Note: If you need to start a new download from the same source, rather than restarting a failed or canceled one, you should create a separate Download object with the same source as the current one.
- -
Promise start();
-
- -
Parameters
- -

None.

- -
Promise resolves to
- -

undefined when the download has finished successfully and you can access the target file.

- -
Promise can be rejected with
- -

DownloadError if the download failed.

- -

launch()

- -

Opens or executes the target file after download has completed.

- -

If the launcherPath property is null, the file will be opened with the default application for the MIME type specified in the contentType property. If the content type is not available, an attempt will be made to obtain it from the extension of the target file.

- -

If the launcherPath property is set, the file will be opened with the specified custom application.

- -
Promise launch();
-
- -
Parameters
- -

None.

- -
Promise resolves to
- -

undefined when the instruction to launch the file has been successfully given to the operating system. Note that the OS might still take a while until the file is actually launched.

- -

showContainingDirectory()

- -

Shows the folder containing the target file, or where the target file will be saved. This may be called at any time, even if the download failed or is currently in progress.

- -
Promise showContainingDirectory();
-
- -
Parameters
- -

None.

- -
Promise resolves to
- -

undefined when the instruction to open the containing folder has been successfully given to the operating system. Note that the OS might still take a while until the folder is actually opened.

- -

cancel()

- -

Cancels the download.

- -

The cancellation request is asynchronous. Until the cancellation process finishes, temporary files or part files may still exist even if they are expected to be deleted.

- -

In case the download completes successfully before the cancellation request could be processed, this method has no effect, and it returns a resolved promise. You should check the properties of the download at the time the returned promise is resolved to determine if the download was canceled.

- -

Calling this method when the download has been completed successfully, failed, or has been canceled has no effect, and the method returns a resolved promise. This behavior is designed for the case where the call to cancel happens asynchronously, and is consistent with the case where the cancellation request could not be processed in time.

- -
Promise cancel();
-
- -
Parameters
- -

None.

- -
Promise resolves to
- -

undefined when the cancellation process has finished.

- -
Promise can be rejected with
- -

Never rejected.

- -

removePartialData()

- -

Removes any partial data kept as part of a canceled or failed download.

- -

If the download is not canceled or failed, this method has no effect, and it returns a resolved promise. If the cancel() method was called but the cancellation process has not finished yet, this method waits for the cancellation to finish, then removes the partial data.

- -

After this method has been called, if the tryToKeepPartialData property is still true when the download is restarted, partial data will be retained during the new download attempt.

- -
Promise removePartialData();
-
- -
Parameters
- -

None.

- -
Promise resolves to
- -

undefined when the partial data has been successfully removed.

- -

whenSucceeded()

- -

Returns a promise that is resolved as soon as this download finishes successfully, even if the download was stopped and restarted meanwhile.

- -

You can use this property for scheduling download completion actions in the current session, for downloads that are controlled interactively. If the download is not controlled interactively, you should use the promise returned by the start() method instead, to check for success or failure.

- -
Promise whenSucceeded();
-
- -
Parameters
- -

None.

- -
Promise resolves to
- -

undefined when the download has finished successfully and you can access the target file.

- -
Promise can be rejected with
- -

Never rejected.

- -

finalize()

- -

Ensures that the download is stopped, and optionally removes any partial data kept as part of a canceled or failed download. After this method has been called, the download cannot be started again.

- -
Note: This method should be used in place of the cancel() and removePartialData() methods while shutting down or disposing of the download object, to prevent other callers from interfering with the operation. This is required because cancellation and other operations are asynchronous.
- -
Promise finalize(
-  boolean aRemovePartialData
-);
-
- -
Parameters
- -
-
aRemovePartialData {{optional_inline()}}
-
Whether any partially downloaded data should be removed after the download has been stopped. The default is false.
-
- -
Promise resolves to
- -

undefined when the operation has finished successfully.

- -

查看其他

- - diff --git a/files/zh-cn/mozilla/javascript_code_modules/downloads.jsm/index.html b/files/zh-cn/mozilla/javascript_code_modules/downloads.jsm/index.html deleted file mode 100644 index 1df73bfd16..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/downloads.jsm/index.html +++ /dev/null @@ -1,306 +0,0 @@ ---- -title: Downloads.jsm -slug: Mozilla/JavaScript_code_modules/Downloads.jsm -tags: - - Add-ons - - Download Manager - - Extensions - - Files - - JavaScript - - Modules - - NeedsTranslation - - TopicStub -translation_of: Mozilla/JavaScript_code_modules/Downloads.jsm ---- -

{{ gecko_minversion_header("26") }}

- -

The Downloads.jsm JavaScript code module provides a single entry point to interact with the downloading capabilities of the platform, including starting new downloads, controlling ongoing downloads, and retrieving download-related configuration. To use it, you first need to import the code module into your JavaScript scope:

- -
Components.utils.import("resource://gre/modules/Downloads.jsm");
-
- -

Method overview

- - - - - - - - - - - - - - - - -
Promise<Download> createDownload(Object aProperties);
Promise<void> fetch(aSource, aTarget, [optional] Object aOptions);
Promise<DownloadList> getList(aType);
Promise<DownloadSummary> getSummary(aType);
- -

Constants

- - - - - - - - - - - - - - - - - - - - -
ConstantDescription
PUBLICWork on downloads that were not started from a private browsing window.
PRIVATEWork on downloads that were started from a private browsing window.
ALLWork on both Downloads.PRIVATE and Downloads.PUBLIC downloads.
- -

Properties

- - - - - - - - - - - - - - -
AttributeTypeDescription
Error Read only ConstructorConstructor for a DownloadError object. When you catch an exception during a download, you can use this to verify if ex instanceof Downloads.Error, before reading the exception properties with the error details. Example (using Task.jsm): -
-try {
-  yield Downloads.fetch(sourceUri, targetFile);
-} catch (ex if ex instanceof Downloads.Error && ex.becauseTargetFailed) {
-  console.log("Unable to write to the target file, ignoring the error.");
-}
-
- -

Methods

- -

createDownload()

- -

Creates a new Download object.

- -
Promise<Download> createDownload(
-  Object aProperties
-);
-
- -
Parameters
- -
-
aProperties
-
Provides the initial properties for the newly created download. This matches the serializable representation of a Download object. Some of the most common properties in this object include: -
    -
  • source: String containing the URI for the download source. Alternatively, may be an {{Interface("nsIURI")}}, a DownloadSource object, or an object with the following properties: -
      -
    • url: String containing the URI for the download source.
    • -
    • isPrivate: {{optional_inline()}} Indicates whether the download originated from a private window. If omitted, the download is public.
    • -
    • referrer: {{optional_inline()}} String containing the referrer URI of the download source. Can be omitted or null if no referrer should be sent or the download source is not HTTP.
    • -
    -
  • -
  • target: String containing the path of the target file. Alternatively, may be an {{Interface("nsIFile")}}, a DownloadTarget object, or an object with the following properties: -
      -
    • path: String containing the path of the target file.
    • -
    -
  • -
  • saver: {{optional_inline()}} String representing the class of the download operation. If omitted, defaults to "copy". Alternatively, may be the serializable representation of a DownloadSaver object.
  • -
-
-
- -
Promise resolves to
- -

The newly created Download object.

- -

fetch()

- -

Downloads data from a remote network location to a local file.

- -

This download method does not provide user interface or the ability to cancel or restart the download programmatically. For that, you should obtain a reference to a Download object using the createDownload() function.

- -

Since the download cannot be restarted, any partially downloaded data will not be kept in case the download fails.

- -
Promise fetch(
-  aSource,
-  aTarget,
-  Object aOptions
-);
-
- -
Parameters
- -
-
aSource
-
String containing the URI for the download source. Alternatively, may be an {{Interface("nsIURI")}} or a DownloadSource object.
-
aTarget
-
String containing the path of the target file. Alternatively, may be an {{Interface("nsIFile")}} or a DownloadTarget object.
-
aOptions {{optional_inline()}}
-
An optional object used to control the behavior of this function. You may pass an object with a subset of the following fields: -
    -
  • isPrivate: {{optional_inline()}} Indicates whether the download originated from a private window. If omitted, the download is public.
  • -
-
-
- -
Promise resolves to
- -

undefined when the download has finished successfully and you can access the target file.

- -
Promise can be rejected with
- -

DownloadError if the download failed.

- -

getList()

- -

Retrieves the specified type of DownloadList object. There is one download list for each type, and this method always retrieves a reference to the same download list when called with the same argument.

- -

Calling this function may cause the download list to be reloaded from the previous session, if it wasn't loaded already.

- -
Promise<DownloadList> getList(aType);
-
- -
Parameters
- -
-
aType
-
This can be Downloads.PUBLIC, Downloads.PRIVATE, or Downloads.ALL. Downloads added to the Downloads.PUBLIC and Downloads.PRIVATE lists are reflected in the Downloads.ALL list, and downloads added to the Downloads.ALL list are also added to either the Downloads.PUBLIC or the Downloads.PRIVATE list based on their properties.
-
- -
Promise resolves to
- -

The requested DownloadList object.

- -

getSummary()

- -

Retrieves the specified type of DownloadSummary object. There is one download summary for each type, and this method always retrieves a reference to the same download summary when called with the same argument.

- -

Calling this function does not cause the list of public downloads to be reloaded from the previous session. The summary will behave as if no downloads are present until the getList() method is called.

- -
Promise<DownloadSummary> getSummary(aType);
-
- -
Parameters
- -
-
aType
-
This can be Downloads.PUBLIC, Downloads.PRIVATE, or Downloads.ALL.
-
- -
Promise resolves to
- -

The requested DownloadSummary object.

- -

Examples

- -

Downloading to a local file

- -

This example downloads an HTML file without showing progress, handling errors programmatically.

- -
Components.utils.import("resource://gre/modules/Downloads.jsm");
-Components.utils.import("resource://gre/modules/osfile.jsm")
-Components.utils.import("resource://gre/modules/Task.jsm");
-
-Task.spawn(function () {
-
-  yield Downloads.fetch("http://www.mozilla.org/",
-                        OS.Path.join(OS.Constants.Path.tmpDir,
-                                     "example-download.html"));
-
-  console.log("example-download.html has been downloaded.");
-
-}).then(null, Components.utils.reportError);
-
- -

Observing downloads

- -

This example logs a message every time a change occurs in one of the global download lists.

- -

To demonstrate the logging, a new download is started while a message box is being shown. The download is stopped and removed from the list when the message box is closed, regardless of whether it has been completed or not.

- -
Components.utils.import("resource://gre/modules/Downloads.jsm");
-Components.utils.import("resource://gre/modules/osfile.jsm")
-Components.utils.import("resource://gre/modules/Task.jsm");
-
-Task.spawn(function () {
-
-  let list = yield Downloads.getList(Downloads.ALL);
-
-  let view = {
-    onDownloadAdded: download => console.log("Added", download),
-    onDownloadChanged: download => console.log("Changed", download),
-    onDownloadRemoved: download => console.log("Removed", download)
-  };
-
-  yield list.addView(view);
-  try {
-    let download = yield Downloads.createDownload({
-      source: "http://www.mozilla.org/",
-      target: OS.Path.join(OS.Constants.Path.tmpDir, "example-download.html"),
-    });
-    list.add(download);
-    try {
-      download.start();
-      alert("Now monitoring all downloads. Close the message to stop.");
-    } finally {
-      yield list.remove(download);
-      yield download.finalize(true);
-    }
-  } finally {
-    yield list.removeView(view);
-  }
-
-}).then(null, Components.utils.reportError);
-
- -

Conversion from nsIDownloadManager

- -

Starting in Firefox for Desktop version 26, the {{interface("nsIDownloadManager")}} and {{interface("nsIDownload")}} interfaces are not available anymore.

- -

The new module works differently from the old component. In general, you should be aware of the following highlights:

- - - -

While some of the legacy methods and properties have an equivalent in Downloads.jsm, there might be subtle differences in behavior. For example, the properties that handle progress are now more detailed and don't use the special value -1 anymore. You may see the documentation of the new methods and properties for details.

- -

Using it in a XUL app

- -

In a XUL standalone application (running with XULRunner or firefox --app), you have to do additionnal things in order to use the new download manager. By default it is not enabled. It will be enabled when the bug 851471 will be closed. If you don't activate it, you could use Downloads.jsm, but your view will not be called by the external helper app service (when a user click on a file to download, in a web page). To enable the new download manager :

- - - -
 Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar)
-                   .registerFactory(Components.ID("{1b4c85df-cbdd-4bb6-b04e-613caece083c}"), "", "@mozilla.org/transfer;1", null);
-
-
- -

 

- -

See also

- - - -
 
diff --git a/files/zh-cn/mozilla/javascript_code_modules/geometry.jsm/index.html b/files/zh-cn/mozilla/javascript_code_modules/geometry.jsm/index.html deleted file mode 100644 index bc18819d7a..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/geometry.jsm/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Geometry.jsm -slug: Mozilla/JavaScript_code_modules/Geometry.jsm -translation_of: Mozilla/JavaScript_code_modules/Geometry.jsm ---- -

{{ gecko_minversion_header("2.0") }}

-

The Geometry.jsm JavaScript code module provides routines for performing common geometry operations on points and rectangles. It exports two classes: Point and Rect.

-

To use these routines, you first need to import the code module into your JavaScript scope:

-
Components.utils.import("resource://gre/modules/Geometry.jsm");
-
-

Once you've imported the module, you can then use the Point and Rect classes.

-
- Note: Although this module is usable from mobile, and is present in Firefox 4, it's currently not used in Firefox 4 and attempting to use it may produce unreliable results there.
-

See also

- diff --git a/files/zh-cn/mozilla/javascript_code_modules/geometry.jsm/services.jsm/index.html b/files/zh-cn/mozilla/javascript_code_modules/geometry.jsm/services.jsm/index.html deleted file mode 100644 index 1acdc77cdf..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/geometry.jsm/services.jsm/index.html +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Services.jsm -slug: Mozilla/JavaScript_code_modules/Geometry.jsm/Services.jsm -translation_of: Mozilla/JavaScript_code_modules/Services.jsm ---- -

{{ gecko_minversion_header("2") }}

-

The Services.jsm  模块提供了一系列的javascript模块,用来简化各种常用的操作.

-

在使用它们之前,你必须首先将Services模块导入到自己的作用域内:

-
Components.utils.import("resource://gre/modules/Services.jsm");
-
-

然后你可以通过服务访问器来轻松的从Services对象导出所需要的模块. 例如,要想获取一个preferences服务,你可以用下面的语句:

-
var prefsService = Services.prefs;
-
-

服务访问器

- - -
服务访问器 服务接口 服务名
appinfo {{ interface("nsIXULAppInfo") }}
{{ interface("nsIXULRuntime") }}
Application information service
console {{ interface("nsIConsoleService") }} Error console service
contentPrefs {{ interface("nsIContentPrefService") }}

Content Preferences service

cookies {{ interface("nsICookieManager2") }}

Cookie Manager 2 service

dirsvc {{ interface("nsIDirectoryService") }}
{{ interface("nsIProperties") }}
Directory service
droppedLinkHandler {{ interface("nsIDroppedLinkHandler") }} Dropped link handler service
eTLD {{ interface("nsIEffectiveTLDService") }}

EffectiveTLD service

io {{ interface("nsIIOService") }}
{{ interface("nsIIOService2") }}
I/O Service
locale {{ interface("nsILocaleService") }} Locale service
logins {{ interface("nsILoginManager") }}

Password Manager service

obs {{ interface("nsIObserverService") }} Observer service
perms {{ interface("nsIPermissionManager") }} Permission manager service
prefs {{ interface("nsIPrefBranch") }}
{{ interface("nsIPrefBranch2") }}
{{ interface("nsIPrefService") }}
Preferences service
prompt {{ interface("nsIPromptService") }} Prompt service
scriptloader {{ interface("mozIJSSubScriptLoader") }} JavaScript subscript loader service
search {{ interface("nsIBrowserSearchService") }} Browser search service1
startup {{ interface("nsIAppStartup") }} Application startup service
storage {{ interface("mozIStorageService") }} Storage API service
strings {{ interface("nsIStringBundleService") }} String bundle service
sysinfo {{ interface("nsIPropertyBag2") }} System info service
telemetry {{ interface("nsITelemetry") }} Telemetry service
tm {{ interface("nsIThreadManager") }} Thread Manager service
urlFormatter {{ interface("nsIURLFormatter") }}

URL Formatter service

vc {{ interface("nsIVersionComparator") }} Version comparator service
wm {{ interface("nsIWindowMediator") }} Window mediator service
ww {{ interface("nsIWindowWatcher") }} Window watcher service
DOMRequest {{ interface("nsIDOMRequestService") }} DOMRequest service
cpmm {{ interface("nsIFrameMessageManager") }} Child Process Message Manager
ppmm {{ interface("nsIFrameMessageManager") }} Parent Process Message Manager
-

Thunderbird 和 SeaMonkey中该特性不可用.

-

相关链接

- -

{{ languages( { "en": "en/JavaScript_code_modules/Services.jsm" } ) }}

diff --git a/files/zh-cn/mozilla/javascript_code_modules/http.jsm/index.html b/files/zh-cn/mozilla/javascript_code_modules/http.jsm/index.html deleted file mode 100644 index 1e77c4e852..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/http.jsm/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Http.jsm -slug: Mozilla/JavaScript_code_modules/Http.jsm -tags: - - API - - HTTP -translation_of: Mozilla/JavaScript_code_modules/Http.jsm ---- -

HTTP.jsm

- -

Http.jsm 提供了 httpRequest-XMLHttpRequest的包装器,它为处理HTTP请求提供了方便和简化的API。

- -

httpRequest 支持以下参数:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
namemeaning
headersheader 的数组
postData -

取值范围:

- -
    -
  • string: 按原样发送
  • -
  • 数组: 编码为表单值
  • -
  • null/undefined: 没有POST数据.
  • -
-
-

method

-
GET, POST , PUT (如果postData存在,将自动设置).
onLoad -

加载完成时调用的方法,它接受两个参数:responseText和XHR对象。

-
onError -

当错误发生时调用的方法,它接受三个参数:error、responseText和XHR对象。

-
logger -

实现调试和日志方法的对象(例如log.jsm)。

-
- -

header 或 postData 是作为二维数组给出的,对于每个内部数组,第一个值是键,第二个值是值。例如: [["key1", "value1"], ["key2", "value2"]].

- -

提交 post 数据

- -

httpRequest允许向post请求附加数据。可以通过postData选项指定数据。postData可以有两种类型:字符串或数组。当给出null/undefined时,将不发送任何数据。如果给定一个字符串,数据将按原样追加到请求中。如果给定一个参数数组,它将被视为一个键值对数组。数组的元素将采用url编码,并会强制设置content type为“application/x-www-form-urlencoded;charset=utf-8"。Http.jsm只在post数据是数组时强行设置content type,并自动序列化它。如果提供的postdata是一个字符串,则不设置内容类型。在这种情况下,可以通过header参数设置content type。

- -

可选的XHR 配置

- -

在调用httpRequest之后,可以手动修改XHR对象上的内容。httpRequest返回一个XHR对象,该对象可用于设置请求的附加参数。例如,可以将XHR配置为在处理响应时使用任何自定义mime类型,而不管服务器返回什么。为此,可以通过调用httpRequest获得XHR对象,然后调用它的overrideMimeType()方法去设置MIME-Type。另一个例子可以在这里找到。

diff --git a/files/zh-cn/mozilla/javascript_code_modules/index.html b/files/zh-cn/mozilla/javascript_code_modules/index.html deleted file mode 100644 index 415663945b..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/index.html +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: JavaScript 代码模块 -slug: Mozilla/JavaScript_code_modules -tags: - - Add-ons(加载项) - - JavaScript - - TopicStub - - XPCOM - - mo - - 扩展 - - 模块 -translation_of: Mozilla/JavaScript_code_modules ---- -

{{Non-standard_Header}}

- -
-

注意: JavaScript代码模块和JavaScript 标准中的模块(module)不是一回事。 要学习如何使用标准中的模块,请点击 {{JSxRef("Statements/export", "export")}} 和 {{JSxRef("Statements/import", "import")}} 查看。

-
- -

JavaScript 代码模块用于具备不同权限的作用域之间的代码共享。例如,Firefox 可以使用模块,也可以通过扩展来使用模块,以避免重复代码。

- - - - - - - - -
-

话题总览

- -
-
使用JavaScript代码模块
-
介绍如何使用JavaScript代码模块
-
Component.utils.import
-
如何导入一个JavaScript的代码模块。
-
Component.utils.unload {{gecko_minversion_inline("7.0")}}
-
如何上传一个JavaScript的代码模块
-
代码片段: Module
-
如何使用模块代码的实例。
-
Mozilla实验室的 JS Modules
-
本页面列出了JS模块的列表,以及下载链接和文档,扩展开发人员可以在代码中使用它们。
-
- -
-
-
-

标准代码模块

- -
-
ctypes.jsm {{fx_minversion_inline("3.6")}}
-
提供一个允许JS代码在不需要开发一个XPCOM元素的前提下调用本地库的接口。
-
FileUtils.jsm {{gecko_minversion_inline("1.9.2")}}
-
提供处理文件的有用的方法
-
Geometry.jsm {{gecko_minversion_inline("2.0")}}
-
提供用于对点和矩形执行基本几何操作的方法。
-
ISO8601DateUtils.jsm
-
提供在JavaScript Date 对象和ISO 8601 data字符串之间转换的方法。
-
Dict.jsm {{gecko_minversion_inline("5.0")}}
-
提供一个可以访问键值对词典的API。
-
NetUtil.jsm
-
提供一些有用的网络实用函数,使您能够轻松地将输入流中的数据异步复制到输出流的。
-
PopupNotifications.jsm {{gecko_minversion_inline("2.0")}}
-
提供一种给用户弹出非模态(non-modal)通知的简便方法
-
openLocationLastURL.jsm {{gecko_minversion_inline("1.9.1.4")}}
-
提供读取使用文件菜单中的“打开定位(Open Location)” 时打开的最后一个URL的能力。
-
DownloadLastDir.jsm {{gecko_minversion_inline("2.0")}}
-
提供最后一次下载时的目录路径。
-
PluralForm.jsm
-
提供获取当前区域使用的正确的复数形式的一种简便方法,当然也可以使用一种指定的复数规则来将一个词语复数化。
-
Services.jsm {{gecko_minversion_inline("2.0")}}
-
提供getter来方便地获取对一些常用服务的访问。
-
source-editor.jsm {{fx_minversion_inline("11.0")}}
-
源编辑器(Souce Editor)是指那些you开发者工具所提供的编辑器,如样式编辑器;此接口实现了源编辑器,并且允许你与之交互。
-
XPCOMUtils.jsm
-
包含一些为JS组件加载器所加载的JavaScript组件的实用程序。
-
PerfMeasurement.jsm {{fx_minversion_inline("4.0")}}
-
提供对底层硬件和操作系统性能测量工具的访问。
-
AddonManager.jsm {{gecko_minversion_inline("2.0")}}
-
安装、管理和卸载加载项(add-ons)的接口。
-
AddonRepository.jsm {{gecko_minversion_inline("2.0")}}
-
允许搜索加载项(add-ons)列表。
-
-
diff --git a/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/deferred/index.html b/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/deferred/index.html deleted file mode 100644 index aa0d921e0c..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/deferred/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: Deferred -slug: Mozilla/JavaScript_code_modules/Promise.jsm/Deferred -translation_of: Mozilla/JavaScript_code_modules/Promise.jsm/Deferred ---- -

 Deferred 对象返回了一个已经被废弃的方法Promise.defer() 并提供给新的promise用来改变promise的状态。

- -

从Gecko 30开始,该对象就已经被废弃,并建议不再使用。可以通过 new Promise() 构造新的promise取代,(或者使用向后/向前兼容的Deferred方法实现,如下:)。等价方法如下: 

- -
var deferred = Promise.defer();
-doSomething(function cb(good) {
-    if (good)
-        deferred.resolve();
-    else
-        deferred.reject();
-});
-return deferred.promise;
- -

应写成:

- -
return new Promise(function(resolve, reject) {
-    doSomething(function cb(good) {
-        if (good)
-            resolve();
-        else
-            reject();
-    });
-});
- -

方法概览

- - - - - - - - - - -
void resolve([optional] aValue);
void reject([optional] aReason);
- -

属性

- - - - - - - - - - - - - - -
AttributeTypeDescription
promise {{ReadOnlyInline()}}Promise新创建的promise,在pending阶段被初始化
- -

方法

- -

resolve()

- -

将指定的值赋给新建的promise,或者改变已存在的 promise 状态。如果关联的 promise 已经调用过 resolve 方法,无论是传入值、rejection,或另一个 promise,此方法都不会起效果。

- -
Note: This function is bound to its associated promise when Promise.defer() is called, and can be called with any value of this.
- -
Note: Calling this method with a pending promise as the aValue argument, and then calling it again with another value before the promise is resolved or rejected, will have no effect the second time, as the associated promise is already resolved to the pending promise value as its resolution.
- -
void resolve(
-  aValue
-);
-
- -
Parameters
- -
-
aValue Optional
-
If this value is not a promise, including undefined, it becomes the fulfillment value of the associated promise. If this value is a promise, then the associated promise will be resolved to the passed promise, and follow the state as the provided promise (including any future transitions).
-
- -

reject()

- -

Rejects the associated promise with the specified reason. If the promise has already been resolved, either to a value, a rejection, or another promise, this method does nothing.

- -
Note: This function is bound to its associated promise when Promise.defer() is called, and can be called with any value of this.
- -
void reject(
-  aReason
-);
-
- -
Parameters
- -
-
aReason Optional
-
-

The rejection reason for the associated promise. Although the reason can be undefined, it is generally an Error object, like in exception handling.

- -
Note: This argument should not be a promise. Specifying a rejected promise would make the rejection reason equal to the rejected promise itself, and not its rejection reason.
-
-
- -

Backwards and forwards compatible helper

- -

This Deferred function can be used for backwards and forwards compatibility, due to a change that took place in Firefox 30.

- -
function Deferred() {
-	// update 062115 for typeof
-	if (typeof(Promise) != 'undefined' && Promise.defer) {
-		//need import of Promise.jsm for example: Cu.import('resource:/gree/modules/Promise.jsm');
-		return Promise.defer();
-	} else if (typeof(PromiseUtils) != 'undefined'  && PromiseUtils.defer) {
-		//need import of PromiseUtils.jsm for example: Cu.import('resource:/gree/modules/PromiseUtils.jsm');
-		return PromiseUtils.defer();
-	} else {
-		/* A method to resolve the associated Promise with the value passed.
-		 * If the promise is already settled it does nothing.
-		 *
-		 * @param {anything} value : This value is used to resolve the promise
-		 * If the value is a Promise then the associated promise assumes the state
-		 * of Promise passed as value.
-		 */
-		this.resolve = null;
-
-		/* A method to reject the assocaited Promise with the value passed.
-		 * If the promise is already settled it does nothing.
-		 *
-		 * @param {anything} reason: The reason for the rejection of the Promise.
-		 * Generally its an Error object. If however a Promise is passed, then the Promise
-		 * itself will be the reason for rejection no matter the state of the Promise.
-		 */
-		this.reject = null;
-
-		/* A newly created Promise object.
-		 * Initially in pending state.
-		 */
-		this.promise = new Promise(function(resolve, reject) {
-			this.resolve = resolve;
-			this.reject = reject;
-		}.bind(this));
-		Object.freeze(this);
-	}
-}
- -

and use this function as would Promise.defer:

- -
function funcWithDefer() {
-  var deferred = new Deferred();
-  var promise = deferred.promise;
-  promise.then(
-    function(aVal) {
-      console.log('Fullfilled - ', aVal);
-    },
-    function(aReason) {
-      console.error('Rejected - aReason:', aReason)
-    }
-  );
-
-  //deferred.resolve('aVal of resolved');
-  deferred.reject('reject val');
-
-  return promise;
-}
-
-var promise_funcWithDefer = funcWithDefer();
-promise_funcWithDefer.then(
-  function(aVal) {
-    console.log('Fullfilled - promise_funcWithDefer - ', aVal);
-  },
-  function(aReason) {
-    var refObj = {name:'promise_funcWithDefer', aReason:aReason};
-    console.error('Rejected - promise_funcWithDefer - ', refObj);
-  }
-).catch(
-  function(aCatch) {
-    console.error('Caught - promise_funcWithDefer - ', aCatch);
-    throw aCatch;
-  }
-);
- -

See also

- - - -

- -

diff --git a/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/index.html b/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/index.html deleted file mode 100644 index a02f5f0385..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/index.html +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: Promise.jsm -slug: Mozilla/JavaScript_code_modules/Promise.jsm -tags: - - NeedsTranslation - - TopicStub -translation_of: Mozilla/JavaScript_code_modules/Promise.jsm ---- -

{{ gecko_minversion_header("25") }}

-

The Promise.jsm JavaScript code module implements the Promises/A+ proposal as known in April 2013. To use it, you first need to import the code module into your JavaScript scope:

-
Components.utils.import("resource://gre/modules/Promise.jsm");
-
-
-

Note: A preliminary promise module is also available starting from Gecko 17, though it didn't conform to the Promises/A+ proposal until Gecko 25:

-
Components.utils.import("resource://gre/modules/commonjs/promise/core.js");     // Gecko 17 to 20
-Components.utils.import("resource://gre/modules/commonjs/sdk/core/promise.js"); // Gecko 21 to 24
-
-

This implementation also includes helper functions that are specific to the Add-on SDK. While you may still import this module from the above paths, the recommended way for loading it is through the Add-on SDK loader.

-
-

Introduction

-

For an introduction to promises, you may start from the Add-on SDK documentation, keeping in mind that only the core subset is implemented in this module.

-

A promise is an object representing a value that may not be available yet. Internally, a promise can be in one of three states:

- -

A reference to an existing promise may be received by different means, for example as the return value of a call into an asynchronous API. In this case, the state of the promise can be observed but not directly controlled.

-

To observe the state of a promise, its then method must be used. This method registers callback functions that are called as soon as the promise is either fulfilled or rejected. The method returns a new promise, that in turn is fulfilled or rejected depending on the state of the original promise and on the behavior of the callbacks. For example, unhandled exceptions in the callbacks cause the new promise to be rejected, even if the original promise is fulfilled. See the documentation of the then method for details.

-

Promises may also be created using the Promise.defer() function, the main entry point of this module. The function, along with the new promise, returns separate methods to resolve or reject the promise. See the documentation of the Deferred object for details.

-

Method overview

- - - - - - - - - - - - -
Deferred defer();
Promise resolve([optional] aValue);
Promise reject([optional] aReason);
-

Methods

-

defer()

-

Creates a new pending promise and provides methods to resolve or reject it.

-
Deferred defer();
-
-
Parameters
-

None.

-
Return value
-

A new object, containing the new promise in the promise property, and the methods to change its state in the resolve and reject properties. See the Deferred documentation for details.

-

resolve()

-

Creates a new promise fulfilled with the specified value, or propagates the state of an existing promise.

-
Promise resolve(
-  aValue
-);
-
-
Parameters
-
-
- aValue {{ optional_inline() }}
-
- If this value is not a promise, including undefined, it becomes the fulfillment value of the returned promise. If this value is a promise, then the returned promise will be resolved with the value, i.e. it will eventually assume the same state as the provided promise.
-
-
Return value
-

A promise that can be pending, fulfilled, or rejected.

-

reject()

-

Creates a new promise rejected with the specified reason.

-
Promise reject(
-  aReason
-);
-
-
Parameters
-
-
- aReason {{ optional_inline() }}
-
-

The rejection reason for the returned promise. Although the reason can be undefined, it is generally an Error object, like in exception handling.

-
- Note: This argument should not be a promise. Specifying a rejected promise would make the rejection reason equal to the rejected promise itself, and not its rejection reason.
-
-
-
Return value
-

A rejected promise.

-

Examples

-
Components.utils.import("resource://gre/modules/Promise.jsm");
-
-// This function creates and returns a new promise.
-function promiseValueAfterTimeout(aValue, aTimeout)
-{
-  let deferred = Promise.defer();
-
-  try {
-    // An asynchronous operation will trigger the resolution of the promise.
-    // In this example, we don't have a callback that triggers a rejection.
-    setTimeout(function () {
-      deferred.resolve(aValue);
-    }, aTimeout);
-  } catch (ex) {
-    // Generally, functions returning promises propagate exceptions through
-    // the returned promise, though they may also choose to fail early.
-    deferred.reject(ex);
-  }
-
-  // We don't return the deferred to the caller, but only the contained
-  // promise, so that the caller cannot accidentally change its state.
-  return deferred.promise;
-}
-
-// This code uses the promise returned be the function above.
-let promise = promiseValueAfterTimeout("Value", 1000);
-
-let newPromise = promise.then(function onFulfill(aValue) {
-  console.log("Fulfilled with this value: " + aValue);
-}, function onReject(aReason) {
-  console.log("Rejected with this reason: " + aReason);
-});
-
-// Unexpected errors should always be reported at the end of a promise chain.
-newPromise.then(null, Components.utils.reportError);
-
- Note: More examples for consuming promises are available in the Promise object documentation.
-

The case of unhandled rejections

-

One of the difficult problems with promises is locating uncaught rejections.

-
-

Warning: When consuming promises, you should always handle or report errors (rejection reasons). See handling errors and common pitfalls.

-
-

Rejection handlers provide information about the exact error time and location, but the handlers may sometimes be forgotten. Consider the following cases:

-
function f() {
-  return Promise.reject(new Error("BOOM!")); // If nobody catches the error, how will it be reported?
-}
-
-
-function g() {
-  return Promise.resolve().then(function() {
-    throw new Error("BOOM!"); // If nobody catches the error, how will it be reported?
-  });
-}
-
-function h() {
-  Promise.reject(new Error("BOOM!"); // Oops, we forgot to return the promise, nobody can catch it!
-}
-
-

We adopt the following strategy: if a promise is rejected at the time of its garbage-collection and if the promise is at the end of a promise chain (i.e. thatPromise.then has never been called), then we print a warning.

-
- Note: This warning is generated some time after the error occurred, and may provide less information about the error location. It generally indicates the need to insert a proper error handler. When a proper rejection handler is used, it effectively replaces this delayed reporting.
-
let deferred = Promise.defer();
-let p = deferred.promise.then();
-deferred.reject(new Error("I am an uncaught error"));
-deferred = null;
-p = null;
-


- In this snippet, since deferred.promise is not the last in the chain, no error will be reported for that promise. However, since p is the last promise in the chain, the error will be reported for p.
-
- Note that this may, in some cases, cause an error to be reported more than once. For instance, consider:

-
let deferred = Promise.defer();
-let p1 = deferred.promise.then();
-let p2 = deferred.promise.then();
-deferred.reject(new Error("I am an uncaught error"));
-p1 = p2 = deferred = null;
-


- In this snippet, the error is reported both at p1 and at p2.

-

See also

- diff --git a/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html b/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html deleted file mode 100644 index 947fd3acdc..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Promise -slug: Mozilla/JavaScript_code_modules/Promise.jsm/Promise -translation_of: Mozilla/JavaScript_code_modules/Promise.jsm/Promise ---- -

Promise对象代表暂时不可用的值。

- -

一个已存在的promise引用可以通过不同的方式被接收,如作为异步API的返回值。一旦得到一个promise对象,就可以调用其 then() 方法,以在其值可用时或者出现异常时执行一个动作。

- -

可以通过 new Promise() 方法创建Promise对象,当使用一个已存在的Promise对象时,不需要引入 Promise.jsm 模块。

- -

promise内部状态可为以下三种之一:

- - - -
-

备注: 使用promise时,应该始终对异常(拒绝理由)进行处理或报告。如果你看见了"A promise chain failed to handle a rejection"的错误信息,你可能就需要检查你的代码。参见下面的 异常处理和常见误区

-
- -

文档约定

- -

文档规定,完成值的类型通过尖括号内的内容指定。如 OS.File.exists 方法返回一个完成值类型为boolean的promise:

- -
Promise<boolean> exists(string path);
-
- -

拒绝理由可能在function文档中单独规定,除非特别指定,一般使用 Error 对象作为拒绝理由。

- -

方法概览

- - - - - - - - - - -
Promise then([optional] Function onFulfill, [optional] Function onReject);
Promise catch([optional] Function onReject);
- -

构造函数

- -

创建一个新的promise,初始化为等待状态,并提供解决函数的引用,用于改变其状态。

- -
new Promise(executor);
- -

参数

- -
-
executor
-
-

该函数会马上被调用,它带有两个参数的函数对象:

- -

 

-
-
-
executor(resolve, reject);
- -

构造函数直到执行完成才会返回。解决函数可以在任何时间被调用,在执行过程完成前后都可以,其目标是控制promise的最终状态。如果执行过程抛出异常,异常值会被传递到reject解决函数中。

-
-
- -

解决函数

- -

resolve()

- -

用特定值满足绑定的promise,或者把状态传递到一个已存在的promise。如果绑定的promise已经被解决(可能是一个值,也可能是一个rejection,或者是另一个promise),该方法不会做任何事。

- -
-

备注: 调用该方法时,如果用一个pending状态的promise作为aValue参数,然后在该promise状态改变为fullfilled或者rejected前用另一个值再次调用,第二次调用将不会生效,因为这个绑定的promise已经被pending promise所解决了。

-
- -
void resolve(
-  aValue
-);
- -
参数
- -
-
aValue  可选
-
如果这个值不是一个promise,包括  undefined, 它会变成绑定promise的实现值。如果这个值是promise,绑定promise会被传递的promise解决,并跟随所提供的promise的状态(包括任何未来的转变)。
-
- -

reject()

- -

用特定原因拒绝绑定的promise。如果promise已经被解决了,不管是值,拒绝,还是另一个promise,这个方法都不会做任何事。

- -
void reject(
-  aReason
-);
- -
参数
- -
-
aReason 可选
-
绑定promise的拒绝原因。通常是一个 Error 对象,就像在异常处理那样,尽管理由也可以是 undefined。
-
- -
-

备注: 该参数不应该是promise。要说明一个被拒绝的promise,应该让拒绝原因等于被拒绝promise自身,而非其拒绝原因。

-
- -

方法

- -

then()

- -

一旦promise完成或被拒绝,就立即执行一个回调函数,并返回一个新的promise对象,新promise的状态取决于promise和传入的回调函数

- -
回调函数始终会在then返回值后被调用,即使promise早已完成或已被拒绝。也可对多次调用同一个promise的then方法。所有的回调函数会按照其注册的顺序被调用。
- -

 

- -
-

警告: 如果 onFulfill 抛出异常,不会调用 onReject ,异常也不会被捕获和输出到控制台(你会看到一个promise chain失败错误),可以在返回的promise上注册一个错误处理函数,以处理在任一回调中出现的异常(使用 catch() 或者 then() ),来处理发生在任何一个注册回调函数的异常。

-
- -

 

- -
-

注意:当多次调用同一个promise的then方法,所有注册的回调函数独立执行。如,当在一个回调函数中出现异常时,不会影响后面回调函数的执行。回调函数的结果只会对其注册所使用的then方法返回的promise产生影响,每一次调用then方法返回的都是不同的promise对象。

-
- -
Promise then(
-  Function onFulfill,
-  Function onReject
-);
-
- -
参数
- -
-
onFulfill {{optional_inline()}}
-
当promise完成时,会调用该函数,并将完成值作为其唯一参数传入,该函数的输出会决定新的promise的状态。如果该参数不是函数(通常为null),则由then返回的新的promise的状态为已完成,且完成值与原promise相同
-
onReject {{optional_inline()}}
-
-

当promise被拒绝时,会调用该函数,并将拒绝理由作为其唯一参数传入,且该函数的输出会决定新的promise的状态。如果该参数不是函数(通常为undefined),则由then返回的新的promise的状态为拒绝,且拒绝理由与原promise相同。

-
-
- -
返回值
- -

新的promise对象,初始状态为未完成,最终状态取决于回调函数的输出:

- - - -
-

catch()

- -

等价于调用onFulfill参数为undefined的 then() 方法。如果你链式调用then( onFulfill ).catch( onReject ),onFulfill中抛出的异常会被捕捉并传递到onReject。

- -
Promise catch(
-  Function onReject
-);
- -

等价于以下调用:

- -
p.then(undefined, logError);
-p.catch(logError);
-
- -
 
- -

调试

- -

按照设计,在不调用 then()的情况下,promise的即时状态和值不能通过代码同步检测到。

- -

为了有助于调试,只有当手动检查promise时,才能看到那些不能通过代码访问的特殊属性的信息(目前由于缺少复杂的语言或调试器的支持,属性名是随机生成的)。

- -

这些代码可访问和可审查的属性有:

- - - -

Promise properties are visible in the debugger.Promise handlers can be watched from the Console.

- -

示例

- -

请看 示例 页面.

- -

异常处理和常见误区

- -

promise应该报告未处理的错误,除非交给其他程序处理该错误。

- -
// ###### WRONG: Silently drops any rejection notified by "OS.File.Exists".
-OS.File.exists(path).then(exists => { if (exists) myRead(path); });
-
-// ###### WRONG: Silently drops any exception raised by "myRead".
-OS.File.exists(path).then(exists => { if (exists) myRead(path); }, Components.utils.reportError);
-
-// CORRECT (for example, might report the exception "myRead is not defined")
-OS.File.exists(path).then(exists => { if (exists) myRead(path); })
-                    .catch(null, Components.utils.reportError);
-
-// CORRECT (the function returns a promise, and the caller will handle the rejection)
-function myReadIfExists(path)
-{
-  return OS.File.exists(path).then(exists => { if (exists) myRead(path); });
-}
- -

参见

- - diff --git a/files/zh-cn/mozilla/javascript_code_modules/timer.jsm/index.html b/files/zh-cn/mozilla/javascript_code_modules/timer.jsm/index.html deleted file mode 100644 index 83ae26b154..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/timer.jsm/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Timer.jsm -slug: Mozilla/JavaScript_code_modules/Timer.jsm -tags: - - JavaScript - - JavaScript计时器 - - 插件 - - 模块 -translation_of: Mozilla/JavaScript_code_modules/Timer.jsm ---- -

{{ gecko_minversion_header("22") }}

- -

Timer.jsm JavaScript模块包含纯JavaScript对setTimeoutclearTimeoutsetIntervalclearInterval功能的实现且适用于DOM窗口函数,但它还可以被那些无法访问DOM窗口的代码(如JavaScript模块框架里的脚本)使用。

- -

 

- -

要使用Timer.jsm,首先导入它:

- -
Components.utils.import("resource://gre/modules/Timer.jsm");
-
- -

然后如同在DOM窗口中一样使用setTimeout和clearTimeout,例如:

- -
let timeoutID = setTimeout(function() { console.log("Hello!"); }, 500);
-
-clearTimeout(timeoutID);
-
- -

类似地,你可以使用setInterval和clearInterval,比如:

- -
let intervalID = setInterval(function() { console.log("Happening every 500ms!"); }, 500);
-
-clearInterval(intervalID);
diff --git a/files/zh-cn/mozilla/javascript_code_modules/using/index.html b/files/zh-cn/mozilla/javascript_code_modules/using/index.html deleted file mode 100644 index 41fdf9970e..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/using/index.html +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: 使用 JavaScript 代码 modules 模式 -slug: Mozilla/JavaScript_code_modules/Using -tags: - - Add-ons - - Extensions - - Guide - - JavaScript - - XPCOM -translation_of: Mozilla/JavaScript_code_modules/Using ---- -

{{ gecko_minversion_header("1.9") }}

- -

JavaScript code modules 在Gecko1.9中引入并被用于具备不同权限的作用域之间的代码共享。 Modules 也可以用于创建全局js单例,这在之前是通过使用XPCOM(跨平台组件模型)实现的。一个 JavaScript code module 是仅仅是位于注册位置的一些 JavaScript 代码。Module 被载入特定的js域,比如 XUL script or JavaScript XPCOM script, 通过Components.utils.import() or Components.utils["import"]().

- -

创建 JavaScript code module

- -

一个简单的例子my_module.jsm:

- -
var EXPORTED_SYMBOLS = ["foo", "bar"];
-
-function foo() {
-  return "foo";
-}
-
-var bar = {
-  name : "bar",
-  size : 3
-};
-
-var dummy = "dummy";
-
- -

可以看到 module 使用规范的js语言来创建函数,对象,常量以及其他的数据类型。 Module 还定义了一个名为 EXPORTED_SYMBOLS 的特殊数组,这个数组中的每一项都会被输出到声明中并且被注入到引入的作用域中。例如:

- -
Components.utils.import("resource://app/my_module.jsm");
-
-alert(foo());         // displays "foo"
-alert(bar.size + 3);  // displays "6"
-alert(dummy);         // displays "dummy is not defined" because 'dummy' was not exported from the module
-
- -
Note: When you're testing changes to a code module, be sure to change the application's build ID (e.g. the version) before your next test run; otherwise, you may find yourself running the previous version of your code module's code still.
- -

The URL for a code module

- -

正如你在上例中看到的, 你需要一个 URL 来导入一个代码块 (code module)。 (就像例子中的 "resource://app/my_module.jsm".)

- -

有三种模式的URL可供选择: chrome:……({{ gecko_minversion_inline("2") }}), resource:……, 或者 file:…….

- - - -

通过code modules共享对象

- -

Components.utils.import() 的一个非常重要行为就是 module 加载后会被缓存起来, 并且随后的的导入不会重新加载一个新版的module, 而是使用之前缓存的版本。这就意味着当导入 module 多次时, 一个给定的 module 会被共享多次。只要引入某个module,任何对数据,对象和函数的变化都会体现在不同的引入该module的域中。比如,一个简单的module被引入到两个不同的域中,在其中一个域中做改变,另一个域也共享这种改变。如下例 :

- -

Scope 1:

- -
Components.utils.import("resource://app/my_module.jsm");
-
-alert(bar.size + 3);  // displays "6"
-
-bar.size = 10;
-
- -

Scope 2:

- -
Components.utils.import("resource://app/my_module.jsm");
-
-alert(foo());         // displays "foo"
-alert(bar.size + 3);  // displays "13"
-
- -

这种共享行为可以被用来创建单例对象(singleton objects)并且可以被 跨windows 和 XUL script 和 XPCOM 组件所共享。

- -

注意:引入某个module的域获得了一组该module中定义的输出符号的按值复制的副本( by-value copy )。 对这些输出符号的改变或者重新定义不会传播到其他的域中。 (虽然对象的属性会通过引用来改变。)。例子如下:

- -

Scope 1:

- -
Components.utils.import("resource://app/my_module.jsm");
-
-bar = "foo";
-alert(bar);         // displays "foo"
-
- -

Scope 2:

- -
Components.utils.import("resource://app/my_module.jsm");
-
-alert(bar);         // displays "[object Object]"
-
- -

按值复制的主要效果就是简单类型的全局变量不会在不同的域之间共享。所以我们经常将变量放在大括号中,然后以对象的形式输出 (就像上例中的bar)。

- -

{{ h2_gecko_minversion("Unloading code modules", "7.0") }}

- -

Components.utils.unload() 允许你卸载之前引入的module。该方法被调用后, 指向该module的引用可以继续工作,但是后续对该module的引入,就会重新加载并重新分配指向该module的引用值。

- -

Extending resource: URLs

- -

{{ Gecko("2.0") }}之前,加载code module最常用的方式是—— resource: URLs. Resource URL 的基本语法如下:

- -
resource://<alias>/<relative-path>/<file.js|jsm>
-
- -

<alias> 是某个位置的别称,通常是一个相对于应用程序或者 XUL runtime的物理位置。这是一些由XUL runtime设置的预定义的别称:

- - - -

<relative-path> 可以是多层的,经常是相对于alias的位置。最常见的相对路径是 "modules" 并常常被XUL Runner and Firefox使用. Code modules 是简单的js文件以 .js or .jsm 作为后缀。

- -

<alias> 对于你的插件必须是唯一的,因为应用和其他的扩展共享同样的命名空间对所有的别称。

- -

使用chrome.manifest

- -

The easiest way for extensions and XUL applications to add custom aliases is by registering an alias in the chrome manifest using a line like this:

- -
resource aliasname uri/to/files/
-
- -

For example, if the XPI for your foo extension includes a top-level modules/ directory containing the bar.js module (that is, the modules/ directory is a sibling to chrome.manifest and install.rdf), you could create an alias to that directory via the instruction:

- -
resource foo modules/
-
- -

(Don't forget the trailing slash!) You could then import the module into your JavaScript code via the statement:

- -
Components.utils.import("resource://foo/bar.js");
-
- -

Programmatically adding aliases

- -

Custom aliases to paths that can be represented as an {{ interface("nsILocalFile") }} can be programmatically added as well. For example:

- -
// Import Services.jsm unless in a scope where it's already been imported
-Components.utils.import("resource://gre/Services.jsm");
-
-var resProt = Services.io.getProtocolHandler("resource")
-                      .QueryInterface(Components.interfaces.nsIResProtocolHandler);
-
-var aliasFile = Components.classes["@mozilla.org/file/local;1"]
-                          .createInstance(Components.interfaces.nsILocalFile);
-aliasFile.initWithPath("/some/absolute/path");
-
-var aliasURI = Services.io.newFileURI(aliasFile);
-resProt.setSubstitution("myalias", aliasURI);
-
-// assuming the code modules are in the alias folder itself
-
- -

Notes

- -

自定义 modules 和 XPCOM components

- -

Note that prior to {{ Gecko("2.0") }} JavaScript XPCOM components are loaded before chrome registration. This means you can't use Components.utils.import() with your own resource URL at the top level in a component source. A possible solution is moving the call to Components.utils.import() into the XPCOM component constructor (discussion).

- -

Packaging notes

- -

It's important to note that you should not typically put your JavaScript code modules in a JAR file in your add-on. Firefox 3.6 doesn't support them at all, and there's only one case in which it's remotely useful: a Firefox 4-only add-on which must be installed unpacked. Otherwise placing code modules in a JAR file breaks compatibility unnecessarily.

- -

Importing CommonJS modules

- -

The JavaScript code modules described here are not the same thing as CommonJS modules, but you can import CommonJS modules into any scope where you can use Components.utils.import. Just call the following:

- -
const { require } = Cu.import("resource://gre/modules/commonjs/toolkit/require.js", {})
- -

This will import require() into your scope.

- -

You can then use that to import CommonJS modules. You can import Add-on SDK modules in just the same way you could from an SDK add-on:

- -
// import the SDK's base64 module
-
-var base64 = require("sdk/base64");
-base64.encode("hello"); // "aGVsbG8="
- -

You can import other CommonJS modules, too, as long as you know the path to them:

- -
// import my module
-
-var myModule = require("resource://path/to/my/module.js");
- -

In this case, though, you might be better off creating your own loader, so you can specify the paths property yourself.

- -

See also

- - diff --git a/files/zh-cn/mozilla/javascript_tips/index.html b/files/zh-cn/mozilla/javascript_tips/index.html deleted file mode 100644 index 2de76fff08..0000000000 --- a/files/zh-cn/mozilla/javascript_tips/index.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: JavaScript 编程技巧 -slug: Mozilla/JavaScript_Tips -translation_of: Mozilla/JavaScript_Tips ---- -

XUL 技巧

- - - -
var UniqueName = {
-  _privateMember: 3,
-  publicMember: "A string",
-
-  init: function UN_init() {
-    this.doSomething(this.anotherMember);
-  },
-
-  doSomething: function UN_doSomething(aParam) {
-    alert(aParam);
-  }
-};
-
- -

XPConnect

- - - -
if (target instanceof Components.interfaces.nsIRDFResource)
-  return target.Value;
-if (target instanceof Components.interfaces.nsIRDFLiteral)
-  return target.Value;
-return null;
-
- - - -
var weakObserver = {
-  QueryInterface: function QueryInterface(aIID) {
-    if (aIID.equals(Components.interfaces.nsIObserver) ||
-        aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
-        aIID.equals(Components.interfaces.nsISupports))
-       return this;
-    throw Components.results.NS_NOINTERFACE;
-  },
-  observe: function observe(aSubject, aTopic, aState) {
-  }
-}
-
- - - -

DOM 元素

- - - -

References

- - - -

{{ languages( { "ja": "ja/JavaScript_style_guide" } ) }}

diff --git a/files/zh-cn/mozilla/js-ctypes/index.html b/files/zh-cn/mozilla/js-ctypes/index.html deleted file mode 100644 index fc3eb24564..0000000000 --- a/files/zh-cn/mozilla/js-ctypes/index.html +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: js-ctypes -slug: Mozilla/js-ctypes -translation_of: Mozilla/js-ctypes ---- -

js-ctype可以让应用程序和浏览器扩展代码调用用C/C++语言编写的本地代码.C++的支持程度有限,查看{{bug("505907")}}了解更多详情.和二进制的XPCOM组件不同的是,用户编写的二进制文件可以用在多个版本的Firefox中.

-
- 注: js-ctype只能在chrome代码中使用,也就是说,普通网页不能使用js-ctype,只有在扩展程序中可用.
- - - - - - - -
-

文档

-
-
- 介绍:使用js-ctype
-
- 开始使用js-ctype.
-
- JS-ctype参考
-
- 关于js-ctype API的参考指南.
-
- OS标准库
-
- 不同操作系统的标准库文档(比如:在Windows上哪个函数存在于哪个dll文件上的文档)
-
- 相关问题
-
- 关于js-ctype的常见问题解答
-
-

View All...

-

代码示例

- 添加到iPhoto -
-
- 一个Firefox扩展,使用js-ctype调用了Mac OS X中的核心基础框架,从而在Firefox中实现了一个"添加到iPhoto"的功能.
-
-
-

社区

-
    -
  • 查看Mozilla论坛...{{DiscussionList("dev-extensions", "mozilla.dev.extensions")}}
  • -
- - -
-

 

diff --git a/files/zh-cn/mozilla/js-ctypes/js-ctypes_reference/ctypes/index.html b/files/zh-cn/mozilla/js-ctypes/js-ctypes_reference/ctypes/index.html deleted file mode 100644 index e375c3df54..0000000000 --- a/files/zh-cn/mozilla/js-ctypes/js-ctypes_reference/ctypes/index.html +++ /dev/null @@ -1,534 +0,0 @@ ---- -title: ctypes -slug: Mozilla/js-ctypes/js-ctypes_reference/ctypes -translation_of: Mozilla/js-ctypes/js-ctypes_reference/ctypes ---- - - - - -
-

草案
- 本页尚未完工.

- -
- -

The ctypes object contains methods and predefined data types used to create and manage a library.

- -

方法概览

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CType ArrayType(type[, length]);
CData cast(data, type);
CType FunctionType(abi, returnType[, argType1, ...]);
CData Int64(n);
String libraryName(name);
Library open(libSpec);
CType PointerType(typeSpec);
CType StructType(name[, fields]);
CData UInt64(n);
- -

属性

- - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
errnoNumber最后一次的系统错误。与库中的errno一样,所有平台都一样,不能被设置。.
winLastErrorNumber|undefined最后一次发生的Windows 的错误。与Windows下的 GetLastError类似,只在Window下有效,不能被设置。
- -

常量

- -

ABI constants

- -

这些常量是用于调用库的方法时使用。

- - - - - - - - - - - - - - - - - - - - -
ConstantDescription
default_abiCorresponds to cdecl; standard libraries use this ABI. You also use this for all system calls on Mac OS X and Linux.
stdcall_abiUsed for calling functions declared with stdcall on Windows. These functions' names are automatically mangled for you by js-ctypes.
winapi_abi用于调用Windows 系统函数。与楼上的不同之处在于不能自己指定函数名字.
- -

预定义的数据类型

- -

原始类型

- -

这些类型在所有平台的表现方式都一样

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescription
int8_tSigned 8-bit integer.
uint8_tUnsigned 8-bit integer.
int16_tSigned 16-bit integer.
uint16_tUnsigned 16-bit integer.
int32_tSigned 32-bit integer.
uint32_tUnsigned 32-bit integer.
int64_tSigned 64-bit integer.
uint64_tUnsigned 64-bit integer.
float32_t32-bit floating-point value.
float64_t64-bit floating-point value.
- -
Note: Some 64-bit values are outside the range of numeric values supported by JavaScript. Because of this, ctypes.int64 and ctypes.uint64 do not automatically convert to JavaScript numbers. Instead, they convert to objects of the wrapper types ctypes.Int64 and ctypes.UInt64, which are JavaScript objects rather than CData objects. See 64-bit integers for details.
- -

C语言特定类型

- -

These types are designed to work exactly like the corresponding type on the native platform.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescription
boolA Boolean type that behaves like the corresponding C type on the platform.
shortA short integer type that behaves like the corresponding C type on the platform.
unsigned_shortAn unsigned short integer type that behaves like the corresponding C type on the platform.
intAn integer type that behaves like the int C type on the platform.
unsigned_intAn unsigned integer type that behaves like the unsigned int C type on the platform.
long -

A long integer type that behaves like the corresponding C type on the platform.

- -
-

NOTE This automatically converts to an Int64 JavaScript object on all platforms, since it's unknown whether this is a 32-bit or 64-bit value. This is done for compatibility's sake.

-
-
unsigned_long -

An unsigned long integer type that behaves like the corresponding C type on the platform.

- -
-

NOTE This automatically converts to a UInt64 JavaScript object on all platforms, since it's unknown whether this is a 32-bit or 64-bit value. This is done for compatibility's sake.

-
-
long_longA integer type at least 64 bits wide.
unsigned_long_longAn unsigned integer type at least 64 bits wide.
floatA floating point value that behaves like the float type on the platform.
doubleA double-precision floating point value that behaves like the double type on the platform.
- -

字符类型

- -

Character types are 8-bit values that behave like their C counterparts. They're similar to the int8_t and uint8_t types, except conversion is handled differently.

- -

For example, ctypes.char.array(30)(str) converts the string str to UTF-8 and returns a new CData object of array type.

- - - - - - - - - - - - - - - - - - - - -
TypeDescription
char -

A character type that behaves like the char C type on the platform.

-
signed_charA signed character that behaves like the char type on the platform.
unsigned_charAn unsigned character that behaves like the unsigned char type on the platform.
- -
大小与处理器位数有关的类型
- -

Because it's unknown whether these values will be 32-bit or 64-bit, they are not automatically converted into JavaScript numbers. Instead, these convert into ctypes.Int64 or ctypes.UInt64 JavaScript objects; see 64-bit integers for details.

- - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescription
size_tA platform-dependent size type.
ssize_tA platform-dependent size type.
intptr_tA platform-dependent integer representation of a pointer.
uintptr_tA platform-dependent unsigned integer representation of a pointer.
- -

JavaScript characters

- -

16-bit C Unicode characters are handled by js-ctypes using the jschar type.

- - - - - - - - - - - - -
TypeDescription
jscharA 16-bit unsigned character. This is different from uint16_t in that C jschar values are automatically converted into 1-character JavaScript strings. These are Unicode characters.
- -

Special C types

- -

These types represent C types that have special meanings.

- - - - - - - - - - - - - - - - -
TypeDescription
void_t -

The special C type void. This can only be used as a return value type.

- -
Note: You must use void_t, not void, since void is a keyword in JavaScript.
-
voidptr_tThe C type void *. This is a pointer to an indeterminate type of data.
- -

Large integer types

- -

Because JavaScript doesn't support large (64-bit) integers, js-ctypes provides two data types allowing access to 64-bit integer data.

- - - - - - - - - - - - - - - - -
TypeDescription
Int64A JavaScript object representing a 64-bit signed integer.
UInt64A JavaScript object representing a 64-bit unsigned integer.
- -

Methods

- -

cast()

- -

把某个对象转换成新的类型,返回值是拥有这些值的新类型的对象。更多了解可以查看Type casting

- -
CData cast(
-  data,
-  type
-);
- -
Parameters
- -
-
data
-
要转换的数据对象。
-
type
-
转换后的数据类型,可以是 Predefined data types, 也可以是任何自定义类型。
-
- -
Return value
- -

拥有相同数据的,不过类型是type的一个新对象。

- -

libraryName()

- -

Returns the correct platform-specific filename for a given library name (e.g. libnss3.dylib for nss3 on OS X.)

- -
String libraryName(
-  name
-);
-
- -
Parameters
- -
-
name
-
The name of the library.
-
- -
Return value
- -

String containing the platform-specific filename of the library.

- -

open()

- -

Opens a library, specified by a pathname. The library is loaded from the specified full path, or, if a partial path is specified, from the appropriate library directory based on the platform on which the application is running. See Library search paths for more details.

- -
Library open(
-  libSpec
-);
-
- -
Parameters
- -
-
libSpec
-
The native library to open, specified as a pathname string.
-
- -
Return value
- -

A Library object representing the opened library.

- -

举些栗子

- -

Windows下使用StructType()的例子

- -

好了,上帝说要有按钮TB_BUTTON,所以我们到MSDN上找TB_BUTTON 的结构体 (MSDN :: TB_BUTTON Structure) ,然后找到了:

- -
typedef struct {
-  int       iBitmap;
-  int       idCommand;
-  BYTE      fsState;
-  BYTE      fsStyle;
-#ifdef _WIN64
-  BYTE      bReserved[6];
-#else
-#if defined(_WIN32)
-  BYTE      bReserved[2];
-#endif
-#endif
-  DWORD_PTR dwData;
-  INT_PTR   iString;
-} TBBUTTON, *PTBBUTTON, *LPTBBUTTON;
- -

所以我们现在注意到64位和32位是不同的。所以我们将会指出这个不同之处,然后创造结构体。代码看起来会是这样的:

- -
var struct_TBButton;
-if (ctypes.voidptr_t.size == 4 /* 32-bit */) {
-  struct_TBButton = ctypes.StructType('TBButton', [
-    {'iBitmap': ctypes.int},
-    {'idCommand': ctypes.int},
-    {'fbState': ctypes.unsigned_char},
-    {'fsStyle': ctypes.unsigned_char},
-    {'bReserved': ctypes.unsigned_char},
-    {'bReserved2': ctypes.unsigned_char},
-    {'dwData': ctypes.uintptr_t},
-    {'iString': ctypes.intptr_t}
-  ]);
-}
-else if (ctypes.voidptr_t.size == 8 /* 64-bit */) {
-  struct_TBButton = ctypes.StructType('TBButton', [
-    {'iBitmap': ctypes.int},
-    {'idCommand': ctypes.int},
-    {'fbState': ctypes.unsigned_char},
-    {'fsStyle': ctypes.unsigned_char},
-    {'bReserved': ctypes.unsigned_char},
-    {'bReserved2': ctypes.unsigned_char},
-    {'bReserved3': ctypes.unsigned_char},
-    {'bReserved4': ctypes.unsigned_char},
-    {'bReserved5': ctypes.unsigned_char},
-    {'bReserved6': ctypes.unsigned_char},
-    {'dwData': ctypes.uintptr_t},
-    {'iString': ctypes.intptr_t}
-  ]);
-}
-else {
-  throw new Error("wut?!");
-}
-
-console.log(struct_TBButton.size);
-// 20 on 32-bit, 32 on 64-bit if I'm not mistaken
- -

There is another way to do this, we can use ArrayType, but example for this I don't know at this time.

- -

Credit for this example is to nmaier (StackOverflow :: Getting TB_BUTTON is crashing and not working)

- -

Example of cast and FunctionType on Windows

- -
Components.utils.import("resource://gre/modules/ctypes.jsm");
-
-var kernel = ctypes.open("kernel32.dll");
-var HMODULE = ctypes.uint32_t;
-var HWND = ctypes.uint32_t;
-var LPCTSTR = ctypes.jschar.ptr;
-var LPCSTR = ctypes.char.ptr;
-var LoadLibrary = kernel.declare("LoadLibraryW", ctypes.winapi_abi, HMODULE, LPCTSTR);
-var GetProcAddress = kernel.declare("GetProcAddress", ctypes.winapi_abi, ctypes.void_t.ptr, HMODULE, LPCSTR);
-
-var hUser = LoadLibrary("user32");
-var funcPtr = GetProcAddress(hUser, "MessageBoxW");
-
-// Now we have a pointer to a function, let's cast it to the right type
-var MessageBoxType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, [HWND, LPCTSTR, LPCTSTR, ctypes.uint32_t]);
-funcPtr = ctypes.cast(funcPtr, MessageBoxType.ptr);
-funcPtr(0, "Test1", "Test2", 0);
-
- -

Credit for this example is to Wladimir Palant (StackOverflow :: How to call a function using pointer in js-ctypes)

- -

See also

- - diff --git a/files/zh-cn/mozilla/js-ctypes/js-ctypes_reference/index.html b/files/zh-cn/mozilla/js-ctypes/js-ctypes_reference/index.html deleted file mode 100644 index d451510edb..0000000000 --- a/files/zh-cn/mozilla/js-ctypes/js-ctypes_reference/index.html +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: js-ctypes reference -slug: Mozilla/js-ctypes/js-ctypes_reference -tags: - - JavaScript - - NeedsTranslation - - TopicStub - - js-ctypes -translation_of: Mozilla/js-ctypes/js-ctypes_reference ---- - - -

This doc is a work in progress.

- -

ctypes Reference

- -

The ctypes object is the base of the ctypes API. It is obtained by by loading the ctypes module:

- -

Components.utils.import("resource://gre/modules/ctypes.jsm");

- -

You can use the ctypes object to load libraries, construct types, and perform miscellaneous tasks such as type casting. The ctypes object also provides numerous predefined types that correspond to primitives and common typedefs in C.

- -

Working with libraries

- -

To load a Library, use ctypes.open().

- -

The Library object is used mostly to declare native functions provided by the library so that js-ctypes knows how to call them. See Library.declare() for instructions on how to declare these functions.

- -

Once you have finished working with a Library, call Library.close().

- -

Calling conventions

- -

See ABI.

- -

Types and data

- -

To use js-ctypes effectively, it is important to understand the different kinds of objects that the module provides. There are three major categories:

- -

Types

- -

These represent a type in C, and are thus represented by CType objects. These objects have two main purposes. First, they provide a concrete representation of different data types, allowing the programmer to describe the arguments and return type of a native function (see Library.declare()).  Second, they serve as constructors to create concrete instances of the given type, i.e. CData objects.

- -

Out of the box, js-ctypes supports a number of predefined types.

- -

Type constructors

- -

These are functions that define new types, and thus return a CType object. These include

- - - -

Data

- -

These are instances of types, represented by CData objects and instantiated by calling CType objects as functions.

- -

These distinctions are crucial, and understanding them will alleviate much of the confusion surrounding js-ctypes. Calling a Type Constructor will return a CType. Calling a CType will return a CData. You declare the arguments and return value of a native function with CType objects. You call a native function with CData objects.

- -

Other Features

- -

Error-handling

- -

js-ctypes supports both errno (on all platforms) and GetLastError (on Windows platforms).

- -

Callbacks

- -

You can pass regular JavaScript functions as callbacks to native functions. See the Callbacks page for details.

- -

64-Bit integer handling

- -

Because JavaScript Number objects can't directly represent every possible 64-bit integer value, js-ctypes provides new types for these. See Int64 and UInt64.

diff --git a/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/declaring_and_using_callbacks/index.html b/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/declaring_and_using_callbacks/index.html deleted file mode 100644 index ae8223ec83..0000000000 --- a/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/declaring_and_using_callbacks/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: Declaring and Using Callbacks -slug: Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks -tags: - - 回调 - - 声明和使用回调 - - 立即调用函数表达式 -translation_of: Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks ---- -

{{jsctypesSidebar("Introduction")}}

- -

C函数偶尔将函数指针作为参数,它们通常用作回调。.在这些情况下,js-ctypes允许您传递常规JavaScript函数作为回调。这是非常强大的,因为它允许本地代码透明地调用JavaScript。

- -
警告: 回调必须在它们注册的同一线程上调用。js-ctypes中没有并发逻辑,因此在其他线程上调用回调会导致事情崩溃。
- -

先决条件

- - - -

声明回调

- -

A callback is declared by using ctypes.FunctionType. The first argument is the calling convention, the second argument is the return type, and the third is an array of arguments the callback expects.

- -

The return type of the javascript callback must match the return type declared, otherwise js-ctypes will throw an error saying "unexpected return type".

- -

范例

- -

例子 1

- -

这个回调返回bool并有两个参数。

- -
var myFuncTypeDeclaration = ctypes.FunctionType(ctypes.default_abi, ctypes.bool, [ctypes.int, ctypes.voidptr_t]);
-
-function myJSCallback(cInt, cPtr) {
-    return true; // as the return of the FunctionType was ctypes.bool we must make our javascript callback return bool otherwise js-ctypes will throw error saying unexpected type return
-}
-
-var myCCallback = myFuncTypeDeclaration.ptr(myJSCallback);
-
- -

例子 2

- -

这个回调返回void,没有参数。当void是返回类型时,javascript回调一定不能返回,或者它应该返回未定义。

- -
var myFuncTypeDeclaration = ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, []);
-
-function myJSCallback() {
-    return undefined; // as the return of the FunctionType was ctypes.void_t we must return undefined OR dont return at all otherwise js-ctypes will throw an error saying unexpected type
-}
-
-var myCCallback = myFuncTypeDeclaration.ptr(myJSCallback);
-
- -

使用回调

- -

Since callbacks are function pointers in C, js-ctypes has special handling for function pointer types. Consider the following code:

- -
function myJSCallback(foo, bar) { .... };
-var funcType = ctypes.FunctionType(...);
-var funcPtrType = funcType.ptr;
-var regularFuncPtr = funcPtrType();
-var callback = funcPtrType(myJSCallback);
-
- -

js-ctypes detects that funcPtrType is a type of function pointer, and adds a special case to its constructor. In the ordinary case, invoking the type object creates a regular CData object containing a pointer to the data. However, if the first argument is a function, js-ctypes creates a special object (known internally as a CClosure) that wraps the JavaScript function within an ordinary C function. This can all be done in a single line of code, like so:

- -
var callback = ctypes.FunctionType(...).ptr(function(...) {...});
-
- -
Note: The use of .ptr() here isn't a method call; we're accessing a property that dynamically creates a callable object, and then invoking the result.
- -

If two arguments are passed to the callback constructor, the second is used as the this parameter:

- -
function myJSCallback() {
-  alert(this.message);
-};
-
-var receiver = { message: 'hi there!' };
-var callback = funcPtrType(myJSCallback, receiver); // alerts with 'hi there' when the callback is invoked
-
- -

If three arguments are passed to the callback constructor, the third argument is used as a sentinel value which the callback returns if an exception is thrown. The sentinel value must be convertible to the return type of the callback:

- -
function myJSCallback() {
-  throw "uh oh";
-};
-
-var callback1 = funcPtrType(myJSCallback, null, -1); // Returns -1 to the native caller when the exception is thrown.
-
- -
Warning: You must store a reference to the callback object as long as the native code might call it. If you don't, the GC might collect the relevant data structures, and the browser will crash when native code attempts to invoke your callback.
- -

参数和返回值

- -

js-ctypes automatically handles the conversion between JavaScript and C value representations. Before the JavaScript callback function is invoked, js-ctypes converts the arguments passed by the caller to JavaScript values. Where possible, js-ctypes will convert arguments to primitive types. For arguments of complex types, temporary CData objects will be created.

- -

The return value is converted in a similar manner.

diff --git a/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/index.html b/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/index.html deleted file mode 100644 index 6a91cfb28f..0000000000 --- a/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/index.html +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: 使用 js-ctypes -slug: Mozilla/js-ctypes/Using_js-ctypes -translation_of: Mozilla/js-ctypes/Using_js-ctypes ---- -

{{ gecko_minversion_header("2.0") }}

- -

{{ draft() }}

- -

在使用 js-ctypes 前,你需要导入 ctypes.jsm 代码模块(Javascript Code Module)。这非常简单,只需要在所需的 Javascript scope 内包含下面这行代码 :

- -
Components.utils.import("resource://gre/modules/ctypes.jsm")
- -

加载本地库

- -

在引入上述的代码模块后,你可以调用 ctypes.open() 来加载你想使用的本地库。例如:在Windows下,你可以这样引入系统的user32库:

- -
var lib = ctypes.open("user32.dll");
- -

On Mac OS X, you can load the Core Foundation library from the Core Foundation framework like this:

- -
var coreFoundation = ctypes.open("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation");
- -

返回值是一个库对象,你可以用这个库对象去声明方法和数据类型,以供使用。

- -
Note: js-ctypes only works with C libraries; you can't use C++ methods directly. Instead, you'll need to create a shim library that uses C functions that then call into the C++ library for you.
- -

库搜索路径

- -

如果你指定了库的完整路径,那么就可以直接加载该库. 否则,系统会以一套标准的流程来搜索该库。

- -

Windows

- -

在Window下,搜索库的顺序如下:

- -
    -
  1. The application's directory.
  2. -
  3. The system directory.
  4. -
  5. The 16-bit system directory.
  6. -
  7. The Windows directory.
  8. -
  9. The current working directory
  10. -
  11. The directories listed in the PATH environment variable.
  12. -
- -
Note: 该内容来至于 this article on MSDN.
- -

用完了

- -

当你使用完库之后,你应该通过调用库对象的close()方法来关闭它。

- -
lib.close();
- -

如果关闭库失败,库会在垃圾回收时,自动关闭。

- -

使用库

- -

你可能需要声明一些新类型。这些类型可能是简单的,也可能是像结构体这样较复杂的类型,欲知详情请查看 Declaring types。大多数情况下,你会需要 声明一个或多个函数(declare one or more functions),以供调用。 

- -

只要你声明了类型和方法,你就可以使用他们。 实例化C 类型的数据对象和引用他们可以参考 Working with data

- -

内存管理

- -

If JS code creates a structure or array, that memory will be valid as long as the JS object stays alive. Pointers to that memory must be carefully managed to make sure the underlying memory is still referenced.

- -

When binary code hands back a pointer/handle to allocated memory, the JS code must make sure to free that memory with the correct allocator. It is usually best to expose a freeing function from the binary.

- -

保持活着的对象

- -

The following js-ctypes objects will hold references to objects, keeping them alive. This is not an exhaustive list, but will help you understand memory management and how it affects your use of js-ctypes:

- - - -

究竟会不会保持活着的对象

- -

It's important to note that getting direct access to the contents of a CData object using address(), addressOfElement(), or contents, will result in a CData object that does not hold its referent alive. Be sure to hold an explicit reference to be sure the referent object doesn't get garbage collected before you're done using it.

- -

闭包

- -

You also need to be sure to retain references to any JavaScript code that native code may call back into. This should be obvious, but is important enough to be worth stating explicitly.

- -

当有疑问时, malloc()

- -

When you absolutely, positively need to keep data around, you can use malloc() to allocate it directly. This bypasses JavaScript's memory management and lets you handle memory management yourself.

- -

示例

- -

这些例子提供对js-ctypes使用的快速浏览。 要看更复杂的例子,请翻阅js-ctypes examples

- -

调用 Windows 例程

- -

这个例子演示了怎么使用ctypes来调用Win32 API。

- -
Components.utils.import("resource://gre/modules/ctypes.jsm");
-
-var lib = ctypes.open("C:\\WINDOWS\\system32\\user32.dll");
-
-/* Declare the signature of the function we are going to call */
-var msgBox = lib.declare("MessageBoxW"/* 函数名称*/,
-                         ctypes.winapi_abi,/*ABI类型,有3种,这里指调用系统的接口*/
-                         ctypes.int32_t,/*返回值*/
-                         ctypes.int32_t,/*告警类型*/
-                         ctypes.jschar.ptr,/*告警内容*/
-                         ctypes.jschar.ptr,/*标题*/
-                         ctypes.int32_t);/*按钮类型*/
-var MB_OK = 0;
-
-var ret = msgBox(0, "Hello world", "title", MB_OK);
-
-lib.close();
- -

第三行, 就是 user32.dll 系统库被加载的地方。第六行声明了 msgBox() 函数是一个调用系统函数MessageBoxW的方法. 第十五行调用了msgBox() ,会显示出一个告警框哦~。

- -

最后当我们完成使用之后,千万记得用close来关闭它。

- -

相较于给定完整的路径,通常只是给一个文件名。

- -

关于声明函数

- -

我们已经知道可以通过MSDN来获取MessageBox (MessageBoxW is just a unicode version of same function) 的相关信息,用以声明函数。也学习了关于lib.declare怎么使用:lib.declare. 学习了数据类型的使用: Data Types. 我们知道了它可以这样来声明:

- -
int WINAPI MessageBox(
-  _In_opt_  HWND hWnd,
-  _In_opt_  LPCTSTR lpText,
-  _In_opt_  LPCTSTR lpCaption,
-  _In_      UINT uType
-);
- -

所以我们阅读这个文章关于类型定义和使用: Declaring Types

- -
var lib = ctypes.open("user32.dll");
-
- -

甚至不用后缀:

- -
var lib = ctypes.open("user32");
-
- -

在 Mac OS X 上调用 Carbon 例程

- -

This example demonstrates how to use ctypes to call a Carbon function on Mac OS X.

- -
Note:This example will not work on 64bit OS X, you will likely need to change to the Cocoa API.
- -
/* build a Str255 ("Pascal style") string from the passed-in string */
-
-function makeStr(str) {
-  return String.fromCharCode(str.length) + str;
-}
-
-Components.utils.import("resource://gre/modules/ctypes.jsm");
-
-var carbon = ctypes.open("/System/Library/Frameworks/Carbon.framework/Carbon");
-
-stdAlert = carbon.declare("StandardAlert",       /* function name */
-                          ctypes.default_abi,    /* ABI type */
-                          ctypes.int16_t,        /* return type */
-                          ctypes.int16_t,        /* alert type */
-                          ctypes.char.ptr,       /* primary text */
-                          ctypes.char.ptr,       /* secondary text */
-                          ctypes.uint32_t,       /* alert param */
-                          ctypes.int16_t);       /* item hit */
-
-var hit = 0;
-var msgErr = makeStr("Carbon Says...");
-var msgExp = makeStr("We just called the StandardAlert Carbon function from JavaScript!");
-
-var err = stdAlert(1, msgErr, msgExp, 0, hit);
-
-carbon.close();
- -

The makeStr() function is a utility routine that takes as input a standard JavaScript string and returns a Carbon-style "Pascal" string, which is a length byte followed by the characters of the string itself. Note that this only works correctly if the string is in fact under 256 characters; if it's longer, this will fail spectacularly.

- -

In line 9, the Carbon library is loaded from the system's Carbon framework.

- -

Line 11 declares the stdAlert() function, which will call the Carbon StandardAlert routine. It uses the default ABI, returns a 16-bit integer (which is a Carbon OSErr value), and accepts an integer (the alert type), two strings, a pointer to a parameter block, which we aren't using, and another integer, which is used to return the hit item. See Apple's documentation for StandardAlert for details.

- -

After that, we simply set up our parameters by using makeStr() to generate the two Str255 strings we need, then call stdAlert(), which produces the following alert window:

- -

ctype-mac-dialog.png

- -

The last thing we do is call carbon.close() to close the library when we're done using it.

- -

在 Linux/POSIX 上调用 LibC 例程

- -

This example demonstrates how to use ctypes to call a libc function on Linux.

- -
/* import js-ctypes */
-Components.utils.import("resource://gre/modules/ctypes.jsm");
-
-/* Open the library */
-try {
-    /* Linux */
-    var libc = ctypes.open("libc.so.6");
-} catch (e) {
-    /* Most other Unixes */
-    libc = ctypes.open("libc.so");
-}
-
-/* Import a function */
-var puts = libc.declare("puts",             /* function name */
-                        ctypes.default_abi, /* call ABI */
-                        ctypes.int,       /* return type */
-                        ctypes.char.ptr);   /* argument type */
-
-var ret = puts("Hello World from js-ctypes!");
-wge
diff --git a/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/memory_management/index.html b/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/memory_management/index.html deleted file mode 100644 index 291ef8205d..0000000000 --- a/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/memory_management/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: 内存管理 -slug: Mozilla/js-ctypes/Using_js-ctypes/Memory_Management -tags: - - GC - - js-ctypes - - 内存管理 -translation_of: Mozilla/js-ctypes/Using_js-ctypes/Memory_Management ---- - - -

内存管理

- -

If JS code creates a structure or an array, that memory will be valid as long as the JS object stays alive. Pointers to that memory must be carefully managed to make sure the underlying memory is still referenced.

- -

When binary code hands back a pointer/handle to allocated memory, the JS code must make sure to free that memory with the correct allocator. It is usually best to expose a freeing function from the binary.

- -

保持 objects 活着

- -

The following js-ctypes objects will hold references to objects, keeping them alive. This is not an exhaustive list, but will help you to  understand memory management and how it affects your use of js-ctypes:

- - - -

什么不保持 objects 活着

- -

It's important to note that getting direct access to the contents of a CData object using address()addressOfElement(), or contents, will result in a CData object that does not hold its referent alive. Be sure to hold an explicit reference so that the referent object doesn't get into garbage collection, before you're done using it.

- -

闭包

- -

You also need to be sure to retain references to any JavaScript code that native code may call back into. This should be obvious, but is important enough to be worth stating explicitly.

- -

有疑问时, malloc()

- -

When you need to keep data around, you can use malloc() to allocate it directly. This bypasses JavaScript's memory management and lets you handle memory management yourself.

- - diff --git a/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/working_with_arraybuffers/index.html b/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/working_with_arraybuffers/index.html deleted file mode 100644 index 521fa9030f..0000000000 --- a/files/zh-cn/mozilla/js-ctypes/using_js-ctypes/working_with_arraybuffers/index.html +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: Working with ArrayBuffers -slug: Mozilla/js-ctypes/Using_js-ctypes/Working_with_ArrayBuffers -translation_of: Mozilla/js-ctypes/Using_js-ctypes/Working_with_ArrayBuffers ---- - - -

导读

- -

类型转换页的指针类型部分解释了此操作的基本原理。第二个代码示例提供了操作的具体说明。

- -

ArrayBuffer 是简单的字节数组 ,这种js 类型 等同于 ctypes.uint8_t.array(###) (ctypes.unsigned_char are also ctypes.uint8_t).

- -

bug 732936 包括使用ArrayBuffer的讨论.

- -

This feature is based on the following work:

- -

https://dxr.mozilla.org/mozilla-central/source/js/src/ctypes/CTypes.cpp#3080

- -

https://dxr.mozilla.org/mozilla-central/source/js/src/vm/ArrayBufferObject.cpp#1301

- -

Example 1 - Image Data

- -

The following example illustrates how to transfer a byte array pointed by ctypes.uint8_t.ptr to ImageData of canvas. This example is based on the fact that the ImageData returned from CanvasRenderingContext2D.getImageData is a Uint8ClampedArray view for an ArrayBuffer.

- -

The following codeblock provides a basic example of getting and setting Uint8ClampedArray and ArrayBuffer of ImageData:

- -
// context is a CanvasRenderingContext2D of some canvas
-var imageData = context.getImageData(x, y, w, h);
-var array = imageData.data; // array is a Uint8ClampedArray
-var buffer = imageData.data.buffer; // buffer is a ArrayBuffer
-
-// incomingBuffer is a TypedArray
-var imageData2 = context.createImageData(w, h);
-imageData2.data.set(incomingBuffer);
-
- -

Further, if you have a byte array pixelBuffer, and you need to create ImageData from it. The data property holds an array of bytes.

- -

We start with the following:

- -
// pixelBuffer is a pointer to a RGBA pixel buffer of 400x400 image.
-pixelBuffer.toString(); // "ctypes.uint8_t.ptr(ctypes.UInt64("0x352e0000"))"
-
-var imgWidth = 400;
-var imgHeight = 400;
-var myImgDat = new ImageData(imgWidth, imgHeight);
-
- -

Method 1: Passing ArrayType CData to Uint8ClampedArray.prototype.set

- -

One method is to get into a js-ctypes array, and then set it into the ImageData, as illustrated by the following code example.

- -
// Cast pointer to array, to pass to Uint8ClampedArray.prototype.set.
-var casted = ctypes.cast(pixelBuffer.address(), ctypes.uint8_t.array(myImgData.data.length).ptr).contents; // myImgDat.data.length is imgWidth * imgHeight * 4 because per pixel there is r, g, b, a numbers
-casted.toString(); // "ctypes.uint8_t.array(640000)([45, 66, 135, 255, 99, 86, 55, 255, .......... ])"
-myImgDat.data.set(casted);
-
- -

The ctypes.cast takes a couple of milliseconds, however, the myImgDat.data.set takes up to 800ms for a size of 52,428,800 (which is image size of 1280 x 1024 pixels). So, for the size of 640,000 it takes about 98ms.

- -

Method 2: Manually Handled

- -

Another strategy is to handle it manually, as illustrated by the following code example:

- -
var casted = ctypes.cast(pixelBuffer.address(), ctypes.uint8_t.array(myImgData.data.length).ptr).contents; // myImgDat.data.length is imgWidth * imgHeight *4 because per pixel there is r, g, b, a numbers
-
-/** METHOD A **/
-for (var nIndex = 0; nIndex < casted.length; nIndex = nIndex + 4) { // casted.length is same as myImgDat.data.length
-    var r = casted[nIndex];
-    var g = casted[nIndex + 1];
-    var b = casted[nIndex + 2];
-    var a = casted[nIndex + 3];
-
-    myImgDat.data[nIndex] = r;
-    myImgDat.data[nIndex + 1] = g;
-    myImgDat.data[nIndex + 2] = b;
-    myImgDat.data[nIndex + 3] = a;
-}
-
-
-/***** OR DO THE BELOW WHICH USES THE .set METHOD *****/
-
-/** METHOD B **/
-var normalArr = [];
-for (var nIndex = 0; nIndex < cast.length; nIndex = nIndex + 4) { // casted.length is same as myImgDat.data.length
-    var r = casted[nIndex];
-    var g = casted[nIndex + 1];
-    var b = casted[nIndex + 2];
-    var a = casted[nIndex + 3];
-
-    normalArr.push(r);
-    normalArr.push(g);
-    normalArr.push(b);
-    normalArr.push(a);
-}
-myImgDat.data.set(normalArr);
-
- -

The preceding example, however, does not take advantage of Method 1, but instead manually goes through the array and sets the ImageData array. The cast takes a couple of milliseconds, roughly the same as Method 1. However, the manual Method A, in the preceding example, takes ~1300 ms. Method B takes ~1400 ms, for an array length of 52,428,800 (which is image size of 1280 x 1024 pixels).

- -

Method 3: Transfer byte array by calling memcpy

- -

This is the recommended method, as it only takes a couple of milliseconds, even for large arrays. Notice that the following example does not cast the pixelBuffer. Passing an ArrayBuffer object to pointer type will pass the pointer to buffer (Based on https://dxr.mozilla.org/mozilla-central/source/js/src/ctypes/CTypes.cpp#3080). Further, it returns dataPointer, and there is no extra allocation (Based on https://dxr.mozilla.org/mozilla-central/source/js/src/vm/ArrayBufferObject.cpp#1301).

- -
var lib;
-switch (OS.Constants.Sys.Name.toLowerCase()) {
-    case 'winnt':
-    case 'winmo':
-    case 'winnt': //windows
-        lib = ctypes.open('msvcrt');
-        break;
-    case 'darwin': // mac
-        lib = ctypes.open('libc.dylib');
-        break;
-    case 'freebsd':
-        lib = ctypes.open('libc.so.7');
-        break;
-    case 'openbsd':
-        lib = ctypes.open('libc.so.61.0');
-        break;
-    case 'android':
-    case 'sunos':
-    case 'netbsd':
-    case 'dragonfly':
-        lib = ctypes.open('libc.so');
-        break;
-    case 'linux':
-        lib = ctypes.open('libc.so.6');
-        break;
-    case 'gnu/kfreebsd':
-        lib = ctypes.open('libc.so.0.1');
-        break;
-    default:
-        //assume unix
-        try {
-            lib = ctypes.open(ctypes.libraryName('c'));
-        } catch (ex) {
-            throw new Error('I dont know where to memcpy is defined on your operating system, "' + OS.Constants.Sys.Name + '"');
-            lib.close();
-        }
-}
-
-try {
-    var memcpy = lib.declare('memcpy', OS.Constants.Sys.Name.toLowerCase().indexOf('win') == 0 ? ctypes.winapi_abi : ctypes.default_abi,
-        ctypes.void_t, // return
-        ctypes.void_t.ptr, // *dest
-        ctypes.void_t.ptr, // *src
-        ctypes.size_t // count
-    );
-} catch (ex) {
-    throw new Error('I dont know where to memcpy is defined on your operating system, "' + OS.Constants.Sys.Name + '"');
-    lib.close()
-}
-
-memcpy(myImgDat.data, pixelBuffer, myImgDat.data.length); // myImgDat.data.length is imgWidth * imgHeight *4 because per pixel there is r, g, b, a numbers
-
-lib.close();
-
- -

See Also

- - diff --git a/files/zh-cn/mozilla/localization/faq/index.html b/files/zh-cn/mozilla/localization/faq/index.html deleted file mode 100644 index 33cecd28f0..0000000000 --- a/files/zh-cn/mozilla/localization/faq/index.html +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: 本地化 FAQ -slug: Mozilla/Localization/FAQ -tags: - - 本地化 -translation_of: Mozilla/Localization/FAQ ---- -

 

- -

本页列出了可能不需要完整页面的调整和提示。 有关通用本地化的更多详细文档,请参阅我们的 本地化 页面。
-
- 我如何在实体中保留空白?
-         如果你真的想保留空格,或者你正在寻找一个不间断的空间,你可以通过&ua0; 或 \ua0 到DTD和属性文件,
- 如何在 .properties 条目中不显示变量?
-         您可以简单地将该值设置为零宽度,即使用%1$0.S

- -

 

diff --git a/files/zh-cn/mozilla/localization/index.html b/files/zh-cn/mozilla/localization/index.html deleted file mode 100644 index b74757ccc1..0000000000 --- a/files/zh-cn/mozilla/localization/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: 参与 Mozilla 本地化工作 -slug: Mozilla/Localization -tags: - - Landing - - Localization - - Mozilla - - NeedsTranslation - - TopicStub - - Translation - - l10n -translation_of: Mozilla/Localization ---- -

Localization (L10n) is the process of translating software user interfaces from one language to another and adapting it to suit a foreign culture. These resources are for anyone with an interest in the technical aspects involved in localization. They are for developers and all contributors

- -

See also

- - diff --git a/files/zh-cn/mozilla/localization/l10n_style_guide/index.html b/files/zh-cn/mozilla/localization/l10n_style_guide/index.html deleted file mode 100644 index 86e242c5ca..0000000000 --- a/files/zh-cn/mozilla/localization/l10n_style_guide/index.html +++ /dev/null @@ -1,482 +0,0 @@ ---- -title: Mozilla 本地化风格指南 -slug: Mozilla/Localization/L10n_Style_Guide -translation_of: Mozilla/Localization/L10n_Style_Guide ---- -

前言

- -
      风格指南定义风格指南用于定义我们用来评价翻译质量的标准 Mozilla 和 Mozilla 的本地化社区定义的规则组成,主要针对如何以最佳的方式翻译 Mozilla 的产品网站和其他项目。风格指南可以用来同时翻译和评估翻译质量。通过遵循这些规则,翻译人员会更容易得到高质量的翻译,便于更好的展示 Mozilla 的价值观和文化。这里我们列出国际上其他组织制定的一些风格指南的例子:
- - - -
本风格指南分为两个主要部分:第一部分特定语言相关,必须由每个 Mozilla 的本地化社区(包括特定的语言风格,术语和单位)来定义的规则;第二个是由 Mozilla 为所有语言定义的一般规则,可以帮助你较好的翻译(包括准确度和流畅性原则
- -

 

- -

简体中文相关 Mozilla 风格

- -
    -
- -
-

基本要求

- -
    -
  1. -

    准确表述原文的意思、情感、立场、价值观;

    -
  2. -
  3. -

    既要避免翻译后反而模糊,也要避免翻译无须翻译的词语,力求浅显易懂;

    - -
      -
    • -

      若有译法尚有争议的单词,应采用最常使用的译法,并在词语后以全角括号标注英文

      -
    • -
    -
  4. -
  5. -

    中文应该意思清晰且符合中文表达习惯,同一句里不要重复出现相同主语(如“if you forget your password”应译为“如果您忘记了密码”),且应适当减少数词与量词

    -
  6. -
  7. -

    明显是美国文化的,或在中国大陆当代文化下难以理解的,可用相近的中国大陆文化代替,但不能与第 1 点抵触;

    -
  8. -
  9. -

    不必字对字、句对句翻译,原文如果表达不清晰,中文应该意译,并且应根据上下文和注释进行推断并填补或删减相应的信息,但不能与第 1 点抵触;

    -
  10. -
  11. -

    情况 5 不能太多;

    -
  12. -
  13. -

    对同样短语的翻译,前后必须一致,可利用 Pontoon 的 Translation Memory 查看以往译法,也可参考其他工具

    -
  14. -
  15. -

    对用户和开发者称“您”,对职员和志愿者称“你”,若需轻松的语气则一律用“你”;

    -
  16. -
  17. -

    不要使用机器翻译的成果来提交,也就是说您可以使用 Google Translate 来帮助您理解内容,但是不能不经考虑就把其自动翻译的结果放在翻译里;

    -
  18. -
  19. -

    若产品内显示的中文换行不理想,应适当增删文字,在网页上也可使用 \n 强制换行。

    -
  20. -
  21. -

    不太有把握的,请大胆地通过这些方式进行讨论。

    -
  22. -
-
- -
 
- -
-

术语表

- -
这里我们列出一些可参考的 软件/互联网 相关的术语和定义的列表:
- - - -
使用对应术语翻译的时候,请注意要保持一致性。而且要注意避免以下几点:
- - - -
 
- -

词语形式

- -
复数 
- -
Pontoon 上 zh-CN 区分单复数。汉语由于没有区分单复数形式,所以一般单数和复数翻译成一样即可。但有时区分单复数会带来更好效果。
- -
 
- -
特殊符号
- -
 
- -
-

常用的有以下几个:

- -
    -
  • -

    \n   换行

    -
  • -
  • -

    \t   水平制表符

    -
  • -
  • -

    \v  竖直制表符

    -
  • -
- -

您不需要将同样数量的格式标记放在翻译中,但是如果它们之一有在原文开始或者结束位置的时候,您必须在翻译中使之包含在对应的开始或者结束之处。

- - -

如果要显示非转义字符,则需要使用 \ 来表明取消转义,如 " (半角双引号)表示字符串的开始或者结束,如果要在内容中使用该符号,则需输入 \",还可以参考以下例子:

- -

----------------------------------------------------------------

- -

\"\\t\"

- -

----------------------------------------------------------------

- -

在运行时显示的结果是 "t"

- - -

(2)XML 中的角括号和“&”号

- -

有一些模块中 XML 被频繁地使用,XML 将“<”“>”和“&”视为保留字符,您不能将其直接添加到翻译中。必须将其实体以下面的形式表示:

- -

&lt 代表 <; &gt 代表 >; &amp 代表 &。

- - -

(3) TRUE 和 FALSE

-“TRUE”和“FALSE”多不要翻译它们。如果程序读不到正确的值,可能会出现问题。
- -
 
- -
标点的使用
- -

一般的原则是:除了小括号、省略号和破折号保留不变以外,都应该使用中文(全角)标点符号。英文标点符号后方常常跟随有一个半角空格,请在翻译成中文标点符号时将其去除。

- - -
    -
  1. -

    英文中的 , 在中文中可能是 ,或者 、

    -
  2. -
  3. -

    英文中的 . 在中文中应该是 ,或者 。,视上下文而定,多数是 。

    -
  4. -
  5. -

    英文中的 \"%s\" 在 GUI 程序中应该翻译为 “%s”, 而不是 \"%s\" 或者 \“%s\”,而且后者是不符合换码序列要求的。即在 GUI 程序中`something' 和 'something' 以及 \"something\" 都应该翻译为 “某事”

    -
  6. -
  7. -

    英文中的 : 应该翻译为:(全角)而不是 :(半角), 而作为分隔符时(例如时间),: 保留为英文(半角)的, 因为这个时候不是标点符号

    -
  8. -
  9. -

    英文中的 ( ) 应该一般都翻译成全角小括号( )。

    -
  10. -
  11. -

    英文中的“…”或“...”,应该保持不变,前者等价于半个全角中文省略号

    -
  12. -
  13. -

    英文中的 -- 应该保持不变。由于全角破折号 —— 兼容性不好,有时显示为两个方格,所以不再使用。

    -
  14. -
  15. -

    其他标点符号的使用参见中华人民共和国 GB/T 15834-2011

    -
  16. -
- -
 
- -
空格
- -
-

为了美观,通常建议在中文与英文、中文与阿拉伯数字、英文与阿拉伯数字之间加入一个半角空格。例如:

- -

----------------------------------------------------------------

- -

原文 "Installing driver for %1"

- -

翻译 "正在安装 %1 的驱动程序"

- - -

原文 ""

- -

"Parameter start_num specifies the character at which to start the search. "

- -

"The first character is character number 1. If start_num is omitted, it is "

- -

"assumed to be 1."

- -

翻译 ""

- -

"参数 start_num 指定开始搜索的字符位置。第一个字符序号为 1。如果省略 "

- -

"start_num,默认它为 1。"

- -

----------------------------------------------------------------

- - -

对于小括号和全角双引号,其两侧不加空格:

- -

----------------------------------------------------------------

- -

原文 "Original idea and author (KDE1)"

- -

翻译 "原始创意和作者(KDE1)"

- - -

原文 ""

- -

"The APM Management subsystem seems to be disabled.\n"

- -

"Try executing \"apm -e 1\" (FreeBSD) and see if \n"

- -

"that helps.\n"

- -

翻译 ""

- -

"APM 管理子系统似乎被禁用了。\n"

- -

"试试执行“apm -e 1”(FreeBSD)并看看\n"

- -

"是否有用。\n"

- -

----------------------------------------------------------------

- - -

包含 XML/HTML 标签的条目,如要在标签中的内容两侧添加空格,请把空格置于标签外侧,否则空格可能显示不出来。

- -

----------------------------------------------------------------

- -

这是 &lt;b&gt;HTML&lt;/b&gt; 的语法手册

- -

----------------------------------------------------------------

-
- -
 
- -
单项中的快捷字符
- -

  与 Gnome 或者 KDE 菜单不同,Firefox 中的菜单快捷键无需添加到翻译的字符串中。

- -

例如:

- -

KDE 菜单:

- -

----------------------------------------------------------------

- -

msgid "C&lear"

- -

msgstr "清除(&L)"

- -

----------------------------------------------------------------

- -

而 Firefox 中,直接翻译为 "清除"即可,不可添加 "(&L)"。

- -
翻译中参数的位置
- -

有时候原来的参数顺序不符合中文的语法,一方面, 翻译可以通过调整副词、语序等手法来符合中文习惯,另外一方面,在必要的情况下,需要改变参数的位置,例如:

- -

----------------------------------------------------------------

- -

原文 "%1$S articles match rule %2$S"

- -

翻译 "匹配规则 %2$S 的文章有 %1$S 个"

- -

----------------------------------------------------------------

- - -

即用 %1$S、%2$S、%3$S 等符号标明参数在原文里出现的位置。同时,任何一个参数的顺序进行了调整,则在这一句译文中所有参数都必须注明原文位置,否则无法通过格式检查。

- -
关于换行
- -

对于很长的译文,就涉及到了换行问题。多数情况下没有限制,因为不影响最终的显示效果,只要阅读起来方便就行。下面几种格式都是正确的:

- -

----------------------------------------------------------------

- -

原文 ""

- -

"Preview failed: neither the internal KDE PostScript viewer (KGhostView) nor "

- -

"any other external PostScript viewer could be found."

- -

翻译 ""

- -

"预览失败:找不到 KDE 内建的 PostScript 查看器(KGhostView)或其它外部"

- -

"的 PostScript 查看器。"

- - -

原文 ""

- -

"Preview failed: neither the internal KDE PostScript viewer (KGhostView) nor "

- -

"any other external PostScript viewer could be found."

- -

翻译 "预览失败:找不到 KDE 内建的 PostScript 查看器(KGhostView)或其它外部"

- -

"的 PostScript 查看器。"

- - -

原文 ""

- -

"Preview failed: neither the internal KDE PostScript viewer (KGhostView) nor "

- -

"any other external PostScript viewer could be found."

- -

翻译 ""

- -

"预览失败:找不到 KDE 内建的 PostScript 查"

- -

"看器(KGhostView)或其它外部"

- -

"的 PostScript 查看器。"

- -

----------------------------------------------------------------

- -
 
- -
关于时间的翻译
- -

鉴于关于日期和时间的译法十分复杂,现在将国家标准中有关规定简要介绍一下,并给出推荐译法。

- -

国标 GB/T 7408-94《数据元和交换格式 信息交换 日期和时间表示法》

- -

1994-12-06 发布,1995-08-01 实施   国家技术监督局发布

- -

本标准等效采用国际标准 ISO 8601-1988《数据元和交换格式  信息交换 日期和时间表示法》

- - -

以下是最需要注意的几个要点:

- -

(1) 在日期格式中不能出现空格,即“2003 年”这样的格式是不符合国标的。

- -

(2) 表示日期时,必须按照年月日的顺序;年份一般用四位数字,而月、日必须使用带前导零的两位数字;必须使用“-”作为分隔符,或完全不使用分隔符。 即“2004-01-03”或“20040103”来表示 2004年1月3日。

- -

(3) 表示时间时,时、分、秒都必须使用两位数字,中间用“:”(半角括号)分隔,或完全不使用分隔符。小时计法采用 24 小时制,不区分上下午。

- -

(4) 日期和时间写在一起的时候,应先写日期再写时间。在日期和时间都不使用分隔符的情况下,在中间添加字母“T”进行分隔,即“19850412T101530”。

- - -

时间的表示方法同 date 命令的表示方法,现将常见的几个对应其含义列表如下:

- -
    -
  1. -

    %%     一个 % 字符

    -
  2. -
  3. -

    %A      星期几(如“星期一”)

    -
  4. -
  5. -

    %B      月份(如“八月”)

    -
  6. -
  7. -

    %d      日期(00-31)

    -
  8. -
  9. -

    %D      日期,格式等于 %m/%d/%y (例如:08/25/09)

    -
  10. -
  11. -

    %F      日期,格式等于 %Y-%m-%d (例如:2009-08-25)

    -
  12. -
  13. -

    %g      ISO-8601 格式年份的最后两位(例如:09)

    -
  14. -
  15. -

    %G      ISO-8601 格式年份(例如:2009)

    -
  16. -
  17. -

    %H      小时(00-23)

    -
  18. -
  19. -

    %i       小时(00-12)

    -
  20. -
  21. -

    %m     月份(01-12)

    -
  22. -
  23. -

    %M     分钟(00-59)

    -
  24. -
  25. -

    %n      换行

    -
  26. -
  27. -

    %p      显示“上午”或者“下午”两个字

    -
  28. -
  29. -

    %S      秒(00-60)

    -
  30. -
  31. -

    %t       制表符

    -
  32. -
  33. -

    %T      时间,等于 %H:%M:%S

    -
  34. -
  35. -

    %x      日期(例如:12/31/99)

    -
  36. -
  37. -

    %X      时间(例如:23:13:48)

    -
  38. -
  39. -

    %y      年份的最后两位(例如:09)

    -
  40. -
  41. -

    %Y      年份(例如:2009)

    -
  42. -
- -

 

- -

参考文档: 开源软件简体中文翻译指南

- -

 

-
- -

Mozilla l10n 通用翻译风格

- -

准确度

- -

意译

- -
翻译的重中之重是达意。译者需要首先本身理解文字的确切意思,然后尽量寻找自己语言中最贴切的文字,尽量不增加或删减任何多余的意义。 有时,要找到完全一致的翻译可能会很困难,当发生这样的情况时,多问问自己如下这些问题:
- - - -

有些时候,旧的翻译记录以及机器翻译工具可能会提供错误的建议。如果您的翻译流程中使用了其中任何一种,请确保在提交翻译之前检查并修正。要完全避免文字直译,特别是对那些看起来在中英文之间相似,但是实际上意思可能不同的词。

- -

不应翻译的内容

- -
快捷键以及访问键
- -

在 Firefox 或其他软件中,均可以使用键盘快捷键来调用特定的命令。例如,可以使用组合键 CTRL+O (Mac 为 Cmd+O  ) 打开一个文件。加速键则因操作系统而异,但是对应的字符一般也是可本地化的。这通常被称为快捷键或者命令键。例如,打开文件… 菜单通常对应:

- -
<!ENTITY openFileCmd.label "Open File…">
-<!ENTITY openFileCmd.accesskey "O">
-<!ENTITY openFileCmd.commandkey "o">
- -

命令键保存在键 openFileCmd.commandkey 中。一般情况下不应修改这个字符,因为通常即使不同的操作系统也使用一样的快捷键(例如 CTRL+S 保存)或者类似的软件中同样的功能都会使用同样的快捷键(例如 CTRL+T 打开新的标签页)。除非该字符在对应的键盘布局中没有,我们才需对其进行修改。例如,意大利语中字母 [ 需要使用 ALT+è 组合键,因此这样的命令键就无法正常工作。

- -

在如上的代码片段中也为 打开文件定义了一个访问键,访问键用于使用键盘访问图形界面中的项目,例如:如果 文件 菜单定义了访问键 F,同时  打开文件… 菜单定义了访问键 O,那么你可以按 ALT+F 来访问文件菜单,然后按 O 键来打开一个文件。

- -

访问键以及命令键,在 .dtd 和 .properties 文件中通常使用单独的行进行定义,而且在键 ID 中通常会包含 .accesskey 字符串。

- -
变量
- -

变量不应该被翻译。变量通常以特殊字符开始(例如 $,#,% 等),并后面无空格紧跟着词。例如:$BrandShortName 和 %S。如有需要,你可以移动变量在字符串中的位置。

- -
品牌,版权以及商标
- -

品牌名称,以及版权声明和商标不应被翻译,或者使用非拉丁语字符替换。详情请查看 Mozilla 品牌指南

- -

翻译特定文化相关的引用

- -

有时候,Mozilla 产品或网站项目(例如 市场宣传)中可能会引用美国文化相关的一些概念。翻译这些内容的时候,最好是找到自己文化中等同的一些文化概念。例如,一个美国人可能会说“干的漂亮,本垒打!”,本垒打指的是垒球中的成功范例。对应较贴切的翻译就是要使用类似等同的比喻,以足球为例,就可以翻译为“干的漂亮,好球!”。

- -

法律相关内容

- -

Mozilla 项目也常包含一些法律内容,如最终用户许可,隐私政策等等。在进行这些内容的翻译时,要特别注意按 Mozilla 的文化以及价值观,确保翻译的精确,流畅,谨慎的进行审核。

- -

流畅

- -
 
- -
要做到流畅的翻译,翻译者不应仅根据语言对应的标准语法,标点和拼写规则,还需尽量避免出现二义性,不一致性,难以理解等问题。
- -
 
diff --git a/files/zh-cn/mozilla/localization/localizing_extension_descriptions/index.html b/files/zh-cn/mozilla/localization/localizing_extension_descriptions/index.html deleted file mode 100644 index 9b9bfcac8f..0000000000 --- a/files/zh-cn/mozilla/localization/localizing_extension_descriptions/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: 本地化 -slug: Mozilla/Localization/Localizing_extension_descriptions -tags: - - Localization -translation_of: Mozilla/Localization/Localizing_extension_descriptions ---- -

     

-
-

本地化 是指将软件的用户界面从一种语言翻译成另一种语言并且适应相应文化习惯的过程。 下面这些是关于基于 Mozilla 的 程序/扩展 本地化的资源。

-
- - - - - - - -
-

文摘

-
-
- 创建一个新的本地化
-
- 创建新的本地化的志愿者必读.
-
-
-
- XUL 教程:本地化
-
- 本地化 XUL 应用程序的XUL 教程部分.
-
-
-
- 编写本地化代码
-
- 给予编程者玩好本地化的最好的文章和指南.
-
-
-
- 本地化扩展描述
-
- 要本地化一个扩展的描述(在【扩展】窗口中显示在扩展名称下面的字符串),你需要使用特殊的首选项键去忽略在你的 install.rdf 文件中指定的描述. 这篇文章包含如何修改这个首选项键的说明.
-
-

查看全部...

-
-

其他页面

- -

相关文章

-
-
- Extensions, XUL
-
-

查看全部...

-
-

 

diff --git a/files/zh-cn/mozilla/mercurial/basics/index.html b/files/zh-cn/mozilla/mercurial/basics/index.html deleted file mode 100644 index 26c4d7cb03..0000000000 --- a/files/zh-cn/mozilla/mercurial/basics/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Mercurial basics -slug: Mozilla/Mercurial/Basics -translation_of: Mozilla/Mercurial/Basics ---- -

我要跟你啰嗦一些关于Mercurial的东西,它可以帮助您少入坑。本页言辞较喷且是以生存型为导向(什么是生存型请自行渡娘)。但我依然坚信Mercurial要比CVS强。——Jorendorff于2008年5月12日16:06(PDT)

- -

期望什么

- -

Mercurial is not CVS. The commands aren't the same. The concepts aren't the same. How is Mercurial different from CVS?

- -

This gun is loaded. You can shoot yourself in the foot. You can lose work. The tool tries to protect you, but it can happen anyway. The two common failure modes are: (a) you run a command without knowing what it's going to do; (b) you hg commit or hg qrefresh with a mistaken understanding of the state of your working directory. So you accidentally commit changes that you didn't want to commit; or you accidentally commit a broken merge; etc. Often it's not immediately obvious that anything is wrong.

- -

Forewarned is forearmed. Don't do these things. Don't run commands without knowing what they're going to do—hg help is your friend. Don't commit without diffing and thinking. And don't let yourself get into "play mode" and stop paying attention to the fact that what you're playing with is your own uncommitted work.

- -

Mercurial is not magic dust. Mercurial is flexible, powerful, and fun. It lets you attempt stuff you never would have tried in CVS. But of course not everything turns out to have been a good idea. (For example, we tried sharing patch queues. It sort of sucked.)

- -

避免入坑

- -

Use the latest stable release of Mercurial.

- -

Learn how to get your bearings. Use read-only commands (like hg status, hg head, hg parents, hg log, hg diff, hg outgoing) to check the status of your repository. This is a key skill.

- -

Configure a merge program and make sure you know how to use it. DO IT NOW. Otherwise you will likely screw up your repository at some point.

- -

Mercurial doesn't leave conflict markers in your files; instead, it wants you to fix the conflicts immediately, using a merge program (like kdiff3) which it can launch for you.

- -

This can be error-prone. By default, Mercurial uses the first merge program it finds on your system, and merge programs can have a learning curve. Mercurial does not do a good job of detecting busted merges and refusing to proceed, so just by closing a window you can unwittingly put yourself in a bad state. Bad merges may lead to seemingly inexplicable Mercurial behavior in the future.

- -

If a merge fails, make sure Mercurial knows that it has failed. When you're first learning the ropes, merges often go wrong. You might see this message:

- -
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-There are unresolved merges, you can redo the full merge using:
-  hg update -C 2
-  hg merge 1
-
- -

This means some conflicts weren't resolved during the merge. If you don't know exactly what they are and how to fix them, use that hg update -C command to tell Mercurial that you've given up on that merge.

- -

If you don't, Mercurial won't know, and the next time you commit, it'll make a merge changeset. This is bad. The result can look a lot like accidentally destroying a bunch of work, actually, but the damage can be undone.

- -

If hg parents shows two parents, you're merging.

- -

If you use Mercurial Queues, back up your work. hg qrefresh destructively replaces the old patch with the new one! Use hg qinit -c to create a separate backup repository for your patches and hg commit --mq -m backup regularly.

- -

Don't use Mercurial Queues in a repository that someone might pull from since applied (non-public) patches would also be pulled.

- -

Recovering

- -

握了个草! Mercurial 这么宝——Mercurial剁你手!

- -

千万别轻易试玩(亵玩)Mercurial哦. 想想你的手,想想你的臂膀,别呀,你还可有个完整.

- -

寻求帮助IRC频道. 在 Mozilla IRC 或 #mercurial on freenode 中输入 #hg 或者 #developers .

- -

 

diff --git a/files/zh-cn/mozilla/mercurial/index.html b/files/zh-cn/mozilla/mercurial/index.html deleted file mode 100644 index 64029a1d1e..0000000000 --- a/files/zh-cn/mozilla/mercurial/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Mercurial -slug: Mozilla/Mercurial -tags: - - Developing Mozilla - - Mercurial - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Mercurial ---- -

 

- -
-

Please refer to Mercurial For Mozillians at ReadTheDocs for current best-practices around Mercurial, including many helpful extra tools and guidelines that make using Mercurial fast and easy.

-
- -

Mercurial (also known as "hg"), is the distributed version control software used for the development of Firefox, Thunderbird, and the shared Gecko core. It replaced CVS after Mozilla 1.9 was branched.

- -

hg is the Mercurial command-line tool, Hg being the chemical symbol for the element mercury.

- -

Installation, configuration, and getting the source

- -

See Installing Mercurial for installation and configuration tips.

- -

See Getting Mozilla Source Code Using Mercurial for getting a tree to build.

- -

Learning to use Mercurial

- -

If you are new to Mercurial, you should start with the official guide.

- -

Then, move on to Mercurial basics and Mercurial FAQ and the version control tool docs for Mozilla-centric Mercurial information.

- -

Further reading

- -

The Mercurial tag lists the Mercurial-related articles on MDN.

- -

And on wiki.mozilla.org, these helpful pages:

- - diff --git a/files/zh-cn/mozilla/mercurial/installing_mercurial/index.html b/files/zh-cn/mozilla/mercurial/installing_mercurial/index.html deleted file mode 100644 index 1ea2cc22e3..0000000000 --- a/files/zh-cn/mozilla/mercurial/installing_mercurial/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: Installing Mercurial -slug: Mozilla/Mercurial/Installing_Mercurial -translation_of: Mozilla/Mercurial/Installing_Mercurial ---- -

{{ Note('If you have not yet read the Mercurial basics do so now, or see Mercurial for other resources.') }}

- -
-

Please refer to Mercurial For Mozillians at ReadTheDocs for current best-practices around Mercurial, including many helpful extra tools and guidelines that make using Mercurial fast and easy.

-
- -

安装

- -

See Installing Mercurial from the Mozilla Version Control Guide.

- -

基本设置

- -

You should configure Mercurial before submitting patches to Mozilla.

- -

If you will be pulling the Firefox source code or one of the derived repositories, the easiest way to configure Mercurial is to run the mercurial-setup mach command:

- -
./mach mercurial-setup
- -

This command starts an interactive wizard that will help ensure your Mercurial is configured with the latest recommended settings. This command will not change any files on your machine without your consent.

- -

If you don't have the Firefox source code available, you should edit your Mercurial configuration file to look like the following:

- -
[ui]
-username = Your Real Name <user@example.com>
-merge = your-merge-program (or internal:merge)
-
-[diff]
-git = 1
-showfunc = 1
-unified = 8
-
-[defaults]
-commit = -v
-
- -

On Windows, these settings can be added to $HOME\.hgrc or $HOME\Mercurial.ini, or, if you'd like global settings, C:\mozilla-build\hg\Mercurial.ini or C:\Program Files\Mercurial\Mercurial.ini. On UNIX-like systems, they should be in your $HOME/.hgrc file.

- -

You can configure the editor to use for commit messages using the editor option in the [ui] section or by setting the EDITOR environment variable.

- -

If you are trying to access the repository through a proxy server, see these instructions.

- -

其他设置

- -

Merge 合并程序

- -

After installing, choose a merge program. Seriously. Do it now. If you don't, Mercurial will choose one for you and spring it on you when you least expect it.

- -

A reasonable thing to do is to set ui.merge=internal:merge in the Mercurial configuration file (see below), which makes Mercurial try to merge changes and add the conflict markers (a la CVS) to the files that couldn't be merged.

- -

Under Ubuntu, you can install meld package, then in in the Mercurial configuration file (see below) set ui.merge=meld

- -

You can see the list of merge conflicts by looking for "merging ... failed!" in the update output.

- -

配置 kdiff3 作为合并工具

- -

If you're on Linux and you have kdiff3 installed, you probably want to configure kdiff3 as a merge tool.  (It's better than meld because it will actually resolve a bunch of the conflicts without prompting you, generally quite accurately.)  You can do this by adding the following lines (which come from contrib/mergetools.hgrc in the Mercurial distribution):

- -
[merge-tools]
-kdiff3.args=--auto -L1 base --L2 local --L3 other $base $local $other -o $output
-kdiff3.regkey=Software\KDiff3
-kdiff3.regappend=\kdiff3.exe
-kdiff3.fixeol=True
-kdiff3.gui=True
-
-
- -

Extensions

- -

There's a number of extensions you can enable. See http://mercurial.selenic.com/wiki/UsingExtensions. Almost everyone should probably enable the following:

- - - -

These can all be turned on by just adding this to your .hgrc file:

- -
[extensions]
-color =
-rebase =
-histedit =
-progress =
-transplant =
-pager =
-
- -

In addition, there are some 3rd party extensions that are incredibly useful for basic development:

- -
-
mozext
-
Mozilla-specific functionality to aid in developing Firefox/Gecko.
-
trychooser
-
Automatically creates a try commit message and then pushes changes to Mozilla's Try infrastructure. Just run: -
hg trychooser
-
-
qimportbz
-
Import patches from Bugzilla. Creates a filename and commit message for you based on the bug's metadata. -
hg qimport bz://1234567
-  
-
-
bzexport
-
Export patches to Bugzilla. There are quite a few optional arguments here to create new or update existing bugs with the attment, as well as auto matically request reviews. Type hg help bzexport for a full list but the basic syntax is: -
hg bzexport -i 1234567
-
-
- -

Installing these is fairly easy. You'll just need to find a place on your system to store the extensions, and clone the extension repos into it:

- -
hg clone https://bitbucket.org/edgimar/crecord
-hg clone https://bitbucket.org/sfink/mqext
-hg clone https://hg.mozilla.org/users/robarnold_cmu.edu/qimportbz
-git clone https://github.com/pbiggar/trychooser
-
- -

And then add then to your .hgrc file

- -
[extensions]
-qcrecord =  /path/to/crecord/crecord
-mqext =  path/to/mqext
-qimportbz =  path/to/qimportbz
-trychooser = path/to/trychooser/trychooser
-
- -

Configuring the try repository

- -

If you have access to the try server you may want to configure Mercurial so you can refer to it simply as "try", since it can be useful from all your trees.  This can be done by adding this to your ~/.hgrc (or Mercurial.ini):

- -

 

- -
[paths]
-try = ssh://hg.mozilla.org/try/
-
- -

You can also configure short names like this that are specific to a particular repository by adding a [paths] section to the .hg/hgrc file within a repository.  There are two magic names, "default" and "default-push", which are used as the default push/pull targets.  (If "default" is specified and "default-push" is not, "default" is used for both.)

- -

Alternatively, you can install the trychooser extension (older version).

diff --git a/files/zh-cn/mozilla/mfbt/index.html b/files/zh-cn/mozilla/mfbt/index.html deleted file mode 100644 index a8b644e23f..0000000000 --- a/files/zh-cn/mozilla/mfbt/index.html +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: Mozilla Framework Based on Templates (MFBT) -slug: Mozilla/MFBT -translation_of: Mozilla/MFBT ---- -

The Mozilla Framework Based on Templates ("mfbt") is the central repository for macros, functions, and data structures used throughout Mozilla code, including in the JavaScript engine. Its code resides in the {{ Source("mfbt/") }} source directory, but headers within it should be included using paths like "mozilla/StandardInteger.h". It is fairly new, so its functionality is currently sparse. Feel free to file bugs to add new functionality to it, or to move existing functionality into it, as needed. 

- -

mfbt code goes to some length to document all its interfaces in comments, including examples when possible. It also attempts to define its functionality in well-named files, such that simply skimming the contents of {{ Source("mfbt/") }} will quickly suggest the relevant header to examine. Therefore this document primarily attempts to direct readers to the correct file to read those comments. Feel free to file a documentation bug if you think this approach could be improved, and feel free to make improvements to this document if you see them.

- -

Functionality

- -

Types and type manipulation

- -

{{ Source("mfbt/StandardInteger.h", "StandardInteger.h") }} implements the <stdint.h> interface. (The <stdint.h> standard header is not available on all platforms and so cannot be used directly. This header also provides a useful "hook" for embeddings that must customize the types underlying the fixed-size integer types.)

- -

{{ Source("mfbt/Types.h", "Types.h") }} includes StandardInteger.h and further provides size_t.

- -

{{ Source("mfbt/CheckedInt.h", "CheckedInt.h") }} implements checked integers. They behave like integers, but safely check for integer overflow and divide-by-zero. Useful for input validation.

- -

{{ Source("mfbt/FloatingPoint.h", "FloatingPoint.h") }} provides various operations for examining and working upon double-precision floating point values, and for producing various special floating point values.

- -

Core

- -

{{ Source("mfbt/Types.h", "Types.h") }} further provides macros to define imported and exported C symbols.

- -

{{ Source("mfbt/Attributes.h", "Attributes.h") }} implements various function and class attribute macros. The function macros control inlining, note whether a function returns, and enforce various C++-related restrictions on inheritance and use. The class macros permit controlling the inheritability of a class.

- -

{{ Source("mfbt/Likely.h", "Likely.h") }} provides MOZ_LIKELY and MOZ_UNLIKELY macros to annotate conditions with their expected truthiness.

- -

{{ Source("mfbt/Util.h", "Util.h") }} implements various other bits of useful functionality. (This header will likely be further split up so that its functionality is less grab-bag.)

- -

Debugging

- -

{{ Source("mfbt/Assertions.h", "Assertions.h") }} provides assertion macros in implementing runtime assertions and compile-time assertions.

- -

{{ Source("mfbt/GuardObjects.h", "GuardObjects.h") }} provides macros which can be used to annotate an RAII-style guard class, so that any attempt to create an unnamed temporary for it will assert. (An unnamed temporary lives for a shorter period of time than the scope where it's found, so it usually isn't what was desired.)

- -

Data structures

- -

{{ Source("mfbt/LinkedList.h", "LinkedList.h") }} implements a type-safe doubly-linked list class. Most new code should use this rather than {{ Source("nsprpub/pr/include/prclist.h", "PRCList") }}.

- -

{{ Source("mfbt/RangedPtr.h", "RangedPtr.h") }} implements RangedPtr, a smart pointer template whose value may be manipulated only within a range specified at construction time, and which may be dereferenced only at valid locations in that range.  This pointer is a useful way to expose access to values within an array.

- -

{{ Source("mfbt/RefPtr.h", "RefPtr.h") }} implements various smart pointer templates to simplify reference counting of values of particular classes.

- -

{{ Source("mfbt/Scoped.h", "Scoped.h") }} implements scope-based resource management, to simplify the task of cleaning up resources when leaving a scope.

- -

{{ Source("mfbt/ThreadLocal.h", "ThreadLocal.h") }} implements thread-local storage, aka "TLS", also called thread-specific storage. It should be used only for static-storage-duration variables, such as global variables or static class members.

diff --git a/files/zh-cn/mozilla/mozilla_on_github/index.html b/files/zh-cn/mozilla/mozilla_on_github/index.html deleted file mode 100644 index a215aef188..0000000000 --- a/files/zh-cn/mozilla/mozilla_on_github/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: GitHub上的Mozilla项目 -slug: Mozilla/Mozilla_on_GitHub -translation_of: Mozilla/Mozilla_on_GitHub ---- -

Although Mozilla's major, core projects are located on the Mozilla Mercurial server, such as mozilla-central, there are a number of tools, services, and so forth whose code is hosted on GitHub. This article offers a quick guide to getting started with Mozilla code on GitHub as well as a list of many of the most interesting GitHub repositories containing Mozilla project code.

- -

起步

- -

You can look at code on GitHub without an account; that's the first thing you should know. To do more—that is, to contribute to the code or to fork it and start your own project based on Mozilla-related code—you'll need a GitHub account. You can learn more about setting up an account on the GitHub site.

- -

Most Mozilla project code is located in repositories owned by the user Mozilla. That's a great place to start looking for any projects not listed below.

- -

项目

- -

This list covers the larger-scale and more important projects we have hosted on GitHub. It's not an authoritative, complete list, since it's hard to keep track of all the smaller projects that crop up (and even, at times, the large ones!). You can see a complete list of Mozilla projects on GitHub.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Project nameDescription
PDF.jsA Portable Document Format (PDF) reader written entirely in JavaScript.
ShumwayShumway is a Flash VM and runtime written in JavaScript.
addon-sdkThe Mozilla Add-on SDK.
asknotThe What Can I Do For Mozilla web site, which helps you figure out how you can contribute to Mozilla.
bugsahoyA Web page to help new Mozilla contributors find bugs to work on.
bugzilla-dashboardA convenient dashboard to help you get an overview of your bugs.
codefirefoxThe CodeFirefox site, with videos and tutorials about how to contribute to the Firefox project and Mozilla code in general.
dxrAn intelligent tool for browsing source code.
emscriptenThe Emscripten LLVM-to-JavaScript compiler.
fxdt-adaptersThe Firefox Developer Tools Adapter lets you debug various remote targets from the Firefox Developer Tools.
gecko-devA read-only mirror of the Mercurial repositories used for Mozilla private code.
kitsuneKitsune is the platform that drives the Mozilla support web site, SUMO.
kumaThe Django project that powers this site (MDN).
mdnCode samples for the MDN Web site.
mozbrickThe Mozilla Brick project.
mozilla-B2GThe Firefox OS project.
mozilla-appmakerThe Appmaker project -- a Web tool to let non-programmers create apps.
mozilla-l10nScripts and tools used by the localization drivers.
mozilla-metricsTools used to collect metrics about Mozilla code.
mozilla-servicesMozilla cloud services projects.
opennewsThe Knight-Mozilla Open News project, helping the journalism/technology community do great work through shared knowledge and code.
rust-langRust编程语言, 为安全地进行高并发编码而设计!
servoThe next-generation rendering engine.
- -

 

diff --git a/files/zh-cn/mozilla/participating_in_the_mozilla_project/index.html b/files/zh-cn/mozilla/participating_in_the_mozilla_project/index.html deleted file mode 100644 index 1de9ed81ad..0000000000 --- a/files/zh-cn/mozilla/participating_in_the_mozilla_project/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: 加入Mozilla项目 -slug: Mozilla/Participating_in_the_Mozilla_project -translation_of: Mozilla/Participating_in_the_Mozilla_project ---- -

如果你有兴趣帮助解决bug或者参与Mozilla平台的代码工作,这里是找到为你指出正确方向的文档的地方。

- - - - - - - -
-

通用话题

-
-
- Mozilla开发者手册
-
- 为Mozilla代码库做贡献的开发向导和提示。
-
- Mozilla源代码
-
- 通过下载或者版本控制来获取Mozilla代码的方法,以及怎样将你的代码加入到代码树中。
-
- 编译
-
- 编译Mozilla项目(包括Firefox和Thunderbird)。
-
- Mozilla平台
-
- 关于Mozilla平台的信息,包括所有的API接口和所包含的技术,以及如何在你的自己的项目中使用它们。
-
- Mozilla文档
-
- 帮助我们创建和改进Mozilla及开放互联网的文档。
-
- 调试
-
- 调试Mozilla代码时有用的提示和参考。
-
- 质量保证
-
- 关于测试及bug跟踪的相关信息。
-
- 本地化
-
- 关于翻译Mozilla项目及其文档等到各种语言。
-
-

项目主页

-
-
- Thunderbird
-
- Mozilla的邮件客户端。
-
- Sunbird
-
- Mozilla的日历项目。
-
-
-

工具

-
-
- Bugzilla
-
- Bugzilla数据库用来跟踪Mozilla项目的相关事件。
-
- MXR
-
- 基于Web浏览及搜索Mozilla源代码库。
-
- Bonsai
-
- Bonsai工具帮助你找到谁在何时对代码库进行了什么修改。
-
- Tinderbox
-
- Tinderbox显示树的状态(无论当前是否编译成功)。 在check-in和check-out之前都要进行检查以确认你正工作在一个working tree上。
-
- 崩溃跟踪
-
- SocorroTalkback提供崩溃跟踪服务。
-
- 性能跟踪
-
- Mozilla项目的性能跟踪。
-
- 开发者论坛
-
- 一个有针对性主题的论坛。在这里你可以讨论开发的各种事件。
-
-
-

  {{ languages( { "en": "en/Participating_in_the_Mozilla_project", "ja": "ja/Participating_in_the_Mozilla_project"} ) }}

diff --git a/files/zh-cn/mozilla/performance/about_colon_memory/index.html b/files/zh-cn/mozilla/performance/about_colon_memory/index.html deleted file mode 100644 index 6710a2441b..0000000000 --- a/files/zh-cn/mozilla/performance/about_colon_memory/index.html +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: 'about:memory' -slug: 'Mozilla/Performance/about:memory' -translation_of: 'Mozilla/Performance/about:memory' ---- -

about:memory 是一个 Firefox 内置的特殊页面,你可以在此查看、保存、载入和比较 Firefox 内存使用的详细测量数据。你还可以执行其他与内存有关的操作,例如执行 GC 和 CC、转储 GC 和 CC 日志记录,以及转储 DMD 报告。这个页面在所有版本当中都可以找到,并且无需任何准备工作就可以使用。

-

如何生成内存报告

-

假设你要测量 Firefox 的内存使用情况(也许你是想自己研究,或者是他人要你用 about:memory 生成“内存报告”以便帮你分析问题),你都可以按照下列步骤进行操作。

- -

请注意,上述方式生成的数据会包含一些与隐私有关的内容,例如你此时所打开网页的完整清单。如果你不想分享这些信息,可以在点击 "Measure and save..." 或 "Measure..." 按钮之前先勾上 “anonymize” 复选框。这样就会去除所有隐私相关的数据,虽然这有可能不太便于他人帮你分析内存占用情况。

-

从文件载入内存报告

-

从文件载入内存报告最简单的方式是点击 "Load..." 按钮,你也可以点击 "Load and diff..." 按钮来找出两个内存报告文件间的不同之处。

-

单个内存报告文件也可以直接被自动载入,只需在 about:memory 后面加上一个文件查询字符串,例如:

-
about:memory?file=/home/username/reports.json.gz
-
-

这种方式在载入 Firefox OS 设备上已转储的内存报告文件时尤为实用。

-

内存报告所保存的文件使用的是用 gzip 压缩的 JSON 格式。这些文件既可以直接载入,也可以解压后再载入。

-

分析内存报告

-

你在 about:memory 页面中看到的几乎所有事物都有着相应的工具提示来解释。将鼠标悬停在任意按钮上就可以看到关于其作用的描述。将鼠标悬停在任意测量数据上就可以查看对它所指内容的描述。

-

测量数据基础介绍

-

大多数测量数据的单位都是字节,少部分使用的是计数值或百分比。

-

测量数据大多以树形结构呈现,例如:

-
 585 (100.0%) -- preference-service
- └──585 (100.0%) -- referent
-    ├──493 (84.27%) ── strong
-    └───92 (15.73%) -- weak
-        ├──92 (15.73%) ── alive
-        └───0 (00.00%) ── dead
-
-

叶节点代表实际的测量数据值,每个内部节点的值都是它子节点值的总和。

-

使用树形结构是为了让测量数据可以根据需要进一步分成类、子类、子类的子类……,直至任意深度。单个树形下的所有测量数据都不会有任何重叠。

-

树的路径可以使用 '/' 来分隔,例如,preference/referent/weak/dead 表示上述例子中直到最终叶节点的整个路径。

-

单击每个子树都可以收起或展开它们。如果你发现某些树所占空间特别大,可以试试先收起所有隶属于它的子树,然后根据需要逐步展开。

-

区段

-

内存报告是在每个进程的基础上显示,每个区段为一个进程。每个进程中的测量数据都包含以下一些子区段。

-

Explicit Allocations

-

这个区段包含单个叫做 "explicit" 的树,它测量的是通过显式调用堆积分配(heap allocations)函数和非堆积分配函数方式分配的所有内存,堆积分配函数像是 malloc 和 new,而非堆积分配函数可以是 mmap 和 VirtualAlloc。

-

下面的例子是一个打开了 cnn.com、techcrunch.com 和 arstechnica.com 这几个标签页的浏览器会话。为了更好地呈现,我们将部分子树展开,其他部分全部收起。

-
191.89 MB (100.0%) -- explicit
-├───63.15 MB (32.91%) -- window-objects
-│   ├──24.57 MB (12.80%) -- top(http://edition.cnn.com/, id=8)
-│   │  ├──20.18 MB (10.52%) -- active
-│   │  │  ├──10.57 MB (05.51%) -- window(http://edition.cnn.com/)
-│   │  │  │  ├───4.55 MB (02.37%) ++ js-compartment(http://edition.cnn.com/)
-│   │  │  │  ├───2.60 MB (01.36%) ++ layout
-│   │  │  │  ├───1.94 MB (01.01%) ── style-sheets
-│   │  │  │  └───1.48 MB (00.77%) -- (2 tiny)
-│   │  │  │      ├──1.43 MB (00.75%) ++ dom
-│   │  │  │      └──0.05 MB (00.02%) ── property-tables
-│   │  │  └───9.61 MB (05.01%) ++ (18 tiny)
-│   │  └───4.39 MB (02.29%) -- js-zone(0x7f69425b5800)
-│   ├──15.75 MB (08.21%) ++ top(http://techcrunch.com/, id=20)
-│   ├──12.85 MB (06.69%) ++ top(http://arstechnica.com/, id=14)
-│   ├───6.40 MB (03.33%) ++ top(chrome://browser/content/browser.xul, id=3)
-│   └───3.59 MB (01.87%) ++ (4 tiny)
-├───45.74 MB (23.84%) ++ js-non-window
-├───33.73 MB (17.58%) ── heap-unclassified
-├───22.51 MB (11.73%) ++ heap-overhead
-├────6.62 MB (03.45%) ++ images
-├────5.82 MB (03.03%) ++ workers/workers(chrome)
-├────5.36 MB (02.80%) ++ (16 tiny)
-├────4.07 MB (02.12%) ++ storage
-├────2.74 MB (01.43%) ++ startup-cache
-└────2.16 MB (01.12%) ++ xpconnect
-

要弄懂这里的所有细节需要一些专业知识才行,不过还是有几点内容需要指出。

- -

部分附加组件的内存占用也会被识别出来,如下例所示。

-
├───40,214,384 B (04.17%) -- add-ons
-│   ├──21,184,320 B (02.20%) ++ {d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}/js-non-window/zones/zone(0x100496800)/compartment([System Principal], jar:file:///Users/njn/Library/Application%20Support/Firefox/Profiles/puna0zr8.new/extensions/%7Bd10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d%7D.xpi!/bootstrap.js (from: resource://gre/modules/addons/XPIProvider.jsm:4307))
-│   ├──11,583,312 B (01.20%) ++ jid1-xUfzOsOFlzSOXg@jetpack/js-non-window/zones/zone(0x100496800)
-│   ├───5,574,608 B (00.58%) -- {59c81df5-4b7a-477b-912d-4e0fdf64e5f2}
-│   │   ├──5,529,280 B (00.57%) -- window-objects
-│   │   │  ├──4,175,584 B (00.43%) ++ top(chrome://chatzilla/content/chatzilla.xul, id=4293)
-│   │   │  └──1,353,696 B (00.14%) ++ top(chrome://chatzilla/content/output-window.html, id=4298)
-│   │   └─────45,328 B (00.00%) ++ js-non-window/zones/zone(0x100496800)/compartment([System Principal], file:///Users/njn/Library/Application%20Support/Firefox/Profiles/puna0zr8.new/extensions/%7B59c81df5-4b7a-477b-912d-4e0fdf64e5f2%7D/components/chatzilla-service.js)
-│   └───1,872,144 B (00.19%) ++ treestyletab@piro.sakura.ne.jp/js-non-window/zones/zone(0x100496800)
-

此外还有一些内容需要指出:

- -

Other Measurements

-

这个区段包含多个树,包括与 "explicit" 树中测量数据相交叉(cross-cut)的树。比如说,在 "explicit" 这个树中所有 DOM 和 layout 测量数据会被分解到每个窗口当中,而在 "Other Measurements" 区段中,这些测量数据又会被汇总成整个浏览器,如下例所示。

-
26.77 MB (100.0%) -- window-objects
-├──14.59 MB (54.52%) -- layout
-│  ├───6.22 MB (23.24%) ── style-sets
-│  ├───4.00 MB (14.95%) ── pres-shell
-│  ├───1.79 MB (06.68%) ── frames
-│  ├───0.89 MB (03.33%) ── style-contexts
-│  ├───0.62 MB (02.33%) ── rule-nodes
-│  ├───0.56 MB (02.10%) ── pres-contexts
-│  ├───0.47 MB (01.75%) ── line-boxes
-│  └───0.04 MB (00.14%) ── text-runs
-├───6.53 MB (24.39%) ── style-sheets
-├───5.59 MB (20.89%) -- dom
-│   ├──3.39 MB (12.66%) ── element-nodes
-│   ├──1.56 MB (05.84%) ── text-nodes
-│   ├──0.54 MB (02.03%) ── other
-│   └──0.10 MB (00.36%) ++ (4 tiny)
-└───0.06 MB (00.21%) ── property-tables
-

但是这个区段部分树的测量数据又不会与 "explicit" 树的相交叉,比如上面提到的 "preference-service" 这个例子当中的树。

-

最后,在这个区段结尾处是其他单独的测量数据,如下例所示。

-
    0.00 MB ── canvas-2d-pixels
-    5.38 MB ── gfx-surface-xlib
-    0.00 MB ── gfx-textures
-    0.00 MB ── gfx-tiles-waste
-          0 ── ghost-windows
-  109.22 MB ── heap-allocated
-        164 ── heap-chunks
-    1.00 MB ── heap-chunksize
-  114.51 MB ── heap-committed
-  164.00 MB ── heap-mapped
-      4.84% ── heap-overhead-ratio
-          1 ── host-object-urls
-    0.00 MB ── imagelib-surface-cache
-    5.27 MB ── js-main-runtime-temporary-peak
-          0 ── page-faults-hard
-    203,349 ── page-faults-soft
-  274.99 MB ── resident
-  251.47 MB ── resident-unique
-1,103.64 MB ── vsize
-

这里有一些值得注意的测量数据:

- -

System

-

这个区段只会在 Firefox OS 当中出现,它包含取自操作系统的对整个设备测量的数据。除此以外,该区段还有助于详细了解整个设备的内存是如何被使用的。

diff --git a/files/zh-cn/mozilla/performance/index.html b/files/zh-cn/mozilla/performance/index.html deleted file mode 100644 index dac76d9a75..0000000000 --- a/files/zh-cn/mozilla/performance/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Performance -slug: Mozilla/Performance -tags: - - NeedsTranslation - - Performance - - TopicStub -translation_of: Mozilla/Performance ---- -

The articles linked to from here will help you improve performance, whether you're developing core Mozilla code or an add-on.

- - - - - - - -
-

Documentation

-
-
- Reporting a Performance Problem
-
- A user friendly guide to reporting a performance problem. A development environment is not required.
-
- Performance best practices in extensions
-
- A performance "best practices" guide for extension developers.
-
- Measuring Add-on Startup Performance
-
- A guide for add-on developers on how to set up a performance testing environment.
-
- XUL School: Add-on Performance
-
- Tips for add-on developers to help them avoid impairing application performance.
-
- GPU performance
-
- Tips for profiling and improving performance when using a GPU.
-
-

View all pages tagged with "Performance"...

-

Memory profiling and leak detection tools

-
-
- about:memory
-
- about:memory is the easiest-to-use tool for measuring memory usage in Mozilla code, and is the best place to start. It also lets you do other memory-related operations like trigger GC and CC, dump GC & CC logs, and dump DMD reports. about:memory is built on top of Firefox's memory reporting infrastructure.
-
- DMD
-
- DMD is a tool that identifies shortcomings in about:memory's measurements, and can also do multiple kinds of general heap profiling.
-
- areweslimyet.com
-
- areweslimyet.com (a.k.a. AWSY) is a memory usage and regression tracker.
-
- BloatView
-
- BloatView prints per-class statistics on allocations and refcounts, and provides gross numbers on the amount of memory being leaked broken down by class. It is used as part of Mozilla's continuous integration testing.
-
- Refcount tracing and balancing
-
- Refcount tracing and balancing are ways to track down leaks caused by incorrect uses of reference counting. They are slow and not particular easy to use, and thus most suitable for use by expert developers.
-
- GC and CC logs
-
- GC and CC logs can be generated and analyzed to in various ways. In particular, they can help you understand why a particular object is being kept alive.
-
- Valgrind
-
- Valgrind is a tool that detects various memory-related problems at runtime, including leaks. Valgrind is used as part of Mozilla's continuous integration testing, though the coverage is limited because Valgrind is slow.
-
- LeakSanitizer
-
- LeakSanitizer (a.k.a. LSAN) is similar to Valgrind, but it runs faster because it uses static source code instrumentation. LSAN is part of Mozilla's continuous integration testing, with most tests running through it as part of the AddressSanitizer (a.k.a. ASAN) test jobs.
-
- Apple tools
-
- Apple provides some tools for Mac OS X that report similar problems to those reported by LSAN and Valgrind. The "leaks" tool is not recommended for use with SpiderMonkey or Firefox, because it gets confused by tagged pointers and thinks objects have leaked when they have not (see bug 390944).
-
- TraceMalloc
-
- TraceMalloc is a tool that does various kinds of heap profiling.
-
- Leak Gauge
-
- Leak Gauge is a tool that can be used to detect certain kinds of leaks in Gecko, including those involving documents, window objects, and docshells.
-
- LogAlloc
-
- LogAlloc is a tool that dumps a log of memory allocations in Gecko. That log can then be replayed against Firefox's default memory allocator independently or through another replace-malloc library, allowing the testing of other allocators under the exact same workload.
-
-

See also the documentation on Leak-hunting strategies and tips.

-
-

Profiling and performance tools

-
-
- Profiling with the Built-in Profiler {{ gecko_minversion_inline("16.0") }}
-
- The built-in profiler is a good tool to start with.
-
- Profiling with Instruments
-
- How to use Apple's Instruments tool to profile Mozilla code.
-
- Profiling with Xperf
-
- How to use Microsoft's Xperf tool to profile Mozilla code.
-
- Profiling with Zoom
-
- Zoom is a profiler for Linux done by the people who made Shark
-
- Measuring performance using the PerfMeasurement.jsm code module {{ gecko_minversion_inline("2.0") }}
-
- Using PerfMeasurement.jsm to measure performance data in your JavaScript code.
-
- Adding a new Telemetry probe
-
- Information on how to add a new measurement to the Telemetry performance-reporting system
-
- Profiling JavaScript with Shark {{ gecko_minversion_inline("1.9") }}
-
- How to use the Mac OS X Shark profiler to profile JavaScript code in Firefox 3.5 or later.
-
- Profiling with Shark
-
- How to use Apple's Shark tool to profile Mozilla code.
-
-
- -
-
- JavaScript, XPCOM, Developing Mozilla, Extensions, Addons
-
-
-

 

diff --git a/files/zh-cn/mozilla/performance/scroll-linked_effects/index.html b/files/zh-cn/mozilla/performance/scroll-linked_effects/index.html deleted file mode 100644 index 5d3c1a7bf0..0000000000 --- a/files/zh-cn/mozilla/performance/scroll-linked_effects/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Scroll-linked effects -slug: Mozilla/Performance/Scroll-linked_effects -tags: - - CSS - - JavaScript - - Web动画 - - 性能 - - 滚动 -translation_of: Mozilla/Performance/Scroll-linked_effects ---- -

scroll-linked 效果指的是某种因滚动条位置变化的而产生的效果,例如,为了产生视差滚动效果而更新 position 属性。 本文讨论 scroll-linked 效果、这些效果对性能的影响、相关工具以及可以缓解问题的技术。

- -

滚动效果解释

- -

滚动效果一般是指通过监听 {{event("scroll")}} 事件,并以某种方式修改页面上的元素(通常是 CSS 的 {{cssxref("position")}} 或 {{cssxref("transform")}} 属性)你可以在 CSS Scroll API: Use Cases 找到这样的效果。

- -

当滚动在浏览器主线程上完成时,这些效果运行良好。但是,大多数浏览器现在支持一种异步滚动,以便为用户提供恒定每秒60帧的体验。在异步滚动模型中,视觉滚动位置(译者注:即用户看到的滚动位置)在合成器线程中更新,并在 DOM 更新 {{event("scroll")}} 事件、主线程触发 {{event("scroll")}} 事件之前对用户可见。这意味着实际显示的效果将会落后于用户看到的滚动位置一点点。 这可能会导致效果变得迟缓,总之,我们想要避免这种情况。

- -

下面是一些在异步滚动中不能良好运行的例子,以及可以很好地运行的等效版本:

- -
- -
- -

示例1:粘性定位

- -

这是一个粘性定位效果的实现,其中“toolbar”的 div 将在您向下滚动时“粘”在屏幕顶部

- -
- -
<body style="height: 5000px" onscroll="document.getElementById('toolbar').style.top = Math.max(100, window.scrollY) + 'px'">
- <div id="toolbar" style="position: absolute; top: 100px; width: 100px; height: 20px; background-color: green"></div>
-</body>
- -

这种粘性定位的实现依赖于监听滚动事件,来重新定位toolbar”的 div。由于滚动事件监听器运行于浏览器主线程的 JavaScript 中,它与用户可见的滚动是异步的。所以,因为有异步滚动,事件处理程序将相对于用户可见的滚动来说是有延迟的,这个 div 不会像预期那样保持视觉上的固定。相反,它将随用户的滚动移动,然后在滚动事件处理器运行时突然回到应有的位置。这种恒定的移动和捕捉将会导致视觉效果的抖动。其中一种解决方法是使用为此设计的 CSS 属性,而不是用滚动事件监听器:

- -
- -
<body style="height: 5000px">
- <div id="toolbar" style="position: sticky; top: 0px; margin-top: 100px; width: 100px; height: 20px; background-color: green"></div>
-</body>
- -

此版本适用于异步滚动,当用户滚动时,浏览器会更新“toolbar”的 div 的位置。

- -

示例2:滚动捕捉

- -

此特性已从 Web 标准中删除。 虽然一些浏览器可能仍然支持它,但它正在被放弃。尽量不要使用它,并尽可能更新现有代码。https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-coordinate#Browser_compatibility

- -
- -

以下是滚动捕捉的实现,当用户的滚动停止在 snaptarget 附近时,滚动位置捕捉到特定目的地(snaptarget)。

- -
- -
<body style="height: 5000px">
- <script>
-    function snap(destination) {
-        if (Math.abs(destination - window.scrollY) < 3) {
-            scrollTo(window.scrollX, destination);
-        } else if (Math.abs(destination - window.scrollY) < 200) {
-            scrollTo(window.scrollX, window.scrollY + ((destination - window.scrollY) / 2));
-            setTimeout(snap, 20, destination);
-        }
-    }
-    var timeoutId = null;
-    addEventListener("scroll", function() {
-        if (timeoutId) clearTimeout(timeoutId);
-        timeoutId = setTimeout(snap, 200, parseInt(document.getElementById('snaptarget').style.top));
-    }, true);
- </script>
- <div id="snaptarget" style="position: relative; top: 200px; width: 100%; height: 200px; background-color: green"></div>
-</body>
- -

在该示例中,有滚动事件监听器,其检测滚动位置是否在“snaptarget”的 div 顶部的 200 像素内。 如果是,则触发动画,将 div 的顶部“卡”到滚动位置。 由于此动画由浏览器主线程上的 JavaScript 驱动,所以可以被其他选项卡或其他窗口中运行的 JavaScript 中断。 因此,动画可能最终看起来很漂亮,但并不像预期那样平滑。 相反,使用 CSS 的 snap-points 属性将允许浏览器异步运行动画,为用户提供平滑的视觉效果。

- -
- -
<body style="height: 5000px">
- <style>
-    body {
-        scroll-snap-type: proximity;
-        scroll-snap-destination: 0 0;
-    }
-    #snaptarget {
-        scroll-snap-coordinate: 0 -8px;
-    }
- </style>
- <div id="snaptarget" style="position: relative; top: 200px; width: 100%; height: 200px; background-color: green"></div>
-</body>
- -

即使浏览器的主线程中运行的 JavaScript 速度较慢,该版本也能在浏览器中顺利运行。

- -

其他效果

- -

在不少情况下,scroll-linked 效果能够通过 CSS 和在排序线程运行来重新实现。 然而, 有时浏览器提供的 API 不允许这么做。但是不管怎样, 如果 Firefox(从版本 46 之后)检测到页面上的 scroll-linked 效果, 将在控制台向开发人员显示警告 。 需要说明的是,使用滚动效果的页面如果在 JavaScript 中不监听滚动事件将无法获得此警告。你可以参考此博客文章( Asynchronous scrolling in Firefox )来了解更多通过 CSS 来实现避免页面延迟的例子。

- -

未来改进

- -

未来我们将在 compositor 中支持更多的效果。为了完成这个目标,我们需要你(没错,就是你!)来告诉我们更多的你努力实现的 scroll-linked 效果,以便我们可以找到好的方式来支持它们。目前有几个对于 API 的提案可以实现这种效果,它们也都有各自的优缺点。目前正在审议的提案是:

- - - -

Call to action

- -

如果你对下列内容有想法或意见:

- - - -

请与我们联系,您可以通过 public-houdini 邮件列表来加入讨论。

diff --git a/files/zh-cn/mozilla/persona/bootstrapping_persona/index.html b/files/zh-cn/mozilla/persona/bootstrapping_persona/index.html deleted file mode 100644 index 4f1c519c0a..0000000000 --- a/files/zh-cn/mozilla/persona/bootstrapping_persona/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Persona引导 -slug: Mozilla/Persona/Bootstrapping_Persona -translation_of: Archive/Mozilla/Persona/Bootstrapping_Persona ---- -

为了真正成功实现分权,Persona需要得到三方面的支持:

- -

This creates a chicken-and-egg problem: none of these groups would significantly benefit unless there was a critical mass of users, but a distributed system can't get a critical mass of users without support from the above groups.

-

To solve this problem, https://login.persona.org hosts three resources:

-
    -
  1. A fallback Identity Provider, which vouches for users whose email providers don't support Persona.
  2. -
  3. A cross-browser, JavaScript implementation of the navigator.id APIs for browsers without native support.
  4. -
  5. A hosted verification API to make it easy for sites to verify user credentials.
  6. -
-

Together, this allows web sites to offer Persona to users regardless of browser and without email providers needing to get involved.

-

These services are temporary, and the Persona system is designed such that they transparently and automatically drop away as native support gets added to browsers and email providers. Thus, they will become less relevant as Persona matures, and may eventually be removed all together. At that point, https://login.persona.org won't feature at all in the Persona system.

-

Fallback Identity Provider

-

Any domain can become an Identity Provider as long as relying parties are willing to trust the certificates issued by that domain. We expect email providers to act as an IdPs for the addresses they administer, making the user experience of Persona seamless for those users.  It allows the user to leverage their existing relationship with the email provider when authenticating at other sites.

-

However, email providers won't become IdPs until there is significant demand from their users. In the meantime, Mozilla operates a fallback IdP at https://login.persona.org. This fallback allows users to sign into sites with their existing email address, regardless of whether or not the email provider supports Persona. The fallback IdP will certify email addresses from any domain using its own authentication flow and its own password, so long as the user is able to prove control of an address by clicking a link in a verification email.

-

Once an email provider supports Persona natively, its users will transparently begin use it instead of the fallback IdP.

-

Cross-browser API Library

-

For Persona to work, the user's browser must support the navigator.id API. Eventually, browsers will add native support for these APIs, but until then a cross-browser implementation is available at https://login.persona.org/include.js. By including this file, web sites can already begin using Persona. Once native implementations of the API are available, the library will automatically defer to those.

-

Remote verification service

-

At https://login.persona.org Mozilla hosts a remote verification service that web sites can use to verify identity assertions sent from users. This makes it simpler for web sites to support Persona as it takes care of parsing the assertion and cryptographically verifying user identities.

-

Once the Persona data formats stabilize, verification will most likely be done locally on each site's server. This transition is especially important for user privacy, since it will make it impossible for the fallback IdP to track its users. Even with remote verification, users of native IdPs can't be tracked by that IdP.

diff --git a/files/zh-cn/mozilla/persona/branding/index.html b/files/zh-cn/mozilla/persona/branding/index.html deleted file mode 100644 index 3120f9a4c8..0000000000 --- a/files/zh-cn/mozilla/persona/branding/index.html +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: 品牌资源 -slug: Mozilla/Persona/branding -tags: - - 图片 - - 按钮 -translation_of: Archive/Mozilla/Persona/User_interface_guidelines ---- -

使用 Persona 样式的按钮登陆

-

图片样式

-

Persona样式的登录按钮有三个版本,三种颜色:

-

英文按钮

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Sign in with your EmailSign in with PersonaSign in
Black
Blue
Red
-

中文按钮

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 使用Email登录使用Persona登录登录
黑色
蓝色
红色
-

中文按钮打包下载

-

地址:persona_sign_in_zh_cn.20130513.001.by.will.chen.7z

-

CSS-Based

-

Sawyer Hollenshead 制作了一些非常优秀的 CSS-based 的按钮. Download (.zip)

-

更多信息

-

你可以在 Sean Martell's style primer找到更多关于Persona视觉效果设计的信息.

diff --git a/files/zh-cn/mozilla/persona/browser_compatibility/index.html b/files/zh-cn/mozilla/persona/browser_compatibility/index.html deleted file mode 100644 index e362b74b3a..0000000000 --- a/files/zh-cn/mozilla/persona/browser_compatibility/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: 浏览器兼容性 -slug: Mozilla/Persona/Browser_compatibility -tags: - - Files -translation_of: Archive/Mozilla/Persona/Browser_compatibility ---- -

支持的浏览器

-

Persona 支持下列浏览器。 Persona 包含一个跨平台的 JavaScript 库,因此用户使用时不需要安装任何插件。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
桌面浏览器
Internet Explorer8.0*, 9.0, 10.0** (详见下方的 兼容模式 说明)
Firefox现有稳定版本, 测试版本, Aurora, 夜间发布版本 和 扩展支持版本
- 以往稳定版本
Chrome最新稳定版本
Safari最新稳定版本
Opera最新稳定版本
iOS 浏览器
SafariiOS 5.x — 6.x
Android 浏览器
默认浏览器2.2 — 4.x
Firefox现有稳定版本, 测试版本, Aurora 和 夜间发布版本
- 以往稳定版本
ChromeLatest Stable Release
-

*: Windows XP. : Windows Vista 和 Windows 7. **Windows 8.  : 如果时间允许.

-

不支持的浏览器

- -

Internet Explorer 的“兼容模式”

-

从 8.0 版开始, Internet Explorer 提供了一项名为“兼容模式”的功能, 其在渲染页面时会模拟 8.0 以前版本的行为。 这个特性可以通过三种方法控制:

-
    -
  1. 浏览器中的本地设置
  2. -
  3. 页面中的 DOCTYPE 声明
  4. -
  5. 网站在 HTTP 头或页面 <meta> 标签中使用 "X-UA-Compatible"。 此方法会覆盖前两种
  6. -
-

由于 Persona 不支持 Internet Explorer 8.0 以前版本, 任何 Internet Explorer 如果模拟了8.0 以前版本也将不能支持 Persona 。 这通常是由于:

- -

详情请见 "Understanding Compatibility Modes in Internet Explorer 8" 和 "IE8 and IE9 Complications".

-

其他浏览器

-

除非明显不被支持, 任何同时支持 {{ domxref("window.postMessage()") }} 和 {{ domxref("Storage", "localStorage") }} 的浏览器都应该能使 Persona 正常运行。 2010年3月后所有主流浏览器都支持这些 API 。

-

已知问题

- diff --git a/files/zh-cn/mozilla/persona/glossary/index.html b/files/zh-cn/mozilla/persona/glossary/index.html deleted file mode 100644 index 430bacbabe..0000000000 --- a/files/zh-cn/mozilla/persona/glossary/index.html +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: 术语表 -slug: Mozilla/Persona/Glossary -translation_of: Archive/Mozilla/Persona/Glossary ---- -

"Persona" 和 "BrowserID"

-

Persona 是 Mozilla 的全新分布式登录系统的完整实现。

-

BrowserID 是 Persona 基于的开放协议。

-

常用 Persona 术语

-
-
- BrowserID
-
- 一种基于电子邮件地址的,开放、去中心化的用户认证协议。
-
- 身份凭证提供者 ("IdP")
-
- 为其用户签发身份凭证的服务。
-
- 邮件服务提供商可以通过在其服务中增加 BrowserID 支持成为身份凭证提供者。 Mozilla 为不支持 Persona 的邮件服务提供商提供了身份凭证服务, 其位于 login.persona.org.
-
- login.persona.org
-
- 由 Mozilla Identity 团队运行的备用身份凭证服务。
-
- Persona
-
- Mozilla 对用户公布的整套认证服务的名称,这套服务包括由 Mozilla Identity 团队运行的备用身份凭证服务。 最终用户应该不需要知道 "BrowserID" 这个术语。
-
- Persona 可能逐渐包含 BrowserID 协议之外的功能,如 Firefox Sync 的部分功能,或者 Open Web Apps 的控制面板。
-
- Relying Party ("RP")
-
- 允许用户通过 Persona 登录的任何网站,应用或服务。
-
-

项目代号

-
-
- BigTent
-
- 三个身份凭证服务的集合,分别针对 Hotmail,Gmail 和 Yahoo Mail 的用户。 BigTent 通过OpenID 或 OAuth 等方式连接各个邮件服务提供商。 源码位于 https://github.com/mozilla/browserid-bigtent 。
-
- Vinz Clortho
-
- 电子邮件后缀为 @mozilla.com@mozilla.org 的身份凭证服务。 通过 LDAP 运行。 源码位于 https://github.com/mozilla/vinz-clortho 。 项目名称向1984年的电影《捉鬼敢死队》致敬。
-
-

不常用 Persona 术语

-
-
- 一级认证机构 ("Primary")
-
- 弃用术语, 指能同时作为身份认证提供者的邮件服务提供商。
-
- 二级认证机构 ("Secondary)
-
- 弃用术语,指为其邮件服务提供商不支持 Persona 的用户提供备用身份认证服务的身份认证提供者。Mozilla 在 login.persona.org 运行了一个备用身份认证服务。
-
- Verified Email Protocol
-
- BrowserID 协议的旧称。
-
diff --git a/files/zh-cn/mozilla/persona/index.html b/files/zh-cn/mozilla/persona/index.html deleted file mode 100644 index 5c19bec83a..0000000000 --- a/files/zh-cn/mozilla/persona/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Mozilla Persona -slug: Mozilla/Persona -tags: - - Mozilla - - Persona - - zh-CN -translation_of: Archive/Mozilla/Persona ---- -
-

保持联系或获取帮助!

- -

关注 我们的 blog,加入 我们的邮件列表,或在 IRC 中的 #identity 找到我们。

-
- -
-

提示:Mozilla将在2016年11月关闭Persona.org

- -

邮件列表:https://mail.mozilla.org/pipermail/persona-notices/2016/000005.html

-
- -

Mozilla Persona 是一个用于 web 的完全去中心化且安全的验证系统,基于开放 BrowserID 协议。Mozilla 当前管理一个 Persona 相关的一个可选的、中心化服务的一小组套件。

- -

为什么你和你的站点应该使用 Persona?

- -
    -
  1. Persona 完全消除了站点特定的密码, 把用户和网站从创建、管理和安全存放密码的责任中解放出来。
  2. -
  3. Persona 易于使用。只需点击两次,一个 Persona 用户可以登入到一个诸如 VoostThe Times Crossword 的新站点,绕开了账户创建相关的摩擦。
  4. -
  5. Persona 易于实现。开发人员在一个下午就可以把 Persona 添加到站点上。
  6. -
  7. 最好的是,不会被锁定。 开发人员获取所有他们用户的验证过的邮件地址,而用户可以在 Persona 上使用任何邮件地址。
  8. -
  9. Persona 基于 BrowserID 协议构建。一旦流行的浏览器供应商实现了 BrowserID,它们不再需要依赖于 Mozilla 来登入。
  10. -
- -

继续阅读来开始!

- -
注意:Persona 在活跃开发中。关注我们的 blog 来了解新特性,或加入我们的邮件列表来提供反馈!
- -

在你的站点上使用 Persona

- - - - - - - - - - - - -
-

准备开始

- -
-
为什么使用 Persona?
-
了解在你的站点上支持 Persona 的原因和它与其它身份验证系统的区别。
-
快速安装
-
一份快捷的攻略,展示了如何向你的网站中添加 Persona。
-
-
-

Persona API 参考

- -
-
navigator.id API 参考
-
navigator.id 对象的参考,web 开发者可以用此来把 Persona 继承到站点中。
-
验证 API 参考
-
建立在 https://verifier.login.persona.org/verify 上的远程验证 API 的参考。
-
-
-

指导

- -
-
安全考虑
-
确保 Persona 部署安全的实践和技术。
-
浏览器兼容性
-
准确获知哪些浏览器支持 Persona。
-
国际化
-
了解 Persona 如何处理不同的语言。
-
-
-

资源

- -
-
库和插件
-
寻找你偏好的编程语言、web 框架、博客或是内容管理系统(CMS)的即插库。
-
Persona cookbook
-
Persona 站点的示例源代码。包括 PHP、Node.JS 等等的片段。
-
品牌资源
-
登入按钮和其它向用户表现 Persona 的图形。
-
-
- -

 

- - - - - - - - -
-

给身份提供者的信息

- -

如果你是一个电子邮件提供商或另一个身份提供服务,翻阅下面的链接来获知如何成为一个 Persona 身份提供者。

- -
-
IdP 概述
-
Persona 身份提供者的高层视角。
-
实现一个 IdP
-
成为一个 IdP 的详细技术细节指导。
-
开发提示
-
开发一个新的身份提供者的一系列开发提示和技巧。
-
.well-known/browserid
-
.well-known/browserid 文件的结构和用途概述,这个文件被 IdPs 用于通知它们支持这个协议。
-
-
-

Persona 项目

- -
-
术语表
-
BrowserID 和 Persona 定义的术语。
-
FAQ
-
常见问题的回答。
-
协议概述
-
底层 BrowserID 协议的中等技术概述。
-
加密
-
一瞥 Persona 和 BrowserID 背后的密码学概念。
-
协议规范
-
这里是深层技术细节。
-
Persona 网站
-
要让 Persona 运作, 我们在https://login.persona.org 建立了三个服务:一个备用身份提供者、一个可迁移的 {{ domxref("navigator.id") }} API 实现以及一个身份断言验证服务。
-
Persona 源码
-
Persona 网站背后的源码托管在 GitHub 的一个仓库上。欢迎提交补丁!
-
-
- -

 

diff --git a/files/zh-cn/mozilla/persona/protocol_overview/index.html b/files/zh-cn/mozilla/persona/protocol_overview/index.html deleted file mode 100644 index 9e61fb2b95..0000000000 --- a/files/zh-cn/mozilla/persona/protocol_overview/index.html +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: 协议概述 -slug: Mozilla/Persona/Protocol_Overview -tags: - - Persona -translation_of: Archive/Mozilla/Persona/Protocol_Overview ---- -

Persona is built on the BrowserID protocol. This page describes the BrowserID protocol at a high level.

- -

角色

- -

The protocol involves three actors:

- - - -

Persona and the BrowserID protocol use email addresses as identities, so it's natural for email providers to become IdPs.

- -

Mozilla operates a fallback IdP so that users can use any email address with Persona, even one with a specific domain that isn't an IdP itself.

- -

协议步骤

- -

There are three distinct steps in the protocol:

- -
    -
  1. User Certificate Provisioning
  2. -
  3. Assertion Generation
  4. -
  5. Assertion Verification
  6. -
- -

As a prerequisite, the user should have an active identity (email address) that they wish to use when logging in to websites. The protocol does not require that IdP-backed identities are SMTP-routable, but it does require that identities follow the user@domain format.

- -

用户认证过程

- -

In order to sign into an RP, a user must be able to prove ownership of their preferred email address. The foundation of this proof is a cryptographically signed certificate from an IdP certifying the connection between a browser's user and a given identity within the IdP's domain.

- -

Because Persona uses standard public key cryptography techniques, the user certificate is signed by the IdP's private key and contains:

- - - -

The user's browser generates a different keypair for each of the user's email addresses, and these keypairs are not shared across browsers. Thus, a user must obtain a fresh certificate whenever one expires, or whenever using a new browser or computer. Certificates must expire within 24 hours of being issued.

- -

When a user selects an identity to use when signing into an RP, the browser checks to see if it has a fresh user certificate for that address. If it does, this step is complete and the browser continues with the assertion generation step below. If the browser does not have a fresh certificate, it attempts to obtain one from the domain associated with the chosen identity.

- -
    -
  1. The browser fetches the /.well-known/browserid support document over SSL from the identity's domain.
  2. -
  3. Using information from the support document, the browser passes the user's email address and associated public key to the IdP and requests a signed certificate.
  4. -
  5. If necessary, the user is asked to sign into the IdP before provisioning proceeds.
  6. -
  7. The IdP creates, signs, and gives a user certificate to the user's browser.
  8. -
- -

With the certificate in hand, the browser can continue with generating an identity assertion and signing into an RP.

- -

user-certificate-provisioning.png

- -

生成断言

- -

The user certificate establishes a verifiable link between an email address and a public key. However, this is alone not enough to log into a website: the user still has to show their connection to the certificate by proving ownership of the private key.

- -

In order to prove ownership of a private key, the user's browser creates and signs a new document called an "identity assertion." It contains:

- - - -

The browser then presents both the user certificate and the identity assertion to the RP for verification.

- -

验证断言

- -

The combination of user certificate and identity assertion is sufficient to confirm a user's identity.

- -

First, the RP checks the domain and expiration time in the assertion. If the assertion is expired or intended for a different domain, it's rejected. This prevents malicious re-use of assertions.

- -

Second, the RP validates the signature on the assertion with the public key inside the user certificate. If the key and signature match, the RP is assured that the current user really does possess the key associated with the certificate.

- -

Last, the RP fetches the IdP's public key from its /.well-known/browserid document and verifies that it matches the signature on the user certificate. If it does, then the RP can be certain that the certificate really was issued by the domain in question.

- -

Once verifying that this is a current login attempt for the proper RP, that the user certificate matches the current user, and that the user certificate is legitimate, the RP is done and can authenticate the user as the identity contained in the certificate.

- -

assertion-generation-and-verify.png

- -

The Persona Fallback IdP

- -

What if a user's email provider doesn't support Persona? In that case, the provisioning step would fail. By convention, the user's browser handles this by asking a trusted third party, https://login.persona.org/, to certify the user's identity on behalf of the unsupported domain. After demonstrating ownership of the address, the user would then receive a certificate issued by the fallback IdP, login.persona.org, rather than the identity's domain.

- -

RPs follow a similar process when validating the assertion: the RP would ultimately request the fallback IdP's public key in order to verify the certificate.

diff --git a/files/zh-cn/mozilla/persona/quick_setup/index.html b/files/zh-cn/mozilla/persona/quick_setup/index.html deleted file mode 100644 index e39958eb98..0000000000 --- a/files/zh-cn/mozilla/persona/quick_setup/index.html +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: 快速安装 -slug: Mozilla/Persona/Quick_Setup -tags: - - Mozilla - - Persona -translation_of: Archive/Mozilla/Persona/Quick_Setup ---- -

要把 Persona 登录系统添加到你的站点只需要 5 步:

-
    -
  1. 在你的页面中包含 Persona 的 JavaScript 库。
  2. -
  3. 添加“登入”和“登出”按钮。
  4. -
  5. 监视登入和登出行为。
  6. -
  7. 验证用户证书。
  8. -
  9. 回顾最佳实现。
  10. -
-

你应该能在一个下午就建立好并运行,但重要的是:如果你要在你的站点上使用 Persona,请花一点时间订阅 Persona 通知 邮件列表。它流量非常低,只用于通知那些对你站点有负面影响的变更或安全问题。

-

步骤1:包含 Persona 库

-

Persona 被设计为跨浏览器且可在全部主要桌面和移动浏览器中工作。

-

在未来我们期望浏览器提供 Persona 的原生支持,但我们同时提供了一个 JavaScript 库完整地实现了用户界面和客户端部分的协议。通过包含这个库,你的用户会可以用 Persona 登入,无论他们的浏览器是否有原生支持。

-

一 旦页面中的这个库加载完毕,你需要的 Persona 函数({{ domxref("navigator.id.watch()", "watch()") }}、{{ domxref("navigator.id.request()", "request()") }} 和 {{ domxref("navigator.id.logout()", "logout()") }})会在全局对象 navigator.id 中可用。

-

要包含 Persona JavaScript 库,你可以把这个 script 标签放进你页面的首部:

-
<script src="https://login.persona.org/include.js"></script>
-
-

必须在每个使用 {{ domxref("navigator.id") }} 中函数的页面里包含这个标签。因为 Persona 始终在开发中,你不应该自行托管 include.js 文件。

-

步骤2:添加登入/登出按钮

-

因 为 Persona 被设计为一个 DOM API,你必须在用户点击你站点上的登入或登出按钮时调用函数。要打开 Persona 对话框并提示用户登入,你应该调用 {{ domxref("navigator.id.request()") }} 。而登出要调用 {{ domxref("navigator.id.logout()") }} 。

-

例如:

-
var signinLink = document.getElementById('signin');
-if (signinLink) {
-  signinLink.onclick = function() { navigator.id.request(); };
-};
-
-var signoutLink = document.getElementById('signout');
-if (signoutLink) {
-  signoutLink.onclick = function() { navigator.id.logout(); };
-};
-
-

那些按钮的是什么样子的?查看我们的品牌资源页面中的预制图片和基于 CSS 的按钮!

-

步骤3:监视登入/登出行为

-

要把 Persona 封装成函数,你需要告诉它当用户登入/登出时做什么。调用 {{ domxref("navigator.id.watch()") }} 函数就可以实现,它支持三个参数:

-
    -
  1. -

    你站点当前用户的 loggedInEmail ,如果没有则为 null 。你应该在渲染页面的时候动态生成它。

    -
  2. -
  3. -

    当触发 onlogin 行为的时候调用的函数。这个函数会被传递一个必须认证的“身份断言”参数。

    -
  4. -
  5. -

    当触发 onlogout 行为的时候调用的函数。这个函数不会被传递任何参数。

    -
  6. -
-
-

注意:你必须总是在调用 {{ domxref("navigator.id.watch()") }} 时同时包含 onloginonlogout

-
-

例如,如果你现在认为鲍勃已经登入到你的站点,你会这样做:

-
var currentUser = 'bob@example.com';
-
-navigator.id.watch({
-  loggedInUser: currentUser,
-  onlogin: function(assertion) {
-    // 一个用户已经登入!这是你需要做的:
-    // 1. 把断言发送到后端验证并创建一个会话。
-    // 2. 更新你的 UI。
-    $.ajax({ /* <-- 本例使用了 jQuery,但你也可以用你想用的 */
-      type: 'POST',
-      url: '/auth/login', // 这是你网站上的一个 URL
-      data: {assertion: assertion},
-      success: function(res, status, xhr) { window.location.reload(); },
-      error: function(res, status, xhr) { alert("登入失败" + res); }
-    });
-  },
-  onlogout: function() {
-    // 一个用户已经登出!这是你需要做的:
-    // 销毁用户的会话并重定向用户或做后端的调用。
-    // 同样,让 loggedInUser 在下个页面加载时变为 null。
-    // (这是一个字面的 JavaScript null。不是 false、 0 或 undefined。null。)
-    $.ajax({
-      type: 'POST',
-      url: '/auth/logout', // 这是你网站上的一个 URL
-      success: function(res, status, xhr) { window.location.reload(); },
-      error: function(res, status, xhr) { alert("登出失败" + res); }
-    });
-  }
-});
-
-

在本例中,onloginonlogout 都通过向你站点的后端发送异步 POST 请求来实现。后端随后通常用设定或删除会话 cookie 中的信息来登入或登出用户。之后,如果一切都核对无误,页面重加载来考虑账户的新登录状态。

-

你当然可以用 AJAX 来不用重加载或重定向来实现,但这超出了本教程的范畴。

-

必须在每个有登入/登出按钮的页面上调用这个函数。要为用户支持 Persona 加强功能,诸如自动登录和全局登出,你应该在网站上的每个页面都调用这个函数。

-

步骤4:验证用户证书

-

Persona 用“身份断言”来代替密码,那是一种类似一次性、单站点的、用户邮件地址捆绑的密码。当用户想要登入时,你的 onlogin 回调会传入一个该用户的断言来调用。在你登入他们前,你必须验证断言的有效性。

-

在你的服务器上而不是用户浏览器上运行的 JavaScript 中验证断言是极度重要的,因为那很容易伪造。上面的例子用 jQuery 的 $.ajax() 辅助函数来把断言通过 POST/auth/login 来呈递给后端。

-

一旦你的服务器获得了断言,你如何验证它?最简单的方法是用 Mozilla 提供的辅助服务。简单地把断言以两个参数 POSThttps://verifier.login.persona.org/verify

-
    -
  1. assertion: 用户提供的身份断言。
  2. -
  3. audience: 你网站的主机名和端口。你必须在后端硬编码这个值;不要从用户提供的任何数据中派生这个值。
  4. -
-

例如,如果你是 example.com,你可以用下面的命令行来测试断言:

-
$ curl -d "assertion=<ASSERTION>&audience=https://example.com:443" "https://verifier.login.persona.org/verify"
-
-

如果它是有效的,你会得到像这样的一个 JSON 响应:

-
{
-  "status": "okay",
-  "email": "bob@eyedee.me",
-  "audience": "https://example.com:443",
-  "expires": 1308859352261,
-  "issuer": "eyedee.me"
-}
-
-

你可以阅读验证服务 API来获知更多关于验证服务的内容。一个 /api/login 实现的使用了 PythonFlask web 框架和 Requests HTTP 库的例子看起来是这样:

-
@app.route('/auth/login', methods=['POST'])
-def login():
-    # 请求必须包含我们要验证的断言
-    if 'assertion' not in request.form:
-        abort(400)
-
-    # 把断言发送给 Mozilla 的验证服务
-    data = {'assertion': request.form['assertion'], 'audience': 'https://example.com:443'}
-    resp = requests.post('https://verifier.login.persona.org/verify', data=data, verify=True)
-
-    # 验证器响应了吗?
-    if resp.ok:
-        # 处理响应
-        verification_data = json.loads(resp.content)
-
-        # 检查断言是否有效
-        if verification_data['status'] == 'okay':
-            # 设置一个安全会话 cookie 来登入用户
-            session.update({'email': verification_data['email']})
-            return resp.content
-
-    # 哎哟,有什么东西不对,放弃
-    abort(500)
-
-

会话管理可能很像你现有的登录系统。首先的大区别是在验证用户身份采用了检查断言而不是检查密码。另一个不同是确保用户的邮件地址有效来用于 {{ domxref("navigator.id.watch()") }} 的 loggedInEmail 参数

-

登出很简单:你只需要移除用户的会话 cookie。

-

步骤5:回顾最佳实践

-

一旦所有的东西都工作正常并且你已经成功登入和登出你的站点,你应该花一会时间来回顾安全可靠地使用 Persona 的最佳实践

-

如果你在做一个要作为生产环境的站点,你会想要编写集成的测试来模拟用 Persona 登入或登出用户。要改善 Selenium 中的这个行为,请考虑使用 bidpom 库。mockmyid.compersonatestuser.org 这两个网站也可能会有用。

-

最后,不要忘记登记加入 Persona 通知 邮件列表,这样会通知你任何安全问题或 Persona API 的向后兼容变更。这个列表的流量非常低:它只用于通知会对你的站点造成负面影响的变更。

diff --git a/files/zh-cn/mozilla/persona/remote_verification_api/index.html b/files/zh-cn/mozilla/persona/remote_verification_api/index.html deleted file mode 100644 index 55f37e793e..0000000000 --- a/files/zh-cn/mozilla/persona/remote_verification_api/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: 远程验证 API -slug: Mozilla/Persona/Remote_Verification_API -translation_of: Archive/Mozilla/Persona/Remote_Verification_API ---- -

概述

-

当用户试图登入一个网站,他们的浏览器会生成一个名为断言的数据结构,这实质上是一个加密签名的邮件地址。浏览器把这个断言发送给网站,网站必须在登入用户前检验断言是否有效。

-

断言可以本地验证,或使用托管在 https://verifier.login.persona.org/verify 的 API。本页面描述如何使用这个 API。

-

方法

-

把 HTTP POST 请求发送至 https://verifier.login.persona.org/verify

-

参数

-

assertion: 断言由用户提供。作为传给  {{ domxref("navigator.id.watch()") }} 中 onlogin  函数的第一个参数。
- audience: 你的站点的协议、域名和端口。 例如, "https://example.com:443"。

-

返回值

-

调用会返回一个包含 status 元素的 JSON 结构,这个元素值会是 "okay" 或是" failure" 。取决于 status 的值,这个结构包含下面列出的额外元素。

-

"okay"

-

断言是有效的。

-

在这种情况下 JSON 结构包含下面的额外元素:

- - - - - - - - - - - - - - - - - - - -
"email"断言中包含欲登录人的邮件地址。
"audience"断言中包含 audience 值。 期望值为你的网站 URL。
"expires"断言过期的日期,表示为Date 对象的原始值: 即从 UTC 1970 年 1 月 1 日午夜至今的毫秒数。
"issuer"发出断言的身份提供者的主机名。
-

"failure"

-

断言是无效的。这种情况下,JSON 结构包含一个额外元素:

- - - - - - - -
"reason"一个解释验证失败原因的字符串。
-

示例

-

node.js

-

例中使用了一个采用 express.js 的 node.js 服务器

-
var express = require("express"),
-    app = express.createServer(),
-    https = require("https"),
-    querystring = require("querystring");
-/* ... */
-
-// audience 值必须匹配你浏览器地址栏显示的值,
-// 包括协议、主机名、端口
-var audience = "http://localhost:8888";
-
-app.post("/authenticate", function(req, res) {
-  var vreq = https.request({
-    host: "verifier.login.persona.org",
-    path: "/verify",
-    method: "POST"
-  }, function(vres) {
-    var body = "";
-    vres.on('data', function(chunk) { body+=chunk; } )
-        .on('end', function() {
-          try {
-            var verifierResp = JSON.parse(body);
-            var valid = verifierResp && verifierResp.status === "okay";
-            var email = valid ? verifierResp.email : null;
-            req.session.email = email;
-            if (valid) {
-              console.log("assertion verified successfully for email:", email);
-            } else {
-              console.log("failed to verify assertion:", verifierResp.reason);
-            }
-            res.json(email);
-          } catch(e) {
-            console.log("non-JSON response from verifier");
-            // bogus response from verifier! return null
-            res.json(null);
-          }
-        });
-  });
-  vreq.setHeader('Content-Type', 'application/x-www-form-urlencoded');
-
-  var data = querystring.stringify({
-    assertion: req.body.assertion,
-    audience: audience
-  });
-  vreq.setHeader('Content-Length', data.length);
-  vreq.write(data);
-  vreq.end();
-  console.log("verifying assertion!");
-});
-
-
-

via Lloyd Hilaiel

-

PHP

-
$url = 'https://verifier.login.persona.org/verify';
-$assert = $_POST['assert'];
-$params = 'assertion='.$assert.'&audience=' .
-           urlencode('http://example.com:80');
-$ch = curl_init();
-$options = array(
-    CURLOPT_URL => $url,
-    CURLOPT_RETURNTRANSFER => TRUE,
-    CURLOPT_POST => 2,
-    CURLOPT_POSTFIELDS => $params
-);
-curl_setopt_array($ch, $options);
-$result = curl_exec($ch);
-curl_close($ch);
-echo $result;
-
-

Via Christian Heilmann

diff --git a/files/zh-cn/mozilla/persona/security_considerations/index.html b/files/zh-cn/mozilla/persona/security_considerations/index.html deleted file mode 100644 index d955e82d13..0000000000 --- a/files/zh-cn/mozilla/persona/security_considerations/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: 安全考虑 -slug: Mozilla/Persona/Security_Considerations -translation_of: Archive/Mozilla/Persona/Security_Considerations ---- -

When you add Persona support to your website, Persona takes on as much of the security burden as it can. However, some aspects of security can only be handled by your website. They're listed below.

-

Essential practices

-

Verify assertions on your server

-

When using Persona, identity assertions are passed into the onlogin function passed to {{ domxref("navigator.id.watch()") }}. You should always pass the assertion to your server for verification, and only your server should decide to grant the user additional permissions based on the verification result:

-
// Inside navigator.id.watch({ ...
-onlogin: function(assertion) {
-  // A user wants to log in! Here you need to:
-  // 1. Send the assertion to your backend for verification and to create a session.
-  // 2. Update your UI.
-},
-
-

If you try to verify the assertion using the JavaScript executing in the user's browser, then a malicious user will be able to impersonate a legitimate user of your site by locally injecting code and subverting your JavaScript. This is possible because you're not fully in control of the user's browser, where the code executes.

-

Again, you should always pass the assertion to your server for verification. Even if you're using the remote verification API.

-

Explicitly specify the audience parameter

-

To verify an assertion, you may issue a POST request to https://verifier.login.persona.org/verify. The request includes a parameter called audience:

-
assertion=<ASSERTION>&audience=https://mysite.com:443"
-

The audience parameter is required. You should always specify the audience explicitly in your code, or in your code's configuration. Specifically:

- -

If you trust the user's browser to tell you the audience, then it becomes possible for a malicious web site to reuse assertions for its web site to log into your web site.

-

Verify SSL certificates

-

To verify an assertion, you may issue a POST request to https://verifier.login.persona.org/verify. You must ensure that your HTTPS request verifies the certificate sent from the server against a trusted root certificate. If you don't, then an attacker could pose as verifier.login.persona.org and issue false verifications.

-

Check that the library you are using to make the request verifies certificates correctly, and that you are initializing it with the appropriate root certificate(s).

-

For example, Python 2.7's standard urllib2 module does not validate server certificates. Instead, we recommend using the "requests" or "urllib3" modules in Python 2.x, or the standard http.client.HTTPSConnection class in Python 3.x. For Perl, ensure that you are using at least version 6.0 of libwww-perl. Depending on the language, library, and operating system that you're using, you may need to supply either a list of trusted CA roots or the single CA used by verifier.login.persona.org.

-

Implement CSRF protection

-

In a CSRF (Cross-Site Request Forgery) login attack, an attacker uses a cross-site request forgery to log the user into a web site using the attacker's credentials.

-

For example: a user visits a malicious web site containing a form element. The form's action attribute is set to an HTTP POST request to http://www.google.com/login, supplying the attacker's username and password. When the user submits the form, the request is sent to Google, the login succeeds and the Google server sets a cookie in the user's browser. Now the user's unknowingly logged into the attacker's Google account.

-

The attack can be used to gather sensitive information about the user. For example, Google's Web History feature logs all the user's Google search terms. If a user is logged into the attacker's Google account and the attacker has Web History enabled, then the user is giving the attacker all this information.

-

CSRF login attacks, and potential defenses against them, are documented more fully in Robust Defenses for Cross-Site Request Forgery (PDF). They're not specific to Persona: most login mechanisms are potentially vulnerable to them.

-

There are a variety of techniques which can be used to protect a site from CSRF login attacks, which are documented more fully in the study above.

-

One approach is to create a secret identifier in the server, shared with the browser, and require the browser to supply it when making login requests. For example:

-
    -
  1. As soon as the user lands on your site, before they try to log in, create a session for them on the server. Store the session ID in a browser cookie.
  2. -
  3. On the server, generate a random string of at least 10 alphanumeric characters. A randomly generated UUID is a good option. This is the CSRF token. Store it in the session.
  4. -
  5. Deliver the CSRF token to the browser by either embedding it in JavaScript or HTML as a hidden form variable.
  6. -
  7. Ensure that the AJAX submission or form POST includes the CSRF token.
  8. -
  9. On the server side, before accepting an assertion, check that the submitted CSRF token matches the session-stored CSRF token.
  10. -
-

Enhancements

-

Content Security Policy (CSP)

-

Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement or distribution of malware.

-

If you use CSP on your site, you may need to tweak your policy to enable Persona. Depending on your policy, you may need to:

- -

An example Apache configuration might include:

-
Header set X-Content-Security-Policy: "default-src 'self'; frame-src 'self' https://login.persona.org ; script-src 'self' https://login.persona.org"
diff --git a/files/zh-cn/mozilla/persona/why_persona/index.html b/files/zh-cn/mozilla/persona/why_persona/index.html deleted file mode 100644 index d7d96a46fc..0000000000 --- a/files/zh-cn/mozilla/persona/why_persona/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: 为什么使用 Persona? -slug: Mozilla/Persona/Why_Persona -translation_of: Archive/Mozilla/Persona/Why_Persona ---- -

流行的用户名和密码系统并非长久之计:用户需要为每个他们使用的站点和服务创建并记住一个新的、复杂的密码,并且每个站点都要安全地存储密码。尽管如此,最近的事故证明了即使是巨头级的大公司也在密码安全上失误,这让他们的用户信息暴露在风险中。

-

Persona 是一个开放的、分布式、web 规模的身份识别系统,它取代了每个网站一个密码的局面。它解决了像 OpenID 这样系统的可用性和隐私相关的缺点而不诉诸于 Facebook Connect 这样的中心化基础架构。

-

Persona 摆脱了每站一密码

-

Persona 让用户在完成一个用于身份识别的简单一次性过程后只需点击两次即可登入网站,而不是每站一密码。这是在公钥密码学上构建的,安全可靠。用户的浏览器生成一个加密的“身份断言”来代替密码,它在几分钟后会过期并只在单个站点上有效。因为没有站点特定的密码,使用 Persona 的网站不需要关心密码数据库如何妥善存储或是丢失隐患。

-

这个快捷的登入过程也减少了用户访问新站点的摩擦。

-

Persona 身份是电子邮件地址

-

Persona 使用邮件地址作为身份,而不是任意形式的用户名。这让用户和开发者有所裨益:

-

用户使用邮件地址的优势

- -

开发者使用邮件地址的优势

- -

更不必说电子邮件已经是一个横跨无数服务提供者的有数以亿计账户的分布式系统。

-

Persona 与其它单点登录服务提供商有何区别?

-

Persona 安全、可靠,并且简单。它用其它提供商保护不用或不能的方法来用户隐私、用户控制和用户选择:

-

许多社交网络,诸如 Facebook 和 Google+,需要用户使用真名,并限制用户到单个账户。通过构建在邮件地址上,Persona 允许用户区分它们的工作、家庭、学校以及其它身份。

-

Persona 是开放的,也是分布式的:任何有电子邮件地址的人都可以登入使用 Persona 的站点。除此之外,任何人可以建立他们自己的身份提供者或委托给其它的权威机构,就像用电子邮件。这与需要一个单一中心化服务账号的社交登录服务相反。

-

Persona 也通过把用户浏览器放进认证过程中来提供保护用户隐私的新颖手段:浏览器从用户的邮件提供商获取证书,然后转向并把那些证书呈递给网站。电子邮件供应商不可能追踪用户,但网站仍然可以通过密码学验证证书来继续信任用户。大多数其它系统,即使是如 OpenID 这样的分布式系统,需要站点“背景连接通信(phone home)”才允许用户登入。

diff --git a/files/zh-cn/mozilla/preferences/index.html b/files/zh-cn/mozilla/preferences/index.html deleted file mode 100644 index 442d12a5db..0000000000 --- a/files/zh-cn/mozilla/preferences/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Preferences -slug: Mozilla/Preferences -translation_of: Mozilla/Preferences ---- -This page was auto-generated because a user created a sub-page to this page. diff --git a/files/zh-cn/mozilla/preferences/mozilla_networking_preferences/index.html b/files/zh-cn/mozilla/preferences/mozilla_networking_preferences/index.html deleted file mode 100644 index 117fa5d6af..0000000000 --- a/files/zh-cn/mozilla/preferences/mozilla_networking_preferences/index.html +++ /dev/null @@ -1,536 +0,0 @@ ---- -title: Mozilla 网络相关首选项 -slug: Mozilla/Preferences/Mozilla_networking_preferences -translation_of: Mozilla/Preferences/Mozilla_networking_preferences ---- -

摘要

-

本文列出了影响网络行为的首选项,并描述了可接受的值和行为。

-

受众

-

质量保证测试员、开发者以及熟知网络内部原理的骨灰级用户。
- 要想获取关于首选项(包括如何编辑)的通用技术文档,请参阅“有关 Mozilla 首选项的简要指南”一文。

-

本文的目标是准确地记录有关 Core-Necko 的行为及是否在 Firefox 中默认存在的信息。

-

概观

-

The sections are in roughly alphabetical + functional order. The preferences are in order of usage by the UI (which is not often alphabetical order). Relevant bugs are provided only when absolutely necessary.

-
-

Note: Do not change any of these via about:config unless you know what you are doing. If you are uncertain what that phrase means, you probably do not.

-
-

If you qualify, you are probably one or more of the following:

- -

首选项

-

HTTP(本部分仍在建设中)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
首选项名称可接受的值首选项是否默认存在及其他说明
general.useragent.contentlocalestring 
general.useragent.misc(major version number) string 
general.useragent.securitystring 
network.http.accept-encodinggzip,deflate (default string)no UI
network.http.accept.defaulttext/xml,application/xml,
- application/xhtml+xml,text/html;

- q=0.9,text/plain;
- q=0.8,video/x-mng,image/png,
- image/jpeg,image/gif;

- q=0.2,*/*;q=0.1
 
network.http.default-socket-type(empty) default?
network.http.keep-alivetrue (default) 
network.http.keep-alive.timeout30no UI
network.http.max-connections96 
network.http.max-connections-per-server32 
network.http.max-persistent-connections-per-proxy4 
network.http.max-persistent-connections-per-server8 
network.http.pipeliningTrue? (on in mozilla, greyed)
network.http.pipelining.firstrequestTrue 
network.http.pipelining.maxrequests8 Hard-coded to 8 max so 30 will have no greater affect
network.http.proxy.keep-alivetrue (default) 
network.http.proxy.pipeliningTrue? (on in mozilla, greyed)
network.http.proxy.version1.1 (default)
- 1.0
 
network.http.redirection-limit20 
network.http.request.max-start-delay10 
network.http.sendRefererHeader2 
network.http.sendSecureXSiteReferrertrue 
network.http.use-cachetrue 
network.http.version1.1 (default)
- 1.0
 
-

文件

- - - - - - - - - - - - - -
首选项名称Acceptable ValuesPreferences UI and comments
security.checkloaduritrue (default)
- false
No UI
- checkloaduri will disable file:// URLs on pages from a network (http: https: ftp:) source, for security reasons.
- Errors are sent to the javascript console, not to the user via dialog box. This preference only works in Gecko versions before 1.8 (so Firefox 1.0 and Mozilla Suite builds). In Firefox 1.5 and Seamonkey 1.0 this preference no longer has an effect.
-

FTP(另请参见“代理”部分)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
首选项名称Acceptable ValuesPreferences UI (in bold) and comments
advanced.mailftpfalse (default)
- true
Preferences | Advanced |
- "{{ mediawiki.external('x') }} Set this email address as anonymous FTP password:"
-
- If false, FTP uses "mozilla@example.com" as anonymous FTP password ({{ Bug("101027") }})
- If true, FTP uses contents of network.ftp.anonymous_password for anonymous FTP password ({{ Bug("57763") }} comment 28)
network.ftp.anonymous_passwordempty (default)
- any text string
Preferences | Advanced |
- (under "{{ mediawiki.external(' ') }} Set this email address as anonymous FTP password:")
- {{ mediawiki.external('text field') }}
-
- If empty, FTP uses "mozilla@example.com" as anonymous FTP password.
network.ftp.idleConnectionTimeout300 (default)
- any integer
No UI
- Measured in seconds
- The open connection can prevent other FTP clients on your system from connecting to sites that allow only one control connection ({{ Bug("117875") }})
network.dir.format0 = HTML view
- 1 = raw view
- 2 = HTML view
- 3 = XUL view
Preferences | Debug | Networking
- Networking
- Directory Listing Format
- ( ) HTML
- ( ) XUL (tree-based)
-

缓存

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
首选项名称Acceptable ValuesPreferences UI (in bold) and comments
browser.cache.disk.capacity -

256000 (default)

-

any integer (in KB)

-
-

Preferences | Advanced | Cache
- Cache: {{ mediawiki.external('MB') }} MB

-
- Note: The default was 51200 prior to Gecko 9.0 {{ geckoRelease("9.0") }}.
-
browser.cache.disk.parent_directorypath to Cache folder in profile (default) -

Cache Folder: {{ mediawiki.external('text box') }}

-
- Note: The contents of the disk and memory caches are different (a very large memory cache is not the same as pointing disk cache to memory mapped disk space (RAM disk).
-
browser.cache.disk.max_entry_size -

51200 (default)

-

-1 = no limit

-
-

The maximum size of an entry in the disk cache.

-
- Note: Items larger than 1/8 of browser.cache.disk.capacity are never cached.
-
browser.cache.check_doc_frequency1 = Every time I view the page
- 0 = Once per session
- 3 = When the page is out of date (default)
- 2 = Never
Compare the page in cache to the page on the network:
browser.cache.disk.enabletrue (default)Preferences | Debug | Cache
- {{ mediawiki.external('x') }} Enable Disk Cache
- {{ mediawiki.external('x') }} Enable Memory Cache
-
- Disabling disk cache has the effect of setting it to zero.
browser.cache.memory.enabletrue (default)
browser.cache.memory.capacityany integer (in KB)Replaced by automatic sizing in Mozilla 1.4b ({{ Bug("105344") }}).
- This value overrides the application.
- 0 disables feature
- (before, 4096 = default)
browser.cache.memory.max_entry_size -

5120 (default)

-

-1 = no limit

-
-

The maximum size of an entry in the memory cache (in KB).

-
- Note: Items larger than 90% of browser.cache.memory.capacity are never cached.
-
network.http.use-cachetrue (default)no UI
browser.cache.disk_cache_sslfalse (default)no UI, added in 1.6a (see {{ Bug("205921") }})
network.prefetch-nextFalsePreferences | Advanced | Cache: Link Prefetching
- {{ mediawiki.external('x') }} Prefetch web pages when idle, so that links in web page designed for prefetching can load faster.
browser.cache.disk.smart_size.first_runtrue (default)Indicates whether or not this is the first time smart sizing has been used.
browser.cache.disk.smart_size.enabledtrue (default)Indicates whether or not smart sizing of the disk cache is enabled.
-

DNS

- - - - - - - - - - - - - - - - - -
首选项名称Acceptable ValuesPreferences UI (in bold) and comments
network.dnsCacheExpiration60 (seconds)default pref-less, not visible in about:config.
- Create and set both values to "0" to disable.
network.dnsCacheEntries20 (entries)
-

Cookie

-

The old section in this document was removed because of dwitte's cookies re-write. Please see: Cookies Preferences in Mozilla

-

代理

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
首选项名称Acceptable ValuesPreferences UI (in bold) and comments
network.proxy.type0 = direct
- 1 = manual
- 2 = PAC
- 3 = mapped to 0
- 4 = WPAD
Preferences | Advanced | Proxies
- Configure Proxies to Access the Internet
- ( ) Direct connection to the internet
- ( ) Auto-detect proxy settings (new in 1.8)
- ( ) Manual proxy configuration
- ( ) Automatic proxy configuration URL
-
- 3 was old Communicator value for DIRECT.
network.proxy.http<Protocol> Proxy: hostname or IPv4 is acceptable. IPv6 needs to be tested.
-
- Port: 0 will cause server:port preference for that manual proxy type to be ignored. 1-65xxx is valid range
Affects http: URLs
network.proxy.http_port
network.proxy.sslAffects https: URLs
- Possibly affects SIMAP and SNEWS
network.proxy.ssl_port
network.proxy.ftpAffects ftp: URLs
network.proxy.ftp_port
network.proxy.gopher {{ obsolete_inline("2.0") }}Affects gopher: URLs
network.proxy.gopher_port {{ obsolete_inline("2.0") }}
network.proxy.socksUsed when application-specific proxy is not configured. Possibly affects other protocols
network.proxy.socks_port
network.proxy.socks_version5 (default)
- 4
Communicator supported only SOCKS V4.
network.proxy.no_proxies_onlocalhost, 127.0.0.1 (default)
- string of comma delimited fqdn's, hostnames, IPv4 addresses and CDIR blocks. See No Proxy For configuration.
Localhost is not proxied by default, {{ Bug("31510") }}.
network.proxy.autoconfig_urlempty (default)
- URL string
must be absolute URl, no hostname
-

在线

- - - - - - - - - - - - - - - - - - -
Preference NameAcceptable ValuesPreferences UI (in bold) and comments
network.onlinetrue = Mozilla is online (default)
- false = Mozilla is offline
Necko updates the offline|online status to this value.
- Changing this value does not change the actual networking status.
- Value is not updated if "Ask me for online state at startup" was selected
- for the current profile ({{ Bug("229677") }}).
offline.startup_state0 = use network.online (default)
- 1 = prompt user
Preferences: Mail & Newsgroups | Offline | When starting up:
- (Pref affects all modules, but was moved from Pref root, {{ Bug("202529") }})
- {{ mediawiki.external('x') }} Remember previous online state
- (Uses network.online to set online|offline status at startup)
- {{ mediawiki.external(' ') }} Ask me for online state at startup
- (Unlike Communicator, prompt always appears, {{ Bug("239564") }})
-

Gopher(另请参见“代理”部分)

- - - - - - - - - - - - -
Preference NameAcceptable ValuesComments (bold for areas that user configures)
network.dir.formatsee FTP {{ obsolete_inline("2.0") }}
-

不推荐修改(Unsupported)

- - - - - - - - - - - - - - - - - - -
Preference NameAcceptable ValuesComments (bold for areas that user configures)
browser.xul.error.pages.enabledfalse (default)
- true
Does not appear in about.config unless added explicitly. See {{ Bug("28586") }})
network.protocol-handler.external.SCHEMEfalse (default)
- true
Mac+Windows: sends URLs of <SCHEME> to the default OS handler
- Linux/UNIX: sends URLs to application
- For example: network.protocol-handler.external.mailto==true is used by Phoenix/Firebird/Firefox to access default mailers.
- Handlers loaded before prefs are read cannot be redirected (e.g. file:)
-

 

-

已过时/已移除(此列表不全)

- -

Under Investigation

- -
-

原始文档信息

- -
-

{{ languages( { "ja": "ja/Mozilla_Networking_Preferences" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/browser.altclicksave/index.html b/files/zh-cn/mozilla/preferences/preference_reference/browser.altclicksave/index.html deleted file mode 100644 index e00172c42c..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/browser.altclicksave/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: browser.altClickSave -slug: Mozilla/Preferences/Preference_reference/browser.altClickSave -translation_of: Mozilla/Preferences/Preference_reference/browser.altClickSave ---- -

 browser.altClickSave 控制是否在按住alt键的同时点击链接执行下载动作.

- -

-
true
在按住alt键的同时点击链接执行下载该链接的动作.
false (默认)
无下载动作 (查看{{ bug("736985") }}).
-
-

{{ languages( { "en": "en/Mozilla/Preferences/Preference_reference/browser.altClickSave" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/browser.download.lastdir.savepersite/index.html b/files/zh-cn/mozilla/preferences/preference_reference/browser.download.lastdir.savepersite/index.html deleted file mode 100644 index e758aedb86..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/browser.download.lastdir.savepersite/index.html +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: browser.download.lastDir.savePerSite -slug: Mozilla/Preferences/Preference_reference/browser.download.lastDir.savePerSite -translation_of: Mozilla/Preferences/Preference_reference/browser.download.lastDir.savePerSite ---- -

browser.download.lastDir.savePerSite 控制是否为每个网站记忆上次下载文件时所选的保存目录. 如果设置为 true, 则数据将保存在 content preference.

- -

-
-
- true (默认)
-
- 该网站上次下载文件时用户所选的目录会被默认选择,如果是第一次在该网站下载文件,则会使用通用的 browser.download.lastDir 目录.
-
- false
-
- 下载文件时默认选择的目录会是通用的上次下载目录 ( browser.download.lastDir)
-
-

相关链接

- -

{{ languages( { "en": "en/Mozilla/Preferences/Preferences_reference/browser.download.lastDir.savePerSite" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/browser.search.context.loadinbackground/index.html b/files/zh-cn/mozilla/preferences/preference_reference/browser.search.context.loadinbackground/index.html deleted file mode 100644 index c80e03a840..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/browser.search.context.loadinbackground/index.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: browser.search.context.loadInBackground -slug: >- - Mozilla/Preferences/Preference_reference/browser.search.context.loadInBackground -translation_of: >- - Mozilla/Preferences/Preference_reference/browser.search.context.loadInBackground ---- -

browser.search.context.loadInBackground 控制右键菜单中的"通过<搜索引擎>搜索<选中文字>"打开新标签页后,立即激活该标签页,还是保持当前标签页状态不变.

- -

-
true
搜索页面在后台打开,保持当前标签页不变
false (默认)
搜索页面在前台打开(打开并激活).
-
-

{{ languages( { "en": "en/Mozilla/Preferences/Preference_reference/browser.search.context.loadInBackground" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/browser.urlbar.trimurls/index.html b/files/zh-cn/mozilla/preferences/preference_reference/browser.urlbar.trimurls/index.html deleted file mode 100644 index 2f57e03212..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/browser.urlbar.trimurls/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: browser.urlbar.trimURLs -slug: Mozilla/Preferences/Preference_reference/browser.urlbar.trimURLs -translation_of: Mozilla/Preferences/Preference_reference/browser.urlbar.trimURLs ---- -

browser.urlbar.trimURLs 控制是否隐藏地址栏中域名前面的http协议字段和域名后面紧跟的斜杠 (前提是地址栏中的域名必须是当前网页的域名) .

- -

-
true (默认值)
如果地址栏中的域名确实是当前网页的域名,那么顶级域名后面紧跟的斜杠会被隐藏.如果地址栏中的网址是以 http:// 协议开头且域名不以ftp. subdomain开头,也不包含@ (通常是ftp登陆信息)符号, 则这个http:// 前缀会被隐藏.

例如: https://www.example.org/ 会显示为 https://www.example.org, http://www.example.org/foobar 会显示为 www.example.org/foobar  http://ftp.example.org/foobar 保持不变.
false
显示完整的URL.
-
-

{{ languages( { "en": "en/Mozilla/Preferences/Preference_reference/browser.urlbar.trimURLs" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/dom.event.clipboardevents.enabled/index.html b/files/zh-cn/mozilla/preferences/preference_reference/dom.event.clipboardevents.enabled/index.html deleted file mode 100644 index cdff9ccd1a..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/dom.event.clipboardevents.enabled/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: dom.event.clipboardevents.enabled -slug: Mozilla/Preferences/Preference_reference/dom.event.clipboardevents.enabled -translation_of: Mozilla/Preferences/Preference_reference/dom.event.clipboardevents.enabled ---- -

dom.event.clipboardevents.enabled 控制,当用户在网页上执行复制,粘贴或者剪切动作时,是否触发 oncopy, oncutonpaste 事件.

- -

-
true (默认)
可以触发 oncopy, oncutonpaste 事件
false
不会触发 oncopy, oncutonpaste 事件
-
-

{{ languages( { "en": "en/Mozilla/Preferences/Preference_reference/dom.event.clipboardevents.enabled" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/index.html b/files/zh-cn/mozilla/preferences/preference_reference/index.html deleted file mode 100644 index f87f26f3cb..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/index.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Preference reference -slug: Mozilla/Preferences/Preference_reference -translation_of: Mozilla/Preferences/Preference_reference ---- -

{{ draft() }}

-

This is an automatically-generated list of subpages.

-

{{ListSubpages()}}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/javascript.options.strict/index.html b/files/zh-cn/mozilla/preferences/preference_reference/javascript.options.strict/index.html deleted file mode 100644 index 0719935e05..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/javascript.options.strict/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: javascript.options.strict -slug: Mozilla/Preferences/Preference_reference/javascript.options.strict -translation_of: Mozilla/Preferences/Preference_reference/javascript.options.strict ---- -

当代码执行时,如果这条语句没有发生运行时错误,但却是用了非标准的特性,写法有问题,可能导致隐含的逻辑错误,则会生成JavaScript警告信息.该选项就控制着这些警告信息是否要打印到JavaScript控制台上.

-

 

-

可用的值和对应的效果

-

True: 在错误控制台上显示JavaScript错误和警告.
-
- False: 在错误控制台上只显示JavaScript错误.(默认值)

-

 

-

相关链接: http://kb.mozillazine.org/Javascript.options.strict

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/ui.alertnotificationorigin/index.html b/files/zh-cn/mozilla/preferences/preference_reference/ui.alertnotificationorigin/index.html deleted file mode 100644 index 7221433f99..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/ui.alertnotificationorigin/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: ui.alertNotificationOrigin -slug: Mozilla/Preferences/Preference_reference/ui.alertNotificationOrigin -translation_of: Mozilla/Preferences/Preference_reference/ui.alertNotificationOrigin ---- -

ui.alertNotificationOrigin 控制由 nsIAlertsService 生成的弹出提示窗口向外滚动时的位置和方向.

- -

-
0
右下角,由下向上滑出
1
右下角, 由右向左滑出
2
左下角, 由下向上滑出
3
左下角, 由左向右滑出
4
右上角, 由上向下滑出
5
右上角, 由右向左滑出
6
左上角, 由上向下滑出
7
左上角, 由左向右滑出
-
-

{{ languages( { "en": "en/Mozilla/Preferences/Preference_reference/ui.alertNotificationOrigin" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/ui.spellcheckerunderline/index.html b/files/zh-cn/mozilla/preferences/preference_reference/ui.spellcheckerunderline/index.html deleted file mode 100644 index cbbb0e3961..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/ui.spellcheckerunderline/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: ui.SpellCheckerUnderline -slug: Mozilla/Preferences/Preference_reference/ui.SpellCheckerUnderline -translation_of: Mozilla/Preferences/Preference_reference/ui.SpellCheckerUnderline ---- -

ui.SpellCheckerUnderline 控制拼写检查器给不认识的单词所加的下划线的颜色.

- -

-
 颜色RGB值 例如 #ff0000 是红色.
-
-

{{ languages( { "en": "en/Mozilla/Preferences/Preference_reference/ui.SpellCheckerUnderline" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/ui.spellcheckerunderlinestyle/index.html b/files/zh-cn/mozilla/preferences/preference_reference/ui.spellcheckerunderlinestyle/index.html deleted file mode 100644 index 573e8ec36f..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/ui.spellcheckerunderlinestyle/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: ui.SpellCheckerUnderlineStyle -slug: Mozilla/Preferences/Preference_reference/ui.SpellCheckerUnderlineStyle -translation_of: Mozilla/Preferences/Preference_reference/ui.SpellCheckerUnderlineStyle ---- -

ui.SpellCheckerUnderlineStyle 控制拼写检查器给不认识的单词所加的下划线的样式.

- -

-

下面的值被定义在源代码 nsStyleConsts.h 中.

-
0
无下划线
1
点状线
2
虚线
3
单实线
4
双实线
5 (默认值)
波浪线
-
-

{{ languages( { "en": "en/Mozilla/Preferences/Preference_reference/ui.SpellCheckerUnderlineStyle" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/ui.tooltipdelay/index.html b/files/zh-cn/mozilla/preferences/preference_reference/ui.tooltipdelay/index.html deleted file mode 100644 index c92dd03248..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/ui.tooltipdelay/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: ui.tooltipDelay -slug: Mozilla/Preferences/Preference_reference/ui.tooltipDelay -translation_of: Mozilla/Preferences/Preference_reference/ui.tooltipDelay ---- -

{{ gecko_minversion_header("11.0") }}

-

ui.tooltipDelay 存储着一个单位为毫秒的时间数值,该数值表示鼠标停留在某个元素上多长时间后显示出提示信息.

- -

-
整数(单位为毫秒, 默认值: 500)
该数值表示鼠标停留在某个元素上多长时间后显示出提示信息,单位为毫秒,默认值为500ms.
-
-

{{ languages( { "zh-cn": "zh-cn/Mozilla/Preferences/Preference_reference/ui.tooltipDelay" } ) }}

diff --git a/files/zh-cn/mozilla/preferences/preference_reference/view_source.syntax_highlight/index.html b/files/zh-cn/mozilla/preferences/preference_reference/view_source.syntax_highlight/index.html deleted file mode 100644 index c09889f0be..0000000000 --- a/files/zh-cn/mozilla/preferences/preference_reference/view_source.syntax_highlight/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: view_source.syntax_highlight -slug: Mozilla/Preferences/Preference_reference/view_source.syntax_highlight -translation_of: Mozilla/Preferences/Preference_reference/view_source.syntax_highlight ---- -

This page was auto-generated because a user created a sub-page to this page.

diff --git a/files/zh-cn/mozilla/projects/crash_reporting/index.html b/files/zh-cn/mozilla/projects/crash_reporting/index.html deleted file mode 100644 index bb8fd91519..0000000000 --- a/files/zh-cn/mozilla/projects/crash_reporting/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Crash reporting -slug: Mozilla/Projects/Crash_reporting -tags: - - Crashes - - Developer Guide - - Developing Mozilla - - Firefox - - Mozilla - - NeedsTranslation - - QA - - TopicStub - - crash reports -translation_of: Mozilla/Projects/Crash_reporting ---- -

Firefox ships with an open-source crash reporting system. This system is combination of projects:

- - - -

Where did my crash get submitted?

- -

Crash data submitted using the Mozilla Crash Reporter is located on crash-stats. If you want to find a specific crash that you submitted, you first need to find the Crash ID that the server has assigned your crash. Type about:crashes into your location bar to get a page listing both submitted and unsubmitted crash reports. For more information, see How to get a stacktrace for a bug report.

- -

Reports and queries

- -

crash-stats has built-in reports of "topcrashes" for each release grouped by signature. There is also a custom query tool which allows users to limit searches on more precise information.

- -

For more automated usage, a summary of each day's crash reports is published as a CSV file, as well as batch analysis jobs. These can be found at https://crash-analysis.mozilla.com/crash_analysis/

- -

Finally, a set of Mozilla employees have access to directly query the underlying data in either SQL summary or using mapreduce on the storage cluster. If you are interested in obtaining this advanced access, contact Benjamin Smedberg.

- -

See also

- - diff --git a/files/zh-cn/mozilla/projects/emscripten/index.html b/files/zh-cn/mozilla/projects/emscripten/index.html deleted file mode 100644 index 9d488c2d8e..0000000000 --- a/files/zh-cn/mozilla/projects/emscripten/index.html +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Emscripten -slug: Mozilla/Projects/Emscripten -translation_of: Mozilla/Projects/Emscripten ---- -

Emscripten 是一个 LLVM (底层虚拟机)生成 JavaScript 的编译器. 它采用 LLVM 的字节码 (例如,使用 Clang 从 C/C++ 或者从其他语言生成的字节码) 并将其编译成可在 Web 上面运行的 JavaScript

- -
-

重要提示:本页简要介绍了 Emscripten 是什么。要开始使用 Emscripten请访问官方的Emscripten Wiki

-
- -

使用 Emscripten,你可以

- - - -

Emscripten 使原生代码可立即使用在 Web 上:是一个具有众多独立兼容的实现,可在从 PC 到 iPad 的任何地方运行的标准平台。

- -

借助 Emscripten,C / C ++ 开发人员无需手动将代码移植到 JavaScript 上,也无需学习 JavaScript。Web 开发人员也可以从中受益,因为他们可以在自己的站点中使用成千上万的已存在的原生实用程序和库。

- -

实际上,任何可移植的 C 或 C++ 代码库都可以通过 Emscripten 编译成 JavaScript,从需要渲染图形,播放声音,加载和处理文件的高性能游戏到诸如 Qt 的应用程序框架。

- -

Emscripten 生成的代码(其默认输出格式为 asm.js ,这是 JavaScript 的高度优化子集)在许多情况下可以以接近原生的速度执行。

- -
-

注意:听起来有趣吗? 阅读有关 Emscripten 的更多信息并尝试一些 demo,然后开始使用它

-
- -

MDN上其他有趣的文章

- - diff --git a/files/zh-cn/mozilla/projects/index.html b/files/zh-cn/mozilla/projects/index.html deleted file mode 100644 index c1e43934a2..0000000000 --- a/files/zh-cn/mozilla/projects/index.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Projects -slug: Mozilla/Projects -tags: - - Mozilla - - NeedsContent - - NeedsTranslation - - Projects - - TopicStub -translation_of: Mozilla/Projects ---- -

{{ draft() }}

-

Below you'll find links to documentation about various Mozilla projects; these are often parts of Firefox or other products, but may also be used in other projects as well.

-

{{ LandingPageListSubpages() }}

diff --git a/files/zh-cn/mozilla/projects/l20n/index.html b/files/zh-cn/mozilla/projects/l20n/index.html deleted file mode 100644 index ce256b741f..0000000000 --- a/files/zh-cn/mozilla/projects/l20n/index.html +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: L20n -slug: Mozilla/Projects/L20n -translation_of: Mozilla/Projects/L20n ---- -

当这个文档还是草案的时候, 请上 GitHub.

-
- 一个JavaScript本地化框架, 释放你的本地语言的魅力, 仅使用简单的代码.
-
-
-

Introducing L20n

-

L20n reinvents software localization. Users should be able to benefit from the entire expressive power of the natural language. L20n keeps simple things simple, and at the same time makes complex things possible.

-

Through L20n, Mozilla is creating a new generation of technology that places more power in localizers' hands. L20n lets localizers reach higher levels of free linguistic expression by sharpening the divide between localization and application logic. It allows to adapt your web application not only to languages and cultures, but also contextual data, user gender and screen dimensions.

-
-
-

What L20n looks like

-

Here is a simple, straightforward example showing an English string being provided:

-
<brandName "Firefox">
-<about "About \{{ brandName }}">
-

Here is the same string being provided in Slovenian:

-
<brandName {
-  nominative: "Firefox",
-  genitive: "Firefoxa",
-  dative: "Firefoxu",
-  accusative: "Firefox",
-  locative: "Firefoxu",
-  instrumental: "Firefoxom"
-}>
-<about "O \{{ brandName.locative }}">
-
-
-

 

-
-
-

For Developers

-

Documentation for developers wanting to implement localization functionality on their web apps using L20n.

-
-
- Internationalization for your web app
-
- First read for developers looking to use the L20n infrastructure.
-
- L20n's HTML bindings
-
- Tutorial on implementing L20n in your HTML code.
-
- L20n JavaScript API
-
- An API for l20n.js.
-
- L20n syntax cheatsheet for developers
-
- A simple cheatsheet to help developers as they add L20n to their localization infrastructure.
-
-
-
-

For Localizers

-

Documentation for Localizers creating localized content for a project that uses L20n.

-
-
- Learn the L20n syntax
-
- How to naturally localize applications using L20n. Complete with use cases and examples of L20n in action.
-
- Localization use-cases
-
- How to naturally localize applications using L20n. Complete with use cases and examples of L20n in action.
-
- L20n and Translation Memory eXchange (TMX)
-
- How L20n impacts the Translation Memory eXchange standard for translation memory data.
-
- L20n syntax cheatsheet for localizers
-
- A simple cheatsheet to help localizers as they localize projects with L20n.
-
-
-
- -

Some additional resources for developers and localizers involved with L20n.

-
-
- L20n.org
-
- You can try L20n live in your browser on the project page.
-
- L20n Tinker
-
- Test out your own L20n code in L20n Tinker.
-
- GitHub
-
- Where the main code for the L20n infrastructure and design spec lives.
-
- Wiki page
-
- Info about the project to develop L20n.
-
-
-
- -
    -
  1. For Developers -
      -
    1. Internationalization for your web app
    2. -
    3. L20n's HTML bindings
    4. -
    5. .lol file format
    6. -
    7. L20n syntax cheatsheet for developers
    8. -
    -
  2. -
  3. For Localizers -
      -
    1. Learn the L20n syntax
    2. -
    3. Localization use cases
    4. -
    5. L20n and Translation Memory eXchange (TMX)
    6. -
    7. L20n syntax cheatsheet for localizers
    8. -
    -
  4. -
  5. Additional resources -
      -
    1. L20n.org
    2. -
    3. L20n Tinker
    4. -
    5. L20n GitHub repo
    6. -
    7. Mozilla Wiki
    8. -
    -
  6. -
diff --git a/files/zh-cn/mozilla/projects/nspr/index.html b/files/zh-cn/mozilla/projects/nspr/index.html deleted file mode 100644 index 2ae2b7b9d5..0000000000 --- a/files/zh-cn/mozilla/projects/nspr/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: NSPR -slug: Mozilla/Projects/NSPR -translation_of: Mozilla/Projects/NSPR ---- -

Netscape Portable Runtime (NSPR)  提供一套面向系统级的与平台无关的 API  和类似于libc的函数. 这些API被用在Mozilla客户端, Red Hat公司、Sun公司的服务应用程序以及其他公司的一些软件中。

- - - - - - - -
-

文档

-
-
- NSPR工程页面
-
- Contains some older technical notes and training materials. (at mozilla.org)
-
-
-
- 关于 NSPR
-
- This topic describes, in general terms, the goals of NSPR and a bit about how it does it.
-
-
-
- NSPR API Reference
-
- The reference describes each API public macro, structure and function in the NSPR API.
-
-
-
- NSPR build instructions
-
- How to checkout and build from source.
-
-
-
- NSPR release process
-
- How to prepare an NSPR release.
-
-

View All...

-
-

Community

-
    -
  • View Mozilla forums...
  • -
-

{{ DiscussionList("dev-tech-nspr", "mozilla.dev.tech.nspr") }}

- -
-
- Necko, NSS
-
-
-

 

-

{{ languages( { "ja": "ja/NSPR", "it": "it/NSPR" } ) }}

diff --git a/files/zh-cn/mozilla/projects/nspr/reference/index.html b/files/zh-cn/mozilla/projects/nspr/reference/index.html deleted file mode 100644 index fe690af267..0000000000 --- a/files/zh-cn/mozilla/projects/nspr/reference/index.html +++ /dev/null @@ -1,770 +0,0 @@ ---- -title: NSPR API Reference -slug: Mozilla/Projects/NSPR/Reference -tags: - - NSPR - - NSPR_API_Reference - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Projects/NSPR/Reference ---- - - -

Introduction to NSPR

- - - -

NSPR Types

- - - -

Threads

- - - -

Process Initialization

- - - -

Locks

- - - -

Condition Variables

- - - -

Monitors

- - - -

Cached Monitors

- - - -

I/O Types

- - - -

I/O Functions

- - - -

Network Addresses

- - - -

Atomic Operations

- - - -

Interval Timing

- - - -

Date and Time

- - - -

Memory Management Operations

- - - -

String Operations

- - - -

Floating Point Number to String Conversion

- - - -

Long Long (64-bit) Integers

- -

BitMaps

- -

Formatted Printing

- -

Linked Lists

- - - -

Dynamic Library Linking

- - - -

Process Management and Interprocess Communication

- - - -

Multiwait Receive

- -

System Information and Environment Variables

- -

Logging

- - - -

Instrumentation Counters

- -

Named Shared Memory

- - - -

Anonymous Shared Memory

- - - -

IPC Semaphores

- - - -

Thread Pools

- - - -

Random Number Generator

- - - -

Hash Tables

- - - -

NSPR Error Handling

- - diff --git a/files/zh-cn/mozilla/projects/nspr/reference/memory_management_operations/index.html b/files/zh-cn/mozilla/projects/nspr/reference/memory_management_operations/index.html deleted file mode 100644 index 9fbb05ae70..0000000000 --- a/files/zh-cn/mozilla/projects/nspr/reference/memory_management_operations/index.html +++ /dev/null @@ -1,424 +0,0 @@ ---- -title: 内存管理操作 -slug: Mozilla/Projects/NSPR/Reference/Memory_Management_Operations -tags: - - GC - - NSPR -translation_of: Mozilla/Projects/NSPR/Reference/Memory_Management_Operations ---- - - -

本章介绍用于执行内存管理的全局函数和宏。NSPR 提供基于堆内存管理的函数,映射到熟悉的malloc(), calloc(), realloc(), 和 free().

- - - -

内存分配函数

- -

NSPR has its own heap, and these functions act on that heap. Libraries built on top of NSPR, such as the Netscape security libraries, use these functions to allocate and free memory. If you are allocating memory for use by such libraries or freeing memory that was allocated by such libraries, you must use these NSPR functions rather than the libc equivalents.

- -

Memory allocation functions are:

- - - -

PR_Malloc(), PR_Calloc(), PR_Realloc(), and PR_Free() have the same signatures as their libc equivalents malloc(), calloc(), realloc(), and free(), and have the same semantics. (Note that the argument type size_t is replaced by PRUint32.) Memory allocated by PR_Malloc(), PR_Calloc(), or PR_Realloc() must be freed by PR_Free().

- -

内存分配 Macros

- -

Macro versions of the memory allocation functions are available, as well as additional macros that provide programming convenience:

- - diff --git a/files/zh-cn/mozilla/projects/psm/index.html b/files/zh-cn/mozilla/projects/psm/index.html deleted file mode 100644 index 69fcd93234..0000000000 --- a/files/zh-cn/mozilla/projects/psm/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Personal Security Manager (PSM) -slug: Mozilla/Projects/PSM -translation_of: Mozilla/Projects/PSM ---- -

PSM全称为Personal Security Manager,包含了一套在客户应用程序上执行密码操作的代码库。这些操作包括设置SSL连接,对象签名和签名认证,证书管理(包括发行和废弃),和其它通用PKI函数。

- -

注意:

- - - -

 

diff --git a/files/zh-cn/mozilla/projects/rhino/bsf/index.html b/files/zh-cn/mozilla/projects/rhino/bsf/index.html deleted file mode 100644 index 8cf8b6c13e..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/bsf/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: BSF -slug: Mozilla/Projects/Rhino/BSF -translation_of: Mozilla/Projects/Rhino/BSF ---- -

BSF是什么?

-

Bean Scripting Framework (BSF)起初被IBM开发,后来作为Apache Software Foundation开源代码的一部分.它为Java上的大量的脚本语言提供了一个框架,Rhino是被支持的语言之一.

-

这个框架已被大量的开源项目嵌入代码中, 包括 XSL 处理器 Xalan 和  XML/Java 构建工具 Ant. 查看 Xalan-Java Extensions 可以获取更多关于把JavaScript添加至XSL、在Apache Ant Manual中使用脚本构建项目时脚本任务的命令项的描述等信息.

-

Using BSF with Rhino

-

Now that the Apache Jakarta Bean Scripting Framework (BSF), version 2.4.0, has been officially released, you can use Rhino easily with BSF. See http://jakarta.apache.org/bsf/index.html.

diff --git a/files/zh-cn/mozilla/projects/rhino/community/index.html b/files/zh-cn/mozilla/projects/rhino/community/index.html deleted file mode 100644 index 8d5c3a446c..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/community/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Rhino社区 -slug: Mozilla/Projects/Rhino/Community -translation_of: Mozilla/Projects/Rhino/Community ---- -

是否有在Rhino文档中找不到解答的问题?下面这些资源可以给你一些帮助:

- -

邮件列表

- -

在Google讨论组中有一个叫mozilla-rhino的讨论组,可以讨论Rhino相关的话题.

- -

还有一个比较老的讨论组叫mozilla.dev.tech.js-engine.rhino,已经很久没有维护了,请使用新的讨论组,但是这个老的组可能也包含一些比较有历史意义的讨论,可以去参考浏览一下.

- -

mozilla.dev.tech.js-engine这个讨论组讨论的是关于使用C语言实现的Javascript,也有在2007年9月27日之前关于Rhino的讨论.要看在2007年9月27日之前的讨论,请移步一个叫Google group for the earlier newsgroup的Google讨论组.

- -

Bug 系统

- -

最好的提交Rhino bug的方式是在Rhino的Github中提交.

- -

如果你愿意解决一些提交的Bug,我们非常欢迎您解决她,并提交一个pull请求.

- -

许多老的Rhino的问题都被记录在Bugzilla中.也许有一些比较有历史意义的bug. 最后注意Rhino有自己的产品类目.

- -

{{ languages( { "ja": "ja/Rhino_help" } ) }}

diff --git a/files/zh-cn/mozilla/projects/rhino/debugger/index.html b/files/zh-cn/mozilla/projects/rhino/debugger/index.html deleted file mode 100644 index 8b5ab147ca..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/debugger/index.html +++ /dev/null @@ -1,220 +0,0 @@ ---- -title: Rhino Debugger -slug: Mozilla/Projects/Rhino/Debugger -translation_of: Mozilla/Projects/Rhino/Debugger ---- -

The Rhino JavaScript debugger is a GUI that allows debugging of interpreted JavaScript scripts run in Rhino. Note that this debugger will not work with JavaScript scripts run in the mozilla browser since Rhino is not the engine used in such environments.

-

-

Current limitations:

- -

Using the Rhino JavaScript Debugger

-

The Mozilla Rhino JavaScript engine includes a source-level debugger for debugging JavaScript scripts. The debugger is itself a Java program which you may run as

-
java org.mozilla.javascript.tools.debugger.Main [options] [filename.js] [script-arguments]
-
-
-

where the options are the same as the shell.

-

The Rhino JavaScript Debugger can debug scripts running in multiple threads and provides facilities to set and clear breakpoints, control execution, view variables, and evaluate arbitrary JavaScript code in the current scope of an executing script.

-
-
- Console Window
-
- The debugger redirects the System.out, System.in, and System.err streams to an internal JavaScript console window which provides an editable command line for you to enter JavaScript code and view system output. The console window maintains a history of the commands you have entered. You may move backward and forward through the history list by pressing the Up/Down arrow keys on the keyboard.
-
- Opening Scripts
-
- You may select the - - File->Open - menu item on the menu bar to load JavaScript scripts contained in files. This action will display a file-selection dialog box prompting you for the location of a script to load. The selected file will be compiled and displayed in a new window.
-
- Running Scripts
-
- You may select the - - File->Run - menu item on the menu bar to execute JavaScript scripts contained in files. This action will display a file-selection dialog box prompting you for the location of a script to execute. The loaded script will be run in a new thread and control will be given to the debugger on its first instruction.
-
-

Controlling Execution

-

The debugger provides the following facilities for you to control the execution of scripts you are debugging:

-
-
- Step Into
-
- To single step entering any function calls, you may do any of the following: -
    -
  • Select the - - Debug->Step Into - menu item on the menu bar
  • -
  • Press the - - Step Into - button on the toolbar
  • -
  • Press the F11 key on the keyboard
  • -
-

Execution will resume. If the current line in the script contains a function call control will return to the debugger upon entry into the function. Otherwise control will return to the debugger at the next line in the current function.

-
-
- Step Over
-
- To single step to the next line in the current function, you may do any of the following: -
    -
  • Select the - - Debug->Step Over - menu item on the menu bar
  • -
  • Press the - - Step Over - button on the toolbar
  • -
  • Press the F7 key on the keyboard
  • -
-

Execution will resume but control will return to the debugger at the next line in the current function or top-level script.

-
-
- Step Out
-
- To continue execution until the current function returns you may do any of the following: -
    -
  • Select the - - Debug->Step Out - menu item on the menu bar
  • -
  • Press the - - Step Out - button on the toolbar
  • -
  • Press the F8 key on the keyboard
  • -
-

Execution will resume until the current function returns or a breakpoint is hit.

-
-
- Go
-
- To resume execution of a script you may do any of the following: -
    -
  • Select the - - Debug->Go - menu item on the menu bar
  • -
  • Press the - - Go - button on the toolbar
  • -
  • Press the F5 key on the keyboard
  • -
-

Execution will resume until a breakpoint is hit or the script completes.

-
-
- Break
-
- To stop all running scripts and give control to the debugger you may do any of the following: -
    -
  • Select the - - Debug->Break - menu item on the menu bar
  • -
  • Press the - - Break - button on the toolbar
  • -
  • Press the Pause/Break key on the keyboard
  • -
-
-
- Break on Exceptions
-
- To give control to the debugger whenever a JavaScript is exception is thrown select the - - Debug->Break on Exceptions - checkbox from the menu bar. Whenever a JavaScript exception is thrown by a script a message dialog will be displayed and control will be given to the debugger at the location the exception is raised.
-
- Break on Function Enter
-
- Selecting - - Debug->Break on Function Enter - will give control to the debugger whenever the execution is entered into a function or script.
-
- Break on Function Exit
-
- Selecting - - Debug->Break on Function Return - will give control to the debugger whenever the execution is about to return from a function or script.
-
- Moving Up and Down the Stack
-
- The lower-left (dockable) pane in the debugger main window contains a combo-box labeled "Context:" which displays the current stack of the executing script. You may move up and down the stack by selecting an entry in the combo-box. When you select a stack frame the variables and watch windows are updated to reflect the names and values of the variables visible at that scope.
-
- Setting and Clearing Breakpoints
-
- The main desktop of the debugger contains file windows which display the contents of each script you are debugging. You may set a breakpoint in a script by doing one of the following: -
    -
  • Place the cursor on the line at which you want to set a breakpoint and right-click with the mouse. This action will display a pop-up menu. Select the - - Set Breakpoint - menu item.
  • -
  • Simply single-click on the line number of the line at which you want to set a breakpoint.
  • -
-

If the selected line contains executable code a red dot will appear next to the line number and a breakpoint will be set at that location.

-

You may clear breakpoint in a script by doing one of the following:

-
    -
  • Place the cursor on the line at which you want to clear a breakpoint and right-click with the mouse. This action will display a pop-up menu. Select the - - Clear Breakpoint - menu item.
  • -
  • Simply single-click on the red dot or the line number of the line at which you want to clear a breakpoint.
  • -
-

The red dot will disappear and the breakpoint at that location will be cleared.

-
-
-

Viewing Variables

-

The lower-left (dockable) pane in the debugger main window contains a tab-pane with two tabs, labeled "this" and "Locals". Each pane contains a tree-table which displays the properties of the current object and currently visible local variables, respectively.

-
-
- This
-
- The properties of the current object are displayed in the - - this - table. If a property is itself a JavaScript object the property may be expanded to show its sub-properties. The - - this - table is updated each time control returns to the debugger or when you change the stack location in the - - Context: - window.
-
- Locals
-
- The local variables of the current function are displayed in the - - Locals - table. If a variable is itself a JavaScript object the variable may be expanded to show its sub-properties. The - - Locals - table is updated each time control returns to the debugger or when you change the stack location in the - - Context: - window
-
- Watch Window
-
- You may enter arbitrary JavaScript expressions in the - - Watch: - table located in the lower-right (dockable) pane in the debugger main window. The expressions you enter are re-evaluated in the current scope and their current values displayed each time control returns to the debugger or when you change the stack location in the - - Context: - window.
-
- Evaluation Window
-
- The - - Evaluate - pane located in the lower-right (dockable) pane in the debugger main window contains an editable command line where you may enter arbitrary JavaScript code. The code is evaluated in the context of the current stack frame. The window maintains a history of the commands you have entered. You may move backward or forward through the history by pressing the Up/Down arrow keys on the keyboard.
-
diff --git a/files/zh-cn/mozilla/projects/rhino/documentation/index.html b/files/zh-cn/mozilla/projects/rhino/documentation/index.html deleted file mode 100644 index 74ae49d94e..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/documentation/index.html +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Rhino 文档 -slug: Mozilla/Projects/Rhino/Documentation -translation_of: Mozilla/Projects/Rhino/Documentation ---- -

以下是面向 Rhino 脚本创作者和集成者的信息.

- -

概述

- -
-
简介
-
Rhino 和 JavaScript 的简介.
-
许可
-
Rhino 的许可信息.
-
依赖和局限
-
运行 Rhino 所需要的要件; 以及 Rhino 不能做什么.
-
发布存档
-
Rhino 的历史版本以及发行说明.
-
优化
-
优化级别的详细说明.
-
FAQ
-
针对 Rhino 的 FAQ.
-
Rhino 的历史
-
关于这只野兽(Rhino)的历史.
-
- -

撰写脚本

- -
-
在 Java 中撰写脚本
-
使用 Rhino 编写 Java 类的方法.
-
在 Java 中撰写脚本
-
使用 Rhino 编写 Java 类的方法. (旧版).
-
性能
-
撰写更高效的 JavaScript 的窍门.
-
- -

JavaScript 工具

- -
-
Rhino Shell
-
交互式或批处理式执行脚本.
-
JavaScript 调试器
-
调试执行于 Rhino 中的脚本.
-
JavaScript 编译器
-
将脚本编译成类文件.
-
运行Rhino测试
-
使用Rhino运行javascript单元测试.
-
- -

嵌入 Rhino

- -
-
嵌入教程
-
一个介绍如何将Rhino嵌入到你的应用程序的简短教程.
-
API Javadoc Reference (无法访问?  Try this at Jarvana.)
-
一个带有解释的Rhino编程api大纲(只有一些小提示).
-
Scopes and Contexts
-
描述如何在多线程环境中高效、灵活的使用scopes和contexts.
-
序列化
-
如何在Rhino中序列化javascript对象和函数.
-
运行时
-
一个对于javascrit运行时的简短介绍.
-
Small Footprint
-
对于那些热衷于小面积脚本嵌入(small-footprint embeddings)的人的提示.
-
例子
-
一些展示如何控制javascript引擎以及创建javascript宿主对象的例子.
-
Using Rhino with Bean Scripting Framework (BSF)
-
如何在支持BSF(Bean 脚本框架)的app中通过Apache Jakarta project使用Rhino.
-
- -

外部链接

- -
-
在java中使用的脚本语言
-
一篇将Rhino和Jython进行对比的文章.
-
- -

Rhino 贡献者

- -

有志于为 Rhino 贡献力量? 来看看 Rhino Wish List 吧.

diff --git a/files/zh-cn/mozilla/projects/rhino/download_rhino/index.html b/files/zh-cn/mozilla/projects/rhino/download_rhino/index.html deleted file mode 100644 index 54bf9966b8..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/download_rhino/index.html +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: 下载 Rhino -slug: Mozilla/Projects/Rhino/Download_Rhino -translation_of: Mozilla/Projects/Rhino/Download_Rhino ---- -

Rhino 同时提供源代码和已编译形式的下载.

- -

字节码文件

- -

Rhino 1.7R5 是最新的稳定发行版.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
发行版本发行时间变更日志下载链接
Rhino 1.7R42012-06-18New in Rhino 1.7R4rhino1_7R4.zip
Rhino 1.7R52015-01-29变更日志rhino1_7R5.zip
Rhino 1.7.62015-04-15变更日志rhino1.7.6.zip
Rhino 1.7.72015-06-17变更日志rhino1.7.7.zip
Rhino 1.7.7.12016-02-01变更日志rhino1.7.7.1.zip
Rhino 1.7.7.22017-08-24变更日志rhino1.7.7.2.zip
Rhino 1.7.82018-01-22变更日志rhino1.7.8.zip
Rhino 1.7.92018-03-15变更日志rhino1.7.9.zip
Rhino 1.7.102018-04-09变更日志rhino1.7.10.zip
Rhino 1.7.112019-05-30变更日志rhino1.7.11.zip
Rhino 1.7.122020-01-13变更日志rhino1.7.12.zip
- -

下载较旧版本的Rhino,可以参考 Rhino 下载存档.

- -

许可

- -

Rhino 是开源的, 从 1.7R4 开始以 MPL 2.0 许可.

- -

在此之前的版本遵循 MPL 1.1/GPL 2.0 许可.

- -

参考更详细的 Rhino 许可证 信息.

- -

源代码

- -

除了从上面zip文件获取源外,Rhino 的源代码可以在GitHub上的https://github.com/mozilla/rhino找到。 要获取源,使用命令

- -
$ git clone https://github.com/mozilla/rhino.git
-
- -

Rhino 使用 Ant 作为它的构建系统.。在Rhino分配的顶级目录运行 ant 命令将打印打印可构建目标的清单。

diff --git a/files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html b/files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html deleted file mode 100644 index b7cf0168f5..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/embedding_tutorial/index.html +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: 'Tutorial: Embedding Rhino' -slug: Mozilla/Projects/Rhino/Embedding_tutorial -translation_of: Mozilla/Projects/Rhino/Embedding_tutorial ---- -

Embedding Rhino can be done simply with good results. With more effort on the part of the embedder, the objects exposed to scripts can be customized further.

-

This tutorial leads you through the steps from a simple embedding to more customized, complex embeddings. Fully compilable examples are provided along the way.

-

The examples live in the rhino/examples directory in the distribution and in mozilla/js/rhino/examples in cvs. This document will link to them using lxr.

-

In this document, JavaScript code will be in green, Java code will be in green, and shell logs will be in purple.

-

In this document:

- -

RunScript: A simple embedding

-

About the simplest embedding of Rhino possible is the RunScript example. All it does it read a script from the command line, execute it, and print a result.

-

Here's an example use of RunScript from a shell command line:

-
$ java RunScript "Math.cos(Math.PI)"
--1
-$ java RunScript "function f(x){return x+1} f(7)"
-8
-
-

Note that you'll have to have both the Rhino classes and the RunScript example class file in the classpath. Let's step through the body of main one line at time.

-

Entering a Context

-

The code

-
Context cx = Context.enter();
-
-

Creates and enters a Context. A Context stores information about the execution environment of a script.

-

Initializing standard objects

-

The code

-
Scriptable scope = cx.initStandardObjects();
-
-

Initializes the standard objects (Object, Function, etc.) This must be done before scripts can be executed. The null parameter tells initStandardObjects to create and return a scope object that we use in later calls.

-

Collecting the arguments

-

This code is standard Java and not specific to Rhino. It just collects all the arguments and concatenates them together.

-
String s = "";
-for (int i=0; i < args.length; i++) {
-    s += args[i];
-}
-
-

Evaluating a script

-

The code

-
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
-
-

uses the Context cx to evaluate a string. Evaluation of the script looks up variables in scope, and errors will be reported with the filename <cmd> and line number 1.

-

Printing the result

-

The code

-
System.out.println(cx.toString(result));
-
-

prints the result of evaluating the script (contained in the variable result). result could be a string, JavaScript object, or other values. The toString method converts any JavaScript value to a string.

-

Exiting the Context

-

The code

-
} finally {
-    Context.exit();
-}
-
-

exits the Context. This removes the association between the Context and the current thread and is an essential cleanup action. There should be a call to exit for every call to enter. To make sure that it is called even if an exception is thrown, it is put into the finally block corresponding to the try block starting after Context.enter().

-

Expose Java APIs

-

Using Java APIs

-

No additional code in the embedding needed! The JavaScript feature called - - LiveConnect - allows JavaScript programs to interact with Java objects:

-
$ java RunScript "java.lang.System.out.println(3)"
-3.0
-undefined
-
-

Implementing interfaces

-

Using Rhino, JavaScript objects can implement arbitrary Java interfaces. There's no Java code to write -- it's part of Rhino's LiveConnect implementation. For example, we can see how to implement java.lang.Runnable in a Rhino shell session:

-
js> obj = { run: function() { print("hi"); } }
-[object Object]
-js> obj.run()
-hi
-js> r = new java.lang.Runnable(obj);
-[object Object]
-js> t = new java.lang.Thread(r)
-Thread[Thread-0,5,main]
-js> t.start()
-hi
-
-

Adding Java objects

-

The next example is RunScript2. This is the same as RunScript, but with the addition of two extra lines of code:

-
Object wrappedOut = Context.javaToJS(System.out, scope);
-ScriptableObject.putProperty(scope, "out", wrappedOut);
-
-

These lines add a global variable out that is a JavaScript reflection of the System.out variable:

-
$ java RunScript2 "out.println(42)"
-42.0
-undefined
-
-

Using JavaScript objects from Java

-

After evaluating a script it's possible to query the scope for variables and functions, extracting values and calling JavaScript functions. This is illustrated in the RunScript3 example. This example adds the ability to print the value of variable x and the result of calling function f. Both x and f are expected to be defined by the evaluated script. For example,

-
$ java RunScript3 "x = 7"
-x = 7
-f is undefined or not a function.
-$ java RunScript3 "function f(a) { return a; }"
-x is not defined.
-f("my args") = my arg
-
-

Using JavaScript variables

-

To print out the value of x, we add the following code:

-
Object x = scope.get("x", scope);
-if (x == Scriptable.NOT_FOUND) {
-    System.out.println("x is not defined.");
-} else {
-    System.out.println("x = " + Context.toString(x));
-}
-
-

Calling JavaScript functions

-

To get the function f, call it, and print the result, we add this code:

-
Object fObj = scope.get("f", scope);
-if (!(fObj instanceof Function)) {
-    System.out.println("f is undefined or not a function.");
-} else {
-    Object functionArgs[] = { "my arg" };
-    Function f = (Function)fObj;
-    Object result = f.call(cx, scope, scope, functionArgs);
-    String report = "f('my args') = " + Context.toString(result);
-    System.out.println(report);
-}
-
-

JavaScript host objects

-

Defining Host Objects

-

Custom host objects can implement special JavaScript features like dynamic properties.

-

Counter example

-

The Counter example is a simple host object. We'll go through it method by method below.

-

It's easy to try out new host object classes in the shell using its built-in defineClass function. We'll see how to add it to RunScript later. (Note that because the java -jar option preempts the rest of the classpath, we can't use that and access the Counter class.)

-
$ java -cp "js.jar;examples" org.mozilla.javascript.tools.shell.Main
-js> defineClass("Counter")
-js> c = new Counter(7)
-[object Counter]
-js> c.count
-7
-js> c.count
-8
-js> c.count
-9
-js> c.resetCount()
-js> c.count
-0
-
-

Counter's constructors

-

The zero-argument constructor is used by Rhino runtime to create instances. For the counter example, no initialization work is needed, so the implementation is empty.

-
public Counter () { }
-
-

The method jsConstructor defines the JavaScript constructor that was called with the expression new Counter(7) in the JavaScript code above.

-
public void jsConstructor(int a) { count
-= a; }
-
-

Class name

-

The class name is defined by the getClassName method. This is used to determine the name of the constructor.

-
public String getClassName() { return "Counter";
-}
-
-

Dynamic properties

-

Dynamic properties are defined by methods beginning with jsGet_ or jsSet_. The method jsGet_count defines the - - count - property.

-
public int jsGet_count() { return count++;
-}
-
-

The expression c.count in the JavaScript code above results in a call to this method.

-

Defining JavaScript "methods"

-

Methods can be defined using the jsFunction_ prefix. Here we define resetCount for JavaScript.

-
public void jsFunction_resetCount() { count
-= 0; }
-
-

The call c.resetCount() above calls this method.

-

Adding Counter to RunScript

-

Now take a look at the RunScript4 example. It's the same as RunScript except for two additions. The method ScriptableObject.defineClass uses a Java class to define the Counter "class" in the top-level scope:

-
ScriptableObject.defineClass(scope, Counter.class);
-
-

Now we can reference the Counter object from our script:

-
$ java RunScript4 "c = new Counter(3); c.count;
-c.count;"
-
-

It also creates a new instance of the Counter object from within our Java code, constructing it with the value 7, and assigning it to the top-level variable myCounter:

-
Object[] arg = { new Integer(7) };
-Scriptable myCounter = cx.newObject(scope, "Counter", arg);
-scope.put("myCounter", scope, myCounter);
-
-

Now we can reference the myCounter object from our script:

-
$ java RunScript3 'RunScript4 'myCounter.count; myCounter.count'
-8
-
diff --git a/files/zh-cn/mozilla/projects/rhino/examples/index.html b/files/zh-cn/mozilla/projects/rhino/examples/index.html deleted file mode 100644 index 087697b94a..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/examples/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Rhino Examples -slug: Mozilla/Projects/Rhino/Examples -translation_of: Mozilla/Projects/Rhino/Examples ---- -
-  
-

-

Examples have been provided that show how to control the JavaScript engine and how  to implement scriptable host objects. All the examples are in the git tree at mozilla/js/rhino/examples.

-

Sample Scripts

-

The unique.js script allows printing unique lines from a file.

-

The liveConnect.js script shows a sample usage of LiveConnect (Java-to-JavaScript connectivity).

-

The jsdoc.js script is a JavaScript analog to Java's javadoc. It makes heavy use of regular expressions.

-

The checkParam.js script is a useful tool to check that @param tags in Java documentation comments match the parameters in the corresponding Java method.

-

The enum.js script is a good example of using a JavaAdapter to implement a Java interface using a JavaScript object.

-

The NervousText.js script is a JavaScript implementation of the famous NervousText applet using JavaScript compiled to Java classes using jsc. It can be run in the HTML page NervousText.html.

-

Controlling the JavaScript Engine

-

The RunScript class

-

RunScript.java is a simple program that executes a script from the command line.

-

The Control class

-

Control.java is a program that executes a simple script and then manipulates the result.

-

JavaScript Shell

-

Shell.java is a program that executes JavaScript programs; it is a simplified version of the shell in the tools package. The programs may be specified as files on the command line or by typing interactively while the shell is running.

-

PrimitiveWrapFactory

-

PrimitiveWrapFactory.java is an example of a WrapFactory that can be used to control the wrapping behavior of the Rhino engine on calls to Java methods.

-

Multithreaded Script Execution

-

DynamicScopes.java is a program that creates a single global scope object and then shares it across multiple threads. Sharing the global scope allows both information to be shared across threads, and amortizes the cost of Context.initStandardObjects by only performing that expensive operation once.

-

Implementing Host Objects

-

First check out the tutorial if you haven't already.

-

The Foo class - Extending ScriptableObject

-

Foo.java is a simple JavaScript host object that includes a property with an associated action and a variable argument method.

-

The Matrix class - Implementing Scriptable

-

Matrix.java provides a simple multidimensional array by implementing the Scriptable interface.

-

The File class - An advanced example

-

File.java extends ScriptableObject to provide a means of reading and writing files from JavaScript. A more involved example of host object definition.

diff --git a/files/zh-cn/mozilla/projects/rhino/index.html b/files/zh-cn/mozilla/projects/rhino/index.html deleted file mode 100644 index 86818aa172..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Rhino -slug: Mozilla/Projects/Rhino -translation_of: Mozilla/Projects/Rhino ---- -

Image:rhino.jpg

- -

Rhino 是一个完全使用Java语言编写的开源JavaScript实现。Rhino通常用于在Java程序中,为最终用户提供脚本化能力。它被作为J2SE 6上的默认Java脚本化引擎。

- -

Rhino 下载

- -

如何 获取源码和二进制文件

- -

Rhino 文档

- -

为脚本编写者和嵌入者提供的 一些Rhino信息.

- -

Rhino 帮助

- -

如果你被卡住了,可以参考 这里的一些资源.

- -

{{ languages( { "zh-cn": "zh-cn/Rhino" } ) }}

diff --git a/files/zh-cn/mozilla/projects/rhino/license/index.html b/files/zh-cn/mozilla/projects/rhino/license/index.html deleted file mode 100644 index 035688ed65..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/license/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Rhino license -slug: Mozilla/Projects/Rhino/License -translation_of: Mozilla/Projects/Rhino/License ---- -

Rhino is available under open source licenses.

- -

MPL/GPL License

- -

The majority of the source code for Rhino is available under a MPL 1.1/GPL 2.0 license.

- -

License for portions of the Rhino debugger

- -

Additionally, some files (currently the contents of toolsrc/org/mozilla/javascript/tools/debugger/treetable/) are available under the following license:

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

Norrisboyd 06:16, 14 April 2008 (PDT)

diff --git a/files/zh-cn/mozilla/projects/rhino/overview/index.html b/files/zh-cn/mozilla/projects/rhino/overview/index.html deleted file mode 100644 index ba6a9aaa18..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/overview/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Rhino overview -slug: Mozilla/Projects/Rhino/Overview -translation_of: Mozilla/Projects/Rhino/Overview ---- -

简介

- -

大多数用过 JavaScript 的人都是将js脚本放入HTML页面中使用。然而, Rhino 仅仅是对javascript核心部分的实现,并没有包含操作HTML的对象或方法。

- -

Rhino 包括

- - - -

语言

- -

JavaScript 的标准是 Standard ECMA-262 ECMAScript: A general purpose, cross-platform programming language. Rhino 1.3 及以上版本遵照上述标准的第3版。

- -

Rhino 1.6 及以上版本实现了 ECMA-357 ECMAScript for XML (E4X) 标准. 查看详细的规格说明可以获得更多的信息,查看 Rhino version 1.6R1 release notes 可以看到Rhino对标准实现的具体情况。

- -

此外,Rhino实现了JavaAdapters,这样我们可以用一个JavaScript对象来实现任何java的接口或者继承任何java的类。查看下载文件中example文件夹中的enum.js获取更多的信息。.

- -

有很多JavaScript的书和教程。 我们推荐JavaScript: The Definitive Guide 这本书,里面有一章是说Rhino的。

- -

废弃的语言特性

- -

很多在JavaScript 1.2中定义的特性已经被废弃了. 这些特性允许“计算反射”:可以决定和影响它被评价方法等方面的能力。 这些特性没有被广泛使用,他们对阻碍和防止优化的行为强加了重要的约束。 这些被废弃的特性是 __proto__ 和 __parent__ 属性, 还有构造函数 With,、ClosureCall。在JavaScript 1.4中使用这些特性会产生错误。在其他的版本中使用这些特性,会产生警告。

- -

国际化

- -

The messages reported by the JavaScript engine are by default retrieved from the property file org/mozilla/javascript/resources/Messages.properties. If other properties files with extensions corresponding to the current locale exist, they will be used instead.

- -

JavaScript语言版本

- -

JavaScript引擎的很多行为与语言的版本有关。在浏览器调用中,JavaScript版本的选择是通过script标签中的LANGUAGE属性定义的,比如"JavaScript1.2"。

- -

1.3 和更高版本是ECMA一致的。

- -

操作符 ==  和 !=

- -

1.2版本用 == 和 != 来处理绝对相等的问题。 在1.3或更高的版本里, == 和 != 和ECMA中所描述的一样。 操作符 === and !== 在所有版本中都表示绝对相等。

- -

布尔转换

- -

1.3之前的所有版本Boolean(new Boolean(false)) 值为false 。在1.3及1.3之后,它的值为true。

- -

Array.prototype.toString 和 Object.prototype.toString

- -

1.2版本只是返回数组或对象的文字符号 (比如"{{ mediawiki.external(1,2,3) }}" or "{a:1, b:2}" )。 在1.3或更高版本中这些函数与ECMA标准一致。

- -

Array 构造函数

- -

只有在1.2版本中,Array(i) 用一个参数i构造一个只有一个元素且元素的值为i的数组。 在其他版本中,使用和ECMA一致的标准 (一个没有元素的数组被构造,长度为i)。

- -

String.prototype.substring

- -

只有在1.2版本中, 如果第一个参数小于第二个参数,两个参数不会互换。其他的版本都符合ECMA标准。

- -

String.prototype.split

- -

只有对1.2版本,split按照Perl4的特例当用一个单独的空格字符作参数时, (跳过最先的空白,用空白分割). 其他的版本完全按照ECMA的标准分割。

- -

安全

- -

Rhino的安全特性提供了找到代码片段的来源的功能 (还有任何会轮流产生的代码片段)。这些特性考虑到了传统的基于URL的安全策略(在网景领航员中的JavaScript)的实现。执行信任的JavaScript代码时可以不考虑安全性特征。

- -

运行不被信任的JavaScript代码时,需要做两件事来保证安全性。第一,每一个被创建的Context必须被提供一个实现SecuritySupport接口的实例。 这样在功能上给Rhino提供了让它执行安全相关任务的支持。

- -

第二, security.requireSecurityDomain属性的值应该被改为true在资源束bundle org.mozilla.javascript.resources.Security中. 这个属性的值可以在运行时通过调用ContextisSecurityDomainRequired方法来决定。将这个属性设置为ture,要求任何编译或评估JavaScript的调用必须提供一个安全区域对象(任意类型),用来标识JavaScript代码。在一个典型的客户端嵌入中,这个对象可能是提供javascript的服务器的URL,或者是一个包含代码片段的签发人的代表(用于基于证书的安全策略)。

- -

当JavaScript代码想要执行一个受限制的行为时,安全区域会被后面的方法检索。类上下文会从安全管理(java.lang.SecurityManager.getClassContext())中得到。执行限制行为的代码对应的类 可以通过寻找一个在类上下文中合适的位置得到。如果调用者是JavaScript,得到的类可能是一种或两种类型。首先,它可能是解释器(如果解释器模式有效)。第二,它有可能是一个生成的类,如果类文件生成支持。一个植入可以区分两种情况,通过调用在Context Class中调用isInterpreterClass()。 如果是解释器类,调用Context的getInterpreterSecurityDomain() 方法来获取当前正在执行的被解释的脚本或方法的安全区域。否则,就是一个生成的类,一个嵌入可以调用在实现SecuritySupport的类中调用getSecurityDomain()。当类被定义而且被打开,恰当的安全区域和它建立关联,而且可以通过调用这个方法找回。一旦安全区域被决定,一个植入可以执行任何检查者适合去决定是否允许去做的操作。

- -

{{ languages( { "ja": "ja/Rhino_Overview" } ) }}

diff --git a/files/zh-cn/mozilla/projects/rhino/requirements_and_limitations/index.html b/files/zh-cn/mozilla/projects/rhino/requirements_and_limitations/index.html deleted file mode 100644 index 8a159ae843..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/requirements_and_limitations/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Rhino requirements and limitations -slug: Mozilla/Projects/Rhino/Requirements_and_Limitations -translation_of: Mozilla/Projects/Rhino/Requirements_and_Limitations ---- -

Requirements

-

Recent versions of Rhino have only been tested with JDK 1.4 and greater. Older versions support JDKs as early as 1.1.

-

To use the JavaAdapter feature or an optimization level of 0 or greater, Rhino must be running under a security manager that allows the definition of class loaders.

-

Limitations

-

LiveConnect

-

If a JavaObject's field's name collides with that of a method, the value of that field is retrieved lazily, and can be counter-intuitively affected by later assignments:

-
javaObj.fieldAndMethod = 5;
-var field = javaObj.fieldAndMethod;
-javaObj.fieldAndMethod = 7;
-// now, field == 7
-
-

You can work around this by forcing the field value to be converted to a JavaScript type when you take its value:

-
javaObj.fieldAndMethod = 5;
-var field = javaObj.fieldAndMethod + 0; // force conversion now
-javaObj.fieldAndMethod = 7;
-// now, field == 5
-
-

JSObject

-

Rhino does NOT support the netscape.javascript.JSObject class.

diff --git a/files/zh-cn/mozilla/projects/rhino/scripting_java/index.html b/files/zh-cn/mozilla/projects/rhino/scripting_java/index.html deleted file mode 100644 index 013ad3aa89..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/scripting_java/index.html +++ /dev/null @@ -1,397 +0,0 @@ ---- -title: Scripting Java -slug: Mozilla/Projects/Rhino/Scripting_Java -translation_of: Mozilla/Projects/Rhino/Scripting_Java ---- -

这篇文章描述了如何在rhino中使用java。使用脚本调用Java有很多用途,它使得我们可以利用Java中现有的库,来帮助我们构建强大的脚本。我们可以通过编写脚本,来对Java程序进行测试。可以通过脚本来进行探索式编程,辅助Java的开发,所谓探索式编程,就是通过快速地编程调用库或API来探索这些库或API可以做什么,显而易见,脚本语言很适合探索式编程。

- -

这里注意,ECMA标准并没有包含和Java(或者其他任何对象系统)交互的标准。本文所描述的所有内容,应该被认为是一个扩展。

- - - -

访问 Java Packages 和 Classes

- -

Java的每段代码都是类的一部分,每一个JAVA类都是包的一部分。在Javascript中,脚本不属于任何package。我们可以访问Java包中的类么?

- -

Rhino定义了一个顶层的变量Packages。Packages的所有属性都是Java中顶层的包,比如java和com。比如我们可以访问java包:

- -
js> Packages.java
-[JavaPackage java]
- -

还有一种更方便的方式,Rhino定义了一个顶层的变量java,等价于Packages.java。所以上面的例子可以更简介地写成:

- -
js> java
-[JavaPackage java]
-
- -

我们可以通过访问包的下层,来直接访问java类:

- -
js> java.io.File
-[JavaClass java.io.File]
-
- -

如果你的脚本需要访问很多的Java类,每次都附带完整的包名会使得编程很麻烦。Rhino提供了一个顶层的方法importPackage,它的功能和Java的import一样。比如,我们可以导入java.io包中的所有类,然后直接通过类名File来访问java.io.File:

- -
js> importPackage(java.io)
-js> File
-[JavaClass java.io.File]
-
- -

这里importPackage(java.io)使得java.io包中的所有类(例如File)可以在顶层被访问。这和Java中的java.io.*;等价。

- -

要注意Java会暗中导入java.lang.*,但是Rhino不会。因为JavaScript的顶层对象Boolean、Math、Number、Object和String和java.lang包中同名的类并不相同。因为这种冲突,建议不要用importPackage来导入java.lang包。

- -

有一点要注意的,就是Rhino对于指定包名或类名时是如何处理错误的。如果java.Myclass是可访问的,Rhino会试图加载名为java.MyClass的类,如果加载失败,它会假设java.MyClass是一个包名,不会报错:

- -
js> java.MyClass
-[JavaPackage java.MyClass]
-
- -

只有在你试图将这个对象当作类使用时,才会报错。

- -

额外的包和类

- -

额外的包和类也可以在Rhino中使用。确认你的.jar或.class文件在你的classpath里,你就可以在你的JavaScript应用中导入它们。这些包基本不会在java包中,所以你在使用时,需要在包前加上前缀"Packages"。 比如你想导入 org.mozilla.javascript 包,你应该像下面这样去使用importPackage():

- -
$ java org.mozilla.javascript.tools.shell.Main
-js> importPackage(Packages.org.mozilla.javascript);
-js> Context.currentContext;
-org.mozilla.javascript.Context@bb6ab6
-
- -

偶尔,我们也会见到在一些例子中使用包的完整名称,而没有使用importPackage()。这也是可以的,只是会让你多打一些字。如果使用完整的名称,上面的例子就会变成下面这样:

- -
$ java org.mozilla.javascript.tools.shell.Main
-js> jsPackage = Packages.org.mozilla.javascript;
-[JavaPackage org.mozilla.javascript]
-js> jsPackage.Context.currentContext;
-org.mozilla.javascript.Context@bb6ab6
-
- -

同样,你可以通过importClass()来导入一个类,上面的例子也可以像这样写:

- -
$ java org.mozilla.javascript.tools.shell.Main
-js> importClass(Packages.org.mozilla.javascript.Context);
-js>  Context.currentContext;
-org.mozilla.javascript.Context@bb6ab6
- -

和Java一起工作

- -

现在我们可以访问Java类,下一步就是要创建一个对象。方法就和在Java中一样, 用new来创建对象:

- -
js> new java.util.Date()
-Thu Jan 24 16:18:17 EST 2002
-
- -

如果我们将创建的对象存放在JavaScript变量中,我们可以调用它的方法:

- -
js> f = new java.io.File("test.txt")
-test.txt
-js> f.exists()
-true
-js> f.getName()
-test.txt
-
- -

静态方法和属性可以直接通过类对象来访问:

- -
js> java.lang.Math.PI
-3.141592653589793
-js> java.lang.Math.cos(0)
-1
-
- -

不像Java,在JavaScript里,方法就是一个对象。它可以被评估,也可以被调用。如果我们去查看这个方法,我们可以看到这个方法所有重载的形式:

- -
js> f.listFiles
-function listFiles() {/*
-java.io.File[] listFiles()
-java.io.File[] listFiles(java.io.FilenameFilter)
-java.io.File[] listFiles(java.io.FileFilter)
-*/}
-
- -

输出告诉我们,File类有listFiles方法的三种重载:一种不包含参数的,另一种包含一个FilenameFilter类型的参数,第三个包含一个FileFilter类型的参数。所有的方法都返回一个File对象数组。可以观察到Java方法的参数和返回类型在探索式编程中是非常有用的,尤其是在对一个方法的参数和返回对象不确定的时候。

- -

另一个有助于探索式编程的特性,是可以看到对象中定义的所有方法和属性。用JavaScript的for..in , 我们可以打印这些值:

- -
js> for (i in f) { print(i) }
-exists
-parentFile
-mkdir
-toString
-wait
-[44 others]
-
- -

注意这里不仅列出了File类中的所有方法,也列出了从基类java.lang.Object中继承的方法,例如wait。这使得我们可以更好地处理那些有复杂继承关系的对象,因为我们可以看到对象中所有可用的方法。

- -

Rhino可以通过属性名来方便地访问JavaBean的属性。一个JavaBean的属性foo被方法getFoo和setFoo定义,另外,一个也叫foo的boolean类型的属性,可以被isFoo来定义。比如, 下面的代码实际上调用了File对象的getName和isDirectory方法。

- -
js> f.name
-test.txt
-js> f.directory
-false
-
- -

调用重载方法

- -

 根据参数类型选择调用方法的过程称为重载决议。在 Java 中, 重载决议在编译时执行, 而在rhino中则在运行时发生。这种差异是不可避免的, 因为 JavaScript 使用动态类型, 在2章中: 由于变量的类型直到运行时才知道, 才会发生重载决议。

- -
-
例如, 请查看下面的 Java 类, 它定义了许多重载方法并调用它们。 
-
- - - -
public class Overload {
-
-    public String f(Object o) { return "f(Object)"; }
-    public String f(String s) { return "f(String)"; }
-    public String f(int i)    { return "f(int)"; }
-
-    public String g(String s, int i) { return "g(String,int)"; }
-    public String g(int i, String s) { return "g(int,String)"; }
-
-    public static void main(String[] args) {
-        Overload o = new Overload();
-        Object[] a = new Object[] { new Integer(3), "hi", Overload.class };
-        for (int i = 0; i != a.length; ++i)
-            System.out.println(o.f(a[i]));
-    }
-}
-
- -

当我们编译和执行程序, 它产生输出

- -
f(Object)
-f(Object)
-f(Object)
-
- -

但是, 如果我们编写一个类似的脚本

- -
var o = new Packages.Overload();
-var a = [ 3, "hi", Packages.Overload ];
-for (var i = 0; i != a.length; ++i)
-    print(o.f(a[i]));
-
- -

并且运行它,将会输出

- -
f(int)
-f(String)
-f(Object)
-
- -

因为Rhino在运行时选择重载方法, 所以它会调用与该参数匹配的更具体的类型。 同时, 在编译时, Java 只在参数的类型上选择重载方法。

- -

尽管这有利于选择一种方法,这种方法可能是每个调用的更好匹配,但它确实对性能有影响,因为每次调用时都要做更多的工作。事实上,这种性能代价在实际应用中并不明显。

- -

因为重载决议发生在运行时,它可能在运行时失败。例如,如果我们用两个整数调用重载方法g,我们就会得到一个错误,因为方法的两个形式都比另一个更接近参数类型:

- -
js> o.g(3,4)
-js:"<stdin>", line 2: The choice of Java method Overload.g
-matching JavaScript argument types (number,number) is ambiguous;
-candidate methods are:
-class java.lang.String g(java.lang.String,int)
-class java.lang.String g(int,java.lang.String)
-
- -

http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html 提供了一个更精确的重载语义定义

- -

  实现Java接口

- - - -

现在我们可以访问Java类,创建Java对象,并访问这些对象的字段、方法和属性,我们就可以轻松掌握大量的功能。但是,在少数情况下是不够用的:Java中的很多API通过提供客户端必须实现的接口来工作。其中一个例子就是Thread类:其构造函数Runnable包含一个run方法,这个方法在新线程启动时被调用。

- -

为了满足这种需求,Rhino提供了创建新的Java对象实现的接口的能力。首先,我们必须定义一个JavaScript对象,其中的函数属性的名称与Java接口所需的方法名称相匹配。要实现一个Runnable ,我们只需要定义一个不带参数的run单方法。如果你还记得第3章,可以用{ propertyName: value}符号定义一个JavaScript对象。我们可以在这里结合函数表达式使用这个语法来用一个 run方法定义一个JavaScript对象:

- -
js> obj = { run: function () { print("\nrunning"); } }
-[object Object]
-js> obj.run()
-
-running
-
- - - -

现在我们可以通过构建一个 Runnable 来实现 Runnable 接口的对象:

- -
js> r = new java.lang.Runnable(obj);
- - - -
js> r = new java.lang.Runnable(obj);
-[object JavaObject]
-
- -

在Java中,不可能在接口上使用new运算符,因为没有可用的实现。Rhino从JavaScript对象中获取实现obj现在我们有一个对象实现Runnable,我们可以创建Thread并运行它。我们定义的函数run 将在新线程上调用。

- -
js> t = new java.lang.Thread(r)
-Thread[Thread-2,5,main]
-js> t.start()
-js>
-
-running
-
- - - -

最终js提示和新线程的输出可能以任意顺序显示,具体取决于线程调度。

- -

在后台,Rhino为一个新的Java类生成字节码,该类实现 Runnable 并转发对其 run方法的所有调用,并转发给关联的JavaScript对象。实现此类的对象称为Java适配器。因为转发到JavaScript是在运行时发生的,所以可能会延迟定义实现接口的方法直到它们被调用。虽然省略必要的方法对大编程来说是一种糟糕的做法,但它对小脚本和探索性编程很有用。

- - - -

JavaAdapter构造函数

- -

在前面的章节中,我们使用 new 运算符与Java接口创建Java适配器。这种方法有其局限性:不可能实现多个接口,也不能扩展非抽象类。因为这些原因,有一个 JavaAdapter 构造函数。

- -

JavaAdapter构造函数的语法是:

- -
new JavaAdapter(javaIntfOrClass, [javaIntf, ..., javaIntf,] javascriptObject)
-
- -

这里javaIntfOrClass是一个实现的接口或一个扩展的类,并且javaIntf是实现接口的接口。而javascriptObject 则包含从Java适配器调用的方法的JavaScript对象。

- -

在实践中,几乎不需要JavaAdapter 直接调用构造函数。大多数情况下,使用new运算符之前的语法就足够了。

- -

作为Java接口的JavaScript函数

- -

通常我们只需要使用一种方法实现一个接口,就像前面的 Runnable 例子或者提供各种事件监听器实现一样。为了方便这个,Rhino允许在这种接口传递JavaScript函数。该函数被称为接口方法的实现。

- -

这里是简化的 Runnable 实例:

- -
js> t = java.lang.Thread(function () { print("\nrunning"); });
-Thread[Thread-0,5,main]
-js> t.start()
-js>
-running
-
- -

如果所有的方法都具有相同的签名,Rhino还允许使用JavaScript函数作为Java接口的实现方法。当调用函数时,Rhino将方法的名称作为附加参数传递。函数可以使用它来代表被调用的方法:

- -
js> var frame = new Packages.javax.swing.JFrame();
-js> frame.addWindowListener(function(event, methodName) {
-	if (methodName == "windowClosing") {
-            print("Calling System.exit()..."); java.lang.System.exit(0);
-	}
-    });
-js> frame.setSize(100, 100);
-js> frame.visible = true;
-true
-js> Calling System.exit()...
-
- -

创建Java数组

- -

Rhino不提供创建Java数组的特殊语法。你必须使用这个 java.lang.reflect.Array 类来达到这个目的。要创建一个由五个Java字符串组成的数组,可以进行以下调用:

- -
js> a = java.lang.reflect.Array.newInstance(java.lang.String, 5);
-[Ljava.lang.String;@7ffe01
-
- -

要创建一个基本类型数组,我们必须使用 java.lang 包中相关对象类中定义的特殊TYPE字段。例如,要创建一个字节数组,我们必须使用特殊字段 java.lang.Byte.TYPE:

- -
js> a = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 2);
-[C@7a84e4
-
- -

而且结果值是允许被使用在该类型的Java数组的任何地方。

- -
js> a[0] = 104
-104
-js> a[1] = 105
-105
-js> new java.lang.String(a)
-hi
-
- -

Java字符串和JavaScript字符串

- -

请记住,Java字符串和JavaScript字符串是一样的。Java字符串类型的实例,java.lang.String ,并具有由该类定义的所有方法。JavaScript字符串具有由...定义的方法,String.prototype. 最常见的绊脚石是 length, 这是Java字符串方法和JavaScript字符串的动态属性:

- -
js> javaString = new java.lang.String("Java")
-Java
-js> jsString = "JavaScript"
-JavaScript
-js> javaString.length()
-4
-js> jsString.length
-10
-
- -

Rhino 在减少这两种类型之间的差异方面提供了一些帮助。首先,您可以将JavaScript字符串传递给需要Java字符串的Java方法,Rhino将执行转换。实际上,我们在前面java.lang.String 例子中构造函数调用中看到了这个特性

- -

如果java.lang.String 类尚未定义它们,Rhino还会使JavaScript方法可用于Java字符串。例如:

- -
js> javaString.match(/a.*/)
-ava
-
- -

JavaImporter 构造函数

- -

JavaImporter是一个新的全局构造函数,它允许在脚本化Java时省略显式的包名称:

- -
var SwingGui = JavaImporter(Packages.javax.swing,
-                            Packages.javax.swing.event,
-                            Packages.javax.swing.border,
-                            java.awt.event,
-                            java.awt.Point,
-                            java.awt.Rectangle,
-                            java.awt.Dimension);
-...
-
-with (SwingGui) {
-    var mybutton = new JButton(test);
-    var mypoint = new Point(10, 10);
-    var myframe = new JFrame();
-...
-}
-
- -

以前,这样的功能仅适用于将 org.mozilla.javascript.ImporterTopLevel 用作顶级作用域的嵌入。这个类提供额外的 importPackage() 和importClass() 全局函数的脚本,但其广泛的使用有污染Java类名的全局命名空间的趋势,还有防止垃圾收集加载类。

- -

详情请参阅 Bugzilla 245882.

- -

Java 异常

- - - -

JavaScript代码使用 try ... catch 语句可以捕获Java方法抛出的异常Rhino将Java异常封装到具有以下属性的错误对象中:

- - - -

instanceof运算符可用于查询异常的类型:

- - - -
try {
-    java.lang.Class.forName("NonExistingClass");
-} catch (e) {
-    if (e.javaException instanceof java.lang.ClassNotFoundException) {
-       print("Class not found");
-    }
-}
-
- -

Rhino 还支持对 try... catch 语句的扩展,允许定义条件捕获异常:

- -
function classForName(name) {
-    try {
-        return java.lang.Class.forName(name);
-    } catch (e if e.javaException instanceof java.lang.ClassNotFoundException) {
-        print("Class " + name + " not found");
-    } catch (e if e.javaException instanceof java.lang.NullPointerException) {
-        print("Class name is null");
-    }
-}
-
-classForName("NonExistingClass");
-classForName(null);
-
diff --git a/files/zh-cn/mozilla/projects/rhino/shell/index.html b/files/zh-cn/mozilla/projects/rhino/shell/index.html deleted file mode 100644 index d5a4b779a9..0000000000 --- a/files/zh-cn/mozilla/projects/rhino/shell/index.html +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: Shell -slug: Mozilla/Projects/Rhino/Shell -translation_of: Mozilla/Projects/Rhino/Shell ---- -

JavaScript的外壳提供了一个简单的方法来在批处理模式下或编程的一个探索性的互动环境运行脚本.

-

调用Shell

-

<big>java org.mozilla.javascript.tools.shell.Main {{ mediawiki.external('options') }} script-filename-or-url {{ mediawiki.external('script-arguments') }} </big>

-

这里是一些选项 options

-

-e script-source

-

script-source  作为 JavaScript 执行.

-

-f script-filename-or-url

-

读取script-filename-or-url 的内容并作为JavaScript执行.

-

-opt optLevel / -O optLevel

-

优化等级 optLevel, 必须是 -1 或 [0-9]之间的整数. 参考Rhino Optimization 或许详情.

-

-version versionNumber

-

制定语言编译版本. 字符串 versionNumber 必须是 100, 110, 120, 130, 140, 150, 160170. 参考JavaScript Language Versions获取更多的语言版本信息.

-

-strict

-

开启strict 模式.

-

-continuations

-

启用continuation的实验支持,建立优化级别为-1强制解释模式. 从Rhino 1.7 开始这个选项不再可用.

-

注意

-

如果shell被使用设置为true的系统属性rhino.use_java_policy_security调用,一个安全管理将被安装, shell限制脚本通过基于根据URL访问Java安全选项的权限.如果JVM实现Java2的安全模型才可以用.

-

预定义的属性

-

在shell中呗执行的脚本访问顶层定义的一些属性.

-

arguments

-

当shell被调用时,arguments 对象是一个包含所有通过命令行输入的字符串的数组

-

environment

-

返回当前环境对象.

-

history

-

显示命令行中执行命令的历史.

-

help()

-

获取帮助信息.

-

defineClass(className)

-

定义一个使用Java类命名的扩展,参数 className是个类名的字符串. 使用 ScriptableObject.defineClass() 定义扩展.

-

deserialize(filename)

-

从指定的文件恢复以前通过调用一个被serialize的对象.

-

gc()

-

运行垃圾回收器.

-

load([filename, ...])

-

载入字符串命名的参数JavaScript源码文件. 如果有多个参数被传递,那么每一个参数都会被读取并执行.

-

loadClass(className)

-

载入并执行字符串className.表示的类.这个类必须是已实现的脚本接口, 就像任何被编译的脚本 Rhino JavaScript Compiler.

-

print([expr ...])

-

评估并打印表达式. 评估每一个表达式, 把结果转化为字符串并打印.

-

readFile(path [, characterCoding])

-

读取给定的文件并使用指定的编码把字节转换为字符串,如果没有制定编码就用默认编码.

-

readUrl(url [, characterCoding])

-

打开指定的url,读取所有的字节并用指定的编码转化为数组,如果没有指定编码就是用默认的.

-

runCommand(commandName, [arg, ...] [options])

-

执行参数中给定的命令,作为一个独立的进程选项并返回该进程的退出状态.

-

Usage:

-
runCommand(command)
-runCommand(command, arg1, ..., argN)
-runCommand(command, arg1, ..., argN, options)
-
-

All except the last arguments to runCommand are converted to strings and denote command name and its arguments. If the last argument is a JavaScript object, it is an option object. Otherwise it is converted to string denoting the last argument and options objects assumed to be empty.

-

The following properties of the option object are processed:

- -

seal(object)

-

Seal the specified object so any attempt to add, delete or modify its properties would throw an exception.

-

serialize(object, filename)

-

Serialize the given object to the specified file.

-

spawn(functionOrScript)

-

Run the given function or script in a different thread.

-

sync(function)

-

creates a synchronized function (in the sense of a Java synchronized method) from an existing function. The new function synchronizes on the this object of its invocation.

-

quit()

-

退出shell. 如果文件字符是在提示符下键入,shell将也退出在交互模式下.

-

version([number])

-

设置或获取JavaScript的版本号. 如果没有参数,就返回当前的版本. 如果有参数,参数要在 100, 110, 120, 130, 140, 150, 160 或 170范围内,它们分别对应 JavaScript1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6 or 1.7.

-

例子

-

调用

-

Here the shell is invoked three times from the command line. (The system command prompt is shown as $.) The first invocation executes a script specified on the command line itself. The next invocation has no arguments, so the shell goes into interactive mode, reading and evaluating each line as it is typed in. Finally, the last invocation executes a script from a file and accesses arguments to the script itself.

-
$ java org.mozilla.javascript.tools.shell.Main -e print('hi')
-hi
-$ java org.mozilla.javascript.tools.shell.Main
-js> print('hi')
-hi
-js> 6*7
-42
-js> function f() {
-  return a;
-}
-js> var a = 34;
-js> f()
-34
-js> quit()
-$ cat echo.js
-for (i in arguments) {
-  print(arguments[i])
-}
-$ java org.mozilla.javascript.tools.shell.Main echo.js foo bar
-foo
-bar
-$
-
-

spawn 和 sync 

-

下面的例子创建了2个线程 via spawn 和 uses sync 去创建同步的函数test test版本.

-
js> function test(x) {
-  print("entry");
-  java.lang.Thread.sleep(x*1000);
-  print("exit");
-}
-js> var o = { f : sync(test) };
-js> spawn(function() {o.f(5);});
-Thread[Thread-0,5,main]
-entry
-js> spawn(function() {o.f(5);});
-Thread[Thread-1,5,main]
-js>
-exit
-entry
-exit
-
-

运行命令

-

这是在Linux下调用 runCommand 的例子.

-
js> runCommand('date')
-Thu Jan 23 16:49:36 CET 2003
-0
-// Using input option to provide process input
-js> runCommand("sort", {input: "c\na\nb"})
-a
-b
-c
-0
-js> // Demo of output and err options
-js> var opt={input: "c\na\nb", output: 'Sort Output:\n'}
-js> runCommand("sort", opt)
-0
-js> print(opt.output)
-Sort Output:
-a
-b
-c
-js> var opt={input: "c\na\nb", output: 'Sort Output:\n', err: ''}
-js> runCommand("sort", "--bad-arg", opt)
-2
-js> print(opt.err)
-/bin/sort: unrecognized option `--bad-arg'
-Try `/bin/sort --help' for more information.
-
-js> runCommand("bad_command", "--bad-arg", opt)
-js: "<stdin>", line 18: uncaught JavaScript exception: java.io.IOException: bad_command: not found
-js> // Passing explicit environment to the system shell
-js> runCommand("sh", "-c", "echo $env1 $env2", { env: {env1: 100, env2: 200}})
-100 200
-0
-js> // Use args option to provide additional command arguments
-js> var arg_array = [1, 2, 3, 4];
-js> runCommand("echo", { args: arg_array})
-1 2 3 4
-0
-
-

Windows下的例子也差不多:

-
js> // Invoke shell command
-js> runCommand("cmd", "/C", "date /T")
-27.08.2005
-0
-js> // Run sort collectiong the output
-js> var opt={input: "c\na\nb", output: 'Sort Output:\n'}
-js> runCommand("sort", opt)
-0
-js> print(opt.output)
-Sort Output:
-a
-b
-c
-js> // Invoke notepad and wait until it exits
-js> runCommand("notepad")
-0
-
-

{{ languages( { "zh-cn": "zh-cn/Shell" } ) }}

diff --git a/files/zh-cn/mozilla/projects/social_api/index.html b/files/zh-cn/mozilla/projects/social_api/index.html deleted file mode 100644 index 55d8b5525e..0000000000 --- a/files/zh-cn/mozilla/projects/social_api/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Social API -slug: Mozilla/Projects/Social_API -tags: - - API - - Landing - - Mozilla - - NeedsTranslation - - Social - - TopicStub -translation_of: Archive/Social_API ---- -

The Social API is an architecture that makes it easier for web browsers to integrate with social media services, using standard web technologies as the API. Once a social service provider is implemented for Firefox, it becomes possible for the browser to integrate web resources from a service, in-chrome user controls and information related to that service. The following articles explain how to implement a social service provider.
-
- The Social API supports specific vertical use cases centered around social interactions, but does not tightly constrain those use cases, allowing flexibility and creativity for 3rd parties. Specific features supported are notifications, share, bookmarking (or save-for-later), sidebars and communications (e.g. chat and video).

- -
-
-

Social API documentation

- -
-
Social API glossary
-
Provides definitions of key terms you'll need to understand when using the Social API.
-
Social service manifest
-
A description of—(TBD: and guide to building)—the manifest required.
-
Social service worker API reference {{obsolete_inline(48)}}
-
A reference to the social service worker API.
-
Social service content API: MozSocial {{obsolete_inline(51)}}
-
A reference to the social service content API, which is provided by the {{domxref("navigator.MozSocial")}} object.
-
Social share API
-
A reference to the Share API.
-
Social bookmarks API {{obsolete_inline(51)}}
-
A reference to the Social Bookmarks API.
-
Social status API {{obsolete_inline(51)}}
-
A reference to the Status API.
-
Social service widgets
-
A guide to the widgets provided by the social service.
-
- -

How to create a SocialAPI Provider

- -

A step-by-step guide to create a simple Social API provider.

- -
-
First Steps
-
The basics of getting an installable social provider running.
-
Adding ambient notifications {{obsolete_inline(51)}}
-
A short guide to implementing ambient notifications using the Social API.
-
Implementing status and notifications {{obsolete_inline(51)}}
-
A guide to implementing a status panel with notifications using the Social API.
-
Adding bookmark support {{obsolete_inline(51)}}
-
A short guide to implementing social bookmarks using the Social API.
-
Implementing share
-
A guide to implementing a share panel using the Social API.
-
Supporting chat {{obsolete_inline(51)}}
-
A guide to implementing chat features using the Social API.
-
- -

View All...

-
- -
-

Getting help from the community

- -

Need help on a Social API related problem and can't find the solution in the documentation?

- -
    -
  • Ask your question on the Mozilla IRC channel: #socialdev
  • -
- -

Don't forget about the netiquette...

- -

Tools and demos

- - - -

View All...

- - - -

Try out any of several providers on the SocialAPI Directory site (Firefox 29 or later required)

- - - - - -
-
- -

 

diff --git a/files/zh-cn/mozilla/projects/social_api/share/index.html b/files/zh-cn/mozilla/projects/social_api/share/index.html deleted file mode 100644 index 844ac9d693..0000000000 --- a/files/zh-cn/mozilla/projects/social_api/share/index.html +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Share -slug: Mozilla/Projects/Social_API/Share -translation_of: Archive/Social_API/Share ---- -

这一篇只是初步草案,可能会被改变。分享从 [TBD: Firefox 23] 开始可用。

- -

A service provider may choose to provide a Share panel that users can use to share content from the current browser tab with their friends.  The Share panel is slightly different from other Social UI in the browser.  The Share panel itself contains a list of providers that support the share functionality.  When a user shares a page, they can choose which provider they want to share with.  Each provider may have differing functionality, such as simply providing a comment box to extensive functionlality allowing for image selection and more.

- -

Share is initiated by the user either through the share button in the toolbar or a context menu.  The user can select an image or text in a page to be shared, or share the page itself.  Links within a page may also be shared without visiting the link.

- -

A provider implementing support for share may choose to use a URL template that is compatible with OExchange, however the browser also sends a DOM event to the page after load containing details of the share.  In some circumstances, such as sharing a link on the page, the browser will not have detailed information.  Using the DOM event allows the provider to display information about the page being shared without needing to fetch it themselves and parse the page for information.  The browser includes certain META tags, including OpenGraph tags in the event data.

- -

A User Experience Flow for Share

- -

SocialAPI content works different than typical web pages.  The are presented as primary UI in the browser, and may be confined in size, live longer than a browser tab, and more.  How your user will interact with your share panel is unique and you will need to take into account how a user should experience your share panel.

- -

[TODO: describe the expected flow here]

- -

OpenGraphData DOM Event

- -

The share page can listen for the OpenGraphData DOM Event.

- -
addEventListener("OpenGraphData", function(e) {
-  var shareData = JSON.parse(e.detail);
-  $("#shared").text(shareData.url);
-})
-
- -

Attributes

- -

The event detail can contain the following attributes which are retreived from META tags and other tags within HEAD, such as the TITLE tag:

- - - -

Share URL Template

- -

While we prefer the use of the DOM event, many sites have existing endpoints that allow users to share to that site.  SocialAPI supports using a URL template to make implementation easy for sites that already have this functionality.  In your manifest, you can define your shareURL in this format:

- -
"shareURL": "https://yoursite.com/share?u=%{url}&t=%{title}
- -

The %{name} values will be replaced with the following attributes if available.  Otherwise that parameter is removed from the final url used to load your share endpoint.

- - - -

How to properly size your share panel

- -

Your share panel is presented in a door hanger from the browser toolbar.  While it can be flexible in size, there is a minimum and a maximum size that the panel will allow.  You also need to implement a couple items to help the browser identify the size you need for your panel.  There are a few ways you can define the proper size for your panel, here are some examples:

- -

Styling the BODY element

- -

By default the browser will look at the body.style.width and body.style.height, also taking into account the margin.  It will try to size the panel to show your full page.

- -
<html>
-<body style="width: 300px; height: 400px">
-</body>
-</html>
-
- -

Identifying a content element

- -

The browser will also look to see if you have defined a primary content element.  If you have, then it will use the width and height styles from that element to size the panel.  You will need to make sure that your content element is properly placed.

- -
<html>
-<body contentid="content">
-<div id="content" style="width: 300px; height: 400px; top: 0; left: 0;"/>
-</body>
-</html>
diff --git a/files/zh-cn/mozilla/projects/spidermonkey/build_documentation/index.html b/files/zh-cn/mozilla/projects/spidermonkey/build_documentation/index.html deleted file mode 100644 index ecb793016e..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/build_documentation/index.html +++ /dev/null @@ -1,294 +0,0 @@ ---- -title: SpiderMonkey Build Documentation -slug: Mozilla/Projects/SpiderMonkey/Build_Documentation -translation_of: Mozilla/Projects/SpiderMonkey/Build_Documentation ---- -
{{SpiderMonkeySidebar("General")}}
- -

构建 SpiderMonkey

- -

使用本说明来构建最新的 SpiderMonkey 源码.

- -

在构建前, 确保有适合你计算机的构建工具: Linux, Windows, Mac, others. 当构建的版本低于28, 你还需要外加 NSPR.

- -

以及理所当然地, 你需要 获取 SpiderMonkey 源代码。

- -

非开发者 (优化) 模式构建

- -

如果你想在生产环境中安装使用SpiderMonkey或运行标准性能测试,可以使用此步骤。 (如果你想在你的C++应用中把 SpiderMonkey 作为库使用, 或从事改进 SpiderMonkey 本身的工作, 按之后的描述,使用 开发者/调试 模式构建.)

- -
cd js/src
-autoconf2.13
-
-# This name should end with "_OPT.OBJ" to make the version control system ignore it.
-mkdir build_OPT.OBJ
-cd build_OPT.OBJ
-../configure
-# Use "mozmake" on Windows
-make
-
- -

一些注意事项:

- - - -
-

Note: If you are on Mac and getting an error similar to

- -

"checking whether the C compiler (gcc-4.2  ) works... no
- configure: error: installation or configuration problem: C compiler cannot create executables.
"

- -

You can try configuring like so:

- -
CC=clang CXX=clang++  ../configure
- -

It is also possible that baldrdash  may fail to compile with

- -
/usr/local/Cellar/llvm/7.0.1/lib/clang/7.0.1/include/inttypes.h:30:15: fatal error: 'inttypes.h' file not found
-
-/usr/local/Cellar/llvm/7.0.1/lib/clang/7.0.1/include/inttypes.h:30:15: fatal error: 'inttypes.h' file not found, err: true
- -

This is because, starting from Mohave, headers are no longer installed in /usr/include. Refer the release notes  under Command Line Tools -> New Features

- -

The release notes also states that this compatibility package will no longer be provided in the near future, so the build system on macOS will have to be adapted to look for headers in the SDK
-
- Until then, the following should help,

- -
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pk
-
-
- -

This builds an executable named js in the directory build-release/dist/bin. You can test it with dist/bin/js --help, which displays a help page. At this point, you're ready to run and try out the shell.

- -

On Mac, Linux, or UNIX, you can install SpiderMonkey on your system with the additional command make install. This installs the shared library to /usr/local/lib, the C header files to /usr/local/include, and the js executable to/usr/local/bin.

- -

开发者 (调试) 模式构建

- -

For developing and debugging SpiderMonkey itself, it is best to have both a debug build (for everyday debugging) and an optimized build (for performance testing), in separate build directories. Thus, in addition to following the steps above, you should also create a debug build using these steps:

- -
cd js/src
-autoconf2.13
-
-# This name should end with "_DBG.OBJ" to make the version control system ignore it.
-mkdir build_DBG.OBJ
-cd build_DBG.OBJ
-../configure --enable-debug --disable-optimize
-# Use "mozmake" on Windows
-make
-
- -

You can also build debug builds of SpiderMonkey with the JS_GC_ZEAL option, which adds a new built-in function to SpiderMonkey that lets you configure zealous garbage collection.  This can help debug memory leaks and other memory-related problems. See JS_SetGCZeal() for details.

- -

For a list of other available build options, type (assuming the current working directory is one of the above-created build directories):

- -
../configure --help
-
- -

生成编译数据库

- -

Some tools (like IDEs, static analyzers and refactoring tools) consume a file called compile_commands.json which contains a description of all the pieces required to build a piece of software so that tools don't have to also understand a build system.

- -

To generate a compile_commands.json with the SpiderMonkey configure script, enable the CompileDB backend, like this:

- -
 ../configure <options> --enable-build-backends=CompileDB,RecursiveMake
-
- -

(RecursiveMake is there as you'd likely also want to be able to build!)

- -

Windows Builds

- -
-

Since version 28, threadsafe builds are the default, and should work out of the box on all POSIX platforms. Hence, the following instructions should only be relevant if you're on Windows or compiling an older version of SpiderMonkey.

-
- -

The MozillaBuild batch file you used to open your shell (e.g. start-shell-msvc2013.bat or start-shell-msvc2013-x64.bat) determines whether the compiler toolchain will target 32-bit or 64-bit builds. To create a 64-bit build, note that you must configure with --target=x86_64-pc-mingw32 --host=x86_64-pc-mingw32.

- -

Since the POSIX NSPR emulation is not available for Windows, a working version of NSPR must be available to your build. The easiest option is to configure with --enable-nspr-build. This configure option builds the in-tree version of NSPR which is probably what you want; because SpiderMonkey uses newer NSPR symbols, the NSPR that ships with your operating system probably does not work.

- -

If --enable-nspr-build does not work, explicitly tell configure where to find NSPR using the --with-nspr-cflags and --with-nspr-libs configure options. For example, assuming your local NSPR has been installed to C:/mozilla-build/msys/local:

- -
./configure --with-nspr-cflags="-IC:/mozilla-build/msys/local/include" \
-            --with-nspr-libs="C:/mozilla-build/msys/local/lib/libnspr4.a \
-                              C:/mozilla-build/msys/local/lib/libplds4.a \
-                              C:/mozilla-build/msys/local/lib/libplc4.a"
-
- -

If you get symbol loading or dynamic library errors, you can force the correct NSPR to load with:

- -
PATH="$PATH;C:/mozilla-build/msys/local/lib/" ./js
- -

指定安装目录

- -

make install puts files in the following directories by default. You can override this by passing options to the configure script:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
What it isWhere it gets putconfigure option
executables, shell scripts/usr/local/bin--bindir
libraries, data/usr/local/lib--libdir
architecture-independent data/usr/local/share--sharedir
C header files/usr/local/include--includedir
- -

For convenience, you can pass the configure script an option of the form --prefix=<PREFIXDIR>, which substitutes <PREFIXDIR> for /usr/local in all the settings above, in one step. This is usually the least troublesome thing to do, as it preserves the typical arrangement of lib, bin, and the rest.

- -
Note: All directories you pass to configure are recorded in the generated makefile, so you don't need to specify them again until you re-run configure.
- -

构建 SpiderMonkey 作为静态库

- -

默认情况下, SpiderMonkey 会构建为共享库. However, you can build SpiderMonkey as a static library by specifying the --disable-shared-js flag when you run configure.

- -

指定编译器及编译标签

- -

If you want to use a compiler other than the one the configure script chooses for you by default, you can set the CXX variable in the environment when you run configure. This will save the values you specify in the generated makefile, so once you've set it, you don't need to do so again until you re-run configure.

- -

If you'd like to pass certain flags to the compiler, you can set the CXXFLAGS environment variable when you run configure. For example, if you're using the GNU toolchain, the following will pass the -g3 flag to the compiler, causing it to emit debug information about macros. Then you can use those macros in gdb commands:

- -
$ CXXFLAGS=-g3 $SRC/configure
-...
-checking whether the C++ compiler (c++ -g3 ) works... yes
-...
-$
-
- -

交叉编译选项

- -

For cross-compiling you will need a cross-compiling compiler. That tends to be easier with clang as clang has cross-compiling support built in. You may need other libraries though.  For example on debian linux you'll need the following to cross compile from x86_64 to x86.

- -
apt install clang libstdc++-8-dev-i386-cross binutils-i686-gnu zlib1g-dev:i386
- -

You'll also need rust, in addition to having normal rust set up you'll need to add another target to your existing rust toolchain (don't add a new toolchain spidermonkey will use only one toolchain and use it for both host and target code:

- -
rustup target add i686-unknown-linux-gnu
- -

To build a 32-bit version on a 64-bit Linux system, you can use the following:

- -
PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig CC="gcc -m32 -mfpmath=sse -msse -msse2" CXX="g++ -m32 -mfpmath=sse -msse -msse2" AR=ar \
-$SRC/configure --target=i686-pc-linux
-
- -

Or for clang.

- -
$SRC/configure --target=i686-pc-linux-gnu
- -

To build a 32-bit arm version on a 64-bit Linux system, that runs in the arm simulator, you can use the following:

- -
   AR=ar CC="gcc -m32 -mfpmath=sse -msse -msse2" CXX="g++ -m32 -mfpmath=sse -msse -msse2" \
-    $SRC/configure --target=i686-pc-linux --enable-simulator=arm
-
- -

To build a 32-bit version on a 64-bit Mac system (the target version is specific to your OS/X SDK), you can use the following:

- -
$SRC/configure --target=i386-apple-darwin16.7.0 # Choose the appropriate SDK version for your version of OS/X
- -

To build a 64-bit version on a 32-bit Mac system (e.g. Mac OS X 10.5), you can use the following:

- -
AR=ar CC="gcc -m64" CXX="g++ -m64" ../configure --target=x86_64-apple-darwin10.0.0
-
- -

To build a 64-bit Windows version, you can use the following:

- -
$SRC/configure --host=x86_64-pc-mingw32 --target=x86_64-pc-mingw32
-
- -
Note: You must have started your MozillaBuild shell with the proper -x64.bat script in order for the 64-bit compilers to be in your PATH.
- -

Whatever compiler and flags you pass to configure are recorded in the generated makefile, so you don't need to specify them again until you re-run configure.

- -

Building your application

- -

While "How to build your complete application" is clearly out of scope for this document, here are some tips that will help get you on your way:

- - - -

Using the js-config script

- -

In addition to the SpiderMonkey libraries, header files, and shell, the SpiderMonkey build also produces a shell script named js-config which other build systems can use to find out how to compile code using the SpiderMonkey APIs, and how to link with the SpiderMonkey libraries.

- -
Note: In SpiderMonkey 1.8.5, the js-config script is not generated properly on many platforms. If the instructions below do not work, you can try this workaround.
- -

When invoked with the --cflags option, js-config prints the flags that you should pass to the C compiler when compiling files that use the SpiderMonkey API. These flags ensure the compiler will find the SpiderMonkey header files.

- -
$ ./js-config --cflags # Example output: -I/usr/local/include/js -I/usr/include/nspr
-
- -

When invoked with the --libs option, js-config prints the flags that you should pass to the C compiler when linking an executable or shared library that uses SpiderMonkey. These flags ensure the compiler will find the SpiderMonkey libraries, along with any libraries that SpiderMonkey itself depends upon (like NSPR).

- -
$ ./js-config --libs # Example output: -L/usr/local/lib -lmozjs -L/usr/lib -lplds4 -lplc4 -lnspr4 -lpthread -ldl -ldl -lm  -lm -ldl
- -

Testing SpiderMonkey

- - - -

Building SpiderMonkey 1.8 or earlier

- -

Use these instructions to build SpiderMonkey from an official source release or from the old CVS repository. To build the latest SpiderMonkey sources from Mercurial, see Building SpiderMonkey above.

- -

SpiderMonkey is easy to build from source if you have the usual Mozilla build prerequisites installed. Before you begin, make sure you have right build tools for your computer: LinuxWindowsMacothers.

- -

First, download a SpiderMonkey source distribution, such as SpiderMonkey 1.8 Release Candidate 1.

- -

To build, use these commands:

- -
tar xvzf js-1.8.0-rc1.tar.gz
-cd js/src
-make -f Makefile.ref
-
- -

This builds a debug version of SpiderMonkey. All build files are created in a subdirectory named depending on your system (for example,Linux_All_DBG.OBJ if you are on Linux). To install this build on your system, see SpiderMonkey installation instructions.

- -

To build an optimized (non-debug) version of SpiderMonkey:

- -
make BUILD_OPT=1 -f Makefile.ref
- -

To build a thread-safe version of SpiderMonkey:

- -
make JS_DIST=/full/path/to/directory/containing/nspr JS_THREADSAFE=1 -f Makefile.ref
-
diff --git a/files/zh-cn/mozilla/projects/spidermonkey/comparision_of_js_engines/index.html b/files/zh-cn/mozilla/projects/spidermonkey/comparision_of_js_engines/index.html deleted file mode 100644 index 934e38ad7a..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/comparision_of_js_engines/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: JS 引擎比较 -slug: Mozilla/Projects/SpiderMonkey/Comparision_of_JS_engines ---- -

概述

-

本页用来纪录各个开源 JS 引擎(SpiderMonkey、V8、JavaScriptCore)在算法、未来趋势上的比较。除非额外说明,内存相关的数据假设系统为 32 位

-

类、函数、词汇比较表

-

为了让懂得其中一个 JS 引擎的程序员迅速了解另外一个引擎,以下整理这些引擎共同概念的实现比较(把鼠标放在类/函数上面可以找到定义该类/函数的文件):

-

常见

- - - - - - - - - - - - - - - - - - - - - - - - - -
SpiderMonkeyV8备注
ValueMaybeObject *代表一个 JS 值(数值、字符串、对象……)的类。SpiderMonkey 是用 nun-boxing,总是一个 double 的大小(因此在 32 位的系统下,传值需要两个 cycle)。V8 是用 tagged pointer,总是一个指针的大小,浮点数存在堆上。MaybeObject 还是很多非 JS 语言对象(代码块等等)的父类
 ObjectImplJSObjectJS 对象(obj instanceof Object)的实现类。SpiderMonkey 与 V8 皆是把部分属性存放在对象行内,部分用外链的一个数组储存的模式。SpiderMonkey 也将小数组的数据存在行内(但是不会分两半),而 V8 的 JS 数组对象(貌似)都是将数据存在外链的数组上。在 SpiderMonkey 中,只有在 new space 的 JS 对象的外链数组的空间由虚拟机分配,其他情况的外链数组的空间malloc 分配(因此内存会比较分裂?)。ObjectImpl 除了有连接到 Shape 的指针之外,还有一个链到 TypeObject 的指针:16 B(ObjectImpl)vs. 12 B(JSObject)。在 SpiderMonkey 中,数据用 Value 存,也就是说,对于一个有 k 个行内属性的 JS 对象来说,内存占用是:16 B + k * 8 B(ObjectImpl)vs. 12 B + k * 4 B(JSObject),行外的情形 V8 则会再多用 8 B(FixedArray 的标头)。
ShapeTypeObjectClassMap隐藏类的实现类。在 SpiderMonkey 中,属性名存在 Shape 上(因此带有 V8 的 DescriptorArray 的作用),JS 对象的原型存在 TypeObject 上,特殊属性的处理方法存在 Class 上(Class 对象不是 JS 堆里的对象,大部分都共用:JSObject::class_JSFunction::class_……)。由于 V8 的 Map 有 SM 三个类的作用,因此占用内存也比较多:24 B(Shape)vs. 40 B(Map)。
-

内存布局与对象创建

-

运行时

- - - - - - - - - - - - - -
SpiderMonkeyV8备注
Interpret(无)解释器的主回圈。V8 没有字节码与解释器。
-

堆与 GC

- - - - - - - - - - - - - -
SpiderMonkeyV8备注
NurseryNewSpace 
-

调优

-

一个容易调优的 JS 引擎应该具备有以下条件(从重要的到不重要的):

- -

参见

- -

跟 “JS 引擎” 比较无关,但是中文的 JS 引擎相关的博文也比较少,这里搜集一下:

- -

代码美观

-

这件事实在不应该是决定使用哪个 JS 引擎的因素,不过……

-

如果(不幸的)需要以 SpiderMonkey 作为基础调优则会碰到以下问题:

-
    -
  1. C 与 C++ 代码混用。SpiderMonkey 原先是 C 写成的,后来大规模的以 C++ 改进,但是留下了很多残骸:宏、不是宏但是名称是大写的函数。(参见 JS::Value 的说明。)
  2. -
  3. 成员变量、方法命名缺乏规则。ObjectImpl::slotsObjectImpl::shape_ 同时存在(前面那个应该加底线)。这个或许是可以修复的 bug。
  4. -
  5. 混入 JavaScriptCore、V8 代码。SpiderMonkey 的组译器是 JavaScriptCore 的,那些类的成员变量是 m_buffer 等等,又增加了成员变量命名的。另外还有 WTF_* 宏,真是 WTF。再批。妈的,WTF_CPU_ARM_THUMB2 跟本不可能为真,这里有大量的死代码(所有代码完全没有用到 JSC::MacroAssembler,用到的是 js::jit::MacroAssembler)。另外,
  6. -
  7. 混乱的名称空间。
  8. -
  9. structclass 混用。
  10. -
  11. 文档命名缺少规则。C 时代的档名是 jsobj.h,C++ 时代的档名是 Value.h 。请自重。
  12. -
  13. 过渡滥用宏。
  14. -
diff --git a/files/zh-cn/mozilla/projects/spidermonkey/index.html b/files/zh-cn/mozilla/projects/spidermonkey/index.html deleted file mode 100644 index 468fafa0cb..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/index.html +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: SpiderMonkey -slug: Mozilla/Projects/SpiderMonkey -tags: - - SpiderMonkey - - Update -translation_of: Mozilla/Projects/SpiderMonkey ---- -

SpiderMonkey 是Mozilla使用C/C++编写的JavaScript 引擎。它被用于包括Firefox在内的多个Mozilla产品中,使用的是MPL 2授权协议.

- -

独立的源代码版本可以在发布页上找到

- - - - - - - - -
-

文档

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

General

-
SpiderMonkey Build Documentation如何获取到SpiderMonkey源代码,编译,并运行测试套.
Introduction to the JavaScript shell如何获取,构建,并使用JavaScript shell.
Running Automated JavaScript Tests如何运行JavaScript测试套件.
Creating JavaScript tests如何为JavaScript测试套件添加测试.
New to SpiderMonkeySpiderMonkey的hacking指南.
Setting up CDT to work on SpiderMonkey如何配置CDT,使之在SpiderMonkey代码上工作.
-

JSAPI

-
JSAPI User Guide本指南简要介绍了SpiderMonkey,还介绍了如何可以将SpiderMonkey嵌入到你的应用程序中.
JSAPI Phrasebook一些常用的JavaScript表达式和语句的JSAPI翻译.
JSAPI ReferenceSpiderMonkey API 参考.
Bytecode ReferenceSpiderMonkey 字节码参考.
JS Debugger API Guide在Gecko 8.0中引入的新的JavaScript调试器API{{ geckoRelease("8.0") }}.
JS Debugger API ReferenceSpiderMonkey 1.8.6(Gecko 8.0 )中引入的Debugger对象的API参考, {{ geckoRelease("8.0") }}.
JSDBGAPI Reference -

SpiderMonkey调试API参考;SpiderMonkey 1.8.5之前版本的调试API, 虽然它并没有被删除.

-
-

提示,技巧和理念

-
How to embed the JavaScript engine如何嵌入SpiderMonkey的基础教程
SpiderMonkey Garbage Collection Tips如何避免垃圾回收时出现的问题.
SpiderMonkey Internals设计概况和实现版本介绍
SpiderMonkey Internals: GC关于垃圾回收的独立的内部文章.
SpiderMonkey Internals: Thread SafetySpiderMonkey的请求模型的内部工作原理.
-
- - - - - -

社区

- -

有问题? 在IRC上提问!

- -

查看 Infomonkey.

- -

有bug? 提交bugCore -> JavaScript Engine

-
diff --git a/files/zh-cn/mozilla/projects/spidermonkey/internals/bytecodes/index.html b/files/zh-cn/mozilla/projects/spidermonkey/internals/bytecodes/index.html deleted file mode 100644 index 7c47ffb7ae..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/internals/bytecodes/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: 字节码 -slug: Mozilla/Projects/SpiderMonkey/Internals/Bytecodes -tags: - - SpiderMonkey -translation_of: Mozilla/Projects/SpiderMonkey/Internals/Bytecodes ---- -
{{SpiderMonkeySidebar("Internals")}}
- -

背景知识

- -

SpiderMonkey字节码是JavaScript引擎使用的标准代码表示形式。JavaScript前端根据源文本构建AST,然后根据JSScript数据结构的一部分从AST生成基于堆栈的字节码。字节码可以引用原子和对象(通常通过数组索引),这些原子和对象也包含在JSScript数据结构中。

- -

在引擎内,所有字节码都在堆栈帧内执行。堆栈帧与全局(顶级)代码和eval代码相关联。堆栈上的框架为几个不同类别的JavaScript值(标记值格式)留出空间。单个JavaScript值空间称为“插槽”,类别为:

- - - -

还有一些保留给专用功能的插槽,用于处理thiscallee返回值。.

- -

总有一个“堆栈顶部”(TOS),它对应于推入表达式堆栈的最新值。所有字节码都根据该位置隐式运行。

- -

字节码列表

- -

所有操作码都用 [-popcount, +pushcount] 标注,以表示整个执行的堆栈效果。

- -

字节码列表已移至 SpiderMonkey Internals: Bytecode Descriptions 页面。

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/internals/functions/index.html b/files/zh-cn/mozilla/projects/spidermonkey/internals/functions/index.html deleted file mode 100644 index 91d96b22eb..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/internals/functions/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Functions -slug: Mozilla/Projects/SpiderMonkey/Internals/Functions -translation_of: Mozilla/Projects/SpiderMonkey/Internals/Functions ---- -
{{SpiderMonkeySidebar("Internals")}}
- -

There are several flavors of JavaScript function. All are JSObjects of the same class, js_FunctionClass.

- -

这里有些Javscript函数,它们属于JSObjects

- -

(But note that objects of other classes can be callable and can even have typeof obj == "function".)

- -

(也存在其他可被Call的对象)

- -

Script functions

- -

Functions written in JavaScript and compiled to bytecode. There are four variations that affect how NameExpressions are evaluated. (NameExpressions are basic expressions like String and x that would eat up a huge amount of run time if the engine weren't smart enough to avoid symbol table lookups.)

- -

General closures are the base case. When the function object is created, its parent is set to the first object on the scope chain. When a name is evaluated that doesn't refer to a local variable, the interpreter consults the scope chain to find the variable. When with or eval are used, we have to do this for correctness.

- -

This is slow, not only because walking the scope chain is a drag, but also because we'd rather avoid actually creating the scope chain at all, if possible. General closures force the interpreter to verify the whole scope chain. So we optimize this when we can.

- -

These optimizations depend on being sure that we will never have to walk the scope chain, so with and eval inhibit them all.

- -

Null closures. If we can prove at compile time that a function does not refer to any locals or arguments of enclosing functions, it is a null closure. Since it will never need to walk the scope chain, its parent is the global object. This is the best case. Barring with and eval, all outermost functions are null closures.

- -

Null closures with upvars. A nested function is algol-like if it is only ever defined and called, and it isn't accessed in any other way (and it is not a generator-function). Such a function is guaranteed never to be called again after the enclosing function exits. An algol-like function may read the local variables and arguments of its immediate enclosing function from the stack, as if by magic. (JSContext::display caches the enclosing function's stack frame.) If that function is also algol-like, its child can read locals and variables from the next enclosing function, and so on. The compiler detects these cases and makes such functions null closures too.

- -

Flat closures. Suppose a function reads some variables from enclosing functions but is not algol-like. If the function does not assign to any closed-on vars/args, and it only reads closed-on local variables and arguments that never change value after the function is created, then the function can be implemented as a flat closure. When a flat closure is created, all the closed-on values are copied from the stack into reserved slots of the function object. To evaluate a name, instead of walking the scope chain, we just take the value from the reserved slot. The function object's parent is the global object.

- -

Flat closures and Null closures have been removed:

- -

https://bugzilla.mozilla.org/show_bug.cgi?id=730497

- -

https://bugzilla.mozilla.org/show_bug.cgi?id=739808

- -

Name lookups

- -

In order of speed, fastest to slowest.

- -
    -
  1. -

    ARG and LOCAL instructions. If a name definitely refers to an argument or local variable of the immediately enclosing function, it can be accessed using JSOP_{GET,SET,CALL}{ARG,LOCAL} instructions. Some of these can even be fused with other operations into combo instructions like JSOP_GETARGPROP, JSOP_FORLOCAL, and JSOP_INCLOCAL. Because arguments and locals can't be deleted, this optimization is available to all functions, and eval does not interfere with it. But a with block can:

    - -
    function f(s) {
    -    eval(s);
    -    print(s);  // s can be loaded with GETARG
    -    with (obj) {
    -        print(s);  // no GETARG here; s might refer to obj.s
    -    }
    -}
    -
    -
  2. -
  3. -

    UPVAR instructions. JSOP_{GET,CALL}UPVAR (in algol-like functions only, I think?) TODO

    -
  4. -
  5. -

    DSLOT instructions. JSOP_{GET,CALL}DSLOT (in flat closures only) TODO

    -
  6. -
  7. -

    GVAR instructions. Outside all functions, if a name definitely refers to a global for which we have seen a var, const, or function declaration, then we emit a JS_DEFVAR instruction in the script prelude and access the global using JSOP_{GET,SET,CALL}GVAR. This is fast if the global either doesn't exist before the script runs (the script creates it) or it's a non-configurable data property (which amounts to the same thing). Otherwise the GVAR instructions are as slow as NAME instructions.

    - -

    There are also combo instructions JSOP_{INC,DEC}GVAR and JSOP_GVAR{INC,DEC}.

    -
  8. -
  9. -

    NAME instructions. In the worst case we emit JSOP_{,SET,CALL}NAME. These are totally general. They can still be optimized via the property cache; in the worst case we walk the scope chain.

    - -

    In some cases, the JIT can optimize a JSOP_NAME instruction that refers to a variable in an enclosing scope to pull the value directly out of the Call object's dslots.

    - -

    For the expression delete name we always emit JSOP_DELNAME. It's not worth optimizing.

    -
  10. -
diff --git a/files/zh-cn/mozilla/projects/spidermonkey/internals/index.html b/files/zh-cn/mozilla/projects/spidermonkey/internals/index.html deleted file mode 100644 index 03228c312f..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/internals/index.html +++ /dev/null @@ -1,292 +0,0 @@ ---- -title: SpiderMonkey Internals -slug: Mozilla/Projects/SpiderMonkey/Internals -tags: - - Guide - - JavaScript - - NeedsMarkupWork - - NeedsTranslation - - SpiderMonkey - - TopicStub -translation_of: Mozilla/Projects/SpiderMonkey/Internals ---- -

Design walk-through

- -

At heart, SpiderMonkey is a fast interpreter that runs an untyped bytecode and operates on values of type jsval—type-tagged double-sized values that represent the full range of JavaScript values. In addition to the interpreter, SpiderMonkey contains a Just-In-Time (JIT) compiler, a garbage collector, code implementing the basic behavior of JavaScript values, a standard library implementing ECMA 262-3 §15 with various extensions, and a few public APIs.

- -

Interpreter

- -

Like many portable interpreters, SpiderMonkey's interpreter is mainly a single, tremendously long function that steps through the bytecode one instruction at a time, using a switch statement (or faster alternative, depending on the compiler) to jump to the appropriate chunk of code for the current instruction. A JS-to-JS function call pushes a JavaScript stack frame without growing the C stack. But since JS-to-C-to-JS call stacks are common, the interpreter is reentrant.

- -

Some SpiderMonkey bytecode operations have many special cases, depending on the type of their arguments. Common cases are inlined in the interpreter loop, breaking any abstractions that stand in the way. So optimizations such as dense arrays and the property cache are, alas, not transparently tucked away in the jsarray.* and jsobj.* files. Both guest-star in jsinterp.cpp (to thunderous applause from Firefox users).

- -

All state associated with an interpreter instance is passed through formal parameters to the interpreter entry point; most implicit state is collected in a type named JSContext. Therefore, almost all functions in SpiderMonkey, API or not, take a JSContext pointer as their first argument.

- -

Compiler

- -

The compiler consumes JavaScript source code and produces a script which contains bytecode, source annotations, and a pool of string, number, and identifier literals. The script also contains objects, including any functions defined in the source code, each of which has its own, nested script.

- -

The compiler consists of: a random-logic rather than table-driven lexical scanner, a recursive-descent parser that produces an AST, and a tree-walking code generator. Semantic and lexical feedback are used to disambiguate hard cases such as missing semicolons, assignable expressions ("lvalues" in C parlance), and whether / is the division symbol or the start of a regular expression. The compiler attempts no error recovery; it bails out on the first error. The emitter does some constant folding and a few codegen optimizations; about the fanciest thing it does is to attach source notes to the script for the decompiler's benefit.

- -

The decompiler implements Function.toSource(), which reconstructs a function's source code. It translates postfix bytecode into infix source by consulting a separate byte-sized code, called source notes, to disambiguate bytecodes that result from more than one grammatical production.

- -

Garbage collector

- -

The GC is a mark-and-sweep, non-conservative (exact) collector. It is used to hold JS objects and string descriptors (but not property lists or string bytes), and double-precision floating point numbers. It runs automatically only when maxbytes (as passed to JS_NewRuntime) bytes of GC things have been allocated and another thing-allocation request is made. JS API users should call JS_GC or JS_MaybeGC between script executions or from the branch callback, as often as necessary.

- -

Because the GC is exact, C/C++ applications must ensure that all live objects, strings, and numbers are GC-reachable. Many techniques are available; see SpiderMonkey Garbage Collection Tips.

- -

JavaScript values

- -

The type jsval represents a JavaScript value.

- -

The representation is 64 bits and uses NaN-boxing on all platforms, although the exact NaN-boxing format depends on the platform. NaN-boxing is a technique based on the fact that in IEEE-754 there are 2**47 different bit patterns that all represent NaN. Hence, we can encode any floating-point value as a C++ double (noting that JavaScript NaN must be represented as one canonical NaN format). Other values are encoded as a value and a type tag:

- - - -

Only JIT code really depends on the layout--everything else in the engine interacts with values through functions like JSVAL_IS_INT. Most parts of the JIT also avoid depending directly on the layout: the files PunboxAssembler.h and NunboxAssembler.h are used to generate native code that depends on the value layout.

- -

Objects consist of a possibly shared structural description, called the map or scope; and unshared property values in a vector, called the slots. Each property has an id, either a nonnegative integer or an atom (unique string), with the same tagged-pointer encoding as a jsval.

- -

The atom manager consists of a hash table associating strings uniquely with scanner/parser information such as keyword type, index in script or function literal pool, etc. Atoms play three roles: as literals referred to by unaligned 16-bit immediate bytecode operands, as unique string descriptors for efficient property name hashing, and as members of the root GC set for exact GC.

- -

Standard library

- -

The methods for arrays, booleans, dates, functions, numbers, and strings are implemented using the JS API. Most are JSNatives. Most string methods are customized to accept a primitive string as the this argument. (Otherwise, SpiderMonkey converts primitive values to objects before invoking their methods, per ECMA 262-3 §11.2.1.)

- -

Error handling

- -

SpiderMonkey has two interdependent error-handling systems: JavaScript exceptions (which are not implemented with, or even compatible with, any kind of native C/C++ exception handling) and error reporting. In general, both functions inside SpiderMonkey and JSAPI callback functions signal errors by calling JS_ReportError or one of its variants, or JS_SetPendingException, and returning JS_FALSE or NULL.

- -

Public APIs

- -

The public C/C++ interface, called the JSAPI, is in most places a thin (but source-compatible across versions) layer over the implementation. See the JSAPI User Guide. There is an additional public API for JavaScript debuggers, JSDBGAPI, but {{Source("js/jsd/jsdebug.h")}} might be a better API for debuggers. Another API, JSXDRAPI, provides serialization for JavaScript scripts. (XUL Fastload uses this.)

- -

Just-In-Time compiler

- -

{{jsapi_minversion_inline("1.8.5")}} SpiderMonkey contains a just-in-time compiler, code-named JägerMonkey, that converts bytecode to machine code for faster execution. The JIT works by detecting commonly executed functions or functions containing hot loops and then compiling these methods into machine code.

- -

A second JIT, code-named IonMonkey was enabled in Firefox 18.

- -

Self-hosting of builtin functions in JS

- -

Starting with Firefox 17, SpiderMonkey has the ability to implement builtin functions in self-hosted JS code. This code is compiled in a special compilation mode that gives it access to functionality that's not normally exposed to JS code, but that's required for safe and specification-conformant implementation of builtin functions.

- -

All self-hosted code lives in .js files under builtin/. For details on implementing self-hosted builtins, see self-hosting.

- -

File walkthrough

- -

jsapi.cpp, jsapi.h

- -

The public API to be used by almost all client code.

- -

jspubtd.h, jsprvtd.h

- -

These files exist to group struct and scalar typedefs so they can be used everywhere without dragging in struct definitions from N different files. The jspubtd.h file contains public typedefs, and is included automatically when needed. The jsprvtd.h file contains private typedefs and is included by various .h files that need type names, but not type sizes or declarations.

- -

jsdbgapi.cpp, jsdbgapi.h

- -

The debugging API. Provided so far:

- -

Traps, with which breakpoints, single-stepping, step over, step out, and so on can be implemented. The debugger will have to consult jsopcode.def on its own to figure out where to plant trap instructions to implement functions like step out, but a future jsdbgapi.h will provide convenience interfaces to do these things. At most one trap per bytecode can be set. When a script (JSScript) is destroyed, all traps set in its bytecode are cleared.

- -

Watchpoints, for intercepting set operations on properties and running a debugger-supplied function that receives the old value and a pointer to the new one, which it can use to modify the new value being set.

- -

Line number to PC and back mapping functions. The line-to-PC direction "rounds" toward the next bytecode generated from a line greater than or equal to the input line, and may return the PC of a for-loop update part, if given the line number of the loop body's closing brace. Any line after the last one in a script or function maps to a PC one byte beyond the last bytecode in the script. An example, from perfect.js:

- -
function perfect(n) {
-  print("The perfect numbers up to " + n + " are:");
-  // We build sumOfDivisors[i] to hold a string expression for
-  // the sum of the divisors of i, excluding i itself.
-  var sumOfDivisors = new ExprArray(n+1,1);
-  for (var divisor = 2; divisor <= n; divisor++) {
-    for (var j = divisor + divisor; j <= n; j += divisor) {
-      sumOfDivisors[j] += " + " + divisor;
-    }
-    // At this point everything up to 'divisor' has its sumOfDivisors
-    // expression calculated, so we can determine whether it's perfect
-    // already by evaluating.
-    if (eval(sumOfDivisors[divisor]) == divisor) {
-      print("" + divisor + " = " + sumOfDivisors[divisor]);
-    }
-  }
-  delete sumOfDivisors;
-  print("That's all.");
-}
- -

The line number to PC and back mappings can be tested using the js program with the following script:

- -
load("perfect.js");
-print(perfect);
-dis(perfect);
-print();
-for (var ln = 0; ln <= 40; ln++) {
-    var pc = line2pc(perfect, ln);
-    var ln2 = pc2line(perfect, pc);
-    print("\tline " + ln + " => pc " + pc + " => line " + ln2);
-}
-
- -

The result of the for loop over lines 0 to 40 inclusive is:

- -
line 0 => pc 0 => line 16
-line 1 => pc 0 => line 16
-line 2 => pc 0 => line 16
-line 3 => pc 0 => line 16
-line 4 => pc 0 => line 16
-line 5 => pc 0 => line 16
-line 6 => pc 0 => line 16
-line 7 => pc 0 => line 16
-line 8 => pc 0 => line 16
-line 9 => pc 0 => line 16
-line 10 => pc 0 => line 16
-line 11 => pc 0 => line 16
-line 12 => pc 0 => line 16
-line 13 => pc 0 => line 16
-line 14 => pc 0 => line 16
-line 15 => pc 0 => line 16
-line 16 => pc 0 => line 16
-line 17 => pc 19 => line 20
-line 18 => pc 19 => line 20
-line 19 => pc 19 => line 20
-line 20 => pc 19 => line 20
-line 21 => pc 36 => line 21
-line 22 => pc 53 => line 22
-line 23 => pc 74 => line 23
-line 24 => pc 92 => line 22
-line 25 => pc 106 => line 28
-line 26 => pc 106 => line 28
-line 27 => pc 106 => line 28
-line 28 => pc 106 => line 28
-line 29 => pc 127 => line 29
-line 30 => pc 154 => line 21
-line 31 => pc 154 => line 21
-line 32 => pc 161 => line 32
-line 33 => pc 172 => line 33
-line 34 => pc 172 => line 33
-line 35 => pc 172 => line 33
-line 36 => pc 172 => line 33
-line 37 => pc 172 => line 33
-line 38 => pc 172 => line 33
-line 39 => pc 172 => line 33
-line 40 => pc 172 => line 33
-
- -

jsconfig.h

- -

Various configuration macros defined as 0 or 1 depending on how JS_VERSION is defined (as 10 for JavaScript 1.0, 11 for JavaScript 1.1, etc.). Not all macros are tested around related code yet. In particular, JS 1.0 support is missing from SpiderMonkey.

- -

js.cpp, jsshell.msg

- -

The "JS shell", a simple interpreter program that uses the JS API and more than a few internal interfaces (some of these internal interfaces could be replaced by jsapi.h calls). The js program built from this source provides a test vehicle for evaluating scripts and calling functions, trying out new debugger primitives, etc.

- -

A look at the places where jsshell.msg is used in js.cpp shows how error messages can be handled in JSAPI applications. These messages can be localized at compile time by replacing the .msg file; or, with a little modification to the source, at run time.

- -

More information on the JavaScript shell.

- -

js.msg

- -

SpiderMonkey error messages.

- -

jsarray.*, jsbool.*, jsdate.*, jsfun.*, jsmath.*, jsnum.*, jsstr.*

- -

These file pairs implement the standard classes and (where they exist) their underlying primitive types. They have similar structure, generally starting with class definitions and continuing with internal constructors, finalizers, and helper functions.

- -

jsobj.*, jsscope.*

- -

These two pairs declare and implement the JS object system. All of the following happen here:

- - - -

The details of a native object's map (scope) are mostly hidden in jsscope.{{mediawiki.external('ch')}}.

- -

jsatom.cpp, jsatom.h

- -

The atom manager. Contains well-known string constants, their atoms, the global atom hash table and related state, the js_Atomize() function that turns a counted string of bytes into an atom, and literal pool (JSAtomMap) methods.

- -

jsarena.cpp, jsarena.h

- -

Last-In-First-Out allocation macros that amortize malloc costs and allow for en-masse freeing. See the paper mentioned in jsarena.h's major comment.

- -

jsgc.cpp, jsgc.h

- -

The garbage collector and tracing routines.

- -

jsinterp.*, jscntxt.*, jsinvoke.cpp

- -

The bytecode interpreter, and related functions such as Call and AllocStack, live in jsinterp.cpp. The JSContext constructor and destructor are factored out into jscntxt.cpp for minimal linking when the compiler part of JS is split from the interpreter part into a separate program.

- -

jsinvoke.cpp is a build hack used on some platforms to build js_Interpret under different compiler options from the rest of jsinterp.cpp.

- -

jstracer.*, nanojit/*

- -

The tracing JIT. The interface between the JIT and the rest of SpiderMonkey is conceptually small—the interpreter calls into the trace recorder—but as with everything else, there are tendrils everywhere.

- -

jsemit.*, jsopcode.tbl, jsopcode.*, jsparse.*, jsscan.*, jsscript.*

- -

Compiler and decompiler modules. The jsopcode.tbl file is a C preprocessor source that defines almost everything there is to know about JS bytecodes. See its major comment for how to use it. For now, a debugger will use it and its dependents such as jsopcode.h directly, but over time we intend to extend jsdbgapi.h to hide uninteresting details and provide conveniences. The code generator is split across paragraphs of code in jsparse.cpp, and the utility methods called on JSCodeGenerator appear in jsemit.cpp. Source notes generated by jsparse.cpp and jsemit.cpp are used in jsscript.cpp to map line number to program counter and back.

- -

jstypes.h

- -

Fundamental representation types and utility macros. This file alone among all .h files in SpiderMonkey must be included first by .cpp files. It is not nested in .h files, as other prerequisite .h files generally are, since it is also a direct dependency of most .cpp files and would be over-included if nested in addition to being directly included.

- -

jsbit.h, jslog2.cpp

- -

Bit-twiddling routines. Most of the work here is selectively enabling compiler-specific intrinsics such as GCC's __builtin_ctz, which is useful in calculating base-2 logarithms of integers.

- -

jsutil.cpp, jsutil.h

- -

The JS_ASSERT macro is used throughout the source as a proof device to make invariants and preconditions clear to the reader, and to hold the line during maintenance and evolution against regressions or violations of assumptions that it would be too expensive to test unconditionally at run-time. Certain assertions are followed by run-time tests that cope with assertion failure, but only where I'm too smart or paranoid to believe the assertion will never fail...

- -

jsclist.h

- -

Doubly-linked circular list struct and macros.

- -

jscpucfg.cpp

- -

This standalone program generates jscpucfg.h, a header file containing bytes per word and other constants that depend on CPU architecture and C compiler type model. It tries to discover most of these constants by running its own experiments on the build host, so if you are cross-compiling, beware.

- -

jsdtoa.cpp, jsdtoa.h, dtoa.c

- -

dtoa.c contains David Gay's portable double-precision floating point to string conversion code, with Permission To Use notice included. jsdtoa.cpp #includes this file.

- -

jshash.cpp, jshash.h, jsdhash.cpp, jsdhash.h

- -

Portable, extensible hash tables. These use multiplicative hash for strength reduction over division hash, yet with very good key distribution over power of two table sizes. jshash resolves collisions via chaining, so each entry burns a malloc and can fragment the heap. jsdhash uses open addressing.

- -

jslong.cpp, jslong.h

- -

64-bit integer emulation, and compatible macros that use intrinsic C types, like long long, on platforms where they exist (most everywhere, these days).

- -

jsprf.*

- -

Portable, buffer-overrun-resistant sprintf and friends. For no good reason save lack of time, the %e, %f, and %g formats cause your system's native sprintf, rather than JS_dtoa(), to be used. This bug doesn't affect SpiderMonkey, because it uses its own JS_dtoa() call in jsnum.cpp to convert from double to string, but it's a bug that we'll fix later, and one you should be aware of if you intend to use a JS_*printf() function with your own floating type arguments - various vendor sprintf's mishandle NaN, +/-Inf, and some even print normal floating values inaccurately.

- -

prmjtime.c, prmjtime.h

- -

Time functions. These interfaces are named in a way that makes local vs. universal time confusion likely. Caveat emptor, and we're working on it. To make matters worse, Java (and therefore JavaScript) uses "local" time numbers (offsets from the epoch) in its Date class.

- -

jsfile.cpp, jsfile.h, jsfile.msg

- -

Obsolete. Do not use these files.

- -

Makefile.in, build.mk

- -

Mozilla makefiles. If you're building Gecko or Firefox, the larger build system will use these files. They are also used for current standalone builds.

- -

Makefile.ref, rules.mk, config.mk, config/*

- -

Obsolete SpiderMonkey standalone makefiles from 1.8 and earlier. See SpiderMonkey Build Documentation.

- -

See also

- - diff --git a/files/zh-cn/mozilla/projects/spidermonkey/introduction_to_the_javascript_shell/index.html b/files/zh-cn/mozilla/projects/spidermonkey/introduction_to_the_javascript_shell/index.html deleted file mode 100644 index b570b78d56..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/introduction_to_the_javascript_shell/index.html +++ /dev/null @@ -1,382 +0,0 @@ ---- -title: JavaScript shell 介绍 -slug: Mozilla/Projects/SpiderMonkey/Introduction_to_the_JavaScript_shell -tags: - - SpiderMonkey - - 蜘蛛猴 -translation_of: Mozilla/Projects/SpiderMonkey/Introduction_to_the_JavaScript_shell ---- -
{{SpiderMonkeySidebar("General")}}
- -
-

JavaScript shell 是一个命令行程序,它被包含在SpiderMonkey源代码中。它在 JavaScript 中类似于 Python 命令行、Lisp 读取执行循环和 Ruby 中的 irb 。这篇文章解释如何使用 shell 去测试 JavaScript 代码和执行 JavaScript 程序。

-
- -

要获取 SpiderMonkey JavaScript shell, 请参见 SpiderMonkey 构建文档 或根据你的平台从 Nightly Builds 下载二进制文件。

- -

对于其他的 JavaScript shells, 参考 JavaScript shells.

- -
-

注意: 从 SpiderMonkey 44 开始,默认情况下使用标准的、与 Web 兼容的 JavaScript 版本(不再使用JS1.7 +)。 内置的 version() 内置函数仍然可以用来测试遗留功能。

-
- -

执行JavaScript shell

- -

jsshell 提供两种操作模式。你既可以交互式操作 shell, 在此模式你可以输入JavaScript 代码并执行。便于实验和测试新特性。你也可以在命令行参数指定一个 JavaScript 代码文件,此文件会自动运行。

- -

在安装 jsshell 之后,你可以执行以下命令打开交互式终端:

- -
js
-
- -
-

注意:如果你在预编译程序执行中遇到
- "symbol lookup error: ./js: undefined symbol: PR_SetCurrentThreadName"
- 这样的错误, 请尝试用 run-mozilla.sh 文件执行它:
- run-mozilla.sh ./js  
- ——我测试过有效

-
- -

如果运行 foo.js file中的JavaScript代码,你可以使用以下命令:

- -
js foo.js
-
- -

如果想运行 foo.js 然后进入交互模式:

- -
js -f foo.js -i
-
- -

说明

- -
注意: 因为JavaScript shell 用来给 JavaScript 引擎做测试环境, 可用的选项和内置函数可能改变。
- -

命令行选项

- -

有许多命令行选项可以控制shell,以下为总结。使用-h选项显示帮助

- -
-
-c, --compileonly
-
仅编译不执行代码,这是一种方便的检查语法错误的方式。
-
-e script
-
运行指定脚本,script 是将要执行的代码字符串。
-
-f filename
-
执行指定的代码文件。
-
-i
-
启用交互模式。(如果参数中没有文件名这个选项默认打开)
-
--no-ion
-
禁用优化的 JIT 编译器。
-
--no-baseline
-
禁用基准的 JIT 编译器。
-
-P
-
如果文件的第一行是 "/usr/bin/env js -P",文件内容将通过 JavaScript 引擎解释执行。
-
这将允许你在 unix 和 OS X 系统上执行 JavaScript 文件。
-
-s
-
启用严格警告模式.
-
-w, --warnings
-
显示警告消息.
-
-W, --nowarnings
-
隐藏警告消息.
-
- -

环境选项

- -

如果设置了这些环境变量,它们将会影响 js shell 的行为。

- -
-
JS_STDOUT=file
-
将标准输出重定向到文件file
-
JS_STDERR=file
-
将标准输入重定向到文件file
-
- -

内置函数

- -

为了使 JavaScript shell 更加实用, 我们提供了一些内置的函数供 JavaScript 程序(包括交互模式下)使用。

- -
-

注意:这个列表是不完整的而且与 Shell 全局对象 重复。请参见{{Source("js/src/shell/js.cpp")}} (在 shell_functions 附近) 以获取详细信息。

-
- -

build()

- -

返回 JavaScript shell 构建的日期和时间.

- -
Note: clear() 函数如果不带任何参数,将清除包括所有内置方法在内的所有东西。
- -

clone(function, [scope])

- -

克隆指定函数对象。如果未指定具体域,新对象的父本和原始对象的相同。否则,新对象被放置于指定域。

- -

countHeap([start[, kind]])

- -

{{ jsapi_minversion_inline("1.8") }}   计算堆中活动的回收垃圾数量,或计算给定且不为 null 的可从 start 到达的对象的数量。kind 是“all”(默认)以计算所有事物,或者是“ object”,“ double”,“ string”,“ function”,“ qname”,“ namespace”,“ xml”之一以仅计算此类事物

- -

dumpHeap([fileName[, start[, toFind[, maxDepth[, toIgnore]]]]])

- -

{{ jsapi_minversion_inline("1.8") }} 转储所有现存对象的数据 (或有关联的子数据) 到文件。详情参见本函数的C/C++版本: JS_DumpHeap.

- -

evalcx(string[, object])

- -

执行 string 中的 JavaScript 代码。如果设置了参数 object,代码将在这个对象中执行,将其视为一个沙盒。

- -

string 为空且没有设置 object 时,evalcx() 将会返回一个具有“eager” 标准类的新对象

- -

string 为 "lazy" 且没有设置 object 时,evalcx() 将会返回一个具有“lazy” 标准类的新对象

- -
注意: evalcx() 仅对进行 JavaScript 引擎极低层工作的开发者有用,用于在 shell 中测试类evalInSandbox 环境
- -

gc()

- -

运行垃圾收集器释放内存。

- -

gcparam(name[, value])

- -

{{ jsapi_minversion_inline("1.8") }} 读取或配置垃圾收集器参数。

- -

名称必须是参数key之一 (例如 'maxBytes', 'maxMallocBytes''gcNumber').

- -

如果value未指定,gcparam()返回与GC参数名name相关联的当前值

- -

如果value被指定,其必须可转换为uint32,gcparam()将GC参数名设置为value。

- -

For more information, see the C/C++ functions  JS_SetGCParameter and JS_SetGCParameter.

- -

gczeal(level)

- -

{{ jsapi_minversion_inline("1.8") }} DEBUG only. 设置GC zeal级别, 这是一个调试特性。0 是正常的周期性垃圾收集,1是频繁的GC, 2是及其频繁的GC. 除了0以外的都将使JavaScript运行极其缓慢但是可能有助于发现GC相关的 bug. For more information, see the C/C++ version of this function, JS_SetGCZeal.

- -

getpda(object)

- -

返回指定对象的属性描述

- -

getslx(object)

- -

返回脚本行范围,这是包含指定对象的代码行数

- -

help([command ...])

- -

显示有关指定命令或所有可用功能的简要帮助信息(如果未指定命令将显示所有帮助信息)。

- -

intern(string)

- -

将指定的字符串 内化到atom表中。每个字符串都有一个唯一的标识符,称为atom。这个系统使得对字符串进行比较变得更加容易。

- -
Note: This function is intended only for use when testing the JavaScript engine.
- -

line2pc([function, ] line)

- -

返回对应于指定行的代码行的程序计数器值。如果指定了函数,那么行就是指定函数的偏移量.

- -

load(filename1 [filename])

- -

加载带有指定名称的JavaScript文件.

- -
Note: For loading non-JavaScript files, use read().
- -

options([option ...])

- -

让你设置或获取选项。如果您在命令行上指定选项,那么调用options的结果将指示您所请求的选项。您还可以传递新的选项来设置.

- -

The available options are:

- - - - - - - - - - - - - - - - - - - - -
Option NameDescription
strict严格模式 is enabled.
werrorWarnings should be treated as errors.
atlineWhen atline is enabled, 表单的注释 //@line num set the number of the following line to num.
- -

pc2line(function, [pc])

- -

返回对应于指定函数的第一行的JavaScript代码的行号. If you specify a program counter offset into the function, the line number of the line of code containing that offset is returned.

- -

print([expression ...])

- -

Evaluates the expression(s) and displays the result(s) on stdout, 分隔 by spaces (" ") and 终止 by a newline ("\n").

- -

putstr(expression)

- -

Evaluates the expression and displays the result on stdout.

- -

quit([status])

- -

Exits the shell. 如果省略,状态默认为0。

- -

read(filename[, type])

- -

Reads and returns the contents of file. If type is "binary" returns an Uint8Array, otherwise returns an UTF-8 decoded string.

- -

readline()

- -

Reads a single line of input from stdin, returning it to the caller. You can use this to create interactive shell programs in JavaScript.

- -

Reflect.parse()

- -

See Parser API.

- -
Note: This function is intended only for use when testing the JavaScript engine.
- -

seal(object[, deep])

- -

密封指定的对象, or an object graph if deep is true. 通过封住对象或对象图,可以禁用这些对象的修改.

- -

sleep(dt)

- -

{{ jsapi_minversion_inline("1.8") }} Only in JS_THREADSAFE builds. Sleep for dt seconds. Fractions of a second are supported. Returns true on success, false if the sleep was interrupted.

- -

stackQuota([number]) {{obsolete_inline}}

- -

{{ jsapi_minversion_inline("1.8") }} 获取或设置脚本堆栈配额.

- -

throwError()

- -

Throws an error from the JS_ReportError() function.

- -
Note: This function is intended only for use when testing the JavaScript engine.
- -

trap([function, [pc,]] expression)

- -

在JavaScript代码的特定点设置trap. 当由pc在函数函数中指定的偏移量即将被执行时,表达式将被求值。

- -

这是一种强大的调试机制,与line2pc()一起使用. 例如, 如果你想在函数的第6行中显示一条消息, doSomething() 被执行, you can enter the following:

- -
trap(doSomething, line2pc(doSomething, 6), "print('line 6!\n')");
-
- -
Note: 当设置陷阱时,程序中的相应字节码将被trap字节码替换,直到您使用untrap() 来移除陷阱。
- -

untrap(function [, pc])

- -

Removes a trap from the specified function at the offset pc. If pc isn't specified, the trap is removed from the function's entry point.

- -

This function has no effect if there is no trap at the specified location.

- -

version([number])

- -

The version() function lets you get or set the JavaScript version number. This may be useful for gaining access to syntax only available in certain versions of JavaScript (for example, see Using JavaScript 1.7).

- -

调试方法

- -

These built-in functions are only available in DEBUG builds.

- -

dis([function])

- -

为整个程序或指定的函数分解JavaScript字节码

- -

For example, if you enter the JavaScript function below:

- -
function test() {
-  var i = 3;
-  print(i+2);
-}
-
- -

Then run the command dis(test);, you get this output:

- -
main:
-00000:  uint16 3
-00003:  setvar 0
-00006:  pop
-00007:  name "print"
-00010:  pushobj
-00011:  getvar 0
-00014:  uint16 2
-00017:  add
-00018:  call 1
-00021:  pop
-00022:  stop
-
-Source notes:
-  0:     0 [   0] newline
-  1:     3 [   3] decl     offset 0
-  2:     7 [   4] newline
-  3:    18 [  11] xdelta
-  4:    18 [   0] pcbase   offset 11
-
- -

dissrc([function])

- -

Disassembles the JavaScript bytecode for the entire program, or for the specified function, showing the source lines. This function only works with programs loaded from files, either using the -f flag on launching the shell, or by using the load() function.

- -

If your program includes a function, doStuff(), like this:

- -
function doStuff(input) {
-	print("Enter a number: ");
-	var n1 = readline();
-	print("Enter another one: ");
-	var n2 = readline();
-
-	print("You entered " + n1 + " and " + n2 + "\n");
-}
-
- -

Calling dissrc(doStuff) function would give this output:

- -
;-------------------------  10:         print("Enter a number: ");
-00000:  10  name "print"
-00003:  10  pushobj
-00004:  10  string "Enter a number: "
-00007:  10  call 1
-00010:  10  pop
-;-------------------------  11:         var n1 = readline();
-00011:  11  name "readline"
-00014:  11  pushobj
-00015:  11  call 0
-00018:  11  setvar 0
-00021:  11  pop
-;-------------------------  12:         print("Enter another one: ");
-00022:  12  name "print"
-00025:  12  pushobj
-00026:  12  string "Enter another one: "
-00029:  12  call 1
-00032:  12  pop
-;-------------------------  13:         var n2 = readline();
-00033:  13  name "readline"
-00036:  13  pushobj
-00037:  13  call 0
-00040:  13  setvar 1
-00043:  13  pop
-;-------------------------  14:
-;-------------------------  15:         print("You entered " + n1 + " and " + n2 + "\n");
-00044:  15  name "print"
-00047:  15  pushobj
-00048:  15  string "You entered "
-00051:  15  getvar 0
-00054:  15  add
-00055:  15  string " and "
-00058:  15  add
-00059:  15  getvar 1
-00062:  15  add
-00063:  15  string "\\n"
-00066:  15  add
-00067:  15  call 1
-00070:  15  pop
-00071:  15  stop
-
- -

dumpheap(([fileName[, start[, toFind[, maxDepth[, toIgnore]]]]])

- -

Dump GC information. This is a thin wrapper for JS_DumpHeap.

- -

gczeal(zeal)

- -

Enable extra-frequent GC, to help find GC hazards. zeal is an integer. The meaning is the same as for the parameter to JS_SetGCZeal.

- -

notes([function])

- -

Shows the source notes for the specified function. Source notes contain information that map the bytecode to the source code, which is used when decompiling the code, such as when using the dissrc() function.

diff --git "a/files/zh-cn/mozilla/projects/spidermonkey/javascript-c\345\274\225\346\223\216\345\265\214\345\205\245\345\274\200\345\217\221\346\214\207\345\215\227/index.html" "b/files/zh-cn/mozilla/projects/spidermonkey/javascript-c\345\274\225\346\223\216\345\265\214\345\205\245\345\274\200\345\217\221\346\214\207\345\215\227/index.html" deleted file mode 100644 index 4752df82f3..0000000000 --- "a/files/zh-cn/mozilla/projects/spidermonkey/javascript-c\345\274\225\346\223\216\345\265\214\345\205\245\345\274\200\345\217\221\346\214\207\345\215\227/index.html" +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: JavaScript-C引擎嵌入开发指南 -slug: Mozilla/Projects/SpiderMonkey/JavaScript-C引擎嵌入开发指南 -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide ---- -

查看Nirvana Studio上的翻译 -


-

-
-
-{{ languages( { "en": "en/JSAPI_User_Guide", "ja": "ja/Embedding_SpiderMonkey" } ) }} diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/boolean_to_jsval/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/boolean_to_jsval/index.html deleted file mode 100644 index 80747881fd..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/boolean_to_jsval/index.html +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: BOOLEAN_TO_JSVAL -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/BOOLEAN_TO_JSVAL -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/BOOLEAN_TO_JSVAL ---- -
{{SpiderMonkeySidebar("JSAPI")}}
- -
{{ obsolete_header("jsapi42") }}
- -
-

Cast a C integer to a boolean {{jsapixref("JS::Value")}} without any type checking or error handling.

-
- -
-

Please use {{jsapixref("JS::BooleanValue")}}/{{jsapixref("JS::TrueValue")}}/{{jsapixref("JS::FalseValue")}} instead in SpiderMonkey 45 or later.

-
- -

Syntax

- -
jsval
-BOOLEAN_TO_JSVAL(bool b);
-
- - - - - - - - - - - - - - -
NameTypeDescription
bboolC integer value to be converted to a boolean jsval.
- -

Description

- -

BOOLEAN_TO_JSVAL converts a bool argument, b, to a boolean jsval.

- -

If b is false, the result is JSVAL_FALSE.

- -

If b is true, the result is JSVAL_TRUE.

- -

See Also

- - diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/index.html deleted file mode 100644 index d076928fba..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/index.html +++ /dev/null @@ -1,646 +0,0 @@ ---- -title: JSAPI 参考 -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference ---- -

JSAPI SpiderMonkey JavaScript 引擎的C 语言应用程序接口(API)。要了解如何使用JSAPI ,请看 JSAPI User Guide and the JSAPI Phrasebook

-


- Alphabetical List

-

运行时和上下文

- - - - - -

Locale callbacks:

- -

Locale callback types:

- -

脚本

-

Just running some JavaScript code is straightforward:

-

只是运行一些JavaScript代码很简单:

- -

You can instead compile JavaScript code into a JSScript which you can then execute multiple times.

-

你可以将JavaScript代码编译后保存在JSScript类型的变量中,这样就可以多次执行。

-

typedef JSScript

- -

You can also compile JavaScript code into a function:

- -

 

-

错误处理

- -

The following functions allow C/C++ functions to throw and catch JavaScript exceptions:

- - -

These functions translate errors into exceptions and vice versa:

- -

值和类型

- -

jsval constants:

- -

Function and macros for checking the type of a jsval:

- -

High-level type-conversion routines for packing and unpacking function arguments.

- - -

The following functions convert JS values to various types. They can be safely applied to jsvals of any type. They may return new objects. For example, JS_ValueToObject(cx, s) where s is a string creates a new String wrapper object. These functions may call JavaScript methods. For example, JS_ValueToString(cx, obj) may call obj.toString().

- -

Fast, unchecked type-casting macros. These macros must not be applied to values that are not known to be the right type. Like C casts, they may cause crashes if applied to incorrect values. They never create new objects or call into JavaScript code.

- -

And:

- -

Memory management

-

These functions act like the Standard C malloc family of functions, except that errors are reported using the SpiderMonkey error APIs rather than errno. These functions also allow SpiderMonkey to account the number of bytes allocated:

- -

JavaScript objects, strings, and floating-point numbers are garbage collected. These functions provide access to the garbage collector:

- -

The rest of these APIs help protect objects from being destroyed by the garbage collector before the application is done using them.

-

If a variable is a root, then anything it points to will not be freed by the garbage collector. Failure to root objects is a very common cause of mysterious crashes.

- -

Local root scopes are another way of protecting objects from the garbage collector.

- -

{{ Jsapi_minversion_inline("1.8 (not yet released)") }} If an object contains references to other GC things that are not stored in SpiderMonkey data structures ("slots"), it must implement the JSTraceOp hook to enable the garbage collector to traverse those references. Otherwise the garbage collector will not find all reachable objects and may collect objects that are still reachable, leading to a crash. (In SpiderMonkey 1.7 and earlier, the JSMarkOp hook is used instead. This will be deprecated when SpiderMonkey 1.8 is released.)

-

The tracing APIs are used by the garbage collector and JSTraceOp hooks. JSAPI applications may also use them to examine the object graph. (For example, these APIs support very smooth integration between the JS garbage collector and other garbage collectors.)

- -

Miscellaneous GC APIs:

- -

Numbers

- -

字符串

- - -

Interning strings tells the SpiderMonkey engine to reuse existing string objects when possible.

- -

The character data for external strings is stored in memory provided by the application. Applications can use this to avoid copying data back and forth between SpiderMonkey's heap and application memory.

- -

对象

- - -

属性

-

These functions correspond directly to the ways scripts access object properties:

- -

The following functions are lower-level, allowing the JSAPI application more access to details of how properties are implemented. "Define" is a lower-level version of "set" that provides access to extra settings and does not call setters. Similarly, "lookup" is a lower-level version of "get" that offers extra options and does not call getters.

- -

The following functions behave like JS_GetProperty except when operating on E4X XML objects.

- -

A SpiderMonkey extension allows a native function to return an lvalue—that is, a reference to a property of an object:

- -

A jsid is kind of like a jsval, only different. A handful of APIs use jsids instead of jsvals for property names: JS_CheckAccess, JS_Enumerate, JS_GetMethodById, and JS_NextProperty.

- -

Classes

-

These API features are used to define custom classes—object types that are implemented in C/C++ code but accessible from JavaScript.

- -

Adding native properties and methods to classes:

- -

JSFastNative methods use these macros:

- -

The behavior of a JSClass and its instances can be customized in many ways using callback functions.

-

JSClass method types:

- -

JSExtendedClass method types:

- -

JSObjectOps method types:

- -

JSXMLObjectOps method types:

- -

These stub functions can be used when creating a custom JSClass:

- -

The behavior of a JSClass can be customized using these flags:

- -

Arrays

- - - -

Functions

-

Calling a function or a method of an object:

- -

Function accessors:

- -

Creating functions:

- -

RegExps

- -

Security

- - -

Threading

-

The following functions support the SpiderMonkey threading model. They are only available in JS_THREADSAFE builds.

- -

The following functions exist in all builds, but in non-JS_THREADSAFE builds, they do nothing:

- -

Time

- -

Callback Types

-

Native function types:

- -

Other callback types:

- -

See also Classes, above.

-

Macros

- -

Preprocessor conditionals

- -

These defines are useful for tuning SpiderMonkey performance:

- -

C++ features

- -

{{ languages( { "ja": "ja/JSAPI_Reference", "pl": "pl/Dokumentacja_JSAPI" } ) }}

-

JSAPI 参考

-

 

-

数据结构

- diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_defineconstdoubles/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_defineconstdoubles/index.html deleted file mode 100644 index 82835b714d..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_defineconstdoubles/index.html +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: JS DefineConstDoubles -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_DefineConstDoubles -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_DefineConstDoubles ---- -

摘要

-

为对象创建一个或多个包含双浮点值的属性。

-

语法

-
  JSBool JS_DefineConstDoubles(JSContext *cx, JSObject *obj,
-    JSConstDoubleSpec *cds);
-
- - - - - - - - - - - - - - - - - - - - - - - -
名称类型描述
cxJSContext *指向JS运行时信息内容的指针。
objJSObject *指向新建的属性的对象指针。
cdsJSConstDoubleSpec *指向创建的包含双浮点属性值和属性名的结构化数组的指针。最后一个数组元素必须包含一个为零值的成员。
-

描述

-

JS_DefineConstDoubles为特定的对象创建一个或多个成员变量,obj, 每个成员变量包含一个双浮点类型的值。每个成员变量在JSConstDoubleSpec结构中的flags字段被自动声名并由cds传递指针。 如果flags被设为0值, 成员变量的属性会自动被设为JSPROP_PERMANENT 或 JSPROP_READONLY

-

cds 是一个指向具有JSConstDoubleSpec结构的数组的第一个元素的指针。每个数组元素定义独立的变量名和变量值。数组的最后一个元素的name字段必须是0。JS_DefineConstDoubles为数组中的每一个名称字段不为零的元素建立一个成员变量。

-

通常情况下, JS_DefineConstDoubles 返回 JS_TRUE, 表明它在数组中已经建立了所有的属性列表。除此之外的情况下它返回JS_FALSE

-

更多参考

- - - - - - - - - - - - - - - -
新闻组Functions
文档LXRSearch
章节 -

JSConstDoubleSpec, JS_DefineElement, JS_DefineFunction, JS_DefineFunctions, JS_DefineObject, JS_DefineProperties, JS_DefineProperty, JS_DefinePropertyWithTinyId

-
-

 

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_doublecolon_call/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_doublecolon_call/index.html deleted file mode 100644 index a0c3d1239a..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_doublecolon_call/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: 'JS::Call' -slug: 'Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::Call' -translation_of: 'Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::Call' ---- -
{{SpiderMonkeySidebar("JSAPI")}}
- -
{{ jsapi_minversion_header("17") }}
- - -
-

调用指定的JS函数。

-
- -

句法

- -
bool
-JS::Call(JSContext *cx, JS::HandleObject thisObj, JS::HandleFunction fun,
-         const JS::HandleValueArray &args, JS::MutableHandleValue rval);
-
-bool
-JS::Call(JSContext *cx, JS::HandleObject thisObj, const char *name,
-         const JS::HandleValueArray& args, JS::MutableHandleValue rval);
-
-bool
-JS::Call(JSContext *cx, JS::HandleObject thisObj, JS::HandleValue fun,
-         const JS::HandleValueArray& args, JS::MutableHandleValue rval);
-
-bool
-JS::Call(JSContext *cx, JS::HandleValue thisv, JS::HandleValue fun,
-         const JS::HandleValueArray& args, JS::MutableHandleValue rval);
-
-bool
-JS::Call(JSContext *cx, JS::HandleValue thisv, JS::HandleObject funObj,
-         const JS::HandleValueArray& args, JS::MutableHandleValue rval);
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称类型描述
cx{{jsapixref("JSRuntime", "JSContext *")}}指向JS上下文的指针,从中可以派生运行时信息。{{Jsapi-requires-request()}}
thisObj{{jsapixref("JSObject", "JS::HandleObject")}} / {{jsapixref("JS::Value", "JS::HandleValue")}}The "current" object on which the function operates; the object specified here is "this" when the function executes.
fun / funObj{{jsapixref("JSFunction", "JS::HandleFunction")}} / {{jsapixref("JS::Value", "JS::HandleValue")}} / {{jsapixref("JSObject", "JS::HandleObject")}}Pointer to the function to call. Should be a native function or JSAPI-compiled function.
nameconst char *Pointer to the function name to call.
args{{jsapixref("JS::HandleValueArray", "JS::HandleValueArray &")}}Arguments to pass to the function.
rval{{jsapixref("JS::Value", "JS::MutableHandleValue")}}Out parameter. On success, *rval receives the return value from the function call.
- -

Description

- -

JS::Callfun在对象上调用指定的函数thisObj在函数执行方面,该对象被视为this

- -

有关更多详细信息,请参阅{{jsapixref("JS_CallFunction")}},{{jsapixref("JS_CallFunctionName")}}和{{jsapixref("JS_CallFunctionValue")}}。

- -

也可以看看

- - diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_doublecolon_ordinarytoprimitive/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_doublecolon_ordinarytoprimitive/index.html deleted file mode 100644 index b09164ee56..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_doublecolon_ordinarytoprimitive/index.html +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: 'JS::OrdinaryToPrimitive' -slug: 'Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::OrdinaryToPrimitive' -translation_of: 'Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::OrdinaryToPrimitive' ---- -
{{SpiderMonkeySidebar("JSAPI")}}
- -

{{ jsapi_minversion_header("38") }}

- -
-

将普通对象转换为原始值

-
- -

语法说明

- -
bool
-JS::OrdinaryToPrimitive(JSContext *cx, JS::HandleObject obj, JSType type,
-                        JS::MutableHandleValue vp);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称类型描述
cx{{jsapixref("JSRuntime", "JSContext *")}}执行转换的上下文. {{ Jsapi-requires-request() }}
obj{{jsapixref("JSObject", "JS::HandleObject")}}要转换的对象。
type{{jsapixref("JSType")}}转换后值的类型。
vp{{jsapixref("JS::Value", "JS::MutableHandleValue")}}输出参数. 成功, *vp 收到转换后的值
- -

描述

- -

JS::OrdinaryToPrimitive 通过ES6 draft rev 28(2014年10月14日)7.1.1第二算法中指定的算法将JavaScript对象转换为指定的类型值。

- -

Most users should not call this -- use {{jsapixref("JS::ToNumber")}}, {{jsapixref("JS::ToBoolean")}}, or {{jsapixref("JS::ToString")}} instead. This should only be called from custom convert hooks. It implements the default conversion behavior shared by most objects in JS, so it's useful as a fallback.

- -

On success, JS::OrdinaryToPrimitive stores the converted value in *vp and returns true. On error or exception, it returns false, and the value left in *vp is undefined.

- -

了解其他

- - diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_evaluatescript/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_evaluatescript/index.html deleted file mode 100644 index 94454ee794..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_evaluatescript/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: SpiderMonkey/JSAPI_参考/JS_EvaluateScript -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_EvaluateScript -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_EvaluateScript ---- -

编译并执行一个脚本。

-

语法

-
JSBool JS_EvaluateScript(JSContext *cx, JSObject *obj,
-    const char *src, uintN length, const char *filename,
-    uintN lineno, jsval *rval);
-
-JSBool JS_EvaluateUCScript(JSContext *cx, JSObject *obj,
-    const jschar *src, uintN length, const char *filename,
-    uintN lineno, jsval *rval);
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称数据类型描述
cxJSContext *脚本运行的上下文. {{ Jsapi-requires-request() }}
objJSObject *The scope in which to execute the script. This parameter is documented in detail at JS_ExecuteScript.
srcconst char * or const jschar *包含要编译和执行的脚本的字符串.
lengthuintNsrc的长度, in characters.
filenameconst char *Name of file or URL containing the script. Used to report filename or URL in error messages.
linenouintNLine number. Used to report the offending line in the file or URL if an error occurs.
rvaljsval *Out parameter. On success, *rval receives the value of the last-executed expression statement processed in the script.
-

描述

-

JS_EvaluateScript compiles and executes a script in the specified scope, obj. On successful completion, rval is a pointer to a variable that holds the value from the last executed expression statement processed in the script. JS_EvaluateUCScript is the Unicode version of the function.

-

src is the string containing the text of the script. length indicates the size of the text version of the script in characters.

-

filename is the name of the file (or URL) containing the script. This information is used in messages if an error occurs during compilation. Similarly, lineno is used to report the line number of the script or file where an error occurred during compilation.

-

If a script compiles and executes successfully, *rval receives the value from the last-executed expression statement in the script, and JS_EvaluateScript or JS_EvaluateUCScript returns JS_TRUE. Otherwise it returns JS_FALSE and the value left in *rval is undefined.

-

See Also

-

{{ LXRSearch("ident", "i", "JS_EvaluateScript") }}
- {{ LXRSearch("ident", "i", "JS_EvaluateUCScript") }}

-

JS_CompileFile, JS_CompileScript, JS_DecompileScript, JS_DestroyScript, JS_EvaluateScriptForPrincipals

-

{{ languages( { "ja": "ja/JS_EvaluateScript" } ) }}

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_getversion/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_getversion/index.html deleted file mode 100644 index a2b2888958..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_getversion/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: SpiderMonkey/JSAPI_参考/JS_GetVersion -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_GetVersion -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_GetVersion ---- -

Retrieves the JavaScript version number used within a specified executable script context.

-

语法

-
JSVersion JS_GetVersion(JSContext *cx);
-
- - - - - - - - - - - - - -
参数名称类型描述
cxJSContext *要查询的上下文.
-

描述

-

JS_GetVersion returns the JavaScript version currently used by the given JSContext, cx. The result is one of the JSVersion constants.

-

When a context is created, its version is initially JSVERSION_DEFAULT. Scripts are compiled using the latest version of the JavaScript language. To configure a context to run scripts using a specific version of JavaScript, use JS_SetVersion.

-

请参阅

-

{{ LXRSearch("ident", "i", "JS_GetVersion") }}

-

JS_VersionToString, JS_StringToVersion

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_hasownproperty/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_hasownproperty/index.html deleted file mode 100644 index ed6e760796..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_hasownproperty/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: JS_HasOwnProperty -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_HasOwnProperty -tags: - - 中文 -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_HasOwnProperty ---- -
{{SpiderMonkeySidebar("JSAPI")}}
- -

{{ jsapi_minversion_header("45") }}

- -
-

Determine whether a JavaScript object has a specified own property.

-
- -

Syntax

- -
bool
-JS_HasOwnProperty(JSContext* cx, HandleObject obj, const char* name,
-                  bool* foundp)
-
-bool
-JS_HasOwnPropertyById(JSContext* cx, HandleObject obj, HandleId id,
-                      bool* foundp)
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
cx{{jsapixref("JSRuntime", "JSContext *")}}A context. {{ Jsapi-requires-request() }}
obj{{jsapixref("JSObject", "JS::HandleObject")}}Object to search on for the property.
name or idconst char * or {{jsapixref("jsid", "JS::HandleId")}}Name of the property to look up.
foundpbool *Non-null pointer to a variable of type bool. On success, JS_HasOwnProperty stores true in this variable if obj has an own property with the given name, and false if not.
- -

Description

- -

JS_HasOwnProperty searches an object, obj, for an own property with the specified name. It behaves like the JavaScript expression Object.hasOwnProperty(obj, name). JS_HasOwnPropertyById is the same but takes a {{jsapixref("jsid", "JS::HandleId")}} for the property name.

- -

If the property exists, this function sets *foundp to true and returns true.

- -

If the object obj has no such property, the function sets *foundp to false and returns true (to indicate that no error occurred).

- -

If an error occurs during the search, the function returns false, and the value of *foundp is undefined.

- -

See Also

- - diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_newruntime/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_newruntime/index.html deleted file mode 100644 index 885bb3dd6e..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_newruntime/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: JS_NewRuntime -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_NewRuntime -tags: - - JSAPI_Reference - - SpiderMonkey -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_NewRuntime ---- -

Initializes the JavaScript runtime.

-

Syntax

-
JSRuntime * JS_NewRuntime(uint32 maxbytes);
-
- - - - - - - - - - - - - -
NameTypeDescription
maxbytesuint32Maximum number of allocated bytes after which garbage collection is run.
-

Description

-

JS_NewRuntime initializes the JavaScript runtime environment. Call JS_NewRuntime before making any other API calls. JS_NewRuntime allocates memory for the JSRuntime and initializes certain internal runtime structures. maxbytes specifies the number of allocated bytes after which garbage collection is run.

-

Generally speaking, most applications need only one JSRuntime. In a JS_THREADSAFE build, each runtime is capable of handling multiple execution threads, using one JSContext per thread, sharing the same JSRuntime. You only need multiple runtimes if your application requires completely separate JS engines that cannot share values, objects, and functions.

-

On success, JS_NewRuntime returns a pointer to the newly created runtime, which the caller must later destroy using JS_DestroyRuntime. Otherwise it returns NULL.

-

Notes

-

Ordinarily, JS_NewRuntime should be the first JSAPI call in an application, and JS_DestroyRuntime and JS_ShutDown should be the last ones.

-

{{ LXRSearch("ident", "i", "JS_NewRuntime") }}

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_seterrorreporter/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_seterrorreporter/index.html deleted file mode 100644 index e04127a541..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_seterrorreporter/index.html +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: SpiderMonkey/JSAPI_参考/JS_SetErrorReporter -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetErrorReporter -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetErrorReporter ---- -

指定一个程序的错误报告途径.

-

语法

-
JSErrorReporter JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
-
- - - - - - - - - - - - - - - - - - -
形式参数类型描述
cxJSContext *Pointer to a JS context from which to derive runtime information.
erJSErrorReporter在你的程序中用于报告错误的自定义函数, 见下面的描述.
-

  回调函数语法

-
typedef void (*JSErrorReporter)(
-    JSContext *cx, const char *message, JSErrorReport *report);
-
- - - - - - - - - - - - - - - - - - - - - - - -
形式参数类型描述
cxJSContext *错误发生的上下文。
messageconst char *一个错误信息。
reportJSErrorReport *一个包含错误额外的详细资料报告记录。
-

描述

-

JS_SetErrorReporter enables you to define and use your own error reporting mechanism in your applications. The reporter you define is automatically passed a JSErrorReport structure when an error occurs and has been parsed by JS_ReportError.

-

Typically, the error reporting mechanism you define should log the error where appropriate (such as to a log file), and display an error to the user of your application. The error you log and display can make use of the information passed about the error condition in the JSErrorReport structure.

-

Like all other SpiderMonkey callbacks, the error reporter callback must not throw a C++ exception.

-

{{ LXRSearch("ident", "i", "JS_SetErrorReporter") }}

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_valuetostring/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_valuetostring/index.html deleted file mode 100644 index ab0e6654a4..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/js_valuetostring/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: SpiderMonkey/JSAPI_参考/JS_ValueToString -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_ValueToString -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_ValueToString ---- -

把一个jsval值 转换成一个 JSString.

- -

 

- -

语法

- -
JSString * JS_ValueToString(JSContext *cx, jsval v);
-
- - - - - - - - - - - - - - - - - - - -
NameTypeDescription
cxJSContext *The context in which to perform the conversion. {{ Jsapi-requires-request() }}
vjsval转换的jsval值.
- -

描述

- -

JS_ValueToString converts a specified JS value, v, to a JS string. It implements the ToString operator specified in ECMA 262-3 §9. If v is an object, the actual conversion is performed by its JSClass.convert callback, which may call the JavaScript methods v.toString() and/or v.valueOf(). On success, JS_ValueToString returns a pointer to a string. On error or exception, it returns NULL. This happens, for example, if v is an object and v.toString() throws an exception.

- -

The resulting JSString is subject to garbage collection unless you protect it using a local root, an object property, or the JS_AddRoot function.

- -

See Also

- -

{{ LXRSearch("ident", "i", "JS_ValueToString") }}

- -

JS_ConvertArguments, JS_ConvertValue, JS_GetTypeName, JS_TypeOfValue, JS_ValueToBoolean, JS_ValueToFunction, JS_ValueToInt32, JS_ValueToNumber, JS_ValueToObject

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsclass/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsclass/index.html deleted file mode 100644 index dd119aba3f..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsclass/index.html +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: JSClass -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSClass -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSClass ---- -

摘要

-

数据结构 定义一个基本类用于建立和维护JS对象。

-

语法

-
struct JSClass {
-    char *name;
-    uint32 flags;
-    /* Mandatory non-null function pointer members. */
-    JSPropertyOp addProperty;
-    JSPropertyOp delProperty;
-    JSPropertyOp getProperty;
-    JSPropertyOp setProperty;
-    JSEnumerateOp enumerate;
-    JSResolveOp resolve;
-    JSConvertOp convert;
-    JSFinalizeOp finalize;
-    /* Optionally non-null members start here. */
-    JSGetObjectOps getObjectOps;
-    JSCheckAccessOp checkAccess;
-    JSNative call;
-    JSNative construct;
-    JSXDRObjectOp xdrObject;
-    JSHasInstanceOp hasInstance;
-    JSMarkOp mark;
-    JSReserveSlotsOp reserveSlots;
-};
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称类型描述
namechar *类名
flagsuint32类的属性(成员变量)。0表明属性不是一个集合. 属性值可以是下面这些值中的一个或多个: - -
addPropertyJSPropertyOp为类增加属性的函数。
delPropertyJSPropertyOp从类中删除属性的函数。
getPropertyJSPropertyOp获取属性值的函数。
setPropertyJSPropertyOp设置属性值的函数
enumerateJSEnumerateOp枚举类所有属性的函数。
resolveJSResolveOpMethod for resolving property ambiguities.
convertJSConvertOp进行属性值转换的函数。
finalizeJSFinalizeOp将类设为不可修改(finalizing)的函数。
getObjectOpsJSGetObjectOps为类定义重载方法指向一个可选的结构。如果你不想重载类的默认方法,可以将getObjectOps 设为 NULL
checkAccessJSCheckAccessOp为类或对象操作结构指定可选的自定义请求控制方法。如果你不想提供自定义的请求控制,设置此值为NULL
callJSNative为对象提供替换这个类的方法。
constructJSNative为对象提供方法去替换这个类的构造器。
xdrObjectJSXDRObjectOp指向一个可选的XDR对象和它的方法。如果你不想使用XDR, 设置这个值为 NULL
hasInstanceJSHasInstanceOpPointer to an optional hasInstance method for this object. If you do not provide a method for hasInstance, set this pointer to NULL.
markJSMarkOpPointer to an optional mark method for this object. If you do not provide a method for mark, set this pointer to NULL.
reserveSlotsJSReserveSlotsOpPointer to an optional reserveSlots method for this object. If you do not provide a method for reserveSlots, set this pointer to NULL.
-

 

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsconstdoublespec/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsconstdoublespec/index.html deleted file mode 100644 index 509d3b12ed..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsconstdoublespec/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: JSConstDoubleSpec -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSConstDoubleSpec -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSConstDoubleSpec ---- -

摘要

-

数据结构

-

定义一个双浮点类型的变量并进行赋值。

-

语法

-
struct JSConstDoubleSpec {
-    jsdouble dval;
-    const char *name;
-    uint8 flags;
-    uint8 spare[3];
-};
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称类型描述
dvaljsdouble双浮点类型的值。
nameconst char *给双浮点类型定义的名称。
flagsuint8双浮点类型的属性。这里可以是0或者是下面这些值之中的一个: - -
spareuint8{{ mediawiki.external(3) }}为以后的扩展保留的属性。
-

描述

-

JS双浮点型的构造规范 典型应用于定义一个双浮点值集合,并使用JS_DefineConstDoubles对生成的对象进行赋值。使用JS_DefineConstDouble为指定的对象创建一个或多个双浮点类型属性。

-

JS_DefineConstDoubles为一类由JSConstDoubleSpecs定义的数组提供证明。为每个数据元素定义独立的属性名和设置独立的属性值。数组的最后一个元素必须包括0值(zero-valued)的属性。JS_DefineConstDoubles 为数组中每个非0值(non-zero)元素创建一个属性值。

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jserrorreport/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jserrorreport/index.html deleted file mode 100644 index 7246c3c416..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jserrorreport/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: JSErrorReport -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSErrorReport -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSErrorReport ---- -

Media:Example.ogg

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsproperty/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsproperty/index.html deleted file mode 100644 index 16f0cca090..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsproperty/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: JSProperty -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSProperty -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSProperty ---- -
{{SpiderMonkeySidebar("JSAPI")}}
- -

{{deprecated_header("jsapi16")}}

- -
-

限内部使用。{{jsapixref("JSObjectOps")}}层使用的JavaScript对象属性的类型。

-
- -

语法

- -
struct JSProperty {
-    jsid id;
-};
-
- -

Description

- -

JSProperty 是所有对象属性的抽象基类。 它在 {{jsapixref("JSObjectOps.lookupProperty")}}, {{jsapixref("JSObjectOps.getAttributes", "getAttributes")}}, {{jsapixref("JSObjectOps.getAttributes", "setAttributes")}}, 和 {{jsapixref("JSObjectOps.dropProperty", "dropProperty")}}中内部使用。

- -

See Also

- - diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jspropertydescriptor/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jspropertydescriptor/index.html deleted file mode 100644 index 9f35d49fdb..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jspropertydescriptor/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: JSPropertyDescriptor -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSPropertyDescriptor -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSPropertyDescriptor ---- -
{{SpiderMonkeySidebar("JSAPI")}}
- -
描述符是一个用于声明一个属性是否可以被修改,是否可以被删除,是否可以被枚举的一个对象
- -

内容

- -

每一个属性只拥有一个描述符对象,但是这个对象中拥有多个键值,用来描述这个属性,下表说明了描述符中可以拥有的键值.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field NameDescription
getterget 语法为属性绑定一个函数,每当查询该属性时便调用对应的函数,查询的结构为该函数的返回值
setter如果试着改变一个属性的值,那么对应的 setter 函数将被执行
value描述指定属性的值 , 可以是任何有效的 Javascript 值(函数 , 对象 , 字符串 ...).
configurable当且仅当该属性的 configurable 为 true 时,该属性 描述符 才能够被改变, 同时该属性也能从对应的对象上被删除.
enumerable描述指定的属性是否是 可枚举 的.
writable当且仅当该属性的 writabletrue 时, value 才能被赋值运算符改变。
- -

描述

- -

描述符 是描述对象属性的属性 , 对象里目前存在的属性描述符有两种主要形式:数据描述符 存取描述符. 可以通过 Object.getOwnPropertyDescriptor() 函数来获取某个对象下指定属性的对应的 描述符 .

- -

示例

- -

下面将演示通过 Object.defineProperty() 函数定义一个对象的属性.

- -
var language = {}; // 定义一个空对象 language
-
-Object.defineProperty(language, 'log', { // 定义 language 对象下的 log 属性
-    value : ['CN','EN'],
-    writable : true,
-    enumerable : true,
-    configurable : true
-})
- -

此时这是一个可读可写可枚举的属性 此时我们将这三个值都设为了 true 此时上面这段代码等价于:

- -
var language = {}; // 定义一个空对象 language
-
-languange.log = ['CN','EN']; // 定义 language 对象下的 log 属性
-
diff --git a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsruntime/index.html b/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsruntime/index.html deleted file mode 100644 index daabc3f876..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/jsapi_reference/jsruntime/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: JSRuntime -slug: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSRuntime -translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_reference/JSRuntime ---- -
{{SpiderMonkeySidebar("JSAPI")}}
- -
-

在JSAPI中,JSRuntime是代表JavaScript引擎实例的顶级对象。一个程序通常只有一个JSRuntime,即使它有很多线程。JSRuntime是JavaScript对象所居住的世界;他们不能去其他人JSRuntime

- -

所有JavaScript代码和大多数JSAPI调用都在内运行JSContextJSContext是对一个孩子JSRuntime上下文可以运行脚本。它包含全局对象和执行堆栈。异常处理错误报告和某些语言选项是基于Per-的JSContext创建上下文后,可以将上下文多次用于不同的脚本或JSAPI查询。例如,浏览器可能会为每个HTML页面创建一个单独的上下文。页面中的每个脚本都可以使用相同的上下文。

- -

对象在同一个 JSRuntimeJSContext之间可以共享。对象与创建对象的上下文之间没有固定的关联。

- -

设置和拆卸a JSRuntime和a的示例代码JSContextJSAPI用户指南中

-
- -

线程

- -

只有一个线程可以使用JSContext JSRuntime较早的版本允许使用  JS_ClearContextThread 和其他功能将a JSContext 从一个线程移动  到另一个线程。此功能已被删除。

- -

相关文档

- - diff --git a/files/zh-cn/mozilla/projects/spidermonkey/parser_api/index.html b/files/zh-cn/mozilla/projects/spidermonkey/parser_api/index.html deleted file mode 100644 index 03b00c9b00..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/parser_api/index.html +++ /dev/null @@ -1,1625 +0,0 @@ ---- -title: Parser API -slug: Mozilla/Projects/SpiderMonkey/Parser_API -translation_of: Mozilla/Projects/SpiderMonkey/Parser_API ---- -

{{ jsapi_minversion_header("1.8.5") }}

- -

最近构建的独立的SpiderMonkey shell包含了SpiderMonkey解析器的反射,可以通过JavaScript API来访问. 这使得我们更容易的用JavaScript写出处理JavaScript源代码的工具, 比如语法高亮工具,静态分析工具, 翻译器,编译器,混淆器等等.

- -

例子:

- -
> var expr = Reflect.parse("obj.foo + 42").body[0].expression
-> expr.left.property
-({loc:null, type:"Identifier", name:"foo"})
-> expr.right
-({loc:{source:null, start:{line:1, column:10}, end:{line:1, column:12}}, type:"Literal", value:42})
-
- -

Reflect也可以使用在Firefox 7及以上版本中,但必须要导入一个模块:

- -
Components.utils.import("resource://gre/modules/reflect.jsm")
-
- -

如果不想用Reflect全局对象,也可以指定一个对象名称:

- -
Components.utils.import("resource://gre/modules/reflect.jsm", obj)
-
- -

内置对象

- -

无论是SpiderMonkey shell还是Firefox (导入模块之后),全局对象Reflect目前都只有一个parse方法.

- -

Reflect对象的属性

- -

Reflect对象目前只有一个方法.

- -

Reflect.parse(src[, options])

- -

将SRC强制转为字符串,并将结果作为javascript程序进行分析。默认情况下,解析返回一个表示被解析的抽象语法树(AST)的程序对象(见下文)

- -

可通过options对象提供其他选项, 可以使用的属性如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
locBooleanDefault: true
如果loctrue,则解析器会在返回的AST节点中包含上源码的位置信息.
sourceStringDefault: null
A description of the input source; typically a filename, path, or URL. This string is not meaningful to the parsing process, but is produced as part of the source location information in the returned AST nodes.
lineNumberDefault: 1
初始行号,用在源码位置信息上.
builderBuilderDefault: null
-

A builder object, which can be used to produce AST nodes in custom data formats. The expected callback methods are described under Builder Objects.

-
- -

If parsing fails due to a syntax error, an instance of SyntaxError is thrown. The syntax error object thrown by Reflect.parse() has the same message property as the syntax error that would be thrown by eval(src). The lineNumber and fileName properties of the syntax error object indicate the source location of the syntax error.

- -

节点对象

- -

默认情况下, Reflect.parse() 生成Node对象, 即普通的JavaScript对象 (i.e., 它们的原型来自标准的Object原型). 所有的节点类型都实现了以下的接口:

- -
interface Node {
-    type: string;
-    loc: SourceLocation | null;
-}
-
- -

type 字段是一个字符串,代表AST变量类型.节点的每个子类型在下面的文档中都用其  type 字段特定的字符串标注出来了. 你可以使用这个字段去决定一个节点要实现的接口.

- -

loc 字段代表节点的源位置信息. 如果解析器未生成有关节点的源位置信息,  null 字段为空;否则它是一个对象, 包括一个起始位置 (the position of the first character of the parsed source region) 和一个结束位置 (the position of the first character after the parsed source region):ss

- -
interface SourceLocation {
-    source: string | null;
-    start: Position;
-    end: Position;
-}
-
- -

每个 Position 包括一个 line 数字 (1-indexed) 和 column 数字 (0-indexed):

- -
interface Position {
-    line: uint32 >= 1;
-    column: uint32 >= 0;
-}
- -

Programs

- -
interface Program <: Node {
-    type: "Program";
-    body: [ Statement ];
-}
-
- -

A complete program source tree.

- -

函数

- -
interface Function <: Node {
-    id: Identifier | null;
-    params: [ Pattern ];
-    defaults: [ Expression ];
-    rest: Identifier | null;
-    body: BlockStatement | Expression;
-    generator: boolean;
-    expression: boolean;
-}
-
- -

A function declaration or expression. The body of the function may be a block statement, or in the case of an expression closure, an expression.

- -
注: Expression closures 是SpiderMonkey特有的.
- -

If the generator flag is true, the function is a generator function, i.e., contains a yield expression in its body (other than in a nested function).

- -
注: Generators 是SpiderMonkey特有的.
- -

If the expression flag is true, the function is an expression closure and the body field is an expression.

- -

语句

- -
interface Statement <: Node { }
-
- -

任意语句.

- -
interface EmptyStatement <: Statement {
-    type: "EmptyStatement";
-}
-
- -

一个空语句,也就是,一个孤立的分号.

- -
interface BlockStatement <: Statement {
-    type: "BlockStatement";
-    body: [ Statement ];
-}
-
- -

一个语句块,也就是由大括号包围的语句序列.

- -
interface ExpressionStatement <: Statement {
-    type: "ExpressionStatement";
-    expression: Expression;
-}
-
- -

一个表达式语句,也就是,仅有一个表达式组成的语句.

- -
interface IfStatement <: Statement {
-    type: "IfStatement";
-    test: Expression;
-    consequent: Statement;
-    alternate: Statement | null;
-}
-
- -

一个if语句.

- -
interface LabeledStatement <: Statement {
-    type: "LabeledStatement";
-    label: Identifier;
-    body: Statement;
-}
-
- -

一个标签语句,也就是, a statement prefixed by a break/continue label.

- -
interface BreakStatement <: Statement {
-    type: "BreakStatement";
-    label: Identifier | null;
-}
-
- -

一个break语句.

- -
interface ContinueStatement <: Statement {
-    type: "ContinueStatement";
-    label: Identifier | null;
-}
-
- -

一个continue语句.

- -
interface WithStatement <: Statement {
-    type: "WithStatement";
-    object: Expression;
-    body: Statement;
-}
-
- -

with statement.

- -
interface SwitchStatement <: Statement {
-    type: "SwitchStatement";
-    discriminant: Expression;
-    cases: [ SwitchCase ];
-    lexical: boolean;
-}
-
- -

一个switch语句. The lexical flag is metadata indicating whether the switch statement contains any unnested let declarations (and therefore introduces a new lexical scope).

- -
interface ReturnStatement <: Statement {
-    type: "ReturnStatement";
-    argument: Expression | null;
-}
-
- -

一个return语句.

- -
interface ThrowStatement <: Statement {
-    type: "ThrowStatement";
-    argument: Expression;
-}
-
- -

一个throw语句.

- -
interface TryStatement <: Statement {
-    type: "TryStatement";
-    block: BlockStatement;
-    handlers: [ CatchClause ];
-    finalizer: BlockStatement | null;
-}
-
- -

一个try语句.

- -
注: 多个catch子句是SpiderMonkey特有的.
- -
interface WhileStatement <: Statement {
-    type: "WhileStatement";
-    test: Expression;
-    body: Statement;
-}
-
- -

一个while语句.

- -
interface DoWhileStatement <: Statement {
-    type: "DoWhileStatement";
-    body: Statement;
-    test: Expression;
-}
-
- -

一个do/while语句.

- -
interface ForStatement <: Statement {
-    type: "ForStatement";
-    init: VariableDeclaration | Expression | null;
-    test: Expression | null;
-    update: Expression | null;
-    body: Statement;
-}
-
- -

一个for语句.

- -
interface ForInStatement <: Statement {
-    type: "ForInStatement";
-    left: VariableDeclaration |  Expression;
-    right: Expression;
-    body: Statement;
-    each: boolean;
-}
-
- -

一个for/in语句, or, if each is true, a for each/in statement.

- -
注: for each语法是SpiderMonkey特有的.
- -
interface LetStatement <: Statement {
-    type: "LetStatement";
-    head: [ { id: Pattern, init: Expression | null } ];
-    body: Statement;
-}
-
- -

一个let语句.

- -
注: let语句形式是SpiderMonkey特有的.
- -
interface DebuggerStatement <: Statement {
-    type: "DebuggerStatement";
-}
-
- -

一个debugger语句.

- -
注: debugger语句是ECMAScript 5中的新语法,尽管SpiderMonkey已经支持它很多年了.
- -

声明

- -
interface Declaration <: Statement { }
-
- -

Any declaration node. Note that declarations are considered statements; this is because declarations can appear in any statement context in the language recognized by the SpiderMonkey parser.

- -
注: 任意嵌套作用域下的声明是SpiderMonkey特有的.
- -
interface FunctionDeclaration <: Function, Declaration {
-    type: "FunctionDeclaration";
-    id: Identifier;
-    params: [ Pattern ];
-    defaults: [ Expression ];
-    rest: Identifier | null;
-    body: BlockStatement | Expression;
-    generator: boolean;
-    expression: boolean;
-}
-
- -

一个函数声明.

- -
注: id字段不能为null.
- -
interface VariableDeclaration <: Declaration {
-    type: "VariableDeclaration";
-    declarations: [ VariableDeclarator ];
-    kind: "var" | "let" | "const";
-}
-
- -

一个变量声明,可以通过var, let, 或const.

- -
interface VariableDeclarator <: Node {
-    type: "VariableDeclarator";
-    id: Pattern;
-    init: Expression | null;
-}
-
- -

一个变量声明符.

- -
注: id字段不能为null.
- -
注: letconst是SpiderMonkey特有的.
- -

表达式

- -
interface Expression <: Node, Pattern { }
- -

任意表达式节点. Since the left-hand side of an assignment may be any expression in general, an expression can also be a pattern.

- -
interface ThisExpression <: Expression {
-    type: "ThisExpression";
-}
-
- -

一个this表达式.

- -
interface ArrayExpression <: Expression {
-    type: "ArrayExpression";
-    elements: [ Expression | null ];
-}
- -

一个数组表达式.

- -
interface ObjectExpression <: Expression {
-    type: "ObjectExpression";
-    properties: [ { key: Literal | Identifier,
-                    value: Expression,
-                    kind: "init" | "get" | "set" } ];
-}
- -

一个对象表达式. A literal property in an object expression can have either a string or number as its value. Ordinary property initializers have a kind value "init"; getters and setters have the kind values "get" and "set", respectively.

- -
interface FunctionExpression <: Function, Expression {
-    type: "FunctionExpression";
-    id: Identifier | null;
-    params: [ Pattern ];
-    defaults: [ Expression ];
-    rest: Identifier | null;
-    body: BlockStatement | Expression;
-    generator: boolean;
-    expression: boolean;
-}
-
- -

一个函数表达式.

- -
interface SequenceExpression <: Expression {
-    type: "SequenceExpression";
-    expressions: [ Expression ];
-}
- -

一个序列表达式,也就是一个由逗号分割的表达式序列.

- -
interface UnaryExpression <: Expression {
-    type: "UnaryExpression";
-    operator: UnaryOperator;
-    prefix: boolean;
-    argument: Expression;
-}
- -

A unary operator expression.

- -
interface BinaryExpression <: Expression {
-    type: "BinaryExpression";
-    operator: BinaryOperator;
-    left: Expression;
-    right: Expression;
-}
- -

一个二元运算符表达式.

- -
interface AssignmentExpression <: Expression {
-    type: "AssignmentExpression";
-    operator: AssignmentOperator;
-    left: Expression;
-    right: Expression;
-}
- -

An assignment operator expression.

- -
interface UpdateExpression <: Expression {
-    type: "UpdateExpression";
-    operator: UpdateOperator;
-    argument: Expression;
-    prefix: boolean;
-}
- -

An update (increment or decrement) operator expression.

- -
interface LogicalExpression <: Expression {
-    type: "LogicalExpression";
-    operator: LogicalOperator;
-    left: Expression;
-    right: Expression;
-}
- -

一个逻辑运算符表达式.

- -
interface ConditionalExpression <: Expression {
-    type: "ConditionalExpression";
-    test: Expression;
-    alternate: Expression;
-    consequent: Expression;
-}
- -

一个条件运算符表达式, i.e., a ternary ?/: expression.

- -
interface NewExpression <: Expression {
-    type: "NewExpression";
-    callee: Expression;
-    arguments: [ Expression ] | null;
-}
- -

A new expression.

- -
interface CallExpression <: Expression {
-    type: "CallExpression";
-    callee: Expression;
-    arguments: [ Expression ];
-}
- -

A function or method call expression.

- -
interface MemberExpression <: Expression {
-    type: "MemberExpression";
-    object: Expression;
-    property: Identifier | Expression;
-    computed : boolean;
-}
- -

一个member表达式. If computed === true, the node corresponds to a computed e1[e2] expression and property is an Expression. If computed === false, the node corresponds to a static e1.x expression and property is an Identifier.

- -
interface YieldExpression <: Expression {
-    argument: Expression | null;
-}
-
- -

yield expression.

- -
注: yield expressions 是SpiderMonkey特有的.
- -
interface ComprehensionExpression <: Expression {
-    body: Expression;
-    blocks: [ ComprehensionBlock ];
-    filter: Expression | null;
-}
-
- -

An array comprehension. The blocks array corresponds to the sequence of for and for each blocks. The optional filter expression corresponds to the final if clause, if present.

- -
注: Array comprehensions 是SpiderMonkey特有的.
- -
interface GeneratorExpression <: Expression {
-    body: Expression;
-    blocks: [ ComprehensionBlock ];
-    filter: Expression | null;
-}
-
- -

A generator expression. As with array comprehensions, the blocks array corresponds to the sequence of for and for each blocks, and the optional filter expression corresponds to the final if clause, if present.

- -
注: Generator expressions 是SpiderMonkey特有的.
- -
interface GraphExpression <: Expression {
-    index: uint32;
-    expression: Literal;
-}
-
- -

graph expression, aka "sharp literal," such as #1={ self: #1# }.

- -
注: Graph expressions 是SpiderMonkey特有的.
- -
interface GraphIndexExpression <: Expression {
-    index: uint32;
-}
-
- -

一个graph索引表达式,又称为"井号变量",比如#1#.

- -
注: Graph索引表达式
- -
Graph索引表达式是SpiderMonkey特有的.
- -
interface LetExpression <: Expression {
-    type: "LetExpression";
-    head: [ { id: Pattern, init: Expression | null } ];
-    body: Expression;
-}
-
- -

一个let表达式.

- -
注: let表达式是SpiderMonkey特有的.
- -

模式

- -
interface Pattern <: Node { }
-
- -

JavaScript 1.7 introduced destructuring assignment and binding forms. All binding forms (such as function parameters, variable declarations, and catch block headers), accept array and object destructuring patterns in addition to plain identifiers. The left-hand sides of assignment expressions can be arbitrary expressions, but in the case where the expression is an object or array literal, it is interpreted by SpiderMonkey as a destructuring pattern.

- -

Since the left-hand side of an assignment can in general be any expression, in an assignment context, a pattern can be any expression. In binding positions (such as function parameters, variable declarations, and catch headers), patterns can only be identifiers in the base case, not arbitrary expressions.

- -
interface ObjectPattern <: Pattern {
-    type: "ObjectPattern";
-    properties: [ { key: Literal | Identifier, value: Pattern } ];
-}
-
- -

An object-destructuring pattern. A literal property in an object pattern can have either a string or number as its value.

- -
interface ArrayPattern <: Pattern {
-    type: "ArrayPattern";
-    elements: [ Pattern | null ];
-}
-
- -

An array-destructuring pattern.

- -

子句

- -
interface SwitchCase <: Node {
-    type: "SwitchCase";
-    test: Expression | null;
-    consequent: [ Statement ];
-}
-
- -

一个case (if test is an Expression) or default (if test === null) clause in the body of a switch语句.

- -
interface CatchClause <: Node {
-    type: "CatchClause";
-    param: Pattern;
-    guard: Expression | null;
-    body: BlockStatement;
-}
-
- -

catch clause following a try block. The optional guard property corresponds to the optional expression guard on the bound variable.

- -
注: The guard expression is SpiderMonkey-specific.
- -
interface ComprehensionBlock <: Node {
-    left: Pattern;
-    right: Expression;
-    each: boolean;
-}
-
- -

for or for each block in an array comprehension or generator expression.

- -
注: Array comprehensions and generator expressions 是SpiderMonkey特有的.
- -

杂项

- -
interface Identifier <: Node, Expression, Pattern {
-    type: "Identifier";
-    name: string;
-}
-
- -

An identifier. Note that an identifier may be an expression or a destructuring pattern.

- -
interface Literal <: Node, Expression {
-    type: "Literal";
-    value: string | boolean | null | number | RegExp;
-}
-
- -

A literal token. Note that a literal can be an expression.

- -
enum UnaryOperator {
-    "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"
-}
-
- -

A unary operator token.

- -
enum BinaryOperator {
-    "==" | "!=" | "===" | "!=="
-         | "<" | "<=" | ">" | ">="
-         | "<<" | ">>" | ">>>"
-         | "+" | "-" | "*" | "/" | "%"
-         | "|" | "^" | "in"
-         | "instanceof" | ".."
-}
-
- -

A binary operator token.

- -
注: The .. operator is E4X-specific.
- -
enum LogicalOperator {
-    "||" | "&&"
-}
-
- -

A logical operator token.

- -
enum AssignmentOperator {
-    "=" | "+=" | "-=" | "*=" | "/=" | "%="
-        | "<<=" | ">>=" | ">>>="
-        | "|=" | "^=" | "&="
-}
-
- -

An assignment operator token.

- -
enum UpdateOperator {
-    "++" | "--"
-}
-
- -

An update (increment or decrement) operator token.

- -

E4X

- -

下面介绍一下为E4X提供支持的节点类型.

- -
注: E4X不是ECMAScript规范(ECMA-262)的一部分,它是一个单独的标准(ECMA-357).
- -

声明

- -
interface XMLDefaultDeclaration <: Declaration {
-    type: "XMLDefaultDeclaration";
-    namespace: Expression;
-}
-
- -

一个默认xml命名空间声明

- -

表达式

- -
interface XMLAnyName <: Expression {
-    type: "XMLAnyName";
-}
-
- -

The special E4X wildcard pseudo-identifier *.

- -
interface XMLQualifiedIdentifier <: Expression {
-    type: "XMLQualifiedIdentifier";
-    left: Identifier | XMLAnyName;
-    right: Identifier | Expression;
-    computed: boolean;
-}
-
- -

An E4X qualified identifier, i.e., a pseudo-identifier using the namespace separator ::. If the qualified identifier has a computed name (i.e., the id::[expr] form), then computed is true and the right property is an expression.

- -
interface XMLFunctionQualifiedIdentifier <: Expression {
-    type: "XMLFunctionQualifiedIdentifier";
-    right: Identifier | Expression;
-    computed: boolean;
-}
-
- -

An E4X identifier qualified by the function keyword, e.g. function::id.

- -
注: function-qualified identifiers 是SpiderMonkey特有的.
- -
interface XMLAttributeSelector <: Expression {
-    type: "XMLAttributeSelector";
-    attribute: Expression;
-}
-
- -

An E4X attribute selector expression, i.e., an @ expression.

- -
interface XMLFilterExpression <: Expression {
-    type: "XMLFilterExpression";
-    left: Expression;
-    right: Expression;
-}
-
- -

An E4X list filter expression, i.e., an expression of the form expr.(expr).

- -
interface XMLElement <: XML, Expression {
-    type: "XMLElement";
-    contents: [ XML ];
-}
-
- -

An E4X literal representing a single XML element.

- -
interface XMLList <: XML, Expression {
-    type: "XMLList";
-    contents: [ XML ];
-}
-
- -

An E4X literal representing a list of XML elements.

- -

XML

- -
interface XML <: Node { }
-
- -

XML data.

- -
interface XMLEscape <: XML {
-    type "XMLEscape";
-    expression: Expression;
-}
-
- -

XML data with an escaped JavaScript expression.

- -
interface XMLText <: XML {
-    type: "XMLText";
-    text: string;
-}
-
- -

Literal XML text.

- -
interface XMLStartTag <: XML {
-    type: "XMLStartTag";
-    contents: [ XML ];
-}
-
- -

An XML start tag.

- -
interface XMLEndTag <: XML {
-    type: "XMLEndTag";
-    contents: [ XML ];
-}
-
- -

An XML end tag.

- -
interface XMLPointTag <: XML {
-    type: "XMLPointTag";
-    contents: [ XML ];
-}
-
- -

An XML point tag.

- -
interface XMLName <: XML {
-    type: "XMLName";
-    contents: string | [ XML ];
-}
-
- -

An XML name.

- -
interface XMLAttribute <: XML {
-    type: "XMLAttribute";
-    value: string;
-}
-
- -

An XML attribute value.

- -
interface XMLCdata <: XML {
-    type: "XMLCdata";
-    contents: string;
-}
-
- -

An XML CDATA node.

- -
interface XMLComment <: XML {
-    type: "XMLComment";
-    contents: string;
-}
-
- -

An XML comment.

- -
interface XMLProcessingInstruction <: XML {
-    type: "XMLProcessingInstruction";
-    target: string;
-    contents: string | null;
-}
-
- -

An XML processing instruction.

- -

Builder objects

- -

The optional builder parameter to Reflect.parse() makes it possible to construct user-specified data from the parser, rather than the default Node objects. Builder objects may contain any of the callback methods described in this section.

- -

Each callback can produce any custom, user-defined datatype; these are referred to below as CustomExpression, CustomStatement, etc.

- -
注: Because this library uses null for optional nodes, it is recommended that user-defined datatypes not use null as a representation of an AST node.
- -

If the loc option is enabled (see the Reflect.parse() options above), then each callback is provided with the source location information of the parsed node as an extra parameter.

- -

All builder callbacks are optional. When a callback is missing, the default format is used, but the provided builder methods are still used recursively for sub-nodes.

- -

Programs

- -
program(body[, loc])
- -
body: [ CustomStatement ]
-loc: SourceLocation
-
- -

返回: CustomProgram

- -

Callback to produce a custom program node.

- -

Statements

- -
emptyStatement([loc])
- -
loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom empty statement node.

- -
blockStatement(body[, loc])
- -
body: CustomStatement
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom block statement node.

- -
expressionStatement(expr[, loc])
- -
expr: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom expression statement node.

- -
labeledStatement(label, body[, loc])
- -
label: CustomIdentifier
-body: CustomStatement
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom labeled statement node.

- -
ifStatement(test, cons, alt[, loc])
- -
test: CustomExpression
-cons: CustomStatement
-alt: CustomStatement | null
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom if statement node.

- -
switchStatement(disc, cases, isLexical[, loc])
- -
disc: CustomExpression
-cases: [ CustomSwitchCase ]
-isLexical: boolean
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom switch statement node. The isLexical flag is metadata indicating whether the switch statement contains any unnested let declarations (and therefore introduces a new lexical scope).

- -
whileStatement(test, body[, loc])
- -
test: CustomExpression
-body: CustomStatement
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom while statement node.

- -
doWhileStatement(body, test[, loc])
- -
body: CustomStatement
-test: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom do-while statement node.

- -
forStatement(init, test, update, body[, loc])
- -
init: CustomVariableDeclaration | CustomExpression | null
-test: CustomExpression | null
-update: CustomExpression | null
-body: CustomStatement
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom for statement node.

- -
forInStatement(left, right, body, isForEach[, loc])
- -
left: CustomVariableDeclaration | CustomExpression
-right: CustomExpression
-body: CustomStatement
-isForEach: boolean
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom for-in statement node. The isForEach flag indicates whether the node is a for each statement.

- -
breakStatement(label[, loc])
- -
label: CustomIdentifier | null
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom break statement node.

- -
continueStatement(label[, loc])
- -
label: CustomIdentifier | null
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom continue statement node.

- -
withStatement(obj, body[, loc])
- -
obj: CustomExpression
-body: CustomStatement
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom with statement node.

- -
returnStatement(arg[, loc])
- -
arg: CustomExpression | null
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom return statement node.

- -
tryStatement(body, handlers, fin[, loc])
- -
body: CustomStatement
-handlers: [ CustomCatchClause ]
-fin: CustomStatement | null
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom try statement node.

- -
throwStatement(arg[, loc])
- -
arg: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom throw statement node.

- -
debuggerStatement([loc])
- -
loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom debugger statement node.

- -
letStatement(head, body[, loc])
- -
head: [ CustomDeclarator ]
-body: CustomStatement
-loc: SourceLocation
-
- -

返回: CustomStatement

- -

Callback to produce a custom let statement node.

- -

声明

- -
functionDeclaration(name, args, body, isGenerator, isExpression[, loc])
- -
name: string
-args: [ CustomPattern ]
-body: CustomStatement | CustomExpression
-isGenerator: boolean
-isExpression: boolean
-loc: SourceLocation
-
- -

返回: CustomDeclaration

- -

Callback to produce a custom function declaration node.

- -
variableDeclaration(kind, dtors[, loc])
- -
kind: "const" | "let" | "var"
-dtors: [ CustomDeclarator ]
-loc: SourceLocation
-
- -

返回: CustomDeclaration

- -

Callback to produce a custom variable declaration node.

- -
variableDeclarator(patt, init[, loc])
- -
patt: CustomPattern
-init: CustomExpression | null
-loc: SourceLocation
-
- -

返回: CustomDeclarator

- -

Callback to produce a custom variable declarator node.

- -

表达式

- -
sequenceExpression(exprs[, loc])
- -
exprs: [ CustomExpression ]
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom sequence expression node.

- -
conditionalExpression(test, cons, alt[, loc])
- -
test: CustomExpression
-cons: CustomExpression
-alt: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom conditional expression node.

- -
unaryExpression(op, arg, isPrefix[, loc])
- -
op: UnaryOperator
-arg: CustomExpression
-isPrefix: boolean
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom unary expression node.

- -
binaryExpression(op, left, right[, loc])
- -
op: BinaryOperator
-left: CustomExpression
-right: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom binary expression node.

- -
assignmentExpression(op, left, right[, loc])
- -
op: AssignmentOperator
-left: CustomExpression
-right: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom assignment expression node.

- -
logicalExpression(op, left, right[, loc])
- -
op: LogicalOperator
-left: CustomExpression
-right: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom logical expression node.

- -
updateExpression(op, arg, isPrefix[, loc])
- -
op: UpdateOperator
-arg: CustomExpression
-isPrefix: boolean
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom update expression node.

- -
newExpression(callee, args[, loc])
- -
callee: CustomExpression
-args: [ CustomExpression ]
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom new-expression node.

- -
callExpression(callee, args[, loc])
- -
callee: CustomExpression
-args: [ CustomExpression ]
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom function call node.

- -
memberExpression(obj, prop, isComputed[, loc])
- -
obj: CustomExpression
-prop: CustomIdentifier | CustomExpression
-isComputed: boolean
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom member expression node.

- -
functionExpression(name, args, body, isGenerator, isExpression[, loc])
- -
name: CustomIdentifier | null
-args: [ CustomPattern ]
-body: CustomStatement | CustomExpression
-isGenerator: boolean
-isExpression: boolean
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom function expression node.

- -
arrayExpression(elts[, loc])
- -
elts: [ CustomExpression | null ]
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom array expression node.

- -
objectExpression(props[, loc])
- -
props: [ CustomObjectProperty ]
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom object expression node.

- -
thisExpression([loc])
- -
loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom this expression node.

- -
graphExpression(index, expr[, loc])
- -
index: uint32 >= 1
-expr: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom graph expression node.

- -
graphIndexExpression(index[, loc])
- -
index: uint32 >= 1
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom graph index expression node.

- -
comprehensionExpression(body, blocks, filter[, loc])
- -
body: CustomExpression
-blocks: [ CustomComprehensionBlock ]
-filter: CustomExpression | null
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom comprehension expression node.

- -
generatorExpression(body, blocks, filter[, loc])
- -
body: CustomExpression
-blocks: [ CustomComprehensionBlock ]
-filter: CustomExpression | null
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom generator expression node.

- -
yieldExpression(arg[, loc])
- -
arg: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom yield expression node.

- -
letExpression(head, body[, loc])
- -
head: [ CustomDeclarator ]
-body: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomExpression

- -

Callback to produce a custom let expression node.

- -

Patterns

- -
arrayPattern(elts[, loc])
- -
elts: [ CustomPattern | null ]
-loc: SourceLocation
-
- -

返回: CustomPattern

- -

Callback to produce a custom array destructuring pattern node.

- -
objectPattern(props[, loc])
- -
props: [ CustomPropertyPattern ]
-loc: SourceLocation
-
- -

返回: CustomPattern

- -

Callback to produce a custom object destructuring pattern node.

- -
propertyPattern(key, patt[, loc])
- -
key: CustomLiteral | CustomIdentifier
-patt: CustomPattern
-loc: SourceLocation
-
- -

返回: CustomPropertyPattern

- -

Callback to produce a custom object property destructuring pattern node.

- -

Clauses

- -
switchCase(test, cons[, loc])
- -
test: CustomExpression | null
-cons: [ CustomStatement ]
-loc: SourceLocation
-
- -

返回: CustomSwitchCase

- -

Callback to produce a custom case or default clause node. The test argument is null if and only if the node is a default clause.

- -
catchClause(arg, guard, body[, loc])
- -
arg: CustomPattern
-guard: CustomExpression
-body: CustomStatement
-loc: SourceLocation
-
- -

返回: CustomCatchClause

- -

Callback to produce a custom catch clause node.

- -
comprehensionBlock(left, right, isForEach[, loc])
- -
left: CustomPattern
-right: CustomExpression
-isForEach: boolean
-loc: SourceLocation
-
- -

返回: CustomComprehensionBlock

- -

Callback to produce a custom comprehension block node. The isForEach flag indicates whether the node is a for each block.

- -

Miscellaneous

- -
identifier(name[, loc])
- -
name: string
-loc: SourceLocation
-
- -

返回: CustomIdentifier/CustomPattern/CustomExpression

- -

Callback to produce a custom identifier node.

- -
literal(val[, loc])
- -
val: string | boolean | null | number | RegExp
-loc: SourceLocation
-
- -

返回: CustomLiteral / CustomExpression

- -

Callback to produce a custom literal node.

- -
property(kind, key, val[, loc])
- -
kind: "init" | "get" | "set"
-key: CustomLiteral | CustomIdentifier
-val: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomObjectProperty

- -

Callback to produce a custom object property initializer node.

- -

E4X

- -

Declarations

- -
xmlDefaultDeclaration(ns[, loc])
- -
loc: SourceLocation
-
- -

返回: CustomDeclaration

- -

Callback to produce a custom XML default namespace declaration node.

- -

Expressions

- -
xmlAnyName([loc])
- -
loc: SourceLocation
-
- -

返回: CustomXMLAnyName/CustomXML/CustomExpression

- -

Callback to produce a custom XML node for the wildcard pseudo-identifier *.

- -
xmlAttributeSelector(expr[, loc])
- -
expr: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomXML/CustomExpression

- -

Callback to produce a custom XML attribute selector node.

- -
xmlFilterExpression(left, right[, loc])
- -
left: CustomExpression
-right: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomXML/CustomExpression

- -

Callback to produce a custom XML filter expression node.

- -
xmlQualifiedIdentifier(left, right, isComputed[, loc])
- -
left: CustomIdentifier | CustomXMLAnyName
-right: CustomIdentifier | CustomExpression
-isComputed: boolean
-loc: SourceLocation
-
- -

返回: CustomXML/CustomExpression

- -

Callback to produce a custom qualified identifier node.

- -
xmlFunctionQualifiedIdentifier(right, isComputed[, loc])
- -
right: CustomIdentifier | CustomExpression
-isComputed: boolean
-loc: SourceLocation
-
- -

返回: CustomXML/CustomExpression

- -

Callback to produce a custom XML function-qualified identifier node.

- -
xmlElement(contents[, loc])
- -
contents: [ CustomXML ]
-loc: SourceLocation
-
- -

返回: CustomXML / CustomExpression

- -

Callback to produce a custom XML element node.

- -
xmlList(contents[, loc])
- -
contents: [ CustomXML ]
-loc: SourceLocation
-
- -

返回: CustomXML/CustomExpression

- -

Callback to produce a custom XML list node.

- -

XML

- -
xmlEscape(expr[, loc])
- -
expr: CustomExpression
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML escape node.

- -
xmlText(text[, loc])
- -
text: string
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML text node.

- -
xmlStartTag(contents[, loc])
- -
contents: [ CustomXML ]
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML start-tag node.

- -
xmlEndTag(contents[, loc])
- -
contents: [ CustomXML ]
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML end-tag node.

- -
xmlPointTag(contents[, loc])
- -
contents: [ CustomXML ]
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML point tag node.

- -
xmlName(contents[, loc])
- -
contents: string | [ CustomXML ]
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML name node.

- -
xmlAttribute(value[, loc])
- -
value: string
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML attribute node.

- -
xmlCdata(contents[, loc])
- -
contents: string
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML CDATA node.

- -
xmlComment(contents[, loc])
- -
contents: string
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML comment node.

- -
xmlProcessingInstruction(target, contents[, loc])
- -
target: string
-contents: string | null
-loc: SourceLocation
-
- -

返回: CustomXML

- -

Callback to produce a custom XML processing instruction node.

diff --git a/files/zh-cn/mozilla/projects/spidermonkey/releases/index.html b/files/zh-cn/mozilla/projects/spidermonkey/releases/index.html deleted file mode 100644 index fd88b37529..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/releases/index.html +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: SpiderMonkey releases -slug: Mozilla/Projects/SpiderMonkey/Releases -translation_of: Mozilla/Projects/SpiderMonkey/Releases ---- -
{{SpiderMonkeySidebar("Releases")}}
- -
-

本页开列了 SpiderMonkey 的版本记录.

-
- -
-

注意: 独立的 SpiderMonkey 并不是官方产品. Our continuous integration system does produce a tarball that is built into a binary that runs our smoke tests, but we do not maintain it nor actively test its suitability for general embedding. We have periodically created "releases", but they are best-effort and incomplete. We do happily accept patches, and make some effort to keep the tip of the Gecko tree minimally working as an embeddable source package. We are very limited in our ability to support older versions, including those labeled as "releases" on this page.

-
- -

The easiest way to fetch the version corresponding to the current Firefox release is to visit the treeherder page for the release repository and click on the first SM(pkg) link you see. That will open a small window in the bottom left with a line like " mozjs-57.0.1.tar.bz2".

- -

当前版本

- - - -

Future release

- - - -

过往版本

- - diff --git a/files/zh-cn/mozilla/projects/spidermonkey/split_object/index.html b/files/zh-cn/mozilla/projects/spidermonkey/split_object/index.html deleted file mode 100644 index 86d82e7d58..0000000000 --- a/files/zh-cn/mozilla/projects/spidermonkey/split_object/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Split object -slug: Mozilla/Projects/SpiderMonkey/Split_object -translation_of: Mozilla/Projects/SpiderMonkey/Split_object ---- -

In SpiderMonkey, a split object is made up of two JSObjects: an inner object and an outer object.

- -

Each half of a split object always has a pointer to the other half. Inner objects implement the JSExtendedClass.outerObject hook, which returns a pointer to the corresponding outer object. Outer objects implement the JSExtendedClass.innerObject hook. But the association is not fixed. An outer object may be associated with different inner objects at different times.

- -

This feature is complicated. Programs other than Mozilla that embed SpiderMonkey should avoid using split objects.

- -

The window object

- -

Split objects were introduced to resolve a problem posed by the window object. Three interrelated requirements on the window object seemed to conflict.

- - - - - - - -

Split objects were the solution. The inner window object is different for each page a browser window visits. It serves as the "globals" object and provides the JSPrincipals for scripts on that page. Access to inner window properties is fast. The outer window object is the object returned by window.open. It represents the window or tab itself and survives as the user navigates in that window or tab. The window object's JSClass.resolve hook ensures that properties of the inner object are visible via the outer object, if the running code has the right principals to access them. This privilege check may be slow.

- -

See {{ interwiki('wikimo', 'Gecko:SplitWindow', 'wikimo:Gecko:SplitWindow') }} and {{ Bug(296639) }} for more discussion.

- -

See also http://groups.google.com/group/mozil...81825b338fb84f

- -

Details

- -

This section describes split objects as a feature of the JSAPI. It catalogues (and tries to explain) the subtle ways in which split objects affect SpiderMonkey's behavior.

- -

Split objects are only useful for implementing objects that will be on the scope chain of functions. SpiderMonkey assumes that inner and outer objects are dangerous in two different and complementary ways.

- -

Inner objects are dangerous because they have fast property accessors that do not perform security checks. Therefore, no function may be allowed to see an inner object that has different JSPrincipals. Apart from the security issue, if one page directly or indirectly gets a reference to another page's window object, that window object must appear to behave like the outer window and navigate from page to page. SpiderMonkey arranges this by not allowing JS code to see inner objects at all. To enforce this rule:

- - - -

Outer objects are dangerous because their JSPrincipals may change over time. Because a Function inherits the JSPrincipals of its lexical scope (specifically, the nearest principals-aware object in its scope chain), untrusted code must never be able to make an outer object appear in a Function's scope chain. Again, SpiderMonkey enforces a slightly stronger rule: outer objects may never appear in a scope chain at all, except when put there by an explicit C-level JSAPI call (to JS_SetParent or equivalent). (Several objects, such as window.location and window.navigator, are intentionally parented to the outer window object using such APIs.) To enforce this rule:

- - - - - -

Inner and outer objects are in certain other respects the same object:

- - - -

Note that none of the rules listed here affects ordinary property accesses. SpiderMonkey's split object support, by itself, does not cause inner object properties to appear on the outer object or vice versa. Split objects that need this behavior must implement it in custom JSClass hooks. In the case of window, each half has custom hooks.

diff --git a/files/zh-cn/mozilla/rust/index.html b/files/zh-cn/mozilla/rust/index.html deleted file mode 100644 index f2964058fb..0000000000 --- a/files/zh-cn/mozilla/rust/index.html +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Rust编程语言 -slug: Mozilla/Rust -translation_of: Mozilla/Rust ---- -

Rust logoRust 是一个全新的开源系统编程语言,由Mozilla和社区的义务劳动者创造,它帮助开发者创造高速与安全的应用,同时能享受到现代多核处理器的强大特性。Rust使用易懂的语法避免了段错误(segmentation faults)并保证了线程安全。

- -

不仅如此,Rust提供了零成本抽象,更多语义,内存安全保证,不会发生竞争的线程,基于特性(trait)的泛型,模式匹配,类型推导,高效的C绑定,和最小运行时大小。

- -

想了解更多Rust,你可以:

- - - -

Rust 与系统编程的未来

- -

{{EmbedYouTube("8EPsnf_ZYU0")}}

- -

用Rust解锁并行的力量

- -

{{EmbedYouTube("cNeIOt8ZdAY")}}

- -

给Web开发者的Rust

- -

{{EmbedYouTube("FfoXFnzZbBM")}}

- -

用Rust实现安全系统编程

- -

{{EmbedYouTube("P3sfNGtpuxc")}}

- -

成长中的Rust社区

- -

{{EmbedYouTube("duv0tuPAnO0")}}

- -

Mozilla将Rust用于生产

- -

{{EmbedYouTube("2RhbYpgVpg0")}}

diff --git a/files/zh-cn/mozilla/tech/index.html b/files/zh-cn/mozilla/tech/index.html deleted file mode 100644 index 2e4f7a5d64..0000000000 --- a/files/zh-cn/mozilla/tech/index.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Mozilla 私有技术 -slug: Mozilla/Tech -translation_of: Mozilla/Tech ---- -

Mozilla has several technologies used as components of its projects. These are documented here. (flesh out this text).

-

{{LandingPageListSubpages}}

diff --git a/files/zh-cn/mozilla/tech/toolkit_api/extisessionstorage/index.html b/files/zh-cn/mozilla/tech/toolkit_api/extisessionstorage/index.html deleted file mode 100644 index 7d49c345e7..0000000000 --- a/files/zh-cn/mozilla/tech/toolkit_api/extisessionstorage/index.html +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: extISessionStorage -slug: Mozilla/Tech/Toolkit_API/extISessionStorage -translation_of: Mozilla/Tech/Toolkit_API/extISessionStorage ---- -

-

-

该条目记录了 Thunderbird 3 引入的新特性

-

-


extISessionStorage 允许一个扩展程序存储数据,该数据会在应用程序的整个生命周期内可用(比如浏览器). extISessionStorage 被定义在 toolkit/components/exthelper/extIApplication.idl.

-

通过XPCOM服务实现的 extIApplication: 查看相关指南在 FUEL (Firefox), STEEL (Thunderbird) 和 SMILE (SeaMonkey) 页面.

-

方法概述

-

这些方法通常是通过Application.storage来访问的.

- -
返回值类型 方法
boolean has(in AString aName)
void set(in AString aName, in nsIVariant aValue)
nsIVariant get(in AString aName, in nsIVariant aDefaultValue)
-

属性

- -
属性名 类型 描述
events readonly attribute extIEvents The events object for the storage supports: "change"
-

方法

-

has()

-

判断一个指定名称的存储项是否已经存在.

-
boolean has(in AString aName)
-
-
参数
-
aName
存储项名称
-
-
返回值
-

如果这个存储项已经存在,则返回true,否则返回false.

-

set()

-

为一个指定名称的存储项赋值.

-
void set(in AString aName, in nsIVariant aValue)
-
-
参数
-
aName
存储项名称
aValue
任意类型的值
-
-
返回值
-

-

get()

-

获取一个指定名称的存储项的值.如果该存储项不存在,则返回一个默认值.

-
nsIVariant get(in AString aName, in nsIVariant aDefaultValue)
-
-
参数
-
aName
存储项名称
-
-
返回值
-

指定存储项的值或者一个默认的返回值.

相关链接

-

 FUEL (Firefox), STEEL (Thunderbird) and SMILE (SeaMonkey)

-

diff --git a/files/zh-cn/mozilla/tech/toolkit_api/index.html b/files/zh-cn/mozilla/tech/toolkit_api/index.html deleted file mode 100644 index 7ba5906994..0000000000 --- a/files/zh-cn/mozilla/tech/toolkit_api/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Toolkit API -slug: Mozilla/Tech/Toolkit_API -translation_of: Mozilla/Tech/Toolkit_API ---- -

 

-

Mozilla Toolkit 是建立在Gecko上的应用程序接口集(APIs),用来提供对XUL应用的高级服务. 这些服务包含:

- -

更多信息

-

下面的开发者页面包含特别主题的例子和讨论:

-

XUL; XUL Overlays; Developing Extensions; XULRunner; Developing Themes; DOM; RDF; Storage; Creating Help Documentation

diff --git a/files/zh-cn/mozilla/tech/viewing_and_searching_mozilla_source_code_online/index.html b/files/zh-cn/mozilla/tech/viewing_and_searching_mozilla_source_code_online/index.html deleted file mode 100644 index 80965735d2..0000000000 --- a/files/zh-cn/mozilla/tech/viewing_and_searching_mozilla_source_code_online/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: 在线搜索并浏览Mozilla源代码 -slug: Mozilla/Tech/Viewing_and_searching_Mozilla_source_code_online -tags: - - 开发Mozilla - - 需要更新 -translation_of: Mozilla/Tech/Viewing_and_searching_Mozilla_source_code_online ---- -

托管在Mercurial资源库中的所有Mozilla项目的源代码都可以使用Searchfox在线搜索和查看,Searchfox是一个运行在AWS上的快速索引搜索引擎。

- -

请勿通过Searchfox下载源码;你可以通过下载tarball或使用Mercurial。

- -

Searchfox索引多个分支和模块。

- -

值得注意的几个Searchfox 有:

- - - -

Mozilla 源代码目录结构 在每个源码目录树中拥有一段简短的描述。

- -
-

你既可以浏览每个特定版本的源码,也可以下载他们. 每个版本连着源码,都在这归档

-
diff --git a/files/zh-cn/mozilla/tech/xpcom/glue/index.html b/files/zh-cn/mozilla/tech/xpcom/glue/index.html deleted file mode 100644 index 58bfdc731e..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/glue/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: XPCOM Glue -slug: Mozilla/Tech/XPCOM/Glue -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Glue ---- -

The XPCOM Glue is a static library which component developers and embedders can link against. It allows developers to link only against the frozen XPCOM method symbols and maintain compatibility with multiple versions of XPCOM.

-

Compiling or linking against XPCOM headers

-

There are three ways to compile/link against XPCOM headers/libraries:

-

Frozen linkage: dependent glue (dependent on xpcom.dll)

-

Code which wishes to use only frozen symbols but can tolerate a load-time dependency on xpcom.dll should link against xpcom.lib and xpcomglue_s.lib. This is the case for XPCOM components.

-

Frozen linkage: standalone glue (no DLL dependencies)

-

Embedding code which wishes to use only frozen symbols and cannot tolerate a load-time dependency on <tt>xpcom.dll</tt> should <tt>#define XPCOM_GLUE 1</tt> while compiling, and link against <tt>xpcomglue.lib</tt>. It should - - not - link against <tt>xpcomglue_s.lib</tt> or <tt>xpcom.lib</tt>.

-

In order to use XPCOM, the embedding application first needs to find where the XPCOM runtime is located. This is typically done using GRE_GetGREPathWithProperties. Then, the code must call XPCOMGlueStartup, which will dynamically link against the XPCOM runtime. Only then can the embedding application initialize and use XPCOM.

-

This linkage strategy is used when an embedder needs to bootstrap an embedding app by finding a compatible GRE. Extension or XULRunner application components should use the dependent glue.

-

Embedders using the standalone glue typically also need to avoid linking against NSPR as well.

-

Emlak ilanlar

-

Using Mozilla internal linkage

-

Mozilla internal code defines MOZILLA_INTERNAL_API while compiling and links against xpcom.lib and xpcom_core.lib. In almost all cases embedders should *not* use internal linkage. Components using internal linkage will have shared-library dependencies against non-frozen symbols in the XPCOM libraries, and will not work with any other versions of XPCOM other than the one it was compiled against.

-

Internal linkage will be unavailable to extension authors in XULRunner 1.9 (Firefox 3) because the nonfrozen symbols will not be exported from libxul. Extension and application authors currently using internal linkage should read the guide on Migrating from Internal Linkage to Frozen Linkage.

-

Threadsafe nsISupports implementations

-

When using glue libraries from Gecko 1.8 or later, a special step needs to be taken to use NS_IMPL_THREADSAFE_ISUPPORTS - - n - . This is because it forces a dependency on the NSPR library, which can otherwise be avoided. As described in bug 299664, the preprocessor symbol XPCOM_GLUE_USE_NSPR needs to be defined.

-

Sample Compiler/Linker Flags

-

Code compiled using XPCOM headers should always <tt>#include "xpcom-config.h"</tt> from the SDK, to ensure that XPCOM #defines are correct.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Linking StrategyCompiler FlagsLinker Flags
WindowsMacLinux
Dependent Glue<tt style="white-space: pre">#include "xpcom-config.h"</tt><tt>-LIBPATH:c:/path/to/sdk/lib xpcomglue_s.lib xpcom.lib nspr4.lib</tt><tt>-L/path/to/sdk/lib -L/path/to/sdk/bin -Wl,-executable-path,/path/to/sdk/bin -lxpcomglue_s -lxpcom -lnspr4</tt><tt>-L/path/to/sdk/lib -L/path/to/sdk/bin -Wl,-rpath-link,/path/to/sdk/bin -lxpcomglue_s -lxpcom -lnspr4</tt>
Standalone Glue<tt style="white-space: pre">#include "xpcom-config.h"
- #define XPCOM_GLUE 1</tt>
<tt>-LIBPATH:c:/path/to/sdk/lib xpcomglue.lib</tt><tt>-L/path/to/sdk/lib -lxpcomglue</tt><tt>-L/path/to/sdk/lib -lxpcomglue</tt>
-

Notes

- -

See Also

- diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/arrays/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/arrays/index.html deleted file mode 100644 index 53939ba6c0..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/arrays/index.html +++ /dev/null @@ -1,573 +0,0 @@ ---- -title: Array -slug: Mozilla/Tech/XPCOM/Guide/Arrays -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Arrays ---- -

 

-

Introduction

-

Array types

-

Mozilla has many array classes because each array is optimized for a particular usage pattern. This guide describes the available arrays as well as the enumerator classes that can be used to get to them. In this document the term Array refers to a container for multiple objects with a numeric, zero-based index.

-

The standard array classes are:

- -

This handy chart may make it easier to understand the different arrays:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassData TypeScriptable?Typesafe?Can be modified?Built in buffer?Ownership
nsIArrayXPCOM objectYesNoNoNoReference Counted, Weak/Strong
nsIMutableArrayXPCOM objectYesNoYesNoReference Counted, Weak/Strong
nsCOMArray<T>XPCOM objectNoYesYes*NoReference Counted, Strong
nsTArray<T>Any that has a default constructor and copy constructorNoYesYes*NoCan hold objects directly, in which case it owns them. When holding pointers, doesn't own the pointer.
nsVoidArrayAnyNoNoYes*NoWeak / None
nsStringArray
- nsCStringArray
nsString
- nsCString
NoYesYes*NoPrivate (copies strings)
nsAutoVoidArrayAnyNoNoYes*YesWeak / None
nsSmallVoidArrayAnyNoNoYes*NoWeak / None
nsISupportsArrayXPCOM ObjectYesNoYes*NoReference Counted, Strong
-

(*) Note: Concrete C++ arrays can be made read-only by declaring them const. For example:

-
// HandleList cannot modify the array because of const
-void HandleList(const nsVoidArray&);
-
-

In-place enumeration

-

Most of the arrays presented here provide callback-style means to enumerate members of an array. Instead of incrementally accessing each element of the array by its index, the arrays provide a way to pass in a callback function that will be called for each element in the array.

-

For most concrete C++ classes like nsVoidArray and nsCOMArray<T>, indexing should be faster than the callback-style enumeration, because accessing an indexed member of such an array is usually very fast, while enumeration has slight function call overhead. In the case of scriptable arrays like nsIArray however, the enumeration mechanism is often preferred because it avoids the AddRef / Release overhead that comes from accessing each object.

-

The only functional drawback to in-place enumeration is that you cannot manipulate the array itself during the enumeration. For example, you should not delete elements of an array during the enumeration as this will often confuse the loop which is enumerating the array.

-

Enumerators

-

Most arrays provide access to an object which is used to enumerate members of the array. These Enumerators maintain state about the current position in the array. Enumerators are used to access the elements in an ordered way, without relying on the underlying array type. These enumerators include:

- -

Obsolete arrays / enumerators

-

There are some deprecated classes which should not be used by new code.

- -

Which Array should I use?

-

Do not use nsISupportsArray; it is deprecated.

-

Does your array need to be scriptable? If so, use nsIArray.

-

Example: an array attribute in an IDL file would be nsIArray.

-

Will your array store non-refcounted objects and need automatic resizing? If so, use nsTArray<T>.

-

Example: an array of integers or an array of strings.

-

Will your array store non-refcounted objects and be a fixed size? If so, just use a native C++ array unless you need the enumeration options on nsTArray<T>.

-

Example: an array of error message static const char* pointers.

-

Are all the things you are storing interface pointers to instances of the same interface? If so, use nsCOMArray.

-

Example: a content node's list of nsIContent children.

-

Otherwise use nsIArray and make liberal use of QueryElementAt().

-

The point of nsCOMArray is that it's a template, and all the pointers in it must be pointers to the same type; it's nice to be able to use it because you get type-safety and don't have to spend time and code QIing (like you have to with nsIArray).

-

Array Guidelines

-

Here are a few simple rules which will keep your code clean and your developers happy:

- -

Scriptable Arrays

-

nsIArray / nsIMutableArray

-

Usage

-

nsIArray is useful if you need to pass arrays of COM objects through interfaces or require a scriptable array. It can hold strong or weak references to its container objects. This basic interface only allows querying of existing elements in the array. The methods that modify the array have been broken out into nsIMutableArray.

-

An nsIArray implementation can be created from C++ with the function NS_NewArray(nsIMutableArray**);. The created array implements nsIMutableArray and nsIArray. Since nsIArray derives from nsIMutableArray, the resulting array can be cast to a read-only array.

-
void GetList(nsIArray** aResult) {
-  nsCOMPtr<nsIMutableArray> array;
-  NS_NewArray(getter_AddRefs(array));
-
-  // append some elements
-  ...
-
-  // return it to the caller
-  *aResult = array;
-  NS_ADDREF(*aResult);
-}
-
-

Access to elements

-

Since nsIArray is a regular XPCOM object, its interfaces follows the standard conventions of ownership. Access to specific elements is through QueryElementAt, which is similar to QueryInterface, but it takes a specific index.

-
void NotifyObservers(nsIArray* aArray) {
-  PRUint32 length;
-  aArray->GetLength(&length);
-  for (PRUint32 i=0; i<length; ++i) {
-    nsCOMPtr<nsIMyObserver> element;
-    aArray->QueryElementAt(i, NS_GET_IID(nsIElement),
-                                getter_AddRefs(element));
-    element->Observe();
-  }
-}
-
-

A simpler option is to use the helper do_QueryElementAt which is typesafe.

-
void NotifyObservers(nsIArray* aArray) {
-  PRUint32 length;
-  aArray->GetLength(&length);
-  for (PRUint32 i=0; i<length; ++i) {
-    nsCOMPtr<nsIMyObserver> element =
-    do_QueryElementAt(aArray, i);
-     element->Observe();
-  }
-}
-
-

Passing as a parameter

-

Since nsIArray is an XPCOM object, it should be passed as a pointer. To distinguish between read-only arrays and writable arrays, you should make sure to pass a nsIArray or nsIMutableArray as appropriate.

-

When the array can or should be modified, then use nsIMutableArray:

-
// array is read-only because it uses nsIArray
-void PrintSize(nsIArray* elements) {
-  PRUint32 count;
-  elements->GetLength(&count);
-  printf("There are %d elements.\n", count);
-}
-
-// using nsIMutableArray, so callee may modify
-void TweakArray(nsIMutableArray* elements) {
-  elements->RemoveElementAt(0);
-  elements->AppendElement(newElement, PR_FALSE);
-}
-
-

While it is usually possible to call QueryInterface on an nsIArray to get access to the nsIMutableArray interface, this is against convention and it should be avoided.

-
// no need for the double-pointer, and this violates XPCOM rules
-// which expect acess to a new object
-void TweakArray(nsIMutableArray** elements) {
-  // ugh, extra indirection!
-  *elements->RemoveElementAt(0);
-  *elements->AppendElement(newElement, PR_FALSE);
-}
-
-

In-place enumeration

-

When accessing all members of an nsIArray, in-place enumeration is preferred over indexed access. However, I seem to have forgotten to implement that. Good thing the interface is under review. Sorry!

-

Enumerators

-

Creating an enumerator from an nsIArray is easy. The method Enumerate() returns a nsISimpleEnumerator which accesses all the elements in the array. Often, simply accessing an array by index, using QueryElementAt is faster. See the section on Enumerators to learn when to properly use enumerators.

-

For example, if you need to iterate an array returned from another object, you might use Enumerate().

-
...
-// get the array
-nsCOMPtr<nsIArray> array;
-foo->GetElements(getter_AddRefs(array));
-
-// make an enumerator
-nsCOMPtr<nsISimpleEnumerator> enumerator;
-array->Enumerate(getter_AddRefs(enumerator));
-
-// now enumerate the elements
-...
-
-

Typesafe Arrays

-

nsCOMArray<T>

-

nsCOMArray<T> is a typesafe wrapper around nsVoidArray, so it has a similar API. It enforces both typesafety and XPCOM reference counting by keeping an owning reference to each element in the array.

-

Usage

-

It is most often used as a member of a C++ class to store a list of well-typed XPCOM objects. It is also usually declared as an inline member rather than a pointer. As a class member, nsCOMArray<T> is preferred over nsIArray when access to the array is confined to the class itself.

-

For example, here is its use in a class:

-
class NodeContainer {
-public:
-  void AddNode(nsINode* node);
-
-private:
-  nsCOMArray<nsINode> mNodes;
-};
-
-// typesafety of mNodes ensures that we only append an nsINode*
-void NodeContainer::AddNode(nsINode* node) {
-  mNodes.AppendObject(node);
-}
-
-
-

nsCOMArray<T> can also be declared on the stack to collect a temporary list of objects and manipulate them. When the object goes out of scope, all its members are released.

-
void ProcessVisibleItems()
-{
-  // temporary stack-based nsCOMArray
-  nsCOMArray<nsIFoo> fooItems;
-  GetCompleteList(fooItems);
-
-  // now filter out non visible objects
-  // doing this backwards
-  PRUint32 i = fooItems.Count();
-  while (i > 0) {
-    --i;
-    PRBool isVisible;
-    fooItems[i]->GetIsVisible(&isVisible);
-    if (!isVisible) {
-      fooItems.RemoveObjectAt(i);
-    }
-  }
-
-  // now deal with the processed list
-  ProcessList(fooItems);
-
-  // fooItems will release all its members
-  // when it goes out of scope
-}
-
-

Access to elements

-

nsCOMArray<T> is a concrete C++ class, and so the [] operator is used to access its members. When using the [] operator, the reference count is unchanged. This allows direct processing of array elements without worrying about calling Release().

-

For example, this code calls the same method on each member:

-
void NotifyObservers(const nsCOMArray<nsIMyObserver>& observers) {
-  // Using [] doesn't leak!
-  for (PRInt32 i = observers.Count() - 1; i >= 0 ; i--)
-    observers[i]->Observe();
-}
-
-

Be careful with this though, you could end up with a weak pointer if you're converting from non-nsCOMArray code.

-
// old version, relied on automatic addref
-// mElements is an nsISupportsArray*
-void GetFirstObject(nsIElement** aResult) {
-  // no need to call NS_ADDREF - this does it for you
-  mElements->QueryElementAt(0, NS_GET_IID(nsIElement),
-  (void**)aResult);
-}
-
-// new version, make sure to call NS_ADDREF()
-// mElements is now a nsCOMArray<nsIElement>
-void GetFirstObject(nsIElement** aResult) {
-  *aResult = mElements[0];
-  NS_ADDREF(*aResult);
-}
-
-

Passing as a parameter

-

When passing nsCOMArray<T> among functions, the convention is to pass by reference. Also be sure to use const if you want to enforce that the array is read-only.

-

Here is an example with a read-only and a writable array:

-
// array is read-only because of const
-void PrintSize(const nsCOMArray<nsIElements>& elements) {
- printf("There are %d elements.\n", elements.Count());
-}
-
-// no const, so we can modify the array
-void TweakArray(nsCOMArray<nsIElement>& elements, nsIElement* newElement) {
-  elements.RemoveObjectAt(0);
-  elements.AppendObject(newElement);
-}
-
-

In-place enumeration

-

The callback-based enumeration in nsCOMArray<T> is about as fast as, if not faster than, standard loop-based iteration. The callback mechanism can be useful when integrating with existing callback-style code however.

-

One particularly nice thing about the callback mechanism is that it is typesafe. For instance:

-
PR_CALLBACK PRBool getFirstVisible(nsIElement* element, void* closure)   {
- PRBool isVisible;
- element->IsVisible(&isVisible);
-
- // stop at first object
- if (isVisible) {
-  NS_STATIC_CAST(ClosureObject*,closure)->element = element;
-  return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-...
-// enumerate to find the object
-ClosureObject closureObject = { 0 };
-if (!mElements.EnumerateForwards(getFirstVisible, closureObject))
-             processElement(closureObject->element);
-...
-
-

Enumerators

-

A nsISimpleEnumerator can be created to provide access to a nsCOMArray<T>. When the enumerator is created, it takes a snapshot of the elements in the array, so that the enumerator can outlive the array.

-

To create the enumerator, use NS_NewArrayEnumerator(nsISimpleEnumerator**, const nsCOMArray<T>&). For example:

-
// mElements is an nsCOMArray<nsIElement>
-nsFoo::GetElements(nsISimpleEnumerator** aResult) {
-  return NS_NewArrayEnumerator(aResult, mElements);
-}
-
-

nsTArray<T>

-

nsTArray<T> is a typesafe array for holding various objects. It can be used to hold objects directly, not just pointers to objects.

-

Usage

-

It is most often used as a member of a C++ class to store a list of well-typed objects. It is also usually declared as an inline member rather than a pointer. As a class member, nsTArray<T> is preferred over nsVoidArray.

-

For example, here is its use in a class:

-
class MediaList {
-public:
-  void AddMedium(const nsString& aMedium);
-
-private:
-  nsTArray<nsString> mMedia;
-};
-
-// typesafety of mMedia ensures that we only append an nsString
-void NodeContainer::AddMedium(const nsString& aMedium) {
-  mMedia.AppendElement(aMedium);
-}
-
-
-

nsTArray<T> can also be declared on the stack to collect a temporary list of objects and manipulate them. When the object goes out of scope, all its members have their destructors called. Note that if the nsTArray<T> holds pointers to objects, the objects will not be deleted (and hence not have their destructors called).

-
void ProcessVisibleItems()
-{
-  // temporary stack-based nsTArray
-  nsTArray<FooStruct> fooItems;
-  GetCompleteList(fooItems);
-
-  // now filter out non visible objects
-  // doing this backwards
-  PRUint32 i = fooItems.Length();
-  while (i > 0) {
-    --i;
-    PRBool isVisible;
-    fooItems[i]->GetIsVisible(&isVisible);
-    if (!isVisible) {
-      fooItems.RemoveElementAt(i);
-    }
-  }
-
-  // now deal with the processed list
-  ProcessList(fooItems);
-
-  // fooItems will call the destructors of all the FooStruct objects
-  // when it goes out of scope
-}
-
-

Access to elements

-

nsTArray<T> is a concrete C++ class, and so the [] operator is used to access its members.

-

For example, this code calls the same method on each member:

-
void NotifyObservers(const nsTArray<ObserverClass*>& observers) {
-  for (PRUint32 i = observers.Length(); i > 0 ; ) {
-    --i;
-    observers[i]->Observe();
-  }
-}
-
-

Passing as a parameter

-

When passing nsTArray<T> among functions, the convention is to pass by reference. Also be sure to use const if you want to enforce that the array is read-only.

-

Here is an example with a read-only and a writable array:

-
// array is read-only because of const
-void PrintSize(const nsTArray<nsElement>& elements) {
- printf("There are %d elements.\n", elements.Length());
-}
-
-// no const, so we can modify the array
-void TweakArray(nsTArray<nsElement>& elements,
-                const nsElement& newElement) {
-  elements.RemoveElementAt(0);
-  elements.AppendElement(newElement);
-}
-
-

In-place enumeration

-

There are no enumerator objects that work on an nsTArray<T>.

-

C++ Arrays

-

nsVoidArray

-

nsVoidArray is a concrete C++ class that allows for storage of any arbitrary object. The base type for all objects is void *. When converting to/from a void *, use NS_STATIC_CAST to ensure that no const-ness is lost.

-

Note that nsVoidArray defines no semantics of ownership of its objects. Depending on its use, the array may either own the objects that it points to, or its member may be pointers to existing objects that are owned by another data structure. Because nsVoidArray itself does not define any ownership rules, it is up to the consumer to know when it is appropriate to free objects out of the array.

-

This implies that when an nsVoidArray goes out of scope, seperate code must free any memory that is semantically owned by the array. This should always be documented in the declaration of the array instance.

-

nsCOMArray<T> was designed to eliminate some of the overhead of using nsVoidArray when using COM objects. If your code is using nsVoidArray to keep references to COM objects, consider converting it to nsCOMArray<T>.

-

Usage

-

nsVoidArray is often used as a member variable in a class. Remember to document ownership!

-
struct FooElement {
- ...
-};
-
-class nsFoo : nsIFoo {
- ...
- virtual ~nsFoo();
- ...
-
- private:
- // mElements owns a list of FooElement structs,
- // which must be deleted when this object goes away
- nsVoidArray mElements;
-
- // mVisibleElements contains weak (non-owning) references
- // to elements in mElements, and does not need to be cleaned up
- nsVoidArray mVisibleElements;
-};
-
-nsFoo::~nsFoo() {
- // mVisibleElements is fine, but
- // don't forget to clean up mElements!
- PRUint32 i, count = mElements.Count();
- for (i=0; i<count; ++i)
-  delete NS_STATIC_CAST(FooElement*, mElements[i]);
- }
-
-
-

As you can see, nsVoidArray has some context-specific overhead to make sure memory is cleaned up appropriately.

-

Access to elements

-

The [] operator is used to access member variables. Don't forget to use NS_STATIC_CAST().

-
for (i=0; i<count; ++i) {
- FooElement* element = NS_STATIC_CAST(FooElement*,mElements[i]);
- // now manipulate element
-}
-
-
-

Passing as a parameter

-

Like other concrete C++ classes, passing by reference using the & syntax is preferred.

-

In-place enumeration

-

Enumerators

-

nsStringArray / nsCStringArray

-

Usage

-

Access to elements

-

Passing as a parameter

-

In-place enumeration

-

Enumerators

-

nsAutoVoidArray

-

Usage

-

Access to elements

-

Passing as a parameter

-

In-place enumeration

-

Enumerators

-

nsSmallVoidArray

-

Usage

-

Access to elements

-

Passing as a parameter

-

In-place enumeration

-

Enumerators

-

Enumerators

-

Enumerators are very simple, structure-free objects for visiting each member of a set of objects. The enumerators are used as a generic interface for arrays, hashtables, and other constructs which contain one or more objects. When designing public interfaces, enumerators are the preferred mechanism for accessing these structures because they hide the details of the implementation behind the interface.

-

nsISimpleEnumerator

-

nsISimpleEnumerator is a generic enumerator for enumerating a list of any XPCOM object. There are many implementations of nsISimpleEnumerator, including one that enumerates nsIArray objects, and another one for nsCOMArray. It is very common for other interfaces which support nsISimpleEnumerator to make their own implementations.

-

nsIStringEnumerator

-

String enumerators provide an easy way to pass a list of strings around with minimal copying. Both unicode strings and UTF8-encoded strings are supported. For more information about the different types of strings, see the String Guide.

-

String enumerators can be created from nsStringArray or nsCStringArray objects. The implementation of the string enumerator interfaces for nsStringArray and nsCStringArray supports conversion between UTF8 and Unicode, and can be QueryInterface'd back and forth between nsIStringEnumerator and nsIUTF8StringEnumerator.

-

To create an nsIStringEnumerator for an nsStringArray, you can use one of the variations of NS_NewStringEnumerator. There are also corresponding enumerators and helpers for UTF8 strings. In the examples below, NS_NewUTF8StringEnumerator can be used along with nsIUTF8StringEnumerator and nsCStringArray.

-

This first example demonstrates the case where a class which owns an nsStringArray, and are returns an nsIStringEnumerator to a caller. You can use the variation of NS_NewStringEnumerator that ensures the owner of the array outlives the enumerator. This is necessary because nsStringArray is not reference counted. Without holding a reference to the owner, the enumerator could be left with a dangling pointer to a deleted nsStringArray.

-
class nsFoo : nsIFoo {
-...
-private:
-  nsStringArray mElementNames;
-};
-
-nsFoo::GetElementNames(nsIStringEnumerator** aResult)
-{
-  // pass in "this" to make sure the enumerator
-  // holds a reference to "this"
-  return NS_NewStringEnumerator(aResult, mElementNames, this);
-}
-
-

One variant of NS_NewStringEnumerator does not require an owner, but should only be used when the lifetime of the enumerator is known to be shorter than that of the array. Often this is used when a method must take a nsIStringEnumerator rather than an nsStringArray, due to some sort of interface constraint.

-
class nsFoo : nsIFoo {
- ...
- // when ProcessElements returns, the enumerator is at the
- // end of the list, and can be released.
- NS_IMETHODIMP ProcessNames(nsIStringEnumerator*);
- private:
-
- nsStringArray mElementNames;
-};
-
-...
-nsCOMPtr<nsIStringEnumerator> enumerator;
-NS_NewStringEnumerator(getter_AddRefs(enumerator), mElementNames);
-
-// now call a method on "this" that has a known behavior
-ProcessNames(enumerator);
-// now enumerator is used up, and can be released
-...
-
-

The last version of nsIStringEnumerator takes ownership of an nsStringArray and is responsible for freeing the array when the enumerator is used up.

-
void GetNames(nsIStringEnumerator** aResult)
-{
- nsStringArray *resultArray = new nsStringArray;
- resultArray->AppendString(str1);
- resultArray->AppendString(str2);
-
- // enumerator will free resultArray
- return NS_NewAdoptingStringEnumerator(aResult, resultArray);
-}
-
-

As noted above, these implementations of nsIStringEnumerator can also be QueryInterface'd between nsIStringEnumerator and nsIUTF8StringEnumerator. The implementations will properly convert back and forth between UTF8 and Unicode. To ensure that you get the right implementation and the conversion is done in the right direction, make sure that you call the version of NS_NewStringEnumerator or NS_NewUTF8StringEnumerator that corresponds to the array type, not the enumerator type.

-

For example, if a class has an internal nsCStringArray of UTF8 strings, but needs to implement an interface which returns an nsIStringEnumerator, it should use NS_NewStringEnumerator:

-
class nsFoo : nsIFoo {
- ...
- NS_IMETHOD GetStrings(nsIStringEnumerator** aResult);
-
-
 private:
- nsCStringArray mElementNames;
-};
-
-NS_IMETHODIMP
-nsFoo::GetStrings(nsIStringEnumerator** aResult) {
- nsresult rv;
- nsCOMPtr<nsIUTF8StringEnumerator> enumerator
- rv = NS_NewUTF8StringEnumerator(getter_AddRefs(enumerator),
-                                       mElementNames, this);
- return CallQueryInterface(enumerator, aResult);
-}
-
-

Obsolete Arrays and Enumerators

-

nsISupportsArray

-

nsIEnumerator (includes nsIBidirectionalEnumerator)

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/an_overview_of_xpcom/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/an_overview_of_xpcom/index.html deleted file mode 100644 index 64bf41704f..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/an_overview_of_xpcom/index.html +++ /dev/null @@ -1,535 +0,0 @@ ---- -title: 创建_XPCOM_组件/XPCOM_简介 -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/An_Overview_of_XPCOM -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/An_Overview_of_XPCOM ---- -

-

« 上一页下一页 »

-

- -

这是一本关于 XPCOM 的书. 这本书是以编写一个 XPCOM 组件的方式来组织的, 但是这个过程涵盖了 XPCOM 组件模型主要的出发点, 概念和术语.

- -

本章以 XPCOM 的快速导览开始, 简单介绍了 XPCOM 和组件开发的基本概念和技术. 本章的大部分内容从一个很高的角度介绍了这些概念, 这些概念将在创建一个称为 WebLock 的 Mozilla 组件过程中逐渐透彻的讲述.

- -

XPCOM 解决方案

- -

Cross Platform Component Object Module (XPCOM) 是一个允许开发人员把一个大的工程划分成小的模块的框架. 这些小模块称为组件, 它们在运行时刻组装在一起.

- -

XPCOM 的目标是使软件的不同部分分别开发, 相互独立. 为了是应用的不同组件之间能够互操作, XPCOM 把组件的实现接口(后面讨论接口)分开. 同时 XPCOM 还提供了加载和操纵这些组件的库和工具以及服务, 以帮助开发人员编写跨平台的代码和组件版本管理; 因此组件可以在不破坏应用或者重新生成应用的同时被替换被更新. 通过使用 XPCOM, 开发人员创建的组件可以在不同的应用中被重用, 或者替换当前应用中的组件以改变应用的功能.

- -

XPCOM 不只提供组件软件开发的支持, 它同时提供一个开发平台的大多数功能的支持:

- - - -

我们将在后面的章节中详细讨论上面的条目, 但是现在, 仅仅把 XPCOM 想象成一个 组件开发平台, 它提供了上面的这些特性.

- -

Gecko

- -

XPCOM 尽管在许多方面类似于 Microsoft COM, 但 XPCOM 被设计成主要应用于应用层. XPCOM 的最重要的应用是 Gecko, 一个开源的, 遵循标准的, 嵌入式 web 浏览器和 工具包.

- -

XPCOM 是访问 Gecko 库和嵌入或扩展 Gecko 的方法. 本书着重于后者 - 扩展 Gecko - 但是本书中描述的基本思想对嵌入 Gecko 的开发人员也很重要.

- -

Gecko 应用在许多 internet 程序中, 主要是浏览器. 包括 Gateway/AOL Instant AOL device 和 Nokia Media Terminal. Gecko 最近还被应用于的 Compuserve 客户端, AOL for Mac OS X, Netscape 7, 当然还包括 Mozilla 客户端. Gecko 是目前而言主流的开源浏览器.

- -

组件

- -

XPCOM 允许把一个大的工程分解为一些小部分. 这些小部分称为组件, 通常是一些小的可重用的二进制库(在 Windows 下表现为一个 DLL (动态联接库), Unix 下为一个 DSO (分布式共享对象), 这些二进制库可以包含一个或多个组件. 当多个相关组件被封装到一个二进制库, 这个库也称为模块.

- -

把软件划分成不同的组件可以使开发和维护工作变得更容易. 除了这个好处, 模块化组件化的编程还有下面的优势:

- - - - - - - - - - - - - - - - - - - - - - - - -
优点描述
重用模块化的代码可以在其他应用和环境中被重用.
更新在不需要重新编译整个应用的情况下更新组件.
性能代码按照模块化组织, 模块就不必要立刻被加载, 而是以 "lazy" 方式加载, 或者根本不需要加载. 这样就可以提升应用的整体性能.
维护甚至在不更新组件的情况下, 按照模块化的方式设计应用也能够使你对感兴趣的部分的维护变得更容易.
- -

Mozilla 有几百万行代码, 没有那个人能够彻底搞明白整个代码的细节. 面对这样的一个系统, 最好的方式是把它划分成一些小的, 更容易管理的部分; 同时使用组件模型来编程, 把相关组件组织到各个模块中去. 比如说, Mozilla 的网络库就包含了 HTTP, FTP, 及其他协议的组件, 这些组件被塞到一个单独的库里. 这个库就是网络模块, 也就是通常所说的 "necko."

- -

但是把事物划分开来并不一定就好, 有许多事物作为一个整体组织起来才是最好的方式, 或者根本就不能划分开来. 比如说, 一个小孩就可能不吃没有果酱的三明志, 对于他来说, 果酱和三明志是缺一不可的整体. 同样的情形也会存在于某些软件中, 某些需要紧耦合的仅仅在内部使用的部分就并不需要费力去把它拆开成为小的模块.

- -

Gecko 中的 HTTP (超文本传输协议)  组件并不会暴露它内部的类, 它是作为一个整体来使用. 组件内部的事物不应该暴露给 XPCOM. 在 Mozilla 早期的开发中, 有些组件的创建并不适当, 但是随着开发的深入, 这些部分会被逐渐移出 XPCOM.

- -

接口

- -

把软件划分成组件通常一个好的解决方法, 但是我们该怎么做呢? 基本的思路是按照功能进行划分, 理解这些功能块之间的如何进行通信. 这些组件之间的通信通道就构成了各个组件的边界, 这些边界形式的描述为接口.

- -

接口并不是编程中的一个新的概念. 从我们的第一个 "HelloWorld" 程序开始我们就一直在不知不觉的使用它, 这里的接口就存在于我们的应用程序和打印程序之间. 应用程序使用 stdio 库提供的接口来把 "hello world" 字符串打印到屏幕上. XPCOM 与 "HelloWorld" 程序的不同之处在于 XPCOM 会在运行时刻找到这个屏幕打印的功能, 而 XPCOM 事前根本就不需要在编译的时刻了解 stdio 库提供了什么东西.

- -

接口允许开发人员把功能的具体实现封装在组件内部, 而客户程序不需要了解这个功能是如何实现的, 它只需要使用它就行了.

- -
-

接口与按照契约(Contract)编程

- -

一个接口在组件与客户程序之间达成契约. 并没有任何强制措施保证认同这个契约, 但是忽略它会是致命的. 在基于组件的编程中, 组件保证它提供的接口是不变的 - 不同版本的组件都要提供同样的访问方法 - 这就与使用它的客户程序达成了一种契约. 从这种角度来说, 基于组件的编程通常也称为按照契约编程.

-
- -

接口与封装

- -

组件边界之间的抽象对软件的可维护性与可重用性是致关重要的. 举个例子来说, 考虑下面一个没有很好封装的类. 在下面的例子中, 使用可自由访问的 public 的初始化方法可能会出问题.

- -

SomeClass类初始化

- -
class SomeClass
-{
-  public:
-    // Constructor
-    SomeClass();
-
-    // Virtual Destructor
-    virtual ~SomeClass();
-
-    // init method
-    void Init();
-
-    void DoSomethingUseful();
-};
-
- -

系统要工作正常, 客户程序员必须注意到组件程序员建立的潜规则. 这就是这个未很好封装的类的契约: 这是一套关于何时该调用一个方法, 调用这个方法之前应该做什么的规则. 这个规则可能指出 DoSomethingUseful 方法只能在调用 Init() 之后被使用. DoSomethingUseful 方法可能会做某些检查工作以保证条件满足 - Init 已经被调用.

- -

除了在代码中给出注释告诉客户程序员关于 Init() 规则之外, 程序员可以使他的契约更明晰. 首先对象的构造函数可以封装起来, 然后向客户程序员提供一个声明 DoSomethingUseful 方法的虚基类. 通过这种方式, 构造函数和初始化函数被隐藏起来. 在这种半封装条件下, 这个类只向客户程序暴露一些良好定义的可调用方法(或者称为接口). 一旦按照这种方式封装一个类, 客户程序只能看到的是下面的接口:

- -

SomeInterface封装

- -
class SomeInterface
-{
-  public:
-    virtual void DoSomethingUseful() = 0;
-};
-
- -

实现类就可以从这个虚基类派生, 实现接口的功能. 客户程序使用类厂(factory pattern)模式来创建对象(参看类厂), 而封装类的内部实现. XPCOM 以这种方式把客户程序屏蔽在组件的内部工作之外, 而客户程序也只依赖于提供所需要功能的接口.

- -

nsISupports 基接口

- -

组件与基于接口的编程的两个最基本的问题是: 一个是组件生存期, 也称为对象所属关系; 另一个是接口查询, 它是在运行时刻确定接口能够提供哪些接口. 这一节介绍基接口 nsISupports - 它是 XPCOM 中所有接口的父接口, 它提供了上面两个问题的解决方案.

- -
对象所属关系
- -

在 XPCOM 中, 由于组件可以实现任意多的不同接口, 接口必须是引用计数的. 组件在内部跟踪客户程序对它的接口引用了多少次, 当接口计数为零的时候组件就会卸载它自己.

- -

当一个组件创建后, 组件内部有一个整数在跟踪这个引用计数值. 客户程序实例化组件就会自动对这个引用计数加一; 在组件的整个生存期内, 引用计数或加或减, 总是大于零的. 如果在某个时刻, 所有的客户程序对该组件都失去了兴趣, 引用计数减到零, 组件就会卸载自己.

- -

客户程序使用相关接口是一个非常直接的过程. XPCOM 有一些工具让我们更方便的使用接口, 我们会在后面讲述. 如果客户程序在使用接口的时候忘记对接口的引用计数进行相关操作, 就会对组件的维护工作带来某些问题. 此时, 由于组件的引用计数始终不为零, 它就永远不会释放, 从而导致内存泄漏. 引用计数系统就象 XPCOM 的许多其他事物一样, 是客户与组件之间的契约. 如果遵守这些契约, 就会工作得很正常, 反之不然. 由创建接口指针的函数负责对初始化的接口引用加1, 这个引用也称为所属引用.

- -
-

XPCOM中的指针

- -

XPCOM 中的指针术语指的是接口指针. 它与常规指针相比有细微的差别, 毕竟它们都指向的是某个内存区域. 但是 XPCOM 指针指向的都是从 nsISupports 基接口派生而来的接口实现, 这个基接口包括三个基本的方法: AddRef, Release, 和 QueryInterface.

-
- -

nsISupports 接口提供了对接口查询与引用计数基本的支持. 这个接口的成员方法包括: QueryInterface, AddRef, 和 Release. 这些方法提供了从一个对象获取正确接口的基本方法, 加引用计数, 释放不再使用的对象. nsISupports 接口的声明如下:

- -

nsISupports 接口

- -
class Sample: public nsISupports
-{
-  private:
-    nsrefcnt mRefCnt;
-  public:
-    Sample();
-    virtual ~Sample();
-
-    NS_IMETHOD QueryInterface(const nsIID &aIID, void **aResult);
-    NS_IMETHOD_(nsrefcnt) AddRef(void);
-    NS_IMETHOD_(nsrefcnt) Release(void);
-};
-
- -

接口中使用的各种数据类型见XPCOM 类型一节. nsISupports 接口的实现代码如下:

- -

nsISupports 接口实现

- -
Sample::Sample()
-{
-  // initialize the reference count to 0
-  mRefCnt = 0;
-}
-Sample::~Sample()
-{
-}
-
-// typical, generic implementation of QI
-NS_IMETHODIMP Sample::QueryInterface(const nsIID &aIID,
-                                  void **aResult)
-{
-  if (aResult == NULL) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  *aResult = NULL;
-  if (aIID.Equals(kISupportsIID)) {
-    *aResult = (void *) this;
-  }
-  if (*aResult == NULL) {
-    return NS_ERROR_NO_INTERFACE;
-  }
-  // add a reference
-  AddRef();
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt) Sample::AddRef()
-{
-  return ++mRefCnt;
-}
-
-NS_IMETHODIMP_(nsrefcnt) Sample::Release()
-{
-  if (--mRefCnt == 0) {
-    delete this;
-    return 0;
-  }
-  // optional: return the reference count
-  return mRefCnt;
-}
-
- -
对象接口的发现
- -

继承是面向对象编程中另一个非常重要的话题. 继承是通过一个类派生另一个类的方法. 当一个类继承另一个类, 继承类可以重载基类的缺省动作, 而不需要拷贝基类的代码, 从而创建更加专有的类. 如下所示:

- -

简单类继承

- -
class Shape
-{
-  private:
-    int m_x;
-    int m_y;
-
-  public:
-    virtual void Draw() = 0;
-    Shape();
-    virtual ~Shape();
-};
-
-class Circle : public Shape
-{
-  private:
-    int m_radius;
-  public:
-    virtual Draw();
-    Circle(int x, int y, int radius);
-    virtual ~Circle();
-};
-
- -

CircleShape 类派生. Circle 本身也是一个 Shape, 但是 Shape 并不一定是 Circle. 在这种情况下, Shape基类, CircleShape 的子类.

- -

在 XPCOM 中, 所有的类都派生自 nsISupports 接口, 这样所有的对象都提供 nsISupports接口, 但是这些对象是更专有的类, 在运行时刻必须能找到它. 比如说在简单类继承例子中, 如果对象是一个 Circle, 你就可以调用 Shape 类的方法. 就是为什么在 XPCOM 中, 所有的对象都派生自 nsISupports 接口: 它允许客户程序根据需要发现和访问不同的接口.

- -

在 C++ 中, 我们可以使用 dynamic_cast<> 来把一个 Shape 对象的指针强制转化成一个 Circle 指针, 如果不能转化就抛出异常. 但是在 XPCOM 中, 由于性能开销和平台兼容性问题, 采用 RTTI (运行时刻类型信息) 的方法是不行的.

- -
-

XPCOM 中的异常

- -

XPCOM 并不直接支持 C++ 的异常处理. 在 XPCOM 中, 所有的异常必须在组件内部处理, 而不能跨越接口的边界. 然后接口方法返回一个 nsresult 错误值(这些错误码请参考 XPCOM API Reference). 客户程序根据这些错误码进行"异常"处理.

-
- -

XPCOM 没有采用 C++ RTTI 机制来实现对象指针的动态转化, 它使用 QueryInterface 方法来把一个对象指针 cast 成正确的接口指针.

- -

每个接口使用称为 "uuidgen" 的工具来生成专有ID. 这个 ID 是一个全局唯一的 128-bit 值. 在接口的语境中, 这个 ID 又称为 IID. (组件语境中, 这个 ID 代表的是一个契约)

- -

当客户程序想查询一个对象是否支持某个接口, 它把接口的 IID 值传递给这个对象的 QueryInterface 方法. 如果对象支持这个接口, 它就会对自己的引用计数加1, 然后返回指向那个专有接口的指针. 反之, 如果不支持这个接口, 它会返回一个错误码.

- -
class nsISupports {
-  public:
-    long QueryInterface(const nsIID & uuid,
-                        void **result) = 0;
-    long AddRef(void) = 0;
-    long Release(void) = 0;
-};
-
- -

QueryInterface 的第一个参数是一个 nsIID 类型的引用, 它封装了 IID. nsIID 类有三种方法: Equals, Parse, 和 ToString. Equals 在接口查询中是最重要的, 它用来比较两个 nsIID 对象是否相同.

- -

在客户以 IID 调用 nsISupports 接口的 QueryInterface 方法时, 我们必须保证返回一个有效的 result 参数(在Using XPCOM Utilities to Make Things Easier 一章中, 我们将看到怎样更方便的实现一个 nsIID 类). QueryInterface 方法应该支持该组件所有接口的查询.

- -

QueryInterface 方法的实现中, IID 参数与组件支持 nsIID 类进行比较. 如果匹配, 对象的 this 指针转化为 void 指针, 引用计数加1, 把 void 指针返回给客户程序.

- -

在上面的例子中, 仅仅使用 C 方式的类型转化就足够了. 但是在把 void 指针 cast 成接口指针的时候, 还有更多的问题, 因为返回的接口指针必须与 vtable (virtual table) 相对应. 当出现菱形多重继承的时候, 可能这种接口转化就会有问题.

- -

XPCOM 的ID

- -

除了上一节中的接口 IID, XPCOM 还使用两种 ID 来区分类与组件.

- -
-

XPCOM ID类

- -

nsIID 类实际上是一种 nsID 类. 其他的 nsID, CID 和 IID, 分别指的是一个实体类和一个专有的接口.

- -

nsID 类提供 Equals 类似的方法, 来比较 ID. 请参考 Identifiers in XPCOM 一节, 其中对 nsID 类有更多的讨论.

-
- -

CID

- -

CID 是一个唯一的 128-bit 值, 类似于 IID, 它用于全局标识唯一的类或者组件. nsISupports 的 CID 就象:

- -

00000000-0000-0000-c000-000000000046

- -

由于 CID 比较长, 通常我们都使用#define来定义它:

- -
#define SAMPLE_CID \
-{ 0x777f7150, 0x4a2b, 0x4301, \
-{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
-
- -

我们将会看到许多 NS_DEFINE_CID 的定义. 下面的宏用 CID 定义了一个静态变量:

- -
static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID);
-
- -

CID 有时也称为类 ID. 如果一个类实现了多个接口, 当CID 在该类发布后, 就与该类的 IID 一起被冻结了.

- -

契约 ID

- -

契约 ID 是一个用于访问组件的可读(to humen)的字符串. 一个 CID 或者一个契约 ID 可以用于从一个组件管理器获取组件. 下面是一个用于 LDAP 操作组件的契约 ID:

- -
"@mozilla.org/network/ldap-operation;1"
-
- -

契约 ID 的格式是: 用斜杠分开的组件的, 模块, 组件名, 版本号.

- -

与 CID 类似, 契约 ID 指的是组件实现而不是接口. 但是契约 ID 并不像CID那样,被限定为某个专有实现, 它更通用. 一个契约 ID 只是指明需要实现的一组接口,可以通过任意数量的CID满足这个需要. 契约 ID 与 CID 的这种不同, 使得组件重写成为可能.

- -

类厂

- -

把代码划分成组件, 客户代码通常使用 new 操作符来构造实例对象:

- -
SomeClass* component = new SomeClass();
-
- -

这种模式或多或少地需要客户对组件有一定的了解,至少要知道组件的大小. 类厂设计模式此时可以用来封装对象的构造过程. 类厂模式的目的是在不暴露对象的实现和初始化的前提下创建对象. 在 SomeClass 例子中, 可以按照类厂模式把 SomeClass 对象的构造和初始化封装在 New_SomeInterface 函数中:

- -

封装构造函数

- -
int New_SomeInterface(SomeInterface** ret)
-{
-  // create the object
-  SomeClass* out = new SomeClass();
-  if (!out) return -1;
-
-  // init the object
-  if (out->Init() == FALSE)
-  {
-    delete out;
-    return -1;
-  }
-
-  // cast to the interface
-  *ret = static_cast<SomeInterface*>(out);
-  return 0;
-}
-
- -

类厂本身是一个管理组件实例化的类. 在 XPCOM 中, 类厂要实现 nsIFactory 接口, 它们就象上面的代码一样要使用类厂设计模式来封装对象的构造和初始化.

- -

封装构造函数 的例子是一个简单的无状态的类厂版本, 实际的编程要复杂一些, 一般的类厂都需要保存状态. 类厂至少应该保存那些对象已经被创建了的信息. 如果类厂管理的实例被存放在一个动态联接库中, 还需要知道什么时候可以卸载这个动态联接库. 当类厂保存了这样的信息, 就可以向类厂查询一个对象是否已经被创建.

- -

另一个需要保存的信息是关于单件(singleton). 如果一个类厂已经创建了一个单件类型的类, 后续的创建该单件的函数调用将返回已经创建的对象. 尽管有更好的工具和方式来管理单件(在讨论 nsIServiceManager 会看到), 开发人员可能仍然需要通过这种方式来保证只有一个单件对象被创建.

- -

厂模式可以完全利用函数来做, 状态可以保存在全局变量中; 但是使用类的方式来实现厂模式还有更多的好处. 其一是: 我们可以管理从 nsISupports 接口派生而来的类厂本身的生存期. 当我们试图把多个类厂划分成一组, 然后确定是否能卸载这一组类厂的时候, 这一点非常重要. 另一个好处是: 类厂可以引入其他需要支持的接口. 在我们后面讨论 nsIClassInfo 接口的时候, 我们会看到某些类厂使用这个接口支持信息查询, 诸如这个对象是用什么语言写的, 对象支持的接口等等. 这种派生自 nsISupports 的 "future-proofing" 特性非常关键.

- -

XPIDL 与类型库

- -

定义接口的简单而强劲的方法是使用接口定义语言(IDL) - 这实际上是在一个跨平台而语言无关开发环境下定义接口的需求. XPCOM 使用的是源自于 CORBA OMG 接口定义语言(IDL)的变体, 称为 XPIDL, 来定义接口, XPIDL 可以定义接口的方法, 属性, 常量, 以及接口继承.

- -

采用 XPIDL 定义接口还存在一些缺陷. 它不支持多继承, 同时 XPIDL 定义的方法名不能相同,你不能有两个相同名字但是所接受的参数不同的函数. - 不能像 C++ 语言的成员函数一样通过参数不同重载, 毕竟接口同时要支持类似于 C 这样的语言.

- -
void FooWithInt(in int x);
-void FooWithString(in string x);
-void FooWithURI(in nsIURI x);
-
- -

然而尽管有这些问题, XPIDL 的功能仍然是非常强大的. XPIDL 能自动生成以 .xpt 为后缀的类型库, 或者说 typelibs. 类型库是接口的二进制表示, 它向非 C++ 语言提供接口的访问与控制. 非 C++ 语言通过类型库来了解接口支持哪些方法, 如何调用这些方法, 这称为 XPConnect. XPConnect 是 XPCOM 向类似于 JavaScript 这样的语言提供组件访问的 Wrapper. 参看Connecting to Components from the Interface获取更多关于 XPConnect 的信息.

- -

从其他类型的语言访问接口, 常常说成是接口被反射(reflected)到这种语言. 每一个被反射的接口必须提供相应的类型库. 当前可以使用 C, C++, 和 JavaScript 来编写组件.

- -
-

使用其他语言编写组件

- -

在使用其他语言创建组件的时候, 不需要利用 XPCOM 提供给 C++ 程序员的工具(诸如一些宏, 智能指针等等, 我们可以方便的利用到这种语言本身来创建组件. 比如说, 基于 Python 的 XPCOM 组件可以从 JavaScript 来调用.

- -

参看 Resources 获取更多使用其他语言来创建组件的信息.

-
- -

所有的 XPCOM 接口都用 XPIDL 语法来定义. xpidl 编译器会从这个 IDL 文件产生类型库和 C++ 头文件. 在Defining the WebLock Interface in XPIDL 一节详细描述了 XPIDL 语法.

- -

XPCOM 服务

- -

当客户需要某个组件提供的功能的时候, 通常都是实例化一个新的组件对象. 比如说, 客户程序需要某些处理文件, 这里每个组件就代表一个文件, 客户可能会同时处理多个这样的组件.

- -

但是在某些情况下对象表示的是一种服务, 这种服务只能有一个拷贝(尽管会有多个服务同时运行). 每次客户程序访问服务提供的功能时, 客户程序都是与同一个服务实例在打交道. 比如说, 一个用户查询公司的电话号码数据库, 数据库作为一个对象对用户来说都是同一的. 如若不然的话, 就需要维护两个数据库拷贝, 这种开销将非常大, 而且还存在数据内容不一致的问题. 单件设计模式就是提供系统中需要的这种单点访问功能.

- -

XPCOM 不仅提供了对组件的支持和管理服务, 它还包含了许多编写跨平台组件所需要的其他服务. 其中包括: 跨平台文件抽象, 向 XPCOM 开发人员提供同一而强大的文件访问功能. 目录服务, 提供应用和特定系统定位信息. 内存管理, 保证所有对象使用同样的内存分配器. 事件通知机制, 允许传递简单消息. 本教程将在后面展现如何使用这些服务, XPCOM API Reference 一节有完整的接口索引列表.

- -

XPCOM 类型

- -

XPCOM 声明了许多数据类型和简单宏, 这些东西将在我们后面的例子中看到. 大多数的宏都是简单的重定义, 下一节我们会描述一些最常用的数据类型.

- -

方法类型

- -

下面的类型用在 XPCOM 方法调用的参数和返回值定义中.

- - - - - - - - - - - - - - - - - - - - - - - - -
NS_IMETHOD声明方法返回值. XPCOM 的方法缺省的返回值声明.
NS_IMETHODIMP方法实现返回值. XPCOM 方法函数返回的时候缺省采用这种类型的返回值.
NS_IMETHODIMP_(type)特定类型的方法实现返回值. 诸如 AddRefRelease 的方法不返回缺省类型, 这种返回值的不一致虽然有点不舒服, 但是必需的.
NS_IMPORT共享库内部使用的符号局部声明
NS_EXPORT共享库导出的符号声明.
- -

引用计数

- -

下面的宏提供对引用计数的基本操作.

- - - - - - - - - - - - - - - - - - - - -
NS_ADDREF调用 nsISupports 对象的 AddRef 方法.
NS_IF_ADDREF与上一个方法类似, 不同之处在于这个宏在AddRef之前会检查对象指针是否为空(虚函数指针).
NS_RELEASE调用 nsISupports 对象的 Release 方法.
NS_IF_RELEASE与上一个方法类似, 不同之处在于这个宏在调用Release之前会检查空指针.
- -

状态码

- -

下面的宏测试状态码.

- - - - - - - - - - - - -
NS_FAILED如果传递的状态码为失败, 则返回真.
NS_SUCCEEDED如果传递的状态码为成功, 则返回真.
- -

变量映射

- - - - - - - - - - - - - - - - -
nsrefcnt缺省的引用计数类型, 是一个 32-bit 整数.
nsresult缺省数据类型, 是一个 32-bit 整数.
nsnull缺省 null 类型.
- -

通用 XPCOM 错误码

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NS_ERROR_NOT_INITIALIZED如果实例未初试化, 返回该值.
NS_ERROR_ALREADY_INITIALIZED如果实例已初试化, 返回该值.
NS_ERROR_NOT_IMPLEMENTED如果方法未实现, 返回该值.
NS_ERROR_NO_INTERFACE如果组件不支持某种类型接口, 返回该值.
NS_ERROR_NULL_POINTER如果指针指向 nsnull, 返回该值 .
NS_ERROR_FAILURE如果某个方法失效, 返回该值, 这时一个通用的错误值.
NS_ERROR_UNEXPECTED如果一个未预料的错误发生, 返回该值.
NS_ERROR_OUT_OF_MEMORY如果无法进行内存分配, 返回该值.
NS_ERROR_FACTORY_NOT_REGISTERED如果一个请求的类型未注册, 返回该值.
- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/building_the_weblock_ui/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/building_the_weblock_ui/index.html deleted file mode 100644 index 51f544fb16..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/building_the_weblock_ui/index.html +++ /dev/null @@ -1,297 +0,0 @@ ---- -title: Building the WebLock UI -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Building_the_WebLock_UI -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Building_the_WebLock_UI ---- -

-

« 上一页下一页 »

-

- -

到目前为止我们建立了一个可以安装到Gecko应用中的组件。你所使用的XPCOM接口和工具是通用的跨平台的,可以被Gecko Runtime Environment或者任何Mozilla1.2以后任何基于Gecko的应用(这时GRE已经可用)。

- -

本章,我们将建立WebLock组件的用户接口,这就意味着添加到现有的 Mozilla 浏览器[other-mozlike-browsers]. 他使用 XUL, 这是一个Gecko知道如何呈现用户界面的XML语言, 同时它也跟特定的Mozilla用户界面交互, 为此它要把自己作为UI的扩展安装起来. Specifically, the user interface we create in this chapter will beoverlaid into the statusbar of the browser component, where it will provide a small icon the user can click to access the web lock interface.

- -

WebLock Indicator in Browser

- -

Image:web-lock-ui.png

- -

User Interface Package List

- -

本章所描述的用户界面包括4个文件:

- - - -

下面章节描述每个文件的功能。. In the following chapter we'll describe how you can take these files and create apackage , an installable archive that includes the WebLock component and the new UI.

- -

因为这些步骤 (特别是 overlay section) 与Mozilla非常相关, the chapter is divided up into a couple of different sections. 第二部分, XUL, 描述XML-based 用户接口语言 (XUL) 以及他如何创建一个对话框访问WebLock 组件和它的服务. 第三部分, Overlaying New User Interface Into Mozilla, 描述如何建立一个overlay到浏览器以便Mozilla build能访问这个对话框. 在overlay section, 我们讨论如何从Mozilla导入scripts, images, 和其他资源到你的 UI, 这会是比较复杂的部分.

- -

If the WebLock component is being installed in Mozilla or another Gecko-based browser, then this third section shows you how to create the entry point in the browser for controlling the web locking. If you are planning on deploying the WebLock component in some other application, you'll have to devise a different means of access (e.g., native widgetry that instantiates and controls the WebLock component).

- -

Client Code Overview

- -

在我们开始实际用户界面以前,我们应该首先建立访问WebLock组件和它的接口来控制browser的Web locking的客户代码.

- -

首先, it's important to be able to 表达Lock的基本状态as soon as it's loaded. 如同安全网页icon, weblock icon 在browser右下角,提示browser是否当前是锁定的. Since the WebLock component is always initialized as unlocked, we can have the 客户代码 - 接口中的JavaScript代码 - 表达并跟踪状态 as the user manipulates the iWebLock interface. A boolean wLocked variable can do this:

- -
// initialize the wLocked variable as unlocked
-var wLocked = 0;
-
- -

Then the functions that get called from the interface and call through to the lock and unlock methods of the WebLock component must also adjust this variable accordingly:

- -
function wLock()
-{
-  // check to see if locking is on or off
-  weblock.lock();
-  wLocked = 1;
-}
-
-function wUnLock()
-{
-  // check to see if locking is on or off
-  weblock.unlock();
-  wLocked = 0;
-}
-
- -

这些函数的前提是WebLock 组件对于 JavaScript可见,in the form of the weblock object being used in the snippets above. As you can see, weblock is initialized as a global JavaScript variable, available in the scope of these functions and others:

- -
var weblock = Components.classes["@dougt/weblock"]
-                        .getService()
-                        .QueryInterface(Components.interfaces.iWebLock);
-
- -

In addition to this basic setup, you must also write JavaScript that uses the AddSite method to add new sites to the white list. This is a bit more complicated, because it requires that you work with the currently loaded page or provide other UI (e.g., a textfield where you can enter an arbitrary URL) for specifying URLs. In the XUL section we'll go into how the user interface is defined. This section describes the functions that are called from the interface and how they interact with the WebLock component.

- -

The URL that the AddSite method expects is a string, so we can pass a string directly in from the user interface, or we can do a check on the string and verify that it's a valid URL. In this tutorial, focusing as it is on the WebLock functionality (rather than the UI), we'll assume the strings we get from the UI itself are URLs we actually want to write to the white list:

- -
function addThisSite()
-{
-  var tf = document.getElementById("dialog.input");
-  // weblock is global and declared above
-  weblock.AddSite(tf.value);
-}
-
- -

这段javascript可以直接被 XUL widget调用, where the input string is retrieved as the value property of the textbox element.

- -

你还需要建立一个函数当用户点击weblock icon的时候来显示WebLock 窗口. That function uses the openDialog method from the window object and takes the URL to the XUL file in which the dialog is defined:

- -
function loadWebLock()
-{
-  window.openDialog("chrome://weblock/weblock.xul");
-}
-
- -

XUL

- -

The entire user interface of the Mozilla browser and all of the applications that go with it, including the mail client, the IRC client, and others, have been defined in an XML language called XUL. Elements in the XUL markup map to widgets in the interface that Gecko renders in a fairly straightforward way - so, for instance, the root element of an application window is the element <window/>, the root element of the dialog we'll be creating here is <dialog/>, and so forth. Within a XUL application file, elements like <button/>, menu/>, and checkbox/> can be hooked up to an event model, to scripts, and to the XPCOM interfaces that carry out a lot of the browser functionality in Mozilla.

- -

In Using XPCOM Components you saw how XPCOM objects are reflected into the interface layer as JavaScript objects. In this chapter, now that we've created the WebLock component and made it available to XPCOM, we create the UI that actually instantiates the WebLock component and uses its methods to control page loading in the browser.

- -

In the previous section, we outlined the JavaScript that interacts with the WebLock component. In this section, we are going to create the XUL interface that calls the JavaScript methods when the user interacts with it.

- -

The XUL Document

- -

The first thing to do is create the actual XUL document in which the user interface for the dialog and the events that initiate interaction with the web locking are defined. At the top of all XUL documents, an XML declaration is followed by the root element for the document, which is usually <window/> 对于对话框,也可以是<dialog/>. The "shell" for the XUL file, then, looks like this:

- -
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<dialog id="weblock_ui"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        title="Web Lock Manager"
-        persist="screenX screenY"
-        screenX="24" screenY="24">
-
-</dialog>
-
- -

注意这部分XUL文件也包含了stylesheet declaration, which imports CSS rules and applies them to particular parts of the interface. In Gecko, CSS 被用来几乎控制所有的XUL界面表现 - its color, position, style, and to some extent its behavior as well. The web lock manager dialog does not deviate from the look of a standard dialog, so it can use a single declaration to import the "global" skin from the browser and make it available to the widgets you define in weblock.xul.

- -

You can save this first, 最外层的web lock dialog部分称为weblock.xul, 你要把它放在附录B所描述的安装包里.

- -
-

注意这个文件包含了当用户/管理员点击web locking icon的时候弹出的对话框. 这部分UI - 需要动态地装载到Mozilla runtime - 在Overlaying New User Interface Into Mozilla.

-
- -

描述

- -

最终的对话框看起来是.

- -

Web Lock Manager Dialog

- -

Image:Weblock-sitelist-ui.png

- -

As you can see, it's a simple interface, providing just enough widgetry to lock and unlock the browser and to add new sites to the list. The entire XUL file for the web lock manager dialog is defined in weblock.xul below.

- -

The Locking UI

- -

Once you have the basic XUL wrapper set up for your interface, the next step is to define that part of the interface that locks and unlocks the browser. One of the most efficient ways to expose this is to use radio buttons, which allow the user to toggle a particulart state, as the figure above illustrates.

- -

In XUL individual <radio/> elements are contained within a parent element called <radiogroup/>. Grouping radio elements together creates the toggling UI by requiring that one or another of the elements be selected, but not both.

- -

The XUL that defines the radiogroup in the web lock manager dialog is this:

- -
<radiogroup>
-   <radio label="lock"/>
-   <radio label="unlock" selected="true"/>
-</radiogroup>
-
- -

Since the WebLock component always starts up in the unlocked position, you can add the selected="true" attribute and value on the unlock radio button and reset it dynamically as the user takes action.

- -

Site Adding UI

- -

The next step is to create that part of the user interface that lets you add a new site to the white list. There are other, more sophisticated ways to do this; you may also want to include some UI that lets you view the white list or edit it as a list. In this part of the tutorial, however, we only provide the means of adding an URL provided as a string (which is not checked for validity) and passing it through to the AddSite API we defined in the earlier part of the tutorial.

- -
<separator class="thin"/>
-
-<hbox align="center">
-  <textbox id="url.input" flex="1"/>
-  <button label="Add this URL" oncommand="addThisSite();"/>
-</hbox>
-
- -

This snippet introduces a couple of new general layout widgets in XUL. The separator that appears at the top of this snippet creates a little divider between widgets like the kind you see in menus that divide sets of functionality available there. The parent of the textbox that users enter an URL into is something called an <hbox/>, which is a layout widget - often invisible - that controls the way its child elements are rendered. In this case the <hbox/> centers the textbox and the button children, and it orients them horizontally (in contrast to the <vbox/>, which orients its children vertically).

- -

Notice also that when it's clicked, the button executes a JavaScript function called addThisSite(), which we've already defined in the weblock.js file in Client Code Overview above.

- -

weblock.xul

- -
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<dialog id="weblock_mgg"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-	title="Web Lock Manager"
-        style="width: 30em;"
-        persist="screenX screenY"
-        screenX="24" screenY="24">
-
-  <script src="chrome://weblock/content/weblock.js"/>
-
-  <hbox>
-    <separator orient="vertical" class="thin"/>
-    <vbox flex="1">
-      <separator class="thin"/>
-      <hbox align="center">
-        <textbox id="dialog.input" flex="1"/>
-        <button label="Add this URL"
-                oncommand="addThisSite();"/>
-      </hbox>
-      <hbox align="center">
-        <radiogroup onchange="toggleLock();">
-          <radio label="lock"/>
-          <radio label="unlock"/>
-        </radiogroup>
-        <spacer flex="1"/>
-      </hbox>
-    </vbox>
-  </hbox>
-
-</dialog>
-
- -

Overlaying New User Interface Into Mozilla

- -

你已经有了一个可以跟WebLock组件交互的对话框, 但是你怎么把它装到browser中? 然后你怎么访问它呢? 当安装和准备好以后,WebLock 组件已经可以用了: XPCOM finds it and adds it to the list of registered components, and then WebLock observes the XPCOM startup event and initializes itself.

- -

But you still have to add your new UI into the browser so it can call the component, and the Mozilla overlay mechanism is the way to do this. Overlays 是 XUL文件可以用来注册他们自己以便动态地嵌入到Browser UI合适的位置.

- -

webLockOverlay.xul

- -

The XUL that defines the new icon is small: 这是一个调用JavaScript function来装载前面我们定义的weblock.xul 文件的小图表. The icon is actually a separate <statusbarpanel/> element that gets overlaid into the main browser, along with some JavaScript and some CSS to control the behavior and appearance of the element, respectively. Here is that XUL file in its entirety:

- -

The WebLock Overlay

- -
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://navigator/content/weblock.css" type="text/css"?>
-
-<overlay id="weblockOverlay"
-         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-  <script type="application/x-javascript"
-          src="chrome://weblock/content/weblock.js"/>
-
-  <statusbar id="status-bar">
-    <statusbarpanel class="statusbarpanel-iconic"
-                    id="weblock-status"
-                    insertbefore="offline-status"
-                    oncommand="loadWebLock();"
-                    status="none"/>
-  </statusbar>
-
-</overlay>
-
- -

文件的根元素不是<window/> 而是<overlay/>. In overlays 被 XUL elements用来把他们和其他元素相区分的id属性被设置称为browser中他们要嵌入部分的值. In this case, the weblock <statusbarpanel/> appears as a child of the <statusbar/> element with id "status-bar". This id is the same one used by the <statusbar/> in navigator.xul, which means that the overlay mechanism will merge the new UI here (i.e., the weblock statusbarpanel) and the UI already defined within that browser <statusbar/> at runtime.

- -

Other Resources

- -

这部分描述剩下的需要添加和打包到WebLock组件来提供web locking用户界面的文件。

- -
-

Other Front End Resources

- -

在某些UI包中, 本地化 resources are also defined. These include DTDs in which the language in which the UI is labelled can be extracted into external files, which are swapped with DTDs for other languages. For example, user interface packages often include an English DTD that defines labels and strings for button and menus and other elements in the interface. When the user selects a differentlanguage pack , all of the English that's been externalized in these files is dynamically replaced with the new choice. In addition to DTDs, the localization parts of a user interface may also include string bundles in which strings that are used in the interface JavaScript can be similarly replaced. 有一些技术通过单独的文件来提供这种功能. 包含bindings in XML files,metadata in RDF files, whole collections of CSS files calledskins , and others.

-
- -

weblock.css

- -

The following style rules are defined in weblock.css, a CSS file that is loaded by the overlay and applied to the icon in the browser that reflects the current status of the web lock and provides access to the web lock manager dialog.

- -
statusbarpanel#weblock-status
-{
-  list-style-image: url("chrome://weblock/wlock.gif");
-}
-
-statusbarpanel#weblock-status[status="locked"]
-{
-  list-style-image: url("chrome://weblock/wl-lock.gif");
-}
-
-statusbarpanel#weblock-status[status="unlocked"]
-{
-  list-style-image: url("chrome://weblock/wl-un.gif");
-}
-
- -

The style rules are distinguished by the state of the status attribute on the element in the XUL with the id "weblock-status." As you can see above, when the status of the element is set to "locked", the image wl-lock.gif is used to show the state, and when the web locking is unlocked, it uses wl-un.gif. (Note: We include three images to represent the state of the weblock, but wlock.gif and wl-lock.gif are identical, since weblock is presumed to be unlocked when it's loaded. This tutorial makes use of only two different states, but you can further customize the look of the weblock using the three images if you wish.)

- -

Since the presentation of the weblock manager dialog itself doesn't require any special styles, these are all the rules you need in the weblock.css. Note that the weblock.xul file in which the manager is defined imports only the global skin:

- -
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
- -

Save weblock.css in your working directory.

- -

You should now have the four files listed at the top of this chapter as the "packing list" for the WebLock package (see User Interface Package List). Don't worry for now about where these files are. 下一章, Packaging WebLock, 我们讨论如何打包这些文件以便 WebLock 组件或者别的资源利用它们.

- -

Image Resources

- -

如果你学习本教程并且希望使用WebLock组件在statusbar中的图片,你可以从 http://www.brownhen.com/weblock下载他们和其他weblock相关资源. The GIF files that represent the various states are:

- - - -
    -
  1. Note: other-mozlike-browsers
    或者你可能会很喜欢这些东西. 还有一些基于 Gecko的browsers ,例如Beonex 和 IBM Web Browser 也会共享很多Mozilla用户界面成分, 你也可能装载 WebLock 组件和用户界面到其中. 不过请注意, WebLock有可能还不能保证完全安装到Mozilla Firefox,因为firefox有一些新的变化 (这本书是2003的版本).
  2. -
- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/component_internals/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/component_internals/index.html deleted file mode 100644 index d29da9a71d..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/component_internals/index.html +++ /dev/null @@ -1,217 +0,0 @@ ---- -title: Component Internals -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Component_Internals -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Component_Internals ---- -

-

« 上一页下一页 »

-
前几章以组件使用者的角度介绍了XPCOM 组件, 本章将以软件开发者的角度讨论XPCOM.您可以继续阅读以明白XPCOM的一般实现方式, 或者您也可以跳到下一章, 在下一章,以WebLock为例向一步一步您介绍 组件的开发过程。 XXX mediawiki...XXX sucks

- -

使用C++创建组件

- -

让我们开始研究怎样用c++创建XPCOM组件. 最常见的组件是以C++编写并编译成共享库(如Windows平台的DLL或者Unix平台的DSO)。

- -

The illustration below shows the basic relationship between the shared library containing the component implementation code you write and the XPCOM framework itself. In this diagram, the outer boundary is that of the module, the shared library in which a component is defined.

- -

A Component in the XPCOM Framework

- -

Image:component-internals-framework.png

- -

When you build a component or module and compile it into a library, it must export a single method named NSGetModule. This NSGetModule function is the entry point for accessing the library. It gets called during registration and unregistration of the component, and when XPCOM wants to discover what interfaces or classes the module/library implements. In this chapter we will outline this entire process.

- -

As A Component in the XPCOM Framework illustrates, in addition to the NSGetModule entry point, there are nsIModule and nsIFactory interfaces that control the actual creation of the component, and also the string and XPCOM glue parts, which we'll discuss in some detail in the next section (see XPCOM Glue). These latter supply ease-of-development utilities like smart pointers, generic modules support, and simple string implementations. The largest and possibly most complex part of a component is the code specific to the component itself.

- -
-

But Where Are the Components?

- -

Components reside in modules, and those modules are defined in shared library files that typically sit in the components directory of an XPCOM application.

- -

A set of default libraries stored in this components directory makes up a typical Gecko installation, providing functionality that consists of networking, layout, composition, a cross-platform user interface, and others.

- -

Another, even more basic view of this relationship of components to the files and interfaces that define them is shown in Onion Peel View of XPCOM Component Creation in the next chapter. The component is an abstraction sitting between the actual module in which it is implemented and the objects that its factory code creates for use by clients.

-
- -

XPCOM Initialization

- -

To understand why and when your component library gets called, it is important to understand the XPCOM initalization process. When an application starts up, that application may initialize XPCOM. The sequence of events that kicks off this XPCOM initialization may be triggered by user action or by the application startup itself. A web browser that embeds Gecko, for example, may initialize XPCOM at startup through the embedding APIs. Another application may delay this startup until XPCOM is needed for the first time. In either case, the initialization sequence within XPCOM is the same.

- -

XPCOM starts when the application makes a call to initialize it. Parameters passed to this startup call allow you to configure some aspects of XPCOM, including the customization of location of specific directories. The main purpose of the API at this point is to change which components directory XPCOM searches when it looks for XPCOM components. This is how the API is used, for example, in the Gecko Runtime Environment (GRE).

- -
-

XPCOM Startup

- -

The six basic steps to XPCOM startup are as follows:

- -
    -
  1. Application starts XPCOM.
  2. -
  3. XPCOM sends a notification that it's beginning startup.
  4. -
  5. XPCOM finds and processes the component manifest (see Component Manifests below).
  6. -
  7. XPCOM finds and processes the type library manifest (see Type Library Manifests below).
  8. -
  9. If there are new components, XPCOM registers them: -
      -
    1. XPCOM calls autoregistration start.
    2. -
    3. XPCOM registers new components.
    4. -
    5. XPCOM calls autoregistration end.
    6. -
    -
  10. -
  11. Complete XPCOM startup: XPCOM notifies that it's begun.
  12. -
- -

Component manifests and type library manifests are described in the following section, XPCOM Registry Manifests.

-
- -

XPCOM Registry Manifests

- -

XPCOM uses special files called manifests to track and persist information about the components to the local system. There are two types of manifests that XPCOM uses to track components:

- -
Component Manifests
- -

When XPCOM first starts up, it looks for the component manifest, which is a file that lists all registered components, and stores details on exactly what each component can do. XPCOM uses the component manifest to determine which components have been overridden. Starting with Mozilla 1.2, this file is named compreg.dat and exists in the components directory, but there are efforts to move it out of this location to a less application-centric (and thus more user-centric) location. Any Gecko-based application may choose to locate it elsewhere. XPCOM reads this file into an in-memory database.

- -
-

Component Manifests

- -

The component manifest is a mapping of files to components and components to classes. It specifies the following information:

- - - -

The component manifest maps component files to unique identifiers for the specific implementations (class IDs), which in turn are mapped to more general component identifiers (contract IDs).

-
- -
Type Library Manifests
- -

Another important file that XPCOM reads in is the type library manifest file. This file is also located in the components directory and is named xpti.dat. It includes the location and search paths of all type library files on the system. This file also lists all known interfaces and links to the type library files that define these interface structures. These type library files are at the core of XPCOM scriptablity and the binary component architecture of XPCOM.

- -
-

Type Library Manifests

- -

Type library manifests contain the following information:

- - -
- -

Using the data in these two manifests, XPCOM knows exactly which component libraries have been installed and what implementations go with which interfaces. Additionally, it relates the components to the type libraries in which the binary representations of the interfaces they support are defined.

- -

The next section describes how to hook into the XPCOM startup and registration process and make the data about your component available in these manifests, so that your component will be found and registered at startup.

- -

Registration Methods in XPCOM

- -
-

What Is XPCOM Registration?

- -

In a nutshell, registration is the process that makes XPCOM aware of your component(s). As this section and the next describe, you can register your component explicitly during installation, or with the regxpcom program, or you can use the autoregistration methods in the Service Manager to find and register components in a specified components directory:

- - - -

The registration process is fairly involved. This section introduces it in terms of XPCOM initialization, and the next chapter describes what you have to do in your component code to register your component with XPCOM.

-
- -

Once the manifest files are read in, XPCOM checks to see if there are any components that need to be registered. There are two supported ways to go about registering your XPCOM component. The first is to use XPInstall, which is an installation technology that may or may not come with a Gecko application and provides interfaces for registering your component during installation. Another, more explicit way to register your component is to run the application regxpcom, which is built as part of Mozilla and is also available in the Gecko SDK. regxpcom registers your component in the default component registry.

- -

A Gecko embedding application may also provide its own way of registering XPCOM components using the interface that is in fact used by both XPInstall and regxpcom, nsIComponentRegistrar. An application, for example, could provide a "registration-less" component directory whose components are automatically registered at startup and unregistered at shutdown. Component discovery does not currently happen automatically in non-debug builds of Gecko, however.

- -

When the registration process begins, XPCOM broadcasts to all registered observers a notification that says XPCOM has begun the registration of new components. After all components are registered, another notification is fired saying that XPCOM is done with the registration step. The nsIObserver interface that handles this notification is discussed in Starting WebLock.

- -

Once registration is complete and the notifications have fired, XPCOM is ready to be used by the application. If XPCOM registered your component, then it will be available to other parts of the XPCOM system. The XPCOM Initialization section in this chapter describes registration in more detail.

- -

Autoregistration

- -

The term autoregistration is sometimes used synonymously with registration in XPCOM. In the What Is XPCOM Registration? note, we describe the three ways you can register components with XPCOM. Sometimes, applications use the nsIComponentRegistrar interface and create their own code for watching a particular directory and registering new components that are added there, which is what's often referred to as autoregistration. You should always know what the installation and registration requirements are for the applications that will be using your component.

- -

The Shutdown Process

- -

When the application is ready to shutdown XPCOM, it calls NS_ShutdownXPCOM. When that method is called, the following sequence of events occurs:

- -
    -
  1. XPCOM fires a shutdown notification to all registered observers.
  2. -
  3. XPCOM closes down the Component Manager, the Service Manager and associated services.
  4. -
  5. XPCOM frees all global services.
  6. -
  7. NS_ShutdownXPCOM returns and the application may exit normally.
  8. -
- -
-

The Unstoppable Shutdown

- -

Note that shutdown observation is unstoppable. In other words, the event you observe cannot be used to implement something like a "Are you sure you want to Quit?" dialog. Rather, the shutdown event gives the component or embedding application a last chance to clean up any leftovers before they are released. In order to support something like an "Are you sure you want to quit" dialog, the application needs to provide a higher-level event (e.g., startShutdown()) which allows for cancellation.

- -

Note also that XPCOM services may deny you access once you have received the shutdown notification. It is possible that XPCOM will return an error if you access the nsIServiceManager at that point, for example, so you may have to keep a reference-counted pointer to the service you are interested in using during this notification.

-
- -

Component Loaders

- -

Components can be written in many languages. So far this book has been focusing on "native components," shared libraries exporting a NSGetModule symbol. But if there is a component loader for Javascript installed, then you can also write a JavaScript component.

- -

To register, unregister, load and manage various component types, XPCOM abstracts the interface between the XPCOM component and XPCOM with the Component Loader. This loader is responsible for initialization, loading, unloading, and supporting the nsIModule interface on behalf of each component. It is the Component Loader's responsibility to provide scriptable component support.

- -

When building a "native" component, the component loader looks for an exported symbol from the components shared library. "Native" here includes any language that can generate a platform native dynamically loaded library. Scripting languages and other "non-native" languages usually have no way to build native libraries. In order to have "non-native" XPCOM components work, XPCOM must have a special component loader which knows how to deal with these type of components.

- -

XPConnect, for example, provides a component loader that makes the various types, including the interfaces and their parameters, available to JavaScript. Each language supported by XPCOM must have a component loader.

- -

Three parts of a XPCOM Component Library

- -

XPCOM is like an onionor a parfait! Everybody likes parfaits. XPCOM components have at least three layers. From the innermost and moving outward these layers include:

- - - -

The core XPCOM object is the object that will implement the functionality you need. For example, this is the object that may start a network download and implement interfaces that will listen to the progress. Or the object may provide a new content type handler. Whatever it does, this object is at the core of the XPCOM component, and the other layers are supporting it, plugging it into the XPCOM system. A single library may have many of these core objects.

- -

One layer above the core object is the factory code. The factory object provides a basic abstraction of the core XPCOM object. An Overview of XPCOM discussed the factory design pattern that's used in a factory object. At this layer of the XPCOM Component Library, the factory objects are factories for the core XPCOM objects of the layer below.

- -

One more layer outward is the module code. The module interface provides yet another abstraction - this time of the factories - and allows for multiple factory objects. From the outside of the component library, there is only the single entry point, NSGetModule(). This point of entry may fan out to any number of factories, and from there, to any number of XPCOM objects.

- -

The factory design pattern in XPCOM is represented by the nsIFactory interface. The module layer is represented by the nsIModule interface. Most component libraries only need these two interfaces, along with the nsISupports interface, to have XPCOM load, recognize, and use their core object code.

- -

In the next section, we'll be writing the code that actually compiles into a component library, and you will see how each layer is implemented and how each interface is used. Following this initial, verbose demonstration of the APIs, we will introduce a faster more generic way of implementing the module and factory code using macros, which can make components much easier to create.

- -

XPCOM Glue

- -

XPCOM contains a lot of stuff. Most XPCOM interfaces are not frozen and are only meant to be used by the Gecko internals and not by clients. XPCOM provides many data structures from linked lists to AVL trees. It's tempting to reuse nsVoidArray or another publicly available class instead of writing your own linked list, but this may prove to be a fatal mistake. The class can change at any time and give you unexpected behavior.

- -

XPCOM makes for a very open environment. At runtime you can acquire any service or component by merely knowing a CID or Contract ID along with an IID. At last count there were over 1300 interfaces defined in XPIDL. Of those 1300 interfaces, less than 100 were frozen, which means that a developer is likely to stumble upon useful interfaces that aren't frozen. Unless an interface is explicitly marked "FROZEN" in the IDL comments, your component may possibly break or crash along with a version change.

- -

The Glue Library

- -

In general, you should avoid any interfaces, symbols in XPCOM, or other part of Gecko libraries that aren't frozen. However, there are some unfrozen tools in XPCOM that are used so often they are practically required parts of component programming.

- -

The smart pointer class, nsCOMPtr, for example, which makes reference counting less tedious and error-prone, is not actually frozen, and neither is nsDebug, a class for aiding in tracking down bugs, nor is nsMemory, a class to ensure that everyone uses the same heap, generic factory, and module. Instead of asking every developer to find and copy these various files into their own application, XPCOM provides a single library of "not-ready-to-freeze-but-really-helpful" classes that you can link into your application, as the following figure demonstrates.

- -

XPCOM Glue and Tools

- -

Image:xpcom-glue-tools.png

- -

This is the glue library. It provides a bridge, or "glue" layer, between your component and XPCOM.

- -

A version of the glue library is built into XPCOM, and when your component uses it, it links a snapshot of this library: it includes a copy of these unfrozen classes directly, which allows the XPCOM library version to change without affecting the software. There is a slight footprint penalty to linking directly, but this gives your component freedom to work in any recent environment. If footprint is a big issue in your component or application, you can trim out the pieces you don't need.

- -

XPCOM String Classes

- -

The base string types that XPCOM uses are nsAString and nsACString. These classes are described in the Mozilla String Guide (see Gecko Resources).

- -

The string classes that implement these abstract classes are another set of helpful, unfrozen classes in XPCOM. Most components and embedding applications need to link to some string class or other in order to utilize certain Gecko APIs, but the string code that Mozilla uses is highly complex and even more expensive than the glue code in terms of footprint (~100k). nsEmbedString and nsEmbedCString are available as very lightweight string implementations for component development, especially in small embedded applications. This string implementation does the bare minimum to support the nsAString/nsACString functionality.

- -

In your own component, you can go "slim" and restrict yourself to the nsEmbedString or go "hog wild" and use any of the the other strings. WebLock restricts itself to using the simple nsEmbedString family of classes.

- -

String Classes and XPCOM

- -

Image:strings-in-xpcom.png

- -

The glue library provides stub functions for the public functions that XPCOM provides (see xpcom/build/nsXPCOM.h). When the glue library is initialized, it dynamically loads these symbols from the XPCOM library, which allows the component to avoid linking directly with the XPCOM library. You shouldn't have to link to the XPCOM library to create a XPCOM component - in fact, if your component has to, then something is wrong.

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/creating_the_component_code/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/creating_the_component_code/index.html deleted file mode 100644 index a4aa535eca..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/creating_the_component_code/index.html +++ /dev/null @@ -1,727 +0,0 @@ ---- -title: Creating the Component Code -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Creating_the_Component_Code -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Creating_the_Component_Code ---- -

 

- -

-

« 上一页下一页 »

-

- -

这一章叙述处理你的组件和XPCOM之间关联的基本代码。让组件被找到和注册是这个章节的目的。在后续章节中,我们开始建立WebLock组件本身的功能。

- -

注:有些部分采用英汉对照的方式。避免翻译的不准确!

- -
-

Use the Calculator (After Learning Long Division)

- -

You have to write a fair amount of code to create a component library that gets loaded into XPCOM. 一个XPCOM组件起码要实现三个XPCOM要求的接口, 通常还有其他一些. 这一章包含了可能你不会需要的更多代码,不过Using XPCOM Utilities to Make Things Easier会教你一些更简单和优雅的使用通用宏建立XPCOM组件的方式, 本章主要讲述基本的内容。 As in grade school when you learned long division, better tools like calculators come after you figure out what's actually happening. In this case, the long-hand implementation gives us an opportunity to talk about various features of XPCOM.

-
- -

What We'll Be Working On

- -

The component we'll be working on in this book controls a special mode in your browser that prevents users from leaving the current domain or a set of safe domains. Once enabled, this weblock mode is password protected and persists until it is turned off by the password holder. It can be used to make the browser into a safe viewer for children, or for targeted "kiosk browsing," where the content is restricted to a particular server. Web Lock User Interface shows the icon that is used to activate the web lock mode (leftmost in the status bar) once you have installed the WebLock component and the extra user interface.

- -

 接下来的内容

- -

文章后续的内容,将向读者描述一个使浏览器处在受控模式(web lock mode)的组件,该组件采用密码保护的方式防止用户从当前域或者一组安全的域中离开。这个组件可以使用在为未成年人提供受限内容或者是在一些小型电子浏览器中防止页面跳出特定服务内容。在用户安装了WebLock组件和额外的用户接口后,在状态栏的最左边,如图Web Lock User Interface,可以用图标来激活受控模式(web lock mode)

- -

Web Lock User Interface

- -

Image:web-lock-ui.png

- -

实际上组件WebLock做的大多数事情是准备组件本身,找到需要的XPCOM接口, 并且挂接到现有的Gecko Browser功能.

- -

Component Registration 组件注册

- -

All XPCOM components - whether they're stored in shared libraries (DLLs, DSOs or dylibs), JavaScript files, or some other file - need to be registered before they can be used. Registration is a process that happens in all XPCOM applications, whether they're embedded Gecko clients, Mozilla, Netscape 7, Compuserve, or any other software that uses XPCOM. Registration provides the information that applications need in order to use components properly.

- -

所有的XPCOM 组件- 无论是存储在shared libraries (DLLs, DSOs 还是 dylibs), JavaScript文件,或者其他文件 - 使用前需要被注册. 使用XPCOM的Gecko clients, Mozilla, Netscape 7, Compuserve, 或者其他程序,都需要注册,才能获得合适的组件信息。

- -

The WebLock component must do a number of things to register itself. Specifically, the component library has to contain implementations for the component-related interfaces described in this chapter: nsIModule and nsIFactory, which are entry points for your implementation code.

- -

想要注册 WebLock 组件必须做许多事情. 特别是, 组件库需要包含本章介绍的组件定义的接口: nsIModule and nsIFactory, 这是你的代码入口.

- -

Once your component implements these interfaces, the rest of the registration process itself is simple. Applications typically use regxpcom, described in the next section.

- -

如果你的组件实现了这些接口,注册将变的很容易. 应用中通常使用regxpcom注册, 在下一节描述.

- -

regxpcom 程序

- -

一个明确的注册组件方法是运行regxpcom. 不带任何参数启动regxpcom时, 程序把组件注册在缺省的组件注册表. 我们建议你如果是运行应用, 你可以拷贝你的组件到对应程序安装目录下的components目录. 拷贝好以后,运行regxpcom将注册包含你的组件在内的所有那个目录中的组件.

- -

regxpcom在1.4 或更高版本有一些新的参数. 参看 regxpcom 加<code>-h 选项。

- -

另外的注册方法

- -

Gecko embedding 应用可能提供其他注册组件的方法. XPInstall, 是一个跨平台的安装技术,Mozilla用来安装浏览器和其他组件,这是一个选择。参看Packaging WebLock. 你可以询问你想要扩展的应用的作者看是否有其他扩展方法.

- -

WebLock Module 源代码概览

- -

As we mentioned in the previous section, components have layers. There are three main parts to every XPCOM component. From the innermost and moving outward, the first object is the XPCOM object. This is the object that contains the business logic, that implements functionality such as starting a network download, implementing interfaces that listen to the download progress, or providing a new content type handler. In Weblock, this is the part that brings together various Gecko services and prevents users from leaving the list of acceptable domains. In a way, the factory and module layers are glue to plug the XPCOM object into the larger XPCOM system.

- -

在前面的章节我们提到,组件是分层的.每一个XPCOM组件都有三部分.从内到外, 第一个对象是XPCOM对象. 这个对象包含了交互逻辑, 负责载入network, 执行一个监听载入过程或新content type的接口。. 在Weblock中, 这部分综合了各种Gecko服务并且防止用户离开允许的一些domain. In a way, the factory and module layers are glue to plug the XPCOM object into the larger XPCOM system.

- -

One layer above the object itself is the nsIFactory object. This object provides basic abstraction of the XPCOM object itself. As you can see in Onion Peel View of XPCOM Component Creation , the main accessor for the XPCOM object is CreateInstance, which is expected to return the object that matches a given CID and IID pair.

- -

XPCOM的上层是 nsIFactory 对象. nsIFactory是对XPCOM的基本抽象. 如同你在 Onion Peel View of XPCOM Component Creation中看到的, 通过CreateInstance与XPCOM对象进行交互, 返回一个匹配给定的CID 和IID 的两个对象.

- -

Moving another layer outward is the nsIModule. This interface provides yet another abstraction of the nsIFactory object, and may allow for multiple nsIFactory objects. The key to this interface is that the return type of getClassObject does not have to be an nsIFactory. Instead, the nsIModule can ask for implementation details about the XPCOM object. This is very useful if the caller is required to know information about the component like its threading module, whether or not it's a singleton, its implementation language, and so forth. The interface used in this case is nsIClassInfo. Starting from the outside in, Onion Peel View of XPCOM Component Creation represents the sequence for constructing an XPCOM object.

- -

最外层是nsIModule对象. 他提供了对nsIFactory 的进一步抽象, 而且可能允许多个nsIFactory对象. 关键点是这个接口的方法getClassObject返回的不一定非要是nsIFactory. nsIModule 也可以用来询问 XPCOM 对象的细节. This is very useful if the caller is required to know information about the component like its threading module, whether or not it's a singleton, its implementation language, and so forth. 这是可以使用接口nsIClassInfo. 从外到内, Onion Peel View of XPCOM Component Creation 表示了建立XPCOM对象的顺序.

- -

Onion Peel View of XPCOM Component Creation

- -

Image:xpcom-is-an-onion.png

- -

Before we begin looking at the various parts of the component and how they'll be implemented in the source, let's look at the module in weblock.cpp as a whole to see where we're going. The source we're referring to is listed in its entirety at the end of this chapter (see webLock1.cpp).

- -

WebLock 组件的源代码包含三个类. 为了让WebLock组件工作在 Mozilla中, 你要为WebLock组件建立一个接口, iWebLock, where the actual work specific to the the web locking features happens. 建立 WebLockModule 实现nsIModule接口, 你也要建立 WebLockFactory实现 nsIFactory来建立一个为你的客户处理组件实例的工厂. These three interface implementations - of the component functionality, of the nsIModule interface, and of the nsIFactory interface that creates and manages instances for clients - are the basic sets of code you need to write to create an XPCOM component.

- -
-

Basic Structure of the WebLock Component Source

- -

The weblock1.cpp source file that defines these classes and the code you need to create a basic component has the following structure:

- -
   * required includes and constants
-   * WebLock: public iWebLock
-   * WebLockFactory: public nsIFactory
-   * WebLockModule: public nsIModule
-
- -

在XPCOM中, 所有这些类要实现 nsISupports.

-
- -

更进一步: 需要的 Includes and Constants

- -

Let's take a look at the first several lines of code in the component and discuss what they mean in XPCOM. The includes and definitions at the top of an XPCOM source file can give you an idea about some of the data types and techniques we'll be discussing more in the upcoming chapters.

- -

介绍一下XPCOM的component代码里面前几行的意思。

- -

例如,MOZILLA_STRICT_API是一个变量,它用来遮蔽某些私有的、非XPCOM的头文件。 For example, MOZILLA_STRICT_API is a variable that shields you from certain private, non-XPCOM headers. For example, including nsIComponentManager.idl without MOZILLA_STRICT_API defined will include the following headers, which are not supported across versions (unfrozen):

- - - -

These variables are picked up by files that do not specify themselves as MOZILLA_STRICT_API.

- -

Includes and Constants in weblock1.cpp

- -
#include <stdio.h>
-
-// may be defined at the project level
-// in the makefile
-#define MOZILLA_STRICT_API
-
-#include "nsIModule.h"
-#include "nsIFactory.h"
-
-#include "nsIComponentManager.h"
-#include "nsIComponentRegistrar.h"
-
-// use classes to handle IIDs
-// classes provide methods for comparison: Equals, etc.
-static const nsIID kIModuleIID   = NS_IMODULE_IID;
-static const nsIID kIFactoryIID   = NS_IFACTORY_IID;
-static const nsIID kISupportsIID = NS_ISUPPORTS_IID;
-static const nsIID kIComponentRegistrarIID = NS_ICOMPONENTREGISTRAR_IID;
-
-
-// generate unique ID here with uuidgen
-#define SAMPLE_CID \
-{ 0x777f7150, 0x4a2b, 0x4301, \
-{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
-
-static const nsCID kSampleCID = SAMPLE_CID;
-
- -

nsIModule.h and nsIFactory.h are required to build your module successfully. They define the module and factory interfaces, and they contain a couple of important macros as well (see the following chapter for information about using these macros). The two other includes, nsIComponentManager.h and nsIComponentRegistrar.h, provide functions such as RegisterFactoryLocation that are required to implement the module and factory classes in your code.

- -

标识符 in XPCOM

- -

一组 nsIID 变量实际上是一些处理XPCOM用来支持客户和组件之间关系的128-bit标识符. The variable kIFactoryIID, for example, provides methods like Equals() that can be used to facilitate comparisons in the code, as in the following example from the Mozilla source:

- -

Using Class Methods to Handle Identifiers

- -
if (aIID.Equals(NS_GET_IID(nsISupports)))
-{
-  *aInstancePtr = (void*)(nsISupports*)this;
-  NS_ADDREF_THIS();
-  return NS_OK;
-}
-
- -

最后, SAMPLE_CID 是一个唯一标示组件的 CID . 所有的XPCOM中使用的128-bit数字 - 类和接口 IDs - 都是 UUIDs的例子, or universal unique identifiers, which were discussed in Object Interface Discovery.

- -
-

Generating CIDs

- -

为组件建立一个CID,你可以使用大多数Unix版本以及Miscrosoft Visual C++都包含的uuidgen 工具. uuidgen is a command-line tool that returns a unique 128-bit number when you call it with no arguments:

- -
$ uuidgen
-ce32e3ff-36f8-425f-94be-d85b26e634ee
-
- -

On Windows, a program called guidgen.exe does the same thing and also provides a graphical user interface if you'd rather point and click. Or you can use one of the special "bots" on IRC in #developers, where you can also get help from human beings.

- -
irc irc.mozilla.org
-/join #developers
-/msg mozbot uuid
-
- -

This command makes the bot generate and return a UUID, which you can then copy into your component source code.

-
- -

Now that we've looked at the preliminaries, it's time to discuss the classes that this module provides and the way that they define the relationships of the component in XPCOM.

- -

Coding for the Registration Process

- -

当 XPCOM 第一次发现你的组件(via XPInstall or regxpcom, both of which are discussed in Component Installation Overview), 第一件事是装载你的库并找到符号NSGetModule. 当这个专用的入口被调用, 它被传送XPCOM's Component Manager和组件存在的共享库位置.

- -

Component Manager是一个是XPCOM实现的用来包含建立对象和提供一些所有组件的综合信息的接口。磁盘的位置是通过另外一个接口 nsIFile传送的. This interface is XPCOM's abstraction of files and directories. An nsIFile object is usually a file or directory on a local volume, but it may represent something on a network volume as well.

- -
nsresult NSGetModule(nsIComponentManager *servMgr,
-                     nsIFile* location,
-                     nsIModule** result);
-
- -

XPCOM 需要成功调用 NSGetModule并返回接口nsIModule. 当你写一个 XPCOM 组件, 你实现了 nsIModule to do all of the necessary registration, unregistration, and object creation. nsIModule 有4个方法必须实现.nsIModule has four methods that must be implemented.

- -

The Registration Methods

- -

Two closely related registration methods are declared below.

- -
NS_IMETHOD RegisterSelf(nsIComponentManager *aCompMgr,
-                        nsIFile *aLocation,
-                        const char *aLoaderStr,
-                        const char *aType) = 0;
-
-NS_IMETHOD UnregisterSelf(nsIComponentManager *aCompMgr,
-                          nsIFile *aLocation,
-                          const char *aLoaderStr) = 0;
-
- -

RegisterSelf 在组件第一次被XPCOM注册的时候调用. 他只执行一次, which gives you a chance to add any one time setup functionality. The RegisterSelf 允许你的组件告诉XPCOM 你将支持什么功能. 注意所有你在 RegisterSelf 中做的都应该在 UnregisterSelf中撤销.

- -

首先, NSGetModule入口从你的库中被调用, 返回一个指向nsIModule的实现. 然后XPCOM调用RegisterSelf, passing parameters that we'll examine here.

- -
The RegisterSelf Method
- -

The first parameter is the nsIComponentManager, which provides a kind of entry point into managing the registration process. 你可以调用QueryInterface 来查找访问下面所述的其他组件管理接口.

- -
-

The Many Faces of the XPCOM Component Manager

- -

三个主要的组件管理接口, nsIComponentManager, nsIServiceManager, and nsIComponentRegistrar, are described below:

- - -
- -

Your RegisterSelf method may call QueryInterface on the nsIComponentManager interface parameter to obtain the nsIComponentRegistrar or nsIServiceManager. nsIServiceManager can be used to obtain a singleton service, which can be useful if you have to register with a service other than the nsIComponentRegistrar if necessary. For example, you may want to get the service that is responsible for an event you want to be notified about. See Getting Called at Startup for an example of this.

- -

第二个参数RegisterSelf是正在注册组件的位置. This parameter is useful when the component needs to know where it has been installed or registered - as, for example, when other files must be stored or accessed relative to the component. This method is only called once, so you have to persist the location if you are going to use it later.

- -

The next two parameters are usually passed into the nsIComponentRegistrar methods and used by XPCOM to determine how to handle the component's registration. The aLoaderStr parameter, which is opaque and should not be modified, distinguishes components that are loaded from the same location specified by the nsIFile parameter. A single ZIP archive may store several XPCOM components, where every component in the archive has the same nsIFile parameter but the aLoaderStr parameter can be used to refer to the location within the ZIP archive.

- -

The last parameter specifies what kind of loader to use on the component. This is reserved as an optimization, for the most part, but it can be a useful way to extend XPCOM. Since XPCOM already knows internally what kind of file it has just loaded and called RegisterSelf on, passing this value to the registration methods is a shortcut for determining what kind of component is being registered.

- -
nsIComponentRegistrar Methods
- -

为了告诉XPCOM这个组件库实现了什么,调用方法:

- -
NS_IMETHOD RegisterFactoryLocation(const nsCID & aClass,
-                                   const char *aClassName,
-                                   const char *aContractID,
-                                   nsIFile *aFile,
-                                   const char *aLoaderStr,
-                                   const char *aType) = 0;
-
- -

The last three parameters are the same as the three passed into the RegisterSelf method of nsIModule objects. All you have to do is forward these parameters from your RegisterSelf call into this method, leaving just the first three parameters.

- -

For any class that implements an XPCOM interface, the implementation must have a class identifier if it is to be shared with other parts of code via XPCOM. This identifier, called a CID, uniquely specifies the implementation. This CID can be created via the tool uuidgen on most operating systems, as in The Many Faces of the XPCOM Component Manager above. Given a CID and an IID, you can refer to any class in XPCOM. Consider the following:

- -

Referencing Objects by ID

- -

Image:referencing-objects-by-id.png

- -

In this case, you have two implementations of the nsISupports interface. Each implementation has a separate CID. The interface also as an IID which is the same for both implementations. When specifying implementation A, the two required pieces of information are the CID of A and the IID of the interface that A supports. The code to register such an object is simple:

- -
NS_IMETHODIMP
-SampleModule::RegisterSelf(nsIComponentManager *aCompMgr,
-                           nsIFile* aPath,
-                           const char* registryLocation,
-                           const char* componentType)
-{
-    printf("Hello Mozilla Registration!\n\n");
-    nsIComponentRegistrar* compReg = nsnull;
-    nsresult rv =
-      aCompMgr->QueryInterface(kIComponentRegistrarIID,(void**)& compReg);
-    if (NS_FAILED(rv))
-        return rv;
-    rv = compReg->RegisterFactoryLocation(kSampleCID,
-                                          "Sample Class",
-                                          nsnull,
-                                          aPath,
-                                          registryLocation,
-                                          componentType);
-    compReg->Release();
-    return rv;
-}
-
- -

Unregistration follows the same logic. To unregister, all you have to do is pass the CID and the file which is passed into UnregisterSelf.

- -

建立你的组件的一个实例

- -

上面的例子用了 CID, 一旦注册以后,任何使用 XPCOM 的客户都可以访问你的组件,通过contract ID or CID. (Note that RegisterSelf method above does not register a contract ID - it simply passes null. This prevents clients from ever accessing the component with a contract ID.)

- -

为了让其他人访问, 你要公开组件包括它支持的接口的 CID 和/或者 contract ID. 上面的例子中,某人可能通过下面的方法建立一个 Sample对象 :

- -
nsIComponentManager* compManager;  // assume initialized
-
-nsISupports* sample;
-compManager->CreateInstance(kSampleCID,
-                            nsnull,
-                            kISupportsIID,
-                            (void**)&sample);
-
- -

In the above snippet, we assume that the component manager has been initialized. In many cases this value is passed in or easily accessible. 如果还没有建立组件管理者,你总可以调用NS_GetComponentManager()来建立它. XPCOM API Reference中列出了一些全局的XPCOM方法.

- -

The first parameter of the call to CreateInstance specifies the component the client code is looking for, which is the same value passed to RegisterFactoryLocation. The next parameter is for aggregation, which the WebLock component does not support. The third parameter is the interface used to talk to the component. The last parameter is the out variable which will contain a valid object if and only if the method succeeds[non-null-out]. The implementation of CreateInstance will ensure that the result will support the passed IID, kISupportsIID. The type of the variable sample should match the IID passed in as kISupportsIID.

- -

CreateInstance 被调用, XPCOM 查询所有的注册组件来匹配CID. XPCOM然后会装载对应的匹配 CID的组件,如果他还没有被装载的话. XPCOM 然后调用库的 NSGetModule. 最后它调用模块上的 GetClassObject. 这个方法是你来实现的,返回匹配 CID/IID 对的nsIFactory. To prepare your component code, you need to create a factory object for each object that you have registered with XPCOM.

- -

The main function that must be implemented in the nsIFactory interface is CreateInstance. The implementation follows a simple algorithm:

- -
    -
  1. Create the raw object.
  2. -
  3. If that fails, return an out of memory error code.
  4. -
  5. Call QueryInterface on the new object.
  6. -
  7. If that fails, null the out param and free the new object.
  8. -
  9. Return the nsresult value from QueryInterface.
  10. -
- -

Often, you don't have to create the object first because the factory implicitly knows what IIDs are supported. When this is not the case, however, doing it this way further abstracts the factories from their concrete classes. If you have a factory that knows every IID supported by the concrete base class, for example, then when you go to add a new supported interface you add this IID comparison in both the factory and the QueryInterface implementation in the concrete class.

- -
NS_IMETHODIMP
-SampleFactory::CreateInstance(nsISupports *aOuter,
-                              const nsIID & iid,
-                              void * *result)
-{
-  if (!result)
-    return NS_ERROR_INVALID_ARG;
-
-  Sample* sample = new Sample();
-  if (!sample)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  nsresult rv = sample->QueryInterface(iid, result);
-
-  if (NS_FAILED(rv)) {
-    *result = nsnull;
-    delete sample;
-  }
-
-  return rv;
-}
-
- -

webLock1.cpp

- -

Before any of the improvements and XPCOM tools we describe in the following chapter are brought in, the source code for the WebLock component that implements all the necessary interfaces looks like this.

- -
#include <stdio.h>
-
-#define MOZILLA_STRICT_API
-
-#include "nsIModule.h"
-#include "nsIFactory.h"
-
-#include "nsIComponentManager.h"
-#include "nsIComponentRegistrar.h"
-
-static const nsIID kIModuleIID = NS_IMODULE_IID;
-static const nsIID kIFactoryIID = NS_IFACTORY_IID;
-static const nsIID kISupportsIID = NS_ISUPPORTS_IID;
-static const nsIID kIComponentRegistrarIID = NS_ICOMPONENTREGISTRAR_IID;
-
-
-#define SAMPLE_CID \
-{ 0x777f7150, 0x4a2b, 0x4301, \
-{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
-
-static const nsCID kSampleCID = SAMPLE_CID;
-
-class Sample: public nsISupports {
-  private:
-    nsrefcnt mRefCnt;
-  public:
-    Sample();
-    virtual ~Sample();
-
-    NS_IMETHOD QueryInterface(const nsIID &aIID, void **aResult);
-    NS_IMETHOD_(nsrefcnt) AddRef(void);
-    NS_IMETHOD_(nsrefcnt) Release(void);
-
-};
-
-Sample::Sample()
-{
-  mRefCnt = 0;
-}
-
-Sample::~Sample()
-{
-}
-
-NS_IMETHODIMP
-Sample::QueryInterface(const nsIID &aIID,
-                       void **aResult)
-{
-  if (aResult == NULL) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  *aResult = NULL;
-  if (aIID.Equals(kISupportsIID)) {
-    *aResult = (void *) this;
-  }
-  if (*aResult == NULL) {
-    return NS_ERROR_NO_INTERFACE;
-  }
-  AddRef();
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt) Sample::AddRef()
-{
-  return ++mRefCnt;
-}
-
-NS_IMETHODIMP_(nsrefcnt) Sample::Release()
-{
-  if (--mRefCnt == 0) {
-    delete this;
-    return 0;
-  }
-  return mRefCnt;
-}
-
-
-
-// factory implementation class for component
-class SampleFactory: public nsIFactory{
-  private:
-    nsrefcnt mRefCnt;
-  public:
-    SampleFactory();
-    virtual ~SampleFactory();
-
-    NS_IMETHOD QueryInterface(const nsIID &aIID, void **aResult);
-    NS_IMETHOD_(nsrefcnt) AddRef(void);
-    NS_IMETHOD_(nsrefcnt) Release(void);
-
-    NS_IMETHOD CreateInstance(nsISupports *aOuter, const nsIID & iid, void * *result);
-    NS_IMETHOD LockFactory(PRBool lock);
-
-};
-
-SampleFactory::SampleFactory()
-{
-  mRefCnt = 0;
-}
-SampleFactory::~SampleFactory()
-{
-}
-
-NS_IMETHODIMP
-SampleFactory::QueryInterface(const nsIID &aIID,
-                              void **aResult)
-{
-  if (aResult == NULL) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  *aResult = NULL;
-  if (aIID.Equals(kISupportsIID)) {
-    *aResult = (void *) this;
-  }
-  else if (aIID.Equals(kIFactoryIID)) {
-    *aResult = (void *) this;
-  }
-
-  if (*aResult == NULL) {
-    return NS_ERROR_NO_INTERFACE;
-  }
-  AddRef();
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(nsrefcnt) SampleFactory::AddRef()
-{
-  return ++mRefCnt;
-}
-
-NS_IMETHODIMP_(nsrefcnt) SampleFactory::Release()
-{
-  if (--mRefCnt == 0) {
-    delete this;
-    return 0;
-  }
-  return mRefCnt;
-}
-
-
-NS_IMETHODIMP
-SampleFactory::CreateInstance(nsISupports *aOuter,
-                              const nsIID & iid,
-                              void * *result)
-{
-  if (!result)
-    return NS_ERROR_INVALID_ARG;
-
-  Sample* sample = new Sample();
-  if (!sample)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  nsresult rv = sample->QueryInterface(iid, result);
-
-  if (NS_FAILED(rv)) {
-    *result = nsnull;
-    delete sample;
-  }
-
-  return rv;
-}
-
-
-NS_IMETHODIMP
-SampleFactory::LockFactory(PRBool lock)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-
-
-
-
-
-// Module implementation
-class SampleModule : public nsIModule
-{
-  public:
-    SampleModule();
-    virtual ~SampleModule();
-
-  // nsISupports methods:
-  NS_IMETHOD QueryInterface(const nsIID & uuid, void * *result);
-  NS_IMETHOD_(nsrefcnt) AddRef(void);
-  NS_IMETHOD_(nsrefcnt) Release(void);
-
-  // nsIModule methods:
-  NS_IMETHOD GetClassObject(nsIComponentManager *aCompMgr,
-                            const nsCID & aClass,
-                            const nsIID & aIID,
-                            void * *aResult);
-  NS_IMETHOD RegisterSelf(nsIComponentManager *aCompMgr,
-                          nsIFile *aLocation,
-                          const char *aLoaderStr,
-                          const char *aType);
-  NS_IMETHOD UnregisterSelf(nsIComponentManager *aCompMgr,
-                            nsIFile *aLocation,
-                            const char *aLoaderStr);
-  NS_IMETHOD CanUnload(nsIComponentManager *aCompMgr,
-                       PRBool *_retval);
-
-  private:
-    nsrefcnt mRefCnt;
-};
-
-
-//----------------------------------------------------------------------
-
-SampleModule::SampleModule()
-{
-  mRefCnt = 0;
-}
-
-SampleModule::~SampleModule()
-{
-}
-
-
-// nsISupports implemention
-NS_IMETHODIMP_(nsrefcnt)
-SampleModule::AddRef(void)
-{
-  return ++mRefCnt;
-}
-
-
-NS_IMETHODIMP_(nsrefcnt)
-SampleModule::Release(void)
-{
-  if (--mRefCnt == 0) {
-    mRefCnt = 1; /* stabilize */
-    delete this;
-    return 0;
-  }
-  return mRefCnt;
-}
-
-NS_IMETHODIMP
-SampleModule::QueryInterface(REFNSIID aIID,
-                             void** aInstancePtr)
-{
-  if (!aInstancePtr)
-    return NS_ERROR_NULL_POINTER;
-
-  nsISupports* foundInterface;
-
-  if (aIID.Equals(kIModuleIID)) {
-    foundInterface = (nsIModule*) this;
-  }
-  else if ( aIID.Equals(kISupportsIID) ) {
-    foundInterface = (nsISupports*) this;
-  }
-  else {
-    foundInterface = 0;
-  }
-
-  if (foundInterface) {
-    foundInterface->AddRef();
-    *aInstancePtr = foundInterface;
-    return NS_OK;
-  }
-
-  *aInstancePtr = foundInterface;
-  return NS_NOINTERFACE;
-}
-
-
-// Create a factory object for creating instances of aClass.
-NS_IMETHODIMP
-SampleModule::GetClassObject(nsIComponentManager *aCompMgr,
-                             const nsCID& aClass,
-                             const nsIID& aIID,
-                             void** result)
-{
-
-  if (!kSampleCID.Equals(aClass))
-    return NS_ERROR_FACTORY_NOT_REGISTERED;
-
-  if (!result)
-    return NS_ERROR_INVALID_ARG;
-
-  SampleFactory* factory = new SampleFactory();
-  if (!factory)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  nsresult rv = factory->QueryInterface(aIID, result);
-
-  if (NS_FAILED(rv)) {
-    *result = nsnull;
-    delete factory;
-  }
-
-  return rv;
-}
-
-
-//----------------------------------------
-
-
-NS_IMETHODIMP
-SampleModule::RegisterSelf(nsIComponentManager *aCompMgr,
-                           nsIFile* aPath,
-                           const char* registryLocation,
-                           const char* componentType)
-{
-
-  nsIComponentRegistrar* compReg = nsnull;
-
-  nsresult rv =
-    aCompMgr->QueryInterface(kIComponentRegistrarIID, (void**)&compReg);
-  if (NS_FAILED(rv))
-    return rv;
-
-  rv = compReg->RegisterFactoryLocation(kSampleCID,
-                                        "Sample Class",
-                                        nsnull,
-                                        aPath,
-                                        registryLocation,
-                                        componentType);
-
-  compReg->Release();
-
-  return rv;
-}
-
-NS_IMETHODIMP
-SampleModule::UnregisterSelf(nsIComponentManager* aCompMgr,
-                             nsIFile* aPath,
-                             const char* registryLocation)
-{
-
-  nsIComponentRegistrar* compReg = nsnull;
-
-  nsresult rv = aCompMgr->QueryInterface(kIComponentRegistrarIID, (void**)&compReg);
-  if (NS_FAILED(rv))
-    return rv;
-
-  rv = compReg->UnregisterFactoryLocation(kSampleCID, aPath);
-
-  compReg->Release();
-
-  return rv;
-}
-
-NS_IMETHODIMP
-SampleModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
-{
-  *okToUnload = PR_FALSE; // we do not know how to unload.
-  return NS_OK;
-}
-
-//----------------------------------------------------------------------
-
-extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
-                                          nsIFile* location,
-                                          nsIModule** return_cobj)
-{
-  nsresult rv = NS_OK;
-
-  // Create and initialize the module instance
-  SampleModule *m = new SampleModule();
-  if (!m) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  // Increase refcnt and store away nsIModule interface to m in return_cobj
-  rv = m->QueryInterface(kIModuleIID, (void**)return_cobj);
-  if (NS_FAILED(rv)) {
-    delete m;
-  }
-  return rv;
-}
-
- -
    -
  1. Note: non-null-out
    The CreateInstance method guarantees that if the out variable is non-null, it is valid.
  2. -
- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/finishing_the_component/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/finishing_the_component/index.html deleted file mode 100644 index 3be93d89f5..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/finishing_the_component/index.html +++ /dev/null @@ -1,337 +0,0 @@ ---- -title: Finishing the Component -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Finishing_the_Component -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Finishing_the_Component ---- -

-

« 上一页下一页 »

-

- -

At this point you have created most of the infrastructure of the component. The component will be recognized by XPCOM and registered with the Category Manager so that it starts up when XPCOM initializes. When the component starts up, it populates a list of URLs read in from a file stored next to the Gecko binary on the local system.

- -

Using Frozen Interfaces

- -

The core functionality of blocking sites is still missing, however. The interfaces needed to block certain URLs from loading are not frozen, and there is still some debate about how exactly this functionality should be exposed to embedders and component developers, so the APIs are not ready to be published. This puts you in the same situation as many developers using Mozilla - you want to use some specific functionality, but the interfaces seem to change on a daily basis.

- -

All of the Mozilla source code is publicly available, and interfaces can be used easily enough. Grab the right headers, use the Component or Service Manager to access the interface you want, and the XPCOM object(s) that implement that interface will do your bidding. With this huge amount of flexibility, however, you lose compatibility. If you use "stuff" that isn't frozen, that stuff is subject to change in future versions of Gecko.

- -

If you want to be protected against changes in Gecko, you must only use interfaces and APIs that are clearly marked as FROZEN. The marking is made in the comments above the interface declaration. For example, take a look at the nsIServiceManager:

- -
/**
- * The nsIServiceManager manager interface provides a means to obtain
- * global services in an application. The service manager depends
- * on the repository to find and instantiate factories to obtain
- * services.
- *
- * Users of the service manager must first obtain a pointer to the
- * global service manager by calling NS_GetServiceManager. After that,
- * they can request specific services by calling GetService.
- * When they are finished they can NS_RELEASE() the service as usual.
- *
- * A user of a service may keep references to particular services
- * indefinitely and only must call Release when it shuts down.
- *
- * @status FROZEN
- */
-
- -

These frozen interfaces and functions are part of the Gecko SDK. The rule of thumb is that interfaces outside of the SDK are considered "experimental" or unfrozen. See the following sidebar for information about how frozen and unfrozen interfaces can affect your component development, and for technical details about how interface changes beneath your code can cause havoc.

- -
-

The Danger of Using Unfrozen Interfaces

- -

Suppose that you need to use the interface nsIFoo that isn't frozen. You build your component using this interface, and it works great with the version of Gecko that you have tested against. However, some point in the future, the nsIFoo interface requires a major change, and methods are reordered, some are added, others are removed. Moreover, since this interface was never supposed to be used by clients other than Gecko or Mozilla, the maintainers of the interface don't know that it's being used, and don't change the IID of the interface. When your component runs in a version of Gecko in which this interface is updated, your method calls will be routed through a different v-table than the one the component expected, most likely resulting in a crash.

- -

Below, the component is compiled against a version of the nsIFoo interface that has three methods. The component calls the method TestA and passes an integer, 10. This works fine in any Gecko installation where a contract guarantees that the interface that was compiled against has the same signature. However, when this same component is used in a Gecko installation where this interface has changed, the method TestA does not exist in the nsIFoo interface; the first entry in the v-table is in fact IsPrime(). When this method call is made, the code execution treats the IsPrime method as TestA. Needless to say, this is a bad thing. Furthermore, there is no way easy way to realize this error at runtime.

- -

Image:vtable-of-altered-interface.png

- -

Gecko developers could change the interface's IID, and some do. This can prevent many errors like this. But unfrozen interfaces are not supported in any formal way, and relying upon a different IID for any change in the interface is not a good idea either.

- -

When using frozen interfaces, you are guaranteed compatibility with future versions of Gecko. The only trouble occurs when the compiler itself changes its v-table layout, which can happen when the compiler changes its ABI. For example, in 2002 the GNU Compiler Collection (GCC), version 3.2 changed the C++ ABI, and this caused problems between libraries compiled with GCC 3.2 and applications compiled with an earlier version and vice versa. Similar problems occurred with GCC 4.0, which underwent similar ABI changes.

-
- -

Before attempting to use unfrozen interfaces, you should contact the developers who are responsible for the code you're trying to use (i.e.,module owners ) and ask them how best to do what you are trying to do. Be as precise you possibly can. They may be able to suggest a supported alternative, or they may be able to notify you about pending changes.

- -

The interface that we need for this project is something called nsIContentPolicy. At the time this book was written, this interface was under review. An interface reaches this state when a group of module owners and peers are actively engaged in discussion about how best to expose it. Usually there are only minor changes to interfaces marked with such a tag. Even with interfaces marked "under review," however, it's still a good idea to contact the module owners responsible for the interfaces you are interested in using.

- -

Copying Interfaces into Your Build Environment

- -

To get and implement interfaces that are not part of Gecko in your component, simply create a new directory in the Gecko SDK named unfrozen. Copy the headers and IDL files that you need from the content/base/public source directory of the Gecko build into this new directory. (For WebLock, all you need are the headers for nsIContentPolicy and the nsIContentPolicy.idl.) Then, using the same steps you used to create the Weblock.h, create a header from this IDL file using the xpidl compiler. Once you have these interface and header files, you can modify the WebLock class to implement the nsIContentPolicy interface. The Weblock class will then support four interfaces: nsISupports, nsIObserver, nsIContentPolicy, and iWeblock.

- -

Image:weblock-implemented-ifaces.png

- -

WebLock Interfaces

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Interface NameDefined byStatusSummary
nsISupportsXPCOMFrozenProvides interface discovery, and object reference counting
nsIObserverXPCOMFrozenAllows messaging passing between objects
nsIContentPolicyContentNot FrozenInterface for policy control mechanism
iWeblockWeb LockNot FrozenEnables and disables Weblock. Also, provides access to the URL that are whitelisted.
- -

Implementing the nsIContentPolicy Interface

- -

To implement the new interface, you must #include the unfrozen nsIContentPolicy, and you must also make sure the build system can find the file you've brought over. The location of the file and the steps for adding that location to the build system vary depending on how you build this component.

- -

Once you have made sure that your component builds with the new header file, you must derive the Weblock class from the interface nsIContentPolicy, which you can do by simply adding a public declaration when defining the class. At the same time, you can add the macro NS_DECL_NSICONTENTPOLICY to the class declaration that provides all of the methods defined in the interface nsIContentPolicy. The updated WebLock class looks as follows:

- -
class WebLock: public nsIObserver, public iWeblock, public nsIContentPolicy
-{
-  public:
-    WebLock();
-    virtual ~WebLock();
-
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIOBSERVER
-    NS_DECL_IWEBLOCK
-    NS_DECL_NSICONTENTPOLICY
-
-  private:
-    urlNode* mRootURLNode;
-    PRBool   mLocked;
-};
-
- -

Remember to change the nsISupports implementation macro to include nsIContentPolicy so that other parts of Gecko will know WebLock supports the nsIContentPolicy interface without modifying this macro.

- -
NS_IMPL_ISUPPORTS3(WebLock, nsIObserver, iWeblock, nsIContentPolicy);
-
- -

Receiving Notifications

- -

To receive notifications, you must register as a new category. You have already registered as a category to receive startup notification. This time, the category name to use is "content-policy". To add the WebLock component to this category, modify the WebLockRegistration callback function so that it looks like this:

- -
static NS_METHOD WebLockRegistration(nsIComponentManager *aCompMgr,
-                                     nsIFile *aPath,
-                                     const char *registryLocation,
-                                     const char *componentType,
-                                     const nsModuleComponentInfo *info)
-{
-  nsresult rv;
-  nsCOMPtr<nsIServiceManager> servman = do_QueryInterface((nsISupports*)aCompMgr, &rv);
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsCOMPtr<nsICategoryManager> catman;
-  servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
-                                  NS_GET_IID(nsICategoryManager),
-                                  getter_AddRefs(catman));
-  if (NS_FAILED(rv))
-    return rv;
-
-  char* previous = nsnull;
-  rv = catman->AddCategoryEntry("xpcom-startup",
-                                "WebLock",
-                                WebLock_ContractID,
-                                PR_TRUE,
-                                PR_TRUE,
-                                &previous);
-  if (previous)
-    nsMemory::Free(previous);
-
-  rv = catman->AddCategoryEntry("content-policy",
-                                "WebLock",
-                                WebLock_ContractID,
-                                PR_TRUE,
-                                PR_TRUE,
-                                &previous);
-  if (previous)
-    nsMemory::Free(previous);
-  return rv;
-}
-
- -

This code adds a new category entry under the topic "content-policy," and it calls AddCategoryEntry in the same way we did in Registering for Notifications. A similar step is required for unregistration.

- -

Implementing the nsIContentPolicy

- -

At this point, you can take the WebLock component and install it into a Gecko installation. When the component is loaded, Gecko calls the nsIContentPolicy implementation in WebLock on every page load, and this prevents pages from displaying by returning the proper value when the load method is called.

- -

The web locking policy that we are going to put into place is quite simple: for every load request that comes through, we will ensure that the URI is in the list of "good" URLs on the white list.

- -
-

If you care to extend this implementation so that the list of URLs is held remotely on a server somewhere - as might be the case when the WebLock component is used in a corporate intranet, for example - there are Networking APIs in Gecko that will support this. Or you could implement the web lock so that instead of blocking any site, the component would simply log all URLs that are loaded. In any case, the process to make the XPCOM component is the same.

-
- -

The method that handles the check before page loading and the only method we care about in our own implementation of nsIContentPolicy is ShouldLoad(). The other method on the nsIContentPolicy interface is for blocking processing of specific elements in a document, but our policy is more restrictive: if the URL isn't on the white list, the entire page should be blocked. In the WebLock component, the ShouldLoad method looks like this:

- -
NS_IMETHODIMP WebLock::ShouldLoad(PRInt32 contentType,
-                                  nsIURI *contentLocation,
-                                  nsISupports *ctxt,
-                                  nsIDOMWindow *window,
-                                  PRBool *_retval)
-
- -

Uniform Resource Locators

- -

The method passes in an interface pointer of type nsIURI, which is based on the Uniform Resource Identifier, or URI. This type is defined by the World Wide Web Consortium as:

- - - -

In this context, URIs are the strings used refer to places or things on the web. This specific form of URI is called a Uniform Resource Locator, or URL. See the intro to the HTML 4 specification for more information about URIs and URLs.

- -

Gecko encapsulates these identifiers into two interfaces, nsIURI and nsIURL. You can QueryInterface between these two interfaces. The networking library, Necko, deals only with these interfaces when handling requests. When you want to download a file using Necko, for example, all you probably have is a string that represents the URI of the file. When you pass that string to Necko, it creates an object that implements at least the nsIURI interface (and perhaps other interfaces as well).

- -

Currently, the WebLock implementation of the ShouldLoad method compares the in parameter with each string in the white list. But it only should do this comparison for remote URLs, because we don't want to block the application from loading local content that it requires, like files it gets via the resource:// protocol. If URIs of this kind are blocked, then Gecko will not be able to start up, so we'll restrict the content policy to the HTTP and FTP protocols.

- -

Instead of extracting the string spec out of the nsIURI to do a string comparison, which would require you to do the parsing yourself, you can compare the nsIURI objects with each other, as in the following section. This ensures that the URLs are canonical before they are compared.

- -

Checking the White List

- -

The WebLock implementation of the ShouldLoad method starts by extracting the scheme of the incoming nsIURI. If the scheme isn't "http", "https", or "ftp", it immediately returns true, which continues the loading process unblocked.

- -

These three are the only kinds of URI that Weblock will try to block. When it has one, it walks the linked list and creates a new nsIURI object for each string URL in the list. From each object, ShouldLoad() extracts the host and compares it to the URI. If they match, the component allows the load to continue by returning true. If these two strings do not match, then the component returns return false and blocks the load.

- -
-

URI Caching

- -

Caching the URI would make this method implementation much faster by avoiding the need to create and destroy so many objects. This points out an important drawback of XPCOM, which is that you cannot create an object on the stack.

- -

Creating this many objects is OK in a tight loop if the buffer of memory that holds the contents of the URLs is guaranteed to be valid for the lifetime of the object. But regardless of how optimized the implementation is with respect to is memory usage, a heap allocation will be made for every XPCOM object created.

-
- -

The string comparison with the URL type "http", "https", and "ftp" looks like this:

- -
nsEmbedCString scheme;
-contentLocation->GetScheme(scheme);
-
-if (strcmp("http", scheme.get())  != 0 &&
-    strcmp("https", scheme.get()) != 0 &&
-    strcmp("ftp", scheme.get())   != 0)
-{
-  // this isn't a type of URI that we deal with.
-  *_retval = PR_TRUE;
-  return NS_OK;
-}
-
- -

Creating nsIURI Objects

- -

To create an nsIURI, use nsIIOService. nsIIOService is the part of the networking library ("necko") that's responsible for kicking off network requests, managing protocols such as http, ftp, or file, and creating nsIURIs. Necko offers tremendous network functionality, but all the WebLock component needs is to create the nsIURI object that can be compared with the URIs on the white list.

- -

Use the Service Manager to acquire the nsIIOService. Since this object is going to be used for the life of the component, it can also be cached. A good place to get an nsIIOService is in the component's Observe() method, which already has a pointer to the Service Manager. The code for getting the IO service from the Service Manager looks like this:

- -
// Get a pointer to the IOService
-rv = servMan->GetServiceByContractID("@mozilla.org/network/io-service;1",
-                                     NS_GET_IID(nsIIOService),
-                                     getter_AddRefs(mIOService));
-
- -

Once you have this interface pointer, you can easily create nsIURI objects from a string, as in the following snippet:

- -
nsCOMPtr<nsIURI> uri;
-nsEmbedCString urlString(node->urlString);
-mIOService->NewURI(urlString,
-                   nsnull,
-                   nsnull,
-                   getter_AddRefs(uri));
-
- -

This code wraps a C-string with a nsEmbedCString, which you'll recall is a string class that many of the Gecko APIs require. See String Classes in XPCOM for more information about strings.

- -

Once the URL string is wrapped in a nsEmbedCString, it can be passed to the method NewURI. This method expects to parse the incoming string and create an object which implements an nsIURI interface. The two nsnull parameters passed to NewURI are used to specify the charset of the string and any base URI to use, respectively. We are assuming here that the charset of the URL string is UTF-8, and also assuming that every URL string is absolute. See the intro to the HTML 4 specification for more information about relative URLs.

- -

Here is the complete implementation of the ShouldLoad() method:

- -
NS_IMETHODIMP
-WebLock::ShouldLoad(PRInt32 contentType,
-                    nsIURI *contentLocation,
-                    nsISupports *ctxt,
-                    nsIDOMWindow *window,
-                    PRBool *_retval)
-{
-  if (!contentLocation)
-    return NS_ERROR_FAILURE;
-
-
-  nsEmbedCString scheme;
-  contentLocation->GetScheme(scheme);
-
-  if (strcmp("http", scheme.get())  != 0 &&
-      strcmp("https", scheme.get()) != 0 &&
-      strcmp("ftp",  scheme.get())  != 0)
-  {
-    // this isn't a type of URI that we deal with
-    *_retval = PR_TRUE;
-    return NS_OK;
-  }
-
-  nsEmbedCString hostToLoad;
-  contentLocation->GetHost(hostToLoad);
-
-  // Assume failure.  Do not allow this nsIURI to load.
-  *_retval = PR_FALSE;
-
-  nsresult rv;
-
-  urlNode* node = mRootURLNode;
-  PRBool match = PR_FALSE;
-
-  while (node)
-  {
-    nsCOMPtr<nsIURI> uri;
-    nsEmbedCString urlString(node->urlString);
-    rv = mIOService->NewURI(urlString, nsnull,  nsnull, getter_AddRefs(uri));
-
-    // if anything bad happens, just abort
-    if (NS_FAILED(rv))
-      return rv;
-
-    nsEmbedCString host;
-    uri->GetHost(host);
-
-    if (strcmp(hostToLoad.get(), host.get()) == 0)
-    {
-      // match found.  Allow this nsIURI to load
-      *_retval = PR_TRUE;
-      return NS_OK;
-    }
-    node = node->next;
-  }
-  return NS_OK;
-}
-
- -

At this point, all of the backend work is complete. You can of course improve this backend in many ways, but this example presents the basic creation of what is commonly referred to as a "browser helper object" like WebLock. The next chapter looks at how to tie this into the front end - specifically, how to use XPConnect to access and control this component from JavaScript in the user interface.

- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/index.html deleted file mode 100644 index 13fd6aff60..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/index.html +++ /dev/null @@ -1,278 +0,0 @@ ---- -title: 创建_XPCOM_组件 -slug: Mozilla/Tech/XPCOM/Guide/Creating_components -tags: - - XPCOM - - 'XPCOM:索引' - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components ---- -

 

- -

-

下一页 »

-

- -

前言

- -
-
谁该读这本书
-
本教程的组织
-
按照例子来学习
-
本书的体例
-
致谢
-
- -

XPCOM 简介

- -
-
XPCOM 解决方案
-
Gecko
-
组件
-
接口 -
-
接口与封装
-
nsISupports 基接口
-
-
-
XPCOM 的ID -
-
CID
-
契约 ID
-
-
-
类厂 -
-
XPIDL 与类型库
-
-
-
XPCOM 服务
-
XPCOM 类型 -
-
方法类型
-
引用计数
-
状态码
-
变量映射
-
通用 XPCOM 错误码
-
-
-
- -

使用 XPCOM 组件

- -
-
组件的例子 - -
-
Cookie 管理器
-
WebBrowserFind 组件
-
WebLock 组件
-
-
-
Mozilla 中使用的组件 -
-
查找 Mozilla 组件
-
在 Cpp 代码中使用 XPCOM 组件
-
XPConnect: 在脚本中使用 XPCOM 组件
-
-
-
- -

组件内幕

- -
-
用Cpp书写组件
-
XPCOM初始化 -
-
XPCOM注册描述
-
XPCOM注册的方法
-
自动注册
-
The Shutdown Process
-
XPCOM组件库的三个部分
-
-
-
XPCOM Glue -
-
The Glue Library
-
XPCOM String Classes
-
-
-
- -

建立组件代码

- -
-
我们将做什么
-
组件注册 -
-
The regxpcom Program
-
其他的注册途径
-
-
-
概览WebLock Module Source
-
深度挖掘: 需要的Includes和常量 -
-
XPCOM中的标识符
-
注册过程的代码
-
注册用的方法
-
建立你的组件的接口
-
-
-
webLock1.cpp
-
- -

使用XPCOM工具类让事情变得简单

- -
-
XPCOM 宏 - -
-
通用XPCOM模块宏
-
基本实现宏
-
声明宏
-
-
-
webLock2.cpp
-
XPCOM中的字符串类 -
-
使用字符串
-
nsEmbedStringnsEmbedCString
-
-
-
智能指针
-
- -

开始WebLock

- -
-
启动时被调用 - -
-
注册到消息
-
访问Category Manager
-
-
-
提供WebLock访问
-
建立WebLock编程接口
-
在XPIDL中定义WebLock接口 -
-
XPIDL书写格式
-
脚本化接口
-
实现nsISupports
-
Web Locking 接口
-
-
-
实现WebLock -
-
声明宏
-
在XPCOM中表达返回值
-
XPIDL代码生成
-
从客户端获取WebLock Service
-
实现iWebLock接口
-
The Directory Service
-
nsIFile改变路径
-
nsIFile操作文件
-
nsILocalFile读取数据
-
处理White List Data
-
-
-
iWebLock方法列举 -
-
Lock and Unlock
-
AddSite
-
RemoveSite
-
SetSites
-
GetNext
-
GetSites
-
HasMoreElements
-
-
-
- -

Finishing the Component

- -
-
Using Frozen Interfaces - -
-
Copying Interfaces Into Your Build Environment
-
Implementing the nsIContentPolicy Interface
-
Receiving Notifications
-
-
-
Implementing the nsIContentPolicy -
-
Uniform Resource Locators
-
Checking the White List
-
Creating nsIURI Objects
-
-
-
- -

Building the WebLock UI

- -
-
User Interface Package List
-
Client Code Overview
-
XUL -
-
The XUL Document
-
The Locking UI
-
Site Adding UI
-
weblock.xul
-
-
-
Overlaying New User Interface Into Mozilla -
-
webLockOverlay.xul
-
-
-
Other Resources -
-
weblock.css
-
Image Resources
-
-
-
- -

打包 WebLock

- -
-
组件安装预览
-
资源归档
-
WebLock 安装脚本
-
WebLock 跟踪脚本
-
分发你的组件
-
- -

附录 A - 建立 Gecko SDK

- -
-
下载和建立 SDK
-
编译一个 Microsoft Visual Cpp 工程 -
-
创建一个新的工程
-
把 Gecko SDK 添加到工程设置
-
-
-
Unix 下的一个 Makefile
-
- -

附录B - 资源

- -
-
WebLock 资源
-
Gecko 资源
-
XPCOM 资源
-
General Development 资源
-
- -

-

下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

- -

 

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/packaging_weblock/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/packaging_weblock/index.html deleted file mode 100644 index 3a7744ec03..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/packaging_weblock/index.html +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Packaging WebLock -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Packaging_WebLock -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Packaging_WebLock ---- -

-

« 上一页下一页 »

-

- -

这是教程最后一部分, 我们将把所有的web所有的组件成分打包成可安装到其他应用中的形式 - the library itself, the type library, the header file, and the user interface resources. The first section, Component Installation Overview, describes the general installation process in Mozilla. The following sections describe the steps you can take to organize the WebLock component for distribution and installation.

- -
-

请注意: 这个教程主要是关注组件开发本身, 所以这部分描述有关打包和安装到Gecko的过程是很简单的. 如果你希望了解详细的打包和安装组件到基于Gecko应用的信息,应该参考http://www.mozilla.org/projects/xpinstall.

-
- -

Component Installation Overview

- -

XPInstall是一组JavaScript APIs用来建立安装脚本. 使用XPInstall,你可以为装载到Gecko-based应用,Mozilla extensions,或者individual components的组件建立web-based安装脚本. WebLock component安装脚本也可以用来注册组件到browser(see Registration Methods in XPCOM for more information on registration).

- -

下面的例子安装脚本使用了Mozilla XPInstall技术来操作安装并且以高层次Javascript对象的方式来跟Mozilla'schrome registry 交互。

- -
-

What Is the Chrome Registry?

- -

Like the Windows registry, the chrome registry is a database of information about applications, skins, and other extensions that have been installed in a Gecko application. Since Mozilla and other Gecko-based applications are cross-platform, this database is abstracted above the operating system or any particular platform's registry.

- -

The chrome registry lives in a series of RDF/XML files in the application directory of Mozilla and other Gecko-based browsers, where new installs, user configurable data, skins, and other information are related to one another and the application itself.

-
- -

XPInstall中的JavaScript APIs Install 对象下载包含了安装文件的JAR并且调用注册方法来告诉 Mozilla 新的组件和用来调用WebLock组件的UI. WebLock Installation Script 是完整的trigger installation script , 可以从网页触发. 文件被存储在JAR file weblock.jar, 这是一个简单的ZIP文件,以XPI结尾,有时候也可能包含一个内部的安装脚本install.js.

- -

一旦你把组件和Weblock相关资源正确打包(see the following section, Archiving Resources), WebLock安装脚本是一个简单的事情(see The WebLock Installation Script).

- -

Archiving Resources

- -

Once you have compiled all the resources that make up the WebLock component and the files that make up the user interface that will be added to the browser, you can place these within a subdirectory called weblock.

- -

Place the entire subdirectory into a ZIP archive and name the archive weblock.xpi. The archive, its subdirectory structure, and its contents should look like this:

- -

weblock.xpi Archive Viewed in WinZIP

- -

Image:weblock-zipped-package.png

- -

Note that the top level of the archive holds the install.js installation file, an RDF manifest for the package as a whole, and the component files (weblock.xpt and weblock4.dll). The component files are copied to the components directory of the Gecko application, and the weblock subdirectory gets copied over into the chrome subdirectory, where its UI resources can be added dynamically to the XUL-based Gecko application.

- -

The next section shows how this process of downloading, copying and registering the necessary files from the XPI can be achieved with an XPInstall installation script.

- -

The WebLock Installation Script

- -

安装脚本是一个存储在XPI中的JavaScript文件. 他必须在包的根目录 (i.e., weblock.xpi) itself. 一旦触发 (see The WebLock Trigger Script), 安章脚本将:

- - - -

The XPInstall API提供了一些核心方法[essential-methods]例如 initInstall, registerChrome, addFile, and others.

- -

WebLock Installation Script

- -
// initialize the installation
-var err = initInstall("WebLock", "weblock", 1.0);
-
-var componentsDir = getFolder("Components");
-var cf = getFolder("Chrome");
-
-// add the DLL and say where it'll go
-addFile("weblock.dll", 1.0, "weblock.dll", componentsDir, "");
-
-// add the typelib also
-addFile("weblock.xpt", "1.0", "weblock.xpt", componentsDir, "");
-
-// add the weblock subdirectory of the XPI and specify that
-// it be installed in the chrome application directory
-err = addDirectory("weblock", "1.0", "", chromeDir, "");
-
-// ? have to register component here or with regxpcom?
-
-// register the new UI with the mozilla chrome registry
-
-registerChrome(CONTENT, getFolder(cf,"weblock.xpi"),"weblock");
-registerChrome(SKIN, getFolder(cf, "weblock.xpi"),"weblock");
-
-// perform the installation if there are no errors
-if (err==SUCCESS)
-  performInstall();
-else
-  cancelInstall(err);
-
- -

The WebLock Trigger Script

- -

The trigger script is the script placed on a web page that actually initiates an XPInstall installation and calls the installation script that appears in the XPI. The following HTML specifies a complete webpage in which the trigger script is defined as a JavaScript function, installWebLock, that gets called when the user clicks the hyperlink.

- -
<html>
-<title>WebLock Installation</title>
-<script type="text/javascript">
-/*
- * Trigger function that downloads the XPI so the
- * install.js file inside can be read and executed
- */
-function installWebLock()
-{
-  weblock_xpi = {'WebLock Extension': 'weblock.xpi'};
-  InstallTrigger.install(weblock_xpi);
-}
-</script>
-
-<h1>Install WebLock</h1>
-
-<p><a href="#" onclick="installWebLock();">install weblock</a></p>
-
-</html>
-
- -

Distributing Your Component

- -

Once you have the component packaged properly and the necessary installation and trigger scripts, you are ready to distribute your component so others can install it in their Gecko applications.

- -

In Mozilla and Netscape browsers, XPInstall makes this process especially easy by providing the file format (XPI) and the necessary installation scripts for doing a web-based installation. As WebLock Installation Script demonstrates, XPInstall uses special keywords to refer to common installation directories such as components in a generalized, cross-platform way.

- -

If you are installing WebLock in an Gecko-based application for which XPInstall is not available, then you will have to devise a separate installation scheme. We leave this as an exercise for the reader.

- -
    -
  1. Note: install-object-methods
    The methods are available on the main Install object, which is implied in the script below in the same way that the window object is implied in JavaScript manipulation of the DOM of a web page. In other words, the fragment initInstall() from the script is equivalent to Install.initInstall().
  2. -
- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/preface/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/preface/index.html deleted file mode 100644 index 0710f0a701..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/preface/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 前言 -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Preface -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Preface ---- -

 

- -

-

下一页 »

-
这本书是关于 Gecko, 以及如何创建基于 Gecko 的 XPCOM 组件. 尽管本书的重点是放在把你的 C++ 代码制作成一个使用 Gecko 的组件的步骤之上, 我们还希望这个过程能够讨论到所有构建 XPCOM 的相关工具, 技巧和技术. 因此本书的安排上是作为一个参考书, 使读者能够自己创建组件, 学习不同的 XPCOM 内容. 比如说, 导言中包含了什么是组件的讨论; 第一章中你可以编译基本的源码并注册到 Mozilla 中, 由此讨论了组件于模块之间的关系, 以及一般的注册过程.

- -

每章的开始会给出这一章的主要内容. Sidebar sections are included to highlight technical details. 在本书的结尾, 如果能够达到本书的目的的话, 读者应该学会如何创建一个组件, Gecko 中的 XPCOM 组件框架.

- -

谁该读这本书

- -

创建 XPCOM 组件 是为 C++ 开发人员而写. 尽管你可能会使用 JavaScript, C 或其他的语言来创建 XPCOM 组件, 组件管理的实现是采用 C++, 许多关于如何创建 XPCOM 组件的讨论也是从 C++ 语言开始的. 然而并不要求读者是一个 C++ 语言的专家, 你需要了解的是基本的 C++ 继承和封装的思想, 我们在书中将尽可能的解释这些 C++ 语言的特性的使用. 由于 Mozilla 使用 JavaScript 脚本语言来访问 XPCOM 组件, 所以熟悉 JavaScript 会很有帮助.

- -

XPCOM 是 Cross Platform Component Object Model (跨平台组件模型)的缩写. 就象它的名字暗示的, XPCOM 类似于 Microsoft 的 COM. 开发 MS COM 的经验大多都可以被应用到 XPCOM. 然而本书假设读者对 COM 一无所知, 本书将包含关于 COM 基本思想的介绍.

- -

本书将描述一个控制浏览动作的 XPCOM 组件的制作过程. 尽管 XPCOM 的多数应用环境与 web 浏览并没有关系, 但是 XPCOM 现在的主要客户应用是 Gecko, 一个开源的, 遵循标准的嵌入式 web 浏览器, 所以它是最简单的, 而且是最实用的展示 XPCOM 功能的例子. 本教程中关于组件的详细描述在这里 What We'll Be Working On.

- -

本教程的组织

- -

下面的列表给出了编制一个称为 WebLock 的 XPCOM 组件的整体步骤, 这个组件向基于 Gecko 的浏览器提供了阻止网站访问的功能. 每个步骤都有各自的章节, 在各个章节中会讨论相关的内容.

- - - -

按照例子来学习

- -

安装 XPCOM 到本地机器上的方法有很多, 如果你已经编译了 Mozilla 1.2 或更高的版本源码, 你就已经有了 XPCOM 框架. 如果你还没有下载 Mozilla 源码, 更简单的方法是下载 Gecko SDK, 它包含了 XPCOM 组件框架的库和工具.

- -

如果有了上面的工具, 你就可以编译自己的组件, 并把这个组件添加到 Gecko 库中. 我们这里讨论的 WebLock 组件是一个实用的浏览器扩展, 编译它需要 1.2 或更高版本的 Gecko SDK / Mozilla 源码.

- -

本书假设你使用的是 SDK, 下载 SDK, 编译, 和获取可用于编成的 Gecko 组件的方法在本书的附录, 建立 Gecko SDK.

- -

本书的体例

- -

下面列出的是格式化文档的习惯,他们用于本书中特定的信息类型并且让信息检索变得简单。目标是使用尽量少的格式类型,同时能辨别不同的信息类型。

- - - - - - - - - - - - - - - - - - - - - - - - -
FormatDescription
boldcomponent names 显示为粗题文字
monospacecode listings, interface namesmembers of interfaces (e.g., createInstance()) 用monospaced 字体表达. 代码行放在不同的box内. 此外, filenamesdirectories 也用 monospaced 字体.
italicvariables appear in italic. 重要的条目和新的概念第一次在文本中出现的时候也应该是斜体字。这些条目通常会立刻有进一步的解释,或者读者可以在本书的某个地方找到详细的解释。
linkReferences to other sections and to figures and tables are links to those sections.
- -

致谢

- -

Thanks to Peter Lubczynski, John Gaunt, Ellen Evans, and Alec Flett for technical reviews. A special thanks goes to Darin Fisher for his very acute observations, close reading, and attention to detail.

-

下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/resources/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/resources/index.html deleted file mode 100644 index b23e6eb4c2..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/resources/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: 资源 -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Resources -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Resources ---- -

Link title - - Italic text -

-
Insert formula here
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/setting_up_the_gecko_sdk/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/setting_up_the_gecko_sdk/index.html deleted file mode 100644 index 3e8c8516e2..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/setting_up_the_gecko_sdk/index.html +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: 建立 Gecko SDK -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Setting_up_the_Gecko_SDK -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Setting_up_the_Gecko_SDK ---- -

-

« 上一页下一页 »

-

- -

这一章提供建立 Gecko SDK 的基本方法, 下面会告诉开发人员如何下载和组织 Gecko SDK, 如何象 WebLock 一样创建一个新的组件工程.

- -

下载和建立 SDK

- -

Gecko SDK 提供了编译 XPCOM 组件所需要的所有的工具, 头文件和库. SDK 现在有 Windows 和 Linux 两个版本, 其他操作系统上的 SDK 正在开发. SDK 在下面的地址下载:

- - - -

注意版号要大于1.4a. 可以在下面的地址获取更新的 SDK 版本 http://ftp.mozilla.org/pub/mozilla/releases/.

- -

一旦你下载了SDK, 你可以解压缩到任何合适的目录. 在本附录中, 我们建立Windows Gecko SDK 到 c:\gecko-sdk\. 如果你选择其他的位置, 记得调整这里描述的设置指向这个位置(e.g., in the 建立一个Microsoft visual cpp工程 章节) .

- -

当你解压缩SDK,它的目录结构看起来应该是:

- -

Layout of the Extracted SDK

- -

Image:sdk-layout.png

- -

目录分别代表SDK中的不同模块。例如网络通讯的所有头文件放在necko目录中,而所有XPCOM需要的头文件则放在 XPCOM 目录中。 这个目录结构使得编译脚本变得比较复杂(因为会产生很多include路径)但是他帮助把SKD的部分组织得更有条例。

- -

两组顶级头文件是比较特别的。mozilla-config.h列出了SDK中使用的所有define,在你的文件中包含着个头文件会保证你创建的组件和Gecko库使用的相同的define。注意mozilla-config.h可能需要在你的组件代码中第一个被include.

- -

每一个模块的目录都分成三个子目录:

- -

Module Subdirectories

- -

Image:module-directory-subdirs.png

- -

bin目录包含了静态库,动态库, 和一些可能会在开发中使用的tools。idl目录包含了模块所公开的公共的IDL文件。includes目录包含了你的组件使用的C++头文件。

- -

现在我们应该提到XPCOM公开的一组二进制代码文件。下面的列表罗列了可执行的Windows文件名:

- - - - - - - - - - - - - - - - - - - - - - - - -
Application NameDescription of functionality
regxpcom.exeRegisters or Unregisters components with XPCOM
xpidl.exeGenerates typelib and C++ headers from XPIDL
xpt_dump.exePrints out information about a given typelib
xpt_link.exeCombines multiple typelibs into a single typelib
- - - - - - - - - - - - -
Library NameDescription of functionality
xpcomglue.libXPCOM Glue library to be used by xpcom components.
- -

编译一个 Microsoft Visual Cpp 工程

- -

一担你建立了Gecko SDK,你可以创建一个Miscrosoft visual c++项目来处理你基于SDK的组件开发。

- -

创建一个新的工程

- -

启动Visual c++以后,从文件菜单重选择new。然后在新建对话框中选择"Win32 Dynamic-Link Library"。 使用对话框右边的栏目输入你的项目和位置。(这个例子使用了 "SampleGeckoProject"作为问兼并,位置是C:\ ).

- -

New Dialog

- -

Image:new-vcpp-project.png

- -

选择OK. 在出现的Win32 Dynamic-Link Library 对话框里, 你可以选择缺省的 "An Empty DLL Project" 作为DLL的类型.

- -

Image:vcpp-dll-dialog.png

- -

选择Finish. Microsoft Studio 将根据你的设定建立一个新的项目并且展开项目开发视图。

- -

把 Gecko SDK 添加到工程设置

- -

为了build使用Gecko的所有信息,你还需要进一步修改项目使得它知道在哪里取得Gecko SDK。为了编辑项目设置, 从项目菜单种选择Settings (or press Alt-F7).

- -

大部分你在下面步骤中所做的修改方法都适用于所有项目设置的修改(包括Debug和Optimize)。选择从Setting菜单中选择"All Configurations",出现一个下拉菜单:

- -

Image:vcpp-project-settings.png

- -

在C/C++ tab,选择Preprocessor组。在这个窗口里你要添加到Gecko SDK的include路径,以及两个 preprocessor defines:

- - - -

最起码你要加上include nspr, embedstringstring include目录, 和xpcom include 子目录. 如果你的组件适用其他SDK的部分(例如Necko), 你也要添加指向他们的路径.

- -

假定你使用例子项目的路径,这些路径看起来会是:

- - - -

Image:vcpp-project-settings-includes.png

- -

在C++ language组, 禁止异常处理. 正如在 XPCOM中的异常章节所表明的, 异常处理不支持跨越Interface, 所以使用这个功能将可能在开发中引起问题。

- -

WebLock 组件需要引用必要的库文件以使用XPCOM Glue. 为添加这些库文件,选择Link tab, 然后选择Input category. 在这个面板上不要连接到 nsprembedstringxpcom中的子目录include ,而改用bin子目录.

- -

我们也会连接到一些Object/library 模块中的库:

- - - -

这些设定看起来会是:

- -

Image:vcpp-project-settings.png

- -

最后一个你需要让Gecko SDK在你的项目中设定成功的修改是"Use run-time library" 设定为 "Multithreaded DLL." 因为这个设置是根据其他设定而确定的,你必须设定Release configuration run-time library 为 release multithreaded DLL runtime, 并且Debug configuration 设定为 the debug multithreaded dll runtime (这个需要澄清一下):

- -

Image:vcpp-runtime-settings.png

- -

完成所有这些设定后,选择OK. 这就完成了项目设定并且让你的项目能包含和编译XPCOM组件.

- -

Unix 下的一个 Makefile

- -

Linux 下不采用工程而采用 Makefile 来组织代码. Makefile 中放置编译环境中的编译选项, 包括使用 Gecko SDK 编译的路径和配置更新等.

- -

下面是一个使用 SDK 来编译的 Makefile, 这里对 Makefile 的详细用法不做解释. 它与 Visual C++ 的工程(Building a Microsoft Visual Cpp Project)相类似, 关于 Makefile 的命令请参看 Make 手册.

- -

Gecko SDK 下的一个 Makefile 例子

- -
CXX   = c++
-
-CPPFLAGS +=     -fno-rtti              \
-                -fno-exceptions        \
-                -shared
-
-# Change this to point at your Gecko SDK directory.
-GECKO_SDK_PATH = /home/dougt/gecko-sdk
-
-# GCC only define which allows us to not have to #include mozilla-config
-# in every .cpp file.  If your not using GCC remove this line and add
-# #include "mozilla-config.h" to each of your .cpp files.
-GECKO_CONFIG_INCLUDE = -include mozilla-config.h
-
-GECKO_DEFINES  = -DXPCOM_GLUE -DMOZILLA_STRICT_API
-
-GECKO_INCLUDES = -I $(GECKO_SDK_PATH)                    \
-                 -I $(GECKO_SDK_PATH)/xpcom/include      \
-                 -I $(GECKO_SDK_PATH)/nspr/include       \
-                 -I $(GECKO_SDK_PATH)/string/include     \
-                 -I $(GECKO_SDK_PATH)/embedstring/include
-
-GECKO_LDFLAGS =  -L $(GECKO_SDK_PATH)/xpcom/bin -lxpcomglue \
-                 -L $(GECKO_SDK_PATH)/nspr/bin -lnspr4      \
-                 -L $(GECKO_SDK_PATH)/nspr/bin -lplds4      \
-                 -L $(GECKO_SDK_PATH)/embedstring/bin/ -lembedstring
-
-build:
-        $(CXX) -o MozShim.so $(GECKO_CONFIG_INCLUDE) $(GECKO_DEFINES) $(GECKO_INCLUDES) $(GECK\
-O_LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) MozShim.cpp
-        chmod +x MozShim.so
-
-clean:
-        rm MozShim.so
-
- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/starting_weblock/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/starting_weblock/index.html deleted file mode 100644 index 65efd53a72..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/starting_weblock/index.html +++ /dev/null @@ -1,1104 +0,0 @@ ---- -title: 开始WebLock -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Starting_WebLock -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Starting_WebLock ---- -

-

« 上一页下一页 »

-

- -

在本章,我们开始设计和实现网络锁定功能本身。我们已经建立了实现多数通用组件功能的模块(例如注册)。这章将关注实际操作网页锁定的功能。

- -

Getting Called at Startup

- -

没有人是一个孤岛,组件也一样。你所建立的例子组件到目前为止还没有任何功能。当他被注册以后,他没做任何事情。

- -

为了当某些事件发生的时候被启动或者通知到,例子组件需要挂接到Mozilla,或者覆盖一个现存组件,或者注册到一些事件上面。WebLock用后面的方式在Gecko Profile Startup发生的时候被调用。当Gecko应用启动的时候,注册的组件被创建或者通过通用观察者接口被提醒nsIObserver

- -

Observer是一些对象,他们当特定的事件发生的时候被通知。使用这种机制提供了一个相互不必了解而可以在对象之间传送信息的机制。

- -

通常,一个对象会通知一系列观察者。例如一个对象被创建的时候它的observe方法被调用,或者它可以注册当XPCOM关闭的时候被通知。这个接口的核心是observe方法。

- -
void observe(in nsISupports aSubject,
-             in string aTopic,
-             in wstring aData);
-
- -

实际上ovserver方法的参数没有什么限制。这些参数根据事件的类型变化。例如,XPCOM关闭的时候,aSubject和aData被定义,aTopic被定义为“xpcom-shotdown’,如果你的对象希望注册到这些事件上面,他首先要实现nsIObserver接口,一旦你完成这些,实现nsIObserverService的observer服务将会利用接口通知你的对象,如下所示:

- -

The Observer Interfaces

- -

Image:observation-overview.png

- -

上图表现了observer服务管理了所有nsIObserver对象的列表. 当通知产生的时候,nsIObserverService把呼叫者从NotifyObserver()发送出的消息传送给nsIObserverObserve()方法。这是一个让不同的类解藕的办法。nsIObserver是一个通用的接口,用来在两个或多个对象间传递信息,而不必定义一个特定的冻结接口,它也是XPCOM建立扩展的一个方式。

- -

WebLock组件对nsIObserver接口的实现和对nsIFactory接口是类似的。XXX what is Example 2?下面的例子2中,你改变一个类的定义为支持nsIObserver接口并且改变NS_IMPL_ISUPOORTS1,从而QueryInterface实现知道组件也支持nsIObserver。启动的时候被通知的WebLock类定义如下:

- -
class WebLock: public nsIObserver {
-  public:
-    WebLock();
-    virtual ~WebLock();
-
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIOBSERVER
-};
-
-NS_IMPL_ISUPPORTS1(WebLock, nsIObserver);
-
- -

Observe()最简单的实现仅仅是比较字符串aTopic和对象所接受事件所定义的值. 如果相匹配, 你可以按照你的方式处理事件. 如果对象仅仅注册到一个消息上, 那你可以忽略字符串 aTopic 而仅仅处理事件. 换句话说,对于对象所没有注册的事件,Observe 方法不应该被调用。

- -
NS_IMETHODIMP
-WebLock::Observe(nsISupports *aSubject,
-                 const char *aTopic,
-                 const PRUnichar *aData)
-{
-  return NS_OK;
-}
-
- -

从observer service来的消息可能是间接的. 直接获得来自observer service的消息的方法是初始化一个nsIObserver 对象. 大多数情况下这样是可以的,但是要注意当你通过这个消息建立组件的情况. 因为组件还没有被建立,所以不存在初始化的 nsIObserver 对象可以用来传递给 nsIObserverService, 组件代码在他被装载以前不能做什么.

- -

注册到消息

- -

nsIObserverService 接口有处理注册和注销一个nsIObserver对象的方法. 这两个方法用来动态添加或者删除一个notification topic上的observer. 但是 WebLock 要被自动初始化和添加到observer service, 这就意味着需要一些数据持久化。(不管怎么说, 我们需要组件在程序每次启动的时候也启动).

- -

This is where a new service that manages sets of related data comes in handy. This service, the nsICategoryService, is what XPCOM and Gecko embedding applications use to persist lists of nsIObserver components that want to have startup notification.

- -

The nsICategoryService maintains sets of name-value pairs like the one below.

- -

The Category Manager

- -

Image:category-manager-table.png

- -

Every category is identified by a string that represents the name of the category. Each category contains a set of name-value pairs. For example, you might have a category named "Important People" in which the name-value pairs would be names and phone numbers. The format of the name-value pair is left up to you.

- -

This data structure is more than enough to support the persisting of components that what to be started up. The category name also maps nicely onto the notion of a notification "topic." The topic name could be something like "xpcom-startup", for instance, and the name-value pair could contain the contract IDs required to create the components requesting startup. In fact, this is exactly how categories are used to handle registration with XPCOM for startup notification. You will see the code which does this in the next section.

- -

Getting Access to the Category Manager

- -

Two fields in the nsModuleComponentInfo structure introduced in the last section are addresses for registration and unregistration callbacks. The first callback is called when the component's nsIModule::RegisterSelf method is called. This callback allows the component to execute any one-time registration code it may need. The inverse of this function is the unregistration callback, where it's a good idea to undo whatever the registration function did. The two functions look like this:

- -
static NS_METHOD
-WebLockRegistration(nsIComponentManager *aCompMgr,
-                    nsIFile *aPath,
-                    const char *registryLocation,
-                    const char *componentType,
-                    const nsModuleComponentInfo *info);
-
-static NS_METHOD
-WebLockUnregistration(nsIComponentManager *aCompMgr,
-                      nsIFile *aPath,
-                      const char *registryLocation,
-                      const nsModuleComponentInfo *info);
-
- -

The names of the functions can be anything you wish. Both functions are passed the Component Manager and the path to the component, including the opaque registryLocation. These are also parameters in the nsIModule implementation in XXX what is Example 1? link to it hereExample 1. In addition to these parameters, the callback functions are passed the nsModuleComponentInfo struct, which is the same structure initially passed into NS_IMPL_NSGETMODULE.

- -

During registration, the registration callback is where you get the nsICategoryManager. Once you have it, you can add the component to the category of components that get started automatically. As a service, the nsICategoryManager is accessible via the nsIServiceManager. Also note that the nsIComponentManager is passed into the callback. Since the object that implements the nsIComponentManager interface also implements nsIServiceManager, all you have to do is QueryInterface the nsIComponentManager to nsIServiceManager to get the Service Manager. You can then use the Service Manager to add the component to the category:

- -
nsresult rv;
-
-nsCOMPtr<nsIServiceManager> servman =
-     do_QueryInterface((nsISupports*)aCompMgr, &rv);
-
-if (NS_FAILED(rv))
-  return rv;
-
- -
-

do_QueryInterface

- -

The previous code uses the special nsCOMPtr function do_QueryInterface that lets you QueryInterface without having to worry about reference counting, error handling, and other overhead. The do_QueryInterface knows what interface to QI to based on the nsCOMPtr that is being assigned into. We could have just as easily have used the raw QueryInterface() method, but using nsCOMPtr is much more economical (see Smart Pointers).

-
- -

Once you have a nsIServiceManager reference, you can ask it for the service you are interested in. This process is similar to using CreateInstance from the nsIComponentManager, but there is no aggregation parameter since the object has already been constructed.

- -
nsCOMPtr<nsICategoryManager> catman;
-rv = servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
-                                     NS_GET_IID(nsICategoryManager),
-                                     getter_AddRefs(catman));
-if (NS_FAILED(rv))
-  return rv;
-
- -

There are two service getters on the nsIServiceManager interface: one that takes a CID and another interface that takes a Contract ID. Here we'll use the latter. The first parameter to the GetServiceByContractID is of course the contract ID, which is defined in the nsXPCOM.h header file. The next parameter is a nifty macro that returns the IID for the interface name that you pass in. The last parameter assigns an out interface pointer to a nsCOMPtr. Assuming there weren't any unexpected errors, the variable catman holds the nsICategoryManager interface pointer, which you can use to add the component as a startup observer by calling a method on the nsICategoryManager.

- -

The next step is to figure out which parameters to pass to the method. There is a category name and a name-value pair, but since the name-value pair meaning is category-specific, you need to figure out which category to use.

- -

There are two startup notifications, both of which create the observer if it isn't already created. The first is provided by XPCOM. This notification will occur during initialization of XPCOM, where all XPCOM services are guaranteed to be available during the calls. Embedding applications may provide other notifications.

- -

Common XPCOM Notifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CategoryNameValueCreates Component
xpcom-startupAnyContract IDYes
xpcom-shutdownAnyContract IDNo
xpcom-autoregistrationAnyContract IDNo
app-startupAnyservice, Contract ID*
- -

The table above summarizes the popular persistent notifications registered through the category manager. The name of the category itself is a well defined string, but the name-value pairs can be anything.

- -

When naming your component in the category, take care to use something that means something and doesn't muddy up the namespace. In this case, "WebLock" is unique and provides context to anyone looking at the category. The value of the name-value part is expected to be the contract ID of the component.

- -

Since every category can define the name-value pairs, the application "app-startup" category can support not only services but component instances as well. For the app-startup notification, you must explicitly pass the string "service," prior to the component's Contract ID. If you do not, the component will be created and then released after the notification, which may cause the component to be deleted.

- -

In short, to register the WebLock component as an xpcom-startup observer, do the following:

- -
char* previous = nsnull;
-rv = catman->AddCategoryEntry("xpcom-startup",
-                              "WebLock",
-                              WebLock_ContractID,
-                              PR_TRUE,  // persist category
-                              PR_TRUE,  // replace existing
-                              &previous);
-if (previous)
-  nsMemory::Free(previous); // free the memory the replaced value might have used
-
- -

The unregistration, which should occur in the unregistration callback, looks like this:

- -
rv = catman->DeleteCategoryEntry("xpcom-startup",
-                                 "WebLock",
-                                  PR_TRUE);  // persist
-
- -

A complete code listing for registering WebLock as a startup observer follows:

- -
#define MOZILLA_STRICT_API
-
-#include "nsIGenericFactory.h"
-
-#include "nsCOMPtr.h"
-#include "nsXPCOM.h"
-#include "nsIServiceManager.h"
-#include "nsICategoryManager.h"
-
-#include "nsMemory.h"
-
-#include "nsIObserver.h"
-
-#include "nsEmbedString.h"
-
-#define WebLock_CID \
-{ 0x777f7150, 0x4a2b, 0x4301, \
-{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
-
-#define WebLock_ContractID "@dougt/weblock"
-
-class WebLock: public nsIObserver
-{
-  public:
-    WebLock();
-    virtual ~WebLock();
-
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIOBSERVER
-};
-
-WebLock::WebLock()
-{
-  NS_INIT_ISUPPORTS();
-}
-
-WebLock::~WebLock()
-{
-}
-
-NS_IMPL_ISUPPORTS1(WebLock, nsIObserver);
-
-NS_IMETHODIMP
-WebLock::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
-{
-  return NS_OK;
-}
-
-static NS_METHOD WebLockRegistration(nsIComponentManager *aCompMgr,
-                                     nsIFile *aPath,
-                                     const char *registryLocation,
-                                     const char *componentType,
-                                     const nsModuleComponentInfo *info)
-{
-  nsresult rv;
-
-  nsCOMPtr<nsIServiceManager> servman = do_QueryInterface((nsISupports*)aCompMgr, &rv);
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsCOMPtr<nsICategoryManager> catman;
-  rv = servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
-                                       NS_GET_IID(nsICategoryManager),
-                                       getter_AddRefs(catman));
-
-  if (NS_FAILED(rv))
-    return rv;
-
-  char* previous = nsnull;
-  rv = catman->AddCategoryEntry("xpcom-startup",
-                                "WebLock",
-                                WebLock_ContractID,
-                                PR_TRUE,
-                                PR_TRUE,
-                                &previous);
-  if (previous)
-    nsMemory::Free(previous);
-
-  return rv;
-}
-
-static NS_METHOD WebLockUnregistration(nsIComponentManager *aCompMgr,
-                                       nsIFile *aPath,
-                                       const char *registryLocation,
-                                       const nsModuleComponentInfo *info)
-{
-  nsresult rv;
-
-  nsCOMPtr<nsIServiceManager> servman = do_QueryInterface((nsISupports*)aCompMgr, &rv);
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsCOMPtr<nsICategoryManager> catman;
-  rv = servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
-                                       NS_GET_IID(nsICategoryManager),
-                                       getter_AddRefs(catman));
-  if (NS_FAILED(rv))
-    return rv;
-
-  rv = catman->DeleteCategoryEntry("xpcom-startup",
-                                   "WebLock",
-                                   PR_TRUE);
-
-  return rv;
-}
-
-NS_GENERIC_FACTORY_CONSTRUCTOR(WebLock)
-
-static const nsModuleComponentInfo components[] =
-{
-  {
-    "WebLock",
-    WebLock_CID,
-    WebLock_ContractID,
-    WebLockConstructor,
-    WebLockRegistration,
-    WebLockUnregistration
-  }
-};
-
-NS_IMPL_NSGETMODULE(WebLockModule, components)
-
- -

Providing Access to WebLock

- -

At this point, the component will be called when XPCOM starts up. WebLock has already implemented the nsISupports, nsIFactory, nsIModule, and nsIObserver interfaces that handle generic component functionality including being initialized at startup. And it speaks to the Component Manager, Service Manager, Category Manager, and the Component Registrar to register itself properly with XPCOM.

- -

The next step is to expose additional functionality to Gecko applications and other clients to query and control the WebLock component. For example, the user interface needs to be able to enable and disable the web locking functionality, see what sites are in the whitelist, and add or remove sites from that list. WebLock needs to provide an API, and it needs to hook into Gecko in order to implement the actual locking functionality.

- -

译: 下一步是expose另外的功能以使得Gecko应用以及其它clients查询和控制WebLock组件. 例如, user interface(用户接口)要有能力去允许或者禁止web locking(web锁定)功能, 查看哪些站点在白名单列表中, 并向列表中添加或移除站点. WebLock需要提供一个API并挂接到Gecko中进而实现实际的locking功能.

- -
-

The WebLock User Interface

- -

The WebLock component in this tutorial uses XUL to define the additional browser UI in a cross-platform way, and XUL uses JavaScript to access and control XPCOM components, but Gecko's pluggable UI allows any user interface to call into Gecko and the components you create as easily as you can from XUL. See XUL for a discussion of how XUL interacts with JavaScript and XPCOM.

- -

在这个教程中WebLock组件使用XUL来定义跨平台的浏览器UI, XUL使用JavaScript来访问和控制XPCOM组件, 但Gecko的可挂接UI也允许任何user interface调用Gecko和你所创建的组件, 就如同XUL一样容易. XUL讨论了XUL如何与JavaScript和XPCOM交互.

-
- -

Creating the WebLock Programming Interface

- -

Design is one of the hardest parts of any programming problem. The question the interface for the WebLock component must answer is: How should WebLock look to the outside world? What, in other words, is the interaction of clients with the WebLock component? In this section, we enumerate the basic functionality the component should expose and create the single interface that organizes and provides this functionality.

- -

译: 设计是任何编程问题中最困难的部分之一. 问题是WebLock组件必须要回答一些问题: WebLock应该如何look to外面的世界? 换言之, 什么是clients与WebLock的交互? 在这部分列举了组件应该expose的基本功能和create一个组织和提供这些功能的接口.

- -

Instead of starting with the implementation, developers use XPIDL (see XPIDL and Type Libraries for more information about XPIDL) to define the interface to the component: how the functionality should be organized, expressed, and exposed to its clients.

- -

译: 开发人员应该使用XPIDL(see XPIDL and Type Libraries for more information about XPIDL)为组件定义接口(定义功能应该如何被组织, 描述和暴露给它的clients)做为开始, 而不应该从实现开始.

- -

In general, the WebLock service interface needs to include the following functionality:

- -

译: 通常, WebLock服务接口要包括以下功能:

- - - -

        译: Lock - 允许web locking, 这样任何Gecko应用中的浏览器被限定只能访问白名单中的web站点域.

- - - -

        译: Unlock - 禁止web locking. 允许Gecko应该中的浏览器访问任何web站点, 而不去管白名单列表.

- - - -

        译: AddSite - 添加当前URL到白名单列表.

- - - -

        译: RemoveSite - 从白名单列表中移除当前URL.

- - - -

        译: EnumerateSites - 允许列举出所有白名单中的站点. EnumerateSites可能会被user         interface(用户接口/用户界面)所提供的例如显示所有白名单列表的可编辑列表框控件所使用.

- -

Even this simple outline presents some ambiguity, however. It's certainly not enough to spell out the interface for the WebLock component in this way. For example, AddSite is supposed to add the current URL to the white list, but is the URL an input parameter to the method, is it the topmost web page in the Gecko application, or is it something more random-a URL picked from global history or that's been given context in some other way?

- -

As a strongly typed and implementation-agnostic language, XPIDL requires that you be quite specific about the APIs, the list of parameters, their order, and their types. XPIDL requires that you spell it all out, in other words. And it's this formality that makes the interfaces in XPCOM effective contracts between services and clients.

- -

The next section shows the interface of the WebLock component, iWebLock, in XPIDL. Once the interface has been described in the XPIDL language, the interface file can be used to generate the header files needed for the implementation code, the binary type library files that let you use the interface of the WebLock component from JavaScript, and even broken linkjavadoc style HTML documentation.

- -

Defining the Weblock Interface in XPIDL

- -

Most interfaces in the XPCOM world are described in XPIDL. The XPIDL file for the iWebLock interface can be used to generate the C++ header file, which you'll need to implement the interface in the component and also a type library that makes the component accessible from JavaScript or other interpreted languages. In Mozilla, JavaScript is the bridge between components and the XUL-based user interface.

- -

译: 在XPCOM世界里大多数接口都是用XPIDL描述的. iWebLock接口的XPIDL文件可以被用来生成C++ header file(你需要它来在组件中实现接口和用来使组件在JavaScript和其它的解译型语言中可访问的类型库). 在Mozilla中, JavaScript是组件与基于XUL的user interface之间的桥梁.

- -

The XPIDL Syntax (XPIDL语法)

- -

The XPIDL syntax is a mix of C++ and Java, and of course it's very much like the OMG IDL upon which it is closely based. The XPIDL for iWebLock appears below:

- -

iWebLock

- -
#include "nsISupports.idl"
-interface nsISimpleEnumerator;
-[scriptable, uuid(ea54eee4-9548-4b63-b94d-c519ffc91d09)]
-interface iWeblock : nsISupports
-{
-  void lock();
-  void unlock();
-
-  // assume strings are UTF-8
-  void addSite(in string url);
-  void removeSite(in string url);
-  attribute nsISimpleEnumerator sites;
-};
-
- -

The first line includes the file nsISupports.idl, which defines the nsISupports interface from which all XPCOM interfaces must derive, and makes it possible for the iWebLock interface to subclass that base interface.

- -
#include "nsISupports.idl"
-
- -

The next line of the XPIDL is a forward declaration of the interface nsISimpleEnumerator. Again, this is similar to the forward declare in C++ (except that C++ does not have the interface keyword seen here).

- -
interface nsISimpleEnumerator;
-
- -

See the XPCOM resources for more information about the XPIDL syntax.

- -

Scriptable Interfaces

- -

The third line in iWebLock is more complex. The first thing it says is that iWebLock will bescriptable .

- -
[scriptable, uuid(ea54eee4-9548-4b63-b94d-c519ffc91d09)]
-
- -

The rest of the line provides a UUID for this interface. Recall that every interface has a unique number that is assigned to it. In the case of interfaces, the identifier is an IID. In the case of the components, which also require unique identifiers, the identifier is the CID.

- -

Subclassing nsISupports

- -

The next line in iWebLock names the interface and defines its base interface. iWeblock derives from nsISupports. XPIDL has no way to define multiple inheritance - something that all scriptable objects must deal with.

- -
interface iWebLock : nsISupports
-
- -

The Web Locking Interface

- -

The body of the block (the stuff between the curly braces) defines the methods and attributes of our interface. There are basically two functional sets on this interface. The first section of the interface controls whether or not WebLock checks to see if a web page can be loaded. If locked, WebLock will prevent sites not on the white list from loading.

- -
  void lock();
-  void unlock();
-
- -

This interface does not enforce any policy with respect to how the user enables or disables this feature. This allows maximum flexibility in the implementation. Any place in the application can acquire this interface via the Service Manager and call unlock or lock. For example, the user interface may bring up a dialog asking the user for a password before calling unlock. Another area of code, such as a "Profile Manager" that starts up and lets users choose which profile to use, may unconditionally call unlock on such a component when switching a profile.

- -

The next set of functionality manages the white list where acceptable domains are stored:

- -
  void addSite(in string url);
-  void removeSite(in string url);
-  attribute nsISimpleEnumerator sites;
-
- -

Operations in this set - add, remove, and enumerate - will be called from a user interface that manages the white list and adds the current website to the white list. There is no policy applied to what sites get added or removed to this list, or who can remove a site.

- -

The most interesting method definition is the enumerator. First of all, it does not look like a method at all:

- -
attribute nsISimpleEnumerator sites;
-
- -

This line defines an attribute in the interface. In C++, this is considered a public variable and "compiled" into a Get method (e.g., getSites). If an attribute is not marked readonly, then both Get and Set methods are generated.

- -

The getter created by this attribute returns a nsISimpleEnumerator interface pointer. This interface allows you to pass a list of elements between interfaces. It has two methods: hasMoreElements() and getNext().

- -
[scriptable, uuid(D1899240-F9D2-11D2-BDD6-000064657374)]
-interface nsISimpleEnumerator : nsISupports
-{
-  /**
-   * Called to determine whether or not the enumerator has
-   * any elements that can be returned via getNext(). This method
-   * is generally used to determine whether or not to initiate or
-   * continue iteration over the enumerator, though it can be
-   * called without subsequent getNext() calls. Does not affect
-   * internal state of enumerator.
-   *
-   * @see getNext()
-   * @return PR_TRUE if there are remaining elements in the enumerator.
-   *         PR_FALSE if there are no more elements in the enumerator.
-   */
-  boolean hasMoreElements();
-
-  /**
-   * Called to retrieve the next element in the enumerator. The "next"
-   * element is the first element upon the first call. Must be
-   * preceded by a call to hasMoreElements() which returns PR_TRUE.
-   * This method is generally called within a loop to iterate over
-   * the elements in the enumerator.
-   *
-   * @see hasMoreElements()
-   * @return NS_OK if the call succeeded in returning a non-null
-   *               value through the out parameter.
-   *         NS_ERROR_FAILURE if there are no more elements
-   *                          to enumerate.
-   * @return the next element in the enumeration.
-   */
-  nsISupports getNext();
-};
-
- -

Implementing WebLock

- -

Once you have defined the interfaces that the component will implement, you can begin to write the implementation code that will actually carry out the web locking functionality.

- -

The WebLock component implements three interfaces:

- - - -

nsISupports is the base interface that all XPCOM objects must implement. The nsIObserver interface is for listening to various events that Gecko generates. Finally, the iWebLock interface is the interface that actually controls the web locking functionality. The first two have already been implemented as part of the generic module code. Recall from Using XPCOM Utilities to Make Things Easier that implementing these basic interfaces can be easy and straightforward if you use the macros and other utilities that XPCOM provides.

- -

Declaration Macros

- -

The class declaration for the WebLock class that implements these three interfaces is as follows:

- -
class WebLock: public nsIObserver, public iWebLock
-{
-  public:
-    WebLock();
-    virtual ~WebLock();
-
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIOBSERVER
-    NS_DECL_IWEBLOCK
-};
-
- -

Note that we derive from the nsIObserver interface as well as the iWeblock class. We do not need to explicitly derive from nsISupports as both of these two other interfaces are already subclasses of nsISupports:

- -

Interface Hierarchy for WebLock

- -

Image:weblock-interface-hierarchy.png

- -

The body of the class declaration uses declaration macros that are generated from an XPIDL interface file. Every header generated from an XPIDL file has a similar macro that defines all the methods in that interface. This makes changes to the interface when designing a bit simpler, as you do not have to modify any class declarations.

- -

There are times, of course, when you cannot use these macros-as when two interfaces share the same method signatures. In these cases you have to manually declare the methods in your class. But in practice, manually declaring class methods in XPCOM is the exception and not the rule. The NS_DECL_IWEBLOCK declaration macro expands into the following:

- -
  NS_IMETHOD Lock(void);
-  NS_IMETHOD Unlock(void);
-  NS_IMETHOD AddSite(const char *url);
-  NS_IMETHOD RemoveSite(const char *url);
-  NS_IMETHOD GetSites(nsISimpleEnumerator * *aSites);
-  NS_IMETHOD SetSites(nsISimpleEnumerator *aSites);
-
- -

Representing Return Values in XPCOM

- -

The code sample above is the C++ version of the iWebLock interface methods. The return result of XPCOM methods generated from XPIDL is always of the type nsresult, and the small macro used in these expansions, NS_IMETHOD, actually represents that return type. nsresult is returned even when in XPIDL you specify that the method return a void. If you require the return result to be something else, the methods are not truly XPCOM methods. If you really want to change the return result type you can use a special flag in your XPIDL that denotes this (see the XPIDL reference). However, we suggest that you simply add an out parameter to the method.

- -

XPIDL Code Generation

- -

The XPIDL compiler also generates a stub implementation of the interface in a commented section of the generated header file, in which each method returns NS_ERROR_NOT_IMPLEMENTED. If you copy the stub implementation from the header file into the source, then rename the dummy class name ("_MYCLASS_") to the WebLock class name already defined, you should be able to compile the source successfully.

- -

Getting the WebLock Service from a Client

- -

At this point, you can install the XPCOM component and have other systems use it. The component doesn't do anything useful, of course, but you have written enough of the code to have it recognized and accessed as a component in XPCOM. The code snippet below illustrates how to get the WebLock service when the component is present:

- -
nsCOMPtr<nsIServiceManager> servMan;
-nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
-if (NS_FAILED(rv))
-{
-  printf("ERROR: XPCOM error [%x].\n", rv);
-  return -1;
-}
-nsCOMPtr<iWebLock> weblock;
-rv = servMan->GetServiceByContractID("@dougt/weblock",
-                                     NS_GET_IID(iWeblock),
-                                     getter_AddRefs(weblock));
-
-if (NS_FAILED(rv))
-{
-  printf("ERROR: XPCOM obtaining service [%x].\n", rv);
-  return -1;
-}
-
- -

Implementing the iWebLock Interface (实现iWebLock接口)

- -

Once the interface is defined, you can focus on implementing the web lock startup functionality itself. The WebLock component starts automatically when XPCOM is started up because it's been registered as a category in XPCOM. When WebLock is called, one of the first things it wants to do is read in a file that lists the URLs that the browser is allowed to load. This file can exist anywhere on the local system, but we've placed it next to the application to keep things simple. The first step in this implementation phase, then, is to create the functionality that accesses this WebLock white list and uses its data to determine which domains are allowed and which are to be blocked. For this, we need to use the file interfaces available in XPCOM.

- -

一旦接口已被定义, 那你的重点应该放在实现web lock的功能上. 当XPCOM运行后WebLock组件也会被自动运行, 因为它已经被注册成为一个XPCOM中的category. 当WebLock被调用时, 它应该做的第一个事情就是读取一个文件, 这个文件列出了允许被浏览器加载的URLs. 这个文件可以位于本地系统中的任何位置, 但我们需要将其放置在距应用程序不远的地方以便操作起来简单一些. 接下来在实现阶段的第一步是实现两个功能, 一是访问WebLock的白名单, 二是使用这些数据去决定哪些域是被允许, 以及哪些是应该被拦截的. 为此, 我们需要使用XPCOM中的文件接口.

- -
File Interfaces
- -

Files and directories are abstracted and encapsulated by interfaces. There are a few reasons for not using strings to represent file locations, but the most important one is that not all file systems can be represented by a series of characters separated by a slash. On the Macintosh platform, for example, files are represented as a triplet - two numbers and one string - so using a string on the Macintosh does not adequately identify files on that operating system.

- -

文件和目录是通过接口来抽象和封装的. 这里有几个原因说明为什么不使用字符串来表示文件位置, 但更重要的一点是并不是所有的文件系统都能够表示成斜线所分割的字符序列. 例如, 在Macintosh(Apple的系统)平台上, 文件被表示成一个triplet(意思是由三个部分组成), 两个数字一个字符串, 因此在Macintosh系统上使用字符串并不能充分在标识文件.

- -

nsIFile, the file interface in XPCOM, provides most of the functionally that file handling requires. That interface includes members representing the file name, file attributes, permissions, existence, and others. A related interface called nsILocalFile provides access to operations specific to local files, but the nsIFile functionality is adequate for the WebLock component.

- -

nsIFile, XPCOM中的文件接口, 提供了大多数操作文件所必须的功能. 这个接口中所包含的成员描述了文件的名字, 属性, 权限, 是否存在等等. 与之相关的接口nsILocalFile提供 操作特定的本地文件, 不过nsIFile的功能对于WebLock组件来说已经足够了.

- -

File Interface Hierarchy

- -

Image:file-iface-hierarchy.png

- -
-

Remote Files and nsIFile

- -

It is not inconceivable for remote files to be represented by the nsIFile interface. Someone could write an nsIFile implementation that represented FTP files on some server. The existing code would need to change very little for a WebLock implementation to take advantage of files that do not actually exist on disk. This kind of implementation does not exist, but this expandability shows some of the flexibility that interface-based programming can provide.

- -

并不难想象, 为远程文件使用nsIFile接口来表示它. 某人可以写一个nsIFile的实现用以表示一些服务器上的FTP文件. 已经存在的代码必须要做一些效小的修改以使WebLock的实现可以接受实际上并不是存在于磁盘上的文件. 这种类型的实现虽然还并不存在, 但至少这种扩展性可以显现出一些基于接口的编程带来的灵活性.

- -

The XPCOM API Reference contains detailed information on nsIFile and other XPCOM interfaces.

-
- -

The Directory Service (目录服务)

- -

The file interfaces are most useful when you can use them to find and manipulate files that are relative to the application. The Directory Service provides directory and file locations in a cross platform uniform way to make this easier. This service, available as nsIDirectoryService, stores the location of various common system locations, such as the the directory containing the running process, the user's HOME directory, and others. It can be expanded so that applications and components can define and store their own special locations - an application plugin directory, for example, preference files and/or directories, or other application specific paths. For example, to expose the location of the "white list" file containing all of the URLs that are safe for WebLock, you can add its location to the nsDirectoryService, which clients can then query for this infomation.

- -

文件接口较有助于当你使用它们去查找和操作与应用相关的文件. 目录服务提供了跨平台的目录与文件定位的统一方法, 这使得进行这种操作变得容易. 这个服务(利用nsIDirectoryService)存储了各种各样通用系统区域的位置, 例如像是包括了正在运行的程序的目录, 用户的HOME目录等等. 因此它可以被扩展为应用程序和组件能够定义并且存储它们自己的特定位置(应用程序插件目录), 例如, 用户自定义的文件和目录, 或者其它的应用程序的特定路径. 比如指定一个"white list"所在的位置, 它包括了所有对于WebLock来讲是安全的URLs, 你可以将这个位置添加到nsDirectoryService中, 使客户端接下来可以查询到这个信息.

- -

The Directory Service implements the nsIProperties interface, which allows you to Get(), Set(), and Undefine() interface pointers. In the case of WebLock, these interface pointers will be nsIFile objects.

- -

目录服务实现了nsIProperties接口, 它允许你Get(), Set()以及Undefine()接口指针. 在WebLock中这些接口指针是nsIFile对象.

- -
[scriptable, uuid(78650582-4e93-4b60-8e85-26ebd3eb14ca)]
-interface nsIProperties : nsISupports
-{
-    /**
-     * Gets a property with a given name.
-     * 用给定的名字(name)取得一个属性(property)
-     *
-     * @return NS_ERROR_FAILURE if a property with that
-     * name doesn't exist.
-     * 如果给定名字的属性不存在, 函数返回NS_ERROR_FAILURE
-     * @return NS_ERROR_NO_INTERFACE if the
-     * found property fails to QI to the
-     * given iid.
-     * 如果取得的属性在以给定的iid于QI方法上调用失败,
-     * 函数返回NS_ERROR_NO_INTERFACE
-     */
-    void get(in string prop,
-             in nsIIDRef iid,
-             [iid_is(iid),retval] out nsQIResult result);
-
-    /**
-     * Sets a property with a given name to a given value.
-     * 用给定的名字和给定的值为设置一个属性
-     */
-    void set(in string prop, in nsISupports value);
-
-    /**
-     * Returns true if the property with the given name exists.
-     * 如果与给定名字的属性存在, 返回true
-     */
-    boolean has(in string prop);
-
-    /**
-     * Undefines a property. 取消一个属性的定义
-     * @return NS_ERROR_FAILURE if a property with that name doesn't
-     * already exist.
-     * 如果给定名字的属性还不存在, 那么函数返回NS_ERROR_FAILURE
-     */
-    void undefine(in string prop);
-
-    /**
-     *  Returns an array of the keys.
-     *  返回一个key的集合
-     */
-    void getKeys(out PRUint32 count,
-                 [array, size_is(count), retval] out string keys);
-};
-
- -

Directory Service Hierarchy

- -

Image:directoryservice-iface-hierarchy.png

- -

There are two steps involved to find directories or files with the Directory Service (nsIDirectoryService). You must know the string key (or property) that refers to the location you are interested in, which is published in the file nsDirectoryServiceDefs.h that comes with the Gecko SDK (for a listing of these locations, see the XPCOM API Reference). The string key for the directory containing the application executable is NS_XPCOM_CURRENT_PROCESS_DIR. Given this key, you can acquire the directory service, call Get(), and pass the key. In the example below, appDir will point to the directory that contains the executable.

- -

这里有两个步骤有关于通过目录服务(nsIDirectoryService)查找目录或文件. 你必须要知道字符串键(或叫属性)用以引用你所想要的位置, 字符串键(或叫属性)被公开于随Gecko SDK一起提供的nsDirectoryServiceDefs.h文件中(可参见XPCOM API Reference以得到这些位置的一个列表). 包含可执行程序的目录的字符串键是NS_XPCOM_CURRENT_PROCESS_DIR. 给定这个键, 你就可以通过调用Get()并将键传递到函数中以获得目录服务. 在下面的实例中, appDir将指向一个包含了可执行程序的目录.

- -
nsCOMPtr<nsIServiceManager> servMan;
-nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
-if (NS_FAILED(rv)) return -1;
-
-nsCOMPtr<nsIProperties> directoryService;
-rv = servMan->GetServiceByContractID(NS_DIRECTORY_SERVICE_CONTRACTID,
-                                     NS_GET_IID(nsIProperties),
-                                     getter_AddRefs(directoryService));
-
-if (NS_FAILED(rv)) return -1;
-
-nsCOMPtr<nsIFile> appDir;
-rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
-                           NS_GET_IID(nsIFile),
-                           getter_AddRefs(appDir));
-
-if (NS_FAILED(rv)) return -1;
-
- -

Most of the useful functionality is exposed by the nsIProperties interface, but the directory service also implements nsIDirectoryService. This interface allows you to extend and override nsIFile objects registered with the directory service. There are currently two ways to add a file location to the directory service: directly and using the delayed method. The direct method is to add a new nsIFile object using the nsIProperties interface, in which case you pass the nsIFile object as an nsISupports to the Set() method of the nsIProperties interface.

- -

大多数有用的功能都是通过nsIProperties接口所提供, 但目录服务还实现了nsIDirectoryService. nsIDirectoryService接口允许利用目录服务你去扩展和重写nsIFile对象的注册. 当前有两种方法添加一个文件位置到目录服务中:立即的与延迟的两种方法. 立即的方法是使用nsIProperties接口添加一个新的nsIFile对象, 在这种情况下你要把nsIFile对象当成一个nsISupports传递给nsIProperties接口的Set()函数.

- -

In the delayed method, you register to be a callback that can provide an nsIFile. To do this, you must get the implementation like we did above. When you have it, QueryInterface for the nsIDirectoryService interface. In this interface, there is a function which allows you to register an nsIDirectoryServiceProvider interface. The interface callback looks like this:

- -
[scriptable, uuid(bbf8cab0-d43a-11d3-8cc2-00609792278c)]
-interface nsIDirectoryServiceProvider: nsISupports
-{
-/**
-* getFile
-*
-* Directory Service calls this when it gets the first request for
-* a prop or on every request if the prop is not persistent.
-*
-* @param prop The symbolic name of the file.
-* @param persistent TRUE - The returned file will be cached by Directory
-* Service. Subsequent requests for this prop will
-* bypass the provider and use the cache.
-* FALSE - The provider will be asked for this prop
-* each time it is requested.
-*
-* @return The file represented by the property.
-*
-*/
-nsIFile getFile(in string prop, out PRBool persistent);
-};
-
- -

Modifying Paths with nsIFile

- -

The directory service returns an nsIFile object, but that object points to the application directory and not the file itself. To modify this nsIFile so that it points to the file, you must call the Append method of the nsIFile. Append adds the input string to the path already specified in the nsIFile. On Unix, for example, calling Append("b") on an nsIFile modifies that nsIFile representing /u/home/dougt/a to point to /u/home/dougt/a/b. The next operation on the nsIFile returns results associated with the "b" path. If "a" wasn't a directory, further operations would fail, even if the initial Append was successful. This is why Append is considered a string operation.

- -

目录服务返回一个nsIFile对象, 但nsIFile对象指向的是应用程序目录而并不是文件. 因此为了修改nsIFile对象以指向文件你必须要调用nsIFile的Append函数. Append函数将字符串输入参数追加到已经被指定到nsIFile的路径里. 例如在Unix里, 在一个nsIFile上调用Append("b")将使nsIFile从指向/u/home/dougt/a修改为指向/u/home/dougt/a/b. 在nsIFile上的后续操作返回的结果将是关于"b"这个路径的. 如果"a"不是一个目录, 那么进一步的操作将会失败, 尽管对于Append函数的调用是成功的. 这就是为什么Append函数被认为是对字符串的操作(不进行目录路径的有效性验证).

- -

The WebLock component manipulates a file named weblock.txt. The following snippet adjusts the theFile object representing that file:

- -

WebLock组件操作名为weblock.txt的文件, 以下程序片段调整了theFile对象以表示那个文件:

- -
nsEmbedCString fileName("weblock.txt");
-appDir->AppendNative(fileName);
-
- -

Manipulating Files with nsIFile

- -

Once you have an nsIFile object pointing to the file that you're interested in, you can open it and read its contents into memory. There are many ways to do this: You can use Standard ANSI File I/O, or NSPR (see The Netscape Portable Runtime Library below for a brief description of NSPR), or you can use the networking APIs that Gecko provides.

- -
-

The Netscape Portable Runtime Library

- -

TheNetscape Portable Runtime Library (NSPR) is a platform-independent library that sits below XPCOM. As a layer of abstraction above the operating system, the NSPR allows Gecko applications to be platform independent by providing the following system-level facilities:

- - - -

The NSPR is included in the Gecko SDK.

-
- -

To keep things as simple as possible, we'll read the file into memory using standard ANSI file I/O, but for examples and information about how to usenecko , the Gecko networking libraries, see http://www.mozilla.org/projects/netlib/.

- -

Using nsILocalFile for Reading Data

- -

An nsIFile object returned from the directory service may also implement the nsILocalFile interface, which has a method that will return a FILE pointer that can be used in fread(). To implement the actual read, you need to allocate a buffer the length of the file, use the nsILocalFile interface pointer to obtain a FILE *, use this result with fread, and close the file pointer.

- -

The following code loads the contents of the file referenced by the nsIFile object theFile into the buffer buf:

- -
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(theFile);
-if (!localFile)
-  return -1;
-
-PRBool exists;
-rv = theFile->Exists(&exists);
-if (NS_FAILED(rv))
-  return -1;
-
-char *buf = NULL;
-
-if (exists)
-{
-  // determine file size:
-  PRUint32 fs, numread;
-  PRInt64 fileSize;
-  rv = theFile->GetFileSize(&fileSize);
-  if (NS_FAILED(rv))
-    return -1;
-
-  // Converting 64 bit value to unsigned int
-  LL_L2UI(fs, fileSize);
-
-  FILE* openFile;
-  rv = localFile->OpenANSIFileDesc("rw", &openFile);
-  if (NS_FAILED(rv))
-    return -1;
-
-  char *buf = (char *)malloc((fs+1) * sizeof(char));
-  if (!buf)
-    return -1;
-
-  numread = fread(buf, sizeof(char), fs, openFile);
-
-  if (numread != fs)
-    // do something useful.
-
-  // ...
-}
-
-if (buf)
-  free(buf);
-
- -

The first line of the code calls QueryInterface on theFile, and if that succeeds assigns the new interface pointer to localFile. If the QueryInterface call fails, localFile will have a value of NULL.

- -
-

Note that the out parameter of the method GetFileSize is a 64-bit integer. The type of this variable is PRInt64, but this type is not represented as a primitive on all platforms. On some platforms, PRInt64 is a struct with two fields - a high and a low 32-bit integer. So operations on this type must use special macros that do the right thing on each platform. On Windows or Linux, for example, it is possible to multiply a PRInt64 by a long like this:

- -
PRInt64 x = 1, y = 2;
-y = x * 2;
-
- -

However, this same snippet will not compile on a platform like Macintosh OS 9, where you need to use macros to perform the calculation:

- -
PRInt64 x, y, two;
-LL_I2L(x, 1);
-LL_I2L(y, 2);
-LL_I2L(two, 2);
-LL_MUL(y, x, two);
-
- -

A full listing of NSPR's long long support can be found at http://www.mozilla.org/projects/nspr/.

- -

The WebLock component doesn't have to deal with files that are longer than 232 bytes. Truncating this value to whatever can fit into a 32-bit unsigned integer may not work for every application, but in this case it doesn't really matter.

-
- -

Processing the White List Data

- -

There are various ways to process the file data itself. The file weblock.txt consists of URL tokens separated by return characters, which makes them easy to read into a data structure.

- -

The white list file can be read in as soon as the component starts up (i.e., as WebLock intercepts the startup notification in the Observe method of the nsIObserver interface that we implement). Since we have only registered to receive a notification when XPCOM starts up, it's a safe assumption that Observe will only be called during the startup event, so we can read the file data in the callback.

- -

After you've read the data into memory, you need to store it in some way to make data access quick and efficient.

- -
-

URL Checking

- -

The way in which URL checking is implemented in the WebLock component is not at all optimal. The WebLock component manages a simple linked list of URL strings. A linear search through the data in the white list may not be terribly bad if the number of URLs is under a couple of dozen, but it decays as the list grows. There's also a large bottleneck in the network request. URL data is accessed as in the diagram below:

- -

Image:urldata-access-in-weblock.png

- -

You might construct hash values for each of the URL strings instead, or add them to some kind of database. But we leave optimizations and real-world performance for web locking to the reader.

-
- -

iWebLock Method by Method

- -

The implementation of the iWeblock interface is straightforward. WebLock is designed so that the user interface notifies this service when we should go into lock mode. During this time, any new URL request that is not in our list of "good" URLs will be denied. Through scriptable access to the iWebLock interface, the user interface can also add, remove, and enumerate the list of URLs that it knows about.

- -

Lock and Unlock

- -

The lock and unlock methods simply set a Boolean representing state in the object. This Boolean value will be used later to determine if we should be denying URL requests:

- -
/* void lock (); */
-NS_IMETHODIMP
-WebLock::Lock()
-{
-  mLocked = PR_TRUE;
-  return NS_OK;
-}
-
-/* void unlock (); */
-NS_IMETHODIMP WebLock::Unlock()
-{
-  mLocked = PR_FALSE;
-  return NS_OK;
-}
-
- -

AddSite

- -

For AddSite, we add a new node to our linked list. The link list nodes contain a char* which points to the string URL that we care about and, of course, a pointer to the next element in the list.

- -
-

nsMemory for Cross-component Boundaries

- -

WebLock maintains ownership of all the memory it allocates, so you can use just about any allocator that you want for WebLock, but this is not always the case. In other places, where allocated buffers cross interface boundaries, you must ensure that the correct allocator is used - namely nsMemory - so that the allocators can match the allocation with the deallocation.

- -

Suppose you call malloc from object A and pass this buffer to another object B, for example. But if object B is using a special allocator that does garbage collection, then when object B deletes a buffer allocated by object A's allocator, the results are unpredictable: probably an assertion will be raised, possibly a memory leak, or a crash. The nsMemory class is a wrapper around the nsIMemory interface, whose only implementation is part of XPCOM. When you use nsMemory, you are guaranteed to be using this same memory allocator in all cases, and this avoids the problem described here.

-
- -

RemoveSite

- -

RemoveSite deletes a node from the linked list:

- -
// a simple link list.
-struct urlNode
-{
-  char* urlString;
-  struct urlNode* next;
-};
-
-/* void addSite (in string url); */
-NS_IMETHODIMP
-WebLock::AddSite(const char *url)
-{
-  // we don't special-case duplicates here
-  urlNode* node = (urlNode*) malloc(sizeof(urlNode));
-  node->urlString = strdup(url);
-  node->next = mRootURLNode;
-  mRootURLNode = node;
-
-  return NS_OK;
-}
-
-/* void removeSite (in string url); */
-NS_IMETHODIMP
-WebLock::RemoveSite(const char *url)
-{
-  // find our entry.
-  urlNode* node = mRootURLNode;
-  urlNode* prev = nsnull;
-
-  while (node)  // test this!
-  {
-    if (strcmp(node->urlString, url) == 0)
-    {
-      free(node->urlString);
-      if (prev)
-        prev->next = node->next;
-      free(node);
-      return NS_OK;
-    }
-    prev = node;
-    node = node->next;
-  }
-
-  return NS_ERROR_FAILURE;
-}
-
- -

SetSites

- -

The purpose of SetSites is to allow clients to pass an enumeration, or set, of URL strings to add to the white list of URLs. SetSites uses an nsISimpleEnumerator and shows how primitive data can be passed as an nsISupports object. The nsISimpleEnumerator interface is shown in The Web Locking Interface.

- -

The first method returns a Boolean if there are more elements in the set. Internally, the object knows the number of elements it has in its enumeration, and every time a client calls getNext, it decrements a counter - or adjusts a pointer to the next element. When the counter goes to zero or the pointer points to a non-element, hasMoreElements will return false.

- -

There is no way to reset an nsISimpleEnumerator. For example, you can't re-enumerate the set. If you need random access to the elements in a nsISimpleEnumerator, you can read them from the nsISimpleEnumerator, store them in an array, and access them there. The getNext method returns a nsISupports interface pointer.

- -

When you want to pass primitive data types like numbers, strings, characters, void *, and others, the solution is to use one of the nsISupportsPrimitive interfaces. These interfaces wrap primitive data types and derive from nsISupports. This allows types like the strings that represent URLs in the WebLock component to be passed though methods that take an nsISupports interface pointer. This becomes clear when when you see the implementation of SetSites:

- -
NS_IMETHODIMP
-WebLock::SetSites(nsISimpleEnumerator * aSites)
-{
-  PRBool more = PR_TRUE;
-  while (more)
-  {
-    nsCOMPtr<nsISupports> supports;
-    aSites->GetNext(getter_AddRefs(supports));
-
-    nsCOMPtr<nsISupportsCString> supportsString =  do_QueryInterface(supports);
-
-    if (supportsString)
-    {
-      nsEmbedCString url;
-      supportsString->GetData(url);
-      AddSite(url.get());
-    }
-
-        aSites->HasMoreElements(&more);
-  }
-
-  return NS_OK;
-}
-
- -

GetNext

- -

GetNext is called with the nsCOMPtr of an nsISupportsCString. nsCOMPtrs are nice because they do whatever QueryInterface calls are necessary under the hood. For example, we know that the GetNext method takes an nsISupports object, but we may not be sure whether the return result supports the interface we want, nsISupportsCString. But after GetNext returns, the nsCOMPtr code takes the out parameter from GetNext and tries to QueryInterface it to the nsCOMPtr's type. In this case, if the out parameter of GetData does not return something that is QueryInterface-able to an nsISupportsCString, the variable will be set to null. Once you know that you have an nsISupportsCString, you can grab the data from the primitive supports interface.

- -

To get something you can pass into the AddSite method, you need to convert from an nsEmbedCString to a const char*. To do this, you can take advantage of the nsEmbedCString described in String Classes in XPCOM.

- -

GetSites

- -

The implementation of GetSites is more involved. You must construct an implementation of nsISimpleEnumerator and return it when GetSites is called. The class needs to walk the list of urlNode's for every call to GetNext, so it makes sense for the constructor itself to take an urlNode:

- -
class myEnumerator : public nsISimpleEnumerator
-{
-  public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSISIMPLEENUMERATOR
-
-    myEnumerator(urlNode* node) {
-      NS_INIT_ISUPPORTS()
-      mNode = node;
-    }
-    virtual ~myEnumerator(void) {}
-
-  protected:
-    urlNode* mNode;
-    nsCOMPtr<nsIComponentManager> mCompMgr;
-};
-
-NS_IMPL_ISUPPORTS1(myEnumerator, nsISimpleEnumerator);
-
- -

The myEnumerator class is going to implement the nsISupports interface and also nsISimpleEnumerator. The only state that it needs to maintain is the current URL node - the one that will be return on the next call to GetNext. There is also an nsCOMPtr to the nsIComponentManager, which is used in every call to GetNext so that you can create nsISupportsCString objects and cache the interface pointer as an optimization.

- -

HasMoreElements

- -

HasMoreElements is simple. All you need to do is make sure that mNode isn't null:

- -
NS_IMETHODIMP
-myEnumerator::HasMoreElements(PRBool* aResult)
-{
-  if (!aResult)
-    return NS_ERROR_NULL_POINTER;
-
-  if (!mNode) {
-    *aResult = PR_FALSE;
-    return NS_OK;
-  }
-
-  *aResult = PR_TRUE;
-  return NS_OK;
-}
-
- -

GetNext needs to create an nsISupportsCString so that you can pass the URL string out through the nsISupports parameter. You must also move mNode to point to the next urlNode.

- -
static NS_DEFINE_CID(kSupportsCStringCID, NS_SUPPORTS_CSTRING_CID);
-
-NS_IMETHODIMP
-myEnumerator::GetNext(nsISupports** aResult)
-{
-  if (!aResult)
-    return NS_ERROR_NULL_POINTER;
-
-  *aResult = nsnull;
-
-  if (!mNode)
-    return NS_ERROR_FAILURE;
-
-  if (!mCompMgr)
-  {
-    NS_GetComponentManager(getter_AddRefs(mCompMgr));
-    if (!mCompMgr)
-      return NS_ERROR_UNEXPECTED;
-  }
-
-  nsISupportsCString* stringSupports;
-  mCompMgr->CreateInstance(kSupportsCStringCID,
-                           nsnull,
-                           NS_GET_IID(nsISupportsCString),
-                           (void**)&stringSupports);
-  if (!stringSupports)
-    return NS_ERROR_UNEXPECTED;
-
-  nsEmbedCString str(mNode->urlString);
-  stringSupports->SetData(str);
-
-  *aResult = stringSupports; // addref'ed above.
-
-  mNode = mNode->next;
-
-  return NS_OK;
-}
-
- -

在实际的GetSites呼叫中, 你需要做的就是产生一个myEnumerator实例并且返回它.

- -

此前,我们建立了一个类并且把它注册到组件管理器。当一个客户端需要获取某个接口的实现时,实际上的对象建立过程隐藏在XPCOM代码中。 但是其中, 你要初始化你自己的nsISimpleEnumerator实现. 这是一个简单的事情,但是你需要注意NS_ADDREF.

- -
NS_IMETHODIMP
-WebLock::GetSites(nsISimpleEnumerator * *aSites)
-{
-  myEnumerator* enumerator = new myEnumerator(mRootURLNode);
-  if (!enumerator)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*aSites = enumerator);
-  return NS_OK;
-}
-
- -
-

AddRef, Releasing, and Deleting Objects

- -

永远不要忘记调用你通过new建立的XPCOM对象的AddRef方法。所有的代码或者活动组件都应该有一个起码一个引用计数。忘记这点可能引起麻烦。

- -

一个相关的警示试你不要忘记永远不要用delete删除一个XPCOM. 当系统的一部分不是释放而是删除一个XPCOM对象的时候,可能会引起几个小时的资源搜索并且引起崩溃。

-
- -

注意上面的实现中,当其他的线程访问链接表的时候myEnumerator 可能变得非法。枚举仅仅表现了访问URL字符串链接表的一个方法。如果你需要枚举成为URL字符串链表的一个快照,你需要重构这个实现让枚举持有一个链表的copy。

- -

当组件中止的时候,你也需要把链表写到磁盘里并且释放空间。我们把这个作为练习留给读者。

- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_components/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_components/index.html deleted file mode 100644 index a0a5b301ba..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_components/index.html +++ /dev/null @@ -1,311 +0,0 @@ ---- -title: 创建_XPCOM_组件/使用_XPCOM_组件 -slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Components -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Components ---- -

-

« 上一页下一页 »

-

- -

创建一个新的 XPCOM 组件, 特别是在我们设计一个供别人使用的组件接口的时候, 最好方式是参照已有的组件. 我们在编写 Starting WebLock 这个例子的时候, 也是这么做的.

- -

Mozilla 浏览器应用是复杂的, 模块化的 XPCOM 客户程序. 实际上, 基本上所有与浏览器相关的功能都被定义成了组件的形式, 包括网页间的跳转, 窗口管理, cookie 管理, 书签, 安全, 搜索, 润色等等的其他功能, 这些功能都是由组件的接口提供的. Mozilla就是一堆 XPCOM 组件.

- -

本章将讨论 Mozilla 是如何使用象 CookieManager 这样的 XPCOM 对象, 然后根据这些例子我们定义 WebLock 组件的访问接口.

- -

组件的例子

- -

可以在这里 XPCOM API Reference 找到下面要描述的组件. 我们要了解的是象本节中所给出的组件是如何被 Mozilla 浏览器获取和使用的.

- - - -

Cookie 管理是以组件形式向 Mozilla 浏览器提供支持的众多组件之一, 这些组件可以被重用在需要类似功能的应用中. 当用户通过 Cookie 管理器对话框来观察, 组织, 或者删除 cookies 的时候, Cookie 管理器在背后默默的工作. Cookie 管理器对话框负责向用户提供 Cookie 管理器的 UI 界面[cookie-manager-ui].

- -

Cookie 管理器对话框

- -

Image:cookie_mgr_dlog.png

- -

对话框是用 XUL (XML UI 语言) 和 JavaScript 语言编写, 使用称为XPConnect 的组件无缝连接到 Cookie 管理器组件(参看下面的 从接口连接到组件). XUL 只是一种暴露 Cookie 管理器功能的方式, 但是却是 Mozilla 环境下最有用的方式之一.

- -

CookieManager 组件的功能通过 nsICookieManager 接口提供, 接口的方法如下:

- -

nsICookieManager 接口

- - - - - - - - - - - - - - - - -
removeAll删除 cookie 列表中所有的 cookies.
enumerator通过 cookie 列表枚举.
remove从列表中删除某个 cookie .
- -

XPCOM 中所有的接口必须固定, 虽然组件对接口的实现会有所变化. 接口都是public 的, 相对的, 接口实现是 private 的[private-xpcom-interfaces]. 当用户选中 cookie 列表中的一个 cookie, 点击 Remove 按钮, nsICookieManager 接口的 Remove 方法被调用. CookieManager 组件执行该函数, 选中的组件就被删除了.

- -

下面的从 JavaScript 中访问 CookieManager 组件代码, 展示了如何从 JavaScript 中调用 Remove() 方法:

- -

从 JavaScript 中访问 CookieManager 组件

- -
// xpconnect to cookiemanager
-// get the cookie manager component in JavaScript
-var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
-                     .getService();
-cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);
-
-// called as part of a largerDeleteAllCookies() function
-function FinalizeCookieDeletions() {
-  for (var c=0; c<deletedCookies.length; c++) {
-    cmgr.remove(deletedCookies[c].host,
-                deletedCookies[c].name,
-                deletedCookies[c].path);
-  }
-  deletedCookies.length = 0;
-}
-
- -
-

从接口连接到组件

- -

Mozilla 中使用的从 JavaScript 访问 XPCOM 组件的技术称为XPConnect, XPConnect 也是一个组件.

- -

XPConnect 把应用程序代码与 Mozilla 浏览器, 基于 Gecko 的 XUL, 和象 xpcshell 这样的 JavaScript 环境绑定在一起.

- -

xpcshsell 是 Mozilla 内嵌的 XPCOM 工具, 它是 JavaScript 的命令行解释器.

- -

参看 http://www.mozilla.org/scriptable/, 获取更多关于 XPConnect 和 JavaScript 的信息.

-
- -

上面展现的技术当然并不是 XPCOM 的全部, 但是却是一个重要的方面. XPCOM 强加的契约打开了一扇通往二进制互操作技术的大门. - 这是一种能够在运行时刻访问, 使用, 重用 XPCOM 组件的技术, 这种技术能够保证用某种语言编写的组件能够被其他的语言所访问.

- -

在 Mozilla 浏览器中, 组件常常通过接口在 JavaScript 中访问, 搜索 Mozilla 的源代码, 会发现 CookieManager 组件只是在 JavaScript 中被调用. 在本教程中, 我们也使用这种方式来访问它[教程中使用的 coocki 管理器].

- -
-

JavaScript 与 Mozilla

- -

JavaScript 是 Mozilla 浏览器的喉舌, 它把自己与 XPCOM 紧紧地绑定在一起. XPCOM 的这种可扩展能力 - 从 XPConnect 绑定的语言中访问组件的能力, 是 XPCOM 的一个关键属性.

-
- -

WebBrowserFind 组件

- -

组件的应用是广泛的: 在浏览这样的高级应用中, 会有 nsWebBrowserFind 这样的接口, 它提供 find()findNext() 方法用于在网页上查找特定内容. 在一些低级应用中, 会提供数据管理这样的功能. 虽然 Mozilla 并不能将所有的 API 都写成 XPCOM 组件的形式, 但是绝大多数浏览器的典型功能都是用 XPCOM 的组件形式实现的, 因此可以被嵌入和扩展.

- -

除了 CookieManager 组件, 这里还要介绍一个 WebBrowserFind 组件. 它实现的 nsIWebBrowserFind 接口见下表 nsIWebBrowserFind 接口.

- -

nsIWebBrowserFind 接口

- - - - - - - - - - - - - - - - - - - - - - - - -
findNext找到字符串出现的下一个位置.
findBackwards布尔类型属性值, 控制 findNext() 方法向前/向后搜索.
searchFrames布尔类型属性值, 标识是否搜索当前页面的子框(subframes).
matchCase布尔类型属性值, 标识是否按照大小写匹配搜索网页.
entireWord布尔类型属性值, 标识是否匹配整个词.
- -

一旦我们使用接口来获的了某个组件, 我们就可以询问该组件是否支持其他的接口. 这种基本服务由 nsISupports 接口提供, 会由所有的 XPCOM 组件继承; 它允许我们查询组件的接口, 并在接口之间进行切换; 它展现了 XPCOM 的运行时刻确定类型的能力. 它由 QueryInterface 方法实现, 我们将在后面什么是 XPCOM?一章中介绍. XPCOM API Reference 中提供了完整的 XPCOM 组件的索引.

- -

WebLock 组件

- -

现在我们把 WebLock 组件看成另一个 XPCOM 组件的例子. 在面向对象编程中, 通常是先设计接口 - 首先定义要提供的功能, 而不是考虑如何实现这些功能. 因此我们把实现这个组件的细节问题放到下一章, 这一章先考虑从外部如何看待这个组件. - 即定义 WebLock 组件的接口.

- -

IWebLock 接口

- - - - - - - - - - - - - - - - - - - - - - - - -
lock锁定浏览器到当前站点, 或者是磁盘上保存的某个白名单上的站点.
unlock解开浏览器锁定, 开放访问所有站点.
addSite添加一个新的站点到白名单.
removeSite从白名单上删除某个站点.
sites枚举白名单上的站点.
- -

WebLock 组件就是要实现上面接口定义的功能. 它在浏览器启动的时候, 注册自己. 当用户或者管理员点击浏览器上的 weblock 图标时, 类厂会创建对象实例.

- -

Mozilla 中使用的组件

- -

那么我们应该如何获得组件, 然后如何在 Mozilla 中使用它呢? 我们在前面已经看到了一小段 JavaScript 代码, 但是我们并没有解释一般情况下该如何获得 XPCOM 组件.

- -

这一节讨论 Mozilla 中实际使用的组件例子. 本节分成三部分: 一部分是关于该如何在 Mozilla 上找到组件. 其他两个部分是关于该如何访问这些组件.

- -

查找 Mozilla 组件

- -

本书试图向读者提供关于 XPCOM 组件和当前冻结的接口的索引信息. Mozilla 嵌入工程跟踪了当前冻结的接口.

- -

Mozilla 包含了 Gecko 提供的查找和显示组件信息的工具 -XPCOM 组件观察器LXR.

- -

提供 XPCOM 组件信息的主要问题是, Mozilla 接口在不断的发展, 试图选择一个冻结的断面是困难的. 组件观察器的实现并没有考虑组件是否已被冻结, 在 LXR 中我们会发现, 被冻结的接口会在头部标记 @status frozen.

- -
XPCOM 组件观察器
- -

组件观察器 是一个可选安装的浏览器插件.

- -

XPCOM 组件观察器

- -

Image:using-component-viewer.png

- -

在上面的图中, 左列显示的是以gtx 字符串搜索契约 ID 得到的组件子集, 右列是左列选中组件实现的接口.

- -

XPCOM 观察器在获取组件的大致信息的时候非常有用, 但是要知道组件观察器显示的是所有的组件, 有些组件并不稳定, 组件的接口可能会在后续版本中变化, 所以要慎重选取我们自己工程中使用的组件.

- -

XXX mediawiki is t3h suxx0r XXX give me my C++

- -

在 Cpp 代码中使用 XPCOM 组件

- -

XPConnect 把对 XPCOM 组件作为 JavaScript 对象, 使得对 XPCOM 组件的访问变得非常简单, 从 C++ 代码中访问 XPCOM 要复杂一些.

- -

从 Cpp 代码管理 Cookies 以 C++ 代码重新实现了从 JavaScript 中访问 CookieManager 组件的功能.

- -

从 Cpp 代码管理 Cookies

- -
nsCOMPtr<nsIServiceManager> servMan;
-nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
-if (NS_FAILED(rv))
-  return -1;
-
-nsCOMPtr<nsICookieManager> cookieManager;
-rv = servMan->GetServiceByContractID("@mozilla.org/cookiemanager",
-                                     NS_GET_IID(nsICookieManager),
-                                     getter_AddRefs(cookieManager));
-
-if (NS_FAILED(rv))
-  return -1;
-
-PRUint32 len;
-deletedCookies->GetLength(&len);
-
-for (int c=0; c<len; c++)
-    cookieManager->Remove(deletedCookies[c].host,
-                          deletedCookies[c].name,
-                          deletedCookies[c].path,
-                          PR_FALSE);
-
- -

XXX: In the original document, there were only the first three parameters to the |Remove| call. I added |PR_TRUE| as a fourth parameter because the interface seems to require it: http://lxr.mozilla.org/mozilla/sourc...Manager.idl#64 This problem also appears in the JavaScript version below, and I've added |false| as a fourth parameter there as well.

- -

如果我们的应用是用 C++ 编写, 从 Cpp 代码管理 Cookies 这段代码向我们提供了很好的模板.

- -

XPConnect: 在脚本中使用 XPCOM 组件

- -

在本章开始我们讨论了CookieManager组件,他提供了一个很好的例子来说明如何使用javascript访问组件.在下面的代码片断里你可以看到如何通过getService()方法创建一个CookieManager组件对象,并且通过它提供的功能来让我们从用户界面来读取和删除cookies.

- -

Managing Cookies from JavaScript

- -
var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
-                     .getService();
-cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);
-
-function loadCookies() {
-  // load cookies into a table
-  var enumerator = cmgr.enumerator;
-  var count = 0;
-  var showPolicyField = false;
-  while (enumerator.hasMoreElements()) {
-    var nextCookie = enumerator.getNext();
-    nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie);
-    /* .... */
-}
-function FinalizeCookieDeletions() {
-  for (var c=0; c<deletedCookies.length; c++) {
-    cmgr.remove(deletedCookies[c].host,
-                deletedCookies[c].name,
-                deletedCookies[c].path,
-                false);
-  }
-  deletedCookies.length = 0;
-}
-
- -

XXX: In the original document, there were only the first three parameters to the |remove| call. I added |false| as a fourth parameter because the interface seems to require it: http://lxr.mozilla.org/mozilla/sourc...Manager.idl#64 This problem also appears in the C++ version above, and I've added |PR_FALSE| as a fourth parameter there as well.

- -

除了CookieManager被调用的方法以外(也就是cookiemanager.remove(他会映射到remove()The nsICookieManager Interface),请注意那些在Javascript中反映XPCOM组件的专门的XPConnect对象和方法。

- -

Components 是用来控制到组件连接的JavaScript对象, 而classes 是一组所有你可以根据契约ID来查询的对象。为了在Javascript中实例化XPCOM组件,你创建一个新的Component对象同时传入你所需要查询的组件契约ID,返回的可能是一个singleton或者一个实例。

- -
var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
-                     .getService();
-
- -

cookiemanager 对象的结果提供组件的所有在IDL中编译好然后编译到类型库中的方法的入口。 使用CookieManager组件, 你可以写如下的代码来完成从系统中清除所有cookies的操作:

- -
cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
-                 .getService();
-cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);
-
-// delete all cookies
-function trashEm() {
-   cmgr.removeAll();
-}
-
- -

这个例子所展示的另外一个关键的XPConnect特性的是可以在所有从XPCOM映射到javascript的对象上执行的QueryInterface方法。如同在C++中, 你可以使用这个方法询问给定对象的别的接口。

- -
-

Services Versus Regular Instances

- -

到底让客户把你的组件作为一个实例还是服务是一个设计问题,你应当在你的组件文挡中进行描述。实际上,例子中通过方法createInstance()调用getService()方法的方法实际上也可以是对组件对象调用并且缓存结果,并让他做为一个singlenton而不是实例。

- -

用来建立服务的singleton设计模式在XPCOM Services进行描述。

-
- -

请记住,QueryInterface让你查询一个对象所支持的接口。在The nsICookieManager Interface的代码片断中, QueryInterface方法被用来从eunumerator中获得nsICookie接口,从而, 比如说, JavaScript代码就可以获得每个cookie的valuename属性。

- -
    -
  1. Note: cookie-manager-ui
    注意接口不是组件的一部分. XPCOM通过Mozilla's Cross Platform Front End (XPFE)和其他的用户接口使使用CookieManager这样的组件变得容易,但是组件本身并不提供自身的UI。
  2. -
- -
    -
  1. Note: private-xpcom-interfaces
    这方面也有例外. 一些XPCOM接口也可以是private并且不是作为公用的. Private接口和在IDL中公开的接口要求有所不同。
  2. -
- -
    -
  1. Note: cookie-manager-in-tutorial
    CookieManager组件用来支持本教程所描述的网页所定功能。
  2. -
- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_utilities_to_make_things_easier/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_utilities_to_make_things_easier/index.html deleted file mode 100644 index 98bb510dd8..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_utilities_to_make_things_easier/index.html +++ /dev/null @@ -1,388 +0,0 @@ ---- -title: 创建XPCOM组件/使用XPCOM工具类让事情变得简单 -slug: >- - Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Utilities_to_Make_Things_Easier -tags: - - XPCOM - - 所有分类 -translation_of: >- - Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Utilities_to_Make_Things_Easier ---- -

-

« 上一页下一页 »

-

- -

本章回顾你已经在教程第一部分建立的代码 (see webLock1.cpp in the previous chapter) 并且使用 XPCOM 工具类让代码更容易更有效. 同时,介绍一个在XPCOM和Gecko API中广泛使用基本的字符串类型.

- -

作为起点,第一部分描述可以替代webLock1.cpp中的很多代码的C++ 宏 . 很多用来完成软件组织和组件注册的代码都可以缩减为精简的数据结构和宏代码.

- -

XPCOM Macros

- -

XPCOM 架构包含了一系列宏让C++开发变得简单. 尽管有某些重叠(例如,高层的宏可以用其他的宏来组织),他们通常可以组织成如下的类别.

- -

Generic XPCOM Module Macros

- -

The work in the previous chapter was useful in setting up the generic component code. But there are only a few places in that code that are unique to the WebLock component, and it was a lot of typing. To write a different component library, you could copy the listing at the end of the chapter, change very little, and paste it into a new project. To avoid these kinds of redundancies, to regulate the way generic code is written, and to save typing, XPCOM providesgeneric module macros that expand into the module code you've already seen.

- -

Since these macros expand into "generic" implementations, they may not offer as much flexibility as you have when you are writing your own implementation. But they have the advantage of allowing much more rapid development. To get an idea about how much can be handled with the macros described in this section, compare the code listing in weblock2.cpp at the end of the chapter with webLock1.cpp in the previous chapter.

- -

The module macros include one set of macros that define the exported NSGetModule entry point, the required nsIModule implementation code and another that creates a generic factory for your implementation class. Used together, these macros can take care of a lot of the component implementation code and leave you working on the actual logic for your component.

- -
-

Note that all of the macros described in this section are similar but are used in slightly different situations. Some differ only in whether or not a method is called when the module is created and/or destroyed. XPCOM Module Macros lists the macros discussed in this section.

-
- -

XPCOM Module Macros

- - - - - - - - - - - - - - - - - - - - - - - - -
MacroDescription
NS_IMPL_NSGETMODULE(name, components)Implements the nsIModule interface with the module name of name and the component list in components.
NS_IMPL_NSGETMODULE_WITH_CTOR(name, components, ctor)Same as above but allows for a special function to be called when the module is created.
NS_IMPL_NSGETMODULE_WITH_DTOR(name, components, dtor)Same as the first macro but allows for a special function to be called when the module is destroyed.
NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(name, components, ctor, dtor)This combines the last two macros so that you can define functions to be called at the construction and destruction of the module object.
- -
Module Implementation Macros
- -

The general case is to use NS_IMPL_NSGETMODULE, which doesn't take any callbacks, but all the macros follow the same general pattern. All of these macros work on an array of structures represented by the components parameter. Each structure describes a CID that is to be registered with XPCOM.

- -

The first parameter for each of these macros is an arbitrary string that names the module. In a debugging environment, this string will be printed to the screen when the component library is loaded or unloaded. You should pick a name that makes sense and helps you keep track of things. The four required parts[other-parts] of the structure contain the following information:

- - - -
static const nsModuleComponentInfo components[] =
-{
-  { "Pretty Class Name",
-    CID,
-    CONTRACT_ID,
-    Constructor
-  },
-  // ...
-};
-
- -

The important thing to note in the fictitious listing above is that it can support multiple components in a module. Modules such as the networking libraries in Gecko ("necko") have over 50 components declared in a single nsModuleComponentInfo array like this.

- -

The first entry of the nsModuleComponentInfo above is the name of the component. Though it isn't used that much internally at the present time, this name should be something that meaningfully describes the module.

- -

The second entry of the nsModuleComponentInfo is the CID. The usual practice is to put the class ID (CID) into a #define and use the define to declare the CID in the components list. Many CIDs take the following form:

- -
#define NS_IOSERVICE_CID                             \
-{ /* 9ac9e770-18bc-11d3-9337-00104ba0fd40 */         \
-    0x9ac9e770,                                      \
-    0x18bc,                                          \
-    0x11d3,                                          \
-    {0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
-}
-
- -

The next entry is the Contract ID string, which is also usually defined in a #define in a header file.

- -

These three entries constitute the required parameters for the RegisterFactoryLocation method we looked at in the prior chapter. When you use these implementation macros, you must declare a constructor for the object, and this keeps you from having to write a factory object.

- -
Factory Macros
- -

The factory macro makes it easy to write factory implementations. Given the class name ConcreteClass, the factory macro declaration is:

- -
NS_GENERIC_FACTORY_CONSTRUCTOR(ConcreteClass)
-
- -

This results in a function called ConcreteClassConstructor that can be used in the nsModuleComponentInfo structure.

- -
#include "nsIGenericFactory.h"
-
-static const nsModuleComponentInfo components[] =
-{
-  { "Pretty Class Name",
-    SAMPLE_CID,
-    "@company.com/sample",
-    SampleConstructor
-  }
-}
-
-NS_IMPL_NSGETMODULE(nsSampleModule, components)
-
- -

Most of the components in the Mozilla browser client use this approach.

- -

Common Implementation Macros

- -

Every XPCOM object implements nsISupports, but writing this implementation over and over is tedious. Unless you have very special requirements for managing reference counting or handling interface discovery, theimplementation macros that XPCOM provides can be used. Instead of implementing the nsISupports yourself, NS_IMPL_ISUPPORTS1 can expand to the implementation of AddRef, Release, and QueryInterface for any object.

- -
NS_IMPL_ISUPPORTS1(classname, interface1)
-
- -

Also, if you implement more than one interface, you can simply change the 1 in the macro to the number of interfaces you support and list the interfaces, separated by commas. For example:

- -
NS_IMPL_ISUPPORTS2(classname, interface1, interface2)
-NS_IMPL_ISUPPORTSn(classname, interface1, ..., interfacen)
-
- -

These macros automatically add the nsISupports entry for you, so you don't need to do something like this:

- -
NS_IMPL_ISUPPORTS2(classname, interface1, nsISupports)
-
- -


- Take a close look at the above example. Note that it uses the actual name of the interface and not an IID. Inside the macro, the interface name expands to NS_GET_IID(), which is another macro that extracts the IID from the generated header of the interface. When an interface is written in XPIDL, the headers include static declarations of their IIDs. On any interface that is generated by XPIDL, you can call NS_GET_IID() to obtain the IID which is associated with that interface.

- -
// returns a reference to a shared nsIID object\
-static const nsIID iid1 = NS_GET_IID(nsISupports);
-
-// constructs a new nsIID object
-static const nsIID iid2 = NS_ISUPPORTS_IID;
-
- -

In order to use NS_IMPL_ISUPPORTSn, you must be sure that a member variable of type nsrefcnt is defined and named mRefCnt in your class. But why even bother when you can use another macro?

- -

Declaration Macros

- -

NS_DECL_NSISUPPORTS declares AddRef, Release, and QueryInterface for you, and it also defines the mRefCnt required by NS_IMPL_ISUPPORTS. Furthermore, NS_DECL_ appended with any interface name in all caps will declare all of the methods of that interface for you. For example, NS_DECL_NSIFOO will declare all of the methods of nsIFoo provided that it exists and that nsIFoo.h was generated by the XPIDL compiler. Consider the following real class:

- -
class myEnumerator : public nsISimpleEnumerator
-{
-  public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSISIMPLEENUMERATOR
-
-    myEnumerator();
-    virtual ~myEnumerator() {}
-};
-
- -

The declaration of this nsISimpleEnumerator class doesn't include any methods other than the contructor and destructor. Instead, the class uses the NS_DECL_ macro[nsISupports-warning].

- -

Using these declaration macros not only saves a tremendous amount of time when you're writing the code, it can also save time if you make changes to your IDL file, since the C++ header file will then automatically include the updated list of methods to be supported.

- -
-

The NS_INIT_ISUPPORTS macro is also a bit of a special case. Historically, it gets called in the constructor for your class and sets mRefCnt to zero. However, a change in XPCOM that occurred before Mozilla 1.3 makes NS_INIT_ISUPPORTS no longer necessary: mRefCnt's type has been changed from an integer to a class that provides its own auto-initialization. If you are building with versions earlier than Mozilla 1.3, this macro is still required.

-
- -

The following table summarizes the macro usage in this portion of the weblock.cpp source file:

- -

Common XPCOM Macros

- - - - - - - - - - - - - - - - - - - - -
NS_IMPL_ISUPPORTSnImplements nsISupports for a given class with n number of interfaces
NS_DECL_ISUPPORTSDeclares methods of nsISupports including mRefCnt
NS_INIT_ISUPPORTSInitializes mRefCnt to zero. Must be called in class's constructor
NS_GET_IIDReturns the IID given the name of an interface. Interface must be generated by XPIDL
- -

Using the macros described here, the code for the WebLock component has gone from around 340 lines of code to just under 40. Clearly from a code maintenance point of view, this kind of reduction is outstanding. The entire source file with these macros included appears in weblock2.cpp.

- -

weblock2.cpp

- -

The listing below shows the generic module code from webLock1.cpp using the macros described in this chapter:

- -

weblock2.cpp

- -
#include "nsIGenericFactory.h"
-#include "nsISupportsUtils.h"
-
-#define SAMPLE_CID \
-{ 0x777f7150, 0x4a2b, 0x4301, \
-{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
-
-class Sample: public nsISupports
-{
-  public:
-    Sample();
-    virtual ~Sample();
-
-    NS_DECL_ISUPPORTS
-};
-
-Sample::Sample()
-{
-  // note: in newer versions of Gecko (1.3 or later)
-  // you don't have to do this:
-  NS_INIT_ISUPPORTS();
-}
-
-Sample::~Sample()
-{
-}
-
-NS_IMPL_ISUPPORTS1(Sample, nsISupports);
-
-NS_GENERIC_FACTORY_CONSTRUCTOR(Sample);
-
-static const nsModuleComponentInfo components[] =
-{
-  { "Pretty Class Name",
-    SAMPLE_CID,
-    "@company.com/sample",
-    SampleConstructor
-  }
-};
-
-NS_IMPL_NSGETMODULE(nsSampleModule, components)
-
- -

String Classes in XPCOM

- -

Strings are usually thought of as linear sequences of characters. In C++, the string literal "XPCOM", for example, consists of 6 consecutive bytes, where `X' is at byte offset zero and a null character is at byte offset 5. Other kinds of strings like "wide" strings use two bytes to represent each character, and are often used to deal with Unicode strings.

- -

The string classes in XPCOM are not just limited to representing a null terminated sequence of characters, however. They are fairly complex because they support the Gecko layout engine and other subsystems that manage large chunks of data. Additionally, in some versions of Mozilla the string classes support sequences of characters broken up into multiple fragments (fragments which may or may not be null terminated)[nulls-in-strings].

- -

All string classes in XPCOM derive from one of two abstract classes[other-string-classes]: nsAString and nsACString. The former handles double byte characters, and the latter tends to be used in more general circumstances, but both of these classes define the functionality of a string. You can see these classes being passed as arguments in many of the XPCOM interfaces we'll look at in the following chapters.

- -

Using Strings

- -

Explaining how all the string classes work is outside the scope of this book, but we can show you how to use strings in the WebLock component. The first thing to note is that the string classes themselves are not frozen, which means that you should not link against them when you can avoid it.

- -

Linking the full string library (.lib or .a) into a component may raise its footprint by more than 100k (on Windows), which in many cases is an unacceptable gain (see the XPCOM string guide). For WebLock, where the string classes need to be only wrappers around already existing string data, trading advanced functionality for a much smaller footprint is the right way to go. The WebLock string classes don't need to append, concatenate, search, or do any other real work on the string data; they just need to represent char* and other data and pass them to methods that expect an nsACString.

- -

nsEmbedString and nsEmbedCString

- -

The strings used in this tutorial are nsEmbedString and nsEmbedCString, which implement the nsAString abstract class and the nsACString abstract classes, respectively. This first example shows an nsEmbedCString being used to pass an nsACString to a method that's not expected to modify the string.

- -
// in IDL: method(in ACString thing);
-
-char* str = "How now brown cow?";
-nsEmbedCString data(str);
-rv = object->Method(data);
-
- -

In this next example, the method is going to set the value of the string - as it might need to do when it returns the name of the current user or the last viewed URL.

- -
// in IDL:  attribute ACString data;
-
-nsEmbedCString data;
-method->GetData(data);
-
-// now to extract the data from the url class:
-
-const char* aStringURL = data.get();
-
- -

Note that the memory pointed to by aStringURL after the call to url.get() is owned by the URL string object. If you need to keep this string data around past the lifetime of the string object, you must make a copy.

- -
-

String Size

- -

The examples above illustrate the use of the single byte string class, nsEmbedCString. The double byte version, nsEmbedString, has the same functionality but the constructor takes nsAString and the .get() method returns the type PRUnichar*. Note that PRUnichar is a two byte value. In the coming chapters, you'll see examples that use this version in the WebLock component.

-
- -

Smart Pointers

- -

All of the interfaces that you've seen so far are reference counted. Leaking a reference by not releasing an object, as the code below demonstrates, can be a major problem.

- -
{
-  nsISupports* value = nsnull;
-  object->method(&value);
-  if (!value) return;
-
-  // ...
-
-  if (NS_FAILED(error))
-    return;   // <------------ leaks |value|
-  //...
-
-  NS_RELEASE(value);  // release our reference
-}
-
- -

A method returns an nsISupports interface pointer that has been reference counted before it is returned (assuming it wasn't nsnull). If you handle an error condition by returning prematurely, whatever value points at will leak-it will never be deleted. This is a trivial fix in this example, but in real code, this can easily happen in goto constructs, or in deep nesting with early returns.

- -

Having more than one interface pointer that needs to be released when a block goes out of scope begs for a tool that can aid the developer. In XPCOM, this tool is the nsCOMPtr, orsmart pointer class, which can save you countless hours and simplify your code when you're dealing with interface pointers. Using smart pointers, the code above can be simplified to:

- -
{
-  nsCOMPtr<nsISupports> value;
-  object->method(getter_AddRefs(value));
-  if (!value) return;
-
-  // ...
-
-  if (NS_FAILED(error))
-    return;
-  // ...
-}
-
- -

The style or syntax may be unfamilar, but smart pointers are worth learning and using because they simplify the task of managing references. nsCOMPtr is a C++ template class that acts almost exactly like raw pointers, that can be compared and tested, and so on. When you pass them to a getter, you must do something special, however: You must wrap the variable with the function getter_AddRefs, as in the example above.

- -

You cannot call the nsISupports AddRef or Release methods on a nsCOMPtr. But this restriction is desirable, since the nsCOMPtr is handling reference counting for you. If for some reason you need to adjust the reference count, you must assign the nsCOMPtr to a new variable and AddRef that. This is a common pattern when you have a local nsCOMPtr in a function and you must pass back a reference to it, as in the following:

- -
SomeClass::Get(nsISupports** aResult)
-{
-  if (!aResult)
-    return NS_ERROR_NULL_POINTER;
-
-  nsCOMPtr<nsISupports> value;
-  object->method(getter_AddRefs(value));
-
-  *aResult = value.get();
-  NS_IF_ADDREF(*aResult);
-  return NS_OK;
-}
-
- -

The first thing that this method does is check to see that the caller passed a valid address. If not, it doesn't even try to continue. Next, it calls another method on an object that is presumed to exist in this context. You can call a .get() method on the nsCOMPtr and have it returned for use as a raw pointer. This raw pointer can then be assigned to a variable and have its reference updated by NS_IF_ADDREF. Be very careful with the result of .get(), however. You should never call Release on this result because it may result in a crash. Instead, to explicitly release the object being held by a nsCOMPtr, you can assign zero to that pointer.

- -

Another nice feature of smart pointers - the part that makes them smart - is that you can QueryInterface them quite easily. For example, there are two interfaces for representing a file on a file system, the nsIFile and nsILocalFile, and they are both implemented by an object. Although we haven't formally introduced these two interfaces, the next code sample shows how simple it is to switch between these two interface:

- -
SomeClass::DoSomething(nsIFile* aFile)
-{
-  if (!aFile)
-    return NS_ERROR_NULL_POINTER;
-
-  nsresult rv;
-  nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(aFile, &rv);
-  // ...
-}
-
- -

If the QueryInterface is successful, localFile will be non-null, and rv will be set to NS_OK. If QueryInterface fails, localFile will be null, and rv will be set to a specific error code corresponding to the reason for the failure. In this construct, the result code rv is an optional parameter. If you don't care what the error code is, you can simply drop it from the function call.

- -

From this point on, we'll be using nsCOMPtrs as much as possible in WebLock. For a complete listing of smart pointer functionality, see mozilla.org's nsCOMPtr documentationXXX this should be in devmo.

- -
    -
  1. Note: other-parts
    This section discusses the main parameters of this structure. For a complete listing of all available options you can look at the complete reference in the XPCOM API Reference.
  2. -
  3. Note: nsISupports-warning
    Note that NS_DECL_ISUPPORTS doesn't obey the general rule in which every interface has a declaration macro of the form NS_DECL_INTERFACENAME, where INTERFACENAME is the name of the interface being compiled.
  4. -
  5. Note: nulls-in-strings
    The string classes may also support embedded nulls.
  6. -
  7. Note: other-string-classes
    There are other abstract string classes, but they are outside the scope of this book.
  8. -
- -

-

« 上一页下一页 »

-

-

Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/hashtables/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/hashtables/index.html deleted file mode 100644 index 24740b535c..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/hashtables/index.html +++ /dev/null @@ -1,282 +0,0 @@ ---- -title: Hashtables -slug: Mozilla/Tech/XPCOM/Guide/Hashtables -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Hashtables ---- -

 

-

What Is a Hashtable?

-

A hashtable is a data construct that stores a set of items. Each item has a key that identifies the item. Items are found, added, and removed from the hashtable by using the key. Hashtables may seem like arrays, but there are important differences:

-

哈希表是一个存储一系列元素的数据结构。每个元素都由一个关键字来标识。元素可以通过关键字来进行查找,添加,删除操作。哈希表非常类似arrays,但是也有一些很大的区别。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 数组哈希表
关键字: - - 整数: - arrays are always keyed on integers, and must be contiguous. 数组必须用整数作为关键字,而且每两个元素之间必须相邻接 - - 任意类型: - almost any datatype can be used as key, including strings, integers, XPCOM interface pointers, IIDs, and almost anything else. Keys can be disjunct (i.e. you can store entries with keys 1, 5, and 3000). 任意类型都可以作为关键字,包括字符串,整数,XPCOM接口指针,IIDs等等。关键字之间可以不在一起(例如,你可以用1,5,和3000来作为关键字。)
查询时间: - - O(1): - lookup time is a simple constant。查找时间是个简单的定值 - - O(1): - lookup time is mostly-constant, but the constant time can be larger than an array lookup。查找时间几乎是定值,但是比数组慢点。
排序: - - sorted: - stored sorted; enumerated in a sorted fashion. - - unsorted: - stored unsorted; cannot be enumerated in a sorted manner.
插入/删除: - - O(n): - adding and removing items from a large array can be time-consuming - - O(1): - adding and removing items from hashtables is a quick operation
浪费空间: - - none: - Arrays are packed structures, so there is no wasted space. - - some: - hashtables are not packed structures; depending on the implementation, there may be significant wasted memory.
-

In their implementation, hashtables take the key and apply a mathematical hash function to randomize the key and then use the hash to find the location in the hashtable. Good hashtable implementations will automatically resize the hashtable in memory if extra space is needed, or if too much space has been allocated.

-

When Should I Use a Hashtable?

-

Hashtables are useful for

- -

Hashtables should - - not - be used for

- -

In these situations, an array, a linked-list, or various tree data structures are more efficient.

-

Mozilla's Hashtable Implementations

-

Mozilla has several hashtable implementations, which have been tested and, tuned, and hide the inner complexities of hashtable implementations:

- -

Which Hashtable Should I Use?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Key Type:
integerString/CStringnsIDnsISupports*Complex
Data Type:None (Hash Set)nsInt32HashSetns(C)StringHashSetnsTHashtable<...>
Simple (PRUint32)nsDataHashtablensTHashtable<...>
<nsUint32HashKey,
- PRUint32>
<ns(C)StringHashKey,
- PRUint32>
<nsIDHashKey,
- PRUint32>
<nsISupportsHashKey,
- PRUint32>
Interface (nsISupports)nsInterfaceHashtable
<nsUint32HashKey,
- nsISupports>
<ns(C)StringHashKey,
- nsISupports>
<nsIDHashKey,
- nsISupports>
<nsISupportsHashKey,
- nsISupports>
Class (nsString*)nsClassHashtable
<nsUint32HashKey,
- nsString>
<ns(C)StringHashKey,
- nsString>
<nsIDHashKey,
- nsString>
<nsISupportsHashKey,
- nsString>
Complex
- (structures, etc.)
nsTHashtable<...>
-

PLDHash (JSDHash)

-

PLDHash and JSDHash are the same thing; one is linked from the XPCOM libraries, the other from the JS libraries. JSDHash is used extensively in the SpiderMonkey JS engine.

-

The PLDHash implementation is a fairly low-level implementation, written in C. It is extremely flexible, but requires some time to understand and use. A basic guide is included here, but you should read most of xpcom/glue/pldhash.h if you intend to use PLDHash. The C++ wrappers for PLDHash (see below) are often much easier and safer to use in C++ code, as many potential casting errors are easily avoided.

-

You must declare an entry struct type, deriving from <code>PLDHashEntryHdr</code>. This entry struct should contain whatever data you wish to store in the hashtable (any pointer or fixed-length data type). Note: because of the double-hashing implementation, entries may move in memory when the hashtable is altered. If you need entry pointers to remain constant, you may want to consider using PLHashTable instead.

-

You must also initialize a <code>PLDHashTableOps</code> structure. This serves similarly to a vtable in C++, with pointers to appropriate user-defined functions that initialize, compare, and match entries. Because PLDHash does not know what datatype your key is, all functions that work with keys are declared using const void*, and your client code must cast these pointers to the appropriate type.

-

PLDHashTables can be allocated on the stack or the heap:

- -

PLHashTable

-

PLHashTable is a part of NSPR. The header file can be found at nsprpub/lib/ds/plhash.h. In general, PLDHash is a better solution than PLHashTable, because PLHashTable makes many heap allocations.

-

There are two situations where PLHashTable may be preferable to PLDHash:

- -

nsTHashtable

-

nsTHashtable is a C++ template that wraps PLDHash. It hides many of the complexities of PLDHash (callback functions, the ops structure, etc). You should read xpcom/glue/nsTHashtable.h.

-

To use nsTHashtable, you must declare an entry-class in a pre-defined format. This entry class contains the key and the data that you are hashing (just like PLDHash, above). It also declares functions that manipulate the key. In most cases, the functions of this entry class can be entirely inline. For examples of entry classes, see the declarations at xpcom/glue/nsHashKeys.h.

-

The template parameter is the entry class. You must use the Init() function to initalize the table properly. At this point, use the functions PutEntry/GetEntry/RemoveEntry to alter the hashtable. EnumerateEntries will do enumeration, but beware that the enumeration will occur in a seemingly-random order (no sorting).

- -

Before using nsTHashtable, see if nsBaseHashtable and relatives will work for you. They are much easier to use, because you do not have to declare an entry class. If you are hashing a simple key type to a simple data type, they are generally a better choice.

-

nsBaseHashtable and friends: nsDataHashtable, nsInterfaceHashtable, and nsClassHashtable

-

These C++ templates provide a high-level interface for using hashtables that hides most of the complexities of PLDHash. They provide the following features:

- -

nsBaseHashtable is not used directly; choose one of the three derivative classes based on the data type you want to store. The KeyClass is taken from nsHashKeys.h and is the same for all three classes:

- -

The important files to read are xpcom/glue/nsBaseHashtable.h and xpcom/glue/nsHashKeys.h. These classes can be used on the stack, as a class member, or on the heap. Initialize using the Init() function; you can specify whether you need thread-safety at this time. Use the Put(), Get(), and Remove() methods to alter the table.

-

There are two enumeration functions:

- -

Using nsTHashtable as a hash-set

-

A hash set only tracks the existence of keys: it does not associate data with the keys. This can be done using nsTHashtable<nsSomeHashKey>. The appropriate entries are GetEntry and PutEntry.

-

Future Plans

-

nsISimpleEnumerator support

-

The (obsolete) nsHashtable has a wrapper that exposes an nsISimpleEnumerator on its items. I will add this support to the various nsBaseHashtable classes as well, as needed.

-

Hash Functions

-

All of the above hashtables need a Hash Function. This function converts the key into a semi-unique integer. The mozilla codebase already contains hash functions for most key types, including narrow and wide strings, pointers, and most binary data:

- - - - - - - - - - - - - - - - - - - - - - - - - -
void*
- (or nsISupports*)
cast using NS_PTR_TO_INT32
char* stringnsCRT::HashCode()
PRUnichar* string
nsAStringHashString()
nsACString
nsID&nsIDHashKey::HashKey()
-

Writing a good hash function is well beyond the scope of this document, and has been discussed extensively in computer-science circles for many years. There are many different types of hash functions. Mozilla has tuned a good general-purpose hash algorithm for strings and nsID.

-

Mozilla's Old/Obsolete/Deprecated/Decrepit Hashtables

-

nsHashtable

-

nsHashtable was a C++ wrapper around PLHashTable, and now wraps PLDHash. The design of the key classes is not optimal, however, and nsHashtable has been deprecated in favor of nsDataHashtable and friends.

-

nsObjectHashtable

-

nsObjectHashtable is a form of nsHashtable. It has been replaced by nsClassHashtable.

-

nsSupportsHashtable

-

nsSupportsHashtable is a form of nsHashtable. It has been replaced by nsInterfaceHashtable.

-

nsHashSets

-

nsHashSets has predefined hash sets for common keys, which are trivially easy to use. See xpcom/ds/nsHashSets.h. This functionality has been replaced by nsTHashtable<nsSomeHashKey>.

-

nsDoubleHashtable

-

nsDoubleHashtable is the (obsolete) precursor to nsTHashtable. It uses macros instead of C++ templates.

-
-

Original Document Information

- -
-

 

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/index.html deleted file mode 100644 index 385888d9fb..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: XPCOM 指南 -slug: Mozilla/Tech/XPCOM/Guide -tags: - - Landing - - Mozilla - - XPCOM -translation_of: Mozilla/Tech/XPCOM/Guide ---- -

 

-

本文提供了关于 XPCOM 的说明和使用文档,包括如何在你的工程中使用,如何为你的 Firefox 扩展等构建 XPCOM 组件。

-

- - -

diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/internal_strings/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/internal_strings/index.html deleted file mode 100644 index fe5806168f..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/guide/internal_strings/index.html +++ /dev/null @@ -1,809 +0,0 @@ ---- -title: Strings -slug: Mozilla/Tech/XPCOM/Guide/Internal_strings -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM/Guide/Internal_strings ---- -

 

-

Preface

-
-

by Alec Flett
- Thanks to David Baron for actual docs,
- Peter Annema for lots of direction,
- Myk Melez for some more docs, and
- David Bradley for a diagram
- Revised by Darin Fisher for Mozilla 1.7
- Revised by Jungshik Shin to clarify character encoding issues

-
-

This guide will attempt to document the plethora of string classes, and hopefully provide an answer to the age old question, "what string class should I use here?"

-
-

If you are a Mozilla embedder or if you are writing an XPCOM component that will be distributed separately from the Mozilla code base, then this string guide is most likely not for you! Provided you are developing against Mozilla 1.7 or later, you should instead be using the new minimal Mozilla string API and in particular the nsEmbedString class.

-
-

In a hurry? Go check out the String Quick-Reference ().

-

Introduction

-

The string classes are a library of C++ classes which are used to manage buffers of unicode and single-byte character strings. They reside in the mozilla codebase in the xpcom/string directory.

-

Abstract (interface) classes begin with "nsA" and concrete classes simply begin with "ns". Classes with a "CString" in the name store 8-bit bytes (char's) which may refer to single byte ASCII strings, or multibyte Unicode strings encoded in UTF-8 or a (multibyte or single byte) legacy character encoding (e.g. ISO-8859-1, Shift_JIS, GB2312, KOI8-R). All other classes simply have "String" in their name and refer to 16-bit strings made up of PRUnichar's, For example: nsAString is an abstract class for storing Unicode characters in UTF-16 encoding, and nsDependentCString is a concrete class which stores a 8-bit string. Every 16-bit string class has an equivalent 8-bit string class. For example: nsCString is the 8-bit string class which corresponds to nsString.

-

8-bit and 16-bit string classes have completely separate base classes, but share the same APIs. As a result, you cannot assign a 8-bit string to a 16-bit string without some kind of conversion helper class or routine. For the purpose of this document, we will refer to the 16-bit string classes in class documentation. It is safe to assume that every 16-bit class has an equivalent 8-bit class.

-

String Guidelines

-

Follow these simple rules in your code to keep your fellow developers, reviewers, and users happy.

- -

The Abstract Classes

-

Every string class derives from nsAString (or nsACString). This class provides the fundamental interface for access and manipulation of strings. While concrete classes derive from nsAString, nsAString itself cannot be instantiated.

-

This is very similar to the idea of an "interface" that mozilla uses to describe abstract object descriptions in the rest of the codebase. In the case of interfaces, class names begin with "nsI" where "I" refers to "Interface". In the case of strings, abstract classes begin with "nsA" and the "A" means "Abstract".

-

There are a number of abstract classes which derive from nsAString. These abstract subclasses also cannot be instantiated, but they describe a string in slightly more detail than nsAString. They guarantee that the underlying implementation behind the abstract class provides specific capabilities above and beyond nsAString.

-

The list below describes the main base classes. Once you are familiar with them, see the appendix describing What Class to Use When.

- -

The remainder of the string classes inherit from either nsSubstring or nsString. Thus, every string class is compatible with nsAString.

-

It's important to note that nsSubstring and nsAString both represent a contiguous array of characters that are not necessarily null-terminated. One might ask then ask why two different yet similar string classes need to exist. Well, nsSubstring exists primarily as an optimization since nsAString must retain binary compatibility with the frozen nsAString class that shipped with Mozilla 1.0. Up until the release of Mozilla 1.7, nsAString was capable of representing a string broken into multiple fragments. The cost associated with supporting multi-fragment strings was high and offered limited benefits. It was decided to eliminate support for multi-fragment strings in an effort to reduce the complexity of the string classes and improve performance. See bug 231995 for more details.

-

Though nsSubstring provides a more efficient interface to its underlying buffer than nsAString, nsAString is still the most commonly used class for parameter passing. This is because it is the string class corresponding to AString in XPIDL. Therefore, this string guide will continue to discuss the string classes with an emphasis on nsAString.

-

Since every string derives from nsAString (or nsACString), they all share a simple API. Common read-only methods:

- -

Common methods that modify the string:

- -

Complete documentation can be found in the Appendix.

-

Read-only strings

-

The const attribute on a string determines if the string is writable. If a string is defined as a const nsAString then the data in the string cannot be manipulated. If one tries to call a non-const method on a const string the compiler will flag this as an error at build time.

-

For example:

-
void nsFoo::ReverseCharacters(nsAString& str) {
-      ...
-     str.Assign(reversedStr); // modifies the string
-}
-
-

This should not compile, because you're assigning to a const class:

-
void nsFoo::ReverseCharacters(const nsAString& str) {
-      ...
-     str.Assign(reversedStr);
-}
-
-

As function parameters

-

It is recommended that you use the most abstract interface possible as a function parameter, instead of using concrete classes. The convention is to use C++ references (the '&' character) instead of pointers (the '*' character) when passing string references around. For example:

-
// abstract reference
-nsFoo::PrintString(const nsAString& str) {..}
-
-// using a concrete class!
-nsFoo::PrintString(const nsString& str) {..}
-
-// using a pointer!
-nsFoo::PrintString(const nsAString* str) {..}
-
-

The abstract classes are also sometimes used to store temporary references to objects. You can see both of these uses in Common Patterns, below.

-

NOTE: While using abstract string classes increases the re-usability of your methods, it also incurs a codesize and performance penalty. Therefore, when writing methods that will only ever be used within the confines of your source file or module, it is better to use const nsSubstring& for input parameters and nsString& for output parameters. --Darin

-

The Concrete Classes - which classes to use when

-

The concrete classes are for use in code that actually needs to store string data. The most common uses of the concrete classes are as local variables, and members in classes or structs. Whereas the abstract classes differ in storage mechansim, for the most part the concrete classes differ in storage policy.

-

The following is a list of the most common concrete classes. Once you are familiar with them, see the appendix describing What Class to Use When.

- -

There are also a number of concrete classes that are created as a side-effect of helper routines, etc. You should avoid direct use of these classes. Let the string library create the class for you.

- -

Of course, there are times when it is necessary to reference these string classes in your code, but as a general rule they should be avoided.

-

Iterators

-

Iterators are objects that retain a reference to a position in a string. In some ways they are like a number which refers to an index in an array, or a character-pointer that refers to a position in a character string. They also provide a syntactic means to distinguish between reading and writing to a string.

-

Iterators are most often used to extract substrings of a string. They provide the capability to modify the contents of a string, but often helper routines, or the string's own methods are quicker at complex string transformations.

-

Iterators are declared from the string class which they are iterating:

-
nsAString::const_iterator start, end; // reading-only iterators for nsAString
-nsString::iterator substr_start, substr_end; // writing iterators for nsString
-
-

Iterators are initialized with one of 4 methods on the string you wish to reference:

-
// let's read from 'str'
-str.BeginReading(start); // initialize 'start' to the beginning of 'str'
-str.EndReading(end); // 'end' will be at the end of the string
-
-// say we also want to write to 'url'
-url.BeginWriting(substr_start);
-url.EndWriting(substr_end);
-
-

You can access the code unit that an iterator points to with the dereference operator *.

-
if (*start == '[')
-     printf("Starts with a bracket\n");
-
-

Note in the above examples, that 'end' and 'substr_end' will actually point to the code unit past the end of the string, so you should never dereference the direct result of .EndReading().

-

You can test if two iterators point to the same position with == or !=. You can advance iterators with ++. Putting the ++ before your iterator is preferred, and will prevent creation of a temporary iterator.

-
while (start != end) // iterate through the whole string
-     ++start;
-
-

You can effectively write to a string with writing iterators (as opposed to const-iterators):

-
// change all * to !
-while (substr_start != substr_end) {
-     if (*substr_start == '*')
-           *substr_start = '!';
-     ++substr_start;
-}
-
-

With the patch for bug 231995, this loop is now as efficient as iterating with raw character pointers.

-

Helper Classes and Functions

-

Searching strings - looking for substrings, characters, etc.

-

FindInReadable() is the replacement for the old string.Find(..). The syntax is:

-
PRBool FindInReadable(const nsAString& pattern,
-                      nsAString::const_iterator start, nsAString::const_iterator end,
-                      nsStringComparator& aComparator = nsDefaultStringComparator());
-
-

To use this, start and end should point to the beginning and end of a string that you would like to search. If the search string is found, start and end will be adjusted to point to the beginning and end of the found pattern. The return value is PR_TRUE or PR_FALSE, indicating whether or not the string was found.

-

An example:

-
const nsAString& str = GetSomeString();
-nsAString::const_iterator start, end;
-
-str.BeginReading(start);
-str.EndReading(end);
-
-NS_NAMED_LITERAL_STRING(valuePrefix, "value=");
-
-if (FindInReadable(valuePrefix, start, end)) {
-    // end now points to the character after the pattern
-    valueStart = end;
-
-}
-
-

Memory Allocation - how to avoid it, which methods to use

-

The preferred method to allocate a new character buffer (PRUnichar*/char*) from an existing string is with one of the following methods:

- -

These methods return a buffer allocated using XPCOM's allocator (nsMemory::Alloc) instead of the traditional allocator (malloc, etc.). You should use nsMemory::Free to deallocate the result when you no longer need it.

-

Substrings (string fragments)

-

It is very simple to refer to a substring of an existing string without actually allocating new space and copying the characters into that substring. Substring() is the preferred method to create a reference to such a string.

-
void ProcessString(const nsAString& str) {
-    const nsAString& firstFive = Substring(str, 0, 5);
-    // firstFive is now a string representing the first 5 characters
-}
-
-

Unicode Conversion ns*CString vs. ns*String

-

Strings can be - - stored - in two basic formats: 8-bit code unit (byte/char) strings, or 16-bit code unit (PRUnichar) strings. Any string class with a capital "C" in the classname contains 8-bit bytes. These classes include nsCString, nsDependentCString, and so forth. Any string class - - without - the "C" contains 16-bit code units.

-

A 8-bit string can be in one of many character encodings while a 16-bit string is always in UTF-16. The most common encodings are:

- -

In addition, there are literally hundreds of encodings that are provided by internationalization libraries. Access to these libraries may be part of the application (such as nsICharsetConversionManager in Mozilla) or built into the operating system (such as iconv() in UNIX operating systems and MultiByteToWideChar/WideCharToMultiByte on Windows).

-

When working with existing code, it is important to examine the current usage of the strings that you are manipulating, to determine the correct conversion mechanism.

-

When writing new code, it can be confusing to know which storage class and encoding is the most appropriate. There is no single answer to this question, but there are a few important guidelines:

- -


- To assist with ASCII, UTF-8, and UTF-16 conversions, there are some helper methods and classes. Some of these classes look like functions, because they are most often used as temporary objects on the stack.

-

UTF-8 / UTF-16 conversion

-

NS_ConvertUTF8toUTF16( - - const nsACString& - ) - a nsAutoString subclass that converts a UTF-8 encoded nsACString or const char* to a 16-bit UTF-16 string. If you need a const PRUnichar* buffer, you can use the .get() method. For example:

-
/* signature: void HandleUnicodeString(const nsAString& str); */
-object->HandleUnicodeString(NS_ConvertUTF8toUTF16(utf8String));
-
-/* signature: void HandleUnicodeBuffer(const PRUnichar* str); */
-object->HandleUnicodeBuffer(NS_ConvertUTF8toUTF16(utf8String).get());
-
-

NS_ConvertUTF16toUTF8( - - const nsAString& - ) - a nsCAutoString which converts a 16-bit UTF-16 string (nsAString) to a UTF-8 encoded string. As above, you can use .get() to access a const char* buffer.

-
/* signature: void HandleUTF8String(const nsACString& str); */
-object->HandleUTF8String(NS_ConvertUTF16toUTF8(utf16String));
-
-/* signature: void HandleUTF8Buffer(const char* str); */
-object->HandleUTF8Buffer(NS_ConvertUTF16toUTF8(utf16String).get());
-
-

CopyUTF8toUTF16( - - const nsACString&, nsAString& - ) - converts and copies:

-
// return a UTF-16 value
-void Foo::GetUnicodeValue(nsAString& result) {
-    CopyUTF8toUTF16(mLocalUTF8Value, result);
- }
-
-

AppendUTF8toUTF16( - - const nsACString&, nsAString& - ) - converts and appends:

-
// return a UTF-16 value
-void Foo::GetUnicodeValue(nsAString& result) {
-    result.AssignLiteral("prefix:");
-    AppendUTF8toUTF16(mLocalUTF8Value, result);
-}
-
-


- UTF8ToNewUnicode( - - const nsACString&, PRUint32* aUTF16Count = nsnull - ) - allocates and converts (the optional parameter will contain the number of 16-byte units upon return, if non-null):

-
void Foo::GetUTF16Value(PRUnichar** result) {
-    *result = UTF8ToNewUnicode(mLocalUTF8Value);
-}
-
-


- CopyUTF16toUTF8( - - const nsAString&, nsACString& - ) - converts and copies:

-
// return a UTF-8 value
-void Foo::GetUTF8Value(nsACString& result) {
-    CopyUTF16toUTF8(mLocalUTF16Value, result);
-}
-
-

AppendUTF16toUTF8( - - const nsAString&, nsACString& - ) - converts and appends:

-
// return a UTF-8 value
-void Foo::GetUnicodeValue(nsACString& result) {
-    result.AssignLiteral("prefix:");
-    AppendUTF16toUTF8(mLocalUTF16Value, result);
-}
-
-

ToNewUTF8String( - - const nsAString& - ) - allocates and converts:

-
void Foo::GetUTF8Value(char** result) {
-    *result = ToNewUTF8String(mLocalUTF16Value);
-}
-
-

Lossy Conversion

-

The following should only be used when you can guarantee that the original string is ASCII. These helpers are very similar to the UTF-8 / UTF-16 conversion helpers above.

-

UTF-16 to ASCII converters

-

These converters are - - very dangerous - because they - - lose information - during the conversion process. You should - - avoid UTF-16 to ASCII conversions - unless your strings are guaranteed to be ASCII. Each 16-bit code unit in 16-bit string is simply cast to an 8-bit byte, which means all Unicode character values above 0xFF are converted to an arbitrary 8-bit byte.

- -

ASCII to UTF-16 converters

-

These converters are - - very dangerous - because they will - - mangle any non-ASCII string - into a meaningless UTF-16 string. You should - - avoid ASCII to UTF-16 conversions - unless your strings are guaranteed to be ASCII. For instance, if you have an 8-bit string encoded in a multibyte character encoding, each byte of the string will be "inflated" to a 16-bit number by simple casting.

-

For example, imagine a UTF-8 string where the first Unicode character of the string is represented with a 3-byte UTF-8 sequence, the "inflated" UTF-16 string will contain the 3 PRUnichar's instead of the single PRUnichar that represents the first character. These PRUnichar's have nothing to do with the first Unicode character in the UTF-8 string.

- -

Common Patterns

-

Callee-allocated Parameters

-

Many APIs result in a method allocating a buffer in order to return strings to its caller. This can be tricky because the caller has to remember to free the string when they have finished using it. Fortunately, the nsXPIDLString class makes this very easy.

-

A method may look like this:

-
void GetValue(PRUnichar** aValue)
-{
-    *aValue = ToNewUnicode(foo);
-}
-
-

Without the string classes, the caller would need to free the string:

-
{
-    PRUnichar* val;
-    GetValue(&val);
-
-    if (someCondition) {
-        // don't forget to free the value!
-        nsMemory::Free(val);
-        return NS_ERROR_FAILURE;
-    }
-
-    ...
-    // and later, still don't forget to free!
-    nsMemory::Free(val);
-}
-
-

With nsXPIDLString you never have to worry about this. You can just use getter_Copies() to wrap the string class, and the class will remember to free the buffer when it goes out of scope:

-
{
-    nsXPIDLString val;
-    GetValue(getter_Copies(val));
-
-    // val will free itself here
-    if (someCondition)
-        return NS_ERROR_FAILURE;
-    ...
-    // and later, still nothing to free
-}
-
-

The resulting code is much simpler, and easy to read.

-

Literal Strings

-

A - - literal string - is a raw string value that is written in some C++ code. For example, in the statement printf("Hello World\n"); the value "Hello World\n" is a literal string. It is often necessary to insert literal string values when an nsAString or nsACString is required. These four macros will provide you with the necessary conversion:

- -

The purpose of the CSTRING versions of these macros may seem unnecessary, given that nsDependentCString will also wrap a string value in an nsCString. The advantage to these macros is that the length of these strings is calculated at compile time, so the string does not need to be scanned at runtime to determine its length.

-

The STRING versions of these macros provide a portable way of declaring UTF-16 versions of the given literal string, avoiding runtime conversion on platforms which support literal UTF-16 strings (e.g., MSVC++ and GCC with the -fshort-wchar option).

-
// call Init(const PRUnichar*)
-Init(L"start value"); // bad - L"..." is not portable!
-Init(NS_ConvertASCIItoUTF16("start value").get()); // bad - runtime ASCII->UTF-16 conversion!
-
-// call Init(const nsAString&)
-Init(nsDependentString(L"start value")); // bad - not portable!
-Init(NS_ConvertASCIItoUTF16("start value")); // bad - runtime ASCII->UTF-16 conversion!
-
-// call Init(const nsACString&)
-Init(nsDependentCString("start value")); // bad - length determined at runtime
-
-

Here are some examples of proper NS_LITERAL_[C]STRING usage.

-
// call Init(const PRUnichar*)
-Init(NS_LITERAL_STRING("start value").get());
-
-// call Init(const nsAString&)
-Init(NS_LITERAL_STRING("start value"));
-
-// call Init(const nsACString&)
-Init(NS_LITERAL_CSTRING("start value"));
-
-

There are a few details which can be useful in tracking down issues with these macros:

-

NS_LITERAL_STRING does compile-time conversion to UTF-16 on some platforms (e.g. Windows, Linux, and Mac) but does runtime conversion on other platforms. By using NS_LITERAL_STRING your code is guaranteed to use the best possible conversion for the platform in question.

-

Because some platforms do runtime conversion, the use of literal string concatenation inside a NS_LITERAL_STRING/NS_NAMED_LITERAL_STRING macro will compile on these platforms, but not on platforms which support compile-time conversion.

-

For example:

-
// call Init(nsAString&)
-Init(NS_LITERAL_STRING("start "
-     "value")); // only compiles on some platforms
-
-

The reason for this is that on some platforms, the L"..." syntax is used, but it is only applied to the first string in the concatenation ("start "). When the compiler attempts to concatenate this with the non-Unicode string "value" it gets confused.

-

Also, using preprocessor macros as the string literal is unsupported:

-
#define some_string "See Mozilla Run"
-...
-Init(NS_LITERAL_STRING( some_string )); // only compiles on some platforms/with some compilers.
-
-
-

String Concatenation

-

Strings can be concatenated together using the + operator. The resulting string is a const nsSubstringTuple object. The resulting object can be treated and referenced similarly to a nsAString object. Concatenation - - does not copy the substrings - . The strings are only copied when the concatenation is assigned into another string object. The nsSubstringTuple object holds pointers to the original strings. Therefore, the nsSubstringTuple object is dependent on all of its substrings, meaning that their lifetime must be at least as long as the nsSubstringTuple object.

-

For example, you can use the value of two strings and pass their concatenation on to another function which takes an const nsAString&:

-
void HandleTwoStrings(const nsAString& one, const nsAString& two) {
-    // call HandleString(const nsAString&)
-    HandleString(one + two);
-}
-
-

NOTE: The two strings are implicitly combined into a temporary nsString in this case, and the temporary string is passed into HandleString. If HandleString assigns its input into another nsString, then the string buffer will be shared in this case negating the cost of the intermediate temporary. You can concatenate N strings and store the result in a temporary variable:

-
NS_NAMED_LITERAL_STRING(start, "start ");
-NS_NAMED_LITERAL_STRING(middle, "middle ");
-NS_NAMED_LITERAL_STRING(end, "end");
-// create a string with 3 dependent fragments - no copying involved!
-nsString combinedString = start + middle + end;
-
-// call void HandleString(const nsAString&);
-HandleString(combinedString);
-
-

If you are using NS_LITERAL_STRING to create a temporary that is only used once, then it is safe to define it inside a concatenation because the string buffer will live as long as the temporary concatenation object (of type nsSubstringTuple).

-
// call HandlePage(const nsAString&);
-// safe because the concatenated-string will live as long as its substrings
-HandlePage(NS_LITERAL_STRING("start ") + NS_LITERAL_STRING("end"));
-
-

Local variables

-

Local variables within a function are usually stored on the stack. The nsAutoString/nsCAutoString classes are derivatives of the nsString/nsCString classes. They own a 64-character buffer allocated in the same storage space as the string itself. If the nsAutoString is allocated on the stack, then it has at its disposal a 64-character stack buffer. This allows the implementation to avoid allocating extra memory when dealing with small strings.

-
...
-nsAutoString value;
-GetValue(value); // if the result is less than 64 code units,
-                 // then this just saved us an allocation
-...
-
-

Member variables

-

In general, you should use the concrete classes nsString and nsCString for member variables.

-
class Foo {
-    ...
-    // these store UTF-8 and UTF-16 values respectively
-    nsCString mLocalName;
-    nsString mTitle;
-};
-
-

Note that the strings are declared directly in the class, not as pointers to strings. Don't do this:

-
class Foo {
-public:
-    Foo() {
-        mLocalName = new nsCString();
-        mTitle = new nsString();
-    }
-    ~Foo() { delete mLocalName; delete mTitle; }
-
-private:
-    // these store UTF-8 and UTF-16 values respectively
-    nsCString* mLocalName;
-    nsString*  mTitle;
-};
-
-

The above code may appear to save the cost of the string objects, but nsString/nsCString are small objects - the overhead of the allocation outweighs the few bytes you'd save by keeping a pointer.

-

Another common incorrect pattern is to use nsAutoString/nsCAutoString for member variables. As described in Local Variables, these classes have a built in buffer that make them very large. This means that if you include them in a class, they bloat the class by 64 bytes (nsCAutoString) or 128 bytes (nsAutoString).

-

An example:

-
class Foo {
-    ...
-
-    // bloats 'Foo' by 128 bytes!
-    nsAutoString mLocalName;
-};
-
-

Raw Character Pointers

-

PromiseFlatString() can be used to create a temporary buffer which holds a null-terminated buffer containing the same value as the source string. PromiseFlatString() will create a temporary buffer if necessary. This is most often used in order to pass an nsAString to an API which requires a null-terminated string.

-

In the following example, an nsAString is combined with a literal string, and the result is passed to an API which requires a simple character buffer.

-
// Modify the URL and pass to AddPage(const PRUnichar* url)
-void AddModifiedPage(const nsAString& url) {
-    NS_NAMED_LITERAL_STRING(httpPrefix, "http://");
-    const nsAString& modifiedURL = httpPrefix + url;
-
-    // creates a temporary buffer
-    AddPage(PromiseFlatString(modifiedURL).get());
-}
-
-

PromiseFlatString() is smart when handed a string that is already null-terminated. It avoids creating the temporary buffer in such cases.

-
// Modify the URL and pass to AddPage(const PRUnichar* url)
-void AddModifiedPage(const nsAString& url, PRBool addPrefix) {
-    if (addPrefix) {
-        // MUST create a temporary buffer - string is multi-fragmented
-        NS_NAMED_LITERAL_STRING(httpPrefix, "http://");
-        AddPage(PromiseFlatString(httpPrefix + modifiedURL));
-    } else {
-        // MIGHT create a temporary buffer, does a runtime check
-        AddPage(PromiseFlatString(url).get());
-    }
-}
-
-

printf and a UTF-16 string

-

For debugging, it's useful to printf a UTF-16 string (nsString, nsAutoString, nsXPIDLString, etc). To do this usually requires converting it to an 8-bit string, because that's what printf expects. However, on Windows, the following should work:

-
printf("%S\n", yourString.get());
-
-

(Note: I didn't test this. Also, I'm not sure what exactly this does to non-ASCII characters, especially when they are outside the system codepage). The reason that this doesn't work on Unix is because a wchar_t, which is what %S expects, is usually 4 bytes there (even when Mozilla is compiled with -fshort-wchar, because this would require libc to be compiled with -fshort-wchar).

-

If non-ASCII characters aren't important, use:

-
printf("%s\n", NS_LossyConvertUTF16toASCII(yourString).get());
-
-

On platforms that use UTF-8 for console output (most Linux distributions), this works:

-
printf("%s\n", NS_ConvertUTF16toUTF8(yourString).get());
-
-

IDL

-

The string library is also available through IDL. By declaring attributes and methods using the specially defined IDL types, string classes are used as parameters to the corresponding methods.

-

IDL String types

-

The C++ signatures follow the abstract-type convention described above, such that all method parameters are based on the abstract classes. The following table describes the purpose of each string type in IDL.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDL typeC++ TypePurpose
stringchar*Raw character pointer to ASCII (7-bit) string, no string classes used. High bit is not guaranteed across XPConnect boundaries
wstringPRUnichar*Raw character pointer to UTF-16 string, no string classes used
AStringnsAStringUTF-16 string
ACStringnsACString8-bit string, all bits are preserved across XPConnect boundaries
AUTF8StringnsACStringUTF-8 string - converted to UTF-16 as necessary when value is used across XPConnect boundaries
DOMStringnsAStringUTF-16 string used in the DOM. More or less the same as AString, but in JavaScript it has no distinction between whether the string is void or just empty. (not sure on this, looking for corrections.
-

C++ Signatures

-

In IDL, in parameters are read-only, and the C++ signatures for *String parameters follows the above guidelines by using const nsAString& for these parameters. out and inout parameters are defined simply as nsAString so that the callee can write to them.

- - - - - - - - - - - -
IDLC++
-
-interface nsIFoo : nsISupports {
-
-    attribute AString utf16String;
-
-
-
-
-    AUTF8String getValue(in ACString key);
-
-};
-
-
-
-class nsIFoo : public nsISupports {
-
-     NS_IMETHOD GetUtf16String(nsAString&
-                               aResult) = 0;
-     NS_IMETHOD SetUtf16String(const nsAString&
-                              aValue) = 0;
-
-     NS_IMETHOD GetValue(const nsACString& aKey,
-                     nsACString& aResult) = 0;
-};
-
-
-

In the above example, utf16String is treated as a UTF-16 string. The implementation of GetUtf16String() will use aResult.Assign to "return" the value. In SetUtf16String() the value of the string can be used through a variety of methods including Iterators, PromiseFlatString, and assignment to other strings.

-

In GetValue(), the first parameter, aKey, is treated as a raw sequence of 8-bit values. Any non-ASCII characters in aKey will be preserved when crossing XPConnect boundaries. The implementation of GetValue() will assign a UTF-8 encoded 8-bit string into aResult. If the this method is called across XPConnect boundaries, such as from a script, then the result will be decoded from UTF-8 into UTF-16 and used as a Unicode value.

-

Choosing a string type

-

It can be difficult to determine the correct string type to use for IDL. The following points should help determine the appropriate string type.

- -

Appendix A - What class to use when

-

This table provides a quick reference for what classes you should be using.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ContextclassNotes
Local VariablesnsAutoString
- nsCAutoString
 
Class Member VariablesnsString
- nsCString
 
Method Parameter typesnsAString
- nsACString
Use abstract classes for parameters. Use const nsAString& for "in" parameters and nsAString& for "out" parameters.
Retrieving "out" string/wstringsnsXPIDLString
- nsXPIDLCString
Use getter_Copies(). Similar to nsString / nsCString.
Wrapping character buffersnsDependentString
- nsDependentCString
Wrap const char* / const PRUnichar* buffers.
Literal stringsNS_LITERAL_STRING
- NS_LITERAL_CSTRING
Similar to nsDependent[C]String, but pre-calculates length at build time.
-

Appendix B - nsAString Reference

-

Read-only methods.

- -

Methods that modify the string.

- diff --git a/files/zh-cn/mozilla/tech/xpcom/index.html b/files/zh-cn/mozilla/tech/xpcom/index.html deleted file mode 100644 index 98620642db..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: XPCOM -slug: Mozilla/Tech/XPCOM -tags: - - XPCOM - - 所有分类 -translation_of: Mozilla/Tech/XPCOM ---- -

XPCOM(Cross Platform Component Object Model)是一种跨平台组件对象模型,其原理与微软的COM技术类似,它支持多种语言绑定(Language Bindings)。也就是说,我们可以使用C++、JAVA、JavaScript、Python、Ruby、Perl等语言来编写组件。而XPCOM的接口是用一种叫做XPIDL的IDL(Interface Description Language)来定义的。

- -
-

XPCOM 本身提供了一套核心的组件和类,用于诸如内存管理,线程,基本数据结构(strings, arrays, variants)等 。但是大部分的XPCOM组件并不是这个核心库提供的,而是由很多第三方的平台(例如Gecko或者Necko)提供,或者由一个应用,甚至一个扩展提供。

- -

 

- -

-
Generic factory
Most XPCOM factories can be very simple. Rick Potts wrote a templated-based generic factory (nsFactory<t>) that simplifies the factory creation process that just requires writing a CreateInstance() method. The new nsIGenericFactory interface takes this a step further, by providing a single interface that can be reused anytime a simple implementation of nsIFactory is needed. Here is the interface, and a description of its use.</t>
Observer Notifications
The following are topics that you can observe during the course of an application. Unless otherwise noted you register for the topics using the nsIObserverService.
Setting HTTP request headers
HTTP 是网络背后的核心技术之一。除了实质内容之外,一些重要的信息通过HTTP 头传递给HTTP 请求和响应。
Storage
Storage 存储是一个 SQLite 数据库API。它可用于受信任的调用者,仅限于扩展和Firefox组件。
XPCOM Glue
The XPCOM Glue is a static library which component developers and embedders can link against. It allows developers to link only against the frozen XPCOM method symbols and maintain compatibility with multiple versions of XPCOM.
XPCOM reference
This reference describes the interfaces and functions provided by the XPCOM library. In addition, it details the various helper classes and functions, as well as the components, provided by the XPCOM glue library. The contents herein are oriented primarily toward extension developers and people embedding XPCOM in other projects.
-
XPCOM 指南
本文提供了关于 XPCOM 的说明和使用文档,包括如何在你的工程中使用,如何为你的 Firefox 扩展等构建 XPCOM 组件。
与XPCOM cycle collector交互
本文是对于在Firefox 3的XPCOM中引入的cycle collector的一个简要描述,描述了将一个已有的C++类修改为一个XPCOM cycle collection中的参与项的步骤。如果你认为你有关于类的循环引用导致的内存泄漏,那可以看看这个。
使用剪贴板
This section provides information about cutting, copying and pasting to and from the clipboard.
创建Python XPCOM组件
Creating Applications with Mozilla 已经包含了一个教程用于编写简单的基于JavaScript和C++(实现nsISimple接口)的组件,本文阐述如何通过Python语言使用PyXPCOM创建相同的组件。
收集 In-Memory 数据源
语言绑定
一款 XPCOM 的语言绑定是连接某种特定的程序设计语言与 XPCOM 之间的纽带,它用来提供从语言到 XPCOM 对象的访问, 并且将此种语言写成的模块作为其他进行 XPCOM 绑定的程序语言的 XPCOM 对象。
-

- -

- -
-

加入 XPCOM 社区

-
-
请选择你喜欢的方式加入我们:
- -
- -
-

- -

-
- -

 

diff --git a/files/zh-cn/mozilla/tech/xpcom/interfacing_with_the_xpcom_cycle_collector/index.html b/files/zh-cn/mozilla/tech/xpcom/interfacing_with_the_xpcom_cycle_collector/index.html deleted file mode 100644 index a0b4472d02..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/interfacing_with_the_xpcom_cycle_collector/index.html +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: 与XPCOM cycle collector交互 -slug: Mozilla/Tech/XPCOM/Interfacing_with_the_XPCOM_cycle_collector -translation_of: Mozilla/Tech/XPCOM/Interfacing_with_the_XPCOM_cycle_collector ---- -

本文是对于在Firefox 3的XPCOM中引入的cycle collector的一个简要描述,描述了将一个已有的C++类修改为一个XPCOM cycle collection中的参与项的步骤。如果你认为你有关于类的循环引用导致的内存泄漏,那可以看看这个。

- -

本文面向Mozilla C++开发者。

- -

cycle collector干了些什么

- -

cycle collector大部分时间在记录可能导致循环引用的XPCOM对象指针。在collector的空闲阶段,nsAutoRefCnt的变体通过collector快速的修改自己的注册状态(注册/注销),会传递出一个“可疑”的引用计数事件(从N+1到N,N≠0)。

- -

collector会阶段性的唤醒并验证缓冲区中记录过的可疑指针。这是collector的扫描阶段。在这个阶段,collector会请求每个候选项的cycle-collection helper类,如果存在,则需要helper来描述候选项拥有的子结构。collector可以以这种方式建立一个从可疑对象开始的拥有权关系图。

- -

如果collector发现一组对象出现了彼此互相引用,并且确定组内对象的引用计数全由组内其他对象提供,则认定这组对象为循环引用,并尝试释放它们。这是collector的释放阶段。在这个阶段,collector遍历已找到的循环引用对象,再次请求它们的helper对象,释放其子结构和其他对象的引用。

- -

collector也能遍历JS堆,并定位传入和传出的循环引用。

- -

collector失效

- -

cycle collector是一个保守的设备。有些情况下,它无法回收循环引用。

- -
    -
  1. 它默认不怀疑任何指针;对象必须要标记它们自己为可疑对象,一般用nsCycleCollectingAutoRefCnt而不是nsAutoRefCnt。
  2. -
  3. 它只遍历那些在QI(QueryInterface)时返回helper对象的对象。如果在遍历图的过程中遇到了未知的边,那它会直接放弃这条边,因此每条边都需要被标记为可疑对象,否则找不到环。
  4. -
  5. helper对象中的TraverseUnlink方法不是魔法,是程序员编码的,如果代码写错了,那collector也还是会崩。
  6. -
  7. collector不知道怎么去搜索一个存在栈中的具有所有权的临时指针,所以将它放在程序的最顶层运行是有必要的。虽然有额外的所有权指针时不会崩,但是它会无法统计已记录的对象的引用计数,这也有可能导致回收失败。
  8. -
- -

怎么标记一个类为候选项

- -

cycle collector和你的类之间的接口使用xpcom/base/nsCycleCollector.h中的内容实现直接获取,但是在xpcom/glue/nsCycleCollectionParticipant.h中提供了很多方便的宏用来标记你的类。通常,如果你用nsCOMPtr的mBar和mBaz来修改类nsFoo,可以简化为几个简单的修改:

- -
    -
  1. 在nsFoo.h和nsFoo.cpp中包含头文件nsCycleCollectionParticipant.h。 
  2. -
  3. 在nsFoo.cpp中加一行用于声明nsFoo类是cycle collection的候选项的语句: -
    NS_IMPL_CYCLE_COLLECTION_CLASS(nsFoo)
    -
  4. -
  5. 在nsFoo的定义里,将写有NS_DECL_ISUPPORTS的行修改为NS_DECL_CYCLE_COLLECTING_ISUPPORTS.
  6. -
  7. -

    在nsFoo的定义里public部分加一行NS_DECL_CYCLE_COLLECTION_CLASS(nsFoo)。如果nsFoo从多个接口继承而来的话,可以写成NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFoo, nsIBar),在你QueryInterface nsFoo为nsISSupports时,nsIBar作为接口返回。(我们把nsIBar称为nsFoo的典型ISupport类型。)

    -
  8. -
  9. 在nsFoo.cpp里接口map处加一行NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsFoo) : -
    NS_INTERFACE_TABLE_HEAD(nsFoo)
    -  NS_INTERFACE_TABLE2(nsFoo,
    -                      nsIBar,
    -                      nsIBaz)
    -  NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsFoo)
    -NS_INTERFACE_MAP_END
    -
    -
  10. -
  11. 在nsFoo.cpp里把NS_IMPL_ADDREF(nsFoo)修改为NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFoo),同样的修改NS_IMPL_RELEASE(nsFoo)NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFoo)。
  12. -
  13. 可以在nsFoo.cpp中添加合适的NS_IMPL_CYCLE_COLLECTION_#宏, #是你类中的成员数量。如果nsFoo包含两个成员变量,mBar和mBaz,我们可以写成NS_IMPL_CYCLE_COLLECTION_2(nsFoo, mBar, mBaz)。
  14. -
- -

你的类可能会比这张图的结构更复杂。例如,你的类可能有好几个nsISupport基类,需要使用一些执行消除歧义的* _AMBIGUOUS宏。或者说你的类拥有复杂的所有权结构,这样简单的NS_IMPL_CYCLE_COLLECTION_N宏就低效了;你可能需要手动的实现helper类的Traverse和Unlink方法。即使是这样的情况,也可以使用NS_IMPL_CYCLE_COLLECTION_TRAVERSE_ {BEGIN,END}和NS_IMPL_CYCLE_COLLECTION_UNLINK_ {BEGIN,END}。可以在一些复杂的类中看到实例,例如content/base/src/nsGenericElement.cpp。 If your class has tearoffs or is being aggregated by other classes it is important to make the tearoff classes or the outer classes participate in cycle collection too, not doing so could lead to the cycle collector trying to collect the objects too soon.

- -

手动的实现Traverse和Unlink方法

- -

每个可能包含循环回收对象的域都需要被传递给cycle collector,以检查通过这些域的循环。

- -

用于Traverse的宏主要是是NS_IMPL_CYCLE_COLLECTION_TRAVERSE:

- -

  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSomeMember)

- -

Unlink同理:

- -

  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSomeMember)

- -

这些宏应当处理各种情况,像指向nsISupports对象的指针或者非nsISupports对象的指针,或者这些指针的数组,当然这些指针都是有引用计数的、被collector记录的指针。

- -

处理JSObject

- -

如果你的类需要保存一个指向JSObject的指针,你需要告知cycle collector。像这样操作:

- -

首先,它必须被保存在JS::Heap<JSObject *>域,假如你的类nsFoo有一个域mSomeObj:

- -
private:
-  ...
-  JS::Heap<JSObject*> mSomeObj;
-  ...
- -

当你在JS对象指针中存了东西时,你需要用mozilla::HoldJSObjects来告诉GC遍历它并保持这个对象的存活:

- -
...
-mSomeObj = ... ;
-mozilla::HoldJSObjects(this);
-...
-
- -

在Unlink方法(或者析构函数)里,需要将对象指针置为空:

- -
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFoo)
-  ...
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSomeMember)
-  ...
-  //如果你的类是wrapper cache:
-  //NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
-
-  tmp->mSomeObj = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
- -

在析构函数里调用

- -
mozilla::DropJSObjects(this);
- -

你需要在Traverse方法列出cycle collector中记录的成员,也就是非JS对象:

- -
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFoo)
-  ...
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSomeMember)
-  ...
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
- -

最后你需要把JS对象加入Trace方法:

- -
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsFoo)
-  //if your class is a wrapper cache:
-  //NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
-
-  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSomeObj)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
- -

如果你的类是一个wrapper cache,可能生成的代码用了NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_#宏而不是NS_IMPL_CYCLE_COLLECTION_#. 这个宏不能定义Trace方法,因此不能列出JS对象;所以你需要向上面那样手动实现Trace和Unlink。

- -

处理 JS::Value fields

- -

 这里说过,一个JS::Value可能引用一个字符串或者对象并且被GC控制。于是我们需要告知cycle collector这种成员变量的存在。这与JSObject相似,但是使用的是NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK宏:

- -
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsFoo)
-  ...
-  NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mSomeJSVal).
-  ...
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.cloneinto/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.cloneinto/index.html deleted file mode 100644 index 0bc55dbf99..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.cloneinto/index.html +++ /dev/null @@ -1,290 +0,0 @@ ---- -title: Components.utils.cloneInto -slug: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.cloneInto -translation_of: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.cloneInto ---- -
- -

该函数为定义在某一作用域中的对象提供了一个安全的、将其结构化克隆到其字作用域中的方法,并返回对克隆对象的引用:

- -
var clonedObject = cloneInto(myObject, targetWindow);
- -

可以将克隆后的对象作为可扩展对象的动态属性引入到特定作用域中,以便运行在该作用域的脚本进行访问:

- -
targetWindow.foo = clonedObject;
- -

通过这种方式,运行在某一作用域中的代码可以和运行在另一作用域中的代码共享对某一对象的访问。

- -

语法

- -
Components.utils.cloneInto(obj, targetScope[, options]);
- -

参数列表

- -
-
obj : object
-
被克隆对象。
-
targetScope : object
-
对象克隆后的容器。
-
options : object
-
该参数为一可选参数。该参数为一拥有以下可选属性的对象:
-
- - - -

返回值

- -

对克隆后的对象的引用。

- -

范例

- -

This add-on script creates an object, clones it into the content window and makes it a property of the content window global:

- -
// add-on script
-
-var addonScriptObject = {"greeting" : "hello from add-on"};
-contentWindow.addonScriptObject = cloneInto(addonScriptObject, contentWindow);
- -

Scripts running in the page can now access the object:

- -
// page script
-
-button.addEventListener("click", function() {
-  console.log(window.addonScriptObject.greeting);     // "hello from add-on"
-}, false);
- -

Of course, you don't have to assign the clone to the window itself: you can assign it to some other object in the target scope:

- -
contentWindow.foo.addonScriptObject = cloneInto(addonScriptObject, contentWindow);
- -

You can also pass it into a function defined in the page script. Suppose the page script defines a function like this:

- -
// page script
-
-function foo(greeting) {
-  console.log("they said: " + greeting.message);
-}
-
- -

The add-on script can define an object, clone it, and pass it into this function:

- -
// add-on script
-
-var addonScriptObject = {"message" : "hello from add-on"};
-contentWindow.foo(cloneInto(addonScriptObject, contentWindow));  // "they said: hello from add-on"
- -

Cloning objects that have functions

- -

If the object to be cloned contains functions, you must pass the {cloneFunctions:true} flag or you'll get an error. If you do pass this flag, then functions in the object are cloned using the same mechanism as that used in Components.utils.exportFunction:

- -
// add-on script
-
-var addonScriptObject = {
-  greetme: function() {
-    alert("hello from add-on");
-  }
-};
-
-contentWindow.addonScriptObject = cloneInto(addonScriptObject,
-                                           contentWindow,
-                                           {cloneFunctions: true});
-
- -
// page script
-
-var test = document.getElementById("test");
-
-test.addEventListener("click", function() {
-  window.addonScriptObject.greetme();
-}, false);
- -

Cloning objects that contain DOM elements

- -

By default, if the object you clone contains objects that are reflected from C++, such as DOM elements, the cloning operation will fail with an error. If you pass the {wrapReflectors:true} flag, then the object you clone is allowed to contain these objects:

- -
// add-on script
-
-var addonScriptObject = {
-  body: contentWindow.document.body
-};
-
-contentWindow.addonScriptObject = cloneInto(addonScriptObject,
-                                           contentWindow,
-                                           {wrapReflectors: true});
- -
// page script
-
-var test = document.getElementById("test");
-
-test.addEventListener("click", function() {
-  console.log(window.addonScriptObject.body.innerHTML);
-}, false);
- -

Access to these objects in the target scope is subject to the normal security checks.

diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.getglobalforobject/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.getglobalforobject/index.html deleted file mode 100644 index a22b49a2d5..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.getglobalforobject/index.html +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Components.utils.getGlobalForObject -slug: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.getGlobalForObject -translation_of: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.getGlobalForObject ---- -

- -

此方法是用于确定与对象关联的全局对象。用于获取创建对象时所处的全局对象, 即在执行创建对象的脚本时使用的全局对象。

- -

语法

- -
var global = Components.utils.getGlobalForObject(obj);
-
- -

参数

- -
-
obj
-
其对应的全局对象将被检索的对象; 非可选参数,必须是对象。
-
- -

例子

- -
var obj = {};
-function foo() { }
-var global = this;
-
-var g1 = Components.utils.getGlobalForObject(foo);
-var g2 = Components.utils.getGlobalForObject(obj);
-// g1 === global, g2 === global, g1 === g2
-
-// In a script in another window
-var global2 = this;
-function bar() { }
-var obj2 = {};
-
-// Then, assuming bar refers to the function defined in that other window:
-var o1 = Components.utils.getGlobalForObject(bar);
-var o2 = Components.utils.getGlobalForObject(obj2);
-// o1 === global2, o2 === global2
-
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/index.html deleted file mode 100644 index cf8ced2678..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/language_bindings/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: 语言绑定 -slug: Mozilla/Tech/XPCOM/Language_Bindings -tags: - - XPCOM - - 'XPCOM:Language Bindings' -translation_of: Mozilla/Tech/XPCOM/Language_Bindings ---- -

一款 XPCOM 的语言绑定是连接某种特定的程序设计语言与 XPCOM 之间的纽带,它用来提供从语言到 XPCOM 对象的访问, 并且将此种语言写成的模块作为其他进行 XPCOM 绑定的程序语言的 XPCOM 对象。 

-

更具体的说, 一个 XPCOM 语言绑定:

- -

由于 XPCOM 层本身使用 C/C++ 编写,因此可以使用 C/C++ 直接访问其 API。而当其它的程序设计语言需要访问该 API 时,则需要通过额外的桥接层来实现。

-

当前有效的链接层如下:

-

-
Components
Components 对象是 XPConnect 功能被映射到 JavaScript 上的对象。Components 对象的 native 实现位置在   nsIXPCComponents , 这个接口会被映射成JavaScript 作为使用 XPConnect 的最高层级的对象。
Components.classes
Components.utils.cloneInto
该函数为定义在某一作用域中的对象提供了一个安全的、将其结构化克隆到其字作用域中的方法,
Components.utils.evalInSandbox
Components.utils.getGlobalForObject
此方法是用于确定与对象关联的全局对象。用于获取创建对象时所处的全局对象, 即在执行创建对象的脚本时使用的全局对象。
-
Components.utils.import
这个方法在 Firefox 3 中被引入,它使得在不同的作用域之间分享代码变得更加容易。例如:你可以直接导入 XPCOMUtils.jsm 而不必复制/粘贴冗长的XPCOM组件。
JavaXPCOM
PyXPCOM
XPConnect
[]
-

diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/index.html deleted file mode 100644 index 6ce4c6a6ba..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: JavaXPCOM -slug: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM -tags: - - Java - - JavaXPCOM -translation_of: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM ---- -

-

JavaXPCOM允许在Java和XPCOM间进行会话,这样一来,Java应用程序就可以访问XPCOM对象,并且XPCOM也可以访问任何实现了XPCOM接口的Java类。借助JavaXPCOM,开发者可以在Java应用程序中同XPCOM或嵌入的Gecko对话。JavaXPCOM和XPConnect(JavaScript-XPCOM桥)十分相似,并且使用XPIDL实现其功能。 -

JavaXPCOM默认地作为XULRunner的一部分被构建。下载最近的编译成品或XULRunner 1.8.0.4进行尝试。 -

- - - - -
-

预览

- -

文章精选

- -

View All... -

-
-

其他页面

- -

相关主题

-
XPCOM, 嵌入式Mozilla -
-

there's no javaxpcom category on webwatch <rss>http://developer.mozilla.org/webwatc...t=23&feed=rss2|short|max=5|charset=UTF-8</rss> <span class="alllinks">View All...</span> -

-
-
-

原始文档信息

- -
-


-

diff --git "a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/\344\275\277\347\224\250javaxpcom\345\234\250java\345\272\224\347\224\250\347\250\213\345\272\217\344\270\255\345\265\214\345\205\245mozilla/index.html" "b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/\344\275\277\347\224\250javaxpcom\345\234\250java\345\272\224\347\224\250\347\250\213\345\272\217\344\270\255\345\265\214\345\205\245mozilla/index.html" deleted file mode 100644 index 9a8e1805fa..0000000000 --- "a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/\344\275\277\347\224\250javaxpcom\345\234\250java\345\272\224\347\224\250\347\250\213\345\272\217\344\270\255\345\265\214\345\205\245mozilla/index.html" +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: 使用JavaXPCOM在Java应用程序中嵌入Mozilla -slug: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM/使用JavaXPCOM在Java应用程序中嵌入Mozilla -tags: - - 'JavaXPCOM:Articles' -translation_of: Archive/Mozilla/Embedding_Mozilla_in_a_Java_Application_using_JavaXPCOM ---- -

-


-XULRunner中包含了JavaXPCOM组件,允许Java代码与XPCOM对象交互。在这片文章中您将会看到,在Java中使用XPCOM对象,要比在C++中容易得多。 -

-

必要条件

- -
-

2006-01-16:XULRunner目前还没有官方发布版本,因此,为了能XULRunner加上JavaXPCOM一起使用,您应该马上下载1.8.0版分支的一个每夜构建。(LinuxMac OS XWindows)。下面提到的MozillaInterfaces.jar文件可以在sdk顶层文件夹中找到。 -

-
-

嵌入

-

为了在Java应用程序中嵌入Mozilla,您需要将库文件MozillaInterfaces.jar加入您的classpath中。这个库(它是SDK的一部分)提供了启动Mozilla和调用XPCOM方法所必需的接口。 -

要开始嵌入,我们使用Mozilla单件类提供的方法。首先,Java应用程序必须找到一个合适的XULRunner安装: -

-
 Mozilla mozilla = Mozilla.getInstance();
- GREVersionRange[] range = new GREVersionRange[1];
- range[0] = new GREVersionRange("1.8.*", false, "1.9", false);
-   // work with trunk nightly version 1.9a1  ^^
-
- try {
-   File grePath = Mozilla.getGREPathWithProperties(range, null);
-   LocationProvider locProvider = new LocationProvider(grePath);
-   mozilla.initEmbedding(grePath, grePath, locProvider);
- } catch (FileNotFoundException e) {
-   // this exception is thrown if greGREPathWithProperties cannot find a GRE
- } catch (XPCOMException e) {
-   // this exception is thrown if initEmbedding failed
- }
-
-

LocationProvider是Java应用程序提供的一个类。它实现了IAppFileLocProvider接口,并且告诉XPCOM那里可以找到那些文件和目录。 -

initEmbedding方法启动嵌入进程,允许Java应用程序与XPCOM和Mozilla一起工作。一旦Java应用程序使用完Mozilla,就需要中止嵌入进程: -

-
 try {
-   mozilla.termEmbedding();
- } catch (XPCOMException e) {
-   // this exception is thrown if termEmbedding failed
- }
-
-

与XPCOM对象一起工作

-

现在,Mozilla已经嵌入了,Java应用程序可以和XPCOM对象工作了。Mozilla类提供了多种方法使工作更加容易,例如getServiceManagergetComponentManager,和newLocalFile。为了在XPCOM对象中增加查询和调用的方法,JavaXPCOM允许Java应用程序传递Java类对象给XPCOM方法。 -

例如: -

-
 Mozilla mozilla = Mozilla.getInstance();
- WindowCreator creator = new WindowCreator();  // implements nsIWindowCreator
-
- nsIServiceManager serviceManager = mozilla.getServiceManager();
-
- nsIWindowWatcher windowWatcher = (nsIWindowWatcher) serviceManager
-   .getServiceManagerByContractID(NS_WINDOWWATCHER_CONTRACTID,
-     nsIWindowWatcher.NS_IWINDOWWATCHER_IID);
- windowWatcher.setWindowCreator(creator);
-
-

在这个例子中,我们有一个叫WindowCreator的类,它实现了nsIWindowCreator接口,我们想要在Mozilla中注册它。要做到这点,我们首先获取服务管理器(service manager),通过它,我们可以获取Mozilla窗口监视器的引用。 -

-
-
diff --git "a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/\345\274\200\345\217\221/index.html" "b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/\345\274\200\345\217\221/index.html" deleted file mode 100644 index d21deddbb6..0000000000 --- "a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/\345\274\200\345\217\221/index.html" +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: 开发 -slug: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM/开发 -tags: - - JavaXPCOM -translation_of: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM/Development ---- -

-

-

简述

-

JavaXPCOM源于Mozilla的Java版firefox计划,后来演变为Mozilla的一项重要的扩展应用技术。目前JavaXPCOM是Mozilla最活跃的扩展应用技术之一。 -简单的说,JavaXPCOM就是通过Java运行环境启动GRE(Gecko Runtime Environment)环境,然后通过Java Interface与GRE typelib的映射关系,使得Java对象可以与XPCOM对象进行对象交互。当然,与XPCOM一样,JavaXPCOM也支持通过XPConnect映射同以xul/js为主体的Mozilla界面环境进行对象交互。 -

-

源代码

-

最新的源代码可以在Mozilla主干上找到,在extensions/java/xpcom目录中。 -

-

构建指令

-

构建指令可以在这里找到:构建JavaXPCOM。 -

-

Bugs

-

所有的JavaXPCOM的bugs都在Bugzilla中被跟踪, 使用"Core"产品和"Java to XPCOM Bridge"组件。 -

- diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/pyxpcom/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/pyxpcom/index.html deleted file mode 100644 index 397d95ff78..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/language_bindings/pyxpcom/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: PyXPCOM -slug: Mozilla/Tech/XPCOM/Language_bindings/PyXPCOM -translation_of: Mozilla/Tech/XPCOM/Language_bindings/PyXPCOM ---- -

 

-
-

PyXPCOM允许在PythonXPCOM之间进行通信,例如Python应用能够访问XPCOM对象,XPCOM能够访问任何实现了XPCOM接口的Python类。使用PyXPCOM一个开发者可以与XPCOM交互或者从一个Python应用中嵌入Gecko。PyXPCOM就类似于JavaXPCOM(Java-XPCOM桥)或者是XPConnect(JavaScript-XPCOM桥)。

-

Python类和接口:Mozilla定义了许多外部接口并允许用于嵌入使用和组件开发。PyXPCOM提供了方法以像Python语言接口那样来访问这些接口。PyXPCOM同时也包含了几个用于提供从Python访问那些初始化及关闭XPCOM和Gecko功能的类,以及一些XPCOM的帮助函数。

-
- - - - - - - -
-

文档

-
-
- 构建 PyXPCOM
-
- PyXPCOM构建指导。
-
-
-
- 创建 Python XPCOM 组件
-
- 如何使用Python创建简单的XPCOM组件的例子。
-
-
-
- PyXPCOM 入门
-
- PyXPCOM是XPCOM与Python之间的一种桥接技术。本节带给你的是PyXPCOM入门级的向导。
-
-

NOTE: The links to Part II and III of this series are broken and I cannot find them on the IBM site. Please update this page if/when the links can be found.

-

View All...

-

历史

-

PyXPCOM was initially developed by ActiveState Tool Corporation, and came out of their Komodo project. Current releases are now integrated with the Mozilla build system.

-

Other Resources
- PythonExt - extension that provides PyXPCOM
- Samples - demo applications using PyXPCOM

-
-

交流

-
- -

源代码

- - -
-
- XPCOM
-
- PyDOM: replace JavaScript with Python
-
- Python-SpiderMonkey
-
-
-

 

diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/xpconnect/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/xpconnect/index.html deleted file mode 100644 index df0270b533..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/language_bindings/xpconnect/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: XPConnect -slug: Mozilla/Tech/XPCOM/Language_bindings/XPConnect -translation_of: Mozilla/Tech/XPCOM/Language_bindings/XPConnect ---- -

XPConnect是JavaScriptXPCOM之间的桥梁。利用XPConnect,你可以通过JavaScript代码使用XPCOM组件,同时让XPCOM组件与JavaScript对象交互。XPConnect是Firefox的组成部分,同时也应用于XUL应用。

- - - - - - - - -
-

文档

- -
-
结构基础
-
XPConnect, JavaScript, XPCOM, XUL...
-
使用组件
-
如何与XPCOM组件通信。
-
XPConnect 和 XPIDL 的常见问题解答
-
关于使用XPConnect和XPIDL的常见问题解答。该页面尚未迁移至MDN。
-
XPConnect Wrappers
-
XPConnect的wrappers的生成和使用
-
- -

XPConnect 脚本安全

-
-

工具

- - -
- -
-
-

加入XPCOM社区

- -
-
选择你喜欢的方式来加入讨论:
- - -
- - -
-
- - diff --git a/files/zh-cn/mozilla/tech/xpcom/observer_notifications/index.html b/files/zh-cn/mozilla/tech/xpcom/observer_notifications/index.html deleted file mode 100644 index 86fdd81a37..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/observer_notifications/index.html +++ /dev/null @@ -1,880 +0,0 @@ ---- -title: Observer Notifications -slug: Mozilla/Tech/XPCOM/Observer_Notifications -translation_of: Mozilla/Tech/XPCOM/Observer_Notifications ---- -

Observer topics

- -

The following are topics that you can observe during the course of an application. Unless otherwise noted you register for the topics using the nsIObserverService.

- -

Application startup

- -

These are the topics that you can observe on startup, in order of appearance.

- -

If your component requires access to the user profile, or any services which require access to the profile (preferences, bookmarks, and so on) then a common pattern is to register with the nsICategoryManager for the app-startup topic which can be done in the component's registration code, and then in that notification register with the observer service for the profile-after-change notification. See Receiving startup notifications for more information about how this works.

- -

Starting in Firefox 3.5 components can simply register for the profile-after-change notification in nsICategoryManager.

- - - - - - - - - - - - -
TopicDescription
* -

Everything.  [nsObserverService.cpp]

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDescription
xpcom-startup -

Note: An extension can no longer be registered to receive this notification in Firefox 4 and later. See XPCOM changes in Gecko 2.0 for details.

- -

Called when xpcom is initialized. Many things are not available for use at this point. To receive this notification you have to register with nsICategoryManager. The registered component is always retrieved as a singleton (That is getService() will be used to instantiate it).

-
app-startup -

Note: An extension can no longer be registered to receive this notification in Firefox 4 and later. See XPCOM changes in Gecko 2.0 for details.

- -

General event for application startup. To receive this notification you have to register with nsICategoryManager. Prepend "service," to the contract ID in the category registration to be invoked via getService() instead of createInstance().

-
profile-do-changeThis is fired after the profile has been selected. You will not be able to access user preferences, bookmarks, or anything that uses the profile folder until this event occurs. This occurs after any profile migration.
profile-after-change -

This is fired after all the observers for profile-do-change have been notified.

- -

You can register with nsICategoryManager to receive this notification. Prior to Firefox 3.5, this was available to observers observing the app-startup/xpcom-startup notification.

-
final-ui-startup -

Triggered just before the first window for the application is displayed.

-
sessionstore-windows-restored -

Sent by the session restore process to indicate that all initial browser windows have opened. Note that while the window are open and the chrome loaded the tabs in the windows may still be being restored after this notification.

- -

Note: This notification is specific to Firefox and SeaMonkey 2.0 applications

-
- -

Application shutdown

- -

These are the topics that you can observe on shutdown, in order of appearance.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDescription
quit-application-requestedSomething has requested that the application be shutdown. You can cancel the shutdown from here by setting aSubject.data to true (aSubject is the first parameter to your observer, the data value is an nsISupportsPRBool).
quit-application-grantedAll observers have agreed to the shutdown.
quit-applicationThe application is about to quit. This can be in response to a normal shutdown, or a restart.
Note: The data value for this notification is either 'shutdown' or 'restart'.
profile-change-net-teardownThe network connection is going offline at this point.
Note: The data value for this notification is either 'shutdown-persist' or 'shutdown-cleanse'.
profile-change-teardownPart of the shutdown, profile data is still available at this point.
Note: The data value for this notification is either 'shutdown-persist' or 'shutdown-cleanse'.
profile-before-changeCalled just before the profile is lost.
Note: The data value for this notification is either 'shutdown-persist' or 'shutdown-cleanse'.
xpcom-will-shutdown Called just before xpcom-shutdown. Observer must not spin event loop.
xpcom-shutdownThis is the end. Many things will not be available here.
- -

Browser

- -

These topics indicate interesting things that happen that the browser alerts you to.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDescription
browser:purge-session-historySent when the sanitizer runs to purge all history and other information.
browser:purge-domain-dataSent after domain-specific history and other information have been purged. The data value is a string form of the domain.
browser-lastwindow-close-requestedSent when the browser wishes to close the last open browser window. When this is sent, it is possible that other windows may still be open, such as the download manager or preferences. The data value is an nsISupportsPRBool. Recipients may set this to true to abort the close.
browser-lastwindow-close-grantedSent when all interested parties have responded to the browser-lastwindow-close-requested notification and none of them requested that the close be aborted. After this is sent and handled, the browser window will close.
browser-delayed-startup-finishedSent when the browser window and all its components have been loaded and initialized.
- -

Documents

- -

These topics indicate notifications you can monitor related to DOM documents.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicSubjectDataDescription
chrome-document-global-created nsIDOMWindownullSent immediately after a chrome document window has been set up, but before any script code has been executed. This lets extensions inject API into chrome windows as needed (see nsIDOMGlobalPropertyInitializer for an alternative method of doing this, which uses significantly less memory).
- data is intentionally left blank.
content-document-global-created nsIDOMWindoworiginSent immediately after a web content document window has been set up, but before any script code has been executed. This lets extensions inject API into content windows as needed (see nsIDOMGlobalPropertyInitializer for an alternative method of doing this).
- data is a string form of the origin (for use in security checks), eg "http://developer.mozilla.org".
document-element-inserted DocumentnullSent immediately after the root element of a document has been created, but before executing any script on it.
user-interaction-active nsIDOMWindownull -

Sent once every 5000ms while this chrome document sees some kind of user activity (for example, keyboard or mouse events), and at the exact moment of the state transition from idle to active.

-
user-interaction-inactive nsIDOMWindownull -

Sent when the chrome document has seen no user activity for a while. The notification is not repeated during a continuous inactivity period.

-
- -

Windows

- -

These topics indicate points of interest during the lifetime of a window.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
dom-window-destroyed  Called just before a DOM window is destroyed.
inner-window-destroyed  nullCalled when an inner window is removed from the backward/forward cache. See Working With BFCache for information about the bfcache, and Inner and outer windows for details about how the window hierarchy works. Extensions that cache information about windows may wish to observe this so they can release information when the window is destroyed.  The window id can be obtained from subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data
outer-window-destroyed nullCalled when an outer window is disconnected from its docshell.  See Inner and outer windows for details about how the window hierarchy works. Extensions that cache information about windows may wish to observe this so they can release information when the window is destroyed.  The window id can be obtained from subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data
toplevel-window-ready Called just after a new top level window has been opened and is ready, but has not yet loaded a document.
xul-window-destroyed Called just before a XUL window is destroyed.
xul-window-registered Called just after a top level XUL window is registered with the window mediator service.
xul-window-visible Called just after a XUL window is made visible.
- -

Spelling checker

- -

These topics indicate activities that have occurred related to the spelling checker.

- - - - - - - - - - - - - - -
TopicDataDescription
spellcheck-dictionary-update Sent by a spell checker implemented by the mozISpellingChecker interface when something has happened that causes a change that may interest the editor; these are received primarily by nsIEditor.
- -

IO Notifications

- -

These topics can be used to watch the IO service for useful information.

- - - - - - - - - - - - - - - - - - - - -
TopicDescription
offline-requestedCalled to query whether the application can go offline. The attempt to go offline can be canceled. -

Note: If your code chooses to cancel the attempt to go offline, it must notify the user.

-
network:offline-about-to-go-offlineCalled just before all network IO is taken offline.
network:offline-status-changedCalled when the offline state has changed.
Note: The data value for this notification 'offline' or 'online' to indicate the new state.
- -

HTTP requests

- -

These are the topics that you can observe during a HTTP request (see Setting HTTP request headers and Creating Sandboxed HTTP Connections). Both are passed an nsIHttpChannel as the subject parameter.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDescription
http-on-modify-requestCalled as a http request is made. The channel is available to allow you to modify headers and such. See this code snippet to learn how to get the tab that issued the request.
http-on-opening-request Similar to http-on-modify-request, but called earlier (synchronously during the channel's asyncOpen() call), and some channel atttributes (proxyInfo) may be missing.  Use only if your observer must be called before asyncOpen returns.
http-on-examine-responseCalled after a response has been received from the web server. Headers are available on the channel. The response can be accessed and modified via nsITraceableChannel.
http-on-examine-cached-response Called instead of http-on-examine-response when a response will be read completely from the cache. Headers are available on the channel.
http-on-examine-merged-responseCalled instead of http-on-examine-response when a response will be read partially from cache, and partially from the network (HTTP 206 or 304 response). Headers are available on the channel.
- -

Cookies

- -

These topics indicate whenever a cookie has been changed (added, changed, cleared, or deleted) or its setting rejected by the browser. See nsICookieService for details.

- - - - - - - - - - - - - - - - -
TopicDescription
cookie-changedCalled upon a cookie change (added, changed, cleared, or deleted)
cookie-rejectedCalled when the setting of a cookie was rejected by the browser (per the user's preferences)
- -

Download Manager

- -

These topics indicate that events related to the Download Manager have occurred.

- - - - - - - - - - - - - - - - -
TopicDescription
download-manager-ui-doneCalled when the list of downloads in the Download Manager windows finishes updating.  This can happen multiple times, such as when the window first opens, when multiple items are removed, and when entering private browsing mode.
download-manager-remove-download Called when a download of the list is removed or all the list is cleared. The subject will be the download id wrapped in nsISupportsPRUint32, for one download removed, or null for multi download remove, for example when the download list is cleared.
- -

Extension Manager

- -
-

Note: These notifications are no longer available starting with Gecko 2.0, instead use AddonManager.addAddonListener() to receive similar events.

-
- -

This topic indicates when the extension manager performs some action. Note that any action will be taken the next time the application starts. See nsIExtensionManager for details.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
em-action-requesteditem-installedA new extension has been installed.
em-action-requesteditem-upgradedA different version of an existing extension has been installed.
em-action-requesteditem-uninstalledAn addon has been marked to be uninstalled.
em-action-requesteditem-enabledAn addon has been enabled.
em-action-requesteditem-disabledAn addon has been disabled.
em-action-requesteditem-cancel-actionA previous action has been cancelled.
- -

Idle Service

- -

This topic indicates when actions related to the Idle Service, provided by the nsIIdleService interface. Unlike the user-interaction-active and user-interaction-inactive topics listed above, the Idle Service monitors user activity in general, whether related to the Mozilla application or not (acting somewhat like the user activity/inactivity events a screen saver would be interested in).

- - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
idleThe length of time the user has been idle, in milliseconds.Sent when the user becomes idle.
idle-dailyThe length of time the user has been idle, in milliseconds.Sent once a day while the user is idle.
backThe length of time the user has been idle, in milliseconds.Sent when the user returns from being idle.
- -

Computer sleep and wake

- -

This topic indicates when actions related to the computer going to sleep or waking up occur.  (Note: these notifications are not currently available on Linux.  See bug 758848.)

- - - - - - - - - - - - - - - - - - - -
TopicDataDescription
sleep_notificationnullSent when the computer is going to sleep.
wake_notificationnullSent when the computer is waking up.
- -

Login Manager

- -

This topic indicates when actions related to the Login Manager occur.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
passwordmgr-found-formnoAutofillFormsA login is available for this form, but autofill of forms is disabled, so the form was not automatically filled out. 
passwordmgr-found-formautocompleteOffA login is available for this form, but autocomplete is disabled.
passwordmgr-storage-changedaddLoginA login has been added to the Login Manager's database. The notification's subject is the login that was added to the database.
passwordmgr-storage-changedremoveLoginA login was removed from the Login Manager's database. The notification's subject is the login that was removed from the database.
passwordmgr-storage-changedmodifyLoginA login in the Login Manager's database was modified. The notification's subject is an array whose first entry is the old login and whose second entry is the new one.
passwordmgr-storage-changedremoveAllLoginsAll logins have been removed from the Login Manager's database.
passwordmgr-storage-changedhostSavingEnabledHost saving has been enabled.
passwordmgr-storage-changedhostSavingDisabledHost saving has been disabled.
- -

Places

- -

This topic indicates when actions related to Places (the history and bookmarks database) occur.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
places-autocomplete-feedback-updated Sent when Places updates the location bar's autocompletion display.
places-connection-closed Sent after Places has closed its database connection. Once this has been sent, no Places features will work.
places-connection-closing  -

Sent as the last notification before the Places service closes its database connection.

- -
Warning: This is for internal use only.
-
places-database-locked The Places database is currently locked by a third-party process and cannot be opened.
places-favicons-expired Sent when all favicons have been expired.
places-init-complete The Places database has been successfully initialized. You should wait until this notification occurs before querying the places database.
places-maintenance-finished Sent when maintenance of the Places database is complete; this is done periodically in the background to keep the Places database tidy.
places-shutdown Sent when Places shuts down. If you are referencing instances of mozIStorageStatement referencing Places databases when this notification occurs, you should call their mozIStorageStatement.finalize() method
places-sync-finished Sent when the Places database has been successfully flushed to disk.
places-will-close-connection  -

Sent when the Places service is about to close its database connection. Only necessary cleanup tasks should run at this point, and nothing should be added to the database. In addition, after this has been sent, no Places APIs should be called.

- -
Warning: This is for internal use only.
-
- -

Session Store

- -

These topics are used when actions related to Session Store occur.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
sessionstore-state-read Sent immediately after session store data is read and before it's used.
sessionstore-state-finalized Sent immediately after the session is restored.
sessionstore-state-write Sent immediately before the session store data is written to disk.
sessionstore-state-write-complete Sent immediately after the session store data is written to disk.
sessionstore-state-purge-complete  
- -

Private browsing

- -

These topics indicate when actions related to private browsing occur.

- - - - - - - - - - - - - - - - - - - -
TopicDataDescription
private-browsingenterSent when private browsing mode is activated.
private-browsingexitSent when private browsing mode is deactivated.
- -

Bookmarks

- -

These topics indicate when actions related to bookmarks occur.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
bookmarks-restore-beginjsonSent just before bookmarks are restored from JSON.
bookmarks-restore-beginhtmlSent just before bookmarks are restored from HTML. If bookmarks will be restored into a specific folder, observers will be passed an nsISupportsPRInt64 through their subject parameters indicating the ID of the folder. The subject is null otherwise.
bookmarks-restore-beginhtml-initialSent just before bookmarks are restored from HTML on initial import. If bookmarks are restored into a specific folder, observers will be passed an nsISupportsPRInt64 through their subject parameters indicating the ID of the folder. The subject is null otherwise.
bookmarks-restore-successjsonSent just after bookmarks are restored from JSON.
bookmarks-restore-successhtmlSent just after bookmarks are restored from HTML. If bookmarks were restored into a specific folder, observers will be passed an nsISupportsPRInt64 through their subject parameters indicating the ID of the folder. The subject is null otherwise.
bookmarks-restore-successhtml-initialSent just after bookmarks are restored from HTML on initial import. If bookmarks were restored into a specific folder, observers will be passed an nsISupportsPRInt64 through their subject parameters indicating the ID of the folder. The subject is null otherwise.
bookmarks-restore-failedjsonSent when bookmarks could not be sucessfully restored from JSON.
bookmarks-restore-failedhtmlSent when bookmarks could not be successfully restored from HTML. If bookmarks were to have been restored into a specific folder, observers will be passed an nsISupportsPRInt64 through their subject parameters indicating the ID of the folder. The subject is null otherwise.
bookmarks-restore-failedhtml-initialSent when bookmarks could not be successfully restored from HTML on intial import. If bookmarks were to have been restored into a specific folder, observers will be passed an nsISupportsPRInt64 through their subject parameters indicating the ID of the folder. The subject is null otherwise.
- -

Themes

- -

These topics indicate when actions related to themes occur.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
lightweight-theme-preview-requested jsonSent when the user requests to preview a lightweight theme, but before existing windows are styled with the new theme.
lightweight-theme-change-requested jsonSent to indicate that the user has chosen a new theme in the add-ons manager, but before the change takes effect.
lightweight-theme-changed -Sent after the current theme is changed.
lightweight-theme-styling-update jsonSent when the current theme being used is changed; this is sent even when the user is previewing a theme, not just when the theme is actually selected.
lightweight-theme-list-changed -The list of available lightweight themes has changed.
- -

Developer tools

- -

These topics let you know about things that have happened related to Firefox's built-in developer tools.

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TopicDataDescription
highlighter-ready - -

Sent when the highlighter component is initialized.

- -
Note: This is used by the Inspector to detect when it should begin its initialization process.
-
inspector-closed -Sent when the Inspector tool is closed.
inspector-editor-closed -Sent after the attribute-value editor has been closed.
inspector-editor-opened -Sent after the attribute-value editor has been opened and initialized.
inspector-editor-saved -Sent when changes have been saved in the attribute-value editor.
inspector-highlighting -Sent every time a different node in the page gets highlighted.
inspector-opened -Sent after the Inspector tool has finished its initialization.
inspector-ruleview-ready -Sent when the inspector's CSS Rule View is opened and initialized.
inspector-state-restored -Sent when the Inspector is re-opened after a tab switch.
inspector-treepanel-ready -Sent when the Inspector's Tree Panel is opened and initialized.
inspector-unhighlighting -Sent every time the highlighter stops highlighting a node.
- -

Telemetry

- - - - - - - - - - - - - - -
TopicDataDescription
gather-telemetry -Sent by the telemetry service when it's time to start gathering telemetry data, since the telemetry ping is coming soon.
- -

Plugins

- - - - - - - - - - - - - - -
TopicDataDescription
plugin-crashed-Sent when a plugin has crashed.
- -

 

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/index.html deleted file mode 100644 index 92f0a47369..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: XPCOM glue classes -slug: Mozilla/Tech/XPCOM/Reference/Glue_classes -tags: - - Classes - - Landing - - NeedsTranslation - - TopicStub - - XPCOM -translation_of: Mozilla/Tech/XPCOM/Reference/Glue_classes ---- -

These "glue" classes are provided to make it easier to use XPCOM from C++ code. When these classes are used by a component, you may need to link the component against the XPCOM glue library.

-

-
-
使用nsCOMPtr
这篇文档是对nsCOMPtr的一个总述。如果您所遇到的问题,无法在该文档中找到答案,可能就没有其他文档可以回答它了。您需要求助于XPCOM新闻组或者有nsCOMPtr使用经验的人来求解,或者根据自己的试验获取答案。
-

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/getting_started_guide/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/getting_started_guide/index.html deleted file mode 100644 index 32dedcf102..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/getting_started_guide/index.html +++ /dev/null @@ -1,478 +0,0 @@ ---- -title: 入门指南 -slug: Mozilla/Tech/XPCOM/Reference/Glue_classes/nsCOMPtr/Getting_Started_Guide -translation_of: Mozilla/Tech/XPCOM/Using_nsCOMPtr/Getting_Started_Guide ---- -

下面开始探讨智能指针问题。

-

介绍

-

什么是 nsCOMPtr?

-

nsCOMPtr 是防止内存泄漏的一种工具。

-

nsCOMPtr 是一种智能指针。 它是一个模板类,在使用上类似C/C++中的普通指针。如:可使用*或者->得到其所指定的内容。nsCOMPtr之所以智能,是因为它不像一般指向XPCOM对象的指针,nsCOMPtr还管理AddRef, Release, 和QueryInterface方法。 nsCOMPtr是在以下源文件中定义的:

- -

...though you probably don't want to look in there, just yet.

-

利用nsCOMPtr,比使用原始的XPCOM接口指针,能够把代码写的更简短,更清晰,更明白,更安全。

-

[XP]COM Basics: Ownership and Reference Counting

-

这段是对XPCOM的一些基本问题的一个复习。对nsCOMPtrs的理解,需要对XPCOM有一个基本的认识。您可通过以下方式对XPCOM进行学习。Don BoxEssential COM 介绍了COM的基本规则和使用。 Don Box 在 Effective COM.一书中更详尽的说明了COM的细节,缺陷和易犯的错误。您还需要对C++有基本的了解。这里列举三本比较有用的书:Bjarne Stroustrup 的 The C++ Programming Language,Scott Meyers 的 Effective C++More Effective C++

-

All XPCOM objects are allocated on the heap. Clients don't get to know much about the implementation of any such object. They reference it only through a pointer to an `interface', i.e., the static type of the pointer is a pointer to an abstract base class, the actual object pointed to is a class derived from that abstract base class. The XPCOM object is said to `implement that interface'. The client's reference to the object is typically called `an interface pointer'.

-

An object may implement many interfaces. Each interface is (at least conceptually) separately `reference counted'. That is, the interface keeps a count of the number of clients holding references to it. When that count goes to zero, the interface may delete itself. Clients are expected to keep this reference count accurate by incrementing it when they acquire a reference to the interface, and decrementing it before they let go. To facilitate this, all interfaces inherit from an abstract base class that provides the member functions AddRef, and Release.

-

A rule of XPCOM is that any function that creates or returns an interface pointer will have already AddRefed it. The caller can then hold onto the reference indefinitely, calling Release when it no longer needs it. When the last pointer to an interface is Released, the interface (and consequently, typically the underlying object) will delete itself. As long as there is an outstanding AddRef against the interface, it continues to exist. If you forget to call Release, the object will leak, i.e., the storage for that object will never be reclaimed. Leaks are bad :-).

-

A reference through which you will call AddRef and Release is called an owning reference. It holds a stake in the underlying object. That object cannot go away until the owning reference has relinquished its claim. Not all references need to be owning references. In fact, if two objects somehow end up owning each other (even transitively) it becomes difficult for either of those object to be reclaimed without adding some `out-of-band' mechanism for breaking the ownership cycle. The document Some COM Ownership Guidelines provides some hints on when ownership is needed. The following lists are good starting point, but by no means complete.

-

You use an owning reference when

- -

You don't need an owning reference when

- -

It turns out that reference counting by hand is hard for programmers to get right. It may sound simple, but in practice it's very easy to forget to Release at the appropriate moment. Or to AddRef too many or too few times.

-

How does nsCOMPtr help?

-

nsCOMPtr manages AddRef, Release, and other red-tape for you. An nsCOMPtr looks and acts as much like a raw XPCOM interface pointer as C allows, but it knows it owns the object it points to. This takes a little getting used to on your part, but ends up with less typing, clearer, safer code, and less leaks.

-

For instance, here is a typical snippet of code (at its most compact) where you assign a XPCOM interface pointer into a member variable, i.e., the body of a `setter' function, side-by-side using raw XPCOM interface pointers and nsCOMPtrs. 

-

对照1.设置成员变量。

-

 

- - - - - - - - -
-  
-
-// raw [XP]COM interface pointers...
-// given: |nsIFoo* mFooPtr;|
-
-/*
-   |AddRef| the new value if it's not
-   |NULL|; assign it in; and |Release|
-   the old value, if any (so we don't
-   leak it).
-
-   This order of assignment is special
-   and must be used to avoid particular
-   ownership bugs.
- */
-
-NS_IF_ADDREF(aFooPtr);
-nsIFoo* temp = mFooPtr;
-mFooPtr = aFooPtr;
-NS_IF_RELEASE(temp);
-
-
-
-// |nsCOMPtr|...
-// given: |nsCOMPtr<nsIFoo> mFooPtr;|
-
-/*
-   This assignment automatically
-   |Release|s the old value in
-   |mFooPtr|, if any, and |AddRef|s the
-   new one, in the appropriate sequence
-   to avoid the ownership bug mentioned
-   earlier.
- */
-
-
-
-
-
-mFooPtr = aFooPtr;
-
-
-
-

Additionally, the class using raw XPCOM interface pointers will need a destructor to Release mFooPtr; and a constructor to ensure that mFooPtr is initially set to NULL (or some other reasonable value).

-

nsCOMPtr helps you write code that is leak-proof, exception safe, and significantly less verbose than you would with raw XPCOM interface pointers. With nsCOMPtr, you may never have to call AddRef, Release, or QueryInterface by hand.

-

You still have to understand XPCOM. You still have to know which functions return interface pointers that have already been AddRefed and which don't. You still have to ensure your program logic doesn't produce circularly referencing garbage. nsCOMPtr is not a panacea. It is, however, helpful, easy to use, well-tested, and polite. It doesn't require that a function author cooperate with you, nor does your use force others to use it.

-

使用nsCOMPtr

-

The Basics

-

多数情况下,使用nsCOMPtr和一个一般的XPCOM接口指针是类似的。注意在声明中的细微区别。

- - - - - - - - -
- 对照 2. 相似点: nsCOMPtr类似于 XPCOM接口指针
-
-// raw [XP]COM interface pointers...
-
-nsIFoo* fooPtr = 0;
- // ...
-fooPtr->SomeFunction(x, y, z);
-AnotherFunction(fooPtr);
-
-if ( fooPtr )
-  // ...
-
-if ( fooPtr == foo2Ptr )
-  // ...
-
-
-
-// |nsCOMPtr|...
-
-nsCOMPtr<nsIFoo> fooPtr;
-// ...
-fooPtr->SomeFunction(x, y, z);
-AnotherFunction(fooPtr);
-
-if ( fooPtr )
-  // ...
-
-if ( fooPtr == foo2Ptr )
-  // ...
-
-
-

 

-

有两点主要区别。第一:不需要也不再允许调用AddRefRelease方法。 

- - - - - - - - -
- 对照 3. 不同点: AddRef Release 对于 nsCOMPtrs 来说是非法的。
-
-// raw [XP]COM interface pointers...
-// given: |nsIFoo* mFooPtr;|
-
-  /*
-    Note: this sequence is not the
-    correct order to do assign
-    raw pointers anyway (see
-    {{ Anch("Comparison 1") }}) but I need it
-    for this comparison.
-  */
-
-NS_IF_RELEASE(mFooPtr);
-
-mFooPtr = aFooPtr;
-NS_IF_ADDREF(mFooPtr);
-
-
-
-
-// |nsCOMPtr|...
-// given: |nsCOMPtr<nsIFoo> mFooPtr;|
-
-  /*
-    You no longer need, nor will the
-    compiler let you, call |AddRef|,
-    or |Release|.
-  */
-
-
-
-NS_IF_RELEASE(mFooPtr);
-  // Error: |Release| is private
-mFooPtr = aFooPtr;
-NS_IF_ADDREF(mFooPtr);
-  // Error: |AddRef| is private
-
-
-

 

-

第二:使用 getter_AddRefs 标识nsCOMPtr,作为获取指针返回值的函数的参数,而不能只使用nsCOMPtr的地址作为参数。

- - - - - - - - -
- 对照 4. 不同点: nsCOMPtr 作为输出参数时,使用 getter_AddRefs。
-
-// raw [XP]COM interface pointers...
-
-nsIFoo* foo;
-
-GetFoo(&foo);
-
-
-
-// |nsCOMPtr|s...
-
-nsCOMPtr<nsIFoo> foo;
-
-GetFoo(getter_AddRefs(foo));
-
-
-

 

-

以上是对nsCOMPtrS的一些说明,基本涵盖了平日使用的90%。以下是在一些复杂情况下,对其的细节说明。

-

 

-

一些细节

-

 

-

以下是更多细节让您更了解 nsCOMPtr

-

通常,通过调用 QueryInterface 获取接口指针 QueryInterface 是一个 getter 函数,由以上方法,可通过 getter_AddRefs 方法来获取。

- - - - - - - -
- The hard way to QueryInterface into an nsCOMPtr.
-
-// A way (though not the best way) to |QueryInterface| into an |nsCOMPtr|...
-
-nsCOMPtr<nsIFoo> foo;
-
-nsresult rv = bar->QueryInterface(NS_GET_IID(nsIFoo), getter_AddRefs(foo));
-
-  // Or, if you're a savvy [XP]COM programmer,
-  //  you use the type-safe version...
-nsresult rv = CallQueryInterface(bar, getter_AddRefs(foo));
-
-
-

因为 QueryInterface 使用频繁,nsCOMPtr 提供了一种特殊方式对其调用。这种方式是类型安全的,QueryInterface的返回值能直接构造nsCOMPtr。这种构造方式比通过赋值进行构造效率更高。这种方式是 do_QueryInterface 。通过使用这种方式,以上例子可写为:

- - - - - - - -
- How to QueryInterface into an nsCOMPtr.
-
-// The best way to |QueryInterface| into an |nsCOMPtr|...
-
-nsresult rv;
-nsCOMPtr<nsIFoo> foo( do_QueryInterface(bar, &rv) );
-
-  // Or, if you don't care about the |nsresult|
-nsCOMPtr<nsIFoo> foo( do_QueryInterface(bar) );
-
-
-

nsCOMPtr happily calls AddRef and Release implicitly. This same favor is not extended to QueryInterface. nsCOMPtr does not QueryInterface on assignment without your explicit permission in the form of the do_QueryInterface directive. You need never worry about hidden queries. However, be aware that if you should have queried but didn't, e.g., when assigning in a raw pointer where C allows the assignment, but XPCOM wouldn't, nsCOMPtr will assert at runtime. Use do_QueryInterface whenever you assign in a pointer to a XPCOM interface of a different type, even if that type happens to derive from the base type of the nsCOMPtr

-

 

- - - - - - - - -
- 对照6. do_QueryInterface 避免了XPCOM 中的类型错误。
-
-class nsIBar
-  : public nsIFoo ... { ... };
-
-nsIBar* p = ...;
-
-  // C   thinks every |nsIBar*| is an
-  //  |nsIFoo*|, therefore, C   allows
-  //  this...
-nsCOMPtr<nsIFoo> foo = p;
-  //  ...even though it is an [XP]COM
-  //  type error
-
-
-
-class nsIBar
-  : public nsIFoo ... { ... };
-
-nsIBar* p = ...;
-
-
-
-  // No type error here...
-nsCOMPtr<nsIFoo> foo( do_QueryInterface(p) );
-
-
-
-
-

Remember, the C type system and the XPCOM type system are really two independent things. Because XPCOM interfaces are expressed as abstract C base classes, you may be tempted to let C handle the differences, or to use C casts to navigate between interface types. This is wrong. The only sanctioned way to get between XPCOM types is with QueryInterface. In the example above, there is no reason to assume that the nsIFoo* C pulls out of p would be the same one that p->QueryInterface() would return.

-

dont_AddRef is a similar directive that helps you when you assign in a pointer that has already been AddRefed, e.g., because you called a getter that returned the pointer as its function result.

- - - - - - - -
- Using dont_AddRef.
-
-nsCOMPtr<nsIFoo> foo( dont_AddRef(CreateFoo()) );
-  // |CreateFoo| |AddRef|s its result, as all good getters do
-
-
-

Something nsCOMPtr Doesn't Do

-

An nsCOMPtr does all that is necessary to behave as an owning reference. A given nsCOMPtr does not, however, cooperate in making other owning pointers. After learning how nsCOMPtr automatically AddRefs a pointer as it is being assigned in, the natural assumption is that it does the same thing when assigning out. Here is a snippet of code that demonstrates this misconception.

- - - - - - -
-
-// Incorrect assumptions about |nsCOMPtr|...
-
-nsresult
-nsCacheRecord::GetFileSpec( nsIFileSpec** aFileSpecResult )
-    /*
-      ...fills in the callers |nsFileSpec*| (which the caller supplied
-      the address of) with a copy of my member variable |mFileSpec|,
-      an |nsCOMPtr|.  I.e., this function is a `getter'.
-
-      Remember: good [XP]COM getters always |AddRef| their result.
-    */
-  {
-    // ...
-    *aFileSpec = mFileSpec;
-      // the |nsCOMPtr| should take care of the refcount here, right?
-    return NS_OK;
-  }
-
-
-

Plainly, the author believed (though perhaps with some question) that the nsCOMPtr, mFileSpec, would AddRef automatically as it was assigned into *aFileSpec. This is not the case. An nsCOMPtr automatically calls AddRef and Release (only) on its own behalf. In all other situations, it is designed to be a drop in replacement for a raw XPCOM pointer. Where ever an nsCOMPtr is used in a situation where a raw pointer is needed, the nsCOMPtr automatically provides one.

- - - - - - -
-
-// |nsCOMPtr| produces a raw pointer when needed...
-
-nsCOMPtr<nsIFoo> foo = ...;
-
-  // 1.  Assigning into a raw pointer
-nsIFoo* raw_foo = foo;
-
-  // 2.  Assigning into another |nsCOMPtr|
-nsCOMPtr<nsIFoo> foo2 = foo;
-
-  // 3.  As a parameter
-SetFoo(foo);
-
-  // 4.  Testing the value in an |if| expression
-  // 5.  Calling a member function
-if ( foo )
-  foo->DoSomething();
-
-
-

In all of these cases, pretty much the exact same code is executed (case 2 is slightly different, but the intent is the same). In each case, you are essentially extracting the raw pointer value for your own purpose. If the nsCOMPtr AddRefed the value each time you did that, cases 4 and 5 would obviously always generate leaks. SetFoo, from case 3, would have to be written two different ways when given an nsCOMPtr, it would know the value was already AddRefed, and when given a raw pointer it would assume the value was not AddRefed. Actually the contradictions run deeper than that. All these cases show that automatically AddRefing on `output' makes nsCOMPtrs and raw-pointers act differently from the point of view of the clients. The goal is to make them act the same so that nsCOMPtrs can be a drop in replacement (modulo managing its own `ownership').

-

Given what you now know, the rule is predictable. As described above, and unless you tell it otherwise, an nsCOMPtr AddRefs when you assign in to it. It does nothing when you assign out of it.

-

Where should I use nsCOMPtrs?

-

You should use an nsCOMPtr any place you use an interface pointer as an owning reference, i.e., where you call AddRef and Release on it. You should use nsCOMPtr as a member variable, where it will simplify setters, and eliminate constructors, destructors, and assignment operators. You should use nsCOMPtr on the stack, where it makes calling QueryInterface almost pleasant, and eliminates the complex logic that falls out of error handling.

-

Where shouldn't I use nsCOMPtrs?

-

Don't use nsCOMPtrs where you don't need an owning reference. See Some COM Ownership Guidelines. nsCOMPtr is designed to be used with XPCOM interfaces, so don't use it with non-interfaces with specific exceptions described below. Don't use nsCOMPtrs in XPCOM interfaces. Don't use them in plain old C code; nsCOMPtrs are, of course, a C only construct. Never cast an nsCOMPtr, it's almost guaranteed to leak.

-

nsCOMPtrs for non-interface classes

-

Appropriately formatted answer to come, in the meanwhile, the full details are available in this news posting (via Google Groups).

-

nsCOMPtrs in function signatures

-

In general, you won't want to use nsCOMPtr in the signature of XPCOM (i.e., `scriptable') functions. nsCOMPtr is not currently directly supported by IDL. However, you may sometime be tempted to use an nsCOMPtr in a non-scriptable function.

-
nsCOMPtr<T> f() 不返回 nsCOMPtr
-

This practice is dangerous. Returning an AddRefed pointer in almost any form as a function result leads to several potential errors, some of which are leaks, some of which are dangling pointers. Returning an nsCOMPtr may seem like a good idea (since it tells clients you are giving them ownership), however it can be the cause of an dangling pointer. Consider:

- - - - - - -
-
-// Don't return |nsCOMPtr|s...
-nsCOMPtr<nsIFoo> CreateFoo();
-// ...
-
-nsIFoo* myFoo = CreateFoo(); // Oops: |myFoo| now dangles!
-  // |CreateFoo| returns an |nsCOMPtr|, which
-  //  automatically |Release|s right after this
-  //  assignment.  Now |myFoo| refers to a
-  //  deleted object.
-
-
-

You can tell callers you are giving them ownership in a way that doesn't pose this hazard by returning a already_AddRefed<T> (see bug #59212). An nsCOMPtr knows not to AddRef a value that is already_AddRefed.

- - - - - - -
-
-// Preferred form: if you must return a pointer, use |already_AddRefed|...
-already_AddRefed<nsIFoo> CreateFoo();
-// ...
-
-nsIFoo* myFoo1 = CreateFoo(); // doesn't dangle
-nsCOMPtr<nsIFoo> myFoo2( CreateFoo() ); // doesn't leak
-nsCOMPtr<nsIFoo> myFoo3( dont_AddRef(CreateFoo()) ); // redundant, but legal and correct
-
-
-

Compare this to the most frequent leaks caused by returning a raw pointer you have already AddRefed:

- - - - - - -
-
-// Don't return raw pointers; that incites leaks...
-nsIFoo* CreateFoo(); // returns an |AddRef|ed pointer
-// ...
-
-nsCOMPtr<nsIFoo> myFoo = CreateFoo(); // Oops: leak;
-nsCOMPtr<nsIFoo> myFoo( dont_AddRef(CreateFoo()) );
-  // Since |CreateFoo| already |AddRef|s its result, we must remind
-  //  our |nsCOMPtr| not to.  It's easy to forget.  Prevent it in advance
-  //  by not returning pointers as function results, or else by returning
-  //  an |already_AddRefed<T>| as above.
-
-
-
void f( nsCOMPtr<T> ) don't pass an nsCOMPtr by value
-

This practice is wasteful, but not otherwise harmful. There is no need to AddRef parameters, as they are guaranteed to live as long as the function call. You only need to AddRef them as you store them in a structure that will live longer than the function call. Which means the appropriate member of that structure should be an nsCOMPtr, not the function parameter. Additionally, this signature may confuse callers into thinking they need an nsCOMPtr just to call the function.

-
void f( const nsCOMPtr<T>& ) don't pass an nsCOMPtr by const reference
-

Exactly as the signature above, this practice is wasteful, but not otherwise harmful, and has the same impact as passing an nsCOMPtr by value if the caller only supplied a raw pointer.

-
void f( nsCOMPtr<T>* ) avoid passing an nsCOMPtr by address, if possible
-

This practice requires callers to have an nsCOMPtr, and requires them to do a little extra work, as operator& for nsCOMPtrs is private (to help prevent leaks caused by casting; also see {{ Bug(59414) }}). This is an acceptable way to declare `in/out' parameters, but prefer passing nsCOMPtrs by reference, as below.

- - - - - - -
-
-// Passing an |nsCOMPtr| by pointer requires extra work...
-void f( nsCOMPtr<nsIFoo>* );
-// ...
-
-nsCOMPtr<nsIFoo> myFoo = ...;
-
-f( address_of(myFoo) );
-
-
-
void f( nsCOMPtr<T>& ) do pass an nsCOMPtr by reference for `in/out' parameters
-

This is the prefered scheme for providing `in/out' parameters. If you were to use a raw pointer instead, your function couldn't know what ownership relationship the caller had to the input value, and hence, couldn't know whether to Release it or not before assigning in the new value. By declaring the parameter as an nsCOMPtr&, the relationship is explicit.

-

Summary

-

An nsCOMPtr is an owning reference. Whatever it points to has been AddRefed, counting the nsCOMPtr as one of its `owners'. An nsCOMPtr always calls Release before letting go, whether the nsCOMPtr is letting go so that it can point to a different object, or because the nsCOMPtr is going out of scope. Any time a new value is assigned into an nsCOMPtr, the nsCOMPtr automatically always Releases its old referent, if any, and (unless you tell it you already have) AddRefs the new.

-

You use an nsCOMPtr exactly as you would a raw XPCOM interface pointer in almost all cases. You won't have to explictly call AddRef or Release through it, nor will the compiler allow it. The only place you can't use an nsCOMPtr without change is where a raw XPCOM interface pointer is an `out' parameter. In this case, you wrap the nsCOMPtr with getter_AddRefs (see {{ web.link("#Comparison_4", "Comparison 4") }}).

-

When assigning into an nsCOMPtr, you will usually just supply another pointer (either a raw XPCOM interface pointer or an nsCOMPtr), with no additional directives { web.link("#Comparison_1", "Comparison 1") }}). As stated above, with no directives, the nsCOMPtr will Release its old referent, if any, and AddRef the new. This is appropriate when the thing you're assigning in hasn't yet been AddRefed to account for the new reference. This is typically the case when you are assigning in a pointer that you didn't call a function to get, e.g., one that was passed in as a parameter, or that you pulled out of a structure.

-

You can tell nsCOMPtr it doesn't need to AddRef the new value on assignment by wrapping the new value in dont_AddRef. Do this, for example, when you got the new value from a function which, like all good XPCOM getters, already called AddRef on your behalf.

-

You may not assign in a pointer to a different interface type; you must first query it to the right type (see, e.g., {{ web.link("#Comparison_6", "Comparison 6") }} and the surrounding discussion). nsCOMPtr never calls QueryInterface implicitly, i.e., you must call it yourself, or explictly ask nsCOMPtr to call it with do_QueryInterface. The do_QueryInterface directive allows you to do the query as part of the assignment. This better facilitates constructing an nsCOMPtr directly from the right value, rather than constructing it and assigning in the correct value later. Construction alone is more efficient than construction followed by assignment. Prefer construction over assignment whereever reasonable. Be careful not to apply do_QueryInterface to a function returning an AddRefed pointer [see this short section for an explanation]

-

For more details, continue on to the Reference Manual.

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/index.html deleted file mode 100644 index d9c427784a..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: 使用nsCOMPtr -slug: Mozilla/Tech/XPCOM/Reference/Glue_classes/nsCOMPtr -translation_of: Mozilla/Tech/XPCOM/Reference/Glue_classes/nsCOMPtr ---- -

这篇文档是对nsCOMPtr的一个总述。如果您所遇到的问题,无法在该文档中找到答案,可能就没有其他文档可以回答它了。您需要求助于XPCOM新闻组或者有nsCOMPtr使用经验的人来求解,或者根据自己的试验获取答案。

- -

如果您尚未使用过nsCOMPtr,您正好可从这里开始。当您使用了一段时间后,或者遇到了不熟悉的领域,或者出现编译错误,您可返回该文档,在参考手册或者FAQ中求助。

- -

内容

- -
    -
  1. 状态,最新修改和计划 - -
      -
    1. nsCOMPtr的最新修改
    2. -
    -
  2. -
  3. 入门指南 -
      -
    1. 介绍
    2. -
    3. 使用 nsCOMPtr
    4. -
    5. 小结
    6. -
    -
  4. -
  5. 参考手册 -
      -
    1. 基本原理
    2. -
    3. 初始化和赋值
    4. -
    5. Using an nsCOMPtr<T> as a T*
    6. -
    7. Efficiency and Correctness
    8. -
    9. Compiler Annoyances
    10. -
    -
  6. -
  7. FAQ -
      -
    1. 编译时错误
    2. -
    3. 运行时错误
    4. -
    5. How do I...
    6. -
    7. General
    8. -
    9. Bibliography
    10. -
    -
  8. -
- -
-

Original Document Information

- - -
- -

 

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/index.html deleted file mode 100644 index 188a822ae6..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/index.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: XPCOM reference -slug: Mozilla/Tech/XPCOM/Reference -translation_of: Mozilla/Tech/XPCOM/Reference ---- -

This reference describes the interfaces and functions provided by the XPCOM library. In addition, it details the various helper classes and functions, as well as the components, provided by the XPCOM glue library. The contents herein are oriented primarily toward extension developers and people embedding XPCOM in other projects.

-
-

Note: If you're working on a module in the Mozilla codebase that's compiled with the MOZILLA_INTERNAL_API flag set, some of these APIs -- the string functions and classes in particular -- are not the ones you should be using. See the XPCOM internal string guide for documentation of the internal string API used within the Mozilla codebase.

-
-

-
XPCOM glue classes
These "glue" classes are provided to make it easier to use XPCOM from C++ code.
XPCOM Interface Reference
这是一个Mozilla平台提供XPCOM接口参考.
-
-

-

Many XPCOM pages return an nsresult. Prior to Gecko 19 (Firefox 19 / Thunderbird 19 / SeaMonkey 2.16), this was an integer that simply returned an error code. It is now a strongly typed enum when XPCOM is built using a C++11 compiler. This causes compile-time errors to occur when improper values are returned as nsresult values, thereby making it easier to catch many bugs.

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/index.html deleted file mode 100644 index da50238f6f..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/index.html +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: XPCOM Interface Reference -slug: Mozilla/Tech/XPCOM/Reference/Interface -translation_of: Mozilla/Tech/XPCOM/Reference/Interface ---- -

这是一个Mozilla平台提供XPCOM接口参考.

-
-

相关链接

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiaccessibleprovider/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiaccessibleprovider/index.html deleted file mode 100644 index 488e504556..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiaccessibleprovider/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: nsIAccessibleProvider -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIAccessibleProvider -tags: - - Accessibility - - Interfaces -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIAccessibleProvider ---- -

 

-


-

-
accessible/public/nsIAccessibleProvider.idl脚本化
- - -Please add a summary to this article. - - -
-  -最后修改于Gecko 1.9 (Firefox 3)
-

-

Inherits from: nsISupports

-

Attributes

- - - - - - - - - - - - - -
AttributeTypeDescription
accessiblensIAccessibleReturns an accessible. - - Read only -
-

See also

- diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboard/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboard/index.html deleted file mode 100644 index a1778f2cbb..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboard/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: nsIClipboard -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboard -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboard ---- -

-
widget/public/nsIClipboard.idl脚本化
- - -This interface supports basic clipboard operations such as: setting, retrieving, emptying, matching and supporting clipboard data. - - -
-继承于: nsISupports -最后修改于Gecko 1.8 (Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0)
-

-

方法概述

- -
void emptyClipboard(in long aWhichClipboard);
void forceDataToClipboard(in long aWhichClipboard); 已废弃 Gecko 1.8
void getData(in nsITransferable aTransferable, in long aWhichClipboard);
boolean hasDataMatchingFlavors([array, size_is(aLength)] in string aFlavorList, in unsigned long aLength, in long aWhichClipboard);
void setData(in nsITransferable aTransferable, in nsIClipboardOwner anOwner, in long aWhichClipboard);
boolean supportsSelectionClipboard();
-

常量

-

Most users will expect clipboard operations to use the global clipboard. In fact, the kSelectionClipboard is peculiar to the X Windows System, and not used much even under X.

- -
常量名称 描述
kSelectionClipboard 0 Clipboard for selection.
kGlobalClipboard 1 Clipboard for global use.
-

方法

-

emptyClipboard()

-

This method empties the clipboard and notifies the clipboard owner. It empties the "logical" clipboard. It does not clear the native clipboard.

-
void emptyClipboard(
-  in long aWhichClipboard
-);
-
-
参数
-
aWhichClipboard
Specifies the clipboard to which this operation applies.
-
-

-

forceDataToClipboard()

- 已废弃 Gecko 1.8 (Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0) -

-

Some platforms support deferred notification for putting data on the clipboard This method forces the data onto the clipboard in its various formats This may be used if the application going away.

-
void forceDataToClipboard(
-  in long aWhichClipboard
-);
-
-
参数
-
aWhichClipboard
Specifies the clipboard to which this operation applies.
-
-

getData()

-

This method retrieves data from the clipboard into a transferable.

-
void getData(
-  in nsITransferable aTransferable,
-  in long aWhichClipboard
-);
-
-
参数
-
aTransferable
The transferable to receive data from the clipboard.
aWhichClipboard
Specifies the clipboard to which this operation applies.
-
-

hasDataMatchingFlavors()

-

This method provides a way to give correct UI feedback about, for instance, whether a paste should be allowed. It does not actually retrieve the data and should be a very inexpensive call. All it does is check if there is data on the clipboard matching any of the flavors in the given list.

-
boolean hasDataMatchingFlavors(
-  [array, size_is(aLength)] in string aFlavorList,
-  in unsigned long aLength,
-  in long aWhichClipboard
-);
-
-
参数
-
aFlavorList
An array of ASCII strings.
aLength
The length of the aFlavorList.
aWhichClipboard
Specifies the clipboard to which this operation applies.
-
-
返回值
-

Returns true, if data is present and it matches the specified flavor. Otherwise it returns false.

-

setData()

-

This method sets the data from a transferable on the native clipboard.

-
void setData(
-  in nsITransferable aTransferable,
-  in nsIClipboardOwner anOwner,
-  in long aWhichClipboard
-);
-
-
参数
-
aTransferable
The transferable containing the data to put on the clipboard.
anOwner
The owner of the transferable.
aWhichClipboard
Specifies the clipboard to which this operation applies.
-
-

supportsSelectionClipboard()

-

This method allows clients to determine if the implementation supports the concept of a separate clipboard for selection.

-
boolean supportsSelectionClipboard();
-
-
参数
-

None.

-
返回值
-

Returns true if kSelectionClipboard is available. Otherwise it returns false.

-

相关链接

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboardhelper/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboardhelper/index.html deleted file mode 100644 index b4c7881597..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboardhelper/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: nsIClipboardHelper -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboardHelper -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboardHelper ---- -
-
widget/public/nsIClipboardHelper.idl脚本化
- - -nsIClipboardHelper接口是能够快速方便的使用 nsIClipboard 接口中常用方法的辅助接口. - - -
-继承于: nsISupports -最后修改于Gecko 1.7
-
-

方法概述

- - - - - - - - - -
void copyString(in AString aString);
void copyStringToClipboard(in AString aString, in long aClipboardID);
-

方法

-

copyString()

-

该方法将字符串复制到默认剪切板.

-
void copyString(
-  in AString aString
-);
-
-
参数
-
-
- aString
-
- 将要复制到剪切板的字符串.
-
-

copyStringToClipboard()

-

该方法将字符串复制到指定剪切板.

-
void copyStringToClipboard(
-  in AString aString,
-  in long aClipboardID
-);
-
-
参数
-
-
- aString
-
- 将要复制到指定剪切板的字符串.
-
- aClipboardID
-
- 指定剪切板的ID(例如kSelectionClipboard).
-
-

相关连接

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiconsoleservice/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiconsoleservice/index.html deleted file mode 100644 index b373505057..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiconsoleservice/index.html +++ /dev/null @@ -1,215 +0,0 @@ ---- -title: nsIConsoleService -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleService -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleService ---- -
-

Error Console在Firefox中已经过期,只有将devtools.errorconsole.enabled - - 设为 - true才能使用. 对于web应用使用 Web Console 代替, 对于浏览器中的chrome应用,使用 Browser Console 代替 .

-
-

-
xpcom/base/nsIConsoleService.idl脚本化
- - -console service是Error Console 后端的一部分, 与每一个Mozilla应用绑定在一起. 它用来记录各种消息、警告以及错误,同时可获取所有已经记录的消息 - - -
-继承于: nsISupports -最后修改于Gecko 1.9 (Firefox 3)
-

-

实现方式: @mozilla.org/consoleservice;1 as a service:

-
var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
-                     .getService(Components.interfaces.nsIConsoleService);
-
-

Method overview

- - - - - - - - - - - - - - - - - - - - - -
void getMessageArray([array, size_is(count)] out nsIConsoleMessage messages, out uint32_t count);已废弃 Gecko 19
- void getMessageArray([optional] out uint32_t count, [retval, array, size_is(count)] out nsIConsoleMessage messages);
void logMessage(in nsIConsoleMessage message);
void logStringMessage(in wstring message);
void registerListener(in nsIConsoleListener listener);
void reset();
void unregisterListener(in nsIConsoleListener listener);
-

Methods

-

getMessageArray()

-

获取有关目前所有控制台记录的信息的数组

-

已废弃 Gecko 19 (Firefox 19 / Thunderbird 19 / SeaMonkey 2.16)
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.

-
void getMessageArray(
-  [array, size_is(count)] out nsIConsoleMessage messages,
-  out PRUint32 count
-);
-
-
Parameters
-
-
- messages
-
- 已经记录的消息数组
-
- count
-
- 数组中消息的数。如果没有消息被记录,函数会返回0,但同时仍会为message分配一个标记,在从脚本调用时,表示返回的一个长度为0的消息。
-
-

-
void getMessageArray(
-  [optional] out PRUint32 count,
-  [retval, array, size_is(count)] out nsIConsoleMessage messages
-);
-
-
Parameters
-
-
- count
-
- The number of messages in the array. If no messages are logged, this function will return a count of 0 but still will allocate one word for messages, so as to show up as a 0-length array when called from script.
-
-

Note: See the code samples below for how to call getMessageArray.

-

logMessage()

-
void logMessage(
-  in nsIConsoleMessage message
-);
-
-
Parameters
-
-
- message
-
- An nsIConsoleMessage to log.
-
-

logStringMessage()

-

Convenience method for logging simple messages.

-
void logStringMessage(
-  in wstring message
-);
-
-
Parameters
-
-
- message
-
- The string to log.
-
-

registerListener()

-

Registers a listener for notification when an error is logged.

-

Note: To guard against stack overflows from listeners that could log messages (it is easy to do this inadvertently from listeners implemented in JavaScript), we do not call any listeners when another error is already being logged.

-
void registerListener(
-  in nsIConsoleListener listener
-);
-
-
Parameters
-
-
- listener
-
- The nsIConsoleListener to add.
-
-

reset()

-

Clear the message buffer (For example, for privacy reasons).

-
void reset();
-
-
Parameters
-

None.

-

Note: Console listeners expect you to log an empty string message before calling reset so that they can clear their message buffers too. (This works before Gecko 1.9 too of course.)

-

unregisterListener()

-

Unregisters a listener.

-
void unregisterListener(
-  in nsIConsoleListener listener
-);
-
-
Parameters
-
-
- listener
-
- The nsIConsoleListener to remove.
-
-

Examples

-

Retrieving the message array

-

To retrieve the message array in Gecko prior to version 19:

-
function getConsoleMessageArray() {
-  var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
-                                 .getService(Components.interfaces.nsIConsoleService);
-  var array = {};
-  consoleService.getMessageArray(array, {});
-  return array.value;
-}
-
-

To retrieve the message array in Gecko 19 or later:

-
function getConsoleMessageArray() {
-  var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
-                                 .getService(Components.interfaces.nsIConsoleService);
-  return consoleService.getMessageArray();
-}
-
-

To retrieve the message array in a compatible way:

-
function getConsoleMessageArray() {
-  var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
-                                 .getService(Components.interfaces.nsIConsoleService);
-  var array = {};
-  return consoleService.getMessageArray(array, {}) || array.value;
-}
-
-

Logging a simple message

-

A common usage is to log a string message to console:

-
function LOG(msg) {
-  var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
-                                 .getService(Components.interfaces.nsIConsoleService);
-  consoleService.logStringMessage(msg);
-}
-
-

Alternative logging methods include Components.utils.reportError and dump().

-

Logging a message with additional information

-

To include other information an nsIConsoleMessage object must be used. In this example nsIScriptError, which implements nsIConsoleMessage, is used to include information about the source file and line number of the error.

-
function myLogToConsole(aMessage, aSourceName, aSourceLine, aLineNumber,
-                        aColumnNumber, aFlags, aCategory)
-{
-  var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
-                                 .getService(Components.interfaces.nsIConsoleService);
-  var scriptError = Components.classes["@mozilla.org/scripterror;1"]
-                              .createInstance(Components.interfaces.nsIScriptError);
-  scriptError.init(aMessage, aSourceName, aSourceLine, aLineNumber,
-                   aColumnNumber, aFlags, aCategory);
-  consoleService.logMessage(scriptError);
-}
-
- -

See also

- -

-
-  
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidirectoryserviceprovider/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidirectoryserviceprovider/index.html deleted file mode 100644 index 20d094eaf3..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidirectoryserviceprovider/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: nsIDirectoryServiceProvider -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIDirectoryServiceProvider -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIDirectoryServiceProvider ---- -

-
xpcom/io/nsIDirectoryService.idl脚本化
- - -本接口是目录服务用于得到文件位置的函数。 - - -
-继承于: nsISupports -最后修改于Gecko 1.7
-

-

nsIDirectoryServiceProvider.

-

方法概览

- - - - - - -
nsIFile getFile(in string prop, out PRBool persistent);
-

方法

-

getFile()

-

The Directory Service calls this method when it gets the first request for a prop or on every request if the prop is not persistent.

-
nsIFile getFile(
-  in string prop,
-  out PRBool persistent
-);
-
-
Parameters
-
-
- prop
-
- The symbolic name of the file.
-
- persistent
-
- true if the returned file will be cached by Directory Service. Subsequent requests for this prop will bypass the provider and use the cache. false if the provider will be asked for this prop each time it is requested.
-
-
Return value
-

The nsIFile represented by the property.

-

示例

-

This code creates a global, read-only string called currDir with the value of the current working directory.

-
 __defineGetter__("currDir",
-                  function getCurrDir() {
-                    return Components.classes["@mozilla.org/file/directory_service;1"]
-                                     .getService(Components.interfaces.nsIDirectoryServiceProvider)
-                                     .getFile("CurWorkD",{}).path;
-                   });
-
-

Test it with to see the magic happen.

-
 alert(currDir);
-
-

参见

- -

Additionally, see section 16.5.2 of the Rapid Application Development with Mozilla book for instructions on how to get the current working directory and the process binary directory, among other things.

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidomclientrect/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidomclientrect/index.html deleted file mode 100644 index 20a00c9e26..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidomclientrect/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: nsIDOMClientRect -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMClientRect -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMClientRect ---- -

-
dom/interfaces/base/nsIDOMClientRect.idl脚本化
-代表一个矩形盒子。盒子类型由返回这种盒子对象的方法指定的。它是由像element.getBoundingClientRect的函数返回的。. - -
- -
1.0
- -
66
- -
- -
- -
Introduced
-
Gecko 1.9
- -
- -
- -
-继承于: nsISupports -最后修改于Gecko 1.9.1 (Firefox 3.5 / Thunderbird 3.0 / SeaMonkey 2.0)
-

- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AttributeTypeDescription
bottomfloatY 轴,相对于视口原点(viewport origin)矩形盒子的底部。只读。 
heightfloat矩形盒子的高度(等同于 bottom 减 top)。只读。
leftfloatX 轴,相对于视口原点(viewport origin)矩形盒子的左侧。只读。 
rightfloatX 轴,相对于视口原点(viewport origin)矩形盒子的右侧。只读。 
topfloatY 轴,相对于视口原点(viewport origin)矩形盒子的顶部。只读。
widthfloat矩形盒子的宽度(等同于 right 减 left)。只读。 
xfloatX 轴,相对于视口原点(viewport origin)矩形盒子的左侧。只读。 
yfloatY 轴,相对于视口原点(viewport origin)矩形盒子的顶部。只读。
- -

参考资料

- - - -

这个对象几次易名:最初叫做 TextRectangle,然后叫做 ClientRect,后来叫做 DOMRect。

- -

该对象最初只有 top、left、right、bottom 属性,后来添加了 width、height、x、y 属性。

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifile/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifile/index.html deleted file mode 100644 index d966771e83..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifile/index.html +++ /dev/null @@ -1,828 +0,0 @@ ---- -title: nsIFile -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIFile -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIFile ---- -

-
xpcom/io/nsIFile.idl脚本化
- - -An instance of this interface is a cross-platform representation of a location in the filesystem. - - -
-继承于: nsISupports -最后修改于Gecko 1.0
-

-

nsIFile is the correct platform-agnostic way to specify a file; you should always use this instead of a string to ensure compatibility.

-

With an nsIFile you can navigate to ancestors or descendants without having to deal with the different path separators used on different platforms, query the state of any file or directory at the position represented by the nsIFile and create, move or copy items in the filesystem.

-

An nsIFile can be retrieved by either instantiating an nsILocalFile using a platform specific path string or by using cross-platform locations retrieved from the directory service.

-

All methods with string parameters have two forms. The preferred form operates on UTF-16 encoded characters strings. An alternate form operates on characters strings encoded in the "native" charset. A string containing characters encoded in the native charset cannot be safely passed to javascript via xpconnect. Therefore, the UTF-16 forms are scriptable, but the "native methods" are not. In addition, the native form cannot deal with files whose name contains characters outside the default system code page on Windows. Using the native form limits the ability of your code to deal with the full Unicode support on Windows 2000 or later where the OS itself does not have such a limitation. Therefore, you must not use the native form unless it is guaranteed that the path passed to a native form function is always ASCII.

-
- Note: nsILocalFile was merged with this interface in Gecko 14. Much of the documentation has not been updated to reflect this change.
-

Method overview

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void append(in AString node);
void appendNative(in ACString node); Native code only!
void appendRelativeNativePath(in ACString relativeFilePath); Native code only!
void appendRelativePath(in AString relativeFilePath);
nsIFile clone();
boolean contains(in nsIFile inFile, in boolean recur);
void copyTo(in nsIFile newParentDir, in AString newName);
void copyToFollowingLinks(in nsIFile newParentDir, in AString newName);
void copyToFollowingLinksNative(in nsIFile newParentDir, in ACString newName); Native code only!
void CopyToNative(in nsIFile newParentDir, in ACString newName); Native code only!
void create(in unsigned long type, in unsigned long permissions);
void createUnique(in unsigned long type, in unsigned long permissions);
boolean equals(in nsIFile inFile);
boolean exists();
ACString getRelativeDescriptor(in nsIFile fromFile);
void initWithFile(in nsIFile aFile);
void initWithNativePath(in ACString filePath); Native code only!
void initWithPath(in AString filePath);
boolean isDirectory();
boolean isExecutable();
boolean isFile();
boolean isHidden();
boolean isReadable();
boolean isSpecial();
boolean isSymlink();
boolean isWritable();
void launch();
PRLibraryStar load(); Native code only!
void moveTo(in nsIFile newParentDir, in AString newName);
void moveToNative(in nsIFile newParentDir, in ACString newName); Native code only!
void normalize();
FILE openANSIFileDesc(in string mode); Native code only!
PRFileDescStar openNSPRFileDesc(in long flags, in long mode); Native code only!
void remove(in boolean recursive);
void reveal();
void setRelativeDescriptor(in nsIFile fromFile, in ACString relativeDesc);
-

Attributes

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AttributeTypeDescription
directoryEntriesnsISimpleEnumeratorReturns an enumeration of the elements in a directory. Each element in the enumeration is an nsIFile. Read only. -
Exceptions thrown
-
-
- NS_ERROR_FILE_NOT_DIRECTORY
-
- Indicates that this nsIFile does not reference a directory.
-
-
diskSpaceAvailable PRInt64The number of bytes available to non-superuser on the disk volume containing the nsIFile. Read only.
fileSizePRInt64 -

The value of this attribute is the number of bytes corresponding to the data represented by the file.

-

On the Mac, getting/setting the file size with nsIFile only deals with the size of the data fork. If you need to know the size of the combined data and resource forks use nsILocalFileMac.GetFileSizeWithResFork().

- Changing the size of a nsIFile operates on the underlying filesystem, possibly truncating the existing file to specified size.
fileSizeOfLinkPRInt64 -

This attribute exposes the size of the symbolic link referenced by this nsIFile.

-

Unlike fileSize, this attribute corresponds to the size of the symbolic link referenced by this nsIFile. If this nsIFile does not reference a symbolic link, then the value of this attribute is undefined.

- The value of this attribute is the number of bytes corresponding to the data represented by the symbolic link. Any meta data, such as a resource fork on the Mac, is not included in the measurement of the file size. Read only.
followLinks PRBool -

Determines whether or not the nsIFile will automatically resolve symbolic links.

- By default, this value is false on all non-UNIX systems. As of Mozilla 1.7, this attribute is ignored on UNIX systems.
lastModifiedTimePRInt64 -

This attribute exposes the time when the file referenced by this nsIFile was last modified.

-

The value of this attribute is milliseconds since midnight (00:00:00), January 1, 1970 Greenwich Mean Time (GMT).

- Changing the last modified time of a nsIFile operates on the underlying filesystem. As of Gecko 1.7, changing the last modified time of a non-existent file has undefined behavior.
lastModifiedTimeOfLinkPRInt64 -

This attribute exposes the time when the symbolic link referenced by this nsIFile was last modified.

-

Unlike lastModifiedTime, this attribute corresponds to the last modified time of the symbolic link referenced by this nsIFile. If this nsIFile does not reference a symbolic link, then the value of this attribute is undefined.

-

The value of this attribute is milliseconds since midnight (00:00:00), January 1, 1970 Greenwich Mean Time (GMT).

- Changing the last modified time of a nsIFile operates on the underlying filesystem. As of Gecko 1.7, changing the last modified time of a non-existent file has undefined behavior.
leafNameAString -

This attribute exposes the name of the nsIFile without any directory components.

- Changing the leaf name of a nsIFile does not affect the underlying filesystem. It only changes what this nsIFile references.
nativeLeafNameACString -

This attribute exposes the name of the nsIFile without any directory components. [native character encoding variant]

- Changing the leaf name of a nsIFile does not affect the underlying filesystem. It only changes what this nsIFile references. Native code only!
nativePathACString -

This attribute exposes the full path of the nsIFile. [native character encoding variant]

- The value of this attribute is a platform-specific file path. Read only. Native code only!
nativeTargetACString -

This attribute exposes the full target of the nsIFile - the full path with any symbolic links dereferenced. [native character encoding variant]

- The value of this attribute is a platform-specific file path. Read only. Native code only!
parentnsIFile -

This attribute returns the parent nsIFile for this nsIFile.

- The parent will be null when this nsIFile references the top of the volume. For example, C:\ does not have a parent. Read only.
pathAString -

This attribute exposes the full platform-specific path of the nsIFile (including the leafName). Read only.

- Example, this could return "/home/user/foo.txt" or "C:\Images\my.jpeg"
permissionsunsigned long -

The value of this attribute is a UNIX-style file permission mask for this nsIFile.

- Changing the permissions of a nsIFile operates on the underlying filesystem. As of Gecko 1.7, changing the permissions of a non-existent file has undefined behavior.
permissionsOfLinkunsigned long -

The value of this attribute is a UNIX-style file permission mask for this nsIFile.

-

Unlike permissions, this attribute corresponds to the permissions of the symbolic link referenced by this nsIFile. If this nsIFile does not reference a symbolic link, then the value of this attribute is undefined.

- Changing the permissions of a nsIFile operates on the underlying filesystem. As of Gecko 1.7, changing the permissions of a non-existent file has undefined behavior.
persistentDescriptor ACString -

On some platforms, the value of nsIFile.path may be insufficient to uniquely identify the file on the local file system. The persistent descriptor is intended to be used whenever a nsIFile needs to be serialized to disk and later recovered. This string is not intended for display to users.

-
Note: The value of the followLinks attribute is not encoded in the persistent descriptor.
targetAString -

This attribute exposes the full target of the nsIFile - the full path with any symbolic links dereferenced.

-

Accessor to the string path. The native version of these strings are not guaranteed to be a usable path to pass to NSPR or the C stdlib. There are problems that affect platforms on which a path does not fully specify a file because two volumes can have the same name (For example Mac). This is solved by holding "private", native data in the nsIFile implementation. This native data is lost when you convert to a string. DO NOT PASS TO USE WITH NSPR OR STDLIB! Read only.

-
Exceptions thrown
-
-
- NS_ERROR_FILE_INVALID_PATH
-
- Indicates that this nsIFile does not reference a symbolic links.
-
-
-

Constants

- - - - - - - - - - - - - - - - - - - - - - - -
ConstantValueDescription
NORMAL_FILE_TYPE0A normal file.
DIRECTORY_TYPE1A directory/folder.
DELETE_ON_CLOSE 0x80000000Optional parameter used by openNSPRFileDesc
-

Methods

-

append()

-

This function is used for constructing a descendant of the current nsIFile.

-
-

Note: This method does not return a new nsIFile; it modifies the object it was called on. If the old nsIFile should be retained, use clone().

-
-
void append(
-  in AString node
-);
-
-
Parameters
-
-
- node
-
- A string which is intended to be a child node of the nsIFile. This string must not contain a path separator character.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_UNRECOGNIZED_PATH
-
- Indicates that aNode incorrectly contains a path separator character.
-
-

Native code only!

appendNative

-

This method is used for constructing a descendant of the current nsIFile. [native character encoding variant]

-
void appendNative(
-  in ACString node
-);
-
-
Parameters
-
-
- node
-
- A string that is intended to be a child node of the current nsIFile. This string must not contain a path separator character. This string must be encoded using the native character encoding.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_UNRECOGNIZED_PATH
-
- Indicates that aNode incorrectly contains a path separator character.
-
-

clone()

-

This method creates a clone of the nsIFile. (It does NOT clone the file itself; see the copy methods.)

-
nsIFile clone();
-
-
Parameters
-

None.

-
Return value
-

A new nsIFile instance that corresponds to the same file or directory as this nsIFile.

-

contains()

-

This method tests whether or not a nsIFile instance is a descendant of the this nsIFile.

-
boolean contains(
-  in nsIFile inFile,
-  in boolean recur
-);
-
-
Parameters
-
-
- inFile
-
- The nsIFile to test.
-
- recur
-
- This parameter specifies whether or not subdirectories should be inspected. As of Gecko 1.7, this parameter is ignored and always treated as false by the canonical Local File implementation.
-
-
Return value
-

true if inFile is a descendant of this nsIFile.

-

copyTo()

-

This method copies a source file to a new location if it does not already exist.

-

This method will NOT resolve aliases/shortcuts during the copy.

-
void copyTo(
-  in nsIFile newParentDir,
-  in AString newName
-);
-
-
Parameters
-
-
- newParentDir
-
- This parameter specifies the parent directory to copy the file into. If this parameter is null, then the parent directory of the file will be used.
-
- newName
-
- This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_DESTINATION_NOT_DIR
-
- If the "newParentDir" is not a directory.
-
- NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
-
- Indicates that the current file path does not exist. It is not possible to copy a file that does not exist.
-
- NS_ERROR_FILE_ALREADY_EXISTS
-
- Indicates that there is already a file named "newName" in the destination directory.
-
-

copyToFollowingLinks()

-

This method copies a source file to a new location if it does not already exist.

-

This method is identical to copyTo() except that any symbolic links will be followed as the name suggests.

-
void copyToFollowingLinks(
-  in nsIFile newParentDir,
-  in AString newName
-);
-
-
Parameters
-
-
- newParentDir
-
- This parameter specifies the parent directory to copy the file into. If this parameter is null, then the parent directory of the file will be used.
-
- newName
-
- This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_DESTINATION_NOT_DIR
-
- If the "newParentDir" is not a directory.
-
- NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
-
- Indicates that the current file path does not exist. It is not possible to copy a file that does not exist.
-
- NS_ERROR_FILE_ALREADY_EXISTS
-
- Indicates that there is already a file named "newName" in the destination directory.
-
-

Native code only!

copyToFollowingLinksNative

-

This method copies this file to a new location. [native character encoding variant]

-

This method is identical to copyToNative() except that any symbolic links will be followed as the name suggests.

-
void copyToFollowingLinksNative(
-  in nsIFile newParentDir,
-  in ACString newName
-);
-
-
Parameters
-
-
- newParentDir
-
- This parameter specifies the parent directory to copy the file into. If this parameter is null, then the parent directory of the file will be used.
-
- newName
-
- This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used. This string must be encoded using the native character encoding.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_DESTINATION_NOT_DIR
-
- If the "newParentDir" is not a directory.
-
- NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
-
- Indicates that the current file path does not exist. It is not possible to copy a file that does not exist.
-
- NS_ERROR_FILE_ALREADY_EXISTS
-
- Indicates that there is already a file named "newName" in the destination directory.
-
-

Native code only!

CopyToNative

-

This method copies this file to a new location. [native character encoding variant]

-
void CopyToNative(
-  in nsIFile newParentDir,
-  in ACString newName
-);
-
-
Parameters
-
-
- newParentDir
-
- This parameter specifies the parent directory to copy the file into. If this parameter is null, then the parent directory of the file will be used.
-
- newName
-
- This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used. This string must be encoded using the native character encoding.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_DESTINATION_NOT_DIR
-
- If the "newParentDir" is not a directory.
-
- NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
-
- Indicates that the current file path does not exist. It is not possible to copy a file that does not exist.
-
- NS_ERROR_FILE_ALREADY_EXISTS
-
- Indicates that there is already a file named "newName" in the destination directory.
-
-

create()

-

This method creates a new file or directory in the file system corresponding to the file path represented by this nsIFile. This method will create any path segments that do not already exist.

-
void create(
-  in unsigned long type,
-  in unsigned long permissions
-);
-
-
Parameters
-
-
- type
-
- This specifies the type of file system object to be made. The only two types at this time are file and directory which are defined above.
-
- permissions
-
- A UNIX-style file permissions value. For example, the octal value 0600 may be used to limit read and write access to the current user of the system. This parameter may be ignored on systems that do not support file permissions.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_ALREADY_EXISTS
-
- Indicates that the file or directory already exists.
-
- NS_ERROR_FILE_UNKNOWN_TYPE
-
- Indicates that the value of "type" does not correspond to a known type.
-
-

createUnique()

-

This function will create a new file or directory in the file system. Any nodes that have not been created or resolved, will be. If this file already exists, we try variations on the leaf name "suggestedName" until we find one that did not already exist. This method will create any path segments that do not already exist.

-
void createUnique(
-  in unsigned long type,
-  in unsigned long permissions
-);
-
-
Parameters
-
-
- type
-
- This specifies the type of file system object to be made. The only two types at this time are file and directory which are defined above.
-
- permissions
-
- A UNIX-style file permissions value. For example, the octal value 0600 may be used to limit read and write access to the current user of the system. This parameter may be ignored on systems that do not support file permissions.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_UNKNOWN_TYPE
-
- Indicates that the value of "type" does not correspond to a known type.
-
- NS_ERROR_FILE_TOO_BIG
-
- Indicates that the search for nonexistent files was unsuccessful because all of the attempted leaf name variants already exist.
-
-

equals()

-

This method tests whether or not two nsIFile instances correspond to the same file or directory.

-
boolean equals(
-  in nsIFile inFile
-);
-
-
Parameters
-
-
- inFile
-
- The nsIFile to compare this nsIFile against.
-
-
Return value
-

true if "inFile" is equivalent to this nsIFile.

-

exists()

-

This method tests whether or not this nsIFile exists.

-
boolean exists()
-
-
Parameters
-

None.

-
Return value
-

true if the file or directory exists. Otherwise it returns false.

-

isDirectory()

-

This method tests whether or not this nsIFile corresponds to a directory.

-
boolean isDirectory();
-
-
Parameters
-

None.

-
Return value
-

true if this nsIFile corresponds to a directory. Otherwise it returns false.

-

isExecutable()

-

This method tests whether or not this nsIFile corresponds to a file that may be executed.

-
-

Note: This method does not work on all platforms due to bug 322865.

-
-
boolean isExecutable();
-
-
-

Note: Use nsIProcess to then execute/run this file.

-
-
Parameters
-

None.

-
Return value
-

true if the nsIFile may be executed by the user. Otherwise it returns false.

-

isFile()

-

This method tests whether or not this nsIFile corresponds to a normal file.

-
boolean isFile();
-
-
Parameters
-

None.

-
Return value
-

true if this nsIFile corresponds to a normal file. Otherwise it returns false.

-

isHidden()

-

This method tests whether or not this nsIFile corresponds to a file or directory that is hidden. In Unix, hidden files start with a period. On Mac and Windows, they have an attribute bit set.

-
boolean isHidden();
-
-
Parameters
-

None.

-
Return value
-

true if the file or directory is hidden. Otherwise it returns false.

-

isReadable()

-

This method tests whether or not this nsIFile corresponds to a file or directory that may be read by the user.

-
boolean isReadable();
-
-
Parameters
-

None.

-
Return value
-

true if the file or directory may be read by the user. Otherwise it returns false.

-

isSpecial()

-

This method tests whether or not this nsIFile corresponds to a special system file.

-

Note: The definition of a special system file is platform dependent. For example, under UNIX platforms this might correspond to a device file, socket, or fifo.

-
boolean isSpecial();
-
-
Parameters
-

None.

-
Return value
-

true if this nsIFile corresponds to a special system file. Otherwise it returns false.

-

isSymlink()

-

This method tests whether or not this nsIFile corresponds to a symbolic link, shortcut, or alias.

-
boolean isSymlink();
-
-
Parameters
-

None.

-
Return value
-

true if this nsIFile corresponds to a symbolic link. Otherwise it returns false.

-

isWritable()

-

This method tests whether or not this nsIFile corresponds to a file or directory that may be modified by the user.  As of Gecko 9, files on read only shares will return false.  Files that are exclusively opened on Win32 will return true if they are normally writable, and files that don't have write permissions will return false. For specific handling before Gecko 9 (Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6), please see bug 682571.

-
boolean isWritable();
-
-
Parameters
-

None.

-
Return value
-

true if the file or directory may be modified by the user. Otherwise it returns false.

-

moveTo()

-

This method moves this file to a new location.

-
- Note: If this method succeeds, this instance will be updated to point to the new file.
-

If the current file path corresponds to a regular file (for storage of bytes), and if the new leaf name identifies a regular file that already exists, then this method will overwrite the destination file.

-

Usually, "move" means to relocate the file to a different directory without changing the file's contents or properties, or in fact the file's serial number (inode). That is a very fast operation because it just changes directory information. The actual data doesn't move.

-

Unfortunately, an actual "move" is impossible between different volumes (disks or partitions). This method attempts to do the "right thing" when moving files across volumes. That is, it will copy the old file to the new location, try to assign the file attributes as the old file had them, and then delete the old file. You should be aware of these possible problems:

- -
void moveTo(
-  in nsIFile newParentDir,
-  in AString newName
-);
-
-
Parameters
-
-
- newParentDir
-
- This parameter specifies the parent directory to move the file into. If this parameter is null, then the parent directory of the file will be used.
-
- newName
-
- This parameter allows you to specify a new leaf name for the file to be moved. This parameter may be empty, in which case the current leaf name will be used.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
-
- Indicates that the current file path does not exist. It is not possible to move a file that does not exist.
-
- NS_ERROR_FILE_DIR_NOT_EMPTY
-
- Indicates that an attempt was made to move a directory to the location of an existing directory that is not empty.
-
- NS_ERROR_FILE_ACCESS_DENIED
-
- Indicates that an attempt was made to move a directory to the location of an existing directory that is not writable.
-
- NS_ERROR_FILE_DESTINATION_NOT_DIR
-
- Indicates that "newParentDir" exists and is not a directory.
-
-

Native code only!

moveToNative

-

This method moves this file to a new location. [native character encoding variant]

-
- Note: If this method succeeds, this instance will be updated to point to the new file.
-

If the current file path corresponds to a regular file (for storage of bytes), and if the new leaf name identifies a regular file that already exists, then this method will overwrite the destination file.

-

Usually, "move" means to relocate the file to a different directory without changing the file's contents or properties, or in fact the file's serial number (inode). That is a very fast operation because it just changes directory information. The actual data doesn't move.

-

Unfortunately, an actual "move" is impossible between different volumes (disks or partitions). This method attempts to do the "right thing" when moving files across volumes. That is, it will copy the old file to the new location, try to assign the file attributes as the old file had them, and then delete the old file. You should be aware of these possible problems:

- -
void moveToNative(
-  in nsIFile newParentDir,
-  in ACString newName
-);
-
-
Parameters
-

 

-
-
- newParentDir
-
- This parameter specifies the parent directory to copy the file into. If this parameter is null, then the parent directory of the file will be used.
-
- newName
-
- This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used. This string must be encoded using the native character encoding.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
-
- Indicates that the current file path does not exist. It is not possible to move a file that does not exist.
-
- NS_ERROR_FILE_DIR_NOT_EMPTY
-
- Indicates that an attempt was made to move a directory to the location of an existing directory that is not empty.
-
- NS_ERROR_FILE_ACCESS_DENIED
-
- Indicates that an attempt was made to move a directory to the location of an existing directory that is not writable.
-
- NS_ERROR_FILE_DESTINATION_NOT_DIR
-
- Indicates that "newParentDir" exists and is not a directory.
-
-

normalize()

-

This method is used to canonicalize the path represented by this nsIFile. (for example removing .. and . components on Unix).

-

As of Gecko 1.7, this method is only implemented under UNIX builds (except for Mac OSX). This method will fail if the path does not exist.

-
void normalize();
-
-
Parameters
-

None.

-
Exceptions thrown
-
-
- NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
-
- Indicates that the file path does not exist.
-
- NS_ERROR_FILE_DESTINATION_NOT_DIR
-
- Indicates that a component of the path prefix is not a directory.
-
- NS_ERROR_FILE_ACCESS_DENIED
-
- Read or search permission was denied for a component of the path prefix.
-
-

remove()

-

This method removes the file or directory corresponding to the file path represented by this nsIFile.

-

This method will not resolve any symlinks.

-
void remove(
-  in boolean recursive
-);
-
-
Parameters
-
-
- recursive
-
- If this nsIFile corresponds to a directory that is not empty, then this parameter must be true in order for the directory to be deleted. Otherwise, this parameter is ignored.
-
-
Exceptions thrown
-
-
- NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
-
- Indicates that the current file path does not exist. It is not possible to remove a file that does not exist.
-
- NS_ERROR_FILE_DIR_NOT_EMPTY
-
- Indicates that an attempt was made to remove a directory that is not empty.
-
- NS_ERROR_FILE_ACCESS_DENIED
-
- Indicates that an attempt was made to remove a file in a way that exceeded your permissions. Details depend on your file system and how its permissions work.
-
-

Remarks

-

All string-valued methods and attributes have two forms. The preferred form operates on UTF-16 (Unicode) encoded character strings. The alternate form operates on character strings encoded in the "native" multibyte character set. The native character encoding is defined as the single-byte character encoding used with the standard fopen function on the host system.

-

The native character encoding is determined using platform specific methods. As of Gecko 1.7, it is UTF-8 on Mac OS X. On Linux and other UNIX platforms, it is the value returned from nl_langinfo (CODESET), which usually corresponds to the value of the LC_ALL, LC_CTYPE and LANG environment variables (with the precedence the same as the order they're enumerated). On Win32 platforms, it is the currently selected ANSI codepage (specified by CP_ACP).

-

The word "Native" appears in the name of methods that operate on or return strings encoded in the native character set.

-

A string containing characters encoded in the native character set cannot be safely passed to JavaScript via XPConnect. Therefore, the "native" methods and attributes are not scriptable.

-

XPCOM provides the string conversion functions NS_CStringToUTF16 and NS_UTF16ToCString, which can be used to convert a string between UTF-16 and the native character encoding.

-

This interface was frozen for Gecko 1.0. See bug 129279 for details. From Gecko 2.0 interfaces are no longer frozen.

-

See also

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifilepicker/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifilepicker/index.html deleted file mode 100644 index 7122dcd1ef..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifilepicker/index.html +++ /dev/null @@ -1,376 +0,0 @@ ---- -title: nsIFilePicker -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker -tags: - - Filepicker - - 文件选取器 -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker ---- -

-
widget/nsIFilePicker.idl脚本化
- - -文件选择器组件是通过显示标准的用户界面来让用户来选择文件和目录,以及选择目的地来命名和新建文件。 - - -
-继承于: nsISupports -最后修改于Gecko 17.0 (Firefox 17.0 / Thunderbird 17.0 / SeaMonkey 2.14)
-

- -

实现自: @mozilla.org/filepicker;1。要创建一个实例,使用以下代码:

- -
var filePicker = Components.classes["@mozilla.org/filepicker;1"]
-                 .createInstance(Components.interfaces.nsIFilePicker);
-
- -

方法概述

- - - - - - - - - - - - - - - - - - - -
void appendFilter(in AString title, in AString filter);
void appendFilters(in long filterMask);
void init(in nsIDOMWindow parent, in AString title, in short mode);
void open(in nsIFilePickerShownCallback aFilePickerShownCallback);
short show(); 已废弃 Gecko 17.0
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型说明
addToRecentDocs booleanIf true, the file is added to the operating system's "recent documents" list (if the operating system has one; nothing happens if there is no such concept on the user's platform). This attribute has no effect if private browsing mode is in effect.
defaultExtensionAStringThe extension for the type of files you want to work with. On some platforms, this is automatically appended to filenames the user enters, if required.  Specify it without a leading dot, for example "jpg".
defaultStringAStringThe filename, including extension, that should be suggested to the user as a default. This should be set this before calling open() or show(). -
Exceptions thrown
- -
-
NS_ERROR_FAILURE
-
If you try to read this attribute.
-
-
displayDirectorynsILocalFileThe directory that the file picker dialog should initially display. This should be set this before calling open() or show() to specify a starting point.
filensILocalFileThe currently selected file or directory. Read only.
filesnsISimpleEnumerator -

An enumerator of the currently selected files. Read only.

-
Note: Only works with modeOpenMultiple mode.
fileURLnsIURIThe URI of the currently selected file or directory. Read only.
filterIndexlongThe (0-based) index of the filter which is currently selected in the file picker dialog. Set this to choose a particular filter to be selected by default.
- -

常量

- -

模式常量

- -

These constants are used to specify the type of file picker to create when calling init().

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
常量说明
modeOpen0Load a file or directory.
modeSave1Save a file or directory.
modeGetFolder2Select a folder/directory.
modeOpenMultiple3Load multiple files.
- -

返回值常量

- -

These values are returned by show(), indicating the result of the file picker activity.

- - - - - - - - - - - - - - - - - - - - - - - - -
ConstantValueDescription
returnOK0The file picker dialog was closed by the user hitting 'Ok'
returnCancel1The file picker dialog was closed by the user hitting 'Cancel'
returnReplace2The user chose an existing file and acknowledged that they want to overwrite the file
- -

筛选器常量

- -

These constants are used to create filters for commonly-used file types. For the most up to date list see filepicker.properties.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ConstantValueDescription
filterAll0x001Corresponds to the *.* filter for file extensions. All files will pass through the filter.
filterHTML0x002Corresponds to the *.html, *.htm, *.shtml and *.xhtml filters for file extensions.
filterText0x004Corresponds to the *.txt and *.text filter for file extensions.
filterImages0x008Corresponds to the *.jpe, *.jpg, *.jpeg, *.gif, *.png, *.bmp, *.ico, *.svg, *.svgz, *.tif, *.tiff, *.ai, *.drw, *.pct, *.psp, *.xcf, *.psd and *.raw filters for file extensions.
filterXML0x010Corresponds to the *.xml filter for file extensions.
filterXUL0x020Corresponds to the *.xul filter for file extensions.
filterApps0x040Corresponds to the platform specific application filter for file extensions. Application files for the user's platform will pass through the filter.
filterAllowURLs0x80Allow URLs.
filterAudio0x100Corresponds to the *.aac, *.aif, *.flac, *.iff, *.m4a, *.m4b, *.mid, *.midi, *.mp3, *.mpa, *.mpc, *.oga, *.ogg, *.ra, *.ram, *.snd, *.wav and *.wma filters for file extensions.
filterVideo0x200Corresponds to the *.avi, *.divx, *.flv, *.m4v, *.mkv, *.mov, *.mp4, *.mpeg, *.mpg, *.ogm, *.ogv, *.ogx, *.rm, *.rmvb, *.smil, *.webm, *.wmv and *.xvid filters for file extensions.
- -

方法

- -

appendFilter()

- -

Appends a custom file extension filter to the dialog. The filter appended first will be used to display the nsIFilePicker dialog, the user may then select another from the list.

- -
void appendFilter(
-  in AString title,
-  in AString filter
-);
-
- -
Parameters
- -
-
title
-
The title of the filter.
-
filter
-
The filter string. Multiple extensions may be included, separated by a semicolon and a space.
-
- -
Example
- -

Some example filter strings:

- - - -

appendFilters()

- -

Appends a list of file extension filters, from the predefined list, to the dialog.

- -
void appendFilters(
-  in long filterMask
-);
-
- -
Parameters
- -
Note: If appendFilters is the first (or only) call to set the file filters the filter with the smallest code will be used as default filter when displaying the nsIFilePicker dialog. If you would like to use another you must append it separately before the others you want to go into the drop down list.
- -
-
filterMask
-
A combination of the filters you wish to use. You may OR multiple filters together; for example filterAll | filterHTML.
-
- -

init()

- -

Initialize the file picker widget. The file picker is not valid until this method is called.

- -
void init(
-  in nsIDOMWindow parent,
-  in AString title,
-  in short mode
-);
-
- -
Parameters
- -
-
parent
-
The nsIDOMWindow parent. This dialog will be dependent on this parent. Must be non-null.
-
title
-
The file picker dialog title. If this is null, the dialog will have the default title.
-
mode
-
One of the mode constants, indicating the type of picker to create.
-
- -

open

- -

Opens the file dialog asynchrounously. The passed in object's done method will be called upon completion.

- -
void open(
-  in nsIFilePickerShownCallback aFilePickerShownCallback
-);
-
- -
Parameters
- -
-
aFilePickerShownCallback
-
The nsIFilePickerShownCallback to be called on completion.
-
- -

show

- -

Displays the file picker dialog. The dialog is displayed modally.

- -
short show();
-
- -
Parameters
- -

None.

- -
Return value
- -

One of the return constants.

- -

示例

- -

Here's an example:

- -
const nsIFilePicker = Components.interfaces.nsIFilePicker;
-
-var fp = Components.classes["@mozilla.org/filepicker;1"]
-	           .createInstance(nsIFilePicker);
-fp.init(window, "Dialog Title", nsIFilePicker.modeOpen);
-fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText);
-
-var rv = fp.show();
-if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
-  var file = fp.file;
-  // Get the path as string. Note that you usually won't
-  // need to work with the string paths.
-  var path = fp.file.path;
-  // work with returned nsILocalFile...
-}
-
- -

If your code is a component and window is not defined, you can get one using nsIWindowMediator.

- -

When selecting multiple files:

- -
    ....
-    fp.init(window, "Dialog Title", nsIFilePicker.modeOpenMultiple);
-    ....
-
-    var files = fp.files;
-    var paths = [];
-    while (files.hasMoreElements())
-    {
-        var arg = files.getNext().QueryInterface(Components.interfaces.nsILocalFile).path;
-        paths.push(arg);
-    }
-
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsihttpchannel/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsihttpchannel/index.html deleted file mode 100644 index b469773f43..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsihttpchannel/index.html +++ /dev/null @@ -1,365 +0,0 @@ ---- -title: nsIHttpChannel -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel ---- -

-
netwerk/protocol/http/nsIHttpChannel.idl脚本化
- - -This interface allows for the modification of HTTP request parameters and the inspection of the resulting HTTP response status and headers when they become available. - - -
-继承于: nsIChannel -最后修改于Gecko 1.3
-

- -

To create an HTTP channel, use nsIIOService with a HTTP URI, for example:

- -
var ios = Components.classes["@mozilla.org/network/io-service;1"]
-                    .getService(Components.interfaces.nsIIOService);
-var ch = ios.newChannel("http://www.example.com/", null, null);
-
- -

方法概述

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ACString getRequestHeader(in ACString aHeader);
ACString getResponseHeader(in ACString header);
boolean isNoCacheResponse();
boolean isNoStoreResponse();
void setRequestHeader(in ACString aHeader, in ACString aValue, in boolean aMerge);
void setResponseHeader(in ACString header, in ACString value, in boolean merge);
void visitRequestHeaders(in nsIHttpHeaderVisitor aVisitor);
void visitResponseHeaders(in nsIHttpHeaderVisitor aVisitor);
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性名类型描述
allowPipeliningboolean -

This attribute is a hint to the channel to indicate whether or not the underlying HTTP transaction should be allowed to be pipelined with other transactions. This should be set to false, for example, if the application knows that the corresponding document is likely to be very large.

- -

This attribute is true by default, though other factors may prevent pipelining.

- This attribute may only be set before the channel is opened. - -
可能抛出的异常
- -
-
NS_ERROR_FAILURE
-
If set after the channel has been opened.
-
-
redirectionLimitunsigned long -

This attribute specifies the number of redirects this channel is allowed to make. If zero, the channel will fail to redirect and will generate a NS_ERROR_REDIRECT_LOOP failure status.

-
Note: An HTTP redirect results in a new channel being created. If the new channel supports nsIHttpChannel, then it will be assigned a value to its redirectionLimit attribute one less than the value of the redirected channel's redirectionLimit attribute. The initial value for this attribute may be a configurable preference (depending on the implementation).
referrernsIURI -

Get or set the URI of the HTTP Referer: header. This is the address (URI) of the resource from which this channel's URI was obtained (see RFC2616 section 14.36).

- -

This attribute may only be set before the channel is opened.

-
Note: The channel may silently refuse to set the Referer: header if the URI does not pass certain security checks (e.g., a "https://" URL will never be sent as the referrer for a plaintext HTTP request). The implementation is not required to throw an exception when the referrer URI is rejected.
- -
可能抛出的异常
- -
-
NS_ERROR_IN_PROGRESS
-
If set after the channel has been opened.
-
-
requestMethodACString -

获取或设置HTTP请求方法(默认为"GET").设置时不区分大小写,获取时返回的都是大写字母组成的字符串.

- -

该属性的值只能在通道打开之前进行设置.

- -

Note:  The data for a "POST" or "PUT" request can be configured via nsIUploadChannel. However, after setting the upload data, it may be necessary to set the request method explicitly. The documentation for nsIUploadChannel has further details.

- -
可能抛出的异常
- -
-
NS_ERROR_IN_PROGRESS
-
If set after the channel has been opened.
-
-
requestSucceededboolean -

Returns true if the HTTP response code indicates success. The value of nsIRequest.status() will be NS_OK even when processing a 404 File Not Found response because such a response may include a message body that (in some cases) should be shown to the user. Use this attribute to distinguish server error pages from normal pages, instead of comparing the response status manually against the set of valid response codes, if that is required by your application. Read only.

- -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
If called before the response has been received (before onStartRequest()).
-
-
responseStatusunsigned long获取HTTP响应状态码(比如200). 只读. -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
If called before the response has been received (before onStartRequest()).
-
-
responseStatusTextACString -

获取HTTP响应状态信息(比如"OK").

-
Note: This returns the raw (possibly 8-bit) text from the server. There are no assumptions made about the charset of the returned text. You have been warned!
Read only. - -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
If called before the response has been received (before onStartRequest()).
-
-
- -

方法

- -

getRequestHeader()

- -

Get the value of a particular request header.

- -
ACString getRequestHeader(
-  in ACString aHeader
-);
-
- -
参数
- -
-
aHeader
-
需要查询的请求头名称,不区分大小写(比如"Cache-Control").
-
- -
返回值
- -

指定请求头的值.

- -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
如果没有这个请求头
-
- -

getResponseHeader()

- -

获取指定响应头的值.

- -
ACString getResponseHeader(
-  in ACString header
-);
-
- -
参数
- -
-
header
-
需要查询的响应头名称,不区分大小写(比如"Set-Cookie").
-
- -
返回值
- -

指定响应头的值.

- -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
在响应头还未完全返回的时候调用了该方法(before onStartRequest()),或者响应中没有包含此响应头的情况下.
-
- -

isNoCacheResponse()

- -

Returns true if the server sent the equivalent of a "Cache-Control: no-cache" response header. Equivalent response headers include: "Pragma: no-cache", "Expires: 0", and "Expires" with a date value in the past relative to the value of the "Date" header.

- -
boolean isNoCacheResponse();
-
- -
参数
- -

- -
返回值
- -

如果服务器返回了"Cache-control: no-cache"或者其他能够禁止缓存的响应头,则该方法返回true,否则返回false.

- -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
在响应头还未完全返回的时候调用了该方法(before onStartRequest()).
-
- -

isNoStoreResponse()

- -
boolean isNoStoreResponse();
-
- -
参数
- -

- -
返回值
- -

如果服务器返回了"Cache-Control: no-store"这样的响应头,则该方法返回true,否则返回false.

- -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
在响应头还未完全返回的时候调用了该方法(before onStartRequest()).
-
- -

setRequestHeader()

- -

This method is called to set the value of a particular request header. This method allows, for example, the cookies module to add "Cookie" headers to the outgoing HTTP request. This method may only be called before the channel is opened. If aValue is empty and aMerge is false, the header will be cleared.

- -
void setRequestHeader(
-  in ACString aHeader,
-  in ACString aValue,
-  in boolean aMerge
-);
-
- -
参数
- -
-
aHeader
-
指定请求头的名称,不区分大小写(例如"Cookie").
-
aValue
-
指定请求头的值(例如"X=1").
-
aMerge
-
如果该参数为true,则新指定的请求头的值会合并到该请求头已有的值的后面.如果指定的请求头不支持(或者说不适合)新旧值的合并操作,则这个参数会被忽略(比如"Connection"头就只能有一个值).具体那些请求头会忽略掉这个参数,本文档不会给出.如果该参数的值为false,则新指定的请求头的值会覆盖掉该请求头已有的值.
-
- -
可能抛出的异常
- -
-
NS_ERROR_IN_PROGRESS
-
在通道已经打开之后才调用了该方法
-
- -

setResponseHeader()

- -

设置指定响应头的值.This method allows, for example, the HTML content sink to inform the HTTP channel about HTTP-EQUIV headers found in HTML <META> tags. If value is empty and merge is false, the header will be cleared.

- -
void setResponseHeader(
-  in ACString header,
-  in ACString value,
-  in boolean merge
-);
-
- -
参数
- -
-
header
-
指定响应头的名称,不区分大小写(例如"Cache-Control").
-
value
-
指定响应头的值(例如"no-cache").
-
merge
-
如果该参数为true,则新指定的响应头的值会合并到该响应头已有的值的后面.如果指定的响应头不支持(或者说不适合)新旧值的合并操作,则这个参数会被忽略(比如"Content-Type"头就只能有一个值).具体那些响应头会忽略掉这个参数,本文档不会给出.如果该参数的值为false,则新指定的响应头的值会覆盖掉该响应头已有的值.
-
- -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
在响应头还未完全返回的时候调用了该方法(before onStartRequest()).
-
NS_ERROR_ILLEGAL_VALUE
-
If changing the value of this response header is not allowed.
-
- -

visitRequestHeaders()

- -

Call this method to visit all request headers. Calling setRequestHeader() while visiting request headers has undefined behavior. Don't do it!

- -
void visitRequestHeaders(
-  in nsIHttpHeaderVisitor aVisitor
-);
-
- -
参数
- -
-
aVisitor
-
The header visitor instance.
-
- -

visitResponseHeaders()

- -

Call this method to visit all response headers.

- -

{

Calling setResponseHeader() while visiting response headers has undefined behavior. Don't do it!

- -
void visitResponseHeaders(
-  in nsIHttpHeaderVisitor aVisitor
-);
-
- -
参数
- -
-
aVisitor
-
The header visitor instance.
-
- -
可能抛出的异常
- -
-
NS_ERROR_NOT_AVAILABLE
-
If called before the response has been received (before onStartRequest()).
-
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiidleservice/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiidleservice/index.html deleted file mode 100644 index a0dec4ad73..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiidleservice/index.html +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: nsIIdleService -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIIdleService -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIIdleService ---- -

nsIIdleService 的定义文档是:widget/public/nsIIdleService.idl 。 It is scriptable and unfrozen (hasn't changed since Mozilla 1.9a) .

-

概要

-

该服务可使您监测到空闲时间,例如,用户没有进行鼠标或者键盘等操作。您可直接捕获到空闲的时间,但一般,需要注册一个监听。

-

目前 nsIIdleService 服务在 Windows, Mac OS X, and Linux (via XScreenSaver) 等系统上都已实现。

-

实现: @mozilla.org/widget/idleservice;1。创建实例如:

-
var idleService = Components.classes["@mozilla.org/widget/idleservice;1"]
-                            .getService(Components.interfaces.nsIIdleService)
-
-

方法预览

- - - - - - - - - -
void addIdleObserver(in nsIObserver observer, in unsigned long time)
void removeIdleObserver(in nsIObserver observer, in unsigned long time)
-

属性

- - - - - - - - - - - - - -
属性类型描述
idleTimelongThe amount of time in milliseconds that has passed since the last user activity. Read only.
-

方法

-

addIdleObserver()

-

添加一个observer,用于侦听使用者何时离开,及何时归来。

-
void addIdleObserver(
-  in nsIObserver observer,
-  in unsigned long time
-)
-
-
参数 
-
-
- observer
-
- The observer to be notified.
-
-
-
- time
-
-    使用者离开多少秒钟后,开始侦听。
-
-
备注
- - - -

-
Gecko 1.9.2 note
-
从版本 Gecko 1.9.2 开始,增加一个新的侦听消息:‘idle-daily’ 。
-

-

removeIdleObserver()

-

删除observer。

-
void removeIdleObserver(
-  in nsIObserver observer,
-  in unsigned long time
-)
-
-
参数
-
-
- observer
-
- the observer to be removed
-
-
-
- time
-
- 消息侦听的时间(一段时间)。
-
-

备注

-

删除 observer 时,根据指定的 idle 时间来删除。如果已经添加了多个 observer ,则需要删除多次。

-

示例:

-

例一:

-
var idleService = Components.classes["@mozilla.org/widget/idleservice;1"]
-                            .getService(Components.interfaces.nsIIdleService)
-setTimeout(function() { alert(idleService.idleTime) }, 1000)
-// if you don't use the mouse or the keyboard after running this snippet,
-// you'll see a number around 1000 alerted.
-
-

例二:

-
var idleService = Components.classes["@mozilla.org/widget/idleservice;1"]
-                            .getService(Components.interfaces.nsIIdleService)
-var idleObserver = {
-  observe: function(subject, topic, data) {
-    alert("topic: " + topic + "\ndata: " + data);
-  }
-};
-idleService.addIdleObserver(idleObserver, 60); // one minute
-// ...
-// Don't forget to remove the observer using removeIdleObserver!
-idleService.removeIdleObserver(idleObserver, 60);
-
-

Interwiki Language Links

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsilocalfile/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsilocalfile/index.html deleted file mode 100644 index 882450bf87..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsilocalfile/index.html +++ /dev/null @@ -1,478 +0,0 @@ ---- -title: nsILocalFile -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile ---- -

 

- -
-

In Gecko 14 this Interface was merged into the nsIFile interface.

-
- -

 

- -

-
xpcom/io/nsILocalFile.idl脚本化
- - -This interface adds methods to nsIFile that are particular to a file that is accessible via the local file system. - - -
- -
66
- -
- -
Introduced
-
Gecko 1.0
- -
- -
Deprecated
-
Gecko 14
- -
- -
-继承于: nsIFile -最后修改于Gecko 1.0
-

- -

Implemented by: @mozilla.org/file/local;1. To create an instance, use:

- -
var localFile = Components.classes["@mozilla.org/file/local;1"]
-                .createInstance(Components.interfaces.nsILocalFile);
-
- -

Method overview

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void appendRelativeNativePath(in ACString relativeFilePath); Native code only!
void appendRelativePath(in AString relativeFilePath);
ACString getRelativeDescriptor(in nsILocalFile fromFile);
void initWithFile(in nsILocalFile aFile);
void initWithNativePath(in ACString filePath); Native code only!
void initWithPath(in AString filePath);
void launch();
PRLibraryStar load(); Native code only!
FILE openANSIFileDesc(in string mode); Native code only!
PRFileDescStar openNSPRFileDesc(in long flags, in long mode); Native code only!
void reveal();
void setRelativeDescriptor(in nsILocalFile fromFile, in ACString relativeDesc);
- -

Attributes

- - - - - - - - - - - - - - - - - - - - - - - - -
AttributeTypeDescription
diskSpaceAvailablePRInt64The number of bytes available to non-superuser on the disk volume containing the nsILocalFile. Read only.
followLinksPRBool -

Determines whether or not the nsILocalFile will automatically resolve symbolic links.

- By default, this value is false on all non-UNIX systems. As of Mozilla 1.7, this attribute is ignored on UNIX systems.
persistentDescriptorACString -

On some platforms, the value of nsIFile.path may be insufficient to uniquely identify the file on the local file system. The persistent descriptor is intended to be used whenever a nsILocalFile needs to be serialized to disk and later recovered. This string is not intended for display to users.

-
Note: The value of the followLinks attribute is not encoded in the persistent descriptor.
- -

Constants

- - - - - - - - - - - - - - -
ConstantValueDescription
DELETE_ON_CLOSE0x80000000Optional parameter used by openNSPRFileDesc().
- -

Methods

- -

Native code only!

appendRelativeNativePath

- -

Appends a relative, native character encoding, path to the current path of the nsILocalFile object.

- -
void appendRelativeNativePath(
-  in ACString relativeFilePath
-);
-
- -
Parameters
- -
-
relativeFilePath
-
A native relative path. For security reasons, this cannot contain '..' or cannot start with a directory separator '.'. Must be in the native file system character set.
-
- -
Exceptions thrown
- -
-
NS_ERROR_FILE_UNRECOGNIZED_PATH
-
Indicates that relativeFilePath incorrectly begins with a path separator character or otherwise contains invalid characters.
-
- -

appendRelativePath()

- -

Appends a relative native path to the current path of the nsILocalFile object.

- -
void appendRelativePath(
-  in AString relativeFilePath
-);
-
- -
Parameters
- -
-
relativeFilePath
-
A native relative path. For security reasons, this cannot contain '..' or cannot start with a directory separator '.' .
-
- -
Exceptions thrown
- -
-
NS_ERROR_FILE_UNRECOGNIZED_PATH
-
Indicates that relativeFilePath incorrectly begins with a path separator character or otherwise contains invalid characters.
-
- -

getRelativeDescriptor()

- -

Returns a relative file path in an opaque, cross platform format. It is therefore not a native path.

- -
ACString getRelativeDescriptor(
-  in nsILocalFile fromFile
-);
-
- -
Parameters
- -
-
fromFile
-
The file from which the descriptor is relative. There is no defined result if this parameter is null.
-
- -
Return value
- -

An opaque string value with undefined character encoding. This string is not intended for display to users.

- -

The result returned from this method may be used with setRelativeDescriptor() to initialize a nsILocalFile instance.

- -

initWithFile()

- -

Initializes this object with another file.

- -
void initWithFile(
-  in nsILocalFile aFile
-);
-
- -
Parameters
- -
-
aFile
-
The file this becomes equivalent to.
-
- -

Native code only!

initWithNativePath

- -

Used to set the full path that this nsILocalFile references. All current settings will be reset.

- -
void initWithNativePath(
-  in ACString filePath
-);
-
- -
Parameters
- -
-
filePath
-
A string that specifies a platform-specific, full path to a file or directory. Must be in the native file system character set.
-
- -
Exceptions thrown
- -
-
NS_ERROR_FILE_UNRECOGNIZED_PATH
-
Indicates that FilePath is not an absolute file path.
-
- -

initWithPath()

- -

Used to set the full path that this nsILocalFile references. All current settings will be reset.

- -
void initWithPath(
-  in AString filePath
-);
-
- -
Parameters
- -
-
filePath
-
A string that specifies a platform-specific, full path to a file or directory.
-
- -
Exceptions thrown
- -
-
NS_ERROR_FILE_UNRECOGNIZED_PATH
-
Indicates that FilePath is not an absolute file path.
-
- -

launch()

- -

Requests that the operating system attempt to open this file.

- -
void launch();
-
- -
Parameters
- -

None.

- -

Native code only!

load

- -

Returns the result of PR_LoadLibrary() on the file. The caller is responsible for calling PR_UnloadLibrary() on the result.

- -
PRLibraryStar load();
-
- -
Parameters
- -

None.

- -
Return value
- -

A pointer to a PRLibrary.

- -
Example
- -
#include "prlink.h"
-#include "nsError.h"
-#include "nsILocalFile.h"
-
-// Load the DLL corresponding to the given nsILocalFile...
-
-nsresult LoadDLL(nsILocalFile *aLocalFile)
-{
-  PRLibrary *dll;
-  nsresult rv = aLocalFile->Load(&dll);
-  if (NS_FAILED(rv))
-    return rv;
-
-  // Do something with the library now that it is open...
-
-  PR_FreeLibrary(dll);
-  return NS_OK;
-}
-
- -

Native code only!

openANSIFileDesc

- -

Returns the result of fopen() on the file. The caller is responsible for calling fclose() on the result.

- -
FILE openANSIFileDesc(
-  in string mode
-);
-
- -
Parameters
- -
-
mode
-
An ANSI file open mode string, which will be passed to fopen().
-
- -
Return value
- -

A pointer to an ANSI FILE type.

- -
Example
- -
#include <stdio.h>
-#include "nsError.h"
-#include "nsILocalFile.h"
-
-// Read the contents of a nsILocalFile...
-
-nsresult ReadLocalFile(nsILocalFile *aLocalFile)
-{
-  FILE *fp;
-  nsresult rv = aLocalFile->OpenANSIFileDesc("r", &fp);
-  if (NS_FAILED(rv))
-    return rv;
-
-  char buf[512];
-  size_t n;
-
-  while ((n = fread(buf, sizeof(buf), 1, fp)) > 0)
-  {
-    // Do something with n-byte block of data from file...
-  }
-
-  if (ferror(fp) != 0)
-    rv = NS_ERROR_UNEXPECTED;
-
-  fclose(fp);
-  return rv;
-}
-
- -

Native code only!

openNSPRFileDesc

- -

Returns the result of PR_Open() on the file. The caller is responsible for calling PR_Close() on the result.

- -
PRFileDescStar openNSPRFileDesc(
-  in long flags,
-  in long mode
-);
-
- -
Parameters
- -
-
flags
-
-

The PR_Open() flags from nsprpub/pr/include/prio.h, plus optionally DELETE_ON_CLOSE. DELETE_ON_CLOSE may be implemented by removing the file (by path name) immediately after opening it, so beware of possible races; the file should be exclusively owned by this process.

- -

A bitwise combination of the following open flags:

- -
    -
  • PR_RDONLY Open for reading only.
  • -
  • PR_WRONLY Open for writing only.
  • -
  • PR_RDWR Open for reading and writing.
  • -
  • PR_CREATE_FILE If the file does not exist, the file is created. If the file exists, this flag has no effect.
  • -
  • PR_APPEND The file pointer is set to the end of the file prior to each write.
  • -
  • PR_TRUNCATE If the file exists, its length is truncated to 0.
  • -
  • PR_SYNC If set, each write will wait for both the file data and file status to be physically updated.
  • -
  • PR_EXCL With PR_CREATE_FILE, if the file does not exist, the file is created. If the file already exists, no action and null is returned.
  • -
  • DELETE_ON_CLOSE File will be deleted when closed.
  • -
-
-
mode
-
A UNIX-style file permissions value. For example, the octal value 0600 may be used to limit read and write access to the current user of the system. This parameter may be ignored on systems that do not support file permissions.
-
- -
Return value
- -

If the file is successfully opened, returns a pointer to the PRFileDesc created for the newly opened file. Returns a null pointer if the open failed.

- -
Example
- -
#include "prio.h"
-#include "nsError.h"
-#include "nsILocalFile.h"
-
-// Read the contents of a nsILocalFile...
-
-nsresult ReadLocalFile(nsILocalFile *aLocalFile)
-{
-  PRFileDesc *fd;
-  nsresult rv = aLocalFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
-  if (NS_FAILED(rv))
-    return rv;
-
-  char buf[512];
-  PRInt32 n;
-
-  while ((n = PR_Read(fd, buf, sizeof(buf))) > 0)
-  {
-    // Do something with n-byte block of data from file...
-  }
-
-  if (n < 0)
-    rv = NS_ERROR_UNEXPECTED;
-
-  PR_Close(fd);
-  return rv;
-}
-
- -

reveal()

- -

Ask the operating system to open the folder which contains this file or folder. This routine only works on platforms which support the ability to open a folder. See the note in the remarks below.

- -
void reveal();
-
- -
Parameters
- -

None.

- -

setRelativeDescriptor()

- -

Initializes the file to the location relative to fromFile using a string returned by getRelativeDescriptor().

- -
void setRelativeDescriptor(
-  in nsILocalFile fromFile,
-  in ACString relativeDesc
-);
-
- -
Parameters
- -
-
fromFile
-
The file to which the descriptor is relative.
-
relativeDesc
-
The relative descriptor obtained from getRelativeDescriptor().
-
- -

Remarks

- -

The methods initWithNativePath() and appendRelativeNativePath() take string valued parameters that are encoded using the native character encoding. That means, you cannot deal with files whose name contain characters outside the default code page on Windows even though Windows 2000 or later has no problem with them. Therefore, never use these functions unless you are absolutely sure that the path passed to them is always ASCII-only. See nsIFile for more information on the native character encoding.

- -

See also

- - diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprocess/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprocess/index.html deleted file mode 100644 index 1abc109440..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprocess/index.html +++ /dev/null @@ -1,283 +0,0 @@ ---- -title: nsIProcess -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess ---- -

-
xpcom/threads/nsIProcess.idl脚本化
- - -This interface represents an executable process. - - -
-继承于: nsISupports -最后修改于Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)
-

-

Implemented by: @mozilla.org/process/util;1. To create an instance, use:

-
var process = Components.classes["@mozilla.org/process/util;1"]
-              .createInstance(Components.interfaces.nsIProcess);
-
-

Method overview

- - - - - - - - - - - - - - - - - - - - - - - - -
void init(in nsIFile executable);
void initWithPid(in unsigned long pid); 已废弃 Gecko 1.9.2
void kill();
void run(in boolean blocking, [array, size_is(count)] in string args, in unsigned long count);
void runAsync([array, size_is(count)] in string args, in unsigned long count, [optional] in nsIObserver observer, [optional] in boolean holdWeak);
void runw(in boolean blocking, [array, size_is(count)] in wstring args, in unsigned long count);
void runwAsync([array, size_is(count)] in wstring args, in unsigned long count, [optional] in nsIObserver observer, [optional] in boolean holdWeak);
-

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性名称属性类型属性描述
exitValuelongThe value returned by the process upon exit. This is only valid after the process has exited. Read only.
isRunningbooleantrue if the process is running, otherwise false. Only accurate if the process was run with blocking disabled. Read only.
locationnsIFile -

The location of the executable file on disk. Read only.

-

-
Gecko 1.9.1 note
-
This attribute is no longer implemented as of Gecko 1.9.1, and is removed entirely in Gecko 1.9.2.
-

-
pidunsigned longThe process ID of the process. This value is only available after the process has started; in addition, some platforms may not offer this value at all. Read only.
processNamestring -

The name of the process. Read only.

-

-
Gecko 1.9.1 note
-
This attribute is no longer implemented as of Gecko 1.9.1, and is removed entirely in Gecko 1.9.2.
-

-
processSignatureunsigned long -

The process signature. Read only.

-

-
Gecko 1.9.1 note
-
This attribute is no longer implemented as of Gecko 1.9.1, and is removed entirely in Gecko 1.9.2.
-

-
-

方法

-

init()

-

Initializes the nsIProcess with the specified executable file. Once initialized, you can start the process executing by calling run().

-

Note: This function does not work with application bundles on Mac OS X, see bug 307463 for details.

-
void init(
-  in nsIFile executable
-);
-
-
参数
-
-
- executable
-
- The nsIFile executable file to be represented by the nsIProcess object.
-
-

-

initWithPid()

- 已废弃 Gecko 1.9.2 (Firefox 3.6 / Thunderbird 3.1 / Fennec 1.0) -

-

Initializes the nsIProcess to represent an existing process, given that process's ID.

-

-
Gecko 1.9.1 note
-
This method is no longer implemented as of Gecko 1.9.1, and is removed entirely in Gecko 1.9.2.
-

-
void initWithPid(
-  in unsigned long pid
-);
-
-
参数
-
-
- pid
-
- The process ID to begin to represent.
-
-

kill()

-

立即终止该nsIProcess对象所代表的进程,只在该进程是非阻塞方式启动的情况下才有效.

-

-
Gecko 1.9.1 note
-
在Gecko 1.9.1 (Firefox 3.5)之前版本中, 该方法在Windows和Mac OS X下无效.目前此bug已经修复.
-

-
void kill();
-
-
参数
-

无.

-

run()

-

开始执行进程.

-

-
Gecko 1.9.1 note
-
在Gecko 1.9.1 (Firefox 3.5)之前版本中,该方法会返回一个新执行进程的进程ID,目前已经不会返回任何值.
-

-
void run(
-  in boolean blocking,
-  [array, size_is(count)] in string args,
-  in unsigned long count
-);
-
-
参数
-
-
- blocking
-
- 如果为true,则该方法会阻塞,直到所打开的进程关闭为止,如果为false,则该方法会立即返回.
-
- args
-
- An array of count arguments, using the native character set, to be passed to the executable on its command line.
-
- count
-
- 参数args中的参数个数.
-
-

runAsync()

-

Asynchronously runs the process with which the object was initialized, optionally calling an observer when the process finishes running.

-
void runAsync(
-  [array, size_is(count)] in string args,
-  in unsigned long count,
-  in nsIObserver observer, 可选
-  in boolean holdWeak 可选
-);
-
-
Parameters
-
-
- args
-
- An array of arguments to pass into the process, using the native character set. This array must have count entries.
-
- count
-
- The number of arguments passed in the args array.
-
- observer 可选
-
- An observer that will be notified when the process exits. The observer will receive this nsIProcess instance as the subject and "process-finished" or "process-failed" as the topic. The observer will be notified on the main thread.
-
- holdWeak 可选
-
- If true, a weak reference is used to hold the observer.
-
-  
-
-

runw()

-

Executes the file this object was initialized with.

-
void runw(
-  in boolean blocking,
-  [array, size_is(count)] in wstring args,
-  in unsigned long count
-);
-
-
Parameters
-
-
- blocking
-
- If true, this method will block until the process terminates; if false, the method returns immediately.
-
- args
-
- An array of count arguments, using UTF-16, to be passed to the executable on its command line.
-
- count
-
- The number of arguments in the args array.
-
-

runwAsync()

-

Asynchronously runs the process with which the object was initialized, optionally calling an observer when the process finishes running.

-
void runwAsync(
-  [array, size_is(count)] in wstring args,
-  in unsigned long count,
-  in nsIObserver observer, 可选
-  in boolean holdWeak 可选
-);
-
-
Parameters
-
-
- args
-
- An array of arguments to pass into the process, using UTF-16. This array must have count entries.
-
- count
-
- The number of arguments passed in the args array.
-
- observer 可选
-
- An observer that will be notified when the process exits. The observer will receive this nsIProcess instance as the subject and "process-finished" or "process-failed" as the topic. The observer will be notified on the main thread.
-
- holdWeak 可选
-
- If true, a weak reference is used to hold the observer.
-
-

Example

-
// create an nsILocalFile for the executable
-var file = Components.classes["@mozilla.org/file/local;1"]
-                     .createInstance(Components.interfaces.nsILocalFile);
-file.initWithPath("c:\\myapp.exe");
-
-// create an nsIProcess
-var process = Components.classes["@mozilla.org/process/util;1"]
-                        .createInstance(Components.interfaces.nsIProcess);
-process.init(file);
-
-// Run the process.
-// If first param is true, calling thread will be blocked until
-// called process terminates.
-// Second and third params are used to pass command-line arguments
-// to the process.
-var args = ["argument1", "argument2"];
-process.run(false, args, args.length);
-
-

See also

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprompt/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprompt/index.html deleted file mode 100644 index 9bd2106964..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprompt/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: nsIPrompt -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIPrompt -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIPrompt ---- -

-
netwerk/base/public/nsIPrompt.idl脚本化
- - -This is the prompt interface which can be used without knowledge of a parent window. The parentage is hidden by the GetInterface though which it is obtained. - - -
-继承于: nsISupports -最后修改于Gecko 1.8 (Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0)
-

-
- 注: 本接口基本等价于nsIPromptService,只是没有parent nsIDOMWindow这个参数.为了避免重复的文档,下面的所有方法都链接到了nsIPromptService.如果你准备使用这个接口,一定要删除那些方法中的nsIDOMWindow参数.
-

Normally you would use the prompt service as it is more flexible, but sometimes a callback will request an nsIPrompt via nsIInterfaceRequestor.getInterface(). To get an instance, call the nsIWindowWatcher.getNewPrompter().

-

方法概述

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void alert(in wstring dialogTitle, in wstring text);
void alertCheck(in wstring dialogTitle, in wstring text, in wstring checkMsg, inout boolean checkValue);
boolean confirm(in wstring dialogTitle, in wstring text);
boolean confirmCheck(in wstring dialogTitle, in wstring text, in wstring checkMsg, inout boolean checkValue);
PRInt32 confirmEx(in wstring dialogTitle, in wstring text, in unsigned long buttonFlags, in wstring button0Title, in wstring button1Title, in wstring button2Title, in wstring checkMsg, inout boolean checkValue);
boolean prompt(in wstring dialogTitle, in wstring text, inout wstring value, in wstring checkMsg, inout boolean checkValue);
boolean promptPassword(in wstring dialogTitle, in wstring text, inout wstring password, in wstring checkMsg, inout boolean checkValue);
boolean promptUsernameAndPassword(in wstring dialogTitle, in wstring text, inout wstring username, inout wstring password, in wstring checkMsg, inout boolean checkValue);
boolean select(in wstring dialogTitle, in wstring text, in PRUint32 count, [array, size_is(count)] in wstring selectList, out long outSelection);
-

常量

-

nsIPrompt中的按钮标识同样等同于nsIPromptService.Constants中定义的那些.示例代码可以在这里找到: 使用按钮标识

-

相关链接

-

nsIPromptService

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsipromptservice/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsipromptservice/index.html deleted file mode 100644 index b194faca6b..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsipromptservice/index.html +++ /dev/null @@ -1,696 +0,0 @@ ---- -title: nsIPromptService -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService ---- -

-
embedding/components/windowwatcher/public/nsIPromptService.idl脚本化
-该接口用来显示一些简单的对话框.在chrome上下文,你应该使用该接口的所属方法来替代常规的DOM方法,例如 window.alert, window.confirm, 等. - -
-继承于: nsISupports -最后修改于Gecko 1.7.5
-

-

You can define access keys (or keyboard shortcuts) for buttons by including an ampersand ("&") in front of the character that should be the access key for that button. If you need to include an ampersand in the button's text, use two of them, like this: "&&".

-
- Note: Some of these interface methods use out and inout parameters. In C++, out parameters are pointers. For JavaScript, they are extra work, as you can't use an out parameter directly. You need to wrap them in a temporary object, which can be either empty or have a value property set to the out parameter type. For more information on out parameters and JavaScript refer to Working with out parameters.
-

该接口由: @mozilla.org/embedcomp/prompt-service;1 组件实现,下面的代码可以得到一个promptService对象实例:

-
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                              .getService(Components.interfaces.nsIPromptService);
-
-

方法概述

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void alert(in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText);
void alertCheck(in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in wstring aCheckMsg, inout boolean aCheckState);
boolean confirm(in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText);
boolean confirmCheck(in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in wstring aCheckMsg, inout boolean aCheckState);
PRInt32 confirmEx(in nsIDOMWindow aParent,in wstring aDialogTitle,in wstring aText, in unsigned long aButtonFlags,in wstring aButton0Title, in wstring aButton1Title,in wstring aButton2Title,in wstring aCheckMsg, inout boolean aCheckState);
boolean prompt(in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aValue, in wstring aCheckMsg, inout boolean aCheckState);
boolean promptUsernameAndPassword(in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aUsername, inout wstring aPassword, in wstring aCheckMsg, inout boolean aCheckState);
boolean promptPassword(in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, inout wstring aPassword, in wstring aCheckMsg, inout boolean aCheckState);
boolean select(in nsIDOMWindow aParent, in wstring aDialogTitle, in wstring aText, in PRUint32 aCount, [array, size_is(aCount)] in wstring aSelectList, out long aOutSelection);
-

常量

-

The following flags are combined to form the aButtonFlags parameter passed to confirmEx. All flags are defined as unsigned long constants and can be accessed as Components.interfaces.nsIPromptService.flagname from JavaScript and as nsIPromptService::flagname from C++.

-

Button position flags

-

On Linux and Mac, button 2 is on the left of the prompt, while buttons 1 and 0 are on the right. On Windows and OS/2, the buttons are centred in the order 0, 2, 1.

- - - - - - - - - - - - - - - - - - - - - - - -
ConstantValueDescription
BUTTON_POS_01This is usually the button used to confirm the prompt. It typically has the label "OK", "Yes" or "Save".
BUTTON_POS_1256This is the button used to cancel the prompt. It typically has the label "Cancel" or "No". It is equivalent to pressing the Escape key (or Cmd+. on the Mac), or closing the window through the OS controls.
BUTTON_POS_265536This button can be used to give the user a choice of options, but still allowing the user to cancel the prompt. For instance, it might have the label "Don't Save".
-

Button title flags

-

These flags are used along with Button position flags to set the labels of buttons in the prompt.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ConstantValueDescription
BUTTON_TITLE_OK1 These flags are used to select standard labels from the user's current locale.
BUTTON_TITLE_CANCEL2
BUTTON_TITLE_YES3
BUTTON_TITLE_NO4
BUTTON_TITLE_SAVE5
BUTTON_TITLE_DONT_SAVE6
BUTTON_TITLE_REVERT7
BUTTON_TITLE_IS_STRING127This flag indicates that the label is passed as a separate string. Use this for labels that don't match one of the constants above.
-

Button default flags

-

These flags are used to select which button is the default.

- - - - - - - - - - - - - - - - - - - - - - - -
ConstantValueDescription
BUTTON_POS_0_DEFAULT0 
BUTTON_POS_1_DEFAULT16777216 
BUTTON_POS_2_DEFAULT33554432 
-

BUTTON_DELAY_ENABLE

-

BUTTON_DELAY_ENABLE causes the buttons to be initially disabled. They are enabled after a timeout expires. The implementation may interpret this loosely, as the intent is to ensure that the user does not click through a security dialog too quickly. Strictly speaking, the implementation could choose to ignore this flag. A delay can be useful not only to give the user more time to think before acting, but also as a countermeasure against malicious web sites that intentionally create a race condition whereby the user intends to click or type a key responding, for example, to the web site's prompt but the security dialog pops up unexpectedly and its button is unintentionally activated.

- - - - - - - - - - - - - -
ConstantValueDescription
BUTTON_DELAY_ENABLE67108864 
-

Standard Buttons flags

- - - - - - - - - - - - - - - - - - -
ConstantValueDescription
STD_OK_CANCEL_BUTTONS513 -

selects the standard set of OK/Cancel buttons.

- (BUTTON_TITLE_OK *BUTTON_POS_0) +(BUTTON_TITLE_CANCEL * BUTTON_POS_1)
STD_YES_NO_BUTTONS1027 -

selects the standard set of Yes/No buttons.

- (BUTTON_TITLE_YES *BUTTON_POS_0) +(BUTTON_TITLE_NO * BUTTON_POS_1)
-

方法

-

alert()

-

alert 方法显示一个警告对话框,包含一个确认按钮. 除了可以设置对话框的标题以外,效果和window.alert全都相同 . 在chrome上下文,你应该使用该xpcom方法来替代window.alert.

-
void alert(
-  in nsIDOMWindow aParent,
-  in wstring aDialogTitle,
-  in wstring aText
-);
-
-
参数
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow.
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
-

代码示例:alert_example.

-

alertCheck()

-

显示一个警告对话框,包含一个确认按钮和一个复选框.

-
void alertCheck(
-  in nsIDOMWindow aParent,
-  in wstring aDialogTitle,
-  in wstring aText,
-  in wstring aCheckMsg,
-  inout boolean aCheckState
-);
-
-
参数
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow..
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
- aCheckMsg
-
- 复选框的说明文字.
-
- aCheckState
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.
-
-

代码示例:alertCheck_example.

-

confirm()

-

显示一个确认对话框,包含一个确认按钮和一个取消按钮.

-
boolean confirm(
-  in nsIDOMWindow aParent,
-  in wstring aDialogTitle,
-  in wstring aText
-);
-
-
参数
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow.
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
-
返回值
-
-
- 点确定按钮返回 true , 点取消按钮返回 false
-
-

代码示例:confirm_example.

-

confirmCheck()

-

显示一个对话框,包含一个确认按钮,一个取消按钮和一个复选框.

-

代码示例:confirm_example.

-
boolean confirmCheck(
-  in nsIDOMWindow aParent,
-  in wstring aDialogTitle,
-  in wstring aText,
-  in wstring aCheckMsg,
-  inout boolean aCheckState
-);
-
-
参数
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow.
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
- aCheckMsg
-
- 复选框的说明文字.
-
- aCheckState
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.
-
-
返回值
-
-
- 点确定按钮返回 true , 点取消按钮返回 false
-
-

confirmEx()

-

Puts up a dialog with up to 3 buttons and an optional, labeled checkbox.

-

The Buttons are numbered 0 - 2. The implementation can decide what order the buttons appear in, and it may not be simply right-to-left (2, 1, 0) or left-to-right (0, 1, 2). See bug 624043 for more on this. Button 0 is the default button unless one of the Button Default Flags is specified (see Button default flags).

-

A button may use a predefined title, specified by one of the Button Title Flags values. Each title value can be multiplied by a position value to assign the title to a particular button. If BUTTON_TITLE_IS_STRING is used for a button, the string parameter for that button will be used. If the value for a button position is zero, the button will not be shown.

-

The following Example creates a Dialog with an OK button an an custom button description.

-

aButtonFlags = (BUTTON_POS_0) * (BUTTON_TITLE_OK) +
- (BUTTON_POS_1) * (BUTTON_TITLE_IS_STRING) +
- BUTTON_POS_1_DEFAULT;

-
- confirmEx always returns 1 if the user closes the window using the close button in the titlebar! bug 345067
-
PRInt32 confirmEx(
-  in nsIDOMWindow  aParent,
-  in wstring aDialogTitle,
-  in wstring aText,
-  in unsigned long aButtonFlags,
-  in wstring aButton0Title,
-  in wstring aButton1Title,
-  in wstring aButton2Title,
-  in wstring aCheckMsg,
-  inout boolean aCheckState
-);
-
-
参数
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow.
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
- aButtonFlags
-
- aButtonFlags is a combination of Button flags as described in Using the button flags below.
-
- aButton0Title
-
- caption displayed for button 0 if(BUTTON_TITLE_IS_STRING*BUTTON_TITLE_POS_0) flags are set in aButtonFlags
-
- aButton1Title
-
- caption displayed for button 1 if(BUTTON_TITLE_IS_STRING*BUTTON_TITLE_POS_1) flags are set in aButtonFlags
-
- aButton2Title
-
- caption displayed for button 2 if(BUTTON_TITLE_IS_STRING*BUTTON_TITLE_POS_2) flags are set in aButtonFlags
-
- aCheckMsg
-
-  复选框的说明文字. 如果值设为Null,则复选框不会显示.
-
- aCheckState
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.
-
-
返回值
-
-
- 按下按钮的索引.
-
-

prompt()

-

显示一个对话框,包含一个文本框,一个可选的复选框.

-

代码示例:prompt_example.

-
boolean prompt(
-  in nsIDOMWindow aParent,
-  in wstring aDialogTitle,
-  in wstring aText,
-  inout wstring aValue,
-  in wstring aCheckMsg,
-  inout boolean aCheckState
-);
-
-
参数
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow.
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
- aValue
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性值就是文本输入框的的初始值.当用户点击确认按钮关闭对话框时,变量的value属性会存储下文本输入框的最后确定值.其他方法关闭对话框时,变量的value属性值不会改变.该变量初始化时可以包含一个类型为字符串值的value属性或者是空对象.
-
- aCheckMsg
-
- 复选框的说明文字. 如果值设为Null,则复选框不会显示.
-
- aCheckState
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.
-
-
返回值
-
-
- 点确定按钮返回 true , 点取消按钮返回 false
-
-

promptUsernameAndPassword()

-

显示一个对话框,内部包含一个文本输入框,一个密码输入框,和一个可选的复选框.

-

代码示例:promptUsernameAndPassword_example.

-
boolean promptUsernameAndPassword(
-  in nsIDOMWindow aParent,
-  in wstring aDialogTitle,
-  in wstring aText,
-  inout wstring aUsername,
-  inout wstring aPassword,
-  in wstring aCheckMsg,
-  inout boolean aCheckState
-);
-
-
参数
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow.
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
- aUsername
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性值就是用户名输入框的的初始值.当用户点击确认按钮关闭对话框时,变量的value属性会存储下用户名输入框的最后确定值.其他方法关闭对话框时,变量的value属性值不会改变.该变量初始化时可以包含一个类型为字符串值的value属性或者是空对象.
-
- aPassword
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性值就是密码输入框的的初始值.当用户点击确认按钮关闭对话框时,变量的value属性会存储下密码输入框的最后确定值.其他方法关闭对话框时,变量的value属性值不会改变.该变量初始化时可以包含一个类型为字符串值的value属性或者是空对象.
-
- aCheckMsg
-
- 复选框的说明文字. 如果值设为Null,则复选框不会显示.
-
- aCheckState
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.
-
-
返回值
-
-
- 点确定按钮返回 true , 点取消按钮返回 false
-
-

promptPassword()

-

显示一个对话框,包含一个密码框,一个可选的复选框.

-

代码示例:promptPassword_example.

-
boolean promptPassword(
-  in nsIDOMWindow aParent,
-  in wstring aDialogTitle,
-  in wstring aText,
-  inout wstring aPassword,
-  in wstring aCheckMsg,
-  inout boolean aCheckState
-);
-
-
参数
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow.
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
- aPassword
-
- 该变量是一个对象引用,当对话框打开时,变量的value属性值就是密码输入框的的初始值.当用户点击确认按钮关闭对话框时,变量的value属性会存储下密码输入框的最后确定值.其他方法关闭对话框时,变量的value属性值不会改变.该变量初始化时可以包含一个类型为字符串值的value属性或者是空对象.
-
- aCheckMsg
-
- 复选框的说明文字. 如果值设为Null,则复选框不会显示.
-
- aCheckState
-
-     该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.
-
-
返回值
-
-
- 点确定按钮返回 true , 点取消按钮返回 false
-
-

select()

-

显示一个对话框,包含一个单项选择的字符串列表.

-

代码示例:select_example.

-
boolean select(
-  in  nsIDOMWindow aParent,
-  in  wstring       aDialogTitle,
-  in  wstring       aText,
-  in  PRUint32     aCount,
-  [array, size_is(aCount)] in wstring aSelectList,
-  out long         aOutSelection
-);
-
-
-
- aParent
-
- 对话框的父窗口,如果该值设为 null,则父窗口为当前激活的窗口 nsIWindowWatcher.activeWindow.
-
- aDialogTitle
-
- 对话框的标题文字.
-
- aText
-
- 对话框的内容文字.
-
- aCount
-
- 参数aSelectList的数组长度.
-
- aSelectList
-
- 构成字符串列表的字符串数组.
-
- aOutSelection
-
- 该变量是一个对象引用,当用户选择某个项目后,变量的value属性值存储了用户所选列表项目的索引值.
-
-
返回值
-
-
- 点确定按钮返回 true , 点取消按钮返回 false
-
-

代码示例

-

 

-

alert example

-

alert() 显示一个简单的对话框.

-

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-prompts.alert(null, "Title of this Dialog", "Hello! You have now been alerted.");
-
-

alertCheck example

-

alertCheck() 显示一个包含复选框的对话框

-

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-var check = {value: false};                      // default the checkbox to false
-
-prompts.alertCheck(null, "Title of this Dialog", "Hello! You have now been alerted.",
-                   "And this is a checkbox", check);
-
-// check.value is now true if the box was checked and false if the box was cleared
-
-

confirm example

-

confirm() 显示一个提示框,内部包含一个确认按钮和一个取消按钮.

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-var result = prompts.confirm(null, "Title of this Dialog", "Are you sure?");
-
-// result is now true if OK was clicked, and false if cancel was clicked
-
-

confirmCheck example

-

confirmCheck 显示一个提示框,内部包含一个确认按钮,一个取消按钮,一个复选框.

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-var check = {value: true};                   // default the checkbox to true
-
-var result = prompts.confirmCheck(null, "Title of this Dialog", "Are you sure?",
-                                  "Don't ask again", check);
-
-// check.value is now true if the box was checked AND OK was pressed, false if
-// the box was cleared AND OK was pressed, and is the default of true if Cancel was pressed.
-
-

confirmEx example

-

confirmEx()  显示一个对话框,内部包含三个或三个以下的按纽,和一个可选的复选框.

-

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-var check = {value: false};                  // default the checkbox to false
-
-var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_SAVE +
-            prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_IS_STRING  +
-            prompts.BUTTON_POS_2 * prompts.BUTTON_TITLE_CANCEL;
-// This value of flags will create 3 buttons. The first will be "Save", the
-// second will be the value of aButtonTitle1, and the third will be "Cancel"
-
-var button = prompts.confirmEx(null, "Title of this Dialog", "What do you want to do?",
-                               flags, "", "Button 1", "", null, check);
-
-// The checkbox will be hidden, and button will contain the index of the button pressed,
-// 0, 1, or 2.
-
-

prompt example

-

prompt() 显示一个对话框,内部包含一个文本输入框.

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-var check = {value: false};                  // default the checkbox to false
-
-var input = {value: "Bob"};                  // default the edit field to Bob
-
-var result = prompts.prompt(null, "Title", "What is your name?", input, null, check);
-
-// result is true if OK is pressed, false if Cancel. input.value holds the value of the edit field if "OK" was pressed.
-
-

promptUsernameAndPassword example

-

promptUsernameAndPassword() 显示一个对话框,内部包含一个文本输入框,一个密码输入框和一个可选的复选框.

-

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-var username = {value: "user"};              // default the username to user
-
-var password = {value: "pass"};              // default the password to pass
-
-var check = {value: true};                   // default the checkbox to true
-
-var result = prompts.promptUsernameAndPassword(null, "Title", "Enter username and password:",
-                                               username, password, "Save", check);
-
-// result is true if OK was pressed, false if cancel was pressed. username.value,
-// password.value, and check.value are set if OK was pressed.
-
-

promptPassword example

-

promptPassword() 显示一个对话框,内部包含一个密码输入框和一个可选的复选框.

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-var password = {value: "pass"};              // default the password to pass
-
-var check = {value: true};                   // default the checkbox to true
-
-var result = prompts.promptPassword(null, "Title", "Enter password:", password, null, check);
-
-// result is true if OK was pressed, false if cancel was pressed. password.value is
-// set if OK was pressed. The checkbox is not displayed.
-
-

select example

-

select() 显示一个对话框,内部是一个包含多个选项的列表框.

-

-
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                        .getService(Components.interfaces.nsIPromptService);
-
-var items = ["Hello", "Welcome", "Howdy", "Hi", ":)"]; // list items
-
-var selected = {};
-
-var result = prompts.select(null, "Title", "What greeting do you want?", items.length,
-                            items, selected);
-
-// result is true if OK was pressed, false if cancel. selected is the index of the item array
-// that was selected. Get the item using items[selected.value].
-
-

相关链接

- -

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiscriptableunicodeconverter/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiscriptableunicodeconverter/index.html deleted file mode 100644 index fe406f1bba..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiscriptableunicodeconverter/index.html +++ /dev/null @@ -1,609 +0,0 @@ ---- -title: nsIScriptableUnicodeConverter -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptableUnicodeConverter -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptableUnicodeConverter ---- -

-
intl/uconv/idl/nsIScriptableUConv.idl脚本化
- - -This interface is a Unicode encoder for use by scripts. - - -
-继承于: nsISupports -最后修改于Gecko 1.8 (Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0)
-

-

Implemented by: @mozilla.org/intl/scriptableunicodeconverter. To create an instance, use:

-
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
-                .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
-
-

Method overview

- - - - - - - - - - - - - - - - - - - - - -
ACString ConvertFromUnicode(in AString aSrc);
ACString Finish();
AString ConvertToUnicode(in ACString aSrc);
AString convertFromByteArray([const,array,size_is(aCount)] in octet aData, in unsigned long aCount);
void convertToByteArray(in AString aString,[optional] out unsigned long aLen,[array, size_is(aLen),retval] out octet aData);
nsIInputStream convertToInputStream(in AString aString);
-

Attributes

- - - - - - - - - - - - - -
AttributeTypeDescription
charsetstringCurrent character set. Throws NS_ERROR_UCONV_NOCONV if the requested charset is not supported.
-

Methods

-

ConvertFromUnicode()

-

Converts the data from Unicode to one Charset. Returns the converted string. After converting, Finish should be called and its return value appended to this return value.

-
ACString ConvertFromUnicode(
-  in AString aSrc
-);
-
-

Finish()

-

Returns the terminator string. Should be called after ConvertFromUnicode() and appended to that function's return value.

-
ACString Finish();
-
-

ConvertToUnicode()

-

Converts the data from one Charset to Unicode.

-
AString ConvertToUnicode(
-  in ACString aSrc
-);
-
-

convertFromByteArray()

-

Converts an array of bytes to a unicode string.

-
AString convertFromByteArray(
-  [const,array,size_is(aCount)] in octet aData,
-  in unsigned long aCount
-);
-
-

convertToByteArray()

-

Convert a unicode string to an array of bytes. Finish does not need to be called.

-
void convertToByteArray(in AString aString,
-  out unsigned long aLen, 可选
-  [array, size_is(aLen),retval] out octet aData
-);
-
-

convertToInputStream()

-

Converts a Unicode string to an input stream. The bytes in the stream are encoded according to the charset attribute. The returned stream is non-blocking.

-
nsIInputStream convertToInputStream(
-  in AString aString
- );
-
-
Parameters
-
Return value
-

An nsIInputStream that will present the text specified in aString as its data.

- -
-
-

Examples

-

See Reading textual data and Writing textual data for examples.

-

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsisyncmessagesender/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsisyncmessagesender/index.html deleted file mode 100644 index 1af1e116c3..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsisyncmessagesender/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: nsISyncMessageSender -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsISyncMessageSender -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsISyncMessageSender ---- -

-
content/base/public/nsIMessageManager.idl脚本化
- - -Handles sending messages synchronously to a destination frame. - - -
- -
1.0
- -
66
- -
- -
- -
Introduced
-
Gecko 2.0
- -
- -
-继承于: nsIFrameMessageManager -最后修改于Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)
-

-

方法概述

- - - - - - -
void sendSyncMessage(in messageName, in JSON, in [array] jsObjects);
-

sendSyncMessage()

-

同步发送一条短消息.

-
void sendSyncMessage(
-  in DOMString messageName,
-  in DOMString json,
-);
-
-
Parameters
-
-
- messageName
-
- 消息的名称.
-
- json
-
- 一个JSON格式的字符串,代表了要发送的数据.
-
-

相关链接

- diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitimer/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitimer/index.html deleted file mode 100644 index 24cfb2eb4f..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitimer/index.html +++ /dev/null @@ -1,285 +0,0 @@ ---- -title: nsITimer -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsITimer -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsITimer ---- -
-
-

nsITimer 接口的功能是:在指定延迟后唤醒一个程序。

-

nsITimer 的定义文档: xpcom/threads/nsITimer.idl 。It is scriptable and unfrozen (hasn't changed since 1.9.1) .

-

继承自: nsISupports

-

实现: @mozilla.org/timer;1。创建实例如:

-
var timer = Components.classes["@mozilla.org/timer;1"]
-                    .createInstance(Components.interfaces.nsITimer);
-
-
-

方法预览

-
- Edit section
- - - - - - - - - - - - - - - -
void initWithCallback(in nsITimerCallback aCallback, in unsigned long aDelay, in unsigned long aType);
[noscript] void initWithFuncCallback(in nsITimerCallbackFunc aCallback, in voidPtr aClosure, in unsigned long aDelay, in unsigned long aType);
void init(in nsIObserver aObserver, in unsigned long aDelay, in unsigned long aType);
void cancel();
-
-
-

属性

-
- Edit section
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AttributeTypeDescription
delayunsigned longThe timeout delay in millisecond.
typeunsigned longDefines the timer type: one shot, repeating slack or repeating precise. Must be one of the constants defined under Constants on this page
callbackreadonly nsITimerCallback The nsITimerCallback object passed to initWithCallback().
closure[noscript] readonly voidPtr -

The opaque pointer pass to initWithFuncCallback().

-
targetnsIEventTarget The nsIEventTarget to which the callback is dispatched.  This target must be set before calling any of the initialization methods.
-
-
-

常量

-
- Edit section
- - - - - - - - - - - - - - - - - - - - - - - -
ConstantValueDescription
TYPE_ONE_SHOT0Type of a timer that fires once only.
TYPE_REPEATING_SLACK1After firing, the timer is stopped and not restarted until its callback completes. Specified timer period will be at least the time between when processing for last firing the callback completes and when the next firing occurs.
TYPE_REPEATING_PRECISE2This repeating timer aims to have constant period between firings. The processing time for each timer callback should not influence the timer period. However, if the processing for the last timer firing could not be completed until just before the next firing occurs, then you could have two timer notification routines being executed in quick succession.
-
-
-

方法

-
- Edit section
-
-

initWithCallback()

-
- Edit section
-

Initialize a timer to fire after the given millisecond interval. This version takes a function to call and a closure to pass to that function.

-
 void initWithCallback (
-   in nsITimerCallback aCallback,
-   in unsigned long aDelay,
-   in unsigned long aType
- );
-
-
-
Parameters
-
- Edit section
-
-
- aFunc
-
- nsITimerCallback interface to call when timer expires.
-
-
-
- aDelay
-
- timeout delay in milliseconds.
-
-
-
- aType
-
- Defines the timer type: one shot, repeating slack or repeating precise. Must be one of the constants defined under Constants on this page.
-
-
-
-
-

initWithFuncCallback()

-
- Edit section
-

Initialize a timer to fire after the given millisecond interval. This version takes a function to call and a closure to pass to that function.

-
 [noscript] void initWithFuncCallback(
-   in nsTimerCallbackFunc aCallback,
-   in voidPtr aClosure,
-   in unsigned long aDelay,
-   in unsigned long aType
- );
-
-
-
Parameters
-
- Edit section
-
-
- aFunc
-
- a nsITimerCallbackFunc interface compatible function to call when timer fires.
-
-
-
- aClosure
-
- An opaque pointer to pass to that function.
-
-
-
- aDelay
-
- timeout delay in milliseconds.
-
-
-
- aType
-
- Defines the timer type: one shot, repeating slack or repeating precise. Must be one of the constants defined under Constants on this page.
-
-
-
-
-

init()

-
- Edit section
-

Initialize a timer that will fire after the specified delay. A user must keep a reference to this timer till it is no longer needed or has been canceled.

-
 void init(
-   in nsIObserver aObserver,
-   in unsigned long aDelay,
-   in unsigned long aType
- );
-
-
-
Parameters
-
- Edit section
-
-
- aObserver
-
- A callback Object, that is capable listening to timer events. If the timer fires, the observer will be notified via the nsIObserver Interface. The subject is set to the nsITimer Object which fired, the topic is equal to "timer-callback" and data is always set to null.
-
-
-
- aDelay
-
- timeout delay in milliseconds.
-
-
-
- aType
-
- Defines the timer type: one shot, repeating slack or repeating precise. Must be one of the constants defined under Constants on this page.
-
-
-
-
-

cancel()

-
- Edit section
-

Cancels the timer. This method works on all types, not just on repeating timers -- you might want to cancel a TYPE_ONE_SHOT timer, and even reuse it by re-initializing it (to avoid object destruction and creation costs by conserving one timer instance).

-
 void cancel();
-
-
-
Parameters
-
- Edit section
-

None.

-
-
-
-
-

备注

-
- Edit section
-

TYPE_REPEATING_SLACK timer is the preferable repeating timer type for most situations

-
-
-

 

-
- 实例
-
- Edit section
-
 // we need a nsITimerCallback
- compatible...
- // ... interface for the callbacks.
- var event
-   = { notify: function(timer) { alert("Fire!"); } }
-
- // Now it is time to create the timer...
- var timer
-   = Components.classes["@mozilla.org/timer;1"]
-       .createInstance(Components.interfaces.nsITimer);
-
- // ... and to initialize it, we want to call event.notify() ...
- // ... one time after exactly ten second.
- timer.initWithCallback(
-   event,
-   10000,
-   Components.interfaces.nsITimer.TYPE_ONE_SHOT);
-
-

 

-
-
-

请参阅

-
- Edit section
-

nsITimerCallbackFunc , nsITimerCallback

-
-
-
- -

标记:

-
- -
-

 

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitraceablechannel/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitraceablechannel/index.html deleted file mode 100644 index ce7c6deb2f..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitraceablechannel/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: nsITraceableChannel -slug: Mozilla/Tech/XPCOM/Reference/Interface/NsITraceableChannel -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/NsITraceableChannel ---- -

-
netwerk/base/public/nsITraceableChannel.idl脚本化
-这个接口用于允许拦截 HTTP 流量。It is implemented by nsIHttpChannel. - -
- -
1.0
- -
66
- -
- -
- -
Introduced
-
Gecko 1.9.0.4
- -
- -
-继承于: nsISupports -最后修改于Gecko 1.9.0.4
-

-

使用这个接口的典型方式如下:

- -

之后,你的 nsIStreamListener 实现将会获取到响应数据(response data),并且能够传递数据到原始的 nsIStreamListener(可能会修改它)。

-

See nsITraceableChannel, Intercept HTTP Traffic for a more detailed description with code samples.

-

See Modify URL before loading page in firefox for an overview of how to modify a request before it is made.

-

Method overview

- - - - - - -
nsIStreamListener setNewListener(in nsIStreamListener aListener);
-

Methods

-

setNewListener()

-

用一个新的来替换该通道的当前监听器,返回先前分配给该通道的监听器。

-
nsIStreamListener setNewListener(
-  in nsIStreamListener aListener
-);
-
-
参数
-
-
- aListener
-
- An nsIStreamListener to be notified of events on the HTTP channel.
-
-
返回值
-

该通道的前一个监听器。Each listener call through to the previous listener for every call, in order to establish a call chain to allow all interested parties a chance to act on each event.

-

实现 nsIStreamListener

-

一个 nsIStreamListener 接口传递给 setNewListener() 需要实现下列的方法,这是通过调用(这些方法)来通知它在 HTTP stream 上发生的事件:

- -
- Note: It is critical that you pass along requests to the previous listener as soon as possible -- especially for onStartRequest.
-

Channels may restrict when you may replace the listener. In particular, listeners typically should not be replaced after onStartRequest has been called.

diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiuri/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiuri/index.html deleted file mode 100644 index d133861ac3..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiuri/index.html +++ /dev/null @@ -1,407 +0,0 @@ ---- -title: nsIURI -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIURI -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIURI ---- -

-
netwerk/base/public/nsIURI.idl脚本化
- - -这是具有国际化支持的统一资源标识符的接口,提供允许设置和查询URI基本组件的属性以及用于在URI上执行基本操作的方法。 - - -
-继承于: nsISupports -最后修改于Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3)
-

- -

细节请查看下列 RFCs:

- - - -

nsIURI的子类,  例如 nsIURL, 加强了URI未来的结构化.

- -

为了创建一个 nsIURI 对象, 你应该如此使用 nsIIOService.newURI():

- -
function makeURI(aURL, aOriginCharset, aBaseURI) {
-  var ioService = Components.classes["@mozilla.org/network/io-service;1"]
-                  .getService(Components.interfaces.nsIIOService);
-  return ioService.newURI(aURL, aOriginCharset, aBaseURI);
-}
-
- -

一个 URI 的组件

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
prePathpath
scheme userPass host port ref
ftp://username@password@hostname:portnumber/pathname?query=value#ref
- -

函数预览

- - - - - - - - - - - - - - - - - - - - - - -
nsIURI clone();
nsIURI cloneIgnoringRef();
boolean equals(in nsIURI other);
boolean equalsExceptRef(in nsIURI other);
AUTF8String resolve(in AUTF8String relativePath);
boolean schemeIs(in string scheme);
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类别描述
asciiHostACString -

The URI host with an ASCII compatible encoding. Follows the IDNA draft specification for converting internationalized domain names (UTF-8) to ASCII for compatibility with existing Internet infrastructure. Read only.

- -
-

Note: IPv6 addresses are not enclosed in square brackets.

-
-
asciiSpecACString (US-ASCII)The URI spec with an ASCII compatible encoding. The host portion follows the IDNA draft spec. Other parts are URL-escaped per the rules of RFC3986. The result is strictly ASCII. Read only.
hasRefbooleanReturns if there is a reference portion (the part after the "#") of the URI.
-
-
hostAUTF8String -

The host is the Internet domain name to which this URI refers. It could be an IPv4 (or IPv6) address literal. If supported, it could be a non-ASCII internationalized domain name.

- -
Exceptions thrown
- -
-
NS_ERROR_FAILURE
-
If host is not applicable to the URI scheme (e.g. about:blank)
-
- -
Note: Characters are not escaped. IPv6 addresses are not enclosed in square brackets.
-
hostPortAUTF8String -

The "host:port" part of the URI (or simply the host, if port is -1).

- -
Exceptions thrown
- -
-
NS_ERROR_FAILURE
-
If hostPort is not applicable to the URI scheme (e.g. about:blank)
-
- -
Note: Characters are not escaped.
-
originCharsetACString -

The charset of the document from which this URI originated. An empty value implies UTF-8.

- If this value is something other than UTF-8 then the URI components (for example spec, prePath, username, and so on) are all fully URL-escaped. Otherwise, the URI components may contain unescaped multibyte UTF-8 characters. Read only.
passwordAUTF8String -

The optional password, assuming the preHost consists of "username:password".

- -
Exceptions thrown
- -
-
NS_ERROR_FAILURE
-
If password is not applicable to the URI scheme (e.g. about:blank)
-
- -

Note: Some characters may be escaped.

-
pathAUTF8String -

The path, typically including at least a leading '/' (but may also be empty, depending on the protocol).

-
Note: Some characters may be escaped.
portlong -

The URI's port. A port value of -1 corresponds to the protocol's default port (for example -1 implies port 80 for HTTP URIs).

- -
Exceptions thrown
- -
-
NS_ERROR_FAILURE
-
If port is not applicable to the URI scheme (e.g. about:blank)
-
-
prePathAUTF8String -

The prePath returns the string before the path (such as "scheme://user:password@host:port").

- -

This is related to the Web Origin Concept of RFC6454.

- -

This is useful for authentication, managing sessions, or for checking the origin of an URI to prevent cross-site scripting attacks while using methods such as window.postMessage().

-
Note: Some characters may be escaped.
Read only.
refAUTF8String -

Returns the reference portion (the part after the "#") of the URI. If there is not one, an empty string is returned.

-
Note: Some characters may be escaped.
schemeACString (US-ASCII) -

The scheme is the protocol to which this URI refers. The scheme is restricted to the US-ASCII charset per RFC3986.

- -
Warning: Setting this is highly discouraged outside of a protocol handler implementation, since doing so will generally lead to unpredictable results.
-
specAUTF8String -

Returns a string representation of the URI. Setting the spec causes the new spec to be parsed using the rules for the scheme the URI currently has. If the string cannot be parsed as a URI, NS_ERROR_MALFORMED_URI thrown.

- -
Warning: Because parsing the string is done using the current URI's scheme, setting the spec to a URI with a different scheme will produce incorrect results. Therefore, only protocol handler implementations should do this.
- -

If the URI stores information from the nsIIOService interface's nsIIOService.newURI() call that created it, other than just the parsed string, the behavior of this information when setting the spec attribute is undefined.

-
Note: Some characters may be escaped.
specIgnoringRefAUTF8StringReturns a string representation of the URI without the ref (part after the #) portion.
-
-
Note: Some characters may be escaped.
usernameAUTF8String -

The optional username, assuming the preHost consists of "username:password".

- -
Exceptions thrown
- -
-
NS_ERROR_FAILURE
-
If username is not applicable to the URI scheme (e.g. about:blank)
-
-
Note: Some characters may be escaped.
userPassAUTF8String -

The "username:password" (or username only if the value doesn't contain a ':').

- -
Exceptions thrown
- -
-
NS_ERROR_FAILURE
-
If userPass is not applicable to the URI scheme (e.g. about:blank)
-
-
Note: Some characters may be escaped.
- -

Methods

- -

clone()

- -

Clones the URI, returning a new nsIURI object.

- -
Note: For some protocols, this is more than just an optimization. For example, under Mac OS X, the spec of a file URI doesn't necessarily uniquely identify a file, since two volumes can have the same name.
- -
nsIURI clone();
-
- -
Parameters
- -

None.

- -
Return value
- -

An nsIURI object that represents the same URI as the current nsIURI.

- -

cloneIgnoringRef()

- -

Clones the current URI, clearing the 'ref' attribute in the clone.

- -
nsIURI cloneIgnoringRef();
-
- -
Parameters
- -

None.

- -
Return value
- -

An nsIURI object that represents the same URI as the current nsIURI without the 'ref' attribute.

- -

equals()

- -

Compares the current URI with another URI.

- -
Note: This is more than a string comparison, as two different URI strings can represent the same location. For example, comparing "http://foo.com:80/" and "http://foo.com/" will return true.
- -
boolean equals(
-  in nsIURI other
-);
-
- -
Parameters
- -
-
other
-
Another nsIURI to compare to.
-
- -
Return value
- -

true if the two URIs represent the same location; otherwise false.

- -

equalsExceptRef()

- -

Compares the current URI with another URI, ignoring the value of the .ref member.

- -
Note: This is more than a string comparison, as two different URI strings can represent the same location. For example, comparing "http://foo.com/#" and "http://foo.com/" or "http://foo.com/#aaa" and "http://foo.com/#bbb" will return true.
- -
boolean equalsExceptRef(
-  in nsIURI other
-);
-
- -
Parameters
- -
-
other
-
Another nsIURI to compare to.
-
- -
Return value
- -

true if the two URIs represent the same location; otherwise false.

- -

resolve()

- -

Resolves a relative URI string, using this URI as the base.

- -

Note: Some implementations may have no concept of a relative URI.

- -
AUTF8String resolve(
-  in AUTF8String relativePath
-);
-
- -
Parameters
- -
-
relativePath
-
The relative path to resolve.
-
- -
Return value
- -

The resolved absolute URI string.

- -

schemeIs()

- -

Quickly reports whether the nsIURI represents a URI with the specified scheme. This comparison is case-insensitive.

- -

Note: This is an optimization, allowing you to check the scheme of the URI without having to get the scheme and do the comparison yourself; this saves memory allocations.

- -
boolean schemeIs(
-  in string scheme
-);
-
- -
Parameters
- -
-
scheme
-
A string representing the scheme to compare to.
-
- -
Return value
- -

true if the URI is for the specified scheme; otherwise false.

- -

See also

- - diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsixmlhttprequest/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsixmlhttprequest/index.html deleted file mode 100644 index f12f52cb12..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsixmlhttprequest/index.html +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: nsIXMLHttpRequest -slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIXMLHttpRequest -tags: - - XMLHttpRequest - - XPCOM API 参考 - - XPCOM 接口参考 - - 指南 - - 接口 -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIXMLHttpRequest ---- -

Obsolete since Gecko 60 (Firefox 60 / Thunderbird 60 / SeaMonkey 2.57)
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.

- -

nsIXMLHttpRequest along with nsIJSXMLHttpRequest and nsIXMLHttpRequestEventTarget are Mozilla's implementation details of the DOM XMLHttpRequest object.

- -
注意: 如果你是 Web 开发者或者 Mozilla add-on 开发者,请参考 XMLHttpRequest
- -

This page contains documentation, specific to Mozilla application and add-on developers.

- -

The interface definition: https://dxr.mozilla.org/mozilla-central/source/dom/xhr/nsIXMLHttpRequest.idl

- -

Elevated Privileges

- -

As mentioned in the "Non-Standard Properties" the property of channel was read-only. When using the XPCOM interface, as seen below in Example 2, we can get access to this. The most obvious benefit is that we can set nsiRequest - Constants in the xhr.channel.loadFlags. For instance, as done in Example 2, the flag of LOAD_ANONYMOUS is added, this strips all user data (cookies, tokens, etc).

- -

Using event handlers from native code

- -

(Not sure if it's up-to-date)

- -

From native code, the way to set up onload and onerror handlers is a bit different. Here is a comment from Johnny Stenback <jst@netscape.com>:

- -
The mozilla implementation of nsIXMLHttpRequest implements the interface nsIDOMEventTarget and that's how you're supported to add event listeners. Try something like this: nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(myxmlhttpreq)); target->AddEventListener(NS_LITERAL_STRING("load"), mylistener, PR_FALSE) where mylistener is your event listener object that implements the interface nsIDOMEventListener. The 'onload', 'onerror', and 'onreadystatechange' attributes moved to nsIJSXMLHttpRequest, but if you're coding in C++ you should avoid using those.
- -

Though actually, if you use addEventListener from C++ weird things will happen too, since the result will depend on what JS happens to be on the stack when you do it....

- -

Conclusion: Do not use event listeners on XMLHttpRequest from C++, unless you're aware of all the security implications. And then think twice about it.

- -

Example code

- -

This is a simple example code for opening a simple HTTP request from a xul application (like a Mozilla extension) without using observers:

- -
 var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
- req.open('POST', "http://www.foo.bar:8080/nietzsche.do", true);
- req.send('your=data&and=more&stuff=here');
-
- -

Example 2

- -
var {Cu: utils, Cc: classes, Ci: instances} = Components;
-Cu.import('resource://gre/modules/Services.jsm');
-function xhr(url, cb) {
-    let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
-
-    let handler = ev => {
-        evf(m => xhr.removeEventListener(m, handler, !1));
-        switch (ev.type) {
-            case 'load':
-                if (xhr.status == 200) {
-                    cb(xhr.response);
-                    break;
-                }
-            default:
-                Services.prompt.alert(null, 'XHR Error', 'Error Fetching Package: ' + xhr.statusText + ' [' + ev.type + ':' + xhr.status + ']');
-                break;
-        }
-    };
-
-    let evf = f => ['load', 'error', 'abort'].forEach(f);
-    evf(m => xhr.addEventListener(m, handler, false));
-
-    xhr.mozBackgroundRequest = true;
-    xhr.open('GET', url, true);
-    xhr.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS | Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_PERSISTENT_CACHING;
-    xhr.responseType = "arraybuffer"; //dont set it, so it returns string, you dont want arraybuffer. you only want this if your url is to a zip file or some file you want to download and make a nsIArrayBufferInputStream out of it or something
-    xhr.send(null);
-}
-
-xhr('https://www.gravatar.com/avatar/eb9895ade1bd6627e054429d1e18b576?s=24&d=identicon&r=PG&f=1', data => {
-    Services.prompt.alert(null, 'XHR Success', data);
-    var file = OS.Path.join(OS.Constants.Path.desktopDir, "test.png");
-    var promised = OS.File.writeAtomic(file, new UInt8Array(data));
-    promised.then(
-        function() {
-            alert('succesfully saved image to desktop')
-        },
-        function(ex) {
-             alert('FAILED in saving image to desktop')
-        }
-    );
-});
diff --git a/files/zh-cn/mozilla/tech/xpcom/setting_http_request_headers/index.html b/files/zh-cn/mozilla/tech/xpcom/setting_http_request_headers/index.html deleted file mode 100644 index b91030b424..0000000000 --- a/files/zh-cn/mozilla/tech/xpcom/setting_http_request_headers/index.html +++ /dev/null @@ -1,261 +0,0 @@ ---- -title: Setting HTTP request headers -slug: Mozilla/Tech/XPCOM/Setting_HTTP_request_headers -translation_of: Mozilla/Tech/XPCOM/Setting_HTTP_request_headers ---- -

HTTP 是网络背后的核心技术之一。除了实质内容之外,一些重要的信息通过HTTP 头传递给HTTP 请求和响应。

- -

你可以添加你自己的HTTP头到应用程序所做的任何请求中,不论你的代码是否启动了显式打开了基于 XMLHttpRequest 活动、<img>元素或者甚至是从css中的 HTTP Channel的请求。

- -

HTTP Channels

- -

当你处理HTTP请求和响应时,通常情况下你是通过 nsIHttpChannel来做的。 nsIHttpChannel接口有一些属性和方法,但是这下方法中我们只对setRequestHeader感兴趣。这个方法允许我们设置一个 HTTP request header.

- -

下面是设置一个HTTP header 的简单代码

- -
// adds "X-Hello: World" header to the request
-httpChannel.setRequestHeader("X-Hello", "World", false);
-
- -

在这个示例代码中我们有一个变量名为httpChannel,它是一个nsIHttpChannel的实例。

- -

setRequestHeader有三个参数,第一个参数是HTTP请求头的名字,第二个参数是HTTP请求头的值,第三个参数我们暂时忽略它,总设置其为false。

- -

在我们的示例代码中,我们为HTTP reques header中增加了被我们命名为X-Hello的HTTP请求头,其值为World

- -
-

NOTE: If you are making up your own HTTP header, you MUST put a X- in front of the name. (In our example, our made up HTTP header is X-Hello and NOT Hello because we correctly added the X- in front of our name.)

- -


- No longer the case: http://tools.ietf.org/html/draft-ietf-appsawg-xdash-02

-
- -

Notifications

- -

The question that may be coming to your mind right now is, how do you get the nsIHttpChannel when an HTTP request is made.

- -

In the case your code initiates the request, you probably already have one. Trapping other requests is done with notifications, which are a lot like events or signals found in other languages and frameworks.

- -

In particular, to get the nsIHttpChannel just before the HTTP request is made we need to observe the "http-on-modify-request" topic. (And yes, "http-on-modify-request" is a string.)

- -
-

NOTE: There are many topics, besides just "http-on-modify-request", that you can get notifications about, for example "http-on-examine-response" and "xpcom-shutdown". You can also make up your own topics and send out your own notifications.

- -

For more information about notifications framework and a list of common notification topics, see Observer Notifications.

-
- -

Observers

- -

To get notified about some topic (like "http-on-modify-request") we need to create an observer. An observer is a component implementing nsIObserver interface. And once the observer is registered for a topic, it will get notified about the topic by having its observe method called.

- -

Below is an example observer that adds a custom header "X-Hello" to the channel passed in for http-on-modify-request notification:

- -
var httpRequestObserver =
-{
-  observe: function(subject, topic, data)
-  {
-    if (topic == "http-on-modify-request") {
-      var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
-      httpChannel.setRequestHeader("X-Hello", "World", false);
-    }
-  }
-};
-
- -

div class="note"> Doesn't seem very suitable for this article; readers should are typically assumed to be familiar with JS. Nickolay '''NOTE''': Often people expect JavaScript to be just like Java. And while superficially, they look very similar, there are some important differences between the two. For example, while Java is an <em>object-oriented programming language</em>, JavaScript is not. JavaScript is <em>prototype-based programming language</em> and as such while it has <em>objects</em> it does not have <em>classes</em>. (Which is why, if you are not well versed with JavaScript, the object creation in the sample code above may look strange.) </div

- -

Note that the number of parameter that the observe method takes is important. It takes 3 parameters (as we've shown in the example code above). For the "http-on-modify-request" topic, the first parameter (named subject in the code above) will be the nsIHttpChannel. However, it is passed to us as an nsISupports. So we need to change the nsISupports into a nsIHttpChannel which is what the QueryInterface call does. And yes, converting objects from one kind to another is very ugly, and lacks (what is usually called) syntactic sugar.

- -

The second line of code in the if block should already be familiar to you. It is the same code we used before, earlier in this article, to add the HTTP request header.

- -

The name of this object -- httpRequestObserver -- isn't important. We could have named it anything we liked.

- -

Registering

- -

After we've created the observer, we need to register it. In our case, we want to register it for the "http-on-modify-request" topic. We can do this with the code below.

- -
var observerService = Components.classes["@mozilla.org/observer-service;1"]
-                                .getService(Components.interfaces.nsIObserverService);
-observerService.addObserver(httpRequestObserver, "http-on-modify-request", false);
-
- -

The first statement gets the object that will let us register with topics that we want to get notified about.

- -

The second statement does the actual registering. We are saying we want httpRequestObserver to be notified (by calling its observe method) when a "http-on-modify-request" topic takes place (which we know happens just before each HTTP request).

- -

Unregistering

- -

You should unregister the observer on shutdown. Failing to do that may cause memory leaks. To unregister the observer use nsIObserverService.removeObserver as follows:

- -
observerService.removeObserver(httpRequestObserver, "http-on-modify-request");
- -

All-in-one example

- -

Here is a slightly different version of our httpRequestObserver object. While the previous version we showed before was good for learning, in an actual real-world application, you'd probably want to code it more like the following.

- -
var httpRequestObserver =
-{
-  observe: function(subject, topic, data)
-  {
-    if (topic == "http-on-modify-request") {
-      var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
-      httpChannel.setRequestHeader("X-Hello", "World", false);
-    }
-  },
-
-  get observerService() {
-    return Components.classes["@mozilla.org/observer-service;1"]
-                     .getService(Components.interfaces.nsIObserverService);
-  },
-
-  register: function()
-  {
-    this.observerService.addObserver(this, "http-on-modify-request", false);
-  },
-
-  unregister: function()
-  {
-    this.observerService.removeObserver(this, "http-on-modify-request");
-  }
-};
-
- -

This object has a convenience register() and unregister() methods, so in order to activate it you just need to call:

- -
httpRequestObserver.register();
-
- -

You should also remember to unregister the observer at shutdown:

- -
httpRequestObserver.unregister();
-
- -

And that's it.

- -

XPCOM components

- -

You need to register a single http-on-modify-request observer per application (and not one per window). This means that you should put the observer's implementation in an XPCOM component instead of an overlay. If you want to support Gecko2 (Firefox4) you need to register your javascript component as described here: https://developer.mozilla.org/zh-cn/XPCOM/XPCOM_changes_in_Gecko_2.0#JavaScript_components.

- -
var headerName  = "X-hello";
-var headerValue = "world";
-
-function LOG(text)
-{
-    //    var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
-    //    consoleService.logStringMessage(text);
-}
-
-function myHTTPListener() { }
-
-myHTTPListener.prototype = {
-
-  observe: function(subject, topic, data)
-  {
-      if (topic == "http-on-modify-request") {
-
-          LOG("----------------------------> (" + subject + ") mod request");
-
-          var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
-          httpChannel.setRequestHeader(headerName, headerValue, false);
-          return;
-      }
-
-
-      if (topic == "profile-after-change") {
-
-          LOG("----------------------------> profile-after-change");
-
-          var os = Components.classes["@mozilla.org/observer-service;1"]
-                             .getService(Components.interfaces.nsIObserverService);
-
-          os.addObserver(this, "http-on-modify-request", false);
-          return;
-      }
-  },
-
-  QueryInterface: function (iid) {
-        if (iid.equals(Components.interfaces.nsIObserver) ||
-            iid.equals(Components.interfaces.nsISupports))
-            return this;
-
-        Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
-        return null;
-    },
-};
-
-var myModule = {
-    registerSelf: function (compMgr, fileSpec, location, type) {
-
-        var compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
-        compMgr.registerFactoryLocation(this.myCID,
-                                        this.myName,
-                                        this.myProgID,
-                                        fileSpec,
-                                        location,
-                                        type);
-
-
-          LOG("----------------------------> registerSelf");
-
-        var catMgr = Components.classes["@mozilla.org/categorymanager;1"].getService(Components.interfaces.nsICategoryManager);
-        catMgr.addCategoryEntry("app-startup", this.myName, this.myProgID, true, true);
-    },
-
-
-    getClassObject: function (compMgr, cid, iid) {
-
-          LOG("----------------------------> getClassObject");
-
-        return this.myFactory;
-    },
-
-    myCID: Components.ID("{9cf5f3df-2505-42dd-9094-c1631bd1be1c}"),
-
-    myProgID: "@dougt/myHTTPListener;1",
-
-    myName:   "Simple HTTP Listener",
-
-    myFactory: {
-        QueryInterface: function (aIID) {
-            if (!aIID.equals(Components.interfaces.nsISupports) &&
-                !aIID.equals(Components.interfaces.nsIFactory))
-                throw Components.results.NS_ERROR_NO_INTERFACE;
-            return this;
-        },
-
-        createInstance: function (outer, iid) {
-
-          LOG("----------------------------> createInstance");
-
-          return new myHTTPListener();
-        }
-    },
-
-    canUnload: function(compMgr) {
-        return true;
-    }
-};
-
-function NSGetModule(compMgr, fileSpec) {
-    return myModule;
-}
-
- -

Privacy and security good practice

- -

A use case for setting specific a HTTP request header is to have a specific web site be able to check if a specific plugin / addon / extension is installed.

- -

The good practice is not to have this specific HTTP header (for example "X-site.net-extension") sent all the time but only when doing requests with this specific web sites. By not advertising to all sites what extensions are installed this improves both privacy (this makes it harder to track a user known by his set of plugins, addons and extensions) and security (some plugins, addons and extensions may be known to have flaws by attackers).

- -

With this privacy and security addition the code to use becomes:

- -
 observe: function(subject, topic, data)
-  {
-    if (topic == "http-on-modify-request") {
-      var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
-      if (/site.net/.test(httpChannel.originalURI.host)) {
-        httpChannel.setRequestHeader("X-Hello", "World", false);
-      }
-    }
-  },
-
diff --git a/files/zh-cn/mozilla/tech/xpidl/index.html b/files/zh-cn/mozilla/tech/xpidl/index.html deleted file mode 100644 index c976d0bae9..0000000000 --- a/files/zh-cn/mozilla/tech/xpidl/index.html +++ /dev/null @@ -1,502 +0,0 @@ ---- -title: XPIDL -slug: Mozilla/Tech/XPIDL -tags: - - XPCOM - - xpidl -translation_of: Mozilla/Tech/XPIDL ---- -

 

-

XPIDL 是一个用于指定 XPCOM 接口类的接口描述语言

-

Interface Description Languages (IDL) are used to describe interfaces in a language- and machine-independent way. IDLs make it possible to define interfaces which can then be processed by tools to autogenerate language-dependent interface specifications. XPIDL is expected to converge towards WebIDL in the future.

-
-

Note: Starting in {{Gecko("9.0")}}, the older xpidl utility, which was previously used to generate C++ header files, typelib information, and so forth has been replaced withpyxpidl in the Gecko SDKpyxpidl has been used for some time now, but now the older tool has been fully retired.

-
-

Writing XPIDL interface files

-

XPIDL closely resembles OMG IDL, with extended syntax to handle IIDs and additional types. Some examples are in the {{Source("xpcom/base")}} and {{Source("xpcom/ds")}} directories of the Mozilla tree.

- -

Explanation of IDL semantics

-

A full guide to the syntax can be found at XPIDL:Syntax, which is written in an ABNF form.

-

An xpidl file is essentially just a series of declarations. At the top level, we can define typedefs, native types, or interfaces. Interfaces may furthermore contain typedefs, natives, methods, constants, or attributes. Most declarations can have properties applied to them.

-

Types

-

There are three ways to make types: a typedef, a native, or an interface. In addition, there are a few built-in native types. The built-in native types are those listed under the type_spec production above. The following is the correspondence table:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 1: Standard IDL types
IDLC++ in parameterC++ out parameterJS typeNotes
booleanboolbool *boolean 
charcharchar *stringOnly chars in range \u0000-\u00ff permitted
doubledoubledouble *number 
floatfloatfloat *number 
longint32_tint32_t *number 
long longint64_tint64_t *number 
octetuint8_tuint8_t *number 
shortint16_tint16_t *number 
stringconst char *char **stringOnly chars in range \u0000-\u00ff permitted
unsigned longuint32_tuint32_t *number 
unsigned long longuint64_tuint64_t *number 
unsigned shortuint16_tuint16_t *number 
wcharPRUnicharPRUnichar *stringFull Unicode set permitted
wstringconst PRUnichar *PRUnichar **stringFull Unicode set permitted
-

In addition to this list, nearly every IDL file includes nsrootidl.idl in some fashion, which also defines the following types:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 2: Types provided by nsrootidl.idl
IDL typedefC++ in parameterC++ out parameterJS typeNotes
PRTime(XPIDL unsigned long long typedef, 64 bits)numberPRTime is in microseconds, while JS date assumes time in milliseconds
nsresult(XPIDL unsigned longtypedef, 32 bits)number 
nsrefcnt(XPIDL unsigned longtypedef, 32 bits)number 
size_t(XPIDL unsigned longtypedef, 32 bits)number 
voidPtrvoid *void *not allowed 
charPtrchar *char **not allowed 
unicharPtrPRUnichar *PRUnichar **not allowed 
nsIDRefconst nsID &nsID *? 
nsIIDRefconst nsIID &nsIID *? 
nsCIDRefconst nsCID &nsCID *? 
nsIDPtrconst nsID *nsID **? 
nsIIDPtrconst nsIID *nsIID **? 
nsCIDPtrconst nsCID *nsCID **? 
nsIIDconst nsIIDnsIID *? 
nsIDconst nsIDnsID *? 
nsCIDconst nsCIDnsCID *? 
nsQIResultvoid *void **objectShould only be used with methods that act like QueryInterface
DOMStringconst nsAString &nsAString &stringFull Unicode set permitted
AUTF8Stringconst nsACString &nsACString &stringFull Unicode set permitted (translated to UTF-8)
ACStringconst nsACString &nsACString &stringOnly chars in range \u0000-\u00ff permitted
AStringconst nsAString &nsAString &stringFull Unicode set permitted
jsvalconst jsval &jsval *anything 
jsidjsidjsid *not allowed 
-

Typedefs in IDL are basically as they are in C or C++: you define first the type that you want to refer to and then the name of the type. Types can of course be one of the fundamental types, or any other type declared via a typedef, interface, or a native type.

-

Native types are types which correspond to a given C++ type. Most native types are not scriptable: if it is not present in the list above, then it is certainly not scriptable (some of the above, particularly jsid, are not scriptable).

-

The contents of the parentheses of a native type declaration (although native declarations without parentheses are parsable, I do not trust that they are properly handled by the xpidl handlers) is a string equivalent to the C++ type. XPIDL itself does not interpret this string, it just literally pastes it anywhere the native type is used. The interpretation of the type can be modified by having properties on the native declaration:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 3: Native type definitions
astringThis is an nsAString declaration. Overrides native string.
cstringThis is an nsACString declaration. Overrides native string.
domstringThis is an nsAString declaration. Overrides native string.
jsvalThis type gets const when an in type. Special in typelib.
nsidThis type gets const when an in type. Special in typelib.
ptrThe type is really (native str)*
refThe type is really (native str)&
utf8stringThis is an nsACString declaration whose text is UTF-8.
-

As far as I can tell, these properties also apply to typedefs. Need to verify.

-

Constants

-

Constants are technically legal at the top level, but xpidl I forbids them from being placed there; instead, they must be in an interface. The only constants supported are those which become integer types when compiled to source code; string constants and floating point constants, though parseable, cannot be made into a header or xpt file.

-

Constants are emitted in header files using anonymous enums, although there is an outstanding patch that combines adjacent constants into the same anonymous enums to quiet enum mismatch warnings.

-

Interfaces

-

Specifying interfaces is the primary purpose of using xpidl. Interfaces are basically a collection of constants, methods, and attributes; in Mozilla, these are the primary ways in which JavaScript code can interact with native C++ code. Furthermore, interfaces can also inherit from another interface. Every interface should inherit nsISupports in some fashion. However, it is generally not recommended to have a chain of interfaces inheriting from each other if you intend to have a chain of implementations for each interface, as it can cause problems in C++ code.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 4: Basic interface attributes
AttributeInterpretation
uuid(12345678-fedc-ba98-7654-0123456789ab)This is the internal way this interface is accessed; it must be unique, and the uuid must be changed anytime any part of the interface or its ancestors are changed. For instructions on how to generate an UUID see Generating GUIDs.
builtinclassJavaScript classes are forbidden from implementing this interface. All children must also be marked with this property.
functionThe JavaScript implementation of this interface may be a function that is invoked on property calls instead of an object with the given property
scriptableThis interface is usable by JavaScript classes. Must inherit from ascriptable interface.
deprecatedThis interface should no longer be used. The compiler will emit warnings if you attempt to use this.
-

Methods and attributes

-

Interfaces declare a series of attributes and methods. Attributes in IDL are akin to JavaScript properties, in that they are a getter and (optionally) a setter pair. In JavaScript contexts, attributes are exposed as a regular property access, while native code sees attributes as a Get and possibly a Set method.

-

Attributes can be declared readonly, in which case setting causes an error to be thrown in script contexts and native contexts lack the Set method, by using the "readonly" keyword.

-

To native code, on attribute declared 'attribute type foo;' is syntactic sugar for the declaration of two methods 'type getFoo();' and 'void setFoo(in type foo);'. If foo were declared readonly, the latter method would not be present. Attributes support all of the properties of methods with the exception of optional_argc, as this does not make sense for attributes.

-

There are some special rules for attribute naming. As a result of vtable munging by the MSVC++ compiler, an attribute with the name `IID' is forbidden. In addition, any attribute whose name matches the regex /^[a-z]{2,3}I[A-Z][a-z]/ is emitted with a warning, as its name looks like an nsIInterface or a mozIInterface declaration. Also like methods, if the first character of an attribute is lowercase in IDL, it is made uppercase in native code only.

-

Methods define a return type and a series of in and out parameters. When called from a JavaScript context, they invocation looks as it is declared for the most part; some parameter properties can adjust what the code looks like. The calls are more mangled in native contexts.

-

An important attribute for methods and attributes is scriptability. A method or attribute is scriptable if it is declared in a scriptable interface and it lacks anoscript or notxpcom property. Any method that is not scriptable can only be accessed by native code. However, scriptable methods must contain parameters and a return type that can be translated to script: any native type, save those declared with an nsiddomstringutf8stringcstringastring, or jsval property, may not be used in a scriptable method or attribute. An exception to the above rule is if the parameter has the iid_is property (a special case for some QueryInterface-like operations). In general, this means that the only usable native types are those declared in nsrootidl.idl (see above).

-

Methods and attributes are mangled on conversion to native code. If a method is declared notxpcom, the mangling of the return type is prevented, so it is called mostly as it looks. Otherwise, the return type of the native method is nsresult, and the return type acts as a final outparameter if it is not void. The name is translated so that the first character is unconditionally uppercase; subsequent characters are unaffected. However, the presence of the binaryname property allows the user to select another name to use in native code (to avoid conflicts with other functions). For example, the method '[binaryname(foo)] void bar();' becomes 'nsresult Foo()' in native code (note that capitalization is still applied). However, the capitalization is not applied when using binaryname with attributes; i.e., [binaryname(foo)] readonly attribute Quux bar; becomes Getfoo(Quux**) in native code. Attributes named 'IID' and methods named 'GetIID' are forbidden, although this is checked before binaryname conversion.

-

The implicit_jscontext and optional_argc parameters are properties which help native code implementations determine how the call was made from script. Ifimplicit_jscontext is present on a method, then an additional JSContext *cx parameter is added just after the regular list which receives the context of the caller. If optional_argc is present, then an additional uint8_t _argc method is added at the end which receives the number of optional arguments that were actually used (obviously, you need to have an optional argument in the first place). Note that if both properties are set, the JSContext *cx is added first, followed by the uint8_t _argc, and then ending with return value parameter. Finally, as an exception to everything already mentioned, for attribute getters and setters the JSContext *cx comes before any other arguments.

-

In addition, methods and attributes can be both marked as deprecated with thedeprecated property, which causes compilers to emit deprecation usage warnings. Note that this is only verified in native code and not script code.

-

The final native-only property is nostdcall. Normally, declarations are made in the stdcall ABI on Windows to be ABI-compatible with COM interfaces. Any non-scriptable method or attribute with nostdcall instead uses the thiscall ABI convention. Methods without this property generally use NS_IMETHOD in their declarations and NS_IMETHODIMP in their definitions to automatically add in the stdcall declaration specifier on requisite compilers; those that use this method may use a plain `nsresult' instead.

-

Source and Binary Compatibility

-

Some consumers of IDL interfaces create binary plugins that expect the interfaces to be stored in a specific way in memory. In other words, some changes made to IDL interfaces require the author to modify the unique identifier (IID) in order to make it clear to plugins that utilize these interfaces that they have changed, and thus their plugin must be recompiled.

-

Common changes to an interface, such as changes to a method signature, number of arguments, and number or type of attributes, automatically require an IID change. In addition, some changes to interface attributes require that an IID be changed, as well. When a change to an interface made by an XPIDL developer requires that third-party binary addons be recompiled, we say that it affects binary compatibility. When a change to an interface made by an XPIDL developer requires that third-party binary addons change their source code, we say that it affects source compatibility. In table 5, the columns on the far right indicate whether changes to a specific attribute affect source compatibility, binary compatibility, or both.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Table 5: Optional interface attributes
AttributeValid for methodsValid for attributesEffectChanges Source Compatibility?Changes Binary Compatibility?
binaryname(foo)YYResults in the C++ method being called "Foo"YN
deprecatedYYEmits a compiler warning if used in C++ codeNN
implicit_jscontextYYAdds an additionalJSContext *cx parameter to the C++ implementationYY
noscriptYYProhibits the method/attribute from being accessible in JS codeNN
nostdcallYYThe C++ implementation uses virtual nsresultinstead ofNS_IMETHOD/NS_IMETHODIMPYY
notxpcomYYThe C++ implementation does not return nsresult(implies noscript)YY
optional_argcYNAdds an additional uint8_t _argc parameter to the C++ implementationYY
-

Method parameters

-

Each method parameter can be specified in one of three modes: inout, or inout. An out parameter is essentially an auxiliary return value, although these are moderately cumbersome to use from script contexts and should therefore be avoided if reasonable. An inout parameter is an in parameter whose value may be changed as a result of the method; these parameters are rather annoying to use and should generally be avoided if at all possible.

-

Out and inout parameters are reflected as objects having the .value property which contains the real value of the parameter; it is not initialized in the case of out parameters and is initialized to the passed-in-value for inout parameters. The script code would need to set this property to assign a value to the parameter. Regular in parameters are reflected more or less normally, with numeric types all representing numbers, booleans as true or false, the various strings (including AString et al) as a JavaScript string, and nsid types as a Components.ID instance. In addition, the jsval type is translated as the appropriate JavaScript value (since a jsval is the internal representation of all JavaScript values), and objects that are marked nsIVariant have their
- types automatically boxed and unboxed as appropriate.

-

The equivalent representations of all IDL types in native code is given in the earlier tables; parameters of type inout follow their out form. Native code should pay particular attention to not passing in null values for out parameters (although some parts of the codebase are known to violate this, it is strictly enforced at the JS<->native barrier), and also ensuring that boolean types only receive values of 0 (false) or 1 (true).

-

Representations of types additionally depend on some of the many types of properties they may have. The array property turns the parameter into an array; the parameter must also have a corresponding size_is property whose argument is the parameter that has the size of the array. In native code, the type gains another pointer indirection, and JavaScript arrays are used in script code. Script code callers can ignore the value of array parameter, but implementors must still set the values appropriately.

-

The const and shared properties are special to native code. As its name implies, the const property makes its corresponding argument const. The shared property is only meaningful for out or inout parameters and it means that the pointer value should not be freed by the caller. Only the string, wstring, and native types having the nsid, domstring, utf8string, cstirng, astring, or jsval properties may be declared shared, and, even then, only if the parameter is not an array parameter. The shared property also makes its corresponding argument const.
-
- The retval property indicates that the parameter is actually acting as the return value, and it is only the need to assign properties to the parameter that is causing it to be specified as a parameter. It has no effect on native code, but script code uses it like a regular return value. Naturally, a method which contains a retval parameter must be declared void, and the parameter itself must be an out parameter and the last parameter.

-

Other properties are the optional and iid_is property. The optional property indicates that script code may omit the property without problems; all subsequent parameters must either by optional themselves or the retval parameter. Note that optional out parameters still pass in a variable for the parameter, but its value will be ignored. The iid_is parameter indicates that the real IID of an nsQIResult parameter may be found in the corresponding parameter, to allow script code to automatically unbox the type.

-

Not all type combinations are possible. Native types with the various string properties are all forbidden from being used as an inout parameter or as an array parameter. In addition, native types with the nsid property but lacking either a ptr or ref property are forbidden unless the method is notxpcom and it is used as an inparameter.

-

For types that reference heap-allocated data (strings, arrays, interface pointers, etc), you must follow the XPIDL data ownership conventions in order to avoid memory corruption and security vulnerabilities:

- -

Resources (mostly outdated)

- diff --git a/files/zh-cn/mozilla/tech/xpidl/syntax/index.html b/files/zh-cn/mozilla/tech/xpidl/syntax/index.html deleted file mode 100644 index daca23f49f..0000000000 --- a/files/zh-cn/mozilla/tech/xpidl/syntax/index.html +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: Syntax -slug: Mozilla/Tech/XPIDL/Syntax -tags: - - xpidl -translation_of: Mozilla/Tech/XPIDL/Syntax ---- -

Status of this document

- -

This is a partial reverse-engineering of the libIDL source code's parser, limited mostly to the subset of functionality that is supported by the Mozilla xpidl binary.

- -

Purpose of this document

- -

This document is not an introduction to XPIDL or IDL in general. It is more focused on XPIDL syntax and grammar. See XPIDL Main Page for more links and introductory content.

- -

Simplifications, conventions and notation

- -

The syntax is specified according to ABNF as defined by RFC 5234, although a few productions use prose for clarity of understanding.

- -

Lexically, tokens are delimited by whitespace (defined here as spaces, tabs, vertical tabs, form feeds, line feeds, and carriage returns, or [ \t\v\f\r\n] in regular expression form). LibIDL only considers a single line feed as a newline, and not carriage returns (although xpidl begs to differ). Additionally, the use of both C-style (/* ... */) and C++-style (// ... end-of-line) comments are permitted between any two tokens.

- -

Some productions can only occur at the beginning of lines; to simplify the grammar, I will not mention them in the grammar, especially since they are handled as a preprocessing step before the IDL source code is actually parsed.

- -
    -
  1. A `%{' that appears at the beginning of a line is the start of a raw code fragment, which extends until the end of a line that begins with `%}'. Text inside raw code fragments are not otherwise parsed by xpidl directly. This may be followed by the language, as in `%{C++', to output the raw fragment only in the specified language.
  2. -
  3. A `#include "file"' line instructs the xpidl processor to include that file in the same sense that the C preprocessor includes a file. Note that includes within comments or raw code fragments are not processed by xpidl. Unlike the C preprocessor, when a file is included multiple times, it acts as if the subsequent includes did not happen; this prevents the need for include guards.
  4. -
- -

XPIDL Syntax (ABNF)

- -

The root production here is idl_file.

- -

idl_file = 1*definition
- definition = [type_decl / const_decl / interface] ";"
- interface = [prop_list] "interface" ident [[inheritance] "{" *(ifacebody) "}"]
- inheritance = ":" *(scoped_name ",") scoped_name]
- ifacebody = [type_decl / op_decl /attr_decl / const_decl] ";" / codefrag
-
- type_decl = [prop_list] "typedef" type_spec *(ident ",") ident
- type_decl /= [prop_list] "native" ident [parens]
- const_decl = "const" type_spec ident "=" expr
- op_decl = [prop_list] (type_spec / "void") parameter_decls raise_list
- parameter_decls = "(" [*(param_decl ",") param_decl] ")"
- param_decl = [prop_list] ("in" / "out" / "inout") type_spec ident
- attr_decl = [prop_list] ["readonly"] "attribute" type_spec *(ident ",") ident
-
- ; Descending order of precedence
- expr /= expr ("|" / "^" / "&") expr ; Unequal precedence "|" is lowest
- expr /= expr ("<<" / ">>") expr
- expr /= expr ("+" / "-") expr
- expr /= expr ("*" / "/" / "%") expr
- expr /= ["-" / "+" / "~"] (scoped_name / literal / "(" expr ")" )
-
- ; Numeric literals: quite frankly, I'm sure you know how these kinds of
- ; literals work, and these are annoying to specify in ABNF.
- literal = octal_literal / decimal_literal / hex_literal / floating_literal
- literal /= string_literal / char_literal
- literal /= "TRUE" / "FALSE"
-
- ; In regex: /"[^"\n]*["\n]/. Yes, newline terminates.
- string_literal = 1*(%x22 *(any char except %x22 or %x0a) (%x22 / %x0a))
- ; Same as above, but s/"/'/g
- char_literal = 1*(%x27 *(any char except %x27 or %x0a) (%x27 / %x0a))
-
- type_spec = "float" / "double" / "string" / "wstring"
- type_spec /= ["unsigned"] ("short" / "long" / "long" "long")
- type_spec /= "char" / "wchar" / "boolean" / "octet"
- type_spec /= scoped_name
-
- prop_list = "[" *(property ",") property "]"
- property = ident [parens]
- raise_list = "raises" "(" *(scoped_name) ",") scoped_name ")"
-
- scoped_name = *(ident "::") ident / "::" ident

- ; In regex: [A-Za-z_][A-Za-z0-9_]*; identifiers beginning with _ cause warnings
- ident = (%x41-5a / %x61-7a / "_") *(%x41-5a / %x61-7a / %x30-39 / "_")
- parens = "(" 1*(any char except ")") ")"

- -

Functionality not used in xpidl

- -

The libIDL parser we use is more powerful than xpidl itself can understand. The following is a list of potential features which are parseable but may not result in expected code:

- - - -

Pyxpidl syntax

- -

idlfile = *(CDATA / INCLUDE / interface / typedef / native)
-
- typedef = "typedef" IDENTIFER IDENTIFIER ";"
- native = [attributes] "native" IDENTIFIER "(" NATIVEID ")"
- interface = [attributes] "interface" IDENTIFIER" [ifacebase] [ifacebody] ";"
- ifacebase = ":" IDENTIFIER
- ifacebody = "{" *(member) "}"
-
- member = CDATA / "const" IDENTIFIER IDENTIFIER "=" number ";"
- member /= [attributes] ["readonly"] "attribute" IDENTIFIER IDENTIFER ";"
- member /= [attributes] IDENTIFIER IDENTIFIER "(" paramlist ")" raises ";"
- paramlist = [param *("," param)]
- raises = ["raises" "(" IDENTIFIER *("," identifier) ")"]
- attributes = "[" attribute *("," attribute) "]"
- attribute = (IDENTIFIER / CONST) ["(" (IDENTIFIER / IID) ")"]
- param = [attributes] ("in" / "out" / "inout") IDENTIFIER IDENTIFIER
-
- number = NUMBER / IDENTIFIER
- number /= "(" number ")"
- number /= "-" number
- number /= number ("+" / "-" / "*") number
- number /= number ("<<" / >>") number
- number /= number "|" number
-
- ; Lexical tokens, I'm going to specify these in regex form
- NUMBER = /-?\d+|0x[0-9A-Fa-f]+/
- CDATA = /%\{[ ]*C\+\+[ ]*\n(.*?\n?)%\}[ ]*(C\+\+)?/s
- INCLUDE = /\#include[ \t]+"[^"\n]+"/
- NATIVEID = /[^()\n]+(?=\))/
- IID = /[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}/
- IDENTIFIER = /unsigned long long|unsigned short|unsigned long|long long|[A-Za-z][A-Za-z_0-9]*/

diff --git a/files/zh-cn/mozilla/tech/xpidl/xpidl/index.html b/files/zh-cn/mozilla/tech/xpidl/xpidl/index.html deleted file mode 100644 index 57838ceae4..0000000000 --- a/files/zh-cn/mozilla/tech/xpidl/xpidl/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: xpidl -slug: Mozilla/Tech/XPIDL/xpidl -tags: - - 'Developing_Mozilla:Tools' - - Tools - - xpidl - - 开发Mozilla - - 所有分类 -translation_of: Mozilla/Tech/XPIDL/xpidl ---- -

 

-

xpidl 是一个基于 XPIDL 接口描述文件, 用于生成 XPCOM 接口信息的工具. 它会自动生成:

- -

编译 xpidl

-

xpidl 的实现是基于 Gnome 工程中的 libIDL idl 编译器. libIDL 编译器依赖的 glib 库也来自于 gnome 工程. xpidl 编译器现在是 Mozilla 整个编译过程中必须包含的一分子, 我们用它来生成 XPCOM 组件的头文件. 如何得到 libIDL 和 glib 请看 Build Documentation.

-

Unix: 如果你仅仅想编译 xpidl 本身, 你只需要编译很少一部分目录. 在获取 mozilla 源码后, 执行 'configure', 然后以下面的命令就可以在 dist/bin 目录下编译出 xpidl:

-
make -C config
-make -C nsprpub
-make -C xpcom/typelib
-
-

使用 xpidl

-

xpidl build page 有关于如何添加一个 XPIDL 文件到 Mozilla 的编译过程的说明. xpidl 也可以在 Unix 和 Windows 下以命令行的形式执行:

-
Usage: ./xpidl -m mode [-w] [-v] [-t version number]
-          [-I path] [-o basename | -e filename.ext] filename.idl
-       -a emit annotations to typelib
-       -w turn on warnings (recommended)
-       -v verbose mode (NYI)
-       -t create a typelib of a specific version number
-       -I add entry to start of include path for ``#include "nsIThing.idl"
-       -o use basename (e.g. ``/tmp/nsIThing) for output
-       -e use explicit output filename
-       -m specify output mode:
-          header        Generate C++ header            (.h)
-          typelib       Generate XPConnect typelib     (.xpt)
-          doc           Generate HTML documentation    (.html)
-          java          Generate Java interface        (.java)
-
-

资源

- -

Flames to docs mike+mozilla@meer.net & mang@subcarrier.org

-

 

-
-

原始文档信息

- -
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/acceltext/index.html b/files/zh-cn/mozilla/tech/xul/attribute/acceltext/index.html deleted file mode 100644 index 77bc1dccbe..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/acceltext/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: acceltext -slug: Mozilla/Tech/XUL/Attribute/acceltext -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/acceltext ---- -
- « XUL Reference home
-
-
- acceltext
-
- Type: - - string -
-
- Text that appears beside beside the menu label to indicate the shortcut key (accelerator key) to use to invoke the command. If this value is set, it overrides an assigned key set in the key attribute. This attribute does not apply to menus directly on the menubar.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/accesskey/index.html b/files/zh-cn/mozilla/tech/xul/attribute/accesskey/index.html deleted file mode 100644 index e6697bda0d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/accesskey/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: accesskey -slug: Mozilla/Tech/XUL/Attribute/accesskey -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/accesskey ---- -
« XUL Reference home
- -
-
-
Attribute of: button, checkbox, caption, description, label, listitem, menu, menuitem, menulist, tab, radio, toolbarbutton, textbox (Firefox autocomplete)
-
-
- -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/activetitlebarcolor/index.html b/files/zh-cn/mozilla/tech/xul/attribute/activetitlebarcolor/index.html deleted file mode 100644 index 5352f49114..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/activetitlebarcolor/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: activetitlebarcolor -slug: Mozilla/Tech/XUL/Attribute/activetitlebarcolor -translation_of: Archive/Mozilla/XUL/Attribute/activetitlebarcolor ---- -
- « XUL Reference home
-
-
- activetitlebarcolor
-
- Type: color string
-
- Specify background color of the window's titlebar when it is active (foreground). Moreover this hides separator between titlebar and window contents. This only affects Mac OS X.
-
-
-

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/align/index.html b/files/zh-cn/mozilla/tech/xul/attribute/align/index.html deleted file mode 100644 index f940cbdbb3..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/align/index.html +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: align -slug: Mozilla/Tech/XUL/Attribute/align -tags: - - Reference - - XUL -translation_of: Archive/Mozilla/XUL/Attribute/align ---- -
« XUL Reference home
- -
-
align
-
Type: one of the values below
-
The align attribute specifies how child elements of the box are aligned, when the size of the box is larger than the total size of the children.
- 当box的尺寸大于全部子元素的尺寸时,align属性指定box元素的对齐方式。 -
    -
  • For boxes that have horizontal orientation, it specifies how its children will be aligned vertically.
  • -
  • 当box设置水平排列,它指定子元素如何垂直对齐。
  • -
  • For boxes that have vertical orientation, it specifies how its children will be aligned horizontally.
  • -
  • 当box设置垂直排列,它指定子元素如何水平对齐
  • -
-
-
-
-
start
-
Child elements are aligned starting from the left or top edge of the box. If the box is larger than the total size of the children, the extra space is placed on the right or bottom side.
- 子元素从box的左边或顶部开始排列。如果box大于全部子元素的总和,多出的空间在右边或底部。
-
center
-
Extra space is split equally along each side of the child elements, resulting in the children being placed in the center of the box.
- 多出的空间在子元素的周围,使子元素放置在box的中间。
-
end
-
Child elements are placed on the right or bottom edge of the box. If the box is larger than the total size of the children, the extra space is placed on the left or top side.
- 子元素从box的右边或底部开始排列。如果box大于全部子元素的总和,多出的空间在左边或顶部部。
-
baseline
-
This value applies to horizontally oriented boxes only. It causes the child elements to be aligned so that their text labels are lined up.
- 这个值只适用于水平方向的box元素。它让子元素的文本标签成一条直线。
-
stretch
-
This is the default value. The child elements are stretched to fit the size of the box. For a horizontal box, the children are stretched to be the height of the box. For a vertical box, the children are stretched to be the width of the box. If the size of the box changes, the children stretch to fit. Use the flex attribute to create elements that stretch in the opposite direction.
- 这是默认值。拉伸子元素来填充box。在水平的box元素中,子元素在高度上被拉伸。在垂直的box元素中,子元素在宽度上被拉伸。如果box元素尺寸改变,子元素也随之改变。使用flex属性创建的元素在相反方向被拉伸。
-
left
-
The elements are aligned on their left edges.
- 元素左边缘对齐。
-
center
-
The elements are centered horizontally.
- 元素水平居中。
-
right
-
The elements are aligned on their right edges.
- 元素右边缘对齐。
-
-
-
The pack attribute is related to the alignment but is used to specify the position in the opposite direction. You can also specify the value of align using the style property -moz-box-align.
- pack也是有关对齐的属性,但是指定相反方向的位置。你也可以在style中使用对齐的方式-moz-box-align
-
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/allowevents/index.html b/files/zh-cn/mozilla/tech/xul/attribute/allowevents/index.html deleted file mode 100644 index 5d17570f74..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/allowevents/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: allowevents -slug: Mozilla/Tech/XUL/Attribute/allowevents -tags: - - XUL Attributes - - XUL Reference -translation_of: Archive/Mozilla/XUL/Attribute/allowevents ---- -
« XUL Reference home
- -
-
allowevents
-
Type: - boolean
-
- 类型:boolean
-
If true, events are passed to children of the element. Otherwise, events are passed to the element only.
- 如果为真,事件向子元素传递。否则,事件只传递到当前元素。
-
- -
-

On listitem and titlebar elements, mouse events normally do not get sent to their children; instead they are retargeted to the listitem and titlebar element itself. This means that elements placed inside a listitem do not respond to events, and instead clicking the mouse simply selects that item within the list. By setting the allowevents attribute to true, this special behavior is disabled, and the events are targeted the same as other elements.
- 在 listitemtitlebar 元素中,鼠标事件通常不发送给子元素;相反它们重定向到 listitemtitlebar 元素本身。这意味着,放置在listitem内部的元素并不响应事件,而点击鼠标仅仅是选择在列表中的元素。当设置allowevents属性为真时,这种特殊的响应被禁止,事件则被定向到其他相同的元素。

- -

For menu, menuseparator, menuitem and treecol elements, as well as menu buttons, and the popup datepicker, mouse events are also retargeted to the element itself. However, the allowevents attribute is handled in a different way. Instead, the allowevents may be set to true on a descendant instead. This does the same thing in that it allows events to be targeted normally, but allows this to be different for each descendant.

- -

This behavior is used for menus, for instance, to allow a menu button to behave as a menu when clicking on it, yet have part of the menu behave as a button. For the latter, the allowevents attribute is set to true to have a click on the child button receive events instead of targeting all events at the menu.

-
- -

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/allownegativeassertions/index.html b/files/zh-cn/mozilla/tech/xul/attribute/allownegativeassertions/index.html deleted file mode 100644 index 51c8c4e222..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/allownegativeassertions/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: allownegativeassertions -slug: Mozilla/Tech/XUL/Attribute/allownegativeassertions -translation_of: Archive/Mozilla/XUL/Attribute/allownegativeassertions ---- -
« XUL Reference home
- -
-
allownegativeassertions
-
Type: boolean
- 类型:布尔类型
-
Valid on any element that has a datasources attribute. When multiple datasources are used, one may override an assertion from another. This attribute, if true, which is the default, allows a datasource to negate an earlier assertion.
- 适用于任何有 datasources 属性的元素。当使用多个数据源,一个数据源可以指定覆盖另一个。这个属性,如果为真,这是默认值,允许一个数据源覆盖之前的数据源。
-
- -
-

-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/autocheck/index.html b/files/zh-cn/mozilla/tech/xul/attribute/autocheck/index.html deleted file mode 100644 index edd3c5e9ed..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/autocheck/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: autocheck -slug: Mozilla/Tech/XUL/Attribute/autocheck -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/autoCheck ---- -
« XUL Reference home
- -
-
autocheck
-
类型: - boolean -
-
如果此属性为 true,或空白, 每次点击按钮时,此按钮的状态检查都会被执行一次。如果此属性为false, 检查会手动的被拒绝。当autocheck值为true的时候,按钮将会变为多选框或者单选框。
-
- -
-

See also

- -

autoCheck

-
- -

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/autoscroll/index.html b/files/zh-cn/mozilla/tech/xul/attribute/autoscroll/index.html deleted file mode 100644 index 9bc1366f88..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/autoscroll/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: autoscroll -slug: Mozilla/Tech/XUL/Attribute/autoscroll -translation_of: Archive/Mozilla/XUL/Attribute/autoscroll ---- -
« XUL Reference home
- -
-
autoscroll
-
Type: boolean
-
Set to false to disable autoscroll for this browser. If this attribute is set to true or omitted, autoscroll will be enabled or depending on the user preference general.autoScroll.
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/buttonaccesskeyaccept/index.html b/files/zh-cn/mozilla/tech/xul/attribute/buttonaccesskeyaccept/index.html deleted file mode 100644 index 4e42f14bad..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/buttonaccesskeyaccept/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: buttonaccesskeyaccept -slug: Mozilla/Tech/XUL/Attribute/buttonaccesskeyaccept -translation_of: Archive/Mozilla/XUL/Attribute/buttonaccesskeyaccept ---- -
- « XUL Reference home
-
-
- buttonaccesskeyaccept
-
- Type: string
-
- The access key to use for the "accept" button.
-
-

 

-
-

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/buttonlabelextra1/index.html b/files/zh-cn/mozilla/tech/xul/attribute/buttonlabelextra1/index.html deleted file mode 100644 index 1de5913a9b..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/buttonlabelextra1/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: buttonlabelextra1 -slug: Mozilla/Tech/XUL/Attribute/buttonlabelextra1 -translation_of: Archive/Mozilla/XUL/Attribute/buttonlabelextra1 ---- -
- « XUL Reference home
-
-
- buttonlabelextra1
-
- Type: string
-
- The label to appear on the first extra button.
-
-
-

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/buttonlabelextra2/index.html b/files/zh-cn/mozilla/tech/xul/attribute/buttonlabelextra2/index.html deleted file mode 100644 index 1a7f700eac..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/buttonlabelextra2/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: buttonlabelextra2 -slug: Mozilla/Tech/XUL/Attribute/buttonlabelextra2 -translation_of: Archive/Mozilla/XUL/Attribute/buttonlabelextra2 ---- -
- « XUL Reference home
-
-
- buttonlabelextra2
-
- Type: string
-
- The label to appear on the second extra button.
-
-
-

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/buttons/index.html b/files/zh-cn/mozilla/tech/xul/attribute/buttons/index.html deleted file mode 100644 index 5759eabd90..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/buttons/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: buttons -slug: Mozilla/Tech/XUL/Attribute/buttons -translation_of: Archive/Mozilla/XUL/Attribute/buttons ---- -
- « XUL Reference
-
-
- buttons
-
- 类型: 列表,下面的值用逗号分隔
-
- 需要显示在对话框上的按钮的一个列表,使用逗号分隔。将按钮放置在合适的位置,将根据用户平台自动执行基本的事件处理。在列表中可以使用以下值: -
    -
  • accept:“确定”按钮,按下按钮时将接受更改。此按钮为默认按钮。
  • -
  • cancel:“取消”按钮,将取消操作。
  • -
  • help:“帮助”按钮,在对话框显示一个“帮助”按钮。
  • -
  • disclosure:“更多信息”按钮,显示一个“more info”按钮。该按钮可能是一个按钮或一个三角形。
  • -
  • extra1:一个可选的额外的按钮。你可以通过buttonlabelextra1 属性设置它的label。
  • -
  • extra2:第二个可选的额外的按钮。你可以通过 buttonlabelextra2 属性设置它的label。
  • -
-
-
-
-

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/checked/index.html b/files/zh-cn/mozilla/tech/xul/attribute/checked/index.html deleted file mode 100644 index 249a1f1ee1..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/checked/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: checked -slug: Mozilla/Tech/XUL/Attribute/checked -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/checked ---- -
- « XUL Reference home
-
-
- checked
-
- Type: - - boolean -
-
- Indicates whether the element is checked or not.
-
- Use hasAttribute() to determine whether this attribute is set instead of getAttribute().
-
- For buttons, the type attribute must be set to checkbox or radio for this attribute to have any effect.<magic name="\"PAGENAME\"/"></magic>
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/class/index.html b/files/zh-cn/mozilla/tech/xul/attribute/class/index.html deleted file mode 100644 index 45eb8dbc87..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/class/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: class -slug: Mozilla/Tech/XUL/Attribute/class -tags: - - XUL Attributes - - XUL Reference -translation_of: Archive/Mozilla/XUL/Attribute/class ---- -
« XUL Reference home
- -
-
class
-
Type: - string
-
- 类型:字符串(string)
-
The style class of the element. Multiple classes may be specified by separating them with spaces.
- 元素样式类型。多个类可以使用空格分开。
-
- -
 
- -

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/coalesceduplicatearcs/index.html b/files/zh-cn/mozilla/tech/xul/attribute/coalesceduplicatearcs/index.html deleted file mode 100644 index 01e6ddd51f..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/coalesceduplicatearcs/index.html +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: coalesceduplicatearcs -slug: Mozilla/Tech/XUL/Attribute/coalesceduplicatearcs -tags: - - XUL Attributes - - XUL Reference -translation_of: Archive/Mozilla/XUL/Attribute/coalesceduplicatearcs ---- -
« XUL Reference home
- -
-
coalesceduplicatearcs
-
Type: boolean
- 类型:布尔类型(boolean)
-
Valid on any element that has a datasources attribute. When multiple datasources are used, one may override an assertion from another. This attribute, if true, which is the default, allows a datasource to negate an earlier assertion.
- 任何有 datasources 属性的元素有效。当有多个数据源时使用,可以覆盖另一个声明。这个属性,如果是真,这是默认属性,允许一个数据源取消更早的声明。 
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/collapsed/index.html b/files/zh-cn/mozilla/tech/xul/attribute/collapsed/index.html deleted file mode 100644 index 50d54b771f..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/collapsed/index.html +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: collapsed -slug: Mozilla/Tech/XUL/Attribute/collapsed -translation_of: Archive/Mozilla/XUL/Attribute/collapsed ---- -
« XUL Reference home
- -
-
collapsed
-
Type: boolean
- 类型:布尔类型(boolean)
-
If true, then the element is collapsed and does not appear. It is equivalent to setting the CSS visibility property to collapse.
- 如果是真,那么这个元素可以折叠并且隐藏。相当于设置CSS的 visibility 属性为 collapse。
-
- -
-

See also
- 相关参考

- - - -

-
- -

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/command/index.html b/files/zh-cn/mozilla/tech/xul/attribute/command/index.html deleted file mode 100644 index 75c4957f0e..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/command/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: command -slug: Mozilla/Tech/XUL/Attribute/command -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/command ---- -
- « XUL Reference home
-
-
- command
-
- Type: - - element id -
-
- Set to the id of a command element that is being observed by the element.
-
-
-

Example

-
<command id="cmd_openhelp" oncommand="alert('Help');"/>
-<button label="Help" command="cmd_openhelp"/>
-<button label="More Help" command="cmd_openhelp"/>
-
-

See also

-

command element, oncommand and commandset

-
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/container/index.html b/files/zh-cn/mozilla/tech/xul/attribute/container/index.html deleted file mode 100644 index 4b1429ae43..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/container/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: container -slug: Mozilla/Tech/XUL/Attribute/container -translation_of: Archive/Mozilla/XUL/Attribute/container ---- -
« XUL Reference home
- -
-
container
-
Type: boolean
- 类型:布尔类型(boolean)
-
Set to true if the element is to act as a container which can have child elements. This would be used for folders. This will be set by the template builder as needed.
- 如果该元素是作为一个容器可以有子元素,设置为真。
-
- -
-

-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/control/index.html b/files/zh-cn/mozilla/tech/xul/attribute/control/index.html deleted file mode 100644 index 74a0edec5a..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/control/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: control -slug: Mozilla/Tech/XUL/Attribute/control -tags: - - XUL Attributes - - XUL Reference -translation_of: Archive/Mozilla/XUL/Attribute/control ---- -
- « XUL Reference home
-
-
- control
-
- Type: element id
-
- This attribute specifies the id of the element with which the label is associated. When the user clicks on the label, the associated element is given focus.
- 这个属性定义了元素的id,它与label相关联。当用户点击 label 的时候,相关联的元素将获得焦点。
-
-
-

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/crop/index.html b/files/zh-cn/mozilla/tech/xul/attribute/crop/index.html deleted file mode 100644 index 1ab3f59210..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/crop/index.html +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: crop -slug: Mozilla/Tech/XUL/Attribute/crop -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/crop ---- -
- « XUL Reference home
-
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- -
-
-
- Depending on the platform and theme being used, some elements will have a set maximum width so they will be always appear cropped. If you wish to use the value none and the displayed text is larger than this maximum width, you may be able to use the max-width CSS property (or the maxwidth attribute) to override this size. For example, for a menuitem in a menu you can add the following CSS rule when you want to use the value none:
-
-
menupopup > menuitem, menupopup > menu { max-width: none; }
-
-
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/description/index.html b/files/zh-cn/mozilla/tech/xul/attribute/description/index.html deleted file mode 100644 index 008aa1281c..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/description/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: description -slug: Mozilla/Tech/XUL/Attribute/description -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/description ---- -
- « XUL Reference home
-
-
- description
-
- Type: - - string -
-
- Descriptive text to appear in addition to the dialog title.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/dir/index.html b/files/zh-cn/mozilla/tech/xul/attribute/dir/index.html deleted file mode 100644 index 0b4c5c36a4..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/dir/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: dir -slug: Mozilla/Tech/XUL/Attribute/dir -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/dir ---- -
- « XUL Reference home
-
-
- dir
-
- Type: - - one of the values below -
-
- The direction in which the child elements of the element are placed.
-
-
-
- normal
-
- For scales, the scale's values are ordered from left to right (for horizontal scales) or from top to bottom (for vertical scales)  For other elements, the elements are placed left to right or top to bottom in the order they appear in the XUL code
-
- reverse
-
- For scales, the scale's values are ordered from right to left (for horizontal scales) or from bottom to top (for vertical scales). For other elements, they are placed right to left or bottom to top. This is reverse of the order in which they appear in the XUL code.
-
- -
-

See also

- -
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/disabled/index.html b/files/zh-cn/mozilla/tech/xul/attribute/disabled/index.html deleted file mode 100644 index 057bca261d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/disabled/index.html +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: disabled -slug: Mozilla/Tech/XUL/Attribute/disabled -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/disabled ---- -
« XUL Reference home
- -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/flex/index.html b/files/zh-cn/mozilla/tech/xul/attribute/flex/index.html deleted file mode 100644 index 7d9954d30a..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/flex/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: flex -slug: Mozilla/Tech/XUL/Attribute/flex -tags: - - XUL Attributes - - XUL Reference -translation_of: Archive/Mozilla/XUL/Attribute/flex ---- -
« XUL Reference home
- -
-
flex
-
Type: string (representing an integer)
- 类型:字符串 (string) 表示一个整数
-
Indicates the flexibility of the element, which indicates how an element's container distributes remaining empty space among its children. Flexible elements grow and shrink to fit their given space. Elements with larger flex values will be made larger than elements with lower flex values, at the ratio determined by the two elements. The actual value is not relevant unless there are other flexible elements within the same container. Once the default sizes of elements in a box are calculated, the remaining space in the box is divided among the flexible elements, according to their flex ratios. Specifying a flex value of 0 has the same effect as leaving the flex attribute out entirely.
- 指示一个元素的伸缩性,
-
- -
-

-
- -

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/href/index.html b/files/zh-cn/mozilla/tech/xul/attribute/href/index.html deleted file mode 100644 index 50013e44b3..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/href/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: href -slug: Mozilla/Tech/XUL/Attribute/href -tags: - - XUL 参考 - - XUL 属性 -translation_of: Archive/Mozilla/XUL/Attribute/href ---- -
« XUL Reference home
- -
-
href
-
类型: 文本
-
定义一个当元素被点击时将会打开的 URL 。需要引用类 text-link
-
- -
-
<label href="http://example.com" class="text-link" value="点击这里前往 example.com"/>
-
-
- -
-

-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/id/index.html b/files/zh-cn/mozilla/tech/xul/attribute/id/index.html deleted file mode 100644 index 50e8e7b188..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/id/index.html +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: id -slug: Mozilla/Tech/XUL/Attribute/id -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/id ---- -
- « XUL Reference home
-
-
- id
-
- 类型: 元素的ID,在主窗口中必须唯一
-
- 一个唯一的标识一边开发者能够定义. 你可以使用方法 getElementById() 或者其他 DOM 的函数并在样式表中添加对元素的引用。
-
-
-

示例

-
<button id="foo" label="Click Me" oncommand="doSomething()"/>
-
-<script>
-function doSomething(){
-    var myButton = document.getElementById('foo');
-    myButton.setAttribute('label','The button was pressed');
-}
-</script>
-
-

一个更加抽象的版本

-
<button id="foo" label="Click Me" oncommand="setWidgetLabel(this, 'I was pressed')"/>
-<script>
-function setWidgetLabel(idName, newCaption){
-   document.getElementById( idName.id ).setAttribute('label',newCaption)
-}
-
-</script>
-
-

同样,这里还有一些资料

-

name

-
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/image.onload/index.html b/files/zh-cn/mozilla/tech/xul/attribute/image.onload/index.html deleted file mode 100644 index 846d404d89..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/image.onload/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: image.onload -slug: Mozilla/Tech/XUL/Attribute/image.onload -translation_of: Archive/Mozilla/XUL/Attribute/image.onload ---- -
« XUL Reference home
- -
-
image.onload
-
类型: 脚本代码
-
该事件的处理函数将会在 image 元素指示的图片加载完毕之后触发。此事件触发适用于用 src 元素属性或用 list-style-image css属性声明元素样式。如果图片的加载源发生变化,该事件会在图片加载完毕之后再次触发。该事件不会在文档树上向上冒泡。
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/image/index.html b/files/zh-cn/mozilla/tech/xul/attribute/image/index.html deleted file mode 100644 index dd82594964..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/image/index.html +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: image -slug: Mozilla/Tech/XUL/Attribute/image -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/image ---- -
- « XUL Reference home
-
-
- image
-
- Type: - - image URL -
-
- The URL of the image to appear on the element. If this attribute is empty or left out, no image appears. The position of the image is determined by the dir and orient attributes.
-
-
-

See also

-

image element

-
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/increment/index.html b/files/zh-cn/mozilla/tech/xul/attribute/increment/index.html deleted file mode 100644 index 782156bb47..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/increment/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: increment -slug: Mozilla/Tech/XUL/Attribute/increment -translation_of: Archive/Mozilla/XUL/Attribute/increment ---- -
- « XUL Reference home
-
-
- increment
-
- 类型:整数
-
- 拖动刻度条控件(scale元素)中的拉杆,点击滚动条控件(scrollbar元素)中的箭头(拖动拉杆也可以),点击数字输入框(type属性为numbertextbox元素)中的箭头时,其curpos属性或者value属性每次改变的数字值,默认值为1.
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/index.html b/files/zh-cn/mozilla/tech/xul/attribute/index.html deleted file mode 100644 index 097a3d6678..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/index.html +++ /dev/null @@ -1,304 +0,0 @@ ---- -title: Attributes -slug: Mozilla/Tech/XUL/Attribute -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute ---- -

« XUL Reference home -

- -
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/label/index.html b/files/zh-cn/mozilla/tech/xul/attribute/label/index.html deleted file mode 100644 index 1846c63a8e..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/label/index.html +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: label -slug: Mozilla/Tech/XUL/Attribute/label -tags: - - XUL Attributes - - XUL Reference -translation_of: Archive/Mozilla/XUL/Attribute/label ---- -
- « XUL Reference home
-
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
-
-

See also

- -

Examples in JavaScript

-
<label value="Whaw" id="the-big-label" command="the-big-button"/>
-<button id="the-big-button" label="Click me"
-	oncommand="alert(document.getElementById('the-big-label').value)"/>
-
-<label id="myLabel" value="My label"/>
-<button label="Click me"
-	oncommand="document.getElementById('myLabel').setAttribute('value','Value changed');" />
-
-<checkbox label="my Checkbox" id="myCheckboX"/>
-<button label="Another click"
-	oncommand="document.getElementById('myCheckboX').setAttribute('label','Still not checked');"/>
-<button label="Show label of checkbox"
-	oncommand="alert( document.getElementById('myCheckboX').getAttribute('label') )"/>
-
-
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/max/index.html b/files/zh-cn/mozilla/tech/xul/attribute/max/index.html deleted file mode 100644 index 93eb88d4f7..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/max/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: max -slug: Mozilla/Tech/XUL/Attribute/max -translation_of: Archive/Mozilla/XUL/Attribute/max ---- -
- « XUL Reference home
-
-
- 类型:整数
-
- 设置刻度条控件(scale元素)或者数字输入框控件(type属性为number的textbox元素)中能输入的最大数字.刻度条控件中,该属性的默认值为100,数字输入框中,该属性的默认值为无穷大.
-
-
-

相关链接

- -
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/menuitem.key/index.html b/files/zh-cn/mozilla/tech/xul/attribute/menuitem.key/index.html deleted file mode 100644 index b4239b866d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/menuitem.key/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: menuitem.key -slug: Mozilla/Tech/XUL/Attribute/menuitem.key -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/menuitem.key ---- -
- « XUL Reference home
-
-
- key
-
- Type: - - element id -
-
- Set to the id of a key element whose key shortcut is displayed in the menuitem.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/menuitem.name/index.html b/files/zh-cn/mozilla/tech/xul/attribute/menuitem.name/index.html deleted file mode 100644 index a485138846..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/menuitem.name/index.html +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: menuitem.name -slug: Mozilla/Tech/XUL/Attribute/menuitem.name -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/menuitem.name ---- -
- « XUL Reference home
-
-
- name
-
- Type: - - string name -
-
- Radio menuitems with the same name as put into a group. Only one menuitem in each radio group can be checked at a time.
-
-
-

Example

-
<toolbox>
-  <menubar id="planets-menubar">
-    <menu id="planet-menu" label="Planet">
-      <menupopup>
-        <menuitem id="jupiter" label="Jupiter" type="radio" name="planet"/>
-        <menuitem id="saturn" label="Saturn" type="radio" name="planet" checked="true"/>
-        <menuitem id="uranus" label="Uranus" type="radio" name="planet"/>
-      </menupopup>
-    </menu>
-  </menubar>
-</toolbox>
-
-

See also

-

name and menus in the XUL Tutorial

-
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/menuitem.type/index.html b/files/zh-cn/mozilla/tech/xul/attribute/menuitem.type/index.html deleted file mode 100644 index 872c50331b..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/menuitem.type/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: menuitem.type -slug: Mozilla/Tech/XUL/Attribute/menuitem.type -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/menuitem.type ---- -
- « XUL Reference home
-
-
- type
-
- Type: - - one of the values below -
-
- Can be used to create checkable menuitems or for radio button menuitems.
-
- -

More information on adding checkmarks to menus in the XUL tutorial

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/min/index.html b/files/zh-cn/mozilla/tech/xul/attribute/min/index.html deleted file mode 100644 index 9646b1da96..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/min/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: min -slug: Mozilla/Tech/XUL/Attribute/min -translation_of: Archive/Mozilla/XUL/Attribute/min ---- -
- « XUL Reference home
-
-
- min
-
- 类型:整数
-
- 该控件可以有的最小的整数值,默认值为0.
-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/name/index.html b/files/zh-cn/mozilla/tech/xul/attribute/name/index.html deleted file mode 100644 index cd1695a84c..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/name/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: name -slug: Mozilla/Tech/XUL/Attribute/name -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/name ---- -
- « XUL Reference home -

See also

- -
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/onpopupshowing/index.html b/files/zh-cn/mozilla/tech/xul/attribute/onpopupshowing/index.html deleted file mode 100644 index ec821daefe..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/onpopupshowing/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: onpopupshowing -slug: Mozilla/Tech/XUL/Attribute/onpopupshowing -translation_of: Archive/Mozilla/XUL/Attribute/onpopupshowing ---- -
- « XUL Reference home
-
-
- onpopupshowing
-
- Type: script code
-
- This event is sent to a popup just before it is opened. This handler is usually used to dynamically set the contents when the user requests to display it. Returning false from this event handler prevents the popup from appearing.
-
- 该事件在 popup 打开之前传给它。它用于动态生成菜单项。如果返回 false 值,则 popup 将不会显示菜单项。
-
-
-

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/onpopupshown/index.html b/files/zh-cn/mozilla/tech/xul/attribute/onpopupshown/index.html deleted file mode 100644 index a94af052a2..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/onpopupshown/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: onpopupshown -slug: Mozilla/Tech/XUL/Attribute/onpopupshown -translation_of: Archive/Mozilla/XUL/Attribute/onpopupshown ---- -
- « XUL Reference home
-
-
- onpopupshown
-
- Type: script code
-
- This event is sent to a popup after it has been opened, much like the onload event is sent to a window when it is opened.
-
- 该事件在 popup 打开之后触发,与 window 的 onload 事件比较类似。
-
-
-

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/orient/index.html b/files/zh-cn/mozilla/tech/xul/attribute/orient/index.html deleted file mode 100644 index aa1c735a6c..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/orient/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: orient -slug: Mozilla/Tech/XUL/Attribute/orient -translation_of: Archive/Mozilla/XUL/Attribute/orient ---- -

布局(orient)

-
-
- 值类型:可以是下面值中的一种。
- 指定了子控件的布局(orient)为水平分布的(horizontally)或者是垂直分布的(vertically)。默认值依赖于控件本身。你也可以使用-moz-box-orient中的样式属性。 -
    -
  • horizontally: 子控件会被按照在xul源文件中出现的位置依次布置在一行中。
  • -
  • vertically: 子控件会被按照在xul源文件中出现的位置依次布置在一列中。
  • -
-
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/pending/index.html b/files/zh-cn/mozilla/tech/xul/attribute/pending/index.html deleted file mode 100644 index 0ab9643c8f..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/pending/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: pending -slug: Mozilla/Tech/XUL/Attribute/pending -translation_of: Archive/Mozilla/XUL/Attribute/pending ---- -
- « XUL Reference home
-
-
- pending
-
- Type: boolean
-
- This attribute is set to true if the tab is currently in the process of being restored by the session store service. Once the tab is restored, this attribute is removed. You can determine if a tab is being restored by checking to see if hasAttribute("pending") is true. If the user has turned on the "Don't load tabs until selected" preference, the pending attribute is set on tabs until they get loaded.
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/persist/index.html b/files/zh-cn/mozilla/tech/xul/attribute/persist/index.html deleted file mode 100644 index b1d30d5a59..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/persist/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: persist -slug: Mozilla/Tech/XUL/Attribute/persist -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/persist ---- -
- « XUL Reference home
-
-
- persist
-
- Type: - - space-separated list of attribute names -
-
- A space-separated list of attributes that are maintained when the window is closed. When the window is re-opened, the values of persistent attributes are restored. In Mozilla, persistent attributes are stored in the per-profile file localstore.rdf. Persistence can also be stored using the document.persist function. In order for persistence to work, the element must also have an id.
-
-

 

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/selected/index.html b/files/zh-cn/mozilla/tech/xul/attribute/selected/index.html deleted file mode 100644 index 47971cd8c8..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/selected/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: selected -slug: Mozilla/Tech/XUL/Attribute/selected -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/selected ---- -
- « XUL Reference home
-
-
- selected
-
- Type: - - boolean -
-
- Indicates whether the element is selected or not. This value is read-only. To change the selection, set either the selectedIndex or selectedItem property of the containing element.
-
-
-

See also

- -
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/selectedindex/index.html b/files/zh-cn/mozilla/tech/xul/attribute/selectedindex/index.html deleted file mode 100644 index 72dd679801..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/selectedindex/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: selectedIndex -slug: Mozilla/Tech/XUL/Attribute/selectedIndex -translation_of: Archive/Mozilla/XUL/Attribute/selectedIndex ---- -
- « XUL Reference home
-
-
- selectedIndex
-
- 类型: 整数
-
- 获取或设置当前所选面板的索引号,索引号从0开始.
-
diff --git a/files/zh-cn/mozilla/tech/xul/attribute/tabindex/index.html b/files/zh-cn/mozilla/tech/xul/attribute/tabindex/index.html deleted file mode 100644 index c5e54fdd1c..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/tabindex/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: tabindex -slug: Mozilla/Tech/XUL/Attribute/tabindex -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/tabindex ---- -
« XUL Reference home
- -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- -
 
- -

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/validate/index.html b/files/zh-cn/mozilla/tech/xul/attribute/validate/index.html deleted file mode 100644 index a56181d8b7..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/validate/index.html +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: validate -slug: Mozilla/Tech/XUL/Attribute/validate -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/validate ---- -
- « XUL Reference home
-
-
- validate
-
- Type: - - one of the values below -
-
- This attribute indicates whether to load the image from the cache or not. This would be useful if the images are stored remotely or you plan on swapping the image frequently. The following values are accepted, or leave out the attribute entirely for default handling:
-
- -
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/attribute/value/index.html b/files/zh-cn/mozilla/tech/xul/attribute/value/index.html deleted file mode 100644 index f436308d89..0000000000 --- a/files/zh-cn/mozilla/tech/xul/attribute/value/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: value -slug: Mozilla/Tech/XUL/Attribute/value -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/Attribute/value ---- -
- « XUL Reference home
-
-
- value
-
- Type: - - string -
-
- The string attribute allows you to associate a data value with an element. It is not used for any specific purpose, but you can access it with a script for your own use.
-
-
-

See also

- -
-

diff --git a/files/zh-cn/mozilla/tech/xul/broadcaster/index.html b/files/zh-cn/mozilla/tech/xul/broadcaster/index.html deleted file mode 100644 index be97efef42..0000000000 --- a/files/zh-cn/mozilla/tech/xul/broadcaster/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: broadcaster -slug: Mozilla/Tech/XUL/broadcaster -translation_of: Archive/Mozilla/XUL/broadcaster ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-
-
- 当您希望若干个元素共享一个或多个属性值时,或者当您想要多个元素对某一个状态改变做出响应是,可以使用 broadcaster。任何监视 broadcaster 的元素都会共享到 broadcaster 中的属性。比如说,假设我们有一个 broadcaster,它拥有一个 label 属性,而它的观察者们正在监视这个 label。这时如果 label 发生了改变,label 的观察者们将立刻被唤醒(update)。改变发生时,每个观察者都会收到一个 onbroadcast 事件。
-
- 对于 menuitem 或者 button 来说,如果只是为了根据功能是否可用,即时更新菜单项目的 disabled 状态,那么您应该优先考虑 command
-

更多内容请参考 Broadcasters and Observers XUL Tutorial.

-

Examples

-

(example needed)

-

Attributes

-

- - - - - -

Inherited from XUL element
-align, -allowevents, -allownegativeassertions, -class, -coalesceduplicatearcs, -collapsed, -container, -containment, -context, -contextmenu, -datasources, -dir, -empty, -equalsize, -flags, -flex, -height, -hidden, -id, -insertafter, -insertbefore, -left, -maxheight, -maxwidth, -menu, -minheight, -minwidth, -mousethrough, -observes, -ordinal, -orient, -pack, -persist, -popup, -position, -preference-editable, -querytype, -ref, -removeelement, -sortDirection, -sortResource, -sortResource2, -statustext, -style, -template, -tooltip, -tooltiptext, -top, -uri, -wait-cursor, -width

-

-

Properties

-

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -

TBD

-

diff --git a/files/zh-cn/mozilla/tech/xul/browser/index.html b/files/zh-cn/mozilla/tech/xul/browser/index.html deleted file mode 100644 index 4f9a039f3a..0000000000 --- a/files/zh-cn/mozilla/tech/xul/browser/index.html +++ /dev/null @@ -1,409 +0,0 @@ ---- -title: browser -slug: Mozilla/Tech/XUL/browser -translation_of: Archive/Mozilla/XUL/browser ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

A frame which is expected to contain a view of a Web document. It is similar to an iframe except that it holds a page history and contains additional methods to manipulate the currently displayed page.

-

Most of the properties and methods of the browser will rarely be used and can only be called from chrome URLs. Other URLs will need to use the document and history objects to change the displayed document.

-
-
- Attributes
-
- autocompleteenabled, autocompletepopup, autoscroll, disablehistory, disablesecurity, homepage, showcaret, src, type
-
-
-
- Properties
-
- accessibleType, canGoBack, canGoForward, contentDocument, contentPrincipal, contentTitle, contentViewerEdit, contentViewerFile, contentWindow, currentURI, docShell, documentCharsetInfo, homePage, markupDocumentViewer, messageManager, preferences, securityUI, sessionHistory, webBrowserFind, webNavigation, webProgress
-
-
-
- Methods
-
- addProgressListener, goBack, goForward, goHome, gotoIndex, loadURI, loadURIWithFlags, reload, reloadWithFlags, removeProgressListener, stop, swapDocShells
-
-

Examples

-
- Image:XUL_ref_browser.png
-
<!-- shows Mozilla homepage inside a groupbox -->
-<groupbox flex="1">
-  <caption label="Mozilla homepage"/>
-  <browser type="content" src="http://www.mozilla.org" flex="1"/>
-</groupbox>
-
-

Attributes

-

-

- - -
-
autocompleteenabled
-
Type: boolean
-
Set to true to enable autocomplete of fields.
-
-
- -
-
- autocompletepopup
-
- Type: id
-
- The id of a popup element used to hold autocomplete results for the element.
-
- -
- - -
-
autoscroll
-
Type: boolean
-
Set to false to disable autoscroll for this browser. If this attribute is set to true or omitted, autoscroll will be enabled or depending on the user preference general.autoScroll.
-
-
- -
disablehistory
Type: boolean
Disables both session and global history for the docshell attached to the browser.
-
-
- - -
-
disablesecurity
-
Type: boolean
-
Set this attribute to true to disable the security UI for this browser. Omit this attribute off to enable it.
-
-
- - -
-
homepage
-
Type: URL
-
This attribute allows you to set a homepage for the browser element. It does not have any correlation with the user's browser homepage; instead it is a convenient property to hold a home page. You can switch to this home page using the goHome method.
-
-
- - -
-
showcaret
-
Type: boolean
-
Whether or not to cause a typing caret to be visible in the content area. Default is false.
-
- - -
- -
-
- src
-
- Type: URI
-
- The URI of the content to appear in the element.
-
- - -
- - -
-
type
-
Type: one of the values below.
-
The type of browser, which can be used to set access of the document loaded inside the browser. If this is not set, the loaded document has the same access as the window containing the browser. More precisely: The document loaded into a chrome window is always of chrome type. Subdocuments of chrome documents are of chrome type, unless the container element (one of iframe, browser or editor) has one of the special type attribute values (the common ones are content, content-targetable and content-primary) indicating that the subdocument is of content type. This boundary has a number of special effects, such as making window.top == window (unless the browser is added to a chrome document), and preventing documents from inheriting the principal of the parent document. The type attribute on all frames in content documents is ignored; subdocuments of content documents are always content documents.
-
-
Warning: The type attribute must be set before the element is inserted into the document.
-
-
-
-
content
-
A browser for content. The content that is loaded inside the browser is not allowed to access the chrome above it.
-
content-primary
-
The primary browser for content. The content that is loaded inside the browser is not allowed to access the chrome above it. For instance, in a web browser, this would be the element that displays the web page. The window for the primary content can be retrieved more conveniently using window.content.
-
content-targetable
-
One browser among many for content. The content that is loaded inside the browser is not allowed to access the chrome above it. This is the preferred value for any browser element in an application, which will use multiple browsers of equal privileges, and is unselected at the moment.
-
chrome
-
(default behaviour): A browser, intended to be used for loading privileged content using a chrome:// URI. Don't use for content from web, as this may cause serious security problems!
-
-
-
- - -

-

Properties

-

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- canGoBack
-
- Type: boolean
-
- This read-only property is true if there is a page to go back to in the session history and the Back button should be enabled.
-
- -
-
canGoForward
-
Type: boolean
-
This read-only property is true if there is a page to go forward to in the session history and the Forward button should be enabled.
-
-
-
- contentDocument
-
- Type: document
-
- This read-only property contains the document object in the element.
-
- -
-
contentPrincipal
-
Type: nsIPrincipal
-
This read-only property contains the principal for the content loaded in the browser, which provides security context information.
-
-
-
- contentTitle
-
- Type: string
-
- This read-only property contains the title of the document object in the browser.
-
-
-
- contentViewerEdit
-
- Type: nsIContentViewerEdit
-
- This read-only property contains the nsIContentViewerEdit which handles clipboard operations on the document.
-
-
-
- contentViewerFile
-
- Type: nsIContentViewerFile
-
- Reference to the nsIContentViewerFile interface for the document.
-
-
contentWindow
Type: TODO
Use the contentWindow.wrappedJSObject to obtain a DOM(html) window object
-
-
-
- currentURI
-
- Type: nsIURI
-
- This read-only property contains the currently loaded URL. To change the URL, use the loadURI method.
-
-
-
- docShell
-
- Type: nsIDocShell
-
- This read-only property contains the nsIDocShell object for the document.
-
-
-
- documentCharsetInfo Obsolete since Gecko 12.0
-
- Type: nsIDocumentCharsetInfo
-
- This read-only property contains the nsIDocumentCharsetInfo object for the document which is used to handle which character set should be used to display the document. The properties of the nsIDocumentCharsetInfo object were merged into the docshell in Gecko 12.0 (Firefox 12.0 / Thunderbird 12.0 / SeaMonkey 2.9).
-
-
-
- homePage
-
- Type: string home page URL
-
- This property holds the value of the user's home page setting.
-
-
-
- markupDocumentViewer
-
- 类型: nsIMarkupDocumentViewer
-
- 这个只读的属性包含 nsIMarkupDocumentViewer 接口,负责document文档的绘制。
-
-
-
- messageManager
-
- Type: message manager object
-
- This read-only property returns the message manager object for the browser element.
-
-
-
- preferences
-
- 类型: nsIPrefService
-
- 这是一个只读属性,其值为一个nsIPref对象,可以用来读取或设置用户的首选项.
-
-
-
- securityUI
-
- Type: nsISecureBrowserUI
-
- The read-only property holds an object which may be used to determine the security level of the loaded document.
-
-
-
- sessionHistory
-
- Type: nsISHistory
-
- This read-only property contains the nsISHistory object which holds the session history.
-
-
-
- webBrowserFind
-
- Type: nsIWebBrowserFind
-
- This read-only property contains an nsIWebBrowserFind object which can be used to search for text in the document.
-
-
-
- webNavigation
-
- Type: nsIWebNavigation
-
- This read-only property contains the nsIWebNavigation object for the document. Most of its methods are callable directly on the element itself, such as goBack and goForward. It also contains the load constants used by reloadWithFlags and loadURIWithFlags.
-
-
-
- webProgress
-
- Type: nsIWebProgress
-
- This read-only property contains an nsIWebProgress object which is used to monitor the progress of a document loading.
-

-

Methods

-

- - - - - -
-

Inherited Methods
-addEventListener(), appendChild(), blur, click, cloneNode(), compareDocumentPosition, dispatchEvent(), doCommand, focus, getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getBoundingClientRect(), getClientRects(), getElementsByAttribute, getElementsByAttributeNS, getElementsByClassName(), getElementsByTagName(), getElementsByTagNameNS(), getFeature(), getUserData, hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isDefaultNamespace(), isEqualNode, isSameNode, isSupported(), lookupNamespaceURI, lookupPrefix, normalize(), querySelector(), querySelectorAll(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS(), setUserData

- -

-

-
- addProgressListener( listener )
-
- Return type: no return value
-
- Add a progress listener to the browser which will monitor loaded documents. The progress listener should implement the nsIWebProgressListener interface.
-
-
goBack()
-
Return type: no return value
-
Go back one page in the history.
-
-
goForward()
-
Return type: no return value
-
Go forward one page in the history.
-
-
goHome()
-
Return type: no return value
-
Load the user's home page into the browser.
-
-
gotoIndex( index )
-
Return type: no return value
-
Navigate to the page in the history with the given index. Use a positive number to go forward and a negative number to go back.
-

NOTE: This is the XUL method on <browser> / <tabbrowser>, not the global function in chrome://browser/content/browser.js. Please check which one you're documenting! (This one has no post data parameter, see loadURIWithFlags for a version that does)

-
-
- loadURI( uri, referrer, charset )
-
- Return type: no return value
-
- Load a URL into the document, with the given referrer and character set.
-
- The first argument should be a string, not a nsIURI object. To get a string from an nsIURI, use nsIURI.spec or nsIURI.asciiSpec
-
-
loadURIWithFlags( uri, flags, referrer, charset, postData )
-
Return type: no return value
-
Load a URL into the document, with the specified load flags, the given referrer, character set, and POST data. In addition to the flags allowed for the reloadWithFlags method, the following flags are also valid: -
    -
  • LOAD_FLAGS_IS_REFRESH: This flag is used when the URL is loaded because of a meta tag refresh or redirect.
  • -
  • LOAD_FLAGS_IS_LINK: This flag is used when the URL is loaded because a user clicked on a link. The HTTP Referer header is set accordingly.
  • -
  • LOAD_FLAGS_BYPASS_HISTORY: Do not add the URL to the session history.
  • -
  • LOAD_FLAGS_REPLACE_HISTORY: Replace the current URL in the session history with a new one. This flag might be used for a redirect.
  • -
-
-
- -

(See nsIWebNavigation.loadURI() for details on the referrer and postData parameters.)

-
reload()
-
Return type: no return value
-
Reloads the document in the browser element on which you call this method.
-
-
reloadWithFlags( flags )
-
Return type: no return value
-
Reloads the document in the browser with the given load flags. The flags listed below may be used, which are all constants of the webNavigation property (or the nsIWebNavigation interface). You may combine flags using a or symbol ( | ). -
    -
  • LOAD_FLAGS_NONE: No special flags. The document is loaded normally.
  • -
  • LOAD_FLAGS_BYPASS_CACHE: Reload the page, ignoring if it is already in the cache. This is the flag used when the reload button is pressed while the Shift key is held down.
  • -
  • LOAD_FLAGS_BYPASS_PROXY: Reload the page, ignoring the proxy server.
  • -
  • LOAD_FLAGS_CHARSET_CHANGE: This flag is used if the document needs to be reloaded because the character set changed.
  • -
-
-
-
removeProgressListener( listener )
-
Return type: no return value
-
Remove a nsIWebProgressListener from the browser.
-
-
- stop()
-
- 返回值: 无返回值
-
- 效果等同于按下了停止按钮,停止当前页面中文档的加载.
-
-
- swapDocShells( otherBrowser )
-
- Return type: no return value
-
- Swaps the content, history and current state of this browser with another browser. During the swap, pagehide and pageshow events are fired on both browsers. This method can be used to move browser between windows or tear off a browser into a new window.
-
- -
-

Note: Both browsers must be either standalone browsers or embedded in a tabbrowser. You can't mix them.

- -
-
- Interfaces
-
- nsIAccessibleProvider
-
-

diff --git a/files/zh-cn/mozilla/tech/xul/button/index.html b/files/zh-cn/mozilla/tech/xul/button/index.html deleted file mode 100644 index a3bcf45284..0000000000 --- a/files/zh-cn/mozilla/tech/xul/button/index.html +++ /dev/null @@ -1,528 +0,0 @@ ---- -title: button -slug: Mozilla/Tech/XUL/button -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/button ---- -
- « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
- -

按钮就是可以点击的东西。事件处理程序可以用来捕获鼠标、键盘和其他事件。它通常呈现为一个灰色开始长方形。您可以指定按钮的label 属性来将按钮的文字设置好,或者直接写在标签中间也行。

- -

更多信息请参阅 XUL tutorial.

- -
-
Attributes
-
accesskey, autocheck, checkState, checked, command, crop, dir, disabled, dlgtype, group, icon, image, label, open, orient, tabindex, type
-
- -
-
Properties
-
accessKey, accessibleType, autoCheck, checkState, checked, command, crop, dir, disabled, dlgType, group, image, label, open, orient, tabIndex, type
-
- -

Examples

- -
Image:XUL_ref_button.png
- -
<button label="Press Me"
-        oncommand="alert('You pressed me!');"/>
-
- -

Attributes

- -

- - - - -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

-
- - -
-
autocheck
-
类型: - boolean -
-
如果此属性为 true,或空白, 每次点击按钮时,此按钮的状态检查都会被执行一次。如果此属性为false, 检查会手动的被拒绝。当autocheck值为true的时候,按钮将会变为多选框或者单选框。
-
- - - -

-
- - -
-
checkState
-
Type: integer, values 0, 1, or 2
-
This attribute may be used to create three state buttons, numbered 0, 1 and 2. When in state 0 or 1, pressing the button will switch to the opposite state. When in state 2, pressing the button will switch to state 0. This means that the button acts like a checkbox except that there is a third state which must be set manually by adjusting the check state. If you wish to have different behavior for how the states are adjusted, set the autoCheck attribute to false and adjust the state with a script. The type attribute must be set to checkbox for buttons with a check state. Constants for the possible values for this attribute are in the nsIDOMXULButtonElement interface.
-
-
- -
-
- checked
-
- Type: - - boolean -
-
- Indicates whether the element is checked or not.
-
- Use hasAttribute() to determine whether this attribute is set instead of getAttribute().
-
- For buttons, the type attribute must be set to checkbox or radio for this attribute to have any effect.<magic name="\"PAGENAME\"/"></magic>
-
-
- -
-
- command
-
- Type: - - element id -
-
- Set to the id of a command element that is being observed by the element.
-
- -

-
- -
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- - -

-
- -
-
- dir
-
- Type: - - one of the values below -
-
- The direction in which the child elements of the element are placed.
-
-
-
- normal
-
- For scales, the scale's values are ordered from left to right (for horizontal scales) or from top to bottom (for vertical scales)  For other elements, the elements are placed left to right or top to bottom in the order they appear in the XUL code
-
- reverse
-
- For scales, the scale's values are ordered from right to left (for horizontal scales) or from bottom to top (for vertical scales). For other elements, they are placed right to left or bottom to top. This is reverse of the order in which they appear in the XUL code.
-
- - -

 

-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
dlgtype
-
Type: one of the values below
-
The dialog type of the button, used only when the button is in a dialog box. You can use this feature to replace the standard dialog box buttons with custom buttons, yet the dialog event methods will still function. For example, if the dlgType is set to accept, the button will replace the dialog box's accept button, which is usually labeled OK. Using this attribute on a button that is not in a dialog box has no effect. The following values can be used as the dialog type:
-
-
-
accept
-
The OK button, which will accept the changes when pressed.
-
cancel
-
The cancel button which will cancel the operation.
-
help
-
A help button for displaying help about the dialog.
-
disclosure
-
A button to show more information. This might be a button or a disclosure triangle.
-
extra1
-
An optional additional button.
-
extra2
-
A second optional additional button.
-
-
-
-
- - -
-
group
-
Type: string group name
-
Buttons with type="radio" and the same value for their group attribute are put into the same group. Only one button from each group can be checked at a time. If the user selects one the buttons, the others in the group are unchecked.
-
-
- - -
-
icon
-
Mozilla 1.8
-
Type: string
-
This attribute should be used to set the usage for common buttons. Some platforms display these buttons with a small icon indicating their usage. This should be used in place of the image attribute. Possible values include: accept, cancel, help, open, save, find, clear, yes, no, apply, close, print, add, remove, refresh, go-forward, go-back, properties, select-font, select-color, network. If you are using a button that matches one of these common usages, use the icon attribute to indicate this. See the appearance of the different icons on some available platforms.
-
-
- -
-
- image
-
- Type: - - image URL -
-
- The URL of the image to appear on the element. If this attribute is empty or left out, no image appears. The position of the image is determined by the dir and orient attributes.
-
- -

-
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- - -
-
open
-
Type: boolean
-
For the menu type buttons, the open attribute is set to true when the menu is open. The open attribute is not present if the menu is closed.
-
-
-

布局(orient)

-
-
- 值类型:可以是下面值中的一种。
- 指定了子控件的布局(orient)为水平分布的(horizontally)或者是垂直分布的(vertically)。默认值依赖于控件本身。你也可以使用-moz-box-orient中的样式属性。 -
    -
  • horizontally: 子控件会被按照在xul源文件中出现的位置依次布置在一行中。
  • -
  • vertically: 子控件会被按照在xul源文件中出现的位置依次布置在一列中。
  • -
-
-
-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- - -
-
type
-
Type: one of the values below
-
The type of button. If this attribute is not present, a normal button is created. Leave the attribute out for a normal button.
-
-
-
checkbox
-
This type of button can be in two states. The user can click the button to switch between the states. This is not the same as a checkbox because it looks like a button.
-
menu
-
Set the type attribute to the value menu to create a button with a menu popup. Place a menupopup element inside the button in this case. The user may click anywhere on the button to open and close the menu.
-
menu-button
-
You can also use the value menu-button to create a button with a menu. Unlike the menu type, this type requires the user to press the arrow to open the menu, but a different command may be invoked when the main part of the button is pressed.
-
panel
-
Similar to the menu type, this opens a popup. Place a panel element inside the button. panel elements are popups that support any type of content.
-
radio
-
The button acts like a radio button. Only one button in the group can be on a once.
-
repeat
-
This button will fire its command event repeatedly while the mouse button is held down.
-
-
-
-

- -

Properties

- -

-
-
- accessKey
-
- Type: - - character -
-
- Gets and sets the value of the accesskey attribute.
-
- -

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

- -
-
autoCheck
-
Type: boolean
-
Gets and sets the value of the autoCheck attribute.
-
-
-
- checkState
-
- Type: integer, values 0, 1, or 2
-
- Gets and sets the value of the checkState attribute.
-
-
-
- checked
-
- Type: boolean
-
- Gets and sets the value of the checked attribute.
-
-
-
- command
-
- Type: - - element id -
-
- Gets and sets the value of the command attribute.
-
- -

-
-
- crop
-
- Type: - - string -
-
- Gets and sets the value of the crop attribute.
-
- -

-
-
- dir
-
- Type: string
-
- Gets and sets the value of the dir attribute.
-
-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

- -
-
dlgType
-
Type: string
-
Gets and sets the value of the dlgType attribute.
-
- -
-
group
-
Type: string group name
-
Gets and sets the value of the group attribute.
-
-
-
- image
-
- Type: - - image URL -
-
- Gets and sets the value of the image attribute.
-
- -

-
-
- label
-
- Type: - - string -
-
- Gets and sets the value of the label attribute.
-
- -

-
-
- open
-
- Type: boolean
-
- Gets and sets the value of the open attribute.
-
-
-
-
- orient
-
- Type: string
-
- Gets and sets the value of the orient attribute.
-
-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

-
-
- type
-
- Type: string
-
- Gets and sets the value of the type attribute.
-
-

- -

Methods

- -

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- - - -
-
Interfaces
-
nsIAccessibleProvider, nsIDOMXULButtonElement
-
- -
 
- -

diff --git a/files/zh-cn/mozilla/tech/xul/checkbox/index.html b/files/zh-cn/mozilla/tech/xul/checkbox/index.html deleted file mode 100644 index ea2eef19ba..0000000000 --- a/files/zh-cn/mozilla/tech/xul/checkbox/index.html +++ /dev/null @@ -1,329 +0,0 @@ ---- -title: checkbox -slug: Mozilla/Tech/XUL/checkbox -tags: - - 中文 -translation_of: Archive/Mozilla/XUL/checkbox ---- -
- « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
- -

An element that can be turned on and off. This is most commonly rendered as a box when the element is off and a box with a check when the element is on. The user can switch the state of the check box by selecting it with the mouse. A label, specified with the label attribute, may be added beside the check box.

- -

More information is available in the XUL tutorial.

- -
-
Attributes
-
accesskey, checked, command, crop, disabled, src, label, preference, tabindex
-
- -
-
Properties
-
accessKey, accessibleType, checked, command, crop, disabled, src, label, tabIndex
-
- -

Examples

- -
Image:XUL_ref_checkbox.png
- -
<checkbox label="Enable JavaScript" checked="true"/>
-<checkbox label="Enable Java" checked="false"/>
-
- -

Attributes

- -

- -

- - - - -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

-
- -
-
- checked
-
- Type: - - boolean -
-
- Indicates whether the element is checked or not.
-
- Use hasAttribute() to determine whether this attribute is set instead of getAttribute().
-
- For buttons, the type attribute must be set to checkbox or radio for this attribute to have any effect.<magic name="\"PAGENAME\"/"></magic>
-
-
- -
-
- command
-
- Type: - - element id -
-
- Set to the id of a command element that is being observed by the element.
-
- -

-
- -
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- - -

-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
src
-
Type: URI
-
Set this to an URI pointing to an image to appear in the checkbox. If this attribute is left out, no image appears. You can have both an image and a label.
-
- - -
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- - -
-
preference
-
Type: id
-
Connects the element to a corresponding preference. This attribute only has any effect when used inside a prefwindow. More information is available in the Preferences System article.
-
-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-

- -

Properties

- -

- -

-
-
- accessKey
-
- Type: - - character -
-
- Gets and sets the value of the accesskey attribute.
-
- -

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- checked
-
- Type: boolean
-
- Gets and sets the value of the checked attribute.
-
-
-
- command
-
- Type: - - element id -
-
- Gets and sets the value of the command attribute.
-
- -

-
-
- crop
-
- Type: - - string -
-
- Gets and sets the value of the crop attribute.
-
- -

-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

- -
-
src
-
Type: URL
-
Gets and sets the value of the src attribute.
-
-
-
- label
-
- Type: - - string -
-
- Gets and sets the value of the label attribute.
-
- -

-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

- -

Methods

- -

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- - - -
-
Interfaces
-
nsIAccessibleProvider, nsIDOMXULCheckboxElement
-
diff --git a/files/zh-cn/mozilla/tech/xul/command/index.html b/files/zh-cn/mozilla/tech/xul/command/index.html deleted file mode 100644 index 7a9a8916f9..0000000000 --- a/files/zh-cn/mozilla/tech/xul/command/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: command -slug: Mozilla/Tech/XUL/command -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/command ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
- command 元素响应不同来源的、对于同一操作的操作请求。比如,剪贴板的粘贴操作,可以来自 “编辑”菜单,可以来自鼠标右键的上下文菜单,也可以来自键盘快捷键。你可以通过 command 的 oncommand 属性调用代码。对于用户来说,从什么地方触发了这个操作并不重要。另外,关闭 command 将自动关闭菜单中的项目和对键盘快捷键的响应。
-

Commands are identified by their id. If you include the script chrome://global/content/globalOverlay.js in your window, you can use the function goDoCommand function to invoke the command. Using this function has the advantage that the command will be sent to the part of the UI which will respond to it. Typically, this will be the currently focused element.

-

Like a broadcaster, commands forward attributes to other elements.

-

More information is available in the XUL tutorial. See also: command attribute, commandset element

-
-
- Attributes
-
- disabled, label, oncommand
-
-

Examples

-

The following code will send a paste command (cmd_paste) to the currently focused element:

-
 // First include chrome://global/content/globalOverlay.js
- goDoCommand("cmd_paste");
-
-

Example with two buttons

-
<command id="cmd_openhelp" oncommand="alert('Help');"/>
-<button label="Help" command="cmd_openhelp"/>
-<button label="More Help" command="cmd_openhelp"/>
-
-

Attributes

-

- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- - -
-
oncommand
-
Type: script code
-
This event handler is called when the command is activated. This occurs when a user selects a menu item or presses a keyboard shortcut attached to the command.
-
- - -

-

Properties

-

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- - -

diff --git a/files/zh-cn/mozilla/tech/xul/deprecated_defunct_markup/index.html b/files/zh-cn/mozilla/tech/xul/deprecated_defunct_markup/index.html deleted file mode 100644 index 6ae3102b4f..0000000000 --- a/files/zh-cn/mozilla/tech/xul/deprecated_defunct_markup/index.html +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Deprecated/Defunct Markup -slug: Mozilla/Tech/XUL/Deprecated_Defunct_Markup -translation_of: Archive/Mozilla/XUL/Deprecated_and_defunct_markup ---- -

The following XUL tags and attribute should be considered deprecated, if not defunct.

-

The list below may include a few elements which are actually in use, but at a deeper level in the code. Even some of the information on the tags below may be out of date, but is provided here for historical reference and to help anyone who comes across them in old code or documentation.

-

Elements

- -

Attributes

- -

References

- diff --git a/files/zh-cn/mozilla/tech/xul/dialog/index.html b/files/zh-cn/mozilla/tech/xul/dialog/index.html deleted file mode 100644 index b4e3680bf3..0000000000 --- a/files/zh-cn/mozilla/tech/xul/dialog/index.html +++ /dev/null @@ -1,364 +0,0 @@ ---- -title: dialog -slug: Mozilla/Tech/XUL/dialog -translation_of: Archive/Mozilla/XUL/dialog ---- -
- « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

window 元素调用对话框时应使用此元素。buttons 属性可以用于设置哪些按钮应该出现在对话框中。这些按钮将被放置在用户平台指定的位置。

-

更多有用信息可以查看 XUL tutorialDialogs and prompts (代码片段)。

-
属性
buttonaccesskeyaccept, buttonaccesskeycancel, buttonaccesskeydisclosure, buttonaccesskeyextra1, buttonaccesskeyextra2, buttonaccesskeyhelp, buttonalign, buttondir, buttondisabledaccept, buttonlabelaccept, buttonlabelcancel, buttonlabeldisclosure, buttonlabelextra1, buttonlabelextra2, buttonlabelhelp, buttonorient, buttonpack, buttons, defaultButton, ondialogaccept, ondialogcancel, ondialogdisclosure, ondialogextra1, ondialogextra2, ondialoghelp, title
-
-
特性
buttons, defaultButton
-
-
方法
acceptDialog, cancelDialog, centerWindowOnScreen, getButton, moveToAlertPosition
-
-

示例

-
Image:XUL_ref_dialog.png
-
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
-<dialog id="donothing" title="Dialog example"
-   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-   buttons="accept,cancel"
-   buttonlabelcancel="Cancel"
-   buttonlabelaccept="Save"
-   ondialogaccept="return doOK();"
-   ondialogcancel="return doCancel();">
-
-    <dialogheader title="Options" description="My preferences"/>
-    <groupbox>
-      <caption label="Colour"/>
-      <radiogroup>
-        <radio label="Red"/>
-        <radio label="Green" selected="true"/>
-        <radio label="Blue"/>
-      </radiogroup>
-      <label value="Nickname"/>
-      <textbox />
-   </groupbox>
-</dialog>
-
-

属性

-

- -
-
- activetitlebarcolor
-
- Type: color string
-
- Specify background color of the window's titlebar when it is active (foreground). Moreover this hides separator between titlebar and window contents. This only affects Mac OS X.
-
- -

 

-
- -
-
- buttonaccesskeyaccept
-
- Type: string
-
- The access key to use for the "accept" button.
-
-

 

- -

 

-
- -
-
- buttonaccesskeycancel
-
- Type: string
-
- The access key to use for the "cancel" button.
-
-
- -
-
- buttonaccesskeydisclosure
-
- Type: string
-
- The access key to use for the "disclosure" button.
-
-
- -
-
- buttonaccesskeyextra1
-
- Type: string
-
- The access key to use for the first extra button.
-
-
- - -
-
buttonaccesskeyextra2
-
Type: string
-
The access key to use for the second extra button.
-
-
- -
-
- buttonaccesskeyhelp
-
- Type: string
-
- The access key to use for the "help" button.
-
-
- -
-
- buttonalign
-
- Type: string
-
- The value of the align attribute for the box containing the buttons.
-
-
- - -
-
buttondir
-
Type: string
-
The value of the dir attribute for the box containing the buttons.
-
-
- - -
-
buttondisabledaccept
-
Type: boolean
-
If true, the accept button is disabled.
-
-
- - -
-
buttonlabelaccept
-
Type: string
-
The label to appear on the "accept" button.
-
-
- - -
-
buttonlabelcancel
-
Type: string
-
The label to appear on the "cancel" button.
-
-
- - -
-
buttonlabeldisclosure
-
Type: string
-
The label to appear on the "disclosure" button.
-
-
- -
-
- buttonlabelextra1
-
- Type: string
-
- The label to appear on the first extra button.
-
- -

 

-
- -
-
- buttonlabelextra2
-
- Type: string
-
- The label to appear on the second extra button.
-
- -

 

-
- - -
-
buttonlabelhelp
-
Type: string
-
The label to appear on the "help" button.
-
-
- - -
-
buttonorient
-
Type: string
-
The value of the orient attribute for the box containing the buttons.
-
-
- - -
-
buttonpack
-
Type: string
-
The value of the pack attribute for the box containing the buttons.
-
-
- -
-
- buttons
-
- 类型: 列表,下面的值用逗号分隔
-
- 需要显示在对话框上的按钮的一个列表,使用逗号分隔。将按钮放置在合适的位置,将根据用户平台自动执行基本的事件处理。在列表中可以使用以下值: -
    -
  • accept:“确定”按钮,按下按钮时将接受更改。此按钮为默认按钮。
  • -
  • cancel:“取消”按钮,将取消操作。
  • -
  • help:“帮助”按钮,在对话框显示一个“帮助”按钮。
  • -
  • disclosure:“更多信息”按钮,显示一个“more info”按钮。该按钮可能是一个按钮或一个三角形。
  • -
  • extra1:一个可选的额外的按钮。你可以通过buttonlabelextra1 属性设置它的label。
  • -
  • extra2:第二个可选的额外的按钮。你可以通过 buttonlabelextra2 属性设置它的label。
  • -
-
-
- -

 

-
- - -
-
defaultButton
-
Type: string
-
Normally this attribute should not be set, but if it is, it specifies the default button in the dialog. Typically, this means that the button will be activated when the Enter key is pressed. This should be set to one of the same values as those for the buttons attribute.
-
-
- - -
-
inactivetitlebarcolor
-
Type: color string
-
Specify background color of the window's titlebar when it is inactive (background). Moreover this hides separator between titlebar and window contents. This affects only on Mac OS X.
-
-
- - -
-
ondialogaccept
-
Type: script code
-
The code in this attribute is called when the accept button is pressed, or when the acceptDialog method is called. If the handler returns true, the dialog will indeed go away, but if it returns false it will not.
-
-
- - -
-
ondialogcancel
-
Type: script code
-
The code in this attribute is called when the "cancel" button is pressed or when the cancelDialog method is called. If the routine returns true, the dialog will indeed go away, but if it returns false it will not.
-
-
- - -
-
ondialogdisclosure
-
Type: script code
-
The code in this attribute is called when the "disclosure" button is pressed.
-
-
- - -
-
ondialogextra1
-
Type: script code
-
The code in this attribute is called when the first extra button is pressed.
-
-
- - -
-
ondialogextra2
-
Type: script code
-
The code in this attribute is called when the second extra button is pressed.
-
-
- - -
-
ondialoghelp
-
Type: script code
-
The code in this attribute is called when the "help" button is pressed.
-
-
- - -
-
title
-
Type: string
-
The text to appear in the title bar of the window.
-
-

-

特性

-

-
buttons
类型: 列表,下面的值用逗号分隔
需要显示在对话框上的按钮的一个列表,使用逗号分隔。将按钮放置在合适的位置,将根据用户平台自动执行基本的事件处理。在列表中可以使用以下值:
  • accept:“确定”按钮,按下按钮时将接受更改。此按钮为默认按钮。
  • cancel:“取消”按钮,将取消操作。
  • help:“帮助”按钮,在对话框显示一个“帮助”按钮。
  • disclosure:“更多信息”按钮,显示一个“more info”按钮。该按钮可能是一个按钮或一个三角形。
  • extra1:一个可选的额外的按钮。你可以通过buttonlabelextra1 属性设置它的label。
  • extra2:第二个可选的额外的按钮。你可以通过 buttonlabelextra2 属性设置它的label。
-
-
- -
-
defaultButton
-
Type: string
-
Normally this attribute should not be set, but if it is, it specifies the default button in the dialog. Typically, this means that the button will be activated when the Enter key is pressed. This should be set to one of the same values as those for the buttons attribute.
-

方法

-

- - - - - -
-

Inherited Methods
-addEventListener(), appendChild(), blur, click, cloneNode(), compareDocumentPosition, dispatchEvent(), doCommand, focus, getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getBoundingClientRect(), getClientRects(), getElementsByAttribute, getElementsByAttributeNS, getElementsByClassName(), getElementsByTagName(), getElementsByTagNameNS(), getFeature(), getUserData, hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isDefaultNamespace(), isEqualNode, isSameNode, isSupported(), lookupNamespaceURI, lookupPrefix, normalize(), querySelector(), querySelectorAll(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS(), setUserData

- -
-
- acceptDialog()
-
- Return type: no return value
-
- Accepts the dialog and closes it, similar to pressing the OK button.
-
-
cancelDialog()
-
Return type: no return value
-
Cancels the dialog and closes it, similar to pressing the Cancel button.
-
-
centerWindowOnScreen()
-
Return type: no return value
-
Centers the dialog on the screen.
-
-
- getButton( type )
-
- 返回值类型: button元素
-
- 返回当前对话框中指定类型的button元素.
-
-
moveToAlertPosition()
-
Return type: no return value
-
Moves and resizes the dialog to a position and size suitable for an alert box.
-

- -
Elements
dialogheader
-
-

diff --git a/files/zh-cn/mozilla/tech/xul/events/index.html b/files/zh-cn/mozilla/tech/xul/events/index.html deleted file mode 100644 index 02cf21976d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/events/index.html +++ /dev/null @@ -1,497 +0,0 @@ ---- -title: Events -slug: Mozilla/Tech/XUL/Events -translation_of: Archive/Mozilla/XUL/Events ---- -
-

 

- -

« XUL Reference

- -

 

- -

下列表格描述了对大部分 XUL 元素有效的事件句柄(Event Handler)。您可以使用 addEventListener 添加事件的监听器(Listener),并使用 removeEventListener 以移除这些监听器。

- -

其中一些事件同样可以使用属性值绑定。当使用属性值绑定事件时,您要注意这样做始终只能绑定一个监听器——后一次绑定会覆盖掉前面一次的绑定。对应的属性名是事件名前加上“on”前缀。

- -

继承的文档树事件

- -

继承的文档树事件(Inherited DOM Events)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
事件描述
-

blur

-
-

与 focus 事件相对,当一个元素失去焦点时会触发 blur 事件。
- 属性:onblur

-
-

change

-
-

当文本框的值被修改且失去焦点后,会触发 change 事件。
- 属性: onchange

-
-

click

-
-

当鼠标键被按下并松开后会触发 click 事件。您可以通过事件对象的 button 属性判断按下的是哪个按键。用户双击时同样会触发这个事件,您可以通过 detail 属性检查有多少次点击发生,用它来检查双击或者三击。在 XUL 中,您应当使用 command 事件响应用户操作,而不应使用 click 事件。

- -

属性: onclick

-
-

dblclick

-
-

这个事件和 click 事件类似,但是仅当用户双击鼠标的时候触发。这是另一种检查 click 事件中 detail 属性的方法。
- 属性: ondblclick

-
-

DOMMouseScroll

-
-

当用户滑动鼠标滚轮时会触发这个事件。不论鼠标滚轮的滑动是否造成了页面内容的滚动。事件的 target 属性是滑动滚轮时在鼠标指针下的对象,这与 click 事件相似。

-
-

focus

-
-

当一个元素收到焦点的时候,会触发 focus 属性。一旦某个元素获得了焦点,那么键盘事件将会被发送到这个元素上。焦点可以通过鼠标点击、按 Tab 键、按 back Tab 键切换到其他的元素上。
- 属性: onfocus

-
-

keydown

-
-

当键盘按键被按下但是并未抬起时,会触发当前具有焦点的元素的 keydown 事件。
- 属性: onkeydown

-
-

keypress

-
-

当键盘按键被按下并松开后,会触发当前具有焦点的元素的 keypress 事件。当用户按下并松开一个键时,会依次触发 keydown 事件、 keypress 事件和 keyup 事件。在一个文本框里,用户可以按住一个键来发送多个对应的字符,这时会像用户重复按了对应键多次一样触发多组按键事件。
- 属性: onkeypress

-
-

keyup

-
-

当键盘按键被松开后,会触发当前具有焦点的元素的 keyup 事件。
- 属性: onkeyup

-
-

load

-
-

当一个窗口(window)被完整加载后,会触发他的 load 事件。这个事件被用在窗口元素上和图片(image)元素或其他支持图片属性的上。用在图片元素上时,当图片元素被加载时会触发这个事件。图片元素的 load 事件不会起泡(bubble up),换句话说,不会因此触发窗口的 load 事件。
- 属性: onload

-
-

mousedown

-
-

当鼠标点击了某个元素但尚未松开时,会触发 mousedown 事件。
- 属性: onmousedown

-
-

mousemove

-
-

当鼠标在一个元素上移动时,会反复地发送 mousemove 事件。
- 属性: onmousemove

-
-

mouseout

-
-

与 mouseover 事件相对,当用户将鼠标移出某个元素时,会触发这个元素的 mouseout 事件。
- 属性: onmouseout

-
-

mouseover

-
-

当鼠标首次移动到某个元素上时,会触发这个元素的 mouseover 事件。您可以使用此事件来提供给用户反馈。
- 属性: onmouseover

-
-

mouseup

-
-

当鼠标在某个元素上松开时,会触发 mouseup 事件。
- 属性: onmouseup

-
-

select

-
-

This event is sent to a listbox or tree when an item is selected.
- 属性: onselect

-
-

unload

-
-

This event is sent to a window when the window has closed. This is done after the close event. You should place this event handler on the window element.
- 属性:onunload

-
- -

Mutation 文档树事件

- - - - - - - - - - - - - - - - - - - - -
事件描述
-

DOMAttrModified

-
-

当一个元素的属性被修改时,会触发 DOMAttrModified 事件。您可以通过 attrName 属性查看哪个属性被修改了,并通过 prevValuenewValue 属性查看对应属性的旧值和新值。

-
-

DOMNodeInserted

-
-

当一个节点作为一个元素的子节点被添加时,会触发 DOMNodeInsterted 事件。如果您在 document 层捕获这个事件,您可以收到所有对文档修改的动作。

-
-

DOMNodeRemoved

-
-

当一个节点被移除时,会触发 DOMNodeRemoved 事件。如果您在 document 层捕获这个事件,您可以收到所有对文档修改的动作。

-
- -
-

请注意,向文档中添加任何 mutation 事件监听器会降低后续文档树操作的性能。而且在后续操作中移除这些监听器并不会使之好转。要了解详细信息,请参考  Mutation events ,并且参考 Mutation observers 考虑使用其他效率更好的方式。

-
- -

通用 XUL 事件

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
事件描述
-

broadcast

-
-

您应当将这个事件句柄置于观察者上。当对应元素(如广播者)的属性被改变时,会触发 boardcast 事件。
- 属性: onbroadcast

-
-

close

-
-

当用户按下关闭按钮以要求关闭窗口时,会触发 close 事件。如果您在一个窗口元素上放置该事件的句柄,您可以陷入(trap)窗口的关闭。如果您在监听器中调用 event.preventDefault() ,可以阻止窗口的关闭。注意, close 事件仅针对用户按了标题栏上的关闭按钮,而不针对诸如点击了菜单中的文件—退出的操作。您可以考虑使用窗口的 unload 事件来处理所有关闭窗口的事件。
- 属性: onclose

-
-

command

-
-

当一个元素被激活时,会触发 command 事件。对于不同的元素,这个事件触发的方式也不尽相同。例如,点击按钮可以触发这个事件,在按钮获得焦点时按回车键也可以触发这个事件,用鼠标选择菜单项时可以触发这个事件,用键盘快捷键选择某个菜单项时同样会触发这个事件。您应当考虑使用 command 事件,而非使用 click 事件,因为 command 事件可以在所有上面说的情况下被调用。
- 属性: oncommand

-
-

commandupdate

-
-

This event occurs when a command update occurs on a <commandset> element. You would use this to update the disabled status of its commands.
- 属性: oncommandupdate

-
-

contextmenu

-
-

当用户试图显示某个元素的菜单时,会触发 contextmenu 事件。因平台不同,这个事件的触发方式也有所不同,通常来说是通过右键单击来触发的。这个事件可以用来在用户点击时动态地设置菜单的内容。您还可以使用 popupshowing 事件。在事件句柄中返回 false 可以阻止菜单弹出。
- 属性: oncontextmenu

-
-

drag

-
-

当拖拽一个节点时,会每秒数次地触发被拖拽节点的 drag 事件。
- 属性: ondrag

-
-

dragdrop

-
-

当用户松开鼠标以释放一个被拖拽的对象时,会触发 dragdrop 事件。The element, if it accepts the drop, should respond in some manner such inserting the dragged object into itself.
- 属性: ondragdrop

-
-

dragend

-
-

当拖拽事件结束时,会触发被拖拽的节点的 dragend 事件。
- 属性: ondragend

-
-

dragenter

-
-

在拖拽过程中,当鼠标节点第一次进入某个对象的范围内时,会触发 dragenter 事件。这个事件与 mouseover 事件相似,不同点在于在拖拽的过程中触发。
- 属性: ondragenter

-
-

dragexit

-
-

在拖拽的过程中,当鼠标指针从一个元素上移出的时候,会触发 dragexit 事件。这个事件同样会在释放元素后触发。这个事件与 mouseout 事件相似,不同点在于在拖拽的过程中触发。
- 属性: ondragexit

-
-

draggesture

-
-

当用户开始拖拽一个元素时,会触发 draggesture 事件。一般来说,拖拽是由按住鼠标移动产生的。
- 属性: ondraggesture

-
-

dragover

-
-

类似于 mouseover 事件,当有东西被拖拽到某个元素之上时,会触发 dragover 事件。这个事件应当判断被拖拽的对象是否可以释放。
- 属性: ondragover

-
-

input

-
-

当用户在文本框输入的时候,会触发 input 事件。仅当显示的文本被修改时会触发这个事件,因此如果用户按了不会显示出来的按键时,这个事件是不会被触发的。
- 属性: oninput

-
-

overflow

-
-

仅当 CSS 的 overflow 属性被设置为 visible 以外的值时才会触发 overflow 。当没有足够的空间显示某个元素当内容时,会触发 overflow 事件。例如,一个最大尺寸为 100 像素的盒,但是可用的空间只有 80 像素,那么就会触发 overflow 事件。如果因为用户修改窗口大小等因素导致大小被改变了,因此有了足够的空间时,会触发相应的 underflow 事件。
- 属性: onoverflow

-
-

popuphidden

-
-

当一个弹出的元素被隐藏了时,会触发 popuphidden 事件。
- 属性: onpopuphidden

-
-

popuphiding

-
-

当一个弹出的元素将被隐藏时,会触发 popuphiding 事件。
- 属性: onpopuphiding

-
-

popupshowing

-
-

当一个弹出元素将被显示时,会触发 popupshowing 事件。这个事件经常被用来在用户需要显示弹出元素时动态地设置它的内容。在句柄中返回 false 可以阻止元素弹出。
- 属性: onpopupshowing

-
-

popupshown

-
-

当一个弹出元素被显示了时,会触发 popupshown 事件。这类似于窗口上的 load 事件。
- 属性: onpopupshown

-
-

syncfrompreference

-
-

因为选项的修改而导致元素改变时,会调用 syncfrompreference 事件。这个事件只会对 prefwindow 中的元素生效。这不是实际意义上的事件而仅仅是一个函数调用,所以这个事件必须使用属性形式的语法定义。函数可以返回不同于选项的特定的值。这个事件通常被用于为了让选项值更适合显式在用户界面中而调整选项值。
- 属性: onsyncfrompreference

-
-

synctopreference

-
-

当与对象连接的属性值被修改时,会调用 synctopreference 事件。这不是实际意义上的事件而仅仅是一个函数调用,所以这个事件必须使用属性形式的语法定义。函数可以返回不同于选项的特定的值,以设置属性的值,而非使用元素的 value 。
- 属性: onsynctopreference

-
-

underflow

-
-

当有了足够的空间完整地显示某个元素时,会触发这个元素的 underflow 事件。这个事件对所有 CSS 的 overflow 属性不为 visible 的盒或其他布局元素生效。这个事件说明滚动条已经没必要了。
- 属性: onunderflow

-
-

DOMMenuItemActive

-
-

当鼠标在菜单或菜单项上时或某个菜单项没高亮时,会触发 DOMMenuItemActive 事件。这个事件是起泡的(bubbles)。

-
-

DOMMenuItemInactive

-
-

当鼠标移出菜单或菜单项或某个菜单项不再被高亮时,会触发 DOMMenuItemInactive 事件。这个事件是起泡的。

-
- -

窗口事件

- -

下列事件被绑定在顶级文档树窗口上,可以使用 window.addEventListener 监听。

- - - - - - - - - - - - - - - - - - - - -
EventDescription
activate 当窗口变为活动窗口时触发。
deactivate 当窗口变为非活动窗口时触发。
sizemodechange -

当某个窗口被最小化,取消最小化,切换到全屏模式,或切换到窗口模式时触发。注意,这个事件可能被调用多次,或者因为修改窗口大小而被调用,(见 bug 715867 )。所以应当在事件中查看 window.windowState 检查窗口的状态。

-
- -

可访问性事件

- -

这些事件被用来通知可访问性系统。一般来说你不应该自行使用这些事件。

- - - - - - - - - - - - - - - - -
EventDescription
-

CheckboxStateChange

-
-

当一个 checkbox 被选中或取消选中时,会触发 CheckboxStateChange 事件。这个事件可能由于用户动作触发,也可能由于脚本改变了选框的值。相比之下, command 事件只会因为用户的动作而触发,这时 CheckboxStateChange 事件在 command 事件之前触发。 CheckboxStateChange 事件是不起泡的。

-
-

RadioStateChange

-
-

当一个 radio 被选中时,会触发 RadioStateChange 事件。这个事件可能时由于用户动作触发,也可能时因为脚本修改了对应的值。相比之下, command 事件只会因为用户的动作而触发,这时 RadioStateChange 事件在 command 事件之前触发。 RadioStateChange 事件是起泡的,因此你可以在 radiogroup 绑定事件句柄。

-
- -

-
- -

 

diff --git a/files/zh-cn/mozilla/tech/xul/image/index.html b/files/zh-cn/mozilla/tech/xul/image/index.html deleted file mode 100644 index f70f4a5f7d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/image/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: image -slug: Mozilla/Tech/XUL/image -translation_of: Archive/Mozilla/XUL/image ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

Summary

-

用于图片显示的元素,与HTML中的img相似.使用 src可以指定图片的URL.

-

More information is available in the XUL tutorial.

-
-
-

Note: Prior to Gecko 8.0, images did not shrink down with the same ratio in both directions when specifying maximum sizes using maxheight or maxwidth. The new behavior aligns more with the HTML <img> element and shrinks both the width and height down proportionally.

-
-
-
-
- Attributes
-
- onerror, onload, src, validate
-
-
-
- Properties
-
- accessibleType, src
-
-
-
- Style classes
-
- alert-icon, error-icon, message-icon, question-icon
-
-

Examples

-
- Image:Firefoxlogo2.png
-
<image src='Firefoxlogo.png' width='135' height='130'/>
-
-

Attributes

-

- - -
-
onerror
-
Type: script code
-
This event is sent to an image element when an error occurs loading the image.
-
-
- -

See

- - - -
- -
-
- src
-
- Type: URI
-
- The URI of the content to appear in the element.
-
- - -
- -
-
- validate
-
- Type: - - one of the values below -
-
- This attribute indicates whether to load the image from the cache or not. This would be useful if the images are stored remotely or you plan on swapping the image frequently. The following values are accepted, or leave out the attribute entirely for default handling:
-
- - -

-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

- -
-
src
-
Type: URL
-
Gets and sets the value of the src attribute.
-
-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

-

Style classes

-

-
- alert-icon
-
- Class that adds an alert icon. This typically looks like an exclamation mark. This and the other icon classes may be used by image elements or other elements which can have an image.
-
-
error-icon
-
Class that adds an error icon. This will typically be a red "X" icon.
-
-
message-icon
-
Class that adds a message box icon.
-
-
question-icon
-
Class that adds a question icon, which usually looks like a question mark.
-

- -

See also the image and icon attributes.

-

Interfaces

- -
-
diff --git a/files/zh-cn/mozilla/tech/xul/index.html b/files/zh-cn/mozilla/tech/xul/index.html deleted file mode 100644 index ac0e9697f5..0000000000 --- a/files/zh-cn/mozilla/tech/xul/index.html +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: XUL -slug: Mozilla/Tech/XUL -tags: - - XUL -translation_of: Archive/Mozilla/XUL ---- -
- 从这里开始
-   帮助你对XUL有一个比较直观的理解(该教程首发于 XULPlanet)
-
-

XUL 是一个Mozilla使用XML来描述用户界面的一种技术,使用XUL你可以快速的创建出跨平台,基于因特网的应用程序。基于XUL技术的应用程序可以很方便的使用好看的字体、图形以及方便的界面布局,而且也更容易部署和定制。如果程序员已经熟悉了Dynamic HTML (DHTML),那学习XUL将是更容易的事,也可以更快的开发基于XUL的应用程序.

-
- - - - - - - -
-

推荐的文章

-
-
- XUL模板手册
-
- XUL模板是用于提供来自查询或是类似于结果集的内容块的一种方法.一个比较好的例子像数据库查询集.对于每个查询结果集,生成相关的内容块.XUL模板允许使用不的规则来生成基于特定要求的不同内容块,也允许给返回结果集设置属性.
-
-
-
- XUL 教程
-
- 这份教程教你如何进入XUL (XML User Interface Language,Mozilla的平台无关界面描述语言)神奇世界.设计一个简单的"查找文件"的界面, 对XUL的各种特性进行了解和学习.
-
-
-
- XUL:用XUL做你意想不到的事
-
- Vlad Vukicevic 写完了这个大杂烩式的 FAQ, 列出了在 XUL 中可以做的事情 (hopefully with bug numbers), 不可以做的事情 (hopefully with explanations), 以及如何解决它们的办法. 欢迎各位添加自己的 XUL 体验到文章里.
-
-
-
- Mozilla's XML 用户接口语言 (表现层)
-
- Ben Goodger 在阿姆斯特丹(Amsterdam)的 XTech 2005 大会上给出了这份关于 XUL 的表现层.
-
-
-
- XUL应用程序教程
-
- 这个教程被设计用来教你学会如何创建一个基于 XUL 的简单程序, 通过循序渐进地开发一个 XUL 程序来演示要讨论的概念.
-
-


- 显示所有...

-
-

 

-

特色主题

- -

其他页面

- -

关联主题

-
-
- JavaScript, XBL, CSS, RDF显示所有...
-
-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/key/index.html b/files/zh-cn/mozilla/tech/xul/key/index.html deleted file mode 100644 index 13fabfbd2d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/key/index.html +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: key -slug: Mozilla/Tech/XUL/key -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/key ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

The key element defines a keyboard shortcut. Event handlers can be used to respond when the appropriate keys are pressed. A key element must be placed inside a keyset element.

-

When a key matching the attributes on the key element is pressed, the command will be fired on the key element. The key pressed must match the key attribute (or keycode attribute) as well as the modifiers attribute in order for the key element to be activated and fire a command event.

-

For example, consider the following key:

-
<key key="r" modifiers="shift"/>
-
-

This key will only match when the Shift key is pressed as well as the R key, and no other keys. For instance, if the Shift, Control and R keys are all pressed, the key will not match.

-

To indiciate that a modifier key may optionally be pressed, place the word 'any' after listing the optional modifier key. For example:

-
<key key="r" modifiers="shift any control"/>
-
-

In this example, the shift key may or may not be pressed, while the control key must be pressed. This allows keys to match more loosely for modifier keys that aren't relevant, yet still allows specific modifiers to be required.

-

If the modifiers attribute is not specified, then no modifiers may be pressed for the key to match.

-

If neither the key or keycode attribute are used, the key element will handle all key events. However, if one of the attributes is set to an empty string, the element doesn't handle any key events. For example:

-
<!-- This element handles all key events -->
-<key/>
-
-<!-- These elements don't handle any key events -->
-<key key="" modifiers="control"/>
-<key keycode="" modifiers="control"/>
-
-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- command, disabled, key, keycode, keytext, modifiers, oncommand, phase
-
-

Examples

-

(example needed)

-

Attributes

-

- -
-
- command
-
- Type: - - element id -
-
- Set to the id of a command element that is being observed by the element.
-
- -

-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
key
-
Type: character
-
The character that must be pressed. This should be set to a displayable character.
-
-
- - -
-
keycode
-
Type: string key code
-
For keys that do not have displayable characters, such as the Enter key or function keys, use this attribute instead of the key attribute. Valid keys are listed at Keyboard Shortcuts.
-
-
- - -
-
keytext
-
Type: string
-
A label for the keyboard shortcut. This text would appear next to a menuitem label if that menuitem is associated with the key element via its key attribute.
-
-
- - -
-
modifiers
-
Type: space-separated list of the values below
-
A list of modifier keys that should be pressed to invoke the keyboard shortcut. Multiple keys may be separated by spaces or commas. Keys will map to other keys on platforms that do not have them.
-
- - -
- - -
-
oncommand
-
Type: script code
-
This event handler is called when the command is activated. This occurs when a user selects a menu item or presses a keyboard shortcut attached to the command.
-
- - -
- - -
-
phase
-
Type: string
-
The event phase where the handler is invoked. This should be set to the value capturing to indicate during the event capturing phase or target to indicate at the target element or left out entirely for the bubbling phase.
-
-

-

Properties

-

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -

TBD

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/label/index.html b/files/zh-cn/mozilla/tech/xul/label/index.html deleted file mode 100644 index f6201f62c0..0000000000 --- a/files/zh-cn/mozilla/tech/xul/label/index.html +++ /dev/null @@ -1,298 +0,0 @@ ---- -title: label -slug: Mozilla/Tech/XUL/label -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/label ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

This element is used to provide a label for a control element. If the user clicks the label, it will move the focus to the associated control, specified with the control attribute.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- accesskey, control, crop, disabled, href, value
-
-
-
- Properties
-
- accessKey, accessibleType, control, crop, disabled, value
-
-
-
- Style classes
-
- header, indent, monospace, plain, small-margin, text-link
-
-

Examples

-
- Image:XUL_ref_label.png
-
<label value="Email address" control="email"/>
-<textbox id="email"/>
-
-

Attributes

-

- - - - -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

-
- -
-
- control
-
- Type: element id
-
- This attribute specifies the id of the element with which the label is associated. When the user clicks on the label, the associated element is given focus.
- 这个属性定义了元素的id,它与label相关联。当用户点击 label 的时候,相关联的元素将获得焦点。
-
- -

 

-
- -
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- - -

-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
href
-
类型: 文本
-
定义一个当元素被点击时将会打开的 URL 。需要引用类 text-link
-
- - - - -
- - -
-
value
-
Type: string
-
The text to be used for the label.
-
-

-

Properties

-

-
-
- accessKey
-
- Type: - - character -
-
- Gets and sets the value of the accesskey attribute.
-
- -

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- control
-
- Type: element id
-
- Gets and sets the value of the control attribute.
-
-
-
-
- crop
-
- Type: - - string -
-
- Gets and sets the value of the crop attribute.
-
- -

-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
- -

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

-

Style classes

-

The following classes may be used to style the element. These classes should be used instead of changing the style of the element directly since they will fit more naturally with the user's selected theme.

-

-
header
-
A class used for headings. Typically, this will cause the text to appear bold.
-
-
indent
-
This class causes the text to be indented on its left side.
-
-
monospace
-
This class causes the text to be displayed in a monospace font.
-
-
plain
-
This class causes the element to be displayed with no border or margin.
-
-
small-margin
-
This class causes the text to be displayed with a smaller margin.
-
-
text-link
-
Labels with this class may be focused and the click handler run or the address in the href attribute opened on a mouse click or Enter key press. Labels will appear like a link (blue and underlined).
-

- -
-
- Elements
-
- description
-
-
-
- Attributes
-
- label
-
-
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULLabelElement
-
-

User notes

-

Remember that the label element has a "value" attribute, unlike value in HTML whereas buttons, checkboxes use label="foo" as the attribute

-
<label label="A Caption"/> <-- wrong -->
-<label value="A Caption"/>
-
-<label value="Click the button"/>
-<button label="A Button"/>
-<checkbox label="A Decision" value="1"/>
-
-

 

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/list_of_commands/index.html b/files/zh-cn/mozilla/tech/xul/list_of_commands/index.html deleted file mode 100644 index 54ff23cabf..0000000000 --- a/files/zh-cn/mozilla/tech/xul/list_of_commands/index.html +++ /dev/null @@ -1,196 +0,0 @@ ---- -title: List of commands -slug: Mozilla/Tech/XUL/List_of_commands -translation_of: Archive/Mozilla/XUL/List_of_commands ---- -

The following lists commands which might be usable by <command> or command dispatchers/controllers.

-

List of Commands (grouped by type)

- - -

Editor commands (legal when the focus is anywhere where you can type text):

- -

Other commands

-

The following list other commands (prefixed by cmd_ or Browser:) which have not been categorized here yet (though they are in the alphabetical list below):

- -

 

-

List of commands (listed alphabetically)

- -

Thanks for help of joe.user0 in compiling: http://readlist.com/lists/mozilla.or...l/3/15261.html . Also obtained from http://www.mozilla.org/unix/customizing.html

-

diff --git a/files/zh-cn/mozilla/tech/xul/listbox/index.html b/files/zh-cn/mozilla/tech/xul/listbox/index.html deleted file mode 100644 index 04489bf06d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/listbox/index.html +++ /dev/null @@ -1,480 +0,0 @@ ---- -title: listbox -slug: Mozilla/Tech/XUL/listbox -translation_of: Archive/Mozilla/XUL/listbox ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

This element is used to create a list of items where one or more of the items may be selected. A listbox may contain multiple columns. There are numerous methods which allow the items in the listbox to be retrieved and modified.

-

You may specify the number of rows to display in the list using the rows attribute. Additional rows can be viewed using a scroll bar. A listbox is expected to contain listitem elements. All the rows in the listbox are the same height, which is the height of the tallest item in the list. If you wish to create a list with variable height rows, or with non-text content, you should instead use the richlistbox element.

-

See List Controls for more information.

-
-
- Attributes
-
- disabled, disableKeyNavigation, preference, rows, seltype, suppressonselect, tabindex, value
-
-
-
- Properties
-
- accessibleType, currentIndex, currentItem, disabled, disableKeyNavigation, itemCount, listBoxObject, selectedCount, selectedIndex, selectedItem, selectedItems, selType, suppressOnSelect, tabIndex, value
-
-
-
- Methods
-
- addItemToSelection, appendItem, clearSelection, ensureElementIsVisible, ensureIndexIsVisible, getIndexOfFirstVisibleRow, getIndexOfItem, getItemAtIndex, getNumberofVisibleRows, getRowCount, getSelectedItem, insertItemAt, invertSelection, moveByOffset, removeItemAt, removeItemFromSelection, scrollToIndex, selectAll, selectItem, selectItemRange, timedSelect, toggleItemSelection
-
-

Examples

-
- Image:XUL_ref_listbox.png
-
 <listbox id="theList">
-   <listitem label="Ruby"/>
-   <listitem label="Emerald"/>
-   <listitem label="Sapphire" selected="true"/>
-   <listitem label="Diamond"/>
- </listbox>
-
-
-

XulListBoxMultiColumn.PNG

-
<listbox id="theList" rows="10" width="400">
-  <listhead>
-     <listheader label="1ct Gem" width="240"/>
-     <listheader label="Price" width="150"/>
-  </listhead>
-  <listcols>
-    <listcol/>
-    <listcol flex="1"/>
-  </listcols>
-</listbox>
-
-var theList = document.getElementById('theList ');
- gems = [  {gem: "Ruby", Price: "$3,500 - $4,600"},
-           {gem: "Emerald", Price: "$700 - 4,250"},
-           {gem: "Blue Sapphire", Price: "$3,400 - $4,500"},
-           {gem: "Diamond", Price: "$5,600 - $16,000"}  ];
-for (var i = 0; i < gems.length; i++)
-    {
-        var row = document.createElement('listitem');
-        var cell = document.createElement('listcell');
-        cell.setAttribute('label', gems[i].gem);
-        row.appendChild(cell);
-
-        cell = document.createElement('listcell');
-        cell.setAttribute('label',  gems[i].Price );
-        row.appendChild(cell);
-
-        theList.appendChild(row);
-    }
-
-
 
-

Attributes

-

- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
disableKeyNavigation
-
Type: boolean
-
If this attribute is not used, the user can navigate to specific items within the element by pressing keys corresponding to letters in the item's label. This is done incrementally, so typing more letters with select more specific items. This feature may be disabled by setting this attribute to true.
-
-
- - -
-
preference
-
Type: id
-
Connects the element to a corresponding preference. This attribute only has any effect when used inside a prefwindow. More information is available in the Preferences System article.
-
-
- -
-
- rows
-
- Type: integer
-
- The number of rows to display in the element. If the element contains more than this number of rows, a scrollbar will appear which the user can use to scroll to the other rows. To get the actual number of rows in the element, use the getRowCount method.
-
-
- - -
-
seltype
-
Type: one of the values below
-
Used to indicate whether multiple selection is allowed.
-
-
-
single
-
Only one row may be selected at a time. (Default in listbox and richlistbox.)
-
multiple
-
Multiple rows may be selected at once. (Default in tree.)
-
-
-
-

For trees, you can also use the following values:

- -
-
cell
-
Individual cells can be selected
-
text
-
Rows are selected; however, the selection highlight appears only over the text of the primary column.
-
- -

For richlistbox, this is new in Firefox 3.5.

-
-
-
- - -
-
suppressonselect
-
Type: boolean
-
If this attribute is not specified, a select event is fired whenever an item is selected, either by the user or by calling one of the select methods. If set to true, the select event is never fired.
-
-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- -
-
- value
-
- Type: - - string -
-
- The string attribute allows you to associate a data value with an element. It is not used for any specific purpose, but you can access it with a script for your own use.
-
- -

-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

- -
-
currentIndex
-
Type: integer
-
Set to the index of the currently focused item in the list. If no item is focused, the value will be -1. (or, on some platforms, typeof(listboxcurrentIndex) will be undefined) In a single selection list, the current index will always be the same as the selected index. In a multiple selection list, the currently focused row may be modified by the user without changing the selection by pressing the Control key and pressing the cursor keys to navigate.
-
- -
-
currentItem
-
Type: listitem element
-
Returns the currently focused item in the list box, which is only useful in a multiple selection list box.
-
-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

-
-
disableKeyNavigation
-
Type: boolean
-
Gets or sets the value of the disableKeyNavigation attribute.
-
-
-
itemCount
-
Type: integer
-
Read only property holding the number of child items.
-
-
-
-
- listBoxObject
-
- Type: nsIListBoxObject
-
- The nsIListBoxObject behind the list box. This property is read-only. Most of the features of the list box are already available directly in the listbox, so you will rarely have need to use this box object directly.
-
- -
-
selectedCount
-
Type: integer
-
Returns the number of items that are currently selected.
-
-
-
- selectedIndex
-
- Type: - - integer -
-
- Returns the index of the currently selected item. You may select an item by assigning its index to this property. By assigning -1 to this property, all items will be deselected.
-
- -

-
-
- selectedItem
-
- Type: - - element -
-
- Holds the currently selected item. If no item is currently selected, this value will be null. You can select an item by setting this value. A select event will be sent to the element when it is changed either via this property, the selectedIndex property, or changed by the user.
-
- -

- -
-
selectedItems
-
Type: array of listitems
-
Returns an array of the selected items in the list.
-
-
-
- selType
-
- Type: string
-
- Gets and sets the value of the seltype attribute.
-
-

 

- -
-
suppressOnSelect
-
Type: boolean
-
Gets and sets the value of the suppressonselect attribute.
-
-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
- -

-

Methods

-

- - - - - -
-

Inherited Methods
-addEventListener(), appendChild(), blur, click, cloneNode(), compareDocumentPosition, dispatchEvent(), doCommand, focus, getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getBoundingClientRect(), getClientRects(), getElementsByAttribute, getElementsByAttributeNS, getElementsByClassName(), getElementsByTagName(), getElementsByTagNameNS(), getFeature(), getUserData, hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isDefaultNamespace(), isEqualNode, isSameNode, isSupported(), lookupNamespaceURI, lookupPrefix, normalize(), querySelector(), querySelectorAll(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS(), setUserData

- -
-
addItemToSelection( item )
-
Return type: no return value
-
Selects the given item, without deselecting any other items that are already selected.
-
-
- appendItem( label, value )
-
- Return type: element
-
- Creates a new item and adds it to the end of the existing list of items. You may optionally set a value. The function returns the newly created element.
-
-
clearSelection()
-
Return type: no return value
-
Deselects all of the items.  A select event is sent before the items are deselected.
-
-
ensureElementIsVisible( element )
-
Return type: no return value
-
If the specified element is not currently visible to the user, the displayed items are scrolled so that it is. If the item is already visible, no scrolling occurs.
-
-
ensureIndexIsVisible( index )
-
Return type: no return value
-
If the item at the specified index is not currently visible to the user the displayed items are scrolled so that it is. If the item is already visible, no scrolling occurs.
-
-
getIndexOfFirstVisibleRow()
-
Return type: integer
-
Returns the index of the first displayed row. Note that this is not the same as the first row -- if the displayed items have been scrolled down, this function will retrieve the index of the first row that the user can see.
-
-
getIndexOfItem( item )
-
Return type: integer
-
Returns the zero-based position of the specified item. Items are numbered starting at the first item displayed in the list.
-
-
getItemAtIndex( index )
-
Return type: element
-
Returns the element that is at the specified index.
-
-
getNumberOfVisibleRows()
-
Return type: integer
-
Returns the number of rows that are currently visible to the user.
-
-
- getRowCount()
-
- Return type: integer
-
- Returns the total number of rows in the element, regardless of how many rows are displayed.
-
-
getSelectedItem( index )
-
Return type: element
-
When multiple items are selected, you can retrieve each selected item using this method. The argument index specifies the index in the list of the selected items, not the row number of the item. The item index is zero-based, thus this example will return the first selected item: getSelectedItem(0).
-
-
- insertItemAt( index, label, value )
-
- Return type: element
-
- This method creates a new item and inserts it at the specified position. You may optionally set a value. The new item element is returned.
-
-
invertSelection()
-
Return type: no return value
-
Reverses the selected state of all items. Selected items become deselected, and deselected items become selected.
-
-
moveByOffset( offset , isSelecting, isSelectingRange)
-
Return type: no return value
-
If offset is positive, adjusts the focused item forward by that many items. If offset is negative, adjusts the focused item backward by that many items. If isSelecting is true, then the selection is also adjusted. If isSelectingRange is also true, then the new item is selected in addition to any currently selected items. If isSelectingRange is false, any existing selection is cleared. Items that are hidden are skipped.
-
-
- removeItemAt( index )
-
- Return type: element
-
- Removes the child item in the element at the specified index. The method returns the removed item.
-
-
removeItemFromSelection( item )
-
Return type: no return value
-
Deselects the specified item without deselecting other items.
-
-
scrollToIndex( index )
-
Return type: no return value
-
Scrolls the element to the specified index. This is different than ensureIndexIsVisible because the view is always scrolled.
-
-
- selectAll()
-
- Return type: no return value
-
- Selects all of the items. A select event is sent after the selection is made.
-
-
- selectItem( item )
-
- Return type: no return value
-
- Deselects all of the currently selected items and selects the given item. A select event is sent after the selection is made.
-
-
- selectItemRange( startItem, endItem )
-
- Return type: no return value
-
- Selects the items between the two items given as arguments, including the start and end items. All other items are deselected. This method does nothing for single-selection list boxes. A select event is sent after the selection is made.
-
-
- timedSelect( item, timeout )
-
- Return type: no return value
-
- Selects the item specified by the argument item after the number of milliseconds given by the timeout argument. All other items are deselected.
-
-
- toggleItemSelection( item )
-
- Return type: no return value
-
- If the specified item is selected, it is deselected. If it is not selected, it is selected. Other items in the list box that are selected are not affected, and retain their selected state.
-

- -
-
- Elements
-
- listcell, listcol, listcols, listhead, listheader, listitem
-
-
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULMultiSelectControlElement
-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/listheader/index.html b/files/zh-cn/mozilla/tech/xul/listheader/index.html deleted file mode 100644 index d71bcb6e83..0000000000 --- a/files/zh-cn/mozilla/tech/xul/listheader/index.html +++ /dev/null @@ -1,180 +0,0 @@ ---- -title: listheader -slug: Mozilla/Tech/XUL/listheader -translation_of: Archive/Mozilla/XUL/listheader ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

A header for a single column in a listbox.

-
-
- Attributes
-
- disabled
-
-
-
- Properties
-
- acesssibleType
-
-

Examples

-
- Image:XUL_ref_listheader.png
-
<listbox>
-  <listhead>
-    <listheader label="Name"/>
-    <listheader label="Occupation"/>
-  </listhead>
-  <listitem>
-    <listcell label="George"/>
-    <listcell label="House Painter"/>
-  </listitem>
-  <listitem>
-    <listcell label="Mary Ellen"/>
-    <listcell label="Candle Maker"/>
-  </listitem>
-  <listitem>
-    <listcell label="Roger"/>
-    <listcell label="Swashbuckler"/>
-  </listitem>
-</listbox>
-
-

Attributes

-

- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- - - - - -

Inherited from XUL element
-align, -allowevents, -allownegativeassertions, -class, -coalesceduplicatearcs, -collapsed, -container, -containment, -context, -contextmenu, -datasources, -dir, -empty, -equalsize, -flags, -flex, -height, -hidden, -id, -insertafter, -insertbefore, -left, -maxheight, -maxwidth, -menu, -minheight, -minwidth, -mousethrough, -observes, -ordinal, -orient, -pack, -persist, -popup, -position, -preference-editable, -querytype, -ref, -removeelement, -sortDirection, -sortResource, -sortResource2, -statustext, -style, -template, -tooltip, -tooltiptext, -top, -uri, -wait-cursor, -width

-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -
-
- Elements
-
- listbox, listcell, listcol, listcols, listhead, listitem
-
diff --git a/files/zh-cn/mozilla/tech/xul/menu/index.html b/files/zh-cn/mozilla/tech/xul/menu/index.html deleted file mode 100644 index b204dcf14b..0000000000 --- a/files/zh-cn/mozilla/tech/xul/menu/index.html +++ /dev/null @@ -1,370 +0,0 @@ ---- -title: menu -slug: Mozilla/Tech/XUL/menu -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/menu ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

An element, much like a button, that is placed on a menubar. When the user clicks the menu element, the child menupopup of the menu will be displayed. This element is also used to create submenus.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- acceltext, accesskey, allowevents, command, crop, disabled, image, label, menuactive, open, sizetopopup, tabindex, value
-
-
-
- Properties
-
- accessibleType, accessKey, command, control, crop, disabled, image, itemCount, label, labelElement, menupopup, open, parentContainer, selected, tabIndex, value
-
-
-
- Methods
-
- appendItem, getIndexOfItem, getItemAtIndex, insertItemAt, removeItemAt
-
-

Example

-
  <menubar id="sample-menubar">
-    <menu id="file-menu" label="File">
-      <menupopup id="file-popup">
-        <menuitem label="New"/>
-        <menuitem label="Open"/>
-        <menuitem label="Save"/>
-        <menuseparator/>
-        <menuitem label="Exit"/>
-      </menupopup>
-    </menu>
-    <menu id="edit-menu" label="Edit">
-      <menupopup id="edit-popup">
-        <menuitem label="Undo"/>
-        <menuitem label="Redo"/>
-      </menupopup>
-    </menu>
-  </menubar>
-
-

Attributes

-

- -
-
- acceltext
-
- Type: - - string -
-
- Text that appears beside beside the menu label to indicate the shortcut key (accelerator key) to use to invoke the command. If this value is set, it overrides an assigned key set in the key attribute. This attribute does not apply to menus directly on the menubar.
-
- -

-
- - - - -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

-
- - -
-
allowevents
-
Type: - boolean
-
- 类型:boolean
-
If true, events are passed to children of the element. Otherwise, events are passed to the element only.
- 如果为真,事件向子元素传递。否则,事件只传递到当前元素。
-
- - - -

-
- -
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- - -

-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- - -
-
menuactive
-
Type: boolean
-
This attribute is set on an item in a menu when it is being hovered over. Typcially, the theme will use this to highlight the item. A DOMMenuItemActive event will be sent to the item when the item is hovered over, and a DOMMenuItemInactive event will be sent to the item when the selection moves away.
-
-
- - -
-
open
-
Type: boolean
-
For the menu type buttons, the open attribute is set to true when the menu is open. The open attribute is not present if the menu is closed.
-
-
- - -
-
sizetopopup
-
Type: one of the values below
-
Indicates how the menu width and the menupopup width are determined. If the sizetopopup attribute is left out or set to none, the menu will be its preferred width and the popup may extend outside of this width, unaffected by the maximum width of the menu itself. Otherwise, the menu will size itself to at least the size of the popup. If the menu has a maximum width, the popup will also be this width.
-
-
-
none
-
The width of the popup will not be constrained to the size of the menu.
-
pref
-
The preferred width of the menu label or button will be the size needed for the popup contents. This is the default value for menulists.
-
always
-
Both the preferred and minimum width of the menu label or button will be the same as that necessary for the menupopup.
-
-
-
-
- -
-
- value
-
- Type: - - string -
-
- The string attribute allows you to associate a data value with an element. It is not used for any specific purpose, but you can access it with a script for your own use.
-
- -

-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- control
-
- Type: - - menu element -
-
- Returns the enclosing menu that the item is inside, if any, or null if there is no enclosing menu.
-
- -

-
-
itemCount
-
Type: integer
-
Read only property holding the number of child items.
-
-
- -
-
menupopup
-
Type: menupopup element
-
A reference to the menupopup used by the menu or menulist. This property is read-only.
-
-
-
- open
-
- Type: boolean
-
- This property will be set to true when the menu is open. The menu may be opened by setting the open property to true and closed by setting it to false.
-
-
-
- parentContainer
-
- Type: - - menu element -
-
- Read only property that returns the containing menu element, or null if there isn't a containing menu.
-
- -

-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
- -

-

Methods

-

- - - - - -
-

Inherited Methods
-addEventListener(), appendChild(), blur, click, cloneNode(), compareDocumentPosition, dispatchEvent(), doCommand, focus, getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getBoundingClientRect(), getClientRects(), getElementsByAttribute, getElementsByAttributeNS, getElementsByClassName(), getElementsByTagName(), getElementsByTagNameNS(), getFeature(), getUserData, hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isDefaultNamespace(), isEqualNode, isSameNode, isSupported(), lookupNamespaceURI, lookupPrefix, normalize(), querySelector(), querySelectorAll(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS(), setUserData

- -
-
- appendItem( label, value )
-
- Return type: element
-
- Creates a new item and adds it to the end of the existing list of items. You may optionally set a value. The function returns the newly created element.
-
-
getIndexOfItem( item )
-
Return type: integer
-
Returns the zero-based position of the specified item. Items are numbered starting at the first item displayed in the list.
-
-
getItemAtIndex( index )
-
Return type: element
-
Returns the element that is at the specified index.
-
-
- insertItemAt( index, label, value )
-
- Return type: element
-
- This method creates a new item and inserts it at the specified position. You may optionally set a value. The new item element is returned.
-
-
- removeItemAt( index )
-
- Return type: element
-
- Removes the child item in the element at the specified index. The method returns the removed item.
-

- -
-
- Elements
-
- menubar, menuitem, menulist, menupopup, menuseparator
-
-
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULContainerElement, nsIDOMXULContainerItemElement, nsIDOMXULSelectControlItemElement
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/menubar/index.html b/files/zh-cn/mozilla/tech/xul/menubar/index.html deleted file mode 100644 index d7946debf9..0000000000 --- a/files/zh-cn/mozilla/tech/xul/menubar/index.html +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: menubar -slug: Mozilla/Tech/XUL/menubar -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/menubar ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

A container that usually contains menu elements. On the Macintosh, the menubar is displayed along the top of the screen, and all non-menu related elements inside the menubar will be ignored.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- grippyhidden, statusbar
-
-
-
- Properties
-
- accessibleType, statusbar
-
-

Examples

-
- Image:XUL_ref_menu.png
-
<menubar id="sample-menubar">
-  <menu id="action-menu" label="Action">
-    <menupopup id="action-popup">
-      <menuitem label="New"/>
-      <menuitem label="Save" disabled="true"/>
-      <menuitem label="Close"/>
-      <menuseparator/>
-      <menuitem label="Quit"/>
-    </menupopup>
-  </menu>
-  <menu id="edit-menu" label="Edit">
-    <menupopup id="edit-popup">
-      <menuitem label="Undo"/>
-      <menuitem label="Redo"/>
-    </menupopup>
-  </menu>
-</menubar>
-
-

Attributes

-

- - -
-
grippyhidden
-
SeaMonkey only
-
Type: boolean
-
When set to true, the grippy will be hidden. When set to false, the default, the grippy will be shown.
-
-
- - -
-
statusbar
-
Type: id
-
If you set this attribute to the id of a statusbar element, the label on the statusbar will update to the statustext of the items on the menu as the user moves the mouse over them.
-
-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

- -
-
statusbar
-
Type: id of statusbar element
-
Gets and sets the value of the statusbar attribute.
-
-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -
-
- Elements
-
- menu, menuitem, menulist, menupopup, menuseparator
-
-
-
- Interfaces
-
- nsIAccessibleProvider
-
-

 

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/menuitem/index.html b/files/zh-cn/mozilla/tech/xul/menuitem/index.html deleted file mode 100644 index a231f6a348..0000000000 --- a/files/zh-cn/mozilla/tech/xul/menuitem/index.html +++ /dev/null @@ -1,575 +0,0 @@ ---- -title: menuitem -slug: Mozilla/Tech/XUL/menuitem -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/menuitem ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

A single choice in a menupopup element. It acts much like a button but it is rendered on a menu.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- acceltext, accesskey, allowevents, autocheck, checked, command, crop, description, disabled, image, key, label, name, selected, tabindex, type, validate, value
-
-
-
- Properties
-
- accessibleType, accessKey, command, control, crop, disabled, image, label, labelElement, parentContainer, selected, tabIndex, value
-
-
-
- Style classes
-
- menuitem-iconic, menuitem-non-iconic
-
-

Example

-
<menu id="edit-menu" label="Edit">
-  <menupopup id="edit-popup">
-     <menuitem label="Undo"/>
-     <menuitem label="Redo"/>
-  </menupopup>
-</menu>
-
-

Attributes

-

- -
-
- acceltext
-
- Type: - - string -
-
- Text that appears beside beside the menu label to indicate the shortcut key (accelerator key) to use to invoke the command. If this value is set, it overrides an assigned key set in the key attribute. This attribute does not apply to menus directly on the menubar.
-
- -

-
- - - - -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

-
- - -
-
allowevents
-
Type: - boolean
-
- 类型:boolean
-
If true, events are passed to children of the element. Otherwise, events are passed to the element only.
- 如果为真,事件向子元素传递。否则,事件只传递到当前元素。
-
- - - -

-
- - -
-
autocheck
-
类型: - boolean -
-
如果此属性为 true,或空白, 每次点击按钮时,此按钮的状态检查都会被执行一次。如果此属性为false, 检查会手动的被拒绝。当autocheck值为true的时候,按钮将会变为多选框或者单选框。
-
- - - -

-
- -
-
- checked
-
- Type: - - boolean -
-
- Indicates whether the element is checked or not.
-
- Use hasAttribute() to determine whether this attribute is set instead of getAttribute().
-
- For buttons, the type attribute must be set to checkbox or radio for this attribute to have any effect.<magic name="\"PAGENAME\"/"></magic>
-
-

-
- Note: if the checked attribute is set to true, and you persist its value via the persist attribute, Mozilla will fail to persist its value when the menuitem is unchecked because of bug 15232. A workaround is to set the autocheck attribute to false, then programmatically set the checked attribute when the user selects the item, and set it to false instead of removing the attribute (i.e. do menuitem.setAttribute("checked", "false") instead of menuitem.removeAttribute("checked")) when the user unchecks the menuitem, as a value of false will both correctly hide the checkmark and persist its hidden state.
-

- -
-
- command
-
- Type: - - element id -
-
- Set to the id of a command element that is being observed by the element.
-
- -

-
- -
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- - -

-
- -
-
- description
-
- Type: - - string -
-
- Descriptive text to appear in addition to the dialog title.
-
- -

-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- -
-
- image
-
- Type: - - image URL -
-
- The URL of the image to appear on the element. If this attribute is empty or left out, no image appears. The position of the image is determined by the dir and orient attributes.
-
- -

-
- -
-
- key
-
- Type: - - element id -
-
- Set to the id of a key element whose key shortcut is displayed in the menuitem.
-
- -

-
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- -
-
- name
-
- Type: - - string name -
-
- Radio menuitems with the same name as put into a group. Only one menuitem in each radio group can be checked at a time.
-
- -

-
- -
-
- selected
-
- Type: - - boolean -
-
- Indicates whether the element is selected or not. This value is read-only. To change the selection, set either the selectedIndex or selectedItem property of the containing element.
-
- -

-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- -
-
- type
-
- Type: - - one of the values below -
-
- Can be used to create checkable menuitems or for radio button menuitems.
-
- -

More information on adding checkmarks to menus in the XUL tutorial

- -

-
- -
-
- validate
-
- Type: - - one of the values below -
-
- This attribute indicates whether to load the image from the cache or not. This would be useful if the images are stored remotely or you plan on swapping the image frequently. The following values are accepted, or leave out the attribute entirely for default handling:
-
- - -

-
- -
-
- value
-
- Type: - - string -
-
- The string attribute allows you to associate a data value with an element. It is not used for any specific purpose, but you can access it with a script for your own use.
-
- -

-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- accessKey
-
- Type: - - character -
-
- Gets and sets the value of the accesskey attribute.
-
- -

-
-
- command
-
- Type: - - element id -
-
- Gets and sets the value of the command attribute.
-
- -

-
-
- control
-
- Type: - - menu element -
-
- Returns the enclosing menu that the item is inside, if any, or null if there is no enclosing menu.
-
- -

-
-
- crop
-
- Type: - - string -
-
- Gets and sets the value of the crop attribute.
-
- -

-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

-
-
- image
-
- Type: - - image URL -
-
- Gets and sets the value of the image attribute.
-
- -

-
-
- label
-
- Type: - - string -
-
- Gets and sets the value of the label attribute.
-
- -

-
-
- labelElement
-
- Type: - - label element -
-
- The label element associated with the control. This is set when a label has a control attribute pointing to this element. This property will be null when no label is associated with the control.
-
- -

-
-
- parentContainer
-
- Type: - - menu element -
-
- Read only property that returns the containing menu element, or null if there isn't a containing menu.
-
- -

-
-
- selected<magic name="\"PAGENAME\"/"></magic>
-
- Type: - - boolean -
-
- This property's value is true if this element is selected, or false if it is not. This property is read only.
-
-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
- -

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

-

Style classes

-

-
- menuitem-iconic
-
- Use this class to have an image appear on the menuitem. Specify the image using the image attribute.
-
- -

-
- menuitem-non-iconic
-
- Normally, menuitems have a margin to the left for an image or checkmark. This class may be used to remove this margin so that the menuitem appears on the left edge of the menupopup.
-
- -

- -
-
- Elements
-
- menu, menubar, menulist, menupopup, menuseparator
-
-
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULContainerItemElement, nsIDOMXULSelectControlItemElement
-
-

 

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/menulist/index.html b/files/zh-cn/mozilla/tech/xul/menulist/index.html deleted file mode 100644 index 7273d413e7..0000000000 --- a/files/zh-cn/mozilla/tech/xul/menulist/index.html +++ /dev/null @@ -1,509 +0,0 @@ ---- -title: menulist -slug: Mozilla/Tech/XUL/menulist -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/menulist ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

An element that can be used for drop-down choice lists. The user may select one of the elements displayed in the menulist. The currently selected choice is displayed on the menulist element. To create the drop-down, put a menupopup inside the menulist containing the choices as menuitem elements. The command event may be used to execute code when the menulist selection changes.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- accesskey, crop, disableautoselect, disabled, editable, focused, image, label, oncommand, open, preference, readonly, sizetopopup, tabindex, value
-
-
-
- Properties
-
- accessibleType, crop, description, disableautoselect, disabled, editable, editor, image, inputField, itemCount, label, menuBoxObject, menupopup, open, selectedIndex, selectedItem, tabIndex, value
-
-
-
- Methods
-
- appendItem, contains, getIndexOfItem, getItemAtIndex, insertItemAt, removeAllItems, removeItemAt, select
-
-

Examples

-
  <menulist>
-    <menupopup>
-      <menuitem label="option 1" value="1"/>
-      <menuitem label="option 2" value="2"/>
-      <menuitem label="option 3" value="3"/>
-      <menuitem label="option 4" value="4"/>
-    </menupopup>
-  </menulist>
-
-

Attributes

-

- - - - -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

-
- -
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- - -

-
- - -
-
disableautoselect
-
Type: boolean
-
If this attribute is true or omitted, the selected item on the menu will update to match what the user entered in the textbox. If the text does not match any of the items in the list, the menu selection is cleared. If this attribute is false, the selection is never updated to match the text box. This attribute applies only to editable menulists.
-
-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
editable
-
Type: boolean
-
Indicates that the value of the menulist can be modified by typing directly into the value field. This is rendered as a textbox with a drop-down arrow beside it. The user may enter text into the textbox or select one of the choices by clicking from the drop-down.
-
-
- - -
-
focused
-
Type: boolean
-
This attribute is true if the element is focused.
-
-
- -
-
- image
-
- Type: - - image URL -
-
- The URL of the image to appear on the element. If this attribute is empty or left out, no image appears. The position of the image is determined by the dir and orient attributes.
-
- -

-
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- - -
-
oncommand
-
Type: script code
-
This event handler is called when the command is activated. This occurs when a user selects a menu item or presses a keyboard shortcut attached to the command.
-
- - -
- - -
-
open
-
Type: boolean
-
For the menu type buttons, the open attribute is set to true when the menu is open. The open attribute is not present if the menu is closed.
-
-
- - -
-
preference
-
Type: id
-
Connects the element to a corresponding preference. This attribute only has any effect when used inside a prefwindow. More information is available in the Preferences System article.
-
-
- - -
-
readonly
-
Type: boolean
-
If set to true, then the user cannot change the value of the element. However, the value may still be modified by a script.
-
-
- - -
-
sizetopopup
-
Type: one of the values below
-
Indicates how the menu width and the menupopup width are determined. If the sizetopopup attribute is left out or set to none, the menu will be its preferred width and the popup may extend outside of this width, unaffected by the maximum width of the menu itself. Otherwise, the menu will size itself to at least the size of the popup. If the menu has a maximum width, the popup will also be this width.
-
-
-
none
-
The width of the popup will not be constrained to the size of the menu.
-
pref
-
The preferred width of the menu label or button will be the size needed for the popup contents. This is the default value for menulists.
-
always
-
Both the preferred and minimum width of the menu label or button will be the same as that necessary for the menupopup.
-
-
-
-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- -
-
- value
-
- Type: - - string -
-
- The string attribute allows you to associate a data value with an element. It is not used for any specific purpose, but you can access it with a script for your own use.
-
- -

-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- crop
-
- Type: - - string -
-
- Gets and sets the value of the crop attribute.
-
- -

- -
-
description
-
Type: string
-
Set to the description of the currently selected menuitem.
-
- -
-
disableautoselect
-
Type: boolean
-
Gets and sets the value of the disableautoselect attribute.
-
-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

-
-
- editable
-
- Type: boolean
-
- Returns true if the element is editable. Autocomplete fields are editable so this property always returns true for those.
-
-

 

- -
-
editor
-
Type: nsIEditor
-
A reference to the nsIEditor for editable text. This property is read only.
-
- -
-
image
-
Type: image URL
-
The image associated with the currently selected item.
-
- -
-
inputField
-
Type: textbox element
-
A reference to the textbox element used for editable menu lists. This property is read only and applies to editable menulists only.
-
- -
-
-
itemCount
-
Type: integer
-
Read only property holding the number of child items.
-
-
-
-
- label
-
- Type: - - string -
-
- Gets and sets the value of the label attribute.
-
- -

- -
-
menuBoxObject
-
Type: nsIMenuBoxObject
-
A reference to the nsIMenuBoxObject which implements the menu.
-
- -
-
menupopup
-
Type: menupopup element
-
A reference to the menupopup used by the menu or menulist. This property is read-only.
-
-
-
- open
-
- Type: boolean
-
- Gets and sets the value of the open attribute.
-
-
-
-
- selectedIndex
-
- Type: - - integer -
-
- Returns the index of the currently selected item. You may select an item by assigning its index to this property. By assigning -1 to this property, all items will be deselected.
-
- -

-
-
- selectedItem
-
- Type: - - element -
-
- Holds the currently selected item. If no item is currently selected, this value will be null. You can select an item by setting this value. A select event will be sent to the element when it is changed either via this property, the selectedIndex property, or changed by the user.
-
- -

-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
- -

-

Methods

-

- - - - - -
-

Inherited Methods
-addEventListener(), appendChild(), blur, click, cloneNode(), compareDocumentPosition, dispatchEvent(), doCommand, focus, getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getBoundingClientRect(), getClientRects(), getElementsByAttribute, getElementsByAttributeNS, getElementsByClassName(), getElementsByTagName(), getElementsByTagNameNS(), getFeature(), getUserData, hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isDefaultNamespace(), isEqualNode, isSameNode, isSupported(), lookupNamespaceURI, lookupPrefix, normalize(), querySelector(), querySelectorAll(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS(), setUserData

- -
-
appendItem( label, value, description )
-
Return type: element
-
Creates a new menuitem element and adds it to the end of the menulist. You may optionally set a value and description. The function returns the new item.
-
-
contains( item )
-
Return type: boolean
-
Returns true if the menulist contains the specified menuitem as one of its items.
-
-
getIndexOfItem( item )
-
Return type: integer
-
Returns the zero-based position of the specified item. Items are numbered starting at the first item displayed in the list.
-
-
getItemAtIndex( index )
-
Return type: element
-
Returns the element that is at the specified index.
-
-
- insertItemAt( index, label, value )
-
- Return type: element
-
- This method creates a new item and inserts it at the specified position. You may optionally set a value. The new item element is returned.
-
-
removeAllItems()
-
Return type: no return value
-
Removes all of the items in the menu.
-
-
- removeItemAt( index )
-
- Return type: element
-
- Removes the child item in the element at the specified index. The method returns the removed item.
-
-
select()
-
Return type: no return value
-
Select all the text in the menulist's textbox. This method applies to editable menulists only.
-

- -
-
- Elements
-
- menu, menubar, menuitem, menupopup, menuseparator
-
-
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULMenuListElement
-
-

 

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/menupopup/index.html b/files/zh-cn/mozilla/tech/xul/menupopup/index.html deleted file mode 100644 index 23b103ebb9..0000000000 --- a/files/zh-cn/mozilla/tech/xul/menupopup/index.html +++ /dev/null @@ -1,324 +0,0 @@ ---- -title: menupopup -slug: Mozilla/Tech/XUL/menupopup -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/menupopup ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

A container used to display the contents of a popup menu. When a menupopup is open, it floats above the window and may extend outside the window border. There are several ways in which a menupopup may be used:

-
    -
  1. It may be placed inside a menu, menulist, toolbarbutton, or a button with the type attribute set to "menu" to create a popup that will open when the menu or button is pressed.
  2. -
  3. It may be attached to any element using the popup attribute. When the element is clicked with the left mouse button, the menupopup will be displayed.
  4. -
  5. It may be attached to any element using the context attribute. When a context menu is opened, the menupopup will be displayed. A context menu may be opened by right-clicking the element, or by pressing the menu key on the keyboard.
  6. -
-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- ignorekeys, left, onpopuphidden, onpopuphiding, onpopupshowing, onpopupshown, position, top
-
-
-
- Properties
-
- accessibleType, popupBoxObject, popup, state
-
-
-
- Methods
-
- hidePopup, moveTo, openPopup, openPopupAtScreen, showPopup, sizeTo
-
-

Examples

-

The following example shows how a menupopup may be attached to a menulist.

-
<menulist>
-  <menupopup>
-    <menuitem label="Mozilla" value="http://mozilla.org"/>
-    <menuitem label="Slashdot" value="http://slashdot.org"/>
-    <menuitem label="Sourceforge" value="http://sf.net"/>
-    <menuitem label="Freshmeat" value="http://freshmeat.net"/>
-  </menupopup>
-</menulist>
-
-

The following example shows how a menupopup can be used a context menu for an element. When the label is right-clicked, the menu will be displayed.

-
- Image:XUL_ref_popup.png
-
<menupopup id="clipmenu">
-  <menuitem label="Cut"/>
-  <menuitem label="Copy"/>
-  <menuitem label="Paste"/>
-</menupopup>
-<label value="Right click for popup" context="clipmenu"/>
-
-

Attributes

-

- - -
-
ignorekeys
-
Type: boolean
-
If true, keyboard navigation between items in the popup is disabled.
-
-
- - -
-
left
-
Type: integer
-
Overrides the horizontal position of the popup specified by the showPopup method.
-
-
- - -
-
onpopuphidden
-
Type: script code
-
This event is sent to a popup after it has been hidden.
-
This event may also be received while the popup is still open, but when sub-menus contained within this popup are hidden.
-
-

Example:

-
-
- -
<menupopup id="top" onpopuphidden="console.log('The onpopuphidden method of id=top was called.');">
-    <menuitem label="item 1"/>
-    <menuitem label="item 2"/>
-    <menu id="submenu1" label="submenu 1">
-        <menupopup id="submenu1-popup">
-            <menuitem label="submenu1 item 1"/>
-            <menuitem label="submenu1 item 2"/>
-        </menupopup>
-    </menu>
-    <menu id="submenu2" label="submenu 1">
-        <menupopup id="submenu2-popup">
-            <menuitem label="submenu2 item 1"/>
-            <menuitem label="submenu2 item 2"/>
-        </menupopup>
-    </menu>
-<menupopup/>
-
- - -
- - -
-
onpopuphiding
-
Type: script code
-
This event is sent to a popup when it is about to be hidden.
-
-
- -
-
- onpopupshowing
-
- Type: script code
-
- This event is sent to a popup just before it is opened. This handler is usually used to dynamically set the contents when the user requests to display it. Returning false from this event handler prevents the popup from appearing.
-
- 该事件在 popup 打开之前传给它。它用于动态生成菜单项。如果返回 false 值,则 popup 将不会显示菜单项。
-
- -

 

-
- -
-
- onpopupshown
-
- Type: script code
-
- This event is sent to a popup after it has been opened, much like the onload event is sent to a window when it is opened.
-
- 该事件在 popup 打开之后触发,与 window 的 onload 事件比较类似。
-
- -

 

-
- - -
-
position
-
Type: string
-
The position attribute determines where the popup appears relative to the element the user clicked to invoke the popup. This allows you to place the popup on one side of a button.  Note that a context menu will never respect this attribute, always appearing relative to the mouse cursor.
-

- This value can be specified either as a single word offering pre-defined alignment positions, or as 2 words specifying exactly which part of the anchor and popup should be aligned.
-

- If specified as 2 words, the value indicates which corner or edge of the anchor (the first word) is aligned which which corner of the popup (the second word).  The anchor value (ie, the first word) can be one of topleft, topright, bottomleft, bottomright, leftcenter, rightcenter, topcenter or bottomcenter.  The popup value (ie, the second word) can be one of topleft, topright, bottomleft or bottomright.
-

- Positions specified as a single word string are shortcuts for the values above.  Valid single-word values are after_start, after_end, before_start, before_end, end_after, end_before, start_after, start_before, overlap, at_pointer or after_pointer.
-
For more details, including examples, please see popup positioning
-
- - -
- - -
-
top
-
Type: integer
-
Overrides the vertical position of the popup specified by the showPopup method.
-
-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- popupBoxObject
-
- Type: nsIPopupBoxObject
-
- This read-only property holds the nsIPopupBoxObject that implements the popup. You wouldn't normally need to use this property as all of its functions are available via the popup itself.
-
-
-
- position
-
- Type: string
-
- Gets and sets the value of the position attribute.
-
-
-
- state
-
- Type: string
-
- This read only property indicates whether the popup is open or not. Four values are possible: -
    -
  • closed: The popup is closed and not visible.
  • -
  • open: The popup is open and visible on screen.
  • -
  • showing: A request has been made to open the popup, but it has not yet been shown. This state will occur during the popupshowing event.
  • -
  • hiding: The popup is about to be hidden. This state will occur during the popuphiding event.
  • -
-
-

-

Methods

-

- - - - - -
-

Inherited Methods
-addEventListener(), appendChild(), blur, click, cloneNode(), compareDocumentPosition, dispatchEvent(), doCommand, focus, getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getBoundingClientRect(), getClientRects(), getElementsByAttribute, getElementsByAttributeNS, getElementsByClassName(), getElementsByTagName(), getElementsByTagNameNS(), getFeature(), getUserData, hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isDefaultNamespace(), isEqualNode, isSameNode, isSupported(), lookupNamespaceURI, lookupPrefix, normalize(), querySelector(), querySelectorAll(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS(), setUserData

- -
-
- hidePopup()
-
- Return type: no return value
-
- Closes the popup immediately.
-
-
- moveTo( x, y )
-
- Return type: no return value
-
- Moves the popup to a new location defined by screen coordinates (and not client coordinates).
-
- If both x and y have the value -1 the call will realign the popup with its anchor node.
-
-
- openPopup( anchor , position , x , y , isContextMenu, attributesOverride, triggerEvent )
-
- Return type: no return value
-
-

Opens the popup relative to a specified node at a specific location.

-
-
- anchor
-
- The popup may be either anchored to another node or opened freely. To anchor a popup to a node, supply an anchor node and set the position to a string indicating the manner in which the popup should be anchored. The anchor node does not need to be in the same document as the popup. Unanchored popups may be created by supplying null as the anchor node. The direction in which the popup is oriented depends on the direction of the anchor.
-
- position
-
- Possible values for position are: before_start, before_end, after_start, after_end, start_before, start_after, end_before, end_after, overlap, and after_pointer. Check Positioning of the Popup Guide for a precise description of the effect of the different values.
-
- x, y
-
- For an anchored popup, the x and y arguments may be used to offset the popup from its anchored position by some number, measured in CSS pixels. An unanchored popup appears at the position specified by x and y, relative to the viewport of the document containing the popup node. In this case, the position and attributesOverride arguments are ignored.
-
- isContextMenu
-
- The isContextMenu argument should be true for context menus and false for all other types of popups. It affects menu item highlighting; that is, while a context menu is open, menus opened earlier do not highlight or execute their items.
-
- attributesOverride
-
- If the attributesOverride argument is true, the position attribute on the popup node overrides the position value argument. If attributesOverride is false, the attribute is only used if the position argument is empty.
-
- triggerEvent
-
- The event that triggered the popup (such as a mouse click, if the user clicked something to open the popup).
-
-
- openPopupAtScreen( x, y, isContextMenu )
-
- Return type: no return value
-
- Open the popup at a specific screen position specified by x and y. This position may be adjusted if it would cause the popup to be off of the screen. The x and y coordinates are measured in CSS pixels.
-
-
showPopup( element, x, y, popupType, anchor, align ) Deprecated since Gecko 1.9
-
Return type: no return value
- Deprecated in favor of openPopup and openPopupAtScreen
-
Opens a popup element. There are two ways of specifying where the popup appears, either at a specific screen position, or relative to some element in the window. If either x or y are set to values, the popup will appear at the screen coordinate (x,y). If x and y are -1, the popup will be positioned relative to the element specified as the first argument. This is what you might do to show a popup below a button, for example. In this latter case, the anchor and align arguments may be used to further control where the popup appears relative to the element. The anchor argument corresponds to the popupanchor attribute on the element. The align argument corresponds to the popupalign attribute on the element. The anchor and align arguments are ignored if either x or y are not -1.
-
- -
-
To have a popup appear relative to another element yet still offset by some number of pixels, determine the actual screen position of the element using the boxObject.screenX and boxObject.screenY properties of the element, and use those as the x and y arguments offset by the desired values.
-
- -
-
The popupType should be one of the strings popup, context, or tooltip. Each type of popup is intended to be displayed only temporarily; they are not expected to be displayed permanently.
-
-
- sizeTo( width, height )
-
- Return type: no return value
-
- Changes the current size of the popup to the new width and height.
-

- -
-
- Elements
-
- menu, menubar, menuitem, menulist, menuseparator
-
-
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULPopupElement
-
-

 

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/menuseparator/index.html b/files/zh-cn/mozilla/tech/xul/menuseparator/index.html deleted file mode 100644 index 5b00451c60..0000000000 --- a/files/zh-cn/mozilla/tech/xul/menuseparator/index.html +++ /dev/null @@ -1,435 +0,0 @@ ---- -title: menuseparator -slug: Mozilla/Tech/XUL/menuseparator -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/menuseparator ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

Used to create a separator between menu items. Typically drawn as a thin line.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- acceltext, accesskey, allowevents, command, crop, disabled, image, label, selected, tabindex, value
-
-
-
- Properties
-
- accessibleType, accessKey, command, control, crop, disabled, image, label, labelElement, parentContainer, selected, tabIndex, value
-
-

Examples

-
<menu label="Help">
-  <menupopup>
-    <menuitem label="Contents"/>
-    <menuseparator/>
-    <menuitem label="Release Notes"/>
-  </menupopup>
-</menu>
-
-

Attributes

-

- -
-
- acceltext
-
- Type: - - string -
-
- Text that appears beside beside the menu label to indicate the shortcut key (accelerator key) to use to invoke the command. If this value is set, it overrides an assigned key set in the key attribute. This attribute does not apply to menus directly on the menubar.
-
- -

-
- - - - -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

-
- - -
-
allowevents
-
Type: - boolean
-
- 类型:boolean
-
If true, events are passed to children of the element. Otherwise, events are passed to the element only.
- 如果为真,事件向子元素传递。否则,事件只传递到当前元素。
-
- - - -

-
- -
-
- command
-
- Type: - - element id -
-
- Set to the id of a command element that is being observed by the element.
-
- -

-
- -
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- - -

-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- -
-
- image
-
- Type: - - image URL -
-
- The URL of the image to appear on the element. If this attribute is empty or left out, no image appears. The position of the image is determined by the dir and orient attributes.
-
- -

-
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- -
-
- selected
-
- Type: - - boolean -
-
- Indicates whether the element is selected or not. This value is read-only. To change the selection, set either the selectedIndex or selectedItem property of the containing element.
-
- -

-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- -
-
- value
-
- Type: - - string -
-
- The string attribute allows you to associate a data value with an element. It is not used for any specific purpose, but you can access it with a script for your own use.
-
- -

-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- accessKey
-
- Type: - - character -
-
- Gets and sets the value of the accesskey attribute.
-
- -

-
-
- command
-
- Type: - - element id -
-
- Gets and sets the value of the command attribute.
-
- -

-
-
- control
-
- Type: - - menu element -
-
- Returns the enclosing menu that the item is inside, if any, or null if there is no enclosing menu.
-
- -

-
-
- crop
-
- Type: - - string -
-
- Gets and sets the value of the crop attribute.
-
- -

-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

-
-
- image
-
- Type: - - image URL -
-
- Gets and sets the value of the image attribute.
-
- -

-
-
- label
-
- Type: - - string -
-
- Gets and sets the value of the label attribute.
-
- -

-
-
- labelElement
-
- Type: - - label element -
-
- The label element associated with the control. This is set when a label has a control attribute pointing to this element. This property will be null when no label is associated with the control.
-
- -

-
-
- parentContainer
-
- Type: - - menu element -
-
- Read only property that returns the containing menu element, or null if there isn't a containing menu.
-
- -

-
-
- selected<magic name="\"PAGENAME\"/"></magic>
-
- Type: - - boolean -
-
- This property's value is true if this element is selected, or false if it is not. This property is read only.
-
-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
- -

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -
-
- Elements
-
- menu, menubar, menuitem, menulist, menupopup
-
-
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULContainerItemElement, nsIDOMXULSelectControlItemElement
-
-

 

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/method/extra1/index.html b/files/zh-cn/mozilla/tech/xul/method/extra1/index.html deleted file mode 100644 index 33546b4a30..0000000000 --- a/files/zh-cn/mozilla/tech/xul/method/extra1/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: extra1 -slug: Mozilla/Tech/XUL/Method/extra1 -translation_of: Archive/Mozilla/XUL/Method/extra1 ---- -
- « XUL Reference home
-
-
- extra1()
-
- 返回值类型:无返回值
-
- 调用该方法可以模拟对extra1按钮的点击,同时也会触发并执行该元素的onextra1属性上设置的代码.
-
diff --git a/files/zh-cn/mozilla/tech/xul/method/focus/index.html b/files/zh-cn/mozilla/tech/xul/method/focus/index.html deleted file mode 100644 index 690ba10358..0000000000 --- a/files/zh-cn/mozilla/tech/xul/method/focus/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: focus -slug: Mozilla/Tech/XUL/Method/focus -translation_of: Archive/Mozilla/XUL/Method/focus ---- -
- « XUL Reference home
-
-
- focus()
-
- 返回值类型: 无返回值
-
- 让指定的元素获得键盘焦点.
-
diff --git a/files/zh-cn/mozilla/tech/xul/method/getbrowserfortab/index.html b/files/zh-cn/mozilla/tech/xul/method/getbrowserfortab/index.html deleted file mode 100644 index 483579d074..0000000000 --- a/files/zh-cn/mozilla/tech/xul/method/getbrowserfortab/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: getBrowserForTab -slug: Mozilla/Tech/XUL/Method/getBrowserForTab -translation_of: Archive/Mozilla/XUL/Method/getBrowserForTab ---- -
- « XUL Reference home
-
-
- getBrowserForTab( tab )
-
- 返回值类型: browser元素
-
- 返回于指定的tab元素相关联的browser元素.
-
diff --git a/files/zh-cn/mozilla/tech/xul/method/getbutton/index.html b/files/zh-cn/mozilla/tech/xul/method/getbutton/index.html deleted file mode 100644 index 11b4f91e6d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/method/getbutton/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: getButton -slug: Mozilla/Tech/XUL/Method/getButton -translation_of: Archive/Mozilla/XUL/Method/getButton ---- -
- « XUL Reference home
-
-
- getButton( type )
-
- 返回值类型: button元素
-
- 返回当前对话框中指定类型的button元素.
-
diff --git a/files/zh-cn/mozilla/tech/xul/method/increase/index.html b/files/zh-cn/mozilla/tech/xul/method/increase/index.html deleted file mode 100644 index b7431b355b..0000000000 --- a/files/zh-cn/mozilla/tech/xul/method/increase/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: increase -slug: Mozilla/Tech/XUL/Method/increase -translation_of: Archive/Mozilla/XUL/Method/increase ---- -
- « XUL Reference home
-
-
-
- 拥有该方法的元素类型: scale textbox
-
-
-
-
- increase()
-
- 返回值类型: 无返回值
-
- 增大刻度条控件(scale元素)或者数字输入框控件(type属性为number的textbox元素)中的数字值(按照其increment属性指定的值).
-
diff --git a/files/zh-cn/mozilla/tech/xul/method/index.html b/files/zh-cn/mozilla/tech/xul/method/index.html deleted file mode 100644 index e5d7d023c0..0000000000 --- a/files/zh-cn/mozilla/tech/xul/method/index.html +++ /dev/null @@ -1,170 +0,0 @@ ---- -title: Methods -slug: Mozilla/Tech/XUL/Method -tags: - - XUL Methods -translation_of: Archive/Mozilla/XUL/Method ---- -

« XUL Reference home

- - - diff --git a/files/zh-cn/mozilla/tech/xul/method/reset/index.html b/files/zh-cn/mozilla/tech/xul/method/reset/index.html deleted file mode 100644 index 258f4d53df..0000000000 --- a/files/zh-cn/mozilla/tech/xul/method/reset/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: reset -slug: Mozilla/Tech/XUL/Method/reset -translation_of: Archive/Mozilla/XUL/Method/reset ---- -
- « XUL Reference home
-
-
- reset()
-
- 返回值:无返回值
-
- 将用户偏好重置为默认值.
-
diff --git a/files/zh-cn/mozilla/tech/xul/method/stop/index.html b/files/zh-cn/mozilla/tech/xul/method/stop/index.html deleted file mode 100644 index 181a6123ae..0000000000 --- a/files/zh-cn/mozilla/tech/xul/method/stop/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: stop -slug: Mozilla/Tech/XUL/Method/stop -translation_of: Archive/Mozilla/XUL/Method/stop ---- -
- « XUL Reference home
-
-
- stop()
-
- 返回值: 无返回值
-
- 效果等同于按下了停止按钮,停止当前页面中文档的加载.
-
diff --git a/files/zh-cn/mozilla/tech/xul/namespaces/index.html b/files/zh-cn/mozilla/tech/xul/namespaces/index.html deleted file mode 100644 index 73a5099ae6..0000000000 --- a/files/zh-cn/mozilla/tech/xul/namespaces/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Namespaces -slug: Mozilla/Tech/XUL/Namespaces -translation_of: Archive/Mozilla/XUL/Namespaces ---- -

 

- -

除此文档外,请参阅Namespaces Crash Course

- -

XML namespaces 提供了区分重复元素和属性名称的方法。当XML文档包含来自两个或多个不同的XML模式 (或者DTD)的元素和属性时,可能会出现重复元素和属性名称。引用 Wikipedia: "一般来说,namespaces是一个抽象的容器,为项目提供上下文... 它拥有并且允许消除具有相同名称的项目的消歧。"

- -

如果你熟悉C++命名空间、Java包、Perl包或者Python模块导入,那么你已经熟悉了namespaces概念。

- -

XML namespace 由唯一的名称 (称为URI, 而不是URL, 即使它看起来像URL)标识。URI 可以是任何字符串,虽然大多数人选择基于URL的URI,因为URL是实现我们期望的唯一性的一种简单的方法。虽然没有任何理由去阻止其他人使用这个namespaces http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul, 但是不太可能有人会不小心选择这个namespaces。即使他们意外的选择了这个namespaces,他们也不可能在他们的模式/DTD中定义与XUL相同的元素 。

- -

XML namespace中的任何元素类型或者属性名称都可以通过其XML  namespace和其“local name”来唯一标识。 这两个项目一起定义了一个限定名称,或者 QName.

- -

例如: <xul:textbox/> 使用名为"xul"的namespace和本地名称 "textbox"。它不同于例子所示,例如: <foobar:textbox/> 可能出现在同一个文档中。xulfoobar namespaces必须定义在它们所使用的XML文档的顶部, 如下:

- -
 <foobar:some-element
-     xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-     xmlns:foobar="the-foobar-namespace">
-   <xul:textbox id="foo" value="bar"/>
-   <foobar:textbox favorite-food="pancakes"/>
- </foobar:some-element>
-
- -

注意我已经在同一个文档中混合了两个<textboxes/> 。区分他们的唯一的方法是他们有不同含义的namespaces.

- -

还有一个事情需要了解:“default namespace(默认namespace)”。每个XML元素有一个 "default namespace", 而且它总是和XUL 元素一起使用。在XUL 文档中,您通常会看到:

- -
 <window
-     id="foo"
-     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-   ...
-   ...
- </window>
-
- -

在XHTML 文档中,您会看到:

- -
 <html xmlns="http://www.w3.org/1999/xhtml">
-   ...
-   ...
- </html>
-
- -

与之前相比,这里有一个非常微妙的差别。 我之前写过xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" ,但是这儿的:xul 部分被省略。这意味着对XML解析器来说,http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul 是元素及其后代元素的 default namespace (除非在后代元素上被default namespace覆盖),并且,如果没有namespace 的任何元素(即,没有前缀和colon)属于default namespace。这就是为什么我们可以使用简写<textbox/>来代替XUL中的 <xul:textbox/> (即使后者在没有使用http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul 作为default namespace是正确的) -- XUL namespace被定义为最顶层元素的默认值。换句话说,default namespace允许一种简短的概括被用于一个元素的所有后代元素。

- -

这里有一个问题:在下面的XML文档中,什么namespace包含了foo元素?

- -
  <foo/>
-
- -

答案是它不在namespace, 或者它在namespace中由空字符串表示:

- -
  <foo xmlns=""/>
-
- -

第二个例子在语义上等同于第一个例子。

- -

那么第二个问题是:  bar、 baz 和 quux 是什么名称空间中的属性?

- -

 

- -
  <foo bar="value">
-    <element xmlns="namespace!" baz="value">
-      <element quux="value"/>
-    </element>
-  </foo>
-
- -

bar 显然不在namespace中。那么 bazquux怎么样呢?答案是他们也不在namespace中。实际上,在namespace中没有任何前缀不确定的属性,主要是因为XML最初没有namespaces,而且从那时起,所有的XML必须保持在无namespace.这是XML namespaces常年混乱的根源。

diff --git a/files/zh-cn/mozilla/tech/xul/popup/index.html b/files/zh-cn/mozilla/tech/xul/popup/index.html deleted file mode 100644 index 05ce34c3bc..0000000000 --- a/files/zh-cn/mozilla/tech/xul/popup/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: popup -slug: Mozilla/Tech/XUL/popup -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/popup ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

The popup element is equivalent to the menupopup element which should be used instead. See the documentation on the menupopup element for more information.

-

popup元素和menupopup元素在功能上是等价的,具体用法可以参考menupopup的说明文档。

-

 

-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/accessibletype/index.html b/files/zh-cn/mozilla/tech/xul/property/accessibletype/index.html deleted file mode 100644 index ae445e8bdb..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/accessibletype/index.html +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: accessibleType -slug: Mozilla/Tech/XUL/Property/accessibleType -translation_of: Archive/Mozilla/XUL/Property/accessibleType ---- -
- « XUL Reference
-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
-
-

Possible values are:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ConstantValue
XULAlert1001
XULButton1002
XULCheckbox1003
XULColorPicker1004
XULColorPickerTile1005
XULCombobox1006
XULDropmarker1007
XULGroupbox1008
XULImage1009
XULLink100A
XULListbox100B
XULListCell1026
XULListHead1024
XULListHeader1025
XULListitem100C
XULMenubar100D
XULMenuitem100E
XULMenupopup100F
XULMenuSeparator1010
XULPane1011
XULProgressMeter1012
XULScale1013
XULStatusBar1014
XULRadioButton1015
XULRadioGroup1016
XULTab1017
XULTabBox1018
XULTabs1019
XULText101A
XULTextBox101B
XULThumb101C
XULTree101D
XULTreeColumns101E
XULTreeColumnItem101F
XULToolbar1020
XULToolbarSeparator1021
XULTooltip1022
XULToolbarButton1023
-

</div>

-
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/accesskey/index.html b/files/zh-cn/mozilla/tech/xul/property/accesskey/index.html deleted file mode 100644 index 7b49328080..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/accesskey/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: accessKey -slug: Mozilla/Tech/XUL/Property/accessKey -translation_of: Archive/Mozilla/XUL/Property/accessKey ---- -
- « XUL Reference
-
-
- accessKey
-
- Type: - - character -
-
- Gets and sets the value of the accesskey attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/browser.preferences/index.html b/files/zh-cn/mozilla/tech/xul/property/browser.preferences/index.html deleted file mode 100644 index 7a0bd25201..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/browser.preferences/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: browser.preferences -slug: Mozilla/Tech/XUL/Property/browser.preferences -translation_of: Archive/Mozilla/XUL/Property/browser.preferences ---- -
- « XUL Reference
-
-
- preferences
-
- 类型: nsIPrefService
-
- 这是一个只读属性,其值为一个nsIPref对象,可以用来读取或设置用户的首选项.
-
diff --git a/files/zh-cn/mozilla/tech/xul/property/buttons/index.html b/files/zh-cn/mozilla/tech/xul/property/buttons/index.html deleted file mode 100644 index 67304e8fa1..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/buttons/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: buttons -slug: Mozilla/Tech/XUL/Property/buttons -translation_of: Archive/Mozilla/XUL/Property/buttons ---- -
« XUL Reference
-
buttons
类型: 列表,下面的值用逗号分隔
需要显示在对话框上的按钮的一个列表,使用逗号分隔。将按钮放置在合适的位置,将根据用户平台自动执行基本的事件处理。在列表中可以使用以下值:
  • accept:“确定”按钮,按下按钮时将接受更改。此按钮为默认按钮。
  • cancel:“取消”按钮,将取消操作。
  • help:“帮助”按钮,在对话框显示一个“帮助”按钮。
  • disclosure:“更多信息”按钮,显示一个“more info”按钮。该按钮可能是一个按钮或一个三角形。
  • extra1:一个可选的额外的按钮。你可以通过buttonlabelextra1 属性设置它的label。
  • extra2:第二个可选的额外的按钮。你可以通过 buttonlabelextra2 属性设置它的label。
-
-

Note: If you don't want to display any buttons in the dialog box, set the value of this attribute to "," (a single comma).

-
diff --git a/files/zh-cn/mozilla/tech/xul/property/command/index.html b/files/zh-cn/mozilla/tech/xul/property/command/index.html deleted file mode 100644 index 10993a17e6..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/command/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: command -slug: Mozilla/Tech/XUL/Property/command -translation_of: Archive/Mozilla/XUL/Property/command ---- -
- « XUL Reference
-
-
- command
-
- Type: - - element id -
-
- Gets and sets the value of the command attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/crop/index.html b/files/zh-cn/mozilla/tech/xul/property/crop/index.html deleted file mode 100644 index 54a99a746b..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/crop/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: crop -slug: Mozilla/Tech/XUL/Property/crop -translation_of: Archive/Mozilla/XUL/Property/crop ---- -
- « XUL Reference
-
-
- crop
-
- Type: - - string -
-
- Gets and sets the value of the crop attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/defaultvalue/index.html b/files/zh-cn/mozilla/tech/xul/property/defaultvalue/index.html deleted file mode 100644 index 7aca9067cb..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/defaultvalue/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: defaultValue -slug: Mozilla/Tech/XUL/Property/defaultValue -translation_of: Archive/Mozilla/XUL/Property/defaultValue ---- -
- « XUL Reference
-
-
- defaultValue
-
- 类型: 字符串
-
- 获取或设置一个textbox元素中显示的默认值.
-
diff --git a/files/zh-cn/mozilla/tech/xul/property/disabled/index.html b/files/zh-cn/mozilla/tech/xul/property/disabled/index.html deleted file mode 100644 index 500640dc2a..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/disabled/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: disabled -slug: Mozilla/Tech/XUL/Property/disabled -translation_of: Archive/Mozilla/XUL/Property/disabled ---- -
- « XUL Reference
-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/image/index.html b/files/zh-cn/mozilla/tech/xul/property/image/index.html deleted file mode 100644 index 5079e489cd..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/image/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: image -slug: Mozilla/Tech/XUL/Property/image -translation_of: Archive/Mozilla/XUL/Property/image ---- -
- « XUL Reference
-
-
- image
-
- Type: - - image URL -
-
- Gets and sets the value of the image attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/index.html b/files/zh-cn/mozilla/tech/xul/property/index.html deleted file mode 100644 index caec3163d8..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/index.html +++ /dev/null @@ -1,266 +0,0 @@ ---- -title: Property -slug: Mozilla/Tech/XUL/Property -tags: - - XUL Properties -translation_of: Archive/Mozilla/XUL/Property ---- -

« XUL Reference -

- - - -
-
diff --git a/files/zh-cn/mozilla/tech/xul/property/label/index.html b/files/zh-cn/mozilla/tech/xul/property/label/index.html deleted file mode 100644 index 83f85cc1e3..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/label/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: label -slug: Mozilla/Tech/XUL/Property/label -translation_of: Archive/Mozilla/XUL/Property/label ---- -
- « XUL Reference
-
-
- label
-
- Type: - - string -
-
- Gets and sets the value of the label attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/labelelement/index.html b/files/zh-cn/mozilla/tech/xul/property/labelelement/index.html deleted file mode 100644 index 6baead11d3..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/labelelement/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: labelElement -slug: Mozilla/Tech/XUL/Property/labelElement -translation_of: Archive/Mozilla/XUL/Property/labelElement ---- -
- « XUL Reference
-
-
- labelElement
-
- Type: - - label element -
-
- The label element associated with the control. This is set when a label has a control attribute pointing to this element. This property will be null when no label is associated with the control.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/markupdocumentviewer/index.html b/files/zh-cn/mozilla/tech/xul/property/markupdocumentviewer/index.html deleted file mode 100644 index 8719292f2d..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/markupdocumentviewer/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: markupDocumentViewer -slug: Mozilla/Tech/XUL/Property/markupDocumentViewer -translation_of: Archive/Mozilla/XUL/Property/markupDocumentViewer ---- -
- « XUL Reference
-
-
- markupDocumentViewer
-
- 类型: nsIMarkupDocumentViewer
-
- 这个只读的属性包含 nsIMarkupDocumentViewer 接口,负责document文档的绘制。
-
diff --git a/files/zh-cn/mozilla/tech/xul/property/max/index.html b/files/zh-cn/mozilla/tech/xul/property/max/index.html deleted file mode 100644 index 3d20dae617..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/max/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: max -slug: Mozilla/Tech/XUL/Property/max -translation_of: Archive/Mozilla/XUL/Property/max ---- -
- « XUL Reference
-
-
- max
-
- 类型:整数
-
- 获取或设置max特性(attribute)的值.
-
diff --git a/files/zh-cn/mozilla/tech/xul/property/menuitem.control/index.html b/files/zh-cn/mozilla/tech/xul/property/menuitem.control/index.html deleted file mode 100644 index a8cd738934..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/menuitem.control/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: menuitem.control -slug: Mozilla/Tech/XUL/Property/menuitem.control -translation_of: Archive/Mozilla/XUL/Property/menuitem.control ---- -
- « XUL Reference
-
-
- control
-
- Type: - - menu element -
-
- Returns the enclosing menu that the item is inside, if any, or null if there is no enclosing menu.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/parentcontainer/index.html b/files/zh-cn/mozilla/tech/xul/property/parentcontainer/index.html deleted file mode 100644 index f8a29d42ae..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/parentcontainer/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: parentContainer -slug: Mozilla/Tech/XUL/Property/parentContainer -translation_of: Archive/Mozilla/XUL/Property/parentContainer ---- -
- « XUL Reference
-
-
- parentContainer
-
- Type: - - menu element -
-
- Read only property that returns the containing menu element, or null if there isn't a containing menu.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/selected/index.html b/files/zh-cn/mozilla/tech/xul/property/selected/index.html deleted file mode 100644 index eee4b31285..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/selected/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: selected -slug: Mozilla/Tech/XUL/Property/selected -translation_of: Archive/Mozilla/XUL/Property/selected ---- -
- « XUL Reference
-
-
- selected<magic name="\"PAGENAME\"/"></magic>
-
- Type: - - boolean -
-
- This property's value is true if this element is selected, or false if it is not. This property is read only.
-
diff --git a/files/zh-cn/mozilla/tech/xul/property/selectedindex/index.html b/files/zh-cn/mozilla/tech/xul/property/selectedindex/index.html deleted file mode 100644 index 22d1a4fba1..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/selectedindex/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: selectedIndex -slug: Mozilla/Tech/XUL/Property/selectedIndex -translation_of: Archive/Mozilla/XUL/Property/selectedIndex ---- -
- « XUL Reference
-
-
- selectedIndex
-
- Type: - - integer -
-
- Returns the index of the currently selected item. You may select an item by assigning its index to this property. By assigning -1 to this property, all items will be deselected.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/selecteditem/index.html b/files/zh-cn/mozilla/tech/xul/property/selecteditem/index.html deleted file mode 100644 index 1583c5f526..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/selecteditem/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: selectedItem -slug: Mozilla/Tech/XUL/Property/selectedItem -translation_of: Archive/Mozilla/XUL/Property/selectedItem ---- -
- « XUL Reference
-
-
- selectedItem
-
- Type: - - element -
-
- Holds the currently selected item. If no item is currently selected, this value will be null. You can select an item by setting this value. A select event will be sent to the element when it is changed either via this property, the selectedIndex property, or changed by the user.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/selectionstart/index.html b/files/zh-cn/mozilla/tech/xul/property/selectionstart/index.html deleted file mode 100644 index 27ecd267c6..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/selectionstart/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: selectionStart -slug: Mozilla/Tech/XUL/Property/selectionStart -translation_of: Archive/Mozilla/XUL/Property/selectionStart ---- -
« XUL Reference
- -
-
selectionStart
-
类型: integer
-
获取或设置字段文本的选定部分的开始。 与selectionEnd 属性结合使用。 该值指定第一个选定字符的索引。
-
- -
-

-
diff --git a/files/zh-cn/mozilla/tech/xul/property/spinbuttons/index.html b/files/zh-cn/mozilla/tech/xul/property/spinbuttons/index.html deleted file mode 100644 index aadb3a3a31..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/spinbuttons/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: spinButtons -slug: Mozilla/Tech/XUL/Property/spinButtons -translation_of: Archive/Mozilla/XUL/Property/spinButtons ---- -
- « XUL Reference
-
-
- spinButtons
-
- 类型:spinbuttons元素
-
- 一个只读属性,返回了数字输入框元素(type属性为number的textbox元素)中包含的spinbuttons元素(也就是右侧调整数字大小的上下小箭头).
-
diff --git a/files/zh-cn/mozilla/tech/xul/property/tabindex/index.html b/files/zh-cn/mozilla/tech/xul/property/tabindex/index.html deleted file mode 100644 index 5e41049910..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/tabindex/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: tabIndex -slug: Mozilla/Tech/XUL/Property/tabIndex -translation_of: Archive/Mozilla/XUL/Property/tabIndex ---- -
- « XUL Reference
-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/property/textbox.value/index.html b/files/zh-cn/mozilla/tech/xul/property/textbox.value/index.html deleted file mode 100644 index 860ed2fd39..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/textbox.value/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: textbox.value -slug: Mozilla/Tech/XUL/Property/textbox.value -translation_of: Archive/Mozilla/XUL/Property/textbox.value ---- -
- « XUL Reference
-
-
- value
-
- 类型:字符串
-
- 读取或设置该textbox元素中的文本内容.
-
diff --git a/files/zh-cn/mozilla/tech/xul/property/value/index.html b/files/zh-cn/mozilla/tech/xul/property/value/index.html deleted file mode 100644 index b56deb5fc4..0000000000 --- a/files/zh-cn/mozilla/tech/xul/property/value/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: value -slug: Mozilla/Tech/XUL/Property/value -translation_of: Archive/Mozilla/XUL/Property/value ---- -
- « XUL Reference
-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/radio/index.html b/files/zh-cn/mozilla/tech/xul/radio/index.html deleted file mode 100644 index ecadeea308..0000000000 --- a/files/zh-cn/mozilla/tech/xul/radio/index.html +++ /dev/null @@ -1,379 +0,0 @@ ---- -title: radio -slug: Mozilla/Tech/XUL/radio -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/radio ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

An element that can be turned on and off. Radio buttons are almost always grouped together in groups. Only one radio button within the same radiogroup may be selected at a time. The user can switch which radio button is turned on by selecting it with the mouse or keyboard. Other radio buttons in the same group are turned off. A label, specified with the label attribute may be added beside the radio button.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- accesskey, command, crop, disabled, focused, group, image, label, selected, tabindex, value
-
-
-
- Properties
-
- accessKey, accessibleType, control, crop, disabled, image, label, radioGroup, selected, tabIndex, value
-
-

Examples

-
- Image:XUL_ref_radio.png
-
<radiogroup>
-  <radio id="orange" label="Red" accesskey="R"/>
-  <radio id="violet" label="Green"  accesskey="G" selected="true"/>
-  <radio id="yellow" label="Blue"  accesskey="B" disabled="true"/>
-</radiogroup>
-
-

Attributes

-

- - - - -
-
accesskey
-
类型: - character【字符】 -
-
本属性允许为控件(元素)设定一个字符作为快捷键,这个字符应该是 label 属性文本中的一个字符。该字符将会被加下划线以重点强调,平台和主体的变换并不影响这一表现行为。 当用户点击 ALT (在其他平台上具有类似功能的键) 和这个字符对应的按键时, 控件(元素)将立刻被从窗口中的某处激活或/并且获得焦点 。虽说字符不分大小写,但是当label中存在大写字符和小写字符时,快捷键的字符将首先选择与之完全匹配的那一个,如果label中存在两个或更多的与accesskey字符相同的字符,其中的第一个字符将被加下划线。
-
      *(有些键在监听按键事件时,分别对应event.ctrlKey和event.metaKey。)
-
- -

 

- -

Example

- -
Image:XUL_ref_accesskey_attr.png
- -
<vbox>
-  <label value="Enter Name" accesskey="e" control="myName"/>
-  <textbox id="myName"/>
-  <button label="Cancel" accesskey="n"/>
-  <button label="Ok" accesskey="O"/>
-</vbox>
-
- -

See also

- -

label attribute, acceltext attribute

- -

-
- -
-
- command
-
- Type: - - element id -
-
- Set to the id of a command element that is being observed by the element.
-
- -

-
- -
-
- crop
-
- Type: - - one of the values below -
-
- If the label of the element is too big to fit in its given space, the text will be cropped on the side specified by the crop attribute. An ellipsis will be used in place of the cropped text. If the box direction is reversed, the cropping is reversed.
-
- - -

-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
focused
-
Type: boolean
-
This attribute is true if the element is focused.
-
-
- - -
-
group
-
Type: string group name
-
Buttons with type="radio" and the same value for their group attribute are put into the same group. Only one button from each group can be checked at a time. If the user selects one the buttons, the others in the group are unchecked.
-
-
- -
-
- image
-
- Type: - - image URL -
-
- The URL of the image to appear on the element. If this attribute is empty or left out, no image appears. The position of the image is determined by the dir and orient attributes.
-
- -

-
- -
-
- label
-
- Type: string
-
- The label that will appear on the element. If this is left out, no text appears.
- label 在元素上显示。如果左侧出界,则不显示任何文字。
-
- -

-
- -
-
- selected
-
- Type: - - boolean -
-
- Indicates whether the element is selected or not. This value is read-only. To change the selection, set either the selectedIndex or selectedItem property of the containing element.
-
- -

-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- -
-
- value
-
- Type: - - string -
-
- The string attribute allows you to associate a data value with an element. It is not used for any specific purpose, but you can access it with a script for your own use.
-
- -

-

-

Properties

-

-
-
- accessKey
-
- Type: - - character -
-
- Gets and sets the value of the accesskey attribute.
-
- -

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

- -
-
control
-
Type: radiogroup element
-
Returns the enclosing radiogroup that the radio element is contained within, which may or may not be its direct parent.
-
-
-
- crop
-
- Type: - - string -
-
- Gets and sets the value of the crop attribute.
-
- -

-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

-
-
- image
-
- Type: - - image URL -
-
- Gets and sets the value of the image attribute.
-
- -

-
-
- label
-
- Type: - - string -
-
- Gets and sets the value of the label attribute.
-
- -

- -
-
radioGroup
-
Type: radiogroup element
-
Equivalent to the control property.
-
-
-
- selected<magic name="\"PAGENAME\"/"></magic>
-
- Type: - - boolean -
-
- This property's value is true if this element is selected, or false if it is not. This property is read only.
-
-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
- -

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -
-
- Elements
-
- radiogroup, checkbox
-
-
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULSelectControlItemElement, nsIDOMXULLabeledControlElement
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/radiogroup/index.html b/files/zh-cn/mozilla/tech/xul/radiogroup/index.html deleted file mode 100644 index a91c7aa8e0..0000000000 --- a/files/zh-cn/mozilla/tech/xul/radiogroup/index.html +++ /dev/null @@ -1,275 +0,0 @@ ---- -title: radiogroup -slug: Mozilla/Tech/XUL/radiogroup -tags: - - radiogroup - - 单选按钮组 -translation_of: Archive/Mozilla/XUL/radiogroup ---- -
- « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
- -

一组单选按钮。在单选按钮组内一次只能选择一个单选按钮。radio 按钮可以指示单选按钮组或后代的子节点。 如果您想要一个边框或 caption ,请将Radiogroup放在一个 groupbox内。radiogroup 默认为垂直方向。

- -

更多信息可以在 XUL 教程 中找到。

- -
-
Attributes
-
disabled, focused, preference, tabindex, value
-
- -
-
Properties
-
accessibleType, disabled, focusedItem, itemCount, selectedIndex, selectedItem, tabIndex, value
-
- -
-
Methods
-
appendItem, checkAdjacentElement, getIndexOfItem, getItemAtIndex, insertItemAt, removeItemAt
-
- -

范例

- -
Image:XUL_ref_radios.png
- -
<radiogroup>
-  <radio id="orange" label="Red"/>
-  <radio id="violet" label="Green" selected="true"/>
-  <radio id="yellow" label="Blue"/>
-</radiogroup>
-
- -

Attributes

- -

- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
focused
-
Type: boolean
-
This attribute is true if the element is focused.
-
-
- - -
-
preference
-
Type: id
-
Connects the element to a corresponding preference. This attribute only has any effect when used inside a prefwindow. More information is available in the Preferences System article.
-
-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- -
-
- value
-
- Type: - - string -
-
- The string attribute allows you to associate a data value with an element. It is not used for any specific purpose, but you can access it with a script for your own use.
-
- -

-

- -

Properties

- -

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

- -
-
focusedItem
-
Type: radio element
-
Holds the currently focused item in the radiogroup, which may or may not be the same as the selected item. You can change the focused item by setting this property.
-
-
-
itemCount
-
Type: integer
-
Read only property holding the number of child items.
-
-
-
-
- selectedIndex
-
- Type: - - integer -
-
- Returns the index of the currently selected item. You may select an item by assigning its index to this property. By assigning -1 to this property, all items will be deselected.
-
- -

-
-
- selectedItem
-
- Type: - - element -
-
- Holds the currently selected item. If no item is currently selected, this value will be null. You can select an item by setting this value. A select event will be sent to the element when it is changed either via this property, the selectedIndex property, or changed by the user.
-
- -

-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

-
-
- value
-
- Type: - - string -
-
- Gets and sets the value of the value attribute.
-
- -

- -

Methods

- -

- - - - - -
-

Inherited Methods
-addEventListener(), appendChild(), blur, click, cloneNode(), compareDocumentPosition, dispatchEvent(), doCommand, focus, getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getBoundingClientRect(), getClientRects(), getElementsByAttribute, getElementsByAttributeNS, getElementsByClassName(), getElementsByTagName(), getElementsByTagNameNS(), getFeature(), getUserData, hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isDefaultNamespace(), isEqualNode, isSameNode, isSupported(), lookupNamespaceURI, lookupPrefix, normalize(), querySelector(), querySelectorAll(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS(), setUserData

- -
-
- appendItem( label, value )
-
- Return type: element
-
- Creates a new item and adds it to the end of the existing list of items. You may optionally set a value. The function returns the newly created element.
-
-
checkAdjacentElement( dir )
-
Return type: no return value
-
Deselects the currently selected radio button in the group and selects the one adjacent to it. If the argument dir is true, the next radio button is selected. If it is false, the previous radio button is selected.
-
-
getIndexOfItem( item )
-
Return type: integer
-
Returns the zero-based position of the specified item. Items are numbered starting at the first item displayed in the list.
-
-
getItemAtIndex( index )
-
Return type: element
-
Returns the element that is at the specified index.
-
-
- insertItemAt( index, label, value )
-
- Return type: element
-
- This method creates a new item and inserts it at the specified position. You may optionally set a value. The new item element is returned.
-
-
- removeItemAt( index )
-
- Return type: element
-
- Removes the child item in the element at the specified index. The method returns the removed item.
-

- - - -
-
Interfaces
-
nsIAccessibleProvider, nsIDOMXULSelectControlElement
-
- -

diff --git a/files/zh-cn/mozilla/tech/xul/script/index.html b/files/zh-cn/mozilla/tech/xul/script/index.html deleted file mode 100644 index 6006a33298..0000000000 --- a/files/zh-cn/mozilla/tech/xul/script/index.html +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: script -slug: Mozilla/Tech/XUL/script -translation_of: Archive/Mozilla/XUL/script ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

Much like the HTML script element, this is used to declare a script to be used by the XUL window. You should usually put scripts in a separate file pointed to by the src attribute, but you may also place the script inline inside the opening and closing script tags.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- src, type
-
-

Examples

-
 <script src="test.js"/>
- <script src="http://example.com/js/test.js"/>
- <script>
-   function foo(){
-     // code
-    }
-  </script>
-
-

Attributes

-

- - -
-
src
-
Type: URI
-
The URI of the script.
-
-
- - -
-
type
-
Type: language content type
-
The language of the script. Usually, you would set this to application/javascript.
-
- Note: If the JavaScript file is in chrome://, setting this attribute to application/javascript will always use the latest available JavaScript version. If you omit this attribute, the default (and older) JavaScript version is used (like you get when including a JavaScript file from web content without specifying a version number).
-
-
- - - - - -

Inherited from XUL element
-align, -allowevents, -allownegativeassertions, -class, -coalesceduplicatearcs, -collapsed, -container, -containment, -context, -contextmenu, -datasources, -dir, -empty, -equalsize, -flags, -flex, -height, -hidden, -id, -insertafter, -insertbefore, -left, -maxheight, -maxwidth, -menu, -minheight, -minwidth, -mousethrough, -observes, -ordinal, -orient, -pack, -persist, -popup, -position, -preference-editable, -querytype, -ref, -removeelement, -sortDirection, -sortResource, -sortResource2, -statustext, -style, -template, -tooltip, -tooltiptext, -top, -uri, -wait-cursor, -width

-

-

Properties

-

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -

diff --git a/files/zh-cn/mozilla/tech/xul/statusbar/index.html b/files/zh-cn/mozilla/tech/xul/statusbar/index.html deleted file mode 100644 index dec688952e..0000000000 --- a/files/zh-cn/mozilla/tech/xul/statusbar/index.html +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: statusbar -slug: Mozilla/Tech/XUL/statusbar -translation_of: Archive/Mozilla/XUL/statusbar ---- -

-

已废弃
该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。

-

-
- 我建议使用附加组件栏来代替.
-
-  
-
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-
-  
-

用来创建状态栏的元素,通常位于窗口底部.可以包含多个statusbarpanel元素.

-
-
- 属性
-
- accessibleType
-
-

示例

-
<statusbar>
-  <statusbarpanel label="Left panel"/>
-  <spacer flex="1"/>
-  <progressmeter mode="determined" value="82"/>
-  <statusbarpanel label="Right panel"/>
-</statusbar>
-
-

Image:XUL_ref_statusbar.png

-

XUL属性(Attribute)

-

- - - - - -

Inherited from XUL element
-align, -allowevents, -allownegativeassertions, -class, -coalesceduplicatearcs, -collapsed, -container, -containment, -context, -contextmenu, -datasources, -dir, -empty, -equalsize, -flags, -flex, -height, -hidden, -id, -insertafter, -insertbefore, -left, -maxheight, -maxwidth, -menu, -minheight, -minwidth, -mousethrough, -observes, -ordinal, -orient, -pack, -persist, -popup, -position, -preference-editable, -querytype, -ref, -removeelement, -sortDirection, -sortResource, -sortResource2, -statustext, -style, -template, -tooltip, -tooltiptext, -top, -uri, -wait-cursor, -width

-

-

DOM属性(Propertie)

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

方法

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -
-
- 元素
-
- statusbarpanel
-
-
-
- 接口
-
- nsIAccessibleProvider
-
diff --git a/files/zh-cn/mozilla/tech/xul/style/index.html b/files/zh-cn/mozilla/tech/xul/style/index.html deleted file mode 100644 index 173c741e34..0000000000 --- a/files/zh-cn/mozilla/tech/xul/style/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Style classes -slug: Mozilla/Tech/XUL/Style -translation_of: Archive/Mozilla/XUL/Style ---- -

This page was auto-generated because a user created a sub-page to this page.

diff --git a/files/zh-cn/mozilla/tech/xul/style/menuitem-iconic/index.html b/files/zh-cn/mozilla/tech/xul/style/menuitem-iconic/index.html deleted file mode 100644 index 8b41b0497e..0000000000 --- a/files/zh-cn/mozilla/tech/xul/style/menuitem-iconic/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: menuitem-iconic -slug: Mozilla/Tech/XUL/Style/menuitem-iconic -translation_of: Archive/Mozilla/XUL/Style/menuitem-iconic ---- -
- « XUL Reference
-
-
- menuitem-iconic
-
- Use this class to have an image appear on the menuitem. Specify the image using the image attribute.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/style/menuitem-non-iconic/index.html b/files/zh-cn/mozilla/tech/xul/style/menuitem-non-iconic/index.html deleted file mode 100644 index c9873b5c31..0000000000 --- a/files/zh-cn/mozilla/tech/xul/style/menuitem-non-iconic/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: menuitem-non-iconic -slug: Mozilla/Tech/XUL/Style/menuitem-non-iconic -translation_of: Archive/Mozilla/XUL/Style/menuitem-non-iconic ---- -
- « XUL Reference
-
-
- menuitem-non-iconic
-
- Normally, menuitems have a margin to the left for an image or checkmark. This class may be used to remove this margin so that the menuitem appears on the left edge of the menupopup.
-
-
-  
-

diff --git a/files/zh-cn/mozilla/tech/xul/tabbox/index.html b/files/zh-cn/mozilla/tech/xul/tabbox/index.html deleted file mode 100644 index c0decfea4f..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tabbox/index.html +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: tabbox -slug: Mozilla/Tech/XUL/tabbox -translation_of: Archive/Mozilla/XUL/tabbox ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

A container used to display a set of tabbed pages of elements. A row of tabs is displayed at the top of tabbox which may be used to switch between each page. The tabbox should contain two children, the first a tabs element which contains the tabs and the second a tabpanels element which contains the contents of the pages.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- eventnode, handleCtrlPageUpDown, handleCtrlTab
-
-
-
- Properties
-
- accessibleType, eventNode, handleCtrlPageUpDown, handleCtrlTab, selectedIndex, selectedPanel, selectedTab, tabs, tabpanels
-
-

Examples

-
<tabbox id="myTabList" selectedIndex="2">
-  <tabs>
-    <tab label="A First tab"/>
-    <tab label="Second tab"/>
-    <tab label="Another tab"/>
-    <tab label="Last tab"/>
-  </tabs>
-  <tabpanels>
-    <tabpanel><!-- tabpanel First elements go here --></tabpanel>
-    <tabpanel><!-- tabpanel Second elements go here --></tabpanel>
-    <tabpanel><button label="Click me"/></tabpanel>
-    <tabpanel><!-- tabpanel Fourth elements go here --></tabpanel>
-  </tabpanels>
-</tabbox>
-
-

Image:XUL_REF_tabboxes.gif

-

Attributes

-

- - -
-
eventnode
-
Type: one of the values below
-
Indicates where keyboard navigation events are listened to. If this attribute is not specified, events are listened to from the tabbox. Thus, if this attribute is not used, the tabbox or an element inside it must have the focus for the keyboard navigation to apply.
-
-
-
parent
-
Keyboard navigation is captured at the parent of the tabbox.
-
window
-
Keyboard navigation is captured at the window level. Tab navigation will occur as long as any element in the window is focused.
-
document
-
Keyboard navigation is captured at the document level. Tab navigation will occur as long as any element in the document is focused.
-
-
-
-
- -
- - -
-
handleCtrlTab
-
Type: boolean
-
If set to true or omitted, the tabbox will switch to the next tab when the Control and Tab keys are pressed. If the Shift key is also held down, the previous tab will be displayed. If this attribute is set to false, these keys do not navigate between tabs.
-
-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

- -
-
eventNode
-
Type: EventTarget
-
Indicates the node where keyboard navigation events listener is set up. The initial value for this property is determined by the value of the eventnode attribute.
-
- -
-
handleCtrlPageUpDown
-
Type: boolean
-
Gets and sets the value of the handleCtrlPageUpDown attribute.
-
- -
-
handleCtrlTab
-
Type: boolean
-
Gets and sets the value of the handleCtrlTab attibute.
-
-
-
- selectedIndex
-
- Type: - - integer -
-
- Returns the index of the currently selected item. You may select an item by assigning its index to this property. By assigning -1 to this property, all items will be deselected.
-
- -

- -
-
selectedPanel
-
Type: element
-
Holds a reference to the currently selected panel within a <tabbox> element. Assigning a value to this property will modify the selected panel. A select event will be sent when the selected panel is changed.
-
- -
-
selectedTab
-
Type: tab element
-
A reference to the currently selected tab, which will always be one of the tab elements in the tabs element. Assign a value to this property to modify the currently selected tab.
-
- -
-
tabs
-
Type: tabs element
-
The tabs element contained within the tabbox.
-
- -
-
tabpanels
-
Type: tabpanels element
-
The tabpanels element contained within the tabbox.
-

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -
-
- Elements
-
- tabs, tab, tabpanels, tabpanel.
-
-

diff --git a/files/zh-cn/mozilla/tech/xul/template_guide/index.html b/files/zh-cn/mozilla/tech/xul/template_guide/index.html deleted file mode 100644 index 9a6ac79352..0000000000 --- a/files/zh-cn/mozilla/tech/xul/template_guide/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Template Guide -slug: Mozilla/Tech/XUL/Template_Guide -translation_of: Archive/Mozilla/XUL/Template_Guide ---- -

Basics of XUL Templates

- -

RDF Template Syntax

- -

XML Template Syntax

- -

SQL Template Syntax

- -

Common Template Syntax

- -

Building Trees with Templates

- -

Template Modifications

- -

Additional Topics

- -

Alternative Approaches

- -

Interwiki Language Links

-

diff --git a/files/zh-cn/mozilla/tech/xul/textbox/index.html b/files/zh-cn/mozilla/tech/xul/textbox/index.html deleted file mode 100644 index 4d032ca259..0000000000 --- a/files/zh-cn/mozilla/tech/xul/textbox/index.html +++ /dev/null @@ -1,653 +0,0 @@ ---- -title: textbox -slug: Mozilla/Tech/XUL/textbox -translation_of: Archive/Mozilla/XUL/textbox ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

An input field where the user can enter text. It is similar to the HTML input element. Only one line of text is displayed by default. The multiline attribute can be specified to display a field with multiple rows.

-

More information is available in the XUL tutorial.

-
-
- Attributes
-
- cols, decimalplaces, disabled, , emptytext, hidespinbuttons, increment, label, max, maxlength, min, multiline, newlines, onchange, oninput, placeholder, preference, readonly, rows, searchbutton, size, spellcheck, tabindex, timeout, type, value, wrap, wraparound
-
-
-
- Properties
-
- accessibleType, clickSelectsAll, decimalPlaces, decimalSymbol, defaultValue, disabled, editor, emptyText, increment, inputField, label, max, maxLength, min, placeholder, readOnly, searchButton, selectionEnd, selectionStart, size, spinButtons, tabIndex, textLength, timeout, type, value, valueNumber, wrapAround
-
-
-
- Methods
-
- decrease, increase, reset, select, setSelectionRange
-
-
-
- Style classes
-
- plain
-
-

Examples

-
- Image:XUL_ref_textbox.png
-
<vbox>
-<label control="your-name" value="Enter your name:"/>
-<textbox id="your-name" value="John"/>
-</vbox>
-
-

Attributes

-

- - -
-
cols
-
Type: integer
-
For multiline textboxes, the number of columns to display.
-
-
- - -
-
decimalplaces
-
Type: integer
-
The number of decimal places to display. The default is 0, which doesn't show any decimal places. The value Infinity may be used if you want no limit on the number of decimal places. Note that decimal numbers are stored as floats.
-
-
- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
emptytext Deprecated since Gecko 2
-
Type: string
-
A string that appears in the textbox when it has no value. This is superseded by the placeholder attribute in Gecko 2.0. The old name is retained for compatibility, but you should update your code.
-
-
- - -
-
hidespinbuttons
-
Type: boolean
-
If true, the number box does not have arrow buttons next to it to allow the user to adjust the value. The value may still be adjusted with the keyboard. The default value is false.
-
-
- -
-
- increment
-
- 类型:整数
-
- 拖动刻度条控件(scale元素)中的拉杆,点击滚动条控件(scrollbar元素)中的箭头(拖动拉杆也可以),点击数字输入框(type属性为numbertextbox元素)中的箭头时,其curpos属性或者value属性每次改变的数字值,默认值为1.
-
-
- - -
-
label
-
Type: string
-
If present and not empty, this will be exposed to screen readers through the label property.
-
-
- -
-
- 类型:整数
-
- 设置刻度条控件(scale元素)或者数字输入框控件(type属性为number的textbox元素)中能输入的最大数字.刻度条控件中,该属性的默认值为100,数字输入框中,该属性的默认值为无穷大.
-
- -

 

-
- - -
-
maxlength
-
Type: integer
-
The maximum number of characters that the textbox allows to be entered.
-
-
- -
-
- min
-
- 类型:整数
-
- 该控件可以有的最小的整数值,默认值为0.
-
-

 

-
- - -
-
multiline
-
Type: boolean
-
If true, the textbox displays multiple lines. If the user presses Enter, a new line is started. If false, the textbox only allows entry of one line.
-
-
- - -
-
newlines
-
Type: one of the values below
-
How the text box handles pastes with newlines in them.
-
Possible values: -
-
pasteintact
-
Paste newlines unchanged
-
pastetofirst
-
Paste text up to the first newline, dropping the rest of the text
-
replacewithcommas
-
Pastes the text with the newlines replaced with commas
-
replacewithspaces
-
Pastes the text with newlines replaced with spaces
-
strip
-
Pastes the text with the newlines removed
-
stripsurroundingwhitespace
-
Pastes the text with newlines and adjacent whitespace removed
-
-
-
-
- - -
-
onchange
-
Type: script code
-
This event is sent when the value of the textbox is changed. The event is not sent until the focus is moved to another element.
-
- - -
- - -
-
oninput
-
Type: script code
-
This event is sent when a user enters text in a textbox. This event is only called when the text displayed would change, thus it is not called when the user presses non-displayable keys.
-
- - -
- - -
-
placeholder
-
Type: string
-
A string that appears in the textbox when it has no value.
-
-
- - -
-
preference
-
Type: id
-
Connects the element to a corresponding preference. This attribute only has any effect when used inside a prefwindow. More information is available in the Preferences System article.
-
-
- - -
-
readonly
-
Type: boolean
-
If set to true, then the user cannot change the value of the element. However, the value may still be modified by a script.
-
-
- -
-
- rows
-
- Type: integer
-
- The number of rows to display in the element. If the element contains more than this number of rows, a scrollbar will appear which the user can use to scroll to the other rows. To get the actual number of rows in the element, use the getRowCount method.
-
-
- - -
-
searchbutton
-
Type: boolean
-
If true, the search field will only fire a command event when the user presses the search button or presses the Enter key. Otherwise, the command event is fired whenever the user modifies the value. This attribute only applies to textboxes with the type search.
-
-
- - -
-
size
-
Type: integer
-
The number of characters that can be displayed in the textbox.
-
-
- - -
-
spellcheck
-
Type: boolean
-
If true, spell checking is enabled by default for the text box; if false, spell checking is disabled by default.
-
If not specified, this defaults to false
-
- -

The HTML

- -
-

The spellcheck attribute uses values of true or false (you cannot simply add the spellcheck attribute to a given element):

- -
<!-- spellcheck everything! -->
-<input type="text" spellcheck="true" /><br />
-<textarea spellcheck="true"></textarea>
-<div contenteditable="true" spellcheck="true">I am some content</div>
-
-<!-- spellcheck nothing! -->
-<input type="text" spellcheck="false" /><br />
-<textarea spellcheck="false"></textarea>
-<div contenteditable="true" spellcheck="false">I am some content</div>
- -

You can use spellcheck on INPUTTEXTAREA, and contenteditable elements.  Thespellcheck attribute works well paired with the autocomplete, autocapitalize, and autocorrect attributes too!

- -

Added from David Walsh's article on Spell Check.

-
-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- - -
-
timeout
-
Type: integer
-
For autocomplete textboxes, the number of milliseconds before the textbox starts searching for completions. The default is 50 milliseconds. For search textboxes, the number of milliseconds before the timer fires a command event. The default is 500 milliseconds. For timed textboxes, the number of milliseconds before the timer fires a command event. There is no default. The timer starts after the user types a character. If the user types another character, the timer resets.
-
-
- - -
-
type
-
Type: one of the values below
-
You can set the type attribute to one of the values below for a more specialized type of textbox. Don't set the type if you wish to use a regular textbox.
-
-
-
autocomplete
-
A textbox that supports autocomplete. For more information about autocomplete textboxes, see the autocomplete documentation (XPFE [Thunderbird/SeaMonkey]) (Firefox)
-
number
-
 A textbox that only allows the user to enter numbers. In addition, arrow buttons appear next to the textbox to let the user step through values. There are several attributes that allow the number textbox to be configured, including decimalplaces, min, max, increment, wraparound, hidespinbuttons, and textbox.value.
-
password
-
A textbox that hides what is typed, used for entering passwords.
-
search
-
 A textbox intended for searching. The command event will fire as the user modifies the value. A listener for the command event should update search results. If the searchbutton attribute is set to true, the command event is only fired if the user presses the search button or presses the Enter key. You may specify grey text to appear when the search box is empty using the emptytext attribute, and a timeout may be set for the command event using the timeout attribute (defaults to 500).
-
timed
-
This textbox will fire a command event after the user types characters and a certain time has passed. The delay is set with the timeout attribute. The command event will fire if the user presses the Enter key. The timed type is deprecated in Gecko 1.9.1 and the search textbox may be used instead.
-
-
-
- - -
- - -
-
value
-
Type: string
-
The default value entered in a textbox. The attribute only holds the default value and is never modified when the user enters text. To get the updated value, use the value property. For number boxes, the default is 0 or the minimum value returned by the min property, whichever is higher.
-
- - -
- - -
-
wrap
-
Type: string
-
Set this attribute to the value off to disable word wrapping in the textbox. If this attribute is not specified, word wrapping is enabled.
-
-
- - -
-
wraparound
-
Type: boolean
-
If true, the value of the number box will wrap around when the maximum or minimum value is exceeded. The minimum and maximum values must both not be infinity.
-
-

-

Properties

-

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

-
-
- clickSelectsAll
-
- Type: boolean
-
- If set to true, the contents of the textbox are selected when focused; otherwise, the cursor is left unchanged.
-
-
-
- decimalPlaces
-
- Type: integer
-
- Gets and sets the value of the decimalplaces attribute.
-
-
-
- decimalSymbol
-
- Type: string
-
- The character used for the decimal place indicator. The default value is a period (.)
-
-
-
- defaultValue
-
- 类型: 字符串
-
- 获取或设置一个textbox元素中显示的默认值.
-
-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

- -
-
editor
-
Type: nsIEditor
-
A reference to the nsIEditor for editable text. This property is read only.
-
- -
-
emptyText Deprecated since Gecko 2
-
Type: string
-
Gets and sets a string that appears in the textbox when it has no value. This is superseded by the  placeholder property in Gecko 2.0. The old name is retained for compatibility, but you should update your code.
-
-
-
- increment
-
- Type: integer
-
- Gets and sets the value of the increment attribute.
-
- -
-
inputField
-
Type: textbox element
-
In Mozilla, the XUL textbox is implemented as a wrapper around an HTML input element. This read only property holds a reference to this inner input element.
-
- -
-
label
-
Type: string
-
Sets the label attribute. Gets the label attribute if it is present and not empty. Otherwise it returns the value of the associated label element, if applicable. Otherwise it returns the placeholder or emptyText property. The getter is mostly useful for screen readers. -
-

Note: Prior to Firefox 3, and always in Thunderbird and SeaMonkey, the label property of an autocomplete textbox returns its value, for compatibility with the menulist element.

-
-
-
-
-
- max
-
- 类型:整数
-
- 获取或设置max特性(attribute)的值.
-
- -
-
maxLength
-
Type: integer
-
The maximum number of characters that the textbox allows to be entered.
-
-
-
- min
-
- Type: integer
-
- Gets and sets the value of the min attribute.
-
- -
-
placeholder
-
Type: string
-
Gets and sets a string that appears in the textbox when it has no value.
-
-
-
- readOnly
-
- Type: boolean
-
- If set to true, then the user cannot modify the value of the element.
-
- -
-
searchButton
-
Type: boolean
-
Gets and sets the value of the searchbutton attribute.
-
- -
-
selectionEnd
-
Type: integer
-
Get or set the end of the selected portion of the field's text. Use in conjuction with the selectionStart property. The value specifies the index of the character after the selection. If this value is equal to the value of the selectionStart property, no text is selected, but the value indicates the position of the caret (cursor) within the textbox.
-
- -
-
selectionStart
-
Type: integer
-
Get or set the beginning of the selected portion of the field's text. Use in conjuction with the selectionEnd property. The value specifies the index of the first selected character.
-
- -
-
size
-
Type: integer
-
Gets and sets the value of the size attribute.
-
-
-
- spinButtons
-
- 类型:spinbuttons元素
-
- 一个只读属性,返回了数字输入框元素(type属性为number的textbox元素)中包含的spinbuttons元素(也就是右侧调整数字大小的上下小箭头).
-
-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

- -
-
textLength
-
Type: integer
-
Holds the length of the text entered in the textbox. This property is read-only.
-
- -
-
timeout
-
Type: integer
-
Gets and sets the value of the timeout attribute.
-
-
-
- type
-
- Type: string
-
- Gets and sets the value of the type attribute.
-
-
-
-
- value
-
- 类型:字符串
-
- 读取或设置该textbox元素中的文本内容.
-
-
-
- valueNumber
-
- Type: number
-
- In contrast to the value property which holds a string representation, the valueNumber property is a number containing the current value of the number box.
-
-
-
- wrapAround
-
- Type: boolean
-
- Gets and sets the value of the wraparound attribute.
-

-

Methods

-

-
- decrease()
-
- Return type: no return value
-
- Decreases the value of the scale or number box by the increment.
-
-
- increase()
-
- 返回值类型: 无返回值
-
- 增大刻度条控件(scale元素)或者数字输入框控件(type属性为number的textbox元素)中的数字值(按照其increment属性指定的值).
-
-
- reset()
-
- 返回值:无返回值
-
- 将用户偏好重置为默认值.
-
-
- select()
-
- Return type: no return value
-
- Selects all the text in the textbox.
-
-
- setSelectionRange( start, end )
-
- Return type: no return value
-
- Sets the selected portion of the textbox, where the start argument is the index of the first character to select and the end argument is the index of the character after the selection. Set both arguments to the same value to move the cursor to the corresponding position without selecting text.
-
-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

-

Style classes

-

The following classes may be used to style the element. These classes should be used instead of changing the style of the element directly since they will fit more naturally with the user's selected theme.

-

-
plain
-
This class causes the element to be displayed with no border or margin.
-

-

Notes

-

The maxlength attribute does not work when in multiline mode. A workaround using JavaScript and the onkeypress event handler as shown in abstract below may be your solution.

-

The XUL script:

-
<textbox id="pnNote" multiline="true" rows="2" cols="70" onkeypress="return pnCountNoteChars(event);"/>
-
-

The Javascript:

-
function pnCountNoteChars(evt) {
-    //allow non character keys (delete, backspace and and etc.)
-    if ((evt.charCode == 0) && (evt.keyCode != 13))
-      return true;
-
-    if(evt.target.value.length < 10) {
-        return true;
-    } else {
-        return false;
-    }
-}
- -
-
- Interfaces
-
- nsIAccessibleProvider, nsIDOMXULTextboxElement
-
-

diff --git a/files/zh-cn/mozilla/tech/xul/toolbarpalette/index.html b/files/zh-cn/mozilla/tech/xul/toolbarpalette/index.html deleted file mode 100644 index 7df0ea3483..0000000000 --- a/files/zh-cn/mozilla/tech/xul/toolbarpalette/index.html +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: toolbarpalette -slug: Mozilla/Tech/XUL/toolbarpalette -translation_of: Archive/Mozilla/XUL/toolbarpalette ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

Firefox only

-

The item is a palette of available toolbar items. It is not displayed, but is used by the toolbar customization dialog to display the list of items. The children of the toolbarpalette should be the complete list of toolbarbuttons and toolbaritems that can be added to the toolbar. Do not add the various spacing items, as those are added automatically.

-

这个控件(item不知道是不是这个意思,下同)是一个调色板控件,它不会显示出来,但是是被工具栏用来个性化对话框从而显示控件列表的。toolbarpalette的子类应该是一个可以被添加入工具栏toolbarbutton和toolbaritem的完整列表。不要加入spacing items,因为它们是被自动添加的。

-

You can add your own custom buttons to the Firefox browser by using an overlay that overlays the toolbarpalette with the idBrowserToolbarPalette.

-

你可以通过overlay来向火狐浏览器添加个性化的按钮,这是通过用BrowserToolbarPalette覆盖toolbarpalette实现的

-

不过个人感觉这个palette好像不怎么用

-

Examples(实例)

-
<toolbarpalette id="BrowserToolbarPalette">
-  <toolbarbutton id="toolbarpalette-button"
-                 class="toolbarbutton-class"
-                 label="&mylabel;"
-                 tooltiptext="&mytiptext;"
-                 oncommand="somefunction()"/>
-</toolbarpalette>
-
-

Attributes

-

- - - - - -

Inherited from XUL element
-align, -allowevents, -allownegativeassertions, -class, -coalesceduplicatearcs, -collapsed, -container, -containment, -context, -contextmenu, -datasources, -dir, -empty, -equalsize, -flags, -flex, -height, -hidden, -id, -insertafter, -insertbefore, -left, -maxheight, -maxwidth, -menu, -minheight, -minwidth, -mousethrough, -observes, -ordinal, -orient, -pack, -persist, -popup, -position, -preference-editable, -querytype, -ref, -removeelement, -sortDirection, -sortResource, -sortResource2, -statustext, -style, -template, -tooltip, -tooltiptext, -top, -uri, -wait-cursor, -width

-

-

Properties

-

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

Methods

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -
-
- Elements(意思应该是这里面含有的元素吧,看样子既然toolbox都在里面说明这个item还是挺大的)
-
- toolbar, toolbarbutton, toolbargrippy, toolbaritem, toolbarseparator, toolbarset, toolbarspacer, toolbarspring, toolbox
-
-

diff --git a/files/zh-cn/mozilla/tech/xul/toolbars/creating_toolbar_buttons/index.html b/files/zh-cn/mozilla/tech/xul/toolbars/creating_toolbar_buttons/index.html deleted file mode 100644 index 363a3b9e2b..0000000000 --- a/files/zh-cn/mozilla/tech/xul/toolbars/creating_toolbar_buttons/index.html +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: 添加工具栏按钮 (定制工具栏) -slug: Mozilla/Tech/XUL/Toolbars/Creating_toolbar_buttons -translation_of: Archive/Mozilla/XUL/Toolbars/Creating_toolbar_buttons ---- -

此文章解释如何使用 overlays 为工具包(firefox,Thunderbird 或 Kompozer) 添加工具栏按钮(就是浏览器右上方一系列按钮,home,下载之类的)。适用用户是拥有 XULCSS 基础知识的 扩展 开发人员。

-

我们假设您已经会创建基础的火狐插件,并且已经成功创建了 Hello World extension ,另外,还有一份更加完全的初学者示例指南,请查看 自定义工具栏按钮。

-

创建一个 overlay

-

The first step is to create an overlay for the document containing the toolbar you wish to enhance. Explaining overlays is beyond the scope of this tutorial -- you can read about them in the XUL Tutorial.

-

To overlay a document, you need to know its URI. You can find a list of URIs for the most commonly overlaid documents at the bottom of this page.

-
- Note: Some people overlay chrome://messenger/content/mailWindowOverlay.xul. That should cause the button to appear on all windows that mailWindowOverlay.xul is applied to (i.e. Main window and View Message window). This needs to be looked into.
-

在工具栏添加按钮

-

Toolkit applications have customizable toolbars; therefore, it's common practice for extensions to add their toolbar buttons to the toolbar palette, rather than adding them directly to the toolbar. The latter is possible but is not recommended and is harder to implement.

-

Adding a button to the toolbar palette is very easy. Just add code like this to your overlay:

-
<toolbarpalette id="BrowserToolbarPalette">
-  <toolbarbutton id="myextension-button" class="toolbarbutton-1"
-    label="&toolbarbutton.label;" tooltiptext="&toolbarbutton.tooltip;"
-    oncommand="MyExtension.onToolbarButtonCommand(event);"/>
-</toolbarpalette>
-
-

注意:

- -
onclick="checkForMiddleClick(this, event)"
- -
<toolbarpalette id="BrowserToolbarPalette">
-  <toolbarbutton id="myextension-button" class="toolbarbutton-1"
-    label="&toolbarbutton.label;" tooltiptext="&toolbarbutton.tooltip;"
-    onclick="MyExtension.onclick(event);"/>
-</toolbarpalette>
-
onclick: function(event) {
-  switch(event.button) {
-    case 0:
-      // Left click
-      break;
-    case 1:
-      // Middle click
-      break;
-    case 2:
-      // Right click
-      break;
-  }
-}
-
-

To add more buttons, put more <toolbarbutton> elements inside the <toolbarpalette> element. Wrap elements other than <toolbarbutton> in <toolbaritem>.

-

为按键应用风格

-

Most toolbar buttons have an icon. To attach an image to the button we use standard Mozilla skinning facilities. If you're unfamiliar with how that works, read the skinning section of Jonah Bishop's excellent Toolbar Tutorial. Although the article covers creating an entire toolbar, rather than just a button, it has a great explanation of the techniques we'll use here.

-

图标大小

-

Toolbar buttons can have two different sizes -- big and small. This means you'll need to provide two icons for each of your toolbar buttons. The dimensions of the icons in various applications for both modes are summarized in the following table (feel free to add information about other applications):

- - - - - - - - - - - - - - - - - - -
Application (Theme name)Big icon sizeSmall icon size
Firefox 1.0 (Winstripe)24x2416x16
Thunderbird 1.0 (Qute)24x2416x16
-

CSS 样式表

-

To set the image for your toolbar button, use the following CSS rules:

-
/*  skin/toolbar-button.css  */
-
-#myextension-button {
-  list-style-image: url("chrome://myextension/skin/btn_large.png");
-}
-
-toolbar[iconsize="small"] #myextension-button {
-  list-style-image: url("chrome://myextension/skin/btn_small.png");
-}
-
-

应用样式表

-

Remember to attach the stylesheet you created to both the overlay file and the Customize Toolbar window. To attach it to the overlay, put this processing instruction (PI) at the top of the overlay file:

-
<?xml-stylesheet href="chrome://myextension/skin/toolbar-button.css" type="text/css"?>
-
-
- Note: The CSS file with your toolbar styles needs to be included in the overlay file, as you would expect, but also in the chrome.manifest file. This is very important because the toolbar customization dialog won't work correctly without this.
-

To include the style on your chrome.manifest file:

-
style chrome://global/content/customizeToolbar.xul chrome://myextension/skin/toolbar-button.css
-
-

If you are developing for Firefox 1.0, attach it to the Customize Toolbar window (chrome://global/content/customizeToolbar.xul) using skin/contents.rdf. The code looks like this:

-
<?xml version="1.0"?>
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
-
-  <Seq about="urn:mozilla:skin:root">
-    <li resource="urn:mozilla:skin:classic/1.0"/>
-  </Seq>
-
-  <Description about="urn:mozilla:skin:classic/1.0">
-    <chrome:packages>
-      <Seq about="urn:mozilla:skin:classic/1.0:packages">
-        <li resource="urn:mozilla:skin:classic/1.0:myextension"/>
-      </Seq>
-    </chrome:packages>
-  </Description>
-
-  <Seq about="urn:mozilla:stylesheets">
-    <li resource="chrome://global/content/customizeToolbar.xul"/>
-  </Seq>
-
-  <Seq about="chrome://global/content/customizeToolbar.xul">
-    <li>chrome://myextension/skin/toolbar-button.css</li>
-  </Seq>
-</RDF>
-
-

The skin/contents.rdf file is denigrated in developing for later releases of Firefox. Extensions for Firefox/Thunderbird 1.5 and above should instead use something like this in their chrome.manifest:

-
skin	myextension	classic/1.0	chrome/skin/
-style	chrome://global/content/customizeToolbar.xul	chrome://myextension/skin/toolbar-button.css
-ia
-

Take note of the Packaging section in this article; you may need to include .jar references if you are delivering your extension as a .xpi file.

-

常见错误

-

This is a list of the most common mistakes made by extension authors, including both symptoms and solutions.

-

Problem: The whole set of default buttons is painted on the toolbar or in the Customize Toolbars window, instead of your own icon.

-

Caused by: Malformed or not applied stylesheet.

-

Solution: Check to be sure your stylesheet is correct, make sure your contents.rdf (or chrome.manifest) is correct, and be sure you didn't forget to apply the stylesheet to customizeToolbar.xul.

-

常见工具栏的 overlayed windows

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
URLApplication and affected window(s)Palette id
chrome://browser/content/browser.xulFirefox - Main windowBrowserToolbarPalette
chrome://navigator/content/navigator.xulSeaMonkey 2.0 - Browser windowBrowserToolbarPalette
chrome://messenger/content/messenger.xulThunderbird - Main windowMailToolbarPalette
chrome://messenger/content/messenger...gercompose.xulThunderbird - Compose windowMsgComposeToolbarPalette
chrome://messenger/content/addressbo...ddressbook.xulThunderbird - Address bookAddressBookToolbarPalette
chrome://editor/content/editor.xulKompozer - Main windowNvuToolbarPalette
chrome://calendar/content/calendar.xulSunbird - Main windowcalendarToolbarPalette
-

更多信息

- diff --git a/files/zh-cn/mozilla/tech/xul/toolbars/custom_toolbar_button/index.html b/files/zh-cn/mozilla/tech/xul/toolbars/custom_toolbar_button/index.html deleted file mode 100644 index 9030e502a8..0000000000 --- a/files/zh-cn/mozilla/tech/xul/toolbars/custom_toolbar_button/index.html +++ /dev/null @@ -1,332 +0,0 @@ ---- -title: 自定义工具栏按钮 -slug: Mozilla/Tech/XUL/Toolbars/Custom_toolbar_button -translation_of: Archive/Mozilla/XUL/Toolbars/Custom_toolbar_button ---- -

此教程教您一步步为 Firefox, SeaMonkey 2.0, Thunderbird 或 Sunbird 制作工具栏按钮 (对于 SeaMonkey 1.x,请查看 Custom Toolbar Button:SeaMonkey.)

-

你不需要任何技巧和工具,所以需要的信息全部在本页。

-

 

-

介绍

-

本页所述技术不包括任何黑科技。你可以自己定制属于自己的扩展。

-

适用示例上的代码可以制作出很多很有用的按钮,如果你懂得 JS 编程,你可以自己编代码,实现更多其他功能。

-

如果你需要创建一个具某项功能的按钮,那么你来对地方了

-

在此页你也能学到扩展程序的基础知识,有利于将来写更复杂的插件。注意,扩展程序非常简单,你或许得查看其他教程,那么-主 扩展 页就是您该去的地方。另外, 创建工具栏按钮 这篇文章(译注:建议先看本文再看这个,那里面有几句没说清楚该放哪去)和 创建一个扩展 更好的展示了创建过程。

-

支持的程序

-

本文中步骤适用于下列 Mozilla 应用:

- -

提前发行版一般都支持 (alphas, betas 和 release candidates) 。

-

译注:本文的例子适用于很多Mozilla 开发的应用程序,原文用Application 代表这些程序,所以我按照原文翻译成了应用/程序,所以如果将来遇到应用/程序等字样,就是指Firefox 等。

-
-

Note:  There is a similar tutorial for SeaMonkey 1.x on the page: Custom Toolbar Button:SeaMonkey

-

Earlier versions and other Mozilla applications also support extensions, but some parts of this tutorial are not appropriate for them.

-
-

所需工具

-

需要两个工具,系统一般都默认提供了:

- -
字符编码
-

有些文本编辑器有调整字符编码的选项。

-

如果你使用拉丁 (ASCII) 字符,那就将你的文本编辑器设为除 Unicode 外的任意编码

-

如果你的语言包含非拉丁字符,那保存文件时请选择 UTF-8 编码。

-

要想测试编辑器,新建一个文件test.txt。在文件中输入属于您语言的文字,然后保存。

-

使用火狐打开此文件,(例如,直接将文件拖动到火狐上,或在菜单中选择 文件 – 打开文件)。

-

在火狐的菜单栏中,选择 查看– 字符编码 – Unicode (UTF-8)。然后看在此设置下,文本中的文字是否能正常显示。

-

如果你的文本编辑器不支持 UTF-8,自己上网搜索装一个。

-

可选工具

-

可以使用任意图像编辑器编辑图片。

-

可以使用 jar 工具或 zip 工具将此按钮项目压缩成跨平台的安装文件 (XPI),方便别人安装使用。

-

制作一个按钮

-

按照下面10步完成

-

完成所有步骤后,文件夹结构应该如下图所示:

-
-
- Directory and file structure
-
-

 profile 和 extensions 文件夹已存在,需要添加图中其他的文件和文件夹(当然此目录下可能还会有其他文件,只是没显示.)

-
-
- 1.
- 前往应用程序的配置文件夹,然后找到extensions 文件夹。 -

注意:  至于如何找到配置文件夹,请查看:配置文件夹

-

说明:  配置文件夹包含用户指定的设置,和主程序分开存放。所以程序重装或升级之后,这些信息不受影响。

-
- 2.
- 在 extensions 文件夹中,创建一个文件夹,名称如下: -

建议直接复制粘贴,以免出错

-
-
- custom-toolbar-button@example.com
-
-

按照后面的步骤,创建两个文件和一个文件夹。

-

说明:  此文件夹名称是用于区分不同扩展程序的唯一标识符。在稍后的部分会有详细的标识符。

-
- 3.
- 创建一个文本文档,名称为 install.rdf. -

完整复制下面内容,粘贴到文档中:

-
<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description
-    about="urn:mozilla:install-manifest"
-
-    em:name="Custom Button"
-    em:description="My custom toolbar button"
-    em:creator="My name"
-
-    em:id="custom-toolbar-button@example.com"
-    em:version="1.0"
-    em:homepageURL="http://developer.mozilla.org/en/docs/Custom_Toolbar_Button"
-
-    em:iconURL="chrome://custombutton/content/icon.png" >
-
-    <em:targetApplication><!-- Firefox -->
-      <Description
-        em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
-        em:minVersion="1.4"
-        em:maxVersion="99" />
-    </em:targetApplication>
-
-    <em:targetApplication><!-- Thunderbird -->
-      <Description
-        em:id="{3550f703-e582-4d05-9a08-453d09bdfdc6}"
-        em:minVersion="1.4"
-        em:maxVersion="99" />
-    </em:targetApplication>
-
-    <em:targetApplication><!-- Sunbird -->
-      <Description
-        em:id="{718e30fb-e89b-41dd-9da7-e25a45638b28}"
-        em:minVersion="0.2.9"
-        em:maxVersion="99" />
-    </em:targetApplication>
-
-    <em:file>
-      <Description
-        about="urn:mozilla:extension:custombutton"
-        em:package="content/custombutton/" />
-    </em:file>
-
-  </Description>
-
-</RDF>
-
-

可选:改变 name, description 和 creator。改变这三行中双引号间的文字即可

-

根据需求,移除不需要的软件说明部分(译注:假如你只想给firefox创建插件,那么就可以删掉别的部分)。

-

保存文件

-

说明:  此文件包含应用程序扩展管理器需要的信息。target applications这一大段表示能运行扩展程序的应用以及版本号。 最后一段描述此插件会添加内容到应用程序。

-
- 4.
- 创建一个文本文档,名称为 chrome.manifest. -

完整复制下面内容,粘贴到文档中:

-
content custombutton chrome/
-style chrome://global/content/customizeToolbar.xul chrome://custombutton/content/button.css
-
-# Firefox
-overlay	chrome://browser/content/browser.xul chrome://custombutton/content/button.xul
-
-# Thunderbird mail
-overlay	chrome://messenger/content/messenger.xul chrome://custombutton/content/button.xul
-
-# Thunderbird compose
-overlay	chrome://messenger/content/messengercompose/messengercompose.xul chrome://custombutton/content/button.xul
-
-# Thunderbird address book
-overlay	chrome://messenger/content/addressbook/addressbook.xul chrome://custombutton/content/button.xul
-
-# Sunbird
-overlay	chrome://calendar/content/calendar.xul chrome://custombutton/content/button.xul
-
-

移除不需要的部分(同上段说明)。

-

保存文件

-

说明:  此文件定义扩展的内容结构。先给工具栏窗口应用一个样式表。然后给每个工具栏都指定一个 overlay 。

-
- 5.
- 创建文件夹: chrome. -

按照下放说明,创建 5 个文件。

-

说明:   chrome 文件夹包含扩展的可执行部分,即扩展是干什的。

-
- 6.
- 创建一个文本文档,名称为 button.xul. -

完整复制下面内容,粘贴到文档中:

-
<?xml version="1.0" encoding="UTF-8"?>
-<?xml-stylesheet type="text/css"
-  href="chrome://custombutton/content/button.css"?>
-
-<!DOCTYPE overlay >
-<overlay id="custombutton-overlay"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<script type="application/javascript"
-  src="chrome://custombutton/content/button.js"/>
-
-<!-- Firefox -->
-<toolbarpalette id="BrowserToolbarPalette">
-  <toolbarbutton id="custom-button-1"/>
-  </toolbarpalette>
-
-<!-- Thunderbird mail -->
-<toolbarpalette id="MailToolbarPalette">
-  <toolbarbutton id="custom-button-1"/>
-  </toolbarpalette>
-
-<!-- Thunderbird compose -->
-<toolbarpalette id="MsgComposeToolbarPalette">
-  <toolbarbutton id="custom-button-1"/>
-  </toolbarpalette>
-
-<!-- Thunderbird address book -->
-<toolbarpalette id="AddressBookToolbarPalette">
-  <toolbarbutton id="custom-button-1"/>
-  </toolbarpalette>
-
-<!-- Sunbird -->
-<toolbarpalette id="calendarToolbarPalette">
-  <toolbarbutton id="custom-button-1"/>
-  </toolbarpalette>
-
-
-<!-- button details -->
-<toolbarbutton id="custom-button-1"
-  label="Custom"
-  tooltiptext="My custom toolbar button"
-  oncommand="CustomButton[1]()"
-  class="toolbarbutton-1 chromeclass-toolbar-additional custombutton"
-  />
-
-</overlay>
-
-

可选:你可以自定义最后一块中的 label 和 tooltiptext 。更改双括号间的内容即可。

-

可选地,移除不需要的部分。。

-

保存文件。

-

说明: XUL 文件会添加一个按钮到应用程序的 toolbar customization palette。此文件还链接了CSS样式表 和 JavaScript 脚本。最后一部分描述按钮的信息(译注;就是按钮名+鼠标放上面会提示什么文字)

-
- 7.
- 创建一个文本文档,名称为: button.css. -

完整复制下面内容,粘贴到文档中:

-
#custom-button-1,
-#wrapper-custom-button-1
-  {list-style-image: url("chrome://custombutton/content/button-1.png");}
-
-/* common style for all custom buttons */
-.custombutton
-  {-moz-image-region: rect( 0px 24px 24px  0px);}
-
-.custombutton:hover
-  {-moz-image-region: rect(24px 24px 48px  0px);}
-
-[iconsize="small"] .custombutton
-  {-moz-image-region: rect( 0px 40px 16px 24px);}
-
-[iconsize="small"] .custombutton:hover
-  {-moz-image-region: rect(24px 40px 40px 24px);}
-
-

没有什么能优化的,保存文件即可

-

说明: CSS 样式表定义按钮如何显示。它链接到了按钮图片,指定了图片四个部分的尺寸。(译注;这里你就可以看文章开头提到的文章了,比这里举的例子更好实现,你只需在css中指定一大一小两个图片即可)

-
- 8.
- 创建一个文本文档,名称为: button.js. -

完整复制下面内容,粘贴到文档中:

-
-
CustomButton = {
-
-1: function () {
-  alert("Just testing")
-  },
-
-}
-
-
-

没有什么能优化的,保存文件即可

-

接下来一部分的教程包含几个实例代码,你可以用他们来实现有用的功能。

-

说明:  此文件指定当按钮按下时执行什么操作。它使用  JavaScript 语言,加应用自己提供的一些特性。

-
- 9.
- 下载按钮图片。 -

右击图片,另存为,保存到 chrome 目录下。请确保文件名为: button-1.png

-
- button-1.png
-

说明:  此图片包含四个部分。左上方是常用的图标。左下是深色的,按下按钮后显示,右侧的是小图标,工具栏设置成使用小图标时需要用。

-
- 10.
- 下载扩展的图片。 -

右击图片,另存为,保存到 chrome 目录下。请确保文件名为:icon.png

-
- icon.png
-

说明:  此图片显示在应用扩展管理窗口中。

-
-

测试您的按钮

-

重启应用程序(firefox)

-

右击工具栏,选中定制,或者在菜单中,依次选择:查看 – 工具栏 – 定制

-

将刚才的新按钮拖动到工具栏,点击“退出定制”保存设置。

-

点击按钮,应该能看到弹出信息了。

-

进一步开发

-

此部分描述如何进一步开发按钮。

-

卸载按钮

-

如果想卸载按钮,删掉步骤 2 创建的文件夹即可。

-

或者,使用程序自己的 扩展管理窗口 正常卸载应用,在下次重启时应用就会删掉此文件夹。

-

重启程序

-

排错

-

如果按钮没在工具栏中显示,或是其他问题,可以按照下列步骤排查。

-

如果有必要,卸载按钮,重头开始,这次不要修改任何内容

-

在能成功让按钮工作后,小心的修改文件。

-

要想看到修改后的结果,需要重启应用。

-
高级排错
-

如果你有一定的技术只是,那么你可以使用应用程序的 JavaScript console 查看错误信息。但是不一定都有用,而且易混淆,或是看到了其他程序的执行结果。

-

在 工具栏 - 开发者(web developer) - Browser Console 中开启 JS 选项。或使用快捷键"Ctrl + Shift + J"

-

 JavaScript console 里会显示 JavaScript, XUL 或 CSS 文件的信息。

-
- Note: The preference setting javascript.options.strict imposes restrictions that are not appropriate for the simple scripts in this tutorial. If you choose to use this setting, either ignore the warnings that it generates, or change the coding style to keep it quiet.
-

为按钮编程

-

要想改变按钮功能,去修改步骤 8 里的 button.js

-

移除行: alert("Just testing") ,替换成其他 js 语句。

-

可以在 Code Samples 查看很多代码示例,不用知道编程知识就能修改并使用。

-

需要重启才能生效变更。

-

添加更多的按钮

-

要想添加更多的按钮,请编辑 button.xul 文件,对于每个应用,复制指定 custom-button-1 的那行,然后将新行指定成 custom-button-2

-

重复最后一部分。在 idoncommand 参数中,将 1 改为 2。然后改变 labeltooltiptext不要改变 class 参数。

-

然后编辑 button.css。复制前三行,改变新行成为 button-2.

-

编辑 button.js 为新按钮添加 js 语句。请确保添加的语句在最后一个花括号的前面,例如,这么添加命令:

-
2: function () {
-  alert("Just testing again")
-  },
-
-

为新按钮创建图标,命名为 button-2.png。下面提供的文件有40 像素宽,48像素高,256色,透明背景,PNG格式,其他格式也能工作。

-

你可以下载使用下列图片:

-
- button-2.png
-
- button-3.png
-
- button-4.png
-
- button-5.png
-

重启程序,并将新按钮添加到工具栏。

-

你可以重复这些步骤,创建更多按钮

-

将您的按钮分发给其他用户

-

如果你想将按钮程序分发给他人,那就必须做些修改以和其他扩展程序做区分。

-

创建一个扩展 ID,格式为:

-
-
- something@domain-name
-
-

必须包含at符号 (@),格式和邮箱地址挺像,但不必是真实邮箱地址。@符号的前后,只能使用字符 : A-Z, a-z, 0-9, 英文句号( . ), 连字符(-)和下划线(_)。如果您没有域名(domain-name),可以自己编个,如果你想让这域名看着不像真正的域名,那就在结尾加个 .invalid

-

使用你的 扩展ID (extension ID)重命名文件夹,然后在 install.rdf 文件中指定相同的 ID。

-

在 install.rdf 文件中,移除您扩展不能正常工作的应用项。例如,如果您的按钮只能在 Thunderbird 上运行,就删除 Firefox 和 Sunbird 的部分。同样道理,修改 button.xulchrome.manifest.

-

改变所有文件中的 "custombutton", "custom-button" 和 "CustomButton" 字样。

-

可以自己更改的:

- -

使用 jar 工具或 zip 工具打包整个文件夹的内容命名为 .xpi 文件。方便用于其他程序。

-

用户可在应用程序的扩展管理窗口中安装此 XPI 文件。

diff --git a/files/zh-cn/mozilla/tech/xul/toolbars/index.html b/files/zh-cn/mozilla/tech/xul/toolbars/index.html deleted file mode 100644 index b028d9cd69..0000000000 --- a/files/zh-cn/mozilla/tech/xul/toolbars/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Toolbars -slug: Mozilla/Tech/XUL/Toolbars -tags: - - NeedsTranslation - - TopicStub -translation_of: Archive/Mozilla/XUL/Toolbars ---- -

Toolbars, implemented using the XUL toolbar element, are containers for toolbar buttons and other user interface objects. The following articles provide details about implementing and working with toolbars.

- - - - - - - -
-

Documentation

-
-
XUL School: Adding Toolbars and Toolbar Buttons
-
A helpful tutorial to creating toolbars and toolbar buttons.
-
Toolbar customization events
-
A look at the events that are sent during toolbar customization; you can use these to be kept aware of changes to toolbars.
-
Creating toolbar buttons
-
How to use overlays to add toolbar buttons to Mozilla applications.
-
Custom toolbar button
-
Another example of how to create a toolbar button, complete with a sample extension you can download and try.
-
Code snippets: Toolbar
-
Code snippets that are helpful when working with toolbars.
-
-
-

View all pages tagged with "Toolbars"...

-
-

Community

- -

Tools

- -

... more tools ...

- - - -
diff --git a/files/zh-cn/mozilla/tech/xul/toolbox/index.html b/files/zh-cn/mozilla/tech/xul/toolbox/index.html deleted file mode 100644 index 4417170b3e..0000000000 --- a/files/zh-cn/mozilla/tech/xul/toolbox/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: toolbox -slug: Mozilla/Tech/XUL/toolbox -translation_of: Archive/Mozilla/XUL/toolbox ---- -

This page has no content. Enrich MDC by contributing.

diff --git a/files/zh-cn/mozilla/tech/xul/tree/index.html b/files/zh-cn/mozilla/tech/xul/tree/index.html deleted file mode 100644 index 7e2de0b669..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tree/index.html +++ /dev/null @@ -1,512 +0,0 @@ ---- -title: tree -slug: Mozilla/Tech/XUL/tree -translation_of: Archive/Mozilla/XUL/tree ---- -
- « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
- -

tree是用来显示表格或层级行元素的容器。 包含若干行 (rows )和列(columns)。树的每行包含若干缩进显示的子行(child rows)。 和其他元素不同的是,用来显示的数据不是通过标签(tags),而是通过一个显示对象(view object)来确定的。这个显示对象(view object)实现了接口 nsITreeView . The view is queried for the data to appear in the tree. 树的使用有以下几种方法, 第二列列出了通过树的 view属性(property)的可用的接口. 第三列指示treeitem 元素是否使用.

- -

If you would like to allow the tree to be horizontally scrolled, simply set the width attributes for each column to make the tree wider than its containing object.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tree typeView interfacesHas DOM nodes?Description
Content treensITreeView, nsITreeContentViewYesThis tree has treeitem elements placed within the treechildren element. In this situation, a content view (which implements the interface nsITreeContentView) which is a more specialized type of view, uses the treeitem elements and their descendants to determine the data to display in the tree. However, the treeitems are not displayed directly; they are used only as data to the content view. However, the content view will automatically update the tree if treeitems are changed.
RDF treensITreeView, nsIXULTreeBuilderNoThis tree is generated from an RDF datasource. It is used when a tree has a datasources attribute, and has dont-build-content in its flags attribute. For this tree, the data comes directly from the RDF datasource. DOM treeitems are not created. Even though the template uses treeitem elements to define the content, DOM nodes for these elements are not created. This is the type that should be used for RDF generated trees with lots of rows.
RDF content treensITreeView, nsIXULTreeBuilder, nsITreeContentViewYesThis tree is generated from an RDF datasource. It is similar to the previous type but is used when the tree does not have dont-build-content in its flags attribute. DOM treeitems are created, so you can access the data using RDF functions or DOM functions. This type is suitable for RDF generated trees with a fairly small number of rows.
Custom tree viewnsITreeViewNoFor this tree you implement the nsITreeView interface yourself. The tree's data is retrieved from this custom view. The custom view should be attached to the tree by setting its view property.
- -

More information is available in the XUL tutorial. Also Tree Widget Changes.

- - - - - - - -
Relevant accessbility guidelines - -
    -
  • Provide alternative access (e.g., via menus) to column picker and for header behaviors like sorting (these have no default keyboard access).
  • -
-
- -
-
Attributes
-
disableKeyNavigation, disabled, editable, enableColumnDrag, flags, hidecolumnpicker, onselect, rows, seltype, statedatasource, tabindex, treelines
-
- -
-
Properties
-
accessibleType, builderView, columns, contentView, currentIndex, disableKeyNavigation, disabled, editingColumn, editingRow, enableColumnDrag, firstOrdinalColumn, inputField, selType, selstyle, tabIndex, treeBoxObject, view
-
- -

Examples

- -

A tree with several columns

- -
<tree flex="1" rows="2">
-
-  <treecols>
-    <treecol id="sender" label="Sender" flex="1"/>
-    <treecol id="subject" label="Subject" flex="2"/>
-  </treecols>
-
-  <treechildren>
-    <treeitem>
-      <treerow>
-        <treecell label="joe@somewhere.com"/>
-        <treecell label="Top secret plans"/>
-      </treerow>
-    </treeitem>
-    <treeitem>
-      <treerow>
-        <treecell label="mel@whereever.com"/>
-        <treecell label="Let's do lunch"/>
-      </treerow>
-    </treeitem>
-  </treechildren>
-
-</tree>
-
- -
Image:trees1.png
- -

A tree with several columns and nested items

- -
<tree id="myTree" flex="1" hidecolumnpicker="false" seltype="single" class="tree"
-      rows="5">
-  <treecols id="myTree2-treeCols">
-    <treecol id="myTree2-treeCol0" primary="true" flex="2" label="Column A"
-             persist="width" ordinal="1"/>
-    <splitter class="tree-splitter" ordinal="2"/>
-    <treecol id="myTree2-treeCol1" flex="1" label="Column B"
-             persist="width" ordinal="3"/>
-  </treecols>
-  <treechildren>
-    <treeitem>
-      <treerow>
-        <treecell label="1"/>
-        <treecell label="a"/>
-      </treerow>
-    </treeitem>
-    <!-- Make sure to set container="true" -->
-    <treeitem container="true" open="true">
-      <treerow>
-        <treecell label="2"/>
-        <treecell label="b"/>
-      </treerow>
-      <treechildren>
-        <treeitem>
-          <treerow>
-            <treecell label="2a"/>
-            <treecell label="ba"/>
-          </treerow>
-        </treeitem>
-      </treechildren>
-    </treeitem>
-  </treechildren>
-</tree>
-
- -

Attributes

- -

- - -
-
disabled
-
 
-
-
类型:boolean
-
-
-
表示元素是被禁用的。
- -

如果这个元素的disabled属性被设置为true,表示元素被禁用,被禁用的属性在页面上通常会显示灰色文本,它无法响应用户的操作,它也无法得到光标。

- -

然而,这个元素仍然能够响应鼠标事件,如果要启用这个元素,把disabled设置为false

-
-
- -

示例:

- -
Image:XUL_ref_attr_disabled.png
- -
// Disabling an element
-document.getElementById('buttonRemove').setAttribute("disabled", "true");
-
-// Enabling back an element by removing the "disabled" attribute
-document.getElementById('buttonRemove').removeAttribute("disabled");
- -

-

Firefox 3.5 note

-

For keyset elements, support for this attribute was added in Firefox 3.5.

-

-
- - -
-
disableKeyNavigation
-
Type: boolean
-
If this attribute is not used, the user can navigate to specific items within the element by pressing keys corresponding to letters in the item's label. This is done incrementally, so typing more letters with select more specific items. This feature may be disabled by setting this attribute to true.
-
-
- - -
-
editable
-
Type: boolean
-
Indicates that the cells of the tree may be edited.
-
-
- - -
-
enableColumnDrag
-
Type: boolean
-
When set to true, the user may drag the column headers around to change the order in which they are displayed.
-
-
- - -
-
flags
-
Type: space-separated list of the values below
-
A set of flags used for miscellaneous purposes. Two flags are defined, which may be the value of this attribute. -
    -
  • dont-test-empty: For template generated content, the builder will not check that a container is empty.
  • -
  • dont-build-content: This flag may be used on a tree to indicate that content elements should not be generated. This results in a performance enhancement, but you will not be able to use the DOM functions to retrieve the tree rows.
  • -
-
-
-
- - -
-
hidecolumnpicker
-
Type: boolean
-
When set to false, a drop-down will appear in the upper right corner of the tree, which the user may use to show and hide columns. When set to true, the column picker will be hidden. The default value is false.
-
-
- - -
-
onselect
-
Type: script code
-
This event is sent to a tree when a row is selected, or whenever the selection changes. The user can select multiple rows by holding down Shift or Control and clicking on a row. The onselect event will be sent for each item added to or removed from the selection.
-
- - -
- -
-
- rows
-
- Type: integer
-
- The number of rows to display in the element. If the element contains more than this number of rows, a scrollbar will appear which the user can use to scroll to the other rows. To get the actual number of rows in the element, use the getRowCount method.
-
-
- - -
-
seltype
-
Type: one of the values below
-
Used to indicate whether multiple selection is allowed.
-
-
-
single
-
Only one row may be selected at a time. (Default in listbox and richlistbox.)
-
multiple
-
Multiple rows may be selected at once. (Default in tree.)
-
-
-
-

For trees, you can also use the following values:

- -
-
cell
-
Individual cells can be selected
-
text
-
Rows are selected; however, the selection highlight appears only over the text of the primary column.
-
- -

For richlistbox, this is new in Firefox 3.5.

-
-
-
- - -
-
statedatasource
-
Type: URI
-
Chrome XUL may specify an RDF datasource to use to store tree state information. This is used to hold which tree items are open and which items are collapsed. This information will be remembered for the next time the XUL file is opened. If you do not specify this attribute, state information will be stored in the local store (rdf:local-store).
-
-
- - -
-
tabindex
-
Type:integer
-
当用户按下 "tab" 键时焦点移动到元素上的顺序。tabindex 数字越大,顺序越靠后。
-
- - - -

-
- -
treelines
-
Type: boolean
When set to true, lines are drawn connecting the lines in the tree; when false, the lines are not drawn. This is false by default.
-
-

- -

Properties

- -

-
-
- accessibleType
-
- Type: - - integer -
-
- A value indicating the type of accessibility object for the element.
-
- -

- -
-
builderView
-
Type: nsIXULTreeBuilder
-
A reference to the tree builder which constructed the tree data. The builder provides access to the RDF resources for each row in the tree, and allows sorting the data by column. In newer versions of Mozilla, the builderView property is actually a synonym for the view property, since the two interfaces are flattened together into a single interface in JavaScript. This property is read-only.
-
-
-
- columns
-
- Type: nsITreeColumns
-
- Returns the columns for the tree as an nsITreeColumns object.
-
-
-
- contentView
-
- Type: nsITreeContentView
-
- For trees built with a content builder - that is, those that do not have flags set -- the contentView will be a reference to the nsITreeContentView for the tree. This interface lets you retrieve the DOM element corresponding to a given a row index and vice versa. For trees that are not built with a content builder, the functions of nsITreeContentView will not be available, since there are no DOM nodes to retrieve. In newer versions of Mozilla, the contentView property is actually a synonym for the view property, since the two interfaces are flattened together into a single interface in JavaScript. This property is read-only.
-
-
-
- currentIndex
-
- Type: integer
-
-

Set to the row index of the tree caret in the tree. For trees with focus, the caret's position is indicated by the focus ring, but unfocused trees won't show  a focus ring, naturally. For unfocused trees, the (undrawn) caret's position can still be obtained by this property. If the caret isn't present for any row (for example, because the tree has never been focused), the value will be -1.

-

You cannot rely on this property to change or determine a tree selection, except for trees with seltype="single". (All trees have seltype="multiple" by default.) To reliably change or determine a selection, instead use the nsITreeSelection interface methods available via tree.view.selection.

-
-
-
-
-
- disabled
-
- Type: - - boolean -
-
- Gets and sets the value of the disabled attribute.
-
- -

-
-
disableKeyNavigation
-
Type: boolean
-
Gets or sets the value of the disableKeyNavigation attribute.
-
- -
-
editingColumn
-
Type: nsITreeColumn
-
The column of the tree cell currently being edited, or null if there is no cell being edited.
-
- -
-
editingRow
-
Type: integer
-
The row index of the tree cell currently being edited, or -1 if there is no cell currently being edited.
-
- -
-
enableColumnDrag
-
Type: boolean
-
When set to true, the user may drag the column headers around to change the order in which they are displayed.
-
- -
-
firstOrdinalColumn
-
Type: treecol element
-
A reference to the first treecol element, which or may not be the first column displayed in the tree.
-
- -
-
inputField
-
Type: textbox element
-
Read-only property that holds the textbox that is used for editing.
-
-
-
- selType
-
- Type: string
-
- Gets and sets the value of the seltype attribute.
-
-

 

-
-
- selstyle
-
- Type: string
-
- If set to the value primary, only the label of the primary column will be highlighted when an item in the tree is selected. Otherwise, the entire row will be highlighted. To see the difference, compare the selection style in the folder list and the message list in Mozilla mail.
-
-
-
- tabIndex
-
- Type: - - integer -
-
- Gets and sets the value of the tabindex attribute.
-
- -

- -
-
treeBoxObject
-
Type: nsITreeBoxObject
-
The box object is responsible for rendering the tree on the window. This object implements the nsITreeBoxObject interface and contains functions for retrieving the cells at certain coordinates, redrawing cells and scrolling the tree. This property is equivalent to the boxObject property.
-
-
-
- view
-
- Type: nsITreeView
-
- The view for the tree, which is the object which generates the data to be displayed. You can assign an object which implements nsITreeView to this property. Trees built from RDF or those which use treeitems directly will already have a view. Functions available in the view allow one to retrieve the data within the cells, and determine which rows are nested within others. For a complete list of view functions, see the nsITreeView interface.
-

- -

Methods

- -

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

-
startEditing( row, column )
-
Return type: no return value
-
Activates user editing of the given cell, which is specified by row index number and the nsITreeColumn in which it is located. The tree view's nsITreeView.getCellText() method is called to obtain the cell contents.
-
-
stopEditing( shouldaccept )
-
Return type: no return value
-
Stops editing the cell currently being edited. If the shouldAccept parameter is true, the cell's label is changed to the edited value (the tree view's nsITreeView.setCellText() method is called to change the cell contents). Otherwise the cell label is reverted to the value it had prior to editing.
-

- - - -
-
Elements
-
treecols, treecol, treechildren, treeitem, treerow, treecell and treeseparator.
-
Interfaces
-
nsIAccessibleProvider, nsIDOMXULTreeElement, nsIDOMXULMultiSelectControlElement
-
- -

Script Examples

- -

To have alternating colors for each row, use the style rules like the following: pma at daffodil dot uk dot com

- -
treechildren::-moz-tree-row(selected) { background-color: #FFFFAA; }
-treechildren::-moz-tree-row(odd) { background-color: #EEEEEE; }
-treechildren::-moz-tree-row(odd, selected) { background-color: #FFFFAA; }
-treechildren::-moz-tree-cell-text(selected) { color: #000000; }
-treechildren::-moz-tree-cell-text(odd, selected) { color: #000000; }
-
- -

If using a content tree view, use the following to get the value of the id attribute for each of the selected rows of a tree: tcooper_mont at yahoo dot com

- -
var idList = [];
-var rangeCount = tree.view.selection.getRangeCount();
-for (var i = 0; i < rangeCount; i++)
-{
-   var start = {};
-   var end = {};
-   tree.view.selection.getRangeAt(i, start, end);
-   for(var c = start.value; c <= end.value; c++)
-   {
-      idList.push(tree.view.getItemAtIndex(c).firstChild.id);
-   }
-}
-
- -

The following returns a array of the indicies of the rows where the value is checked in a checkbox type column: jfabre at ismans dot fr

- -
function getCellChecked(tree, columnid)
-{
-  var arr = [];
-  var column = tree.columns.getNamedColumn(columnid);
-  for (var i = 0; i < tree.view.rowCount; i++){
-    if (tree.view.getCellValue(i, column) == 'true')
-      arr.push(i);
-  }
-  return arr;
-}
-
- -

To get the text value for a specific column (e.g. column 'age') from the currently focused row in the tree:

- -
var t = document.getElementById('mytree');
-document.title = t.view.getCellText(t.currentIndex,t.columns.getNamedColumn('age'));
-
- -

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/adding_buttons/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/adding_buttons/index.html deleted file mode 100644 index 607e4d0abc..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/adding_buttons/index.html +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: XUL_教程/增加一些按钮 -slug: Mozilla/Tech/XUL/Tutorial/Adding_Buttons -tags: - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/Adding_Buttons ---- -

 

-

-

« 上一页下一页 »

-

-

 

-

在本章,我们将学习如何向window添加button。

-

添加多个按钮到一个窗口

-

到目前为止我们创建的这个窗口里面什么也没有,因此还不算非常有趣. 在这一节中,我们将添加两个按钮, 一个“查找”按钮和一个“取消”按钮.我们还将学到一个简单的方法在窗口上来定位它们.

-

像HTML, XUL也有许多标记,它们被用来当作创建用户接口的元素. 最基本的一个 button 标记. 这个元素被用来创建简单的按钮。

-

按钮元素有两个主要的属性,一个label和一个image。你可以要一个或两个都要。因此,按钮可以只有一个标签,一个图片或标签和图片都有。通常在对话框中会使用“确定”和“取消”按钮。

-

按钮的语法

-

button标签有下面的语法要求:

-
<button
-    id="identifier"
-    class="dialog"
-    label="OK"
-    image="images/image.jpg"
-    disabled="true"
-    accesskey="t"/>
-
-

可用的属性如下,有一些是可选的:

-
-
- id 
-
- 你用来标识按钮的唯一标识。你会在所有的元素中看到此属性。你可以在样式表(style)或脚本(script)中通过它来引用按钮。因此,你几乎可以在所有的元素中添加这个属性。在这个教程中它不是一直都出现在元素中(It isn't always placed on elements in this tutorial for simplicity)。
-
- class 
-
- 按钮的样式表。在这里的用法和在HTML中是一样的。它是使用在显示按钮里面的样式。在这节中的dialog值就使用了。多数情况下,你不用在按钮上使用此属性。
-
- label 
-
- 标签会显示在按钮上。例如,“确定”或者“取消”。如果没人设置这个参数,在按钮上就不会显示文字。
-
- image 
-
- 在按钮上显示指定路径的图片。如果没有给出此属性,则不会显示图片。你通常可以使用如下的样式表属性list-style-image来指定要显示的图片。
-
- disabled 
-
- 如果这个属性被设置为true,按钮就会被禁用。这样通常按钮上的文字将会显示为灰色(grey)。如果按钮被禁用,按钮上的功能就不可以被执行。如果这个属性没有设置,按钮就是启用的。你可以用JavaScript来对按钮的可用状态进行控制。
-
- accesskey 
-
- 这个属性让你可以设置一个字母它的功能就像是一个快捷键。这个字母会被划上下划线并显示在标签里。当用户按ALT键(或者在每个平台中一个功能类似的键)的同时按下这里设置的键时,不论按钮在窗口的任何地方都能取得到焦点。
-
-

注释:按钮支持比上面列出的更多的属性。其他的属性可以参考 discussed later.

-

更多的按钮例子

-

Example 1 : Source View

-
- image:Buttons1.png
-
<button label="Normal"/>
-<button label="Disabled" disabled="true"/>
-
-

上面的这些例子是在图片里面生成按钮。第一个按钮是一个标准的按钮。第二个按钮是禁用的,所以它整个显示为灰色。

-

注:label属性不应该指定中文名称,否则解析xul时会报错。对于本地化,应该通过locale包来完成。

-

我们将从为查找文件工具创建一个简单的查找按钮开始。下面这个例子的源码显示怎么去做这件事。

-
<button id="find-button" label="Find"/>
-
-
- 注释:Firefox不允许你从网页上打开chrome,因此查看教程中的链接时会显示在一个标准的浏览器窗口中。至此,按钮会显示在窗口中间并自动伸展。你可以增加align="start"到window标签阻止其自动伸展。
-
-
例子 findfile.xul
-

请添加我们在前面章节创建的这些代码到findfile.xul文件。这些代码必须插入到 window 标签里面。代码是下面红色显示的部份:

-
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<window
-    id="findfile-window"
-    title="Find Files"
-    orient="horizontal"
-     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-  <button id="find-button" label="Find"/>
-  <button id="cancel-button" label="Cancel"/>
-
-</window>
-
-
- Image:buttons2.png
-

你也可以注释掉“取消”按钮。窗口提供水平对齐地显示两个按钮。如果你在Mozilla中打开这个文件,你就可以获得和这里显示的图片一样的效果。

-
-

 

-
- 注解:我们不能直接在XUL文件中写文本标签。我们可以使用 实体替换这样文本可以很容易地进行翻译.
-

在下一节,我们将会学会怎么向窗口中增加标签和图片

-

查看更多参考 更多按钮特性

-

-

« 上一页下一页 »

-

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/adding_event_handlers/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/adding_event_handlers/index.html deleted file mode 100644 index ef85e01bd1..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/adding_event_handlers/index.html +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: 添加事件处理函数 -slug: Mozilla/Tech/XUL/Tutorial/Adding_Event_Handlers -translation_of: Archive/Mozilla/XUL/Tutorial/Adding_Event_Handlers ---- -

« Previous Next »

- -

 

- -

  

- -

 

- -

    到此为止我们的 findfile 看起来很棒。我们还没有搞定它,因为到此为止我们仅只是建立了一个简单的用户界面。接下来我们将给他添加脚本。

- -
-

使用脚本

- -
Edit section
- -

    为了使 find files 对话框工作,我们需要添加一些脚本来完成与用户的交互。我们想要为查找按钮、取消按钮以及各级菜单项添加脚本。我们会像在 HTML 中一样使用 JavaScript 来写一些函数。

- -

    你可以使用 script 元素为 XUL 文件引入脚本。你可以直接在 <script>  </script>标签之间嵌入脚本,但是最好是使用独立的文件来包含脚本,这样 XUL 窗口加载会快一些。 src 属性用于引入外部脚本文件。

- -
-
-
 find files 的例子
- -
Edit section
- -

    让我们为 find file 对话框添加脚本。尽管脚本文件的文件名无关紧要,但通常的它采用与 XUL 文件相同的文件名并以 .js 作为后缀。我们建立一个 findfile.js 文件。把下面的一行加到 window 开标记之后,所有元素之前

- -
<script src="findfile.js"/>
-
- -

    当我们知道改在脚本文件里添加什么之后,我们再建立这个文件。我们会在这个文件中定义一些函数,并且我们把这些函数称为事件处理函数。

-
-
- -

    你可以通过使用多个 script 标记向 XUL 文件添加多个脚本文件,此时你可以使用相对或绝对 URLs。比如下面的例子:

- -
<script src="findfile.js"/>
-<script src="chrome://findfiles/content/help.js"/>
-<script src="http://www.example.com/js/items.js"/>
-
- -

    本教程不涉及与事件处理无关的 JavaScript 的使用。因为这实在有太多的内容需要讲述,而且也可以从很多其他其他的资料获得所需的知识。

- -
默认的 JavaScript 仅在页面上显示错误。为了显示在 chrome JavaScript 中的错误,有必要更改以下设置: javascript.options.showInConsole = true
-如果设置 javascript.options.strict = true 那么任何不标准的,写法不良的,有语法上导致逻辑错误的,都将会写到日志中。
-
- -
-

响应事件

- -
Edit section
- -

    脚本需要响应一系列的事件包括用户触发的或是其他状态引起的。起码有三种不同的事件需要用不同的方法来处理。一种是用户按下鼠标键或是按下一个键盘按键。每一个 XUL 元素都有能力在不同的状态触发特定事件。一些事件仅由特定元素触发。

- -

    每一个事件都有一个名字,如 'mousemove' 是用户在一个 UI 元素上移动鼠标所触发的事件。XUL 与 DOM Events使用同样的机制来处理事件。当一个动作发生就会触发一个事件,比如用户移动鼠标,就会由一个相应类型的事件对象产生。 事件对象中包含一系列的属性包括:鼠标位置,哪个键被按下等。

- -

    事件按阶段被发送到 XUL。

- - - -

    可以在路由及返回阶段响应事件。一旦事件完成以上传播过程而为得以处理将使用默认的动作来处理该事件。

- -

    比如,当鼠标在一个包含在 box 中的按钮上移动时,产生一个 'mousemove' 事件,这个事件先被发送到窗口,紧接着是文件,然后是这个 box ,这样就完成了路由过程。然后事件被发送给按钮。最后,返回阶段,事件被发给 box、文件及窗口。返回阶段本质上是路由过程的逆过程。需要说明的是,有些事件没有返回阶段。

- -

    在事件传播的每一个阶段你都可以在任何元素上监听。由于事件会传递给所有祖先你可以在继承关系的更高层来添加监听器。当然,一个高层收到事件会通知它的全部子元素,而对于按钮的事件仅属于这个按钮。这一点对与你希望使用同样的代码控制一些元素是有用的。

- -

    大多数公共事件使用 'command' 事件。 当使用者启动一个元素 command 事件会被触发,例如按按钮,选择菜单项等。对与不同的触发元素 command 会自动的按照不同的方式进行处理,比如,无论用户是使用鼠标点击按钮还是通过快捷键都会触发 command 事件。

- -

    有两种办法来为一个元素添加事件监听器。其一,把脚本本身作为其属性;其二,使用元素的 addEventListener 方法。 前者只处理返回事件但写起来更方便。后者可以控制事件的任何阶段,并且对同一个元素、事件可以使用多个监听器。对大多数元素来说,更多的使用属性的方式。

-
- -
-

事件监听器属性

- -
Edit section
- -

    使用属性形式,在你希望监听的元素上加一个属性,名字是待监听的事件名前加'on'。如,为了响应事件  'command' 属性名为 'oncommand'。属性值是处理此事件的一段脚本。通常代码短小,或者就是调用独立脚本文件中的函数。下面的例子响应按钮按下。

- -

Example 1  : Source View

- -
<button label="OK" oncommand="alert('Button was pressed!');"/>
-
- -

    由于 'command' 事件会返回,也可以把事件监听器添加到封装元素中。下面的例子监听器会响应全部两元素。

- -

Example 2  : Source View

- -
<vbox oncommand="alert(event.target.tagName);">
-  <button label="OK"/>
-  <checkbox label="Show images"/>
-</vbox>
-
- -

    在这个例子中,command 事件会有 button 或 checkbox 返回到设置了事件处理的 vbox 上。如果在按钮上在加一个监听器 (oncommand 属性) ,按钮上的代码会先调用,然后是 vbox 的。事件处理函数会传递一个隐含参数 'event',这参数可以获得事件的额外信息。一个常用的属性是 'target' ,它保存着事件是由谁产生的。这个例子里,显示事件产生者的标签名。target 很有用,因为你可以在一段代码里为一系列按钮作响应。

- -

    你可能注意到这里使用的语法与 HTML 中的一样。事实上, HTML 和 XUL 共用统计的事件机制。一个重要的不同是 'click' 事件 (或  onclick 属性) 在 HTML 中它仅用于响应按钮,而在 XUL 中 command 事件被用于替代它。XUL 有一个 click 事件,但是仅响应鼠标点击,不响应键盘。因此点击事件在XUL中应避免使用,除非你希望一个元素仅可以通过鼠标触发。补充一下,如果元素的 disable 属性为 true 时 command 事件不会被发送,而 click 事件则不然。

- -
-
-
find files 的例子
- -
Edit section
- -

     command 处理器可以用于响应查找和取消按钮,按查找按钮开始查找,当然由于我们没有实现这部分,我们现在还不能,这部分我们以后再完成,按取消按钮关闭窗口,下面的代码显示怎么做。并且我们也为关闭菜单也写了相同的代码。

- -
<menuitem label="Close" accesskey="c" oncommand="window.close();"/>
-...
-
-<button id="cancel-button" label="Cancel"
-     oncommand="window.close();"/>
-
- -

      这里加了两个处理器。oncommand 被加到关闭菜单项中了。通过使用这个处理器,用户可以使用鼠标点击菜单或使用键盘来选择此菜单来关闭窗口。oncommand 处理器也加到了取消按钮上。

-
-
-
- -

DOM 事件监听器

- -
Edit section
- -

    为一个元素添加事件处理的另一种方法是使用元素的 addEventListener 方法,这允许你动态的监听事件或在路由阶段处理事件。语法如下。

- -

Example 3  : Source View

- -
<button id="okbutton" label="OK"/>
-
-<script>
-function buttonPressed(event){
-  alert('Button was pressed!');
-}
-
-var button = document.getElementById("okbutton");
-button.addEventListener('command', buttonPressed, true);
-</script>
-
- -

     getElementById() 函数返回给定 id 的元素,这里返回这个按钮。addEventListener() 函数新建一个路由阶段的事件监听器。第一个参数是待监听的事件名,第而个参数是事件发生时要调用的函数名,最后一个参数如是 true 表示这是一个路由阶段的监听器,设为 false 则监听返回阶段。作为事件处理函数的第二个参数需要带一个参数(这个事件对象),就像上面定义的 buttonPressed 函数一样。

- -
Find files example so far  : Source View
- -

 

- -

    接下来,我们详细的看看 事件对象event object)。

- -

 

- -
-

« Previous Next »

-
- -

 

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/adding_html_elements/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/adding_html_elements/index.html deleted file mode 100644 index 6e1f8c38c6..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/adding_html_elements/index.html +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: XUL_教程/增加HTML元素 -slug: Mozilla/Tech/XUL/Tutorial/Adding_HTML_Elements -tags: - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/Adding_HTML_Elements ---- -

-

« 上一页下一页 »

-

-

 

-

增加HTML元素到窗口

-

除了可以使用XUL的所有元素,你也可以直接将HTML元素添加到XUL文件的内部。现在你可以在XUL文件中使用任意的HTML元素,意思是说可以在窗口中布置JAVA小应用程序(applet)和表格。如果可以你应该避免在XUL文件中使用HTML元素。(这是有原因的,主要涉及版面的控制这将在后面进行描述)。然而,不管怎样这节将描述如何使用它们。记住XML是大小写敏感的,因此你必须用小写输入标签和属性。

-

XHTML命名空间(namespace)

-

为了在XUL文件中使用HTML元素,你必须声明你要用到的XHTML命令空间。这个方法是Mozilla从XUL中区分HTML标签的。 下面的属性应该加在XUL文件的window 标签中,或者放到HTML元素的最外面。

-
xmlns:html="http://www.w3.org/1999/xhtml"
-
-

这个HTML的声明很像我们用过的XUL声明。要正常显示必须正确地输入这句,否则它不能正常运行。注意:Mozilla不会去下载这个URL的内容,但它会在运行HTML时对它进行验证。

-

这是一个可以加到文件查找窗口的例子:

-
 <?xml version="1.0"?>
- <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
- <window
-   id="findfile-window"
-   title="Find Files"
-   orient="horizontal"
-   xmlns:html="http://www.w3.org/1999/xhtml"
-   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-

因此,你可以像平常一样使用HTML,下面列出需注意的守则:

- -

使用HTML元素

-

你可以像headbody使用所有的HTML标签,不是真的有益。下面演示一些使用HTML元素的例子。

-
<html:img src="banner.jpg"/>
-
-<html:input type="checkbox" value="true"/>
-
-<html:table>
-  <html:tr>
-    <html:td>
-      A simple table
-    </html:td>
-  </html:tr>
-</html:table>
-
-

这些示例将从banner.jpg创建一个图像,一个多选项和一个只有一个单元格的表。如果XUL的特性是可用的你应该总是使用它们并且你不应该在XUL中使用表格作为布局。(XUL有自己的布局元素可以用)。注意html:前缀需要添加到每个标签的前面。这是Mozilla为什么会知道它是一个HTML标签而不是一个XUL标签。如果你没有加上html:部份,浏览器就会认为元素是一个XUL元素并且它们不能被正常显示,因为 img, input, table, 等都不是有效的XUL标签。

-

在XUL,你可以使用descriptionlabel元素添加文本标签。当你要用时应该使用这些元素。你也可以使用HTML的label元素添加文本标签的操作或者你可以像下面的例子一样简单地将文本放在不同的HTML元素之间(就像pdiv)。

-

例1 : Source View

-
<html:p>
-  搜索:
-  <html:input id="find-text"/>
-  <button id="okbutton" label="确定"/>
-</html:p>
-
-

这段代码的目的是显示'搜索:',接着显示一个文本输入框元素和一个确定按钮。注意XUL按钮可以显示在HTML元素之间,在这里它可以正常使用。在HTML元素之间的纯文本仅仅用来显示通常用来显示文字(就像p标签)。放在外面的文本是不能被显示的,除非XUL元素允许将文本放在里面(例如:description元素)。下面的例子可以帮助你理解。

-

HTML元素的实例

-

下面是在窗口在添加HTML元素的一些例子。在每个例子的窗口边都能找到简单的说明信息。

-

带多选框的对话框

-

例2 : Source View

-
- Image:htmlelem-ex1.png
-
<html:p>
-  点击下面方框会记住这个结果。
-  <html:p>
-    <html:input id="rtd" type="checkbox"/>
-    <html:label for="rtd">记住这个结果</html:label>
-  </html:p>
-</html:p>
-
-

在这个例子,一个 p 标签用来放置文本,另外一人用来放置分离的多行文本。

-

在HTML块外面的文本

-

例3 : Source View

-
- Image:htmlelem-ex2.png
-
<html:div>
-    你想保存下面的文档吗?
-    <html:hr/>
-</html:div>
-Expense Report 1
-What I Did Last Summer
-<button id="yes" label="Yes"/>
-<button id="no" label="No"/>
-
-

从图像上可以看到,在div标签里面的文本可以显示出来但其它的文本没有显示(Expense Report 1 和 What I Did Last Summer)。这是因为要显示的文本没有被HTML或XUL元素围绕起来。要显示这些文本,你必须将它放在div标签里面,或者用description 标签将它围起来。

-

无效的HTML元素

-
<html:po>Case 1</html:po>
-<div>Case 2</div>
-<html:description value="Case 3"/>
-
-

上面这三个样例不能被显示,每个都有一个不同的原因。

-
-
- 样例1 
-
- po不是一个正确的HTML标签,所以Mozilla不知怎么去处理它。
-
- 样例2 
-
- div是有效的,但是只能用在HTML中。如果要在这里使用,你必须为它添加html:限定符。
-
- 样例3 
-
- description元素仅仅在XUL中是有效的,而不是在HTML中。它不可以有html:限定符。
-
-

接下来,我们将要学习如何用 在元素间添加定位格.

-

-

« 上一页下一页 »

-

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/adding_labels_and_images/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/adding_labels_and_images/index.html deleted file mode 100644 index e3850373fc..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/adding_labels_and_images/index.html +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: XUL_教程/增加标签和图像 -slug: Mozilla/Tech/XUL/Tutorial/Adding_Labels_and_Images -translation_of: Archive/Mozilla/XUL/Tutorial/Adding_Labels_and_Images ---- -

-

« 上一页下一页 »

-
 

-

 

-

这一章描述了向窗口中加入标签和图像的方法。另外,我们将看到如何将一些元素包含到一个组中。

-

文本元素

-

在不使用标记的情况下,你不能直接向XUL文件中插入文本,它也不会做任何显示。为了达到这个目的你使用如下两个XUL元素来完成。

-

标签元素

-

将文本加入到将文本加入到窗体中的一个最基本的方法就是使用label元素。请看下面的例子:

-

Example 1 : Source View

-
<label value="This is some text"/>
-
-

value属性被用于指定要显示的文本。这样设置的文本在显示的时候不会换行,所以适合于较短的文本。这种语法适用于多数情况中使用的标签。

-

如果文本需要换行,你可以如下例所示将文本放在开启和关闭元素之间:

-

Example 2 :

-
<label>This is some longer text that will wrap onto several lines.</label>
-
-

就像HTML,换行和多余的空格将被压缩为一个空格。 接下来, 我们可以在 找到怎么去控制元素的宽度 这样我们就可以很容易地控制换行。

-
操作(Control)属性
-

你可以使用 control 属性去设置关联的标签。当用户在标签上进行点击操作时,已关联的控件就会被触发。accessibility这种关联的辅助操作很重要,这样屏幕阅读器就可以对选中的文本进行语音提示。设置control属性的值会触发与这个值对应的id的元素。 Example 3 : Source View

-
<label value="Click here:" control="open-button"/>
-<button id="open-button" label="Open"/>
-
-

在上面这个例子中,在标签上点击会使得按钮被触发。

-

描述(Descriptive)元素

-

在没有一些特定的关联操作的文本时你可以使用 description 标签。 这个元素使用于在对话框的上面或实例的一组控制的文本提示信息. 与 label 元素一样, 你既可以在 value 属性中指定单行的文本也可以在开合标签之间填充一大块的文本。在描述元素的大多数属性和文本内容的语法是与标签元素(label)是一样的。

-

例4 : Source View

-
<description>
-  This longer section of text is displayed.
-</description>
-
-

从内部看, 标签元素(label)和描述元素( description)是相同的。标签元素(label)用于有操作的标签,就像一个文本框(text field)。 操作属性仅仅为标签提供支持。 描述元素(description)用于其他描述性的情况,如对话框(dialog)上面的提示信息文本。

-

-

« 上一页下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/adding_more_elements/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/adding_more_elements/index.html deleted file mode 100644 index 9af4cc954f..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/adding_more_elements/index.html +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: 增加更多的元素 -slug: Mozilla/Tech/XUL/Tutorial/Adding_More_Elements -translation_of: Archive/Mozilla/XUL/Tutorial/Adding_More_Elements ---- -
-

添加元素

-
-
-
-

 

-

 

-
-

« Previous Next »

-
-

  

-

 

-

    我们继续通过为findfile对话框添加一些box来讨论box。

-
-
-

为 find files 的例子添加元素

-
- Edit section
-

    现在我们将为findfile对话框添加一些元素,首先添加选择其他检索信息的能力(如尺寸和数据):

-
<hbox>
-  <menulist id="searchtype">
-    <menupopup>
-      <menuitem label="Name"/>
-      <menuitem label="Size"/>
-      <menuitem label="Date Modified"/>
-    </menupopup>
-  </menulist>
-  <spacer style="width: 10px;"/>
-  <menulist id="searchmode">
-    <menupopup>
-      <menuitem label="Is"/>
-      <menuitem label="Is Not"/>
-    </menupopup>
-  </menulist>
-  <spacer style="width: 10px;"/>
-  <textbox id="find-text" flex="1" style="min-width: 15em;"/>
-</hbox>
-
-
- Image:boxfinal1.png
-

    加了两个 drop down boxes 。一个 spacer 加进来用于分割各元素,每个空白有10像素,你会看到当窗口尺寸改变时,文本框会改变尺寸而其他元素不会 ,也会看到标签被移除了。

-

    如果垂直的改变窗口尺寸,元素不会改变尺寸,这是因为他们在水平的box中。 Find 和 Cancel 按钮总在春光看的底部是合适的。这很容易通过在两个水平box间添加空白实现。

-
<spacer style="height: 10px"/>
-<hbox>
-  <menulist id="searchtype">
-    <menupopup>
-      <menuitem label="Name"/>
-      <menuitem label="Size"/>
-      <menuitem label="Date Modified"/>
-    </menupopup>
-  </menulist>
-  <spacer style="width: 10px;"/>
-  <menulist id="searchmode">
-    <menupopup>
-      <menuitem label="Is"/>
-      <menuitem label="Is Not"/>
-    </menupopup>
-  </menulist>
-  <spacer style="width: 10px;"/>
-  <textbox id="find-text" flex="1" style="min-width: 15em;"/>
-</hbox>
-
-<spacer style="height: 10px" flex="1"/>
-
-<hbox>
-
-

    现在当窗口改变尺寸,这两个按钮会移动以确保总在窗口的底部。 spacer 被添加在标题和检索条件之间。

-

    在检索条件上画上边框可能会更好看。可以使用 CSS border 属性或使用 groupbox 元素,第一种方法需要设置box的样式。我们使用后一种方法。  groupbox 可以画出适合当前主题的漂亮的边框。

-

    把box改为 groupbox

-
<groupbox orient="horizontal">
-  <caption label="Search Criteria"/>
-  <menulist id="searchtype">
-  .
-  .
-  .
-  <spacer style="width: 10px;"/>
-  <textbox id="find-text" flex="1" style="min-width: 15em;"/>
-</groupbox>
-
-
- Image:boxfinal2.png
-

   当然还有其他的美化方案,比如让组框延伸到窗口底边。也可以修饰一下边界让他们看起来更漂亮。

-

    我们会在这个教程中看到更多关于box的例子及其功能因为我们还有在findfile对话框中添加新的元素。

-

Find files example so far Source View

-
-
-


-      下一章,create stacks.

-

 

-
-

« Previous Next »

-
-

  

-

 

-
-
-
-
-

Retrieved from "https://developer.mozilla.org/En/XUL_Tutorial/Adding_More_Elements"

-
- -

 

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/adding_style_sheets/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/adding_style_sheets/index.html deleted file mode 100644 index 630627f941..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/adding_style_sheets/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: 添加样式表 -slug: Mozilla/Tech/XUL/Tutorial/Adding_Style_Sheets -translation_of: Archive/Mozilla/XUL/Tutorial/Adding_Style_Sheets ---- -
<?xml version="1.0"?>
-<?xml-stylesheet href="css/ued.css" type="text/css"?>
-
-
-

用xml-stylesheet引入CSS文件!可以是本地或来自网络的文件。使用http或chrome协议均可。

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/anonymous_content/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/anonymous_content/index.html deleted file mode 100644 index 6362be89f6..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/anonymous_content/index.html +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: XUL_教程/匿名内容 -slug: Mozilla/Tech/XUL/Tutorial/Anonymous_Content -translation_of: Archive/Mozilla/XUL/Tutorial/Anonymous_Content ---- -

 

-

-

« 上一页Anonymous_Content">下一页 »

-

-

在这一节,我们将讲解用XBL创建content。

-

XBL Content

-

XBL被用来自动在另一个元素中添加一组元素。当内部元素用XBL描述时,XUL文件只需要指定外部元素。对于创建由其它控件构成的单独的控件来说这是很有用的,但只被认为是单独的控件。这里讲解了向由外部元素指定的内部元素添加属性的机理。

-

Declaring Scrollbar Example

-

以下的例子指出了滚动条是怎么声明的(从实例简化1bit)

-
<bindings xmlns="http://www.mozilla.org/xbl"
-          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <binding id="scrollbarBinding">
-    <content>
-      <xul:scrollbarbutton type="decrement"/>
-      <xul:slider flex="1">
-        <xul:thumb/>
-      </xul:slider>
-      <xul:scrollbarbutton type="increment"/>
-    </content>
-  </binding>
-</bindings>
-
-

这个文件包含一个用binding元素声明的单独的binding。ID属性应该设置为binding的标识符。这会在css文件中设置-moz-binding属性时用到。

-

content标签被用来声明将被增进滚动条的anonymous content。content标签里的所有元素将被添加进被绑定界面元素内部。这种 binding将被绑定到滚动条,虽然没必要这样。将CSS -moz-binding 属性的设置为binding的URI的任何元素都将使用它。

-

使用上述 binding会导致下面的XUL的行会如下扩展,假设滚动条与上述的XBL相关联:

-
<scrollbar/>
-
-expands to:
-
-<scrollbar>
-  <xul:scrollbarbutton type="decrement"/>
-    <xul:slider flex="1">
-      <xul:thumb/>
-    </xul:slider>
-  <xul:scrollbarbutton type="increment"/>
-</scrollbar>
-
-

含有content标签的元素被无记录的添加到滚动条。虽然无记录内容被显示在屏幕上,但在正常方式下,不能通过脚本得到它。对于XUL,就像只有一个元素,尽管它实际上由大量元素构成。

-

检查 Mozilla窗口中的滚动条,就会发现它由一个arrow按钮、一个slider、内部thumb和一个末尾的second arrow 按钮组成。它们都是XBL上面出现过的元素。这些元素将依次绑定在运用基础XUL元素的其它bindings上。请注意 content元素需要XUL姓名空间(他们出现在XUL之前:),因为他们是XUL元素,而且在XBL中无效。这个命名空间声明在bindings标签内。如果您不想使用XUL元素的命名空间, Mozilla将假定元素都是XBL,不理解这里,您的元素可能不会正常工作。

-

Filename Input Field Example

-

另一个例子是关于输入一个文件名的域:

-
<binding id="fileentry">
-  <content>
-    <textbox/>
-    <button label="Browse..."/>
-  </content>
-</binding>
-
-

连接这个元素的binding将会导致输入浏览按钮之后的文本时它包含一个域。这个内部内容被匿名的创建了,而且用DOM不能查看到。

-

Override the Bound Element

-

Anonymous content被匿名的创建在 binding连接到一个元素的任何地方。如果您在XUL里放置子元素,他们将覆盖由binding提供的元素。例如XUL段,假设它早期与滚动条XBL绑定:(如果在xul文件中,给被绑定界面元素添加子元素,那么会覆盖掉binding中的元素。例如下面的xul片断,假设它被绑定到了前面的scrollbar的binding上)

-
<scrollbar/>
-
-<scrollbar>
-  <button label="Overridden"/>
-</scrollbar>
-
-

第一个滚动条,因为它没有自己的内容,它将从在XBL文件里声明的binding来生成它的内容。第二个滚动条有它自己的内容,因此它将不会运用XBL内容,这产生了不完全是滚动条的产品。请注意比如滚动条这样的内建元素,从toolkit包的bindings目录得到它们的XBL。

-

这只应用于在content标签内定义的元素。不论content是否从XBL而来或不论XUL是否提供自己的content,XBL的属性、方法和其它方面仍然可用。

-

Using the Children Element

-

当您想将XBL的内容和由XUL文件提供的内容一起都显示出来,可能需要重复几次。您能运用children元素来实现。在XUL中添加的子元素被添加来替代children元素。当创建自定义菜单控件时,这是很容易操作的。例如,一个简单的可编辑的menulist元素,可能如下创建:

-
XUL:
-
-<menu class="dropbox">
-  <menupopup>
-    <menuitem label="1000"/>
-    <menuitem label="2000"/>
-  </menupopup>
-</menu>
-
-CSS:
-
-menu.dropbox {
-    -moz-binding:  url('chrome://example/skin/example.xml#dropbox');
-}
-
-XBL:
-
-<binding id="dropbox">
-  <content>
-    <children/>
-    <xul:textbox flex="1"/>
-    <xul:button src="chrome://global/skin/images/dropbox.jpg"/>
-  </content>
-</binding>
-
-

这个例子用旁边的按钮创建了一个输入域,menupopup将添加到由children元素指定位置。请注意对DOM结构来说,这些内容将与在XUL文件中显示的一样,因此menupopup将成为menu的一个子元素。对于开发者来说xbl的内容是看不到的,所以也没必要知道它的位置。

-

结果内容应该是:

-
<menu class="dropbox">
-  <menupopup>
-    <menuitem label="1000"/>
-    <menuitem label="2000"/>
-  </menupopup>
-  <textbox flex="1"/>
-  <button src="chrome://global/skin/images/dropbox.jpg"/>
-</menu>
-
-

includes Attribute

-

某些情况下,您可能希望只包括特定类型的内容。或者您只希望在不同的位置放置不同类型的内容。includes属性能够用来使只有某些元素才能在children的内容里出现。它的值应该设定到一个单独的标签名。或者到一个由“|”分隔的标签列表

-
<children includes="button"/>
-
-

所有的button将会被添加到被绑定元素的children所指明的位置。其它元素将不会与这个标签匹配。您能够放置多个children 元素到一个binding中,来在不同的地方放置不同类型的内容。如果XUL中一个元素没有匹配任何children元素,那个元素(和其他任何不匹配的元素)将会被用来替代这个绑定的内容。

-

这里有另一个例子。让我们来介绍一下创建一个控件,并用两边的zoom in 和zoom out 按钮显示图象的方法。这将用一个box来创建,它包含图象和两个按钮。因为每个用法不同,这个图象元素得放置在XBL外部。

-
XUL:
-
-<box class="zoombox">
-  <image src="images/happy.jpg"/>
-  <image src="images/angry.jpg"/>
-</box>
-
-XBL:
-
-<binding id="zoombox">
-  <content>
-    <xul:box flex="1">
-      <xul:button label="Zoom In"/>
-      <xul:box flex="1" style="border: 1px solid black">
-        <children includes="image"/>
-      </xul:box>
-      <xul:button label="Zoom Out"/>
-    </xul:box>
-  </content>
-</binding>
-
-

XUL文件中详述的子元素将放置在children标签位置。有两幅图象,因此两个都将被添加到彼此的旁边。显示结果等价如下:

-
<binding id="zoombox">
-  <content>
-    <xul:box flex="1">
-      <xul:button label="Zoom In"/>
-      <xul:box flex="1" style="border: 1px solid black">
-        <xul:image src="images/happy.jpg"/>
-        <xul:image src="images/angry.jpg"/>
-      </xul:box>
-      <xul:button label="Zoom Out"/>
-    </xul:box>
-  </content>
-</binding>
-
-

从 DOM的观点来看,子元素仍然在初始的存储单元。这就是说,外部的XUL box有两个子元素,它们是这两幅图像。里边带边框的box有一个子元素,就是children 标签。当使用带XBL的DOM时,这是一个重要的区别。这也可以应用于CSS选择器规则。

-

多个子元素

-

您也能够使用多个children元素而且可以把某些元素放置在一个地方,其它元素放置在其它地方,通过添加一个includes属性和将它设置成标签的垂直的bar-separated列表,您能够使得只有在那个列表里的元素被放置在那个地方。例如,下面的XBL将导致文本标签和按钮出现在与其他元素不同的地方。

-

Source

-
<binding id="navbox">
-  <content>
-    <xul:vbox>
-      <xul:label value="Labels and Buttons"/>
-      <children includes="label|button"/>
-    </xul:vbox>
-    <xul:vbox>
-      <xul:label value="Other Elements"/>
-      <children/>
-    </xul:vbox>
-  </content>
-</binding>
-
-

第一个children元素只含有标签和按钮元素,正如它的includes属性指示的一样。第二个children元素因为它没有includes属性,它将包含所有的剩余的元素。

-

See also Anonymous Content section of the XBL reference.

-

(Next)在下一节,我们将研究属性如何被继承到 anonymous  content中.

-

-

« 上一页Anonymous_Content">下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/box_model_details/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/box_model_details/index.html deleted file mode 100644 index 7b647957ba..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/box_model_details/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: 分组细节 -slug: Mozilla/Tech/XUL/Tutorial/Box_Model_Details -translation_of: Archive/Mozilla/XUL/Tutorial/Box_Model_Details ---- -

This page has no content. Enrich MDC by contributing.

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/content_panels/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/content_panels/index.html deleted file mode 100644 index b2909f9a05..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/content_panels/index.html +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: 内容面板 -slug: Mozilla/Tech/XUL/Tutorial/Content_Panels -translation_of: Archive/Mozilla/XUL/Tutorial/Content_Panels ---- -

这一节我们来看看如何向HTML页面或者其他XUL文件中添加面板。

-

添加子面板

-

你可能经常想要使用不同页面的文件中的一部分。有时候你或许想将一个窗口中的一部分进行改变。一个很好的例子是一个一步接一步的向导,可以通过很多页面、询问一系列问题来指导你。每当用户点击下一步按钮的时候,向导就会显示下一个画面。

-

你可以通过为每个不同的画面打开一个新的窗口来创建向导。但这样有三个问题。首先,每个窗口会出现在不同的位置。第二,后退和下一步按钮都是一样的,如果这是内容区域变化将会更好。第三,当在不同的窗口中运行的时候使用脚本会非常困难。

-

注意,XUL有一个wizard元素可以用来创建向导接口。这将会在后面的章节中进行描述。

-

另一种方法是使用iframe元素。这与HTML中有相同的名字。它可以在一个窗口中创建独立的文档。其优点是可以在任何需要内容的地方加载不同的文件。将文档的URL设置这个框架的src属性。这个URL可以指向任意类型的文件,尽管通常是指向一个HTML文件或者其他XUL文件。你可以使用脚本来控制iframe中的内容而不需要影响主窗口。

-

在mozilla浏览器中,网页显示的区域就是用iframe创建的。当用户输入一个URL或者点击一个文档的链接的时候,这个frame的资源就变化了。

-

Iframe例子

-

例子1:

- - - - - - -
-

<toolbox>

-

  <toolbar id="nav-toolbar">

-

    <toolbarbutton label="Back"/>

-

    <toolbarbutton label="Forward"/>

-

    <textbox id="urlfield"/>

-

  </toolbar>

-

</toolbox>

-

 

-

<iframe id="content-body" src="http://www.mozilla.org/index.html" flex="1"/>

-
-

这个例子为浏览器创建了一个非常简单的接口。创建了一个格子来容纳两个元素,一个是工具栏一个是iframe。一个后退按钮,一个前进按钮,以及一个用来输入URL的输入区。在iframe里面将会出现一个网页。这里会默认的出现index.html文件。

-

这个例子功能并不完全。下面我们将会添加一个脚本在需要的时候来改变src属性,例如当用户按回车键的时候。

-

 browser

-

还有一种内容面板,使用browser标签。如果你想创建一个像浏览器一样显示内容的框架就可以使用这个元素。事实上iframe也可以完成这样的功能,但是browser又很多附加特性。例如browser可以保持历史页面用来进行前进和后退。Browser还可以加载带有参照页和其他标志的页面。需要的时候,你可以使用browser标签来常见一个像浏览器一样的接口,但是如果只需要一个简单的面板的话可以使用iframe来实现。

-

一个类似的元素tabbrowser,可以提供browser的全部功能而且还提供一个tab标签来在多个页面中切换。这是用在mozilla浏览器中的标签页浏览的小工具。元素tabbrowser事实上提供了一个含有一系列browser的tabbox元素。两种类型的browser都提供了相同的页面显示控制方式。

-

Browser实例

-

例子2:

- - - - - - -
-

<browser src="http://www.mozilla.org" flex="1"/>

-
-

与iframe一样,你可以使用src属性来指定browser的URL。对tabbrowser,你不可以设置直接像这样设置URL,因为他不会仅仅显示一个URL,相反的,你必须使用脚本调用loadURL函数来实现。

-

有三种类型的browser,基于你想要显示的内容的内部机制。可以使用type属性来指定其类型。

-

第一种类型如果不指定的话是默认的类型。这种情况,加载内容的内部browser就是与应用程序相同的,而且可以在外部窗口中访问。这意味着当一个脚本在browser内部加载文件的时候会获取最顶层的窗口。,会获得XUL窗口中的最外部的窗口。

-

这可能对于一个应用程序的子XUL面板比较合适,但是当你想要用browser来加载网页的时候,就不是你想要的了。相反的,你可能想现限制网页仅仅获取网页的内容,你可能注意到mozilla浏览器窗口的工具条和状态条有一个XUL内容以及更高级的tabbrowser组成了主要的区域。这个内部的区域显示了一个网页,但是网页无法访问其周围的XUL。这是因为使用的是第二种类型的browser,指定type属性为content。这可以阻止内容穿越到XUL窗口中,示例如下:

- - - - - - -
-

<browser src="http://www.mozilla.org" type="content" flex="1"/>

-
-

元素tabbrowser的每个标签页在创建的时候默认类型都设置为content。因此你不需要明确的为它指定类型。

-

第三种类型在你的程序中包含多个browser元素的时候使用的,例如,你有一个侧边栏来显示额外的内容,将主browser元素的type属性设置为content-primary来表明其内容是窗口中的主内容。这与content值一样,只是里面的内容只有使用XUL窗口的content属性才可以访问。这使得用脚本访问主窗口的内容时变得容易。对tabbrowser自动将可见的browser设置为content-primary,也就是说,这样你总是可以在当前可见的窗口中看到内容。

-

下一节,我们看看如何创建分隔线

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/creating_a_skin/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/creating_a_skin/index.html deleted file mode 100644 index 4fabb4c388..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/creating_a_skin/index.html +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: 创建一个皮肤 -slug: Mozilla/Tech/XUL/Tutorial/Creating_a_Skin -translation_of: Archive/Mozilla/XUL/Tutorial/Creating_a_Skin ---- -

本节讲述如何创建一个简单的皮肤,简单起见,我们只将其应用于查找文件对话框。

- -

一个简单的皮肤。

- -

下图是当前的查找文件对话框的样子。我们将创建一个应用于其上的皮肤。当然,一个皮肤可以应用于任何程序,但是当我们只关注于文件查找对话框时,事情就回简单些。因此我们只修改findfile.css 而 不修改global.css 文件。本节假设你正在使用经典的皮肤。你可能希望再工作之前留有一个原来皮肤的备份。

- -

Image:cskin1.jpg

- -

你需要再用户皮肤中创建文件'findfile.css' 。或者你可以临时把他放在内容目录中并用样式表指令引用。你也可以直接修改当前的findfile.css文件,看看他会变的怎样,或者你可以创建一个用户皮肤并连接到其上。

- -

创建用户皮肤包

- -

创建皮肤,步骤如下:(如果使用火狐1.5或以上,参见 配置文件 代替以下步骤)

- -
    -
  1. 创建一个放置皮肤文件的文件夹。
  2. -
  3. 从经典或现代皮肤文件夹中复制配置文件 (contents.rdf) 到这个新建的文件夹。
  4. -
  5. 修改配置文件引用你的皮肤。比如:将 'classic/1.0' 改为 'blueswayedshoes/1.0'.
  6. -
  7. 在文件‘chrome/installed-chrome.txt’ 中增加如下一行: skin,install,url,file:///stuff/blueswayedshoes/ 其中最后一部分是你现在创建的目录。务必在最后加一个斜杠。
  8. -
- -

把文件findfile.css 复制到新目录。我们将使用它作为新皮肤的基础。我们可以使用 'chrome://findfile/skin/findfile.css'来引用它

- -

添加样式规则

- -

首先决定要做怎样的改变。我们会修改颜色、改变按钮样式、稍微改变间隔,让我们从菜单、工具栏、标签面板开始。

- -

把下面的内容加到findfile.css 就会产生如下图的改变。

- -
window > box {
-  background-color: #0088CC;
-}
-
-menubar,menupopup,toolbar,tabpanels {
-  background-color: lightblue;
-  border-top: 1px solid white;
-  border-bottom: 1px solid #666666;
-  border-left: 1px solid white;
-  border-right: 1px solid #666666;
-}
-
-caption {
-  background-color: lightblue;
-}
-
- -

Image:cskin2.jpg

- - - -

上面的第一条规则(用于 'window > box') 制定窗口的内框使用不同的颜色,这可能不是最好的办法,我们可以使用样式类来做出这样的改变。那样做的话,我们可以修改XUL文件,不必要求box是窗口的第一个子元素。

- -
CSS:
-.findfilesbox {
-  background-color: #0088CC;
-}
-
-XUL:
-<vbox class="findfilesbox" orient="vertical" flex="100%">
-<toolbox>
-
- -

把标签修圆

- -

下面,修改标签。我们将要使选中的标签变为粗体,并且修圆标签。

- -
tab:first-child {
-  -moz-border-radius: 4px 0px 0px 0px;
-}
-
-tab:last-child {
-  -moz-border-radius: 0px 4px 0px 0px;
-}
-
-tab[selected="true"] {
-  color: #000066;
-  font-weight: bold;
-  text-decoration: underline;
-}
-
- -
Image:cskin3.jpg
- -

这里添加了两条规则,第一条将第一个标签修圆,第二条将最后一个标签修圆。这里使用了一个特殊的样式规则, -moz-border-radius, 他再边框的角上创建一个圆弧。第一个标签的左上角,第二个标签的右上角用4个像素修圆而其他的角都设为0,这相当于没有修圆,值越大就越接近圆,值越小就越接近矩形。

- -

最后的规则只有当标签的属性 selected 设为 true时才有效,他是使选中的标签的文字以粗体,下划线、深蓝色显示,注意图中只有第一个标签这样显示,第二个不会,因为他没有被选中。

- -

添加工具栏按钮

- -

有时候我们很难区分工具栏上的按钮和菜单栏的命令,如果我们为工具栏的按钮添加图标就会更清楚。火狐的创造者为例如打开保存等按钮创建了图标,我们直接用再这里可以节省时间。我们可以使用 list-style-image CSS 属性为按钮添加图标。

- -
#opensearch {
-  list-style-image: url("chrome://editor/skin/icons/btn1.gif");
-  -moz-image-region: rect(48px 16px 64px 0);
-  -moz-box-orient: vertical;
-}
-
-#savesearch {
-  list-style-image: url("chrome://editor/skin/icons/btn1.gif");
-  -moz-image-region: rect(80px 16px 96px 0);
-  -moz-box-orient: vertical;
-}
-
- -
Image:cskin4.jpg
- -

Mozilla provides a custom style property -moz-image-region which can be used to make an element use part of an image. You can think of it as a clip region for the image. You set the property to a position and size within an image and the button will display only that section of the image. This allows you to use the same image for multiple buttons and set a different region for each one. When you have lots of buttons, with states for hover, active and disabled, this saves space that would normally be occupied by mutliple images. In the code above, we use the same image for each button, but set a different image region each one. If you look at this image (btn1.gif), you will notice that it contains a grid of smaller images, each one 16 by 16 pixels.

- -

The -moz-box-orient property is used to orient the button vertically, so that the image appears above the label. This property has the same meaning as the orient attribute. This is convenient because the skin cannot change the XUL. Most of the box attributes have corresponding CSS properties.

- -

其他改变

- -

Next, we'll make a couple of changes to the buttons along the bottom, again reusing some icons from Mozilla to save time. If creating your own skin, you will need to create new icons or copy the icons to new files. If following the example in this section, just copy the files to your new skin and change the URLs accordingly.

- -
#find-button {
-  list-style-image: url("chrome://global/skin/checkbox/images/cbox-check.jpg");
-  font-weight: bold;
-}
-
-#cancel-button {
-  list-style-image: url("chrome://global/skin/icons/images/close-button.jpg");
-}
-
-button:hover {
-  color: #000066;
-}
-
- -
Image:cskin5.jpg
- -

We add some images to the buttons and make the Find button have bold text to indicate that it is the default button. The last rule applies to buttons when the mouse is hovering over them. We set the text color to dark blue in this case. Finally, some minor changes to the spacing around the items, by setting margins:

- -
tabbox {
-  margin: 4px;
-}
-
-toolbarbutton {
-  margin-left: 3px;
-  margin-right: 3px;
-}
-
- -

After those changes, the find files dialog now looks like the image.

- -

Image:cskin6.jpg

- -

As you can see, some simple changes to the style rules has resulted in quite a different appearance to the find files dialog. We could continue by changing the menus, the grippies on the toolbar and the input and checkbox elements.

- -

创建全局皮肤

- -

The skin created above is simple and only applies to the find files dialog. Some of the changes made to the skin could be placed in the global style sheets (those in the global directory of the skin) to be applied to all applications. For example, having different images for the check boxes in the find files dialog as other windows looks a little odd. This change should really be moved into the global style sheet.

- -

Try moving the CSS styles from findfile.css into global.css and then look at some of the dialogs in Mozilla. (The cookie viewer is a good example.) You will notice that it has adopted the rules that we have added. Some of the rules conflict with those already in the global stylesheets. For example, rules are already defined for buttons and tabs and so on and we defined additional rules for them. When changing the global skin, you would need to merge the changes into the existing rules.

- -

For the best skinnability, it is best to declare appearance related style rules in the global directory rather than in individual style files. This includes colors, fonts and general widget appearances. If you change the color of something in a local skin file (such as findfile.css), the dialog may look odd if the user changes their global skin. Don't expect the user to be using the default one.

- -
-

Our Find files example with this skin: Source View Stylesheet

-
- -

See also

- -

Mozilla CSS extensions, and CSS reference

- -


- 下一章讨论 XUL程序的本地化

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/creating_a_window/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/creating_a_window/index.html deleted file mode 100644 index 5a7329bac3..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/creating_a_window/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: 创建一个窗口 -slug: Mozilla/Tech/XUL/Tutorial/Creating_a_Window -translation_of: Archive/Mozilla/XUL/Tutorial/Creating_a_Window ---- -

-

« 上一页下一页 »

-

- -

 

- -

前面提到: 我们要在本教程中创建一个简单的查找文件工具。不过开始之前,我们得先看看XUL文件的基本语法。

- -

 

- -

创建一个 XUL 文件

- -

一个 XUL 文件可以有任何名字,但它必须拥有一个 .xul 的扩展名。最简单的 XUL 文件具有下述结构:

- -
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<window
-    id="findfile-window"
-    title="查找文件"
-    orient="horizontal"
-    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-<!-- Other elements go here -->
-</window>
-
- -

这个窗口不会做任何事情,因为它没有包含任何用户界面元素。那些元素会在下面的部分中添加。这里对上面的代码进行逐行断开解释:

- -
    -
  1. <?xml version="1.0"?>
    - 这一行只是简单声明这是一个 XML 文件。你通常在每一个 xul 文件的顶端都会添加这一行,非常像在一个 HTML 文件的顶端添加 HTML 的标识。
  2. -
  3. <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
    - 这一行是用来指定文件使用的样式表的。这是 XML 文件用以导入样式表的语法。在这种情况下,我们从一个皮肤包的全局部分导入样式。我们没有指定特定的文件,所以 Mozilla 会确定使用文件夹中的哪一个文件。在这种情况下,会选中最重要的 global.css 文件。这个文件包括了所有 XUL 元件的默认声明。因为 XML 并不知道如何显示元件,因此这个文件指出怎样去做。通常,你会将这一行放在每一个 XUL 文件的顶部。你也可以采用类似语法导入其他的样式表。需要注意的是你一般都会在你的样式表文件中导入全局样式表。
  4. -
  5. <window
    - 这一行说明你在描述一个 window 。每一个用户界面窗口都在一个单独的文件中进行描述。这个标记非常类似 HTML 中包围全部内容的 BODY 标记。 一些属性可以放到 window 标记中——在本例中有四个属性。在本例中,每一个属性都占一个单独的行,但并不是必须这样做。
  6. -
  7. id="findfile-window"
    - id 属性用作标识以便窗口被脚本所引用。你通常会为所有的软件放上 id 属性。虽然名字可由你任起,但应该是有一定关联的。
  8. -
  9. title="查找文件"
    - The title Attribute 属性描述显示时将在窗口的标题栏上显现的文本。在本例中将显示'查找文件'。
  10. -
  11. orient="horizontal"
    - orient 属性确定窗口中元件的排布。值 horizontal 意味着元件应该横过窗口水平放置。你也可以使用值 vertical,这表示元件将成一列放置。这是默认值,所以如果你希望使用垂直方向的话可以将这个属性完全关闭。
  12. -
  13. xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    - 这一行声名了 XUL 的名空间,你应该将它放到窗口元件以表示它的所有子元件都是 XUL。注意这个 URL 实际上不需要下载的。Mozilla 内部会识别这个 URL。
  14. -
  15. <!-- 其他元件写到这里 -->
    - 将这个注释块替换成其他显示在窗口中的元件(按钮、菜单以及其他用户界面组件)。我们在接下面的部分将添加一些元件。
  16. -
  17. </window>
    - 最后,我们需要在文件的结尾关闭 window 标记。
  18. -
- -

打开窗口

- -

声明完一个窗口,如果打开它呢?这里有几种方法:

- - - -

不过,因为我们的XUL中没有定义其它元素,因此使用Mozilla打开时,什么也看不到。并且在浏览器中打开时,窗口会显示在浏览器中,这不是一个真正的应用,不过进行测试没有关系。

- - - -

-chrome参数并不会带来特殊权限,而是chrome URL备具特殊权限。

- -

到这里可以把已经学过的做一个测试。包的组织不一定要是content/skin/locale这种形式。象我的测试就是:

- -
-

d:\project\test\xul\findfile

-
- -

现在目录下有两个文件:

- -
-

findfile.xul和contents.rdf

-
- -

然后修改installed-chrome.txt文件。

- -

切换到Mozilla目录,然后在命令行下输入:

- -
-

mozilla -chrome chrome://findfile/content/filefile.xul

-
- -

不过执行完后,什么都没有,就一个标题条。

- -

(英文原文: XUL_Tutorial:Creating_a_Window ) 本篇wiki基于limodou的学习记录: XUL学习:XUL Tutorial(五) -- Creating a Window

- -

 

- -

-

« 上一页下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/creating_an_installer/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/creating_an_installer/index.html deleted file mode 100644 index aef43ec39b..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/creating_an_installer/index.html +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: 创建安装程序 -slug: Mozilla/Tech/XUL/Tutorial/Creating_an_Installer -translation_of: Archive/Mozilla/XUL/Tutorial/Creating_an_Installer ---- -

 

-
-

Parts of this page show the use of the XPInstall API. The majority of this API is now deprecated and as of Gecko 1.9 no longer available. Extension, theme, and plug-in developers must switch away from install.js based packages to the new packaging scheme with an install.rdf manifest. In particular plugin developers should see how to package a plugin as an extension.

-
-

 

-

 

-
-

« Previous Next »

-
-

  

-

 

-

This section will describe packaging a XUL application into an installer.

-
-

XPInstall Packages

-
- Edit section
-

Mozilla provides a mechanism which can be used to package XUL windows, scripts, skins and other files into single file installers. You can place this installer file somewhere for users to download. A simple script can be used to have the package downloaded and installed. This mechanism is called XPInstall (Cross platform Install).

-

XPInstall installers are packaged into JAR files. Inside the JAR file, you can add all the various files that you want to have installed. In addition, installers should contain an install script (a file named install.js) which can be used to script the installation process. This script has access to various install functions which can be used to install files and components.

-

The JAR file installers typically have the extension .xpi (pronounced zippy) to distinguish them from other archives. The installers will be usually used to install Mozilla components such as new skins, plugins and packages.

-

There are several steps involved in launching an installer and installing components. These are described step by step below.

-
    -
  1. Create a Web page from which the user can download the software to be installed. This page will contain an install trigger which is a small piece of script which launches the install.
  2. -
  3. The user is presented with a dialog which indicates the package being installed. It is possible for the install trigger to launch multiple installers. In this case, they will be presented in a list. The user may choose to continue or cancel.
  4. -
  5. If the user chooses to continue, the installer XPI file is downloaded. A progress bar is displayed to the user during this process.
  6. -
  7. The file install.js is extracted from the install archive and executed. This script will call install functions which will indicate which files from the archive should be installed.
  8. -
  9. Once the script is complete, the new package has been installed. If multiple packages are being installed, their scripts will run in sequence.
  10. -
-
-
-

Install Triggers

-
- Edit section
-

As indicated above, the install process is started by an install trigger. This involves the use of the special global object InstallTrigger. It contains a number of methods which can be used to start an installation. You can use this object in local or remote content, meaning that it is suitable for a download from a Web site.

-

Let's create an example install trigger. This involves the use of the function InstallTrigger.install(). This function takes two arguments, the first is a list of packages to install, and the second is a callback function which will be called when the installation is complete. Here is an example:

-
function doneFn ( name , result ){
-  alert("The package " + name + " was installed with a result of " + result);
-}
-
-var xpi = new Object();
-xpi["Calendar"] = "calendar.xpi";
-InstallTrigger.install(xpi,doneFn);
-
-

First, we define a callback function doneFn() which will be called when the install is complete. You can name the function whatever you like of course. This function has two arguments. The first is the name of the package that was just installed. This is important if you are installing multiple components. The second argument is a result code. If the result is 0, the installation completed successfully. If the result is non-zero, an error occured and the value is an error code. The function doneFn() here just displays an alert box to the user.

-

Next, we create an array xpi which will hold the name (Calendar) and URL (calendar.xpi) of the installer. You can add an additional similar such line for each package you wish to have installed. Finally, we call the install function.

-

When this section of script is executed, the file calendar.xpi will be installed.

-
-
-

Our find files example

-
- Edit section
-

Let's try this with the find files dialog.

-
function doneFn ( name , result ){
-  if (result) alert("An error occured: " + result);
-}
-
-var xpi = new Object();
-xpi["Find Files"] = "findfile.xpi";
-InstallTrigger.install(xpi,doneFn);
-
-
-
-
-

The XPI Archive

-
- Edit section
-
- Note: If you want to create a new XULRunner application, extension, or theme, see Bundles.
-

The installer XPI file is required to contain one file called install.js which is a JavaScript file which is executed during the installation. The remaining files are the files to be installed. These files will typically be placed inside a directory in the archive but they do not have to be. For chrome files, they might be structured like the chrome directory.

-

Often, the only files placed in an XPI archive will be the install script (install.js) and a JAR file. This JAR file contains all of the files used by your application. The components provided with Mozilla are stored in this manner.

-

Because the XPI file is just a special ZIP file, you can create it and add files to it using a zip utility.

-
-
-

Our find files example

-
- Edit section
-

For the find files dialog, we'll create a structure in the archive much like the following:

-
install.js
-findfile
-  content
-    contents.rdf
-    findfile.xul
-    findfile.js
-  skin
-    contents.rdf
-    findfile.css
-  locale
-    contents.rdf
-    findfile.dtd
-
-
-
-

A directory has been added for each part of the package, the content, the skin and the locale. The contents.rdf files have also been added because they will be needed to register the chrome files.

-

Next, we'll look further at the install script.

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/creating_dialogs/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/creating_dialogs/index.html deleted file mode 100644 index 1b3dbb2fab..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/creating_dialogs/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Creating Dialogs -slug: Mozilla/Tech/XUL/Tutorial/Creating_Dialogs -translation_of: Archive/Mozilla/XUL/Tutorial/Creating_Dialogs ---- -

This page has no content. Enrich MDC by contributing.

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/document_object_model/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/document_object_model/index.html deleted file mode 100644 index 15112d1cc7..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/document_object_model/index.html +++ /dev/null @@ -1,220 +0,0 @@ ---- -title: 文档对象模型 -slug: Mozilla/Tech/XUL/Tutorial/Document_Object_Model -tags: - - DOM - - XUL_教程_cn -translation_of: Archive/Mozilla/XUL/Tutorial/Document_Object_Model ---- -
-
-

 

-

 

-
-

« Previous Next »

-
-

  

-

 

-

    XUL元素的文档对象模型 (DOM) 可以用于获取信息或修改他们。

-
-

DOM 介绍

-
- Edit section
-

    文档对象模型 (DOM) 用于储存XUL节点树。当一个XUL文件加载后,标记被解析并转换成节点的继承关系结构。每个节点包含标记及一个文本块。DOM 结构可以使用一系列方法检查并修改。特殊的XUL 元素也提供了附加的方法可供使用。

-

    每一个加载了的XUL 文件都有一个可以显示在窗口或框架内的文档。尽管在特定时间只有一个文档与窗口相关,也有一系列方法使你可以加载更多的文档。

-

    Mozilla中, DOM 可以被JavaScript访问并操作。大量的文件对象包含可以被脚本使用的函数。然而,需要了解的是 DOM 是一个可以被 JavaScript 访问的 API 。JavaScript 本身仅是一种脚本语言,它能够访问这些对象是因为 Mozilla 为他提供了这些。

-

    JavaScript 中,由一个全局对象总可以被访问。你可以不使用对象就引用这个全局对象的属性及方法。比如,如果这个全局对象由一个 'name' 属性,你可以用这样的代码来改变它 'name = 7',而不用指明你所使用的对象。在浏览器环境中,window 是这个全局对象,对于XUL同样。当然对于不同的窗口这个全局对象也有所不同。每一个框架都含有一个独立的窗口对象。

-

    窗口经常使用 window property 引用,尽管这是可选的。有时这仅是为了澄清你所引用的方法的范围。举例来说,下面的两行等效的打开了一个新窗口。

-
window.open("test.xul","_new");
-open("test.xul","_new");
-
-

    当你在脚本的顶层定义一个函数或变量时,你实际上是为全局对象定义了一个属性。在 XUL中你定义的每一个函数都会被设为窗口对象的属性,比如下面的代码会在提示框中显示 'Message' 两次。

-
function getText(){
-  return "Message";
-}
-
-alert(getText());
-alert(window.getText());
-
-

    如果你希望访问在另一个窗口的脚本中定义的变量或函数,你值需要使用另一个窗口的 window 对象。比如,把上面的两个例子做成一个我们希望在另一个窗口(比如test.xul窗口)中调用getText()函数,可以这样做:

-
alert(window.opener.getText());
-
-

    每一个窗口都有一个 opener 属性,它保存着这个窗口对象是由谁打开的。在这个例子中,我们得到窗口的打开者,并调用这个窗口的 getText() 函数。注意,我们使用窗口属性前缀 'window' 仅为了清晰。

-

    窗口的 open() 方法也返回一个新窗口的引用,我们也可以从 opener调用新窗口的函数。提示: open() 在窗口完全加载前返回函数可能不会有效。

-

    窗口对象并不是有由 DOM 标准定义的,但在 Mozilla中有时把这部分称作 DOM Level 0——一个一些开发者称呼那些还未加入标准的类 DOM 功能的名字。在春光看中显示的文档可以通过窗口的 document 属性获得。由于它是窗口最常用的属性 document 属性经常不使用 'window.' 前缀。

-

     Mozilla 为不同的文档提供了一系列文档对象。三个主要的是HTMLDocument, XMLDocument, a及 XULDocument, 分别支持 HTML, XMLXUL 文档。这三种文件类型十分相似,事实上他们共享基本实现。然而,一些函数在一种或几种文档类型是特殊的。

-
-
-

检索元素

-
- Edit section
-

    最常用的检索元素的方法是给出待检索元素的id 属性利用getElementById() 方法检索。在 find file 对话框中我们为不少元素都添加了id属性,比如,我们可以使用这样的代码获得check box 的状态。

-
var state = document.getElementById('casecheck').checked;
-
-

     casecheck 代表待检索 checkbox 的id,如果我们需要检查是否它被选中,我们只需按上面的方法检查。我们可以对其他的单选框或其他有id的元素作相同的检查。比如获得输入框中的字符。;

-
-
-

find files 的例子

-
- Edit section
-

    要让 progress bartree data在findfile对话框显示时就显示出来,这不是难题。只要加在XUL文件中就可以了。现在我们要先去掉它,然后在按下 Find 按钮后显示。 首先,应将他们初始化化为不可见。hidden 属性用于确定元素是否显示。

-

    把进度条初始化为隐藏,同时为了能够用脚本引用添加一个 id 属性。同样的为了隐藏tree我们也将splitter 隐藏。

-
<tree id="results" hidden="true" flex="1">
-  .
-  .
-  .
-<splitter id="splitbar" resizeafter="grow" hidden="true"/>
-
-<hbox>
-
-  <progressmeter id="progmeter" value="50%"
-    style="margin: 4px;" hidden="true"/>
-
-

    添加 hidden 属性并设值为 true。这将导致窗口首次显示时该元素不可见。

-

    接下来,我们添加一个在Find按钮按下时调用的函数。我们把脚本写在findfile.js里,在上一章,我们已经在XUL文件中添加了脚本( script元素,如果你还不知道如何添加,请看下面的例子。 oncommand 控制器也被加到 Find 按钮上。

-
<script src="findfile.js"/>
-  .
-  .
-  .
-<button id="find-button" label="Find"
-   oncommand="doFind();"/>
-
-

    现在与findfile.xul相同的目录中创建一个叫 findfile.js 的文件,我们在文件中写一个 doFind() 函数。 script 标签允许直接编写脚本代码,但是出于包括格式在内的多种原因,脚本经常写在独立的文件里,除非它可以直接放到处理器中。

-
function doFind(){
-  var meter = document.getElementById('progmeter');
-  meter.hidden = false;
-}
-
-

    这个函数首先通过进度条的id引用它,然后改变的hidden属性。

-

    最后用一个提示框显示需要检索的文字。当然,这不是最后的版本,但现在我们需要让它发生些什么以使我们确认。

-
function doFind(){
-  var meter=document.getElementById('progmeter');
-  meter.hidden = false;
-  var searchtext=document.getElementById('find-text').value;
-  alert("Searching for \"" + searchtext + "\"");
-}
-
-

    现在,由于提示框的存在,我们知道当点击Find按钮时,会发生什么。同样,我们也需要为 drop-down boxes 添加代码以获得用用户选项。

-
-
-
-
-

XUL 元素的 DOM

-
- Edit section
-

    每一个 XUL 元素都还有一系列的属性,功能及子元素。

-
    -
  • 属性是在源文件中定义的,如flex="1"将 flex 属性设为 1
  • -
  • JavaScript 中属性使用点语法。例如:element.hidden 引用延伸的hidden 属性
  • -
  • 子元素的是指嵌在源文件标签中的元素。
  • -
-

    使用DOM方法可以动态的处理一个元素的属性,方法及子元素。

-

    注意属性及方法是不一样的东西。有一个属性并不意味着有一个同名的方法,当然通常会有这样一个方法。比如说获得元素的flex属性可以使用flex方法。这种情况下方法的代码就返回这属性。对于其他的方法 XUL 会进行更复杂的处理

-

    你可以用以下的方法处理元素的属性:

-
-
- getAttribute ( name )
-
- 返回给定元素的属性。
-
- hasAttribute ( name )
-
- 如果元素有指定名字的属性返回真。
-
- setAttribute ( name , value )
-
- 将value 为给定名字为name 的属性赋值。
-
- removeAttribute ( name )
-
- 删除给定名字的属性。
-
-

    这些方法可以让你在任何时候取得或改变属性的值。比如:

-
 var box = document.getElementById('somebox');
- var flex = box.getAttribute("flex");
-
- var box2 = document.getElementById('anotherbox');
- box2.setAttribute("flex", "2");
-
-

   当然 flex 属性有对应的脚本方法 可以用以代替。它并不更为有效,当更为简洁。下面的例子与上面的效果相同。

-
 var box = document.getElementById('somebox');
- var flex = box.flex;
-
- var box2 = document.getElementById('anotherbox');
- box2.flex = 2;
-
-

    一旦你引用了元素你就可以引用它的方法。比如,为了获得一个元素的 hidden 方法可以使用element.hidden 。你可能已经注意到了在方法参考中,一项会同时出现在属性及方法中,这是不一样的。比如,对于隐藏的元素 getAttribute("hidden") 返回字符串 'true' ,而 hidden 方法返回‘值true’  。用方法会自动完成类型转换。

-

    像 HTMLXML 元素一样,每一个 XUL 元素实现 XULElement 接口。一个 XUL 元素可以是任何定义在 XUL 名空间中的元素。所以XUL有非XUL 元素没有的属性及方法。XULElement 接口有一系列属性及方法来定义XUL 元素,其中有很多继承至 DOM 元素接口。

-

    一个名空间用一个URI 描述元素,下面是例子。

-
<button xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
-<button xmlns="http://www.w3.org/1999/xhtml"/>
-<html:button xmlns:html="http://www.w3.org/1999/xhtml"/>
-<html:button xmlns:html="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
-

    名空间使用 xmlns 属性

-
    -
  • 第一个按钮是被置于XUL名空间在的 XUL 元素。
  • -
  • 第二个按钮是被置于XHTML名空间在的 XHTML 元素。
  • -
  • 第三个例子,前缀 'html' 关联到 'http://www.w3.org/1999/xhtml',当你的文档中需要多个名空间时,你也可以使用使用冒号语法来使用前缀名空间。本例创建一个 XHTML 按钮。
  • -
  • 第四个按钮是XUL按钮,尽管使用的‘html’前缀,这要看前缀关联到哪个名空间。
  • -
-

    这是一个很重要的区别,不过在真正的文档中会为不同的名空间使用不同的前缀。

-

    DOM 提供了与无名空间相似的名空间相关的方法。比如 getAttributeNS()getAttribute() 相似除了需要一个指明名空间的参数。

-

    许多XUL元素有不同于其他元素的方法。参见 element reference

-
-
-

DOM遍历

-
- Edit section
-

    DOM是一个只有一个根的树。可以使用documentElement 方法获取根节点。根节点只要一个,但其他节点则不一定。一个元素对应与源文件中的标签,但也有文本节点、注释节点、及其他类型的节点。在XUL文档中根节点是源文件中的window标签。 树中的每一个节点都可能有其子节点,每个子节点又有它字节的子节点。由于DOM是树结构所以可以用一系列方法来遍历它。常用的几个列在下面:

-
-
- firstChild
-
- 引用元素的第一个子节点。
-
- lastChild
-
- 引用元素的最后一个子节点。
-
- childNodes
-
- 返回元素子节点的列表。
-
- parentNode
-
- 返回元素的亲节点。
-
- nextSibling
-
- 引用下一个兄弟节点。
-
- previousSibling
-
- 引用前一个兄弟节点。
-
-

    这些方法允许你以多种方法遍历文件,比如,使用 firstChild 方法获得第一个子节点并用 nextSibling 方法遍历子节点,或者可以用childNodes 返回子节点列表。在Mozilla中后者更有效。

-

    这个例子展示如何遍历根节点的全部子节点:

-
var childNodes = document.documentElement.childNodes;
-for (var i = 0; i < childNodes.length; i++) {
-  var child = childNodes[i];
-  // do something with child
-}
-
-

    变量 childNodes 保存着文档根节点的全部子节点。然后像处理数组一样用一个 for 循环枚举全部元素。

-
- Find files example so far: Source View
-

See also: A re-introduction to JavaScript and the JavaScript reference

-

    下一章学习修改DOM modify the DOM.

-

 

-
-

« Previous Next »

-
-

  

-

 

-
-
-
-
-
-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/element_positioning/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/element_positioning/index.html deleted file mode 100644 index df6c75dee6..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/element_positioning/index.html +++ /dev/null @@ -1,254 +0,0 @@ ---- -title: XUL_教程/元素定位 -slug: Mozilla/Tech/XUL/Tutorial/Element_Positioning -tags: - - XUL_Tutorial -translation_of: Archive/Mozilla/XUL/Tutorial/Element_Positioning ---- -

-

« 上一页下一页 »

-

- -

分组元素定位

- -

迄今为止, 我们知道怎么在一个分组里面将元素进行水平或垂直定位。我们通常需要在分组内对元素的定位和尺寸进行更多的控制。为此,我们首先需要知道一个分组是怎么工作的。

- -

一个元素的定位由他所属容器的布局样式决定。例如,在水平分组中的一个按钮在前面的按钮的右边。一个元素的尺寸由两个因素决定:元素期望的大小和用户指定的大小。元素期望的大小由该元素所包含的内容决定。例如,一个按钮的宽度由按钮上所显示文本的长度决定。

- -

一般来说元素的大小仅够容纳它的内容。一些元素,像文本输入框会使用一个默认的尺寸。分组会分配足够的尺寸去将元素放在它里面。一个包括三个按钮的水平分组将会包含比三个按钮更多的宽度,插入一些填充。

- -
Image:boxstyle1n.png
- -

在图片中,开始两个按钮为它们的文本提供了合适的尺寸。第三个按钮比较长因为它包含更多的内容。分组的宽度包含按钮间的填充空间和按钮的宽度总和。按钮的高度采用能够放置它的文本的合适尺寸。

- -

宽度和高度属性

- -

在窗口中你可能需要对元素的尺寸进行更多的控制。有更多的特性允许你去控制元素的尺寸。有一个快捷的方法可以通过在元素中简单添加widthheight 属性,更像你在HTML中的 img 标签的用法。下面展示了一个例子:

- -

例1 : Source View

- -
<button label="确认" width="100" height="40"/>
-
- -

然而,不推荐这样做。这么做适用性不好且可能与某些主题不匹配。一个更好的方法是使用样式表属性,它可以像中HTML中的样式表一样工作。可以使用下面的CSS属性。

- -
-
width 
-
指定元素的宽度。
-
height 
-
指定元素的高度。
-
- -

随便设置这两属性中的一个,元素将会创建它的宽度和高度。如果你只指定一个尺寸属性,另一个需要被算出。这些样式表属性的尺寸可以指定一个数字后面跟着一个单位。

- -

可伸缩元素

- -

非伸缩元素可以很简单快捷地计算尺寸。它们的宽度和高度可以直接被指定,如果没有指定尺寸,元素的默认尺寸就是刚好能放下它的内容的大小。对于可伸缩元素,计算需要一点窍门。

- -

可伸缩元素有一个可以设置为大于0的属性flex。被用来设置在可伸缩性元素中可以扩展和收缩的有用填充空间。它们的默认尺寸可以像非伸缩元素一样被计算。下面的例子做了这个的演示:

- -

例2 : Source View

- -
<window orient="horizontal"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<hbox>
-  <button label="Yes" flex="1"/>
-  <button label="No"/>
-  <button label="I really don't know one way or the other"/>
-</hbox>
-
-</window>
-
- -

这个窗口会像之前的图片所显示的一样。前面两个按钮将一个合适尺寸作为默认宽度,第三个按钮将会比较大因为它有一个较长的标签。第一个按钮被建成是可伸缩的,并且将所有的三元素放在一个分组里面。分组的宽度被设置成全部三个元素的总宽度(图片的宽度大约是430像素)。

- -

如果你增加窗口的宽度,元素会被检查清楚它们是否是可伸缩的,然后被分配到填充的空白空间。按钮只是可伸缩元素,但它不会增加宽度。这是因为按钮所在的分组不是可伸缩的。一个非伸缩元素在空间有效时也不会改变尺寸,所以按钮不会比其他情况下变得更宽。因此,按钮不会变得更宽。

- -

这个解决方案也用于创建可伸缩性的分组。于是,当你创建一个更宽的窗口时,因此分组会伸长以便填充多余的空间。因为分组比较大,更多的空余空间可以被放在它里面,放在它里面的可伸缩按钮可以填充有效空间而得到扩展。这会被许多内嵌的分组重复处理。

- -

设置最小和最大尺寸

- -

你可以允许一个元素能够扩展但限制它的尺寸不能比一个确定的尺寸更大。或者,你可设置一个最小尺寸。你可以通过以下四个属性来达到这个目的:

- -
-
minwidth 
-
指定元素的最小宽度。
-
minheight 
-
指定元素的最小高度。
-
maxwidth 
-
指定元素的最大宽度。
-
maxheight 
-
指定元素的最大高度。
-
- -

这个值的单位是像素。你也可以使用相应的CSS属性:min-widthmin-heightmax-widthmax-height

- -

这些属性只可以用于可伸缩元素。例如,设置一个最大高度,一个可伸缩的按钮将只能扩展到一个 确定的最大高度。你可以更改窗口的尺寸超过这个值但按钮会在指定的尺寸停止扩展。分组中的按钮将会一直扩展到你设置的分组最大高度时止。

- -

如果两个按钮都具有相等的弹性值,普通情况下它们两个会共享相同的多余空间。如果一个按钮有一个最大宽度,第二个将会一直扩展直到用光所有的空间为止。

- -

如果一个分组有一个最大宽度或高度,子分组不会扩展超出它的最大尺寸。如果一个分组有一个最小宽度或高度,它的子分组不能缩小到比它的最小尺寸更小。

- -
设置宽度和高度的例子
- -
<button label="1" style="width: 100px;"/>
-<button label="2" style="width: 100em; height: 10px;"/>
-<button label="3" flex="1" style="min-width: 50px;"/>
-<button label="4" flex="1" style="min-height: 2ex; max-width: 100px"/>
-<textbox flex="1" style="max-width: 10em;"/>
-<description style="max-width: 50px">This is some boring but simple
-wrapping text.</description>
-
- -
-
例1 
-
第一个按钮将显示成宽度为100像素的(px 的意思是像素)。你必须增加单位否则宽度将被忽略。
-
例2 
-
第二个按钮将显示成高度为10像素和宽度为100em(em是当前字体一个字符的尺寸)。
-
例3 
-
第三个按钮是可伸缩的所以它可以基于包含它的分组的尺寸进行扩展。然而,按钮不能收缩到比50像素更小。其它可伸缩组件像定位格可以吸收保留空间,而不管弹性比率。
-
例4 
-
第四个按钮是可伸缩的并且不能有一个比2ex(ex是当前字体中的字母x的高度)小的高度或比100像素更大的宽度。
-
例5 
-
文本输入框是可伸缩的但不能扩展超过10em。你会经常去使用em单位作为指定文本内容它们的尺寸。这个单位用于文本输入框因此字体可以更改并且文本输入框可以一直有个合适的尺寸,如果字体非常大时也一样。
-
例6 
-
description 元素包含50像素的最大宽度。在50像素后,文本会自动被截到下一行。
-
- -
-
我们的文件查找对话框
- -

让我们将这些样式增加到文件查找对话框。我们将会创建它因此文本输入框可以在输入窗口中改变尺寸。

- -
<textbox id="find-text" flex="1" style="min-width: 15em;"/>
-
- -
Image:boxstyle1.png
-在这里,文本输入框被做成可伸缩的。这样,它可以在用户改变对话框的尺寸时进行扩展。这可以用于如果用户想要输入一个很长的文本字符串时。通常地,设置了一个最小宽度为15em则输入框会一直显示为至少15个字符的宽度。如果用户更改对话框的尺寸到很小,文本输入框不会缩小超过15个字符长度。在窗口里面的输入框将会被画出来,并超出窗口的范围。注解:在图片中文本输入框被扩展为充满窗口的尺寸。
- -

Box Packing

- -

Let's say you have a box with two child elements, both of which are not flexible, but the box is flexible. For example:

- -

Example 3 : Source View

- -
<box flex="1">
-  <button label="Happy"/>
-  <button label="Sad"/>
-</box>
-
- -

If you resize the window, the box will stretch to fit the window size. The buttons are not flexible, so they will not change their widths. The result is extra space that will appear on the right side of the window, inside the box. You may wish, however, for the extra space to appear on the left side instead, so that the buttons stay right aligned in the window.

- -

You could accomplish this by placing a spacer inside the box, but that gets messy when you have to do it numerous times. A better way is to use an additional attribute pack on the box. This attribute indicates how to pack the child elements inside the box. For horizontally oriented boxes, it controls the horizonal positioning of the children. For vertically oriented boxes, it controls the vertical positioning of the children. You can use the following values:

- -
-
start 
-
This positions elements at the left edge for horizontal boxes and at the top edge for vertical boxes. This is the default value.
-
center 
-
This centers the child elements in the box.
-
end 
-
This positions elements at the right edge for horizontal boxes and at the bottom edge for vertical boxes.
-
- -

The pack attribute applies to the box containing the elements to be packed, not to the elements themselves.

- -

We can change the earlier example to center the elements as follows:

- -

Example 4 : Source View

- -
<box flex="1" pack="center">
-  <button label="Happy"/>
-  <button label="Sad"/>
-</box>
-
- -

Now, when the window is resized, the buttons center themselves horizontally. Compare this behavior to that of the previous example.

- -

Box Alignment

- -

If you resize the window in the Happy-Sad example above horizontally, the box will grow in width. If you resize the window vertically however, you will note that the buttons grow in height. This is because the flexibility is assumed by default in the other direction.

- -

You can control this behavior with the align attribute. For horizontal boxes, it controls the position of the children vertically. For vertical boxes, it controls the position of the children horizontally. The possible values are similar to those for pack.

- -
-
start 
-
This aligns elements along the top edge for horizontal boxes and along the left edge for vertical boxes.
-
center 
-
This centers the child elements in the box.
-
end 
-
This aligns elements along the bottom edge for horizontal boxes and along the right edge for vertical boxes.
-
baseline 
-
This aligns the elements so that the text lines up. This is only useful for horizontal boxes.
-
stretch 
-
This value, the default, causes the elements to grow to fit the size of the box, much like a flexible element, but in the opposite direction.
-
- -

As with the pack attribute, the align attribute applies to the box containing the elements to be aligned, not to the elements themselves.

- -

For example, the first box below will have its children stretch, because that is the default. The second box has an align attribute, so its children will be placed centered.

- -

Example 5 : Source View

- -
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<window id="yesno" title="Question" orient="horizontal"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-  <hbox>
-    <button label="Yes"/>
-    <button label="No"/>
-  </hbox>
-  <hbox align="center">
-    <button label="Maybe"/>
-    <button label="Perhaps"/>
-  </hbox>
-
-</window>
-
- -
Image:boxstyle2-b.png
- -

You can also use the style properties -moz-box-pack and -moz-box-align instead of specifying attributes.

- -
You may find the Box Alignment Example useful for trying out the various box properties.
- -

Cropping Text and Buttons

- -

You could potentially create a button element that contains a label that is larger than the maximum width of the button. Of course, a solution would be to increase the size of the button. However, buttons (and other elements with a label) have a special attribute called crop that allows you to specify how the text may be cropped if it is too big.

- -

If the text is cropped, an ellipsis (...) will appear on the button where the text was taken out. Four possible values are valid:

- -
-
left 
-
The text is cropped on its left side
-
right 
-
The text is cropped on its right side
-
center 
-
The text is cropped in the middle.
-
none 
-
The text is not cropped. This is the default value.
-
- -

This attribute is really only useful when a dialog has been designed to be useful at any size. The crop attribute can also be used with other elements that use the label attribute for labels. The following shows this attribute in use:

- -

Example 6 : Source View

- -
Image:boxstyle2.png
- -
<button label="Push Me Please!" crop="right" flex="1"/>
-
- -

Notice how the text on the button has had the right side of it cropped after the window is made smaller.

- -
-

Find files example so far : Source View

-
- -

Next, a summary and some additional details of the box model are described.

- -

-

« 上一页下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/features_of_a_window/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/features_of_a_window/index.html deleted file mode 100644 index cae533b206..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/features_of_a_window/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Features of a Window -slug: Mozilla/Tech/XUL/Tutorial/Features_of_a_Window -translation_of: Archive/Mozilla/XUL/Tutorial/Features_of_a_Window ---- -

This page has no content. Enrich MDC by contributing.

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/grids/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/grids/index.html deleted file mode 100644 index 47201b797c..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/grids/index.html +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: 网格 -slug: Mozilla/Tech/XUL/Tutorial/Grids -translation_of: Archive/Mozilla/XUL/Tutorial/Grids ---- -

XUL有一系列的元素来创建表格布局

-

 XUL的表格布局

-

使用grid元素可以在XUL中使用一系列的元素来进行元素的布局。这与HTML中的table有很大的相似性。网格本身不会有任何的显示,它仅仅是使用行和列的形式来定位其他元素。

-

一个网格内部的元素排列成行。在grid里面,你需要声明两种东西,columns和rows。正如HTML的table,你可以将label和button等内容放在row里面。但是,grid只支持单独的row或者单独的column,因此你可以将内容放在rows里面或者columns里面。通常是使用rows。但是在grid中你还是可以使用column并制定其大小和显示方式。或者你可以将内容放在columns里面,然后用row来指定其显示方式。首先看看以row的方式组织元素的方法。

-

声明一个网格

-

使用rows标签来声明一系列的row。Rows必须是grid的子元素。在rows里面你可以添加row元素,row用在每一行。在row元素中你可以放任何你想要的内容在里面。

-

相似的,列由columns来声明。其中有单独的column元素,每个你想添加的列都是一个column元素。

-

用一个例子更容易理解。

-

例子1:

-

- - - - - - -
-

<grid flex="1">

-

  <columns>

-

    <column flex="2"/>

-

    <column flex="1"/>

-

  </columns>

-

  <rows>

-

    <row>

-

      <button label="Rabbit"/>

-

      <button label="Elephant"/>

-

    </row>

-

    <row>

-

      <button label="Koala"/>

-

      <button label="Gorilla"/>

-

    </row>

-

  </rows>

-

</grid>

-
-

添加了一个两行两列的grid。每个列由一个column标签声明。每一列都设置了flex属性。每行航油两个元素都是半年。每个单元格不需要进行声明,可以直接将内容放在row元素里面。

-

带有更多元素的网格

-

你可以使用任何元素来代替上面的button元素,。如果你想要一个详细的关于容纳多个元素的单元,你可以使用嵌套的hbox或者其他box元素。一个hbox元素是一个单一的元素,但是你可以在里面放任意多的元素。例如:

-

例子2:

- - - - - - -
-

<grid flex="1">

-

 

-

  <columns>

-

    <column/>

-

    <column flex="1"/>

-

  </columns>

-

 

-

  <rows>

-

    <row>

-

      <label control="doctitle" value="Document Title:"/>

-

      <textbox id="doctitle" flex="1"/>

-

    </row>

-

    <row>

-

      <label control="docpath" value="Path:"/>

-

      <hbox flex="1">

-

        <textbox id="docpath" flex="1"/>

-

        <button label="Browse..."/>

-

      </hbox>  

-

    </row>

-

  </rows>

-

 

-

</grid>

-
-

-

注意第二列的第二行,含有一个box,box里面有一个文本框和一个按钮。你可以添加嵌套的box或者在里面放置另外一个grid。

-

由于第二行和文本框都设置了flex属性,所以改变窗口尺寸的时候文本框会改变大小,而其他元素不会改变。

-

一列的宽度由该列中最宽的元素决定。同牙膏的一行的高度由这一行中最高的元素决定。你可以使用minwidth和maxwidth以及相关的属性来对尺寸作更多的定义。

-

按列组织

-

你也可以在列中添加元素,这样一来,row元素就只是用来表示有多少行了。

-

例子3:

- - - - - - -
-

<grid>

-

  <rows>

-

    <row/>

-

    <row/>

-

    <row/>

-

  </rows>

-

 

-

  <columns>

-

    <column>

-

      <label control="first" value="First Name:"/>

-

      <label control="middle" value="Middle Name:"/>

-

      <label control="last" value="Last Name:"/>

-

    </column>

-

    <column>

-

      <textbox id="first"/>

-

      <textbox id="middle"/>

-

      <textbox id="last"/>

-

    </column>

-

  </columns>

-

 

-

</grid>

-
-

这个网格有桑航两列。元素row仅仅表示有多少行。你可以添加flex属性来使其自适应。内容在每一列中。

-

如果你在列和行中都填内容,内容将会相互覆盖,不过他们会在grid中合适的进行排列。就像在网格中有堆元素一样。

-

Grid中元素的顺序决定了哪一个会显示在上面,哪一个在下面。如果rows元素放在columns元素后面,在rows中的内容会显示在上面。如果columns放在rows元素后面,列中的内容会显示在上面。事件的获取也一样。

-

网格自适应

-

网格的一个优点是在一系列嵌套box中你可以创建在水平和竖直方向上都自适应的单元格。你可以通过使用flex属性在row和column元素上来实现。下面的例子说明了这一点:

-

例子4:

- - - - - - -
-

<grid flex="1">

-

 <columns>

-

  <column flex="5"/>

-

  <column/>

-

  <column/>

-

 </columns>

-

 <rows>

-

  <row flex="10">

-

    <button label="Cherry"/>

-

    <button label="Lemon"/>

-

    <button label="Grape"/>

-

  </row>

-

  <row flex="1">

-

    <button label="Strawberry"/>

-

    <button label="Raspberry"/>

-

    <button label="Peach"/>

-

  </row>

-

 </rows>

-

</grid>

-
-

第一列和所有两行都设置为自适应。这样的结果是第一列中的单元格在水平方向上自适应,另外每个单元格都会在竖直方向上自适应,因为两行都是自适应的,不过第一行还不止这样。第一列和第一行的单元格将会在水平方向上以5的倍率伸缩,在竖直方向上以10的倍率伸缩。

-

元素grid也要设置flex属性,这样所有的网格才能自适应,否则就只会在一个方向上自适应。

-

列宽扩展

-

让很多行和列中的一个单元格扩展是没有意义的。但是可以让一行或者一列整个的扩展。为了实现这一点只需要在rows元素中添加一个元素。比如可以使用一个box样式。让回将其他元素放在里面。下面是一个简单的例子:

-

例子5:

- - - - - - -
-

<grid>

-

  <columns>

-

    <column flex="1"/>

-

    <column flex="1"/>

-

  </columns>

-

 

-

  <rows>

-

    <row>

-

      <label value="Northwest"/>

-

      <label value="Northeast"/>

-

    </row>

-

    <button label="Equator"/>

-

    <row>

-

      <label value="Southwest"/>

-

      <label value="Southeast"/>

-

    </row>

-

  </rows>

-

</grid>

-
-

按钮将会扩展以适合整个grid的宽带,因为它不是一个grid的行中的元素。你也可以将相似的方式用在两个列中。这样就会扩展以一与网格的高度相适应。你可以在行和列上都使用,如果你想这样做。

-

下一节我们来看看内容面板

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/groupboxes/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/groupboxes/index.html deleted file mode 100644 index c62dd0f004..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/groupboxes/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: 分组框 -slug: Mozilla/Tech/XUL/Tutorial/Groupboxes -translation_of: Archive/Mozilla/XUL/Tutorial/Groupboxes ---- -

    本章介绍在组框中添加元素的方法。

-
-

Groupboxes

-
- Edit section
-

    HTML 通过了 fieldset 元素来使元素分组,一般的会在元素的边上画一个框来显示元素的关系。比如一系列单选按钮。XUL 也通过了 groupbox 元素来完成相似的功能。

-

    就像名字暗示的一样 groupbox 是一类box,这意味着在其中的元素可以安装box指定的形式排列。与一般的box相比groupbox有两点不同。

- -

    因为组框是一种box,你可以使用如 orient flex 等属性。你可以把任何你想放入box中的元素放入组框中,无论他们有什么关系。

-

    组框顶端的标签使用 caption 元素创建,类似于 HTML 中的legend 元素,请把 caption 作为第一个元素放入组框。

-
-

一个组框的例子

-
- Edit section
-

    下面的例子显示一个简单组框。

-

Example 1  : Source View

-
- Image:titledbox1.png
-
<groupbox>
-  <caption label="Answer"/>
-  <description value="Banana"/>
-  <description value="Tangerine"/>
-  <description value="Phone Booth"/>
-  <description value="Kiwi"/>
-</groupbox>
-
-

    以上代码表示:四条文本被一个以 Answer 为标签的box框起来,注意组框默认的定向方式为垂直定向,所以元素会排成一列。

-
-
-

更复杂的标题

-
- Edit section
-

    你可以在 caption 元素中添加子元素构造一个更复杂的标题,比如,Mozilla的字体选择面板使用一个下拉菜单作为标题。尽管任何元素都可以在这里使用,通常的是使用下拉菜单和复选框。

-

Example 2  : Source View

-
- Image:groupbox2.png
-
<groupbox flex="1">
-  <caption>
-    <checkbox label="Enable Backups"/>
-  </caption>
-  <hbox>
-    <label control="dir" value="Directory:"/>
-    <textbox id="dir" flex="1"/>
-  </hbox>
-  <checkbox label="Compress archived files"/>
-</groupbox>
-
-


-     这个例子里一个 checkbox 被作为标题。我看可以根据复选框是否被选中,使用脚本来控制组框中的元素是否有效。组框中包含了一个有 label textbox 的水平框,文本框和组框均被设定为是可变的,所以元素会随着窗口延伸。复选框出现在组框底下是因为组框默认为垂直定向。下一章我们为find files 对话框添加一个组框。

-
-
-
-

单选组

-
- Edit section
-

    你可以使用 radiogroup 把单选按钮组织在一起。 radiogroup 是一种box,你可以在其中放置任何元素,并且他对 radio 按钮具有特殊的处理。

-

    那些放在单选组里的单选按钮会被组织起来,即使它在其他的box中 。也可添加额外的元素,如下例:

-

Example 3  : Source View

-
<radiogroup>
-  <radio id="no" value="no" label="No Number"/>
-  <radio id="random" value="random" label="Random Number"/>
-  <hbox>
-    <radio id="specify" value="specify" label="Specify Number:"/>
-    <textbox id="specificnumber"/>
-  </hbox>
-</radiogroup>
-
-

    注意 radiogroup 不会画出边框。如果需要边框及标题请放置在 groupbox 中。

-

    接下来,我们使用学到的新知识来为findfile对话框添加元素。(additional elements to the find files dialog.)

-

 

-
-

« Previous Next »

-
-

  

-

 

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/index.html deleted file mode 100644 index a164d16f7f..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/index.html +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: XUL 教程 -slug: Mozilla/Tech/XUL/Tutorial -tags: - - XUL - - XUL_Tutorial -translation_of: Archive/Mozilla/XUL/Tutorial ---- -

- 这份XUL的教程是源自 Neil Deakin之手。很感谢他能给MDC授权使用这篇文章。

- -

这篇教程会教你如何开发和设计基于XUL(XML User-interface Language XML用户交互语言)的应用程序. XUL是Mozilla创建的并且应用在Mozilla的应用程序的界面描述语言。

- -
第一章 引言
- - - -
简单的示例
- - - -
箱模型
- - - -
更多的布局元素
- - - -
工具栏和菜单
- - - -
事件和脚本
- - - -
文档对象模型
- - - -
- - - -
RDF 和模板
- - - -
本地化和皮肤
- - - -
绑定
- - - -
特殊的窗口类型
- - - -
安装
- - - -
-
关于原始文档的信息
- - -
- -

 

- -

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/input_controls/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/input_controls/index.html deleted file mode 100644 index d901c50eeb..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/input_controls/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: XUL_教程/输入控件 -slug: Mozilla/Tech/XUL/Tutorial/Input_Controls -tags: - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/Input_Controls ---- -

-

« 上一页下一页 »

-

-

 

-

文本输入框

-

HTML有一个输入元素可以用于文本输入操作。 XUL 有一个相似的元素, textbox, 用于文本输入。 不用任何属性, textbox 元素创建一个框让用户可以输入文本。文本框具有像HTML的输入操作相同的许多属性。下面列出其中一部份:

-
-
- id 
-
- 控件的唯一性标识。
-
- class 
-
- 输入框的样式。
-
- value 
-
- 如果你要输入框显示一个默认值,可以指定此属性。
-
- disabled 
-
- 如果需要禁用文本输入框可以将这个属性设为true
-
- type 
-
- 你可以将这个属性的值设为password, 创建一个输入框隐藏用户的输入内容。 通常用于密码输入框。
-
- maxlength 
-
- 输入框允许输入的字符最大数量。
-
-

注解:在HTML里, 使用input元素区分几个不同类型的字段,在XUL里用每种类型对元素进行区分。

-

下面列出输入框的一些属性:

-

例1 : Source View

-
<label control="some-text" value="Enter some text"/>
-<textbox id="some-text"/>
-<label control="some-password" value="Enter a password"/>
-<textbox id="some-password" type="password" maxlength="8"/>
-
-

多行文本输入框

-

上面的textbox 例子创建的输入框仅仅可以输入一行文本。HTML也有一个textarea元素用来创建一个大的文本输入区域。在XUL,你可以使用textbox元素达到很好的效果 -- 这两种元素都不是很常用。如果你设置multiline属性为true,文本输入框将显示为多行。

-

例2 : Source View

-
<textbox multiline="true"
-           value="This is some text that could wrap onto multiple lines."/>
-
-

就像HTML中的textarea,你可以使用 rowscols 属性设置大小。这可以设置显示字符的行和列数量。

-
-

我们文件查找的例子

-

让我们给文件查找对话框添加一个搜索输入框。我们将要使用 textbox 元素。

-
<label value="Search for:" control="find-text"/>
-<textbox id="find-text"/>
-
-<button id="find-button" label="Find"/>
-
-
-
- Image:inputs1.png
-
-

将这些行插入到在前一节最后我们创建的按钮的前面。如果你打开这个窗口,你将会看到像显示的图片一样的效果。

-

注解:标签和文本输入框现在已经显示在窗口里。文本输入框已具有完全的功能你可以在它里面输入文本和选中文本。使用control 属性后因此当label 被点击后输入框被选中。

-

多选和单选按钮

-

另外两个元素是用于创建多选输入框和单选按钮。它们是按钮的变体。多选输入框元素(checkbox element)有多个选择项,可以被选或不选。单选按钮的用法相似,它有一个集合并且只能选择其中之一。

-

你可以像使用按钮的属性一样使用多选输入框和单选按钮。下面的例子向你展示一些简单的多选输入框和单选按钮。

-
<checkbox id="case-sensitive" checked="true" label="Case sensitive"/>
-<radio id="orange" label="Orange"/>
-<radio id="violet" selected="true" label="Violet"/>
-<radio id="yellow" label="Yellow"/>
-
-

第一行创建一个简单的 checkbox。当用户点击多选项,它在选中和非选中之间切换。checked 属性可以用在表明它的默认状态。你可以将它的值设为true或者falselabel属性可以用于设置显示在多选项旁边的文本。对于radio 按钮,你可以使用 selected 属性代替 checked 属性。设置它的值为 true 让默认选中其中的一个单选按钮,或者不选中其他的单选按钮。

-

单选项组元素

-

为了把单选按钮组合在一起,你需要用到radiogroup 元素。 在单选按钮组中同一时间只允许其中的一个单选按钮被选中。在其中的一个中点击将会把同一组中的其他按钮都设成关闭。下面的例子很好地示范了这一点。

-

例3 : Source View

-
<radiogroup>
-  <radio id="orange" label="Orange"/>
-  <radio id="violet" selected="true" label="Violet"/>
-  <radio id="yellow" label="Yellow"/>
-</radiogroup>
-
-

属性

-

像按钮一样,多选框和单选按钮可以用文本标签和图片进行包装,当它被按下时通过切换图片来表达选中或没选中。多选项有很多与按钮相同的属性:

-
-
- label 
-
- 在多选项或单选按钮上的文本标签。
-
- disabled 
-
- 设为truefalse 去禁用或启用多选项或单选按钮。
-
- accesskey 
-
- 用于选中元素的快捷键。字母会在标签中以下划线显示。
-
-
-

到目前为止文件查找的例子 : Source View

-
-

在下一节,我们将可以看到一些适用于输入和选择数值的元素。

-
-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/introduction/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/introduction/index.html deleted file mode 100644 index 5e80393d30..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/introduction/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: XUL_教程/引言 -slug: Mozilla/Tech/XUL/Tutorial/Introduction -tags: - - XUL_Tutorial -translation_of: Archive/Mozilla/XUL/Tutorial/Introduction ---- -

-

下一页 »

-

- -

这份教程可以帮助你如何用 XUL (XML用户界面语言) 来创建跨平台的可描述界面的应用程序.

- -

这份教程将设计出一个"查找文件"的应用程序界面, 类似于Macintosh的Sherlock或是Windows的文件查找的窗口. 只会提供基本的界面以及一些简单的功能函数. 真正的文件查找功能并没有实现,.

- -

什么是XUL,及为什么要创建它?

- -

XUL (发音是 zool,有点像cool) 是为开发更快更简单的Mozilla浏览器而开发的. 这是一个基于 XML 可扩展描述语言 的语言 ,所以XML的所有特性都适用于XUL.

- -

大多数应用程序在开发的时候都需要应用某个特定平台的特性,这就使得创建一个跨平台的软件变得费时费力。而这对于某些用户或许并非重要,但是对那些想在其它设备上,比如手持设备或机顶盒上,运行一个应用程序的用户来说却,跨平台确是至关重要的。

- -

在过去诸多跨平台的解决方案都已被开发出来。比如Java的可移植性就是其主要卖点。XUL则是一个那样的语言,它被设计出用于创建可移植的用户界面。

- -

创建一个应用程序是要花费好多时间的,哪怕它只工作在某个平台下。编译和排错需要的时间可能会很多。而使用XUL,一个界面可以被快速方便地制作和修改。

- -

XUL具备所有其它XML语言的所有优点。举例来说,XHTML或者其它XML语言,比如MathML 数学标记语言 或 SVG 可伸缩矢量图,可以被插入到XUL当中。同样,XUL中的文本也可以很容易地被本地化,那意味着它可以稍加努力就可以被翻译成其它国家的语言。样式表可以被提供用于修改用户界面的外观(就像WinAmp的主题和皮肤或者某些窗口管理器)。

- -

用XUL可以做些什么类型的用户界面?

- -

XUL有能力创建现代图形界面中的大多数元件。它的应用广泛到可以满足特定设备特殊要求,而它的强大足以使开发者创建出复杂的界面。

- -

下列组件可以被创建:

- - - -

显示的内容创建自XUL文件及数据源的数据,在Mozilla中,数据源包含用户邮件箱、书签、搜索结果等等,菜单、树状列表和其它元素都能从那添加,也可以从RDF文件添加自定义的数据。

- -

创建XUL应用程序的方法有几种:

- - - -

前三种类型需要在用户电脑做安装操作,但是这样程序就没有安全限制了,可以访问本地文件和读写属性。例如扩展,所包含的XUL文件、脚本和图像将被打包成单一文件,用户下载后安装到本地。基于Mozilla的程序比如Firefox,提供了扩展管理器来对包进行安装管理,而不需要很多代码操作。 XUL也可以从远程WEB站点打开,然而这样很多类型操作会有限制,以及一些XUL外观效果会失效。如果你需要从远程站点载入XUL内容,WEB服务器必须设置XUL文件头格式为'application/vnd.mozilla.xul+xml'。通常XUL文件使用.xul为扩展名,你可以从Mozilla浏览器打开它,跟打开其它文件一样,点击菜单【打开文件】或者直接在地址栏输入URL地址。

- -

学习这份教程之前,我需要做些什么知识准备?

- -

你需要理解HTML,以及了解XML和CSS一些基础知识,下面几点建议需要注意:

- - - -

基于Mozilla和Gecko平台的程序都支持XUL,例如Mozilla Firefox和Netscape6。随着时间推移XUL在语法有些不同,你可能需要使用适当的版本来进行工作。在大多例子里使用的是Mozilla 1.0或更高版本。XUL在Firefox和其它基于Mozilla浏览器中是相似的,虽然也存在一些细微的差别,例如工具栏。 该指南将最大限度介绍XUL方方面面,然而还是无法讲述所有的特征。一旦你熟悉XUL,可以使用XUL Element Reference来查找其它标签的属性特征。

- -

-

下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/introduction_to_rdf/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/introduction_to_rdf/index.html deleted file mode 100644 index 03e0c64a88..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/introduction_to_rdf/index.html +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: XUL_教程/RDF介绍 -slug: Mozilla/Tech/XUL/Tutorial/Introduction_to_RDF -translation_of: Archive/Mozilla/XUL/Tutorial/Introduction_to_RDF ---- -

 

-

-

« 上一页下一页 »

-

-

 

-

    本章我们关注与RDF (资源描述框架).

-

资源描述框架

-

    我们可以使用 tree 元素呈现数据集,就像书签和邮件管理器一样。然而这样却使向 XUL 文件中直接添加数据变得很不方便。直接在XUL文件中修改书签变得十分困难。这就需要RDF 数据结构。

-

    RDF (资源描述框架)是一种用于储存像书签或邮件这样的资源的格式。其他形式的数据可以被编码为RDF,也可以有RDF创建其他形式的数据。这是 Mozilla 处理像书签、邮件、历史等的方法。Mozilla 为这些常用的数据提供了数据源,使我们很容易使用他们。

-

    你可以使用任意的RDF数据源来填充树结构,或者仅把RDF指向一个存有数据的XML文件。这使得显示含有许多行的树变得非常容易。RDF 也可以填充其他的 XUL 元素比如列表及菜单,见下一章。

-

    这里是关于RDF的一个非常简略的概述,希望看到更为详尽的内容请访问XULPlanet上的 Introduction to the RDF Model。如果你刚刚接触RDF请继续向下阅读。

-

    更多信息参见 RDF specification.

-

RDF/XML

-

    RDF 包含这数据的图表示形式。 RDF/XML 时一种用于表示RDF数据的XML语言。它包含非常简单的元素集,下面的例子显示一个简单的RDF模板。

-
<?xml version="1.0"?>
-<RDF:RDF
-  xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-  ...
-</RDF:RDF>
-
-

    与XUL头有些相似,window 元素被 RDF 元素代替。同样为RDF定义了名空间,在RDF元素中将填充一些数据。可以在Mozilla文件夹中找到一些 RDF/XML 文件的例子,他们以rdf作为后缀。

-

RDF 数据库

-

    让我们来以有RDF产生的书签列表为例。书签列表包含一系列记录,每项记录都有一系列数据相关联,比如书签标题,URL,访问日期等。

-

    把书签当作数据库来考虑,这个数据库是一个含有多个域的表格。这个列表需要分级,因为我们需要利用文件夹来分组书签。每一个域都来源与RDF数据库,都由名字相关联。名字用URI描述。

-

    例如Mozilla书签列表的名字的RUI描述如下:

- - - - - - - - - - - - - - - - - - - - - - - -
Namehttp://home.netscape.com/NC-rdf#NameBookmark name
URLhttp://home.netscape.com/NC-rdf#URLURL to link to
Descriptionhttp://home.netscape.com/NC-rdf#DescriptionBookmark description
Last Visitedhttp://home.netscape.com/WEB-rdf#LastVisitDateDate of last visit
-

    这些是按照名空间加域名构造的。下一章,我们利用它来自动填充数据域。注意访问日期的名空间与其他的不同。

-

RDF/XML 文件样例

-

    下面是一个RDF/XML文件,有三条记录和三个域。

-
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-         xmlns:ANIMALS="http://www.some-fictitious-zoo.com/rdf#">
-
-  <RDF:Seq about="http://www.some-fictitious-zoo.com/all-animals">
-    <RDF:li>
-       <RDF:Description about="http://www.some-fictitious-zoo.com/mammals/lion">
-         <ANIMALS:name>Lion</ANIMALS:name>
-         <ANIMALS:species>Panthera leo</ANIMALS:species>
-         <ANIMALS:class>Mammal</ANIMALS:class>
-       </RDF:Description>
-    </RDF:li>
-    <RDF:li>
-       <RDF:Description about="http://www.some-fictitious-zoo.com/arachnids/tarantula">
-         <ANIMALS:name>Tarantula</ANIMALS:name>
-         <ANIMALS:species>Avicularia avicularia</ANIMALS:species>
-         <ANIMALS:class>Arachnid</ANIMALS:class>
-       </RDF:Description>
-    </RDF:li>
-    <RDF:li>
-       <RDF:Description about="http://www.some-fictitious-zoo.com/mammals/hippopotamus">
-         <ANIMALS:name>Hippopotamus</ANIMALS:name>
-         <ANIMALS:species>Hippopotamus amphibius</ANIMALS:species>
-         <ANIMALS:class>Mammal</ANIMALS:class>
-       </RDF:Description>
-    </RDF:li>
-  </RDF:Seq>
-</RDF:RDF>
-
-

    对每一种动物使用一条记录描述。每一个 RDF:Description 标签描述一条记录。每条记录定义了三个域:namespeciesclass。虽然没有必要让每一条记录拥有相同的域,但是最好如此。

-

    三个域都在 ANIMALS名空间下, ANIMALS名空间在RDF标签中定义。选择这个名字是因为它的意思,但完全可以选择其他名字。这里的名空间定义是有用的,因为如果使用样式表class 域可能发生冲突。

-

     Seqli 元素在列表中区分每一条记录,与HTML 列表中的定义很相似。 Seq 指明记录是有序的紧挨着的,对于无序内容使用 Bag 标签, Alt 用于指明其中的记录只能选择其一(如映射 URL)。

-

    在XUL文件中可以通过名空间和域名来引用其中的数据,在上例中,下面的URI描述其中的数据域:

- - - - - - - - - - - - - - - -
Namehttp://www.some-fictitious-zoo.com/rdf#name
Specieshttp://www.some-fictitious-zoo.com/rdf#species
Classhttp://www.some-fictitious-zoo.com/rdf#class
-

    记下来,看看如何使用RDF来填充XUL数据。

-

-

« 上一页下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/list_controls/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/list_controls/index.html deleted file mode 100644 index 27486e030b..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/list_controls/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: XUL_教程/列表控件 -slug: Mozilla/Tech/XUL/Tutorial/List_Controls -tags: - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/List_Controls ---- -

-

« 上一页下一页 »

-

-

 

-

列表控件

-

列表控件用来在列表中显示许多的项目。用户可以从列表中选择一个项。

-

XUL提供两种类型的元素去创建列表,listbox元素用于创建多行的列表框,和menulist元素用于创建下拉列表框。它们的工作方法类似于在HTML中的 select元素,它们执行的功能相同,但XUL的元素包括更多的特性。

-

简单列表框使用listbox元素创建列表框,和使用listitem元素创建每个项目。例如,这个列表框有四行,每个项目使用一行。

-

例1 : Source View

-
- 图像:lists1.png
-
<listbox>
-  <listitem label="Butter Pecan"/>
-  <listitem label="Chocolate Chip"/>
-  <listitem label="Raspberry Ripple"/>
-  <listitem label="Squash Swirl"/>
-</listbox>
-
-

如HTML中的option元素,你可以使用value为每个项指定一个值。你也可以在脚本中使用这个值。列表框会默认设置一个合适的尺寸,但你可以通过rows属性来控制尺寸。通过设置它来确定在列表框中显示的行数。如果列表包括的项超出这个值,在显示时将会出现滚动条。

-

下面这个例子演示这些不同的特性:

-

例2 : Source View

-
<listbox rows="3">
-  <listitem label="Butter Pecan" value="bpecan"/>
-  <listitem label="Chocolate Chip" value="chocchip"/>
-  <listitem label="Raspberry Ripple" value="raspripple"/>
-  <listitem label="Squash Swirl" value="squash"/>
-</listbox>
-
-

这个例子已改成一次只显示3行。已经为列表中的每个项目添加了值。列表框还有其他的一些特性,将在后面进行描述。

-

多列列表框

-

列表框也支持多列。每个单元格可以有独有的内容,即使只使用文本。当用户选择列表中的一个项目时,当前的行将被选中。你不能只选中其中的一个单元格。

-

在列表框中有两个标签可以使用。listcols元素用来对列信息进行控制,每个列指定一个listcol元素。在列表框中你将需要为每个列指定一个listcol元素。

-

listcell元素用于一行中的每个单元格。 如果你需要3列,你就需要增加3个listcell元素到每个listitem里面。要给单元格指定文本内容,替换listcell元素里面的label属性。

-

一个简单的例子,如果只有一个列,你也需要将 label属性直接地填充在listitem元素里面的listcell元素中, 看起来像前面的例子里一样。

-

下面是一个有2列和3行的列表框的例子:

-

例3 : Source View

-
<listbox>
-  <listcols>
-    <listcol/>
-    <listcol/>
-  </listcols>
-  <listitem>
-    <listcell label="George"/>
-    <listcell label="House Painter"/>
-  </listitem>
-  <listitem>
-    <listcell label="Mary Ellen"/>
-    <listcell label="Candle Maker"/>
-  </listitem>
-  <listitem>
-    <listcell label="Roger"/>
-    <listcell label="Swashbuckler"/>
-  </listitem>
-</listbox>
-
-

表头行

-

列表框一直允许使用一个特殊的表头行。 这和正常的行显示有很大不同。你可以使用它来创建列头。有两个新的元素可以使用。

-

listhead元素用于表头行,就像listitem元素用于普通行。表头行不是普通行,因此使用脚本去获取列表的首行时获得的将是表头行的下一行。

-

listheader元素用于表头行里的单元格。使用 label属性设置表头行单元格的标签。

-

这是一个带表头行的简单例子:

-

例4 : Source View

-
- Image:morelists1.png
-
<listbox>
-
-  <listhead>
-    <listheader label="Name"/>
-    <listheader label="Occupation"/>
-  </listhead>
-
-  <listcols>
-    <listcol/>
-    <listcol flex="1"/>
-  </listcols>
-
-  <listitem>
-    <listcell label="George"/>
-    <listcell label="House Painter"/>
-  </listitem>
-  <listitem>
-    <listcell label="Mary Ellen"/>
-    <listcell label="Candle Maker"/>
-  </listitem>
-  <listitem>
-    <listcell label="Roger"/>
-    <listcell label="Swashbuckler"/>
-  </listitem>
-
-</listbox>
-
-

在这个例子中,flex属性用于制作灵活的列。这个属性将在最后一节中说明,这里它允许列进行水平扩展。你可以调整窗口的大小去查看列根据窗口而进行伸缩的效果。如果你水平缩小,表格中的标签会自动截成带省略号(...)的样子。你可以在表格或项中使用crop属性的值为none去禁止标签被截。

-

下拉列表

-

在HTML里可以使用select元素创建下拉列表。用户可以在文本框内看到一个单选并且点击箭头或其他类似按钮文本制做成不同的选项。其他的选择将会显示在一个弹出的窗口中。 XUL有一个menulist元素可以实现这种效果。它是使用在一个文本框的旁边加一个按钮。选中这个名字是因为当它被选中时会弹出一个菜单。

-

描述一个下拉列表需要三个元素。第一个是menulist 元素, 在按钮的旁边创建一个文本输入框。第二,menupopup,当按钮被点击时创建并显示弹出窗口。第三,menuitem,创建单独的选择。

-

下面的范例很好地描述了它的语法:

-

Example 5 : Source View

-
- Image:inputs2.png
-
<menulist label="Bus">
-  <menupopup>
-    <menuitem label="Car"/>
-    <menuitem label="Taxi"/>
-    <menuitem label="Bus" selected="true"/>
-    <menuitem label="Train"/>
-  </menupopup>
-</menulist>
-
-

这个菜单列表包括了四个项,全部都使用一个menuitem 元素。要显示菜单里的项,点击菜单列表中的箭头按钮。当一个被选中,它会在菜单列表中显示为选中。selected属性用于设置哪个被默认选中。

-

可编辑的菜单列表

-

默认情况,你只可以从列表中进行选择。你不能在它上面输入你自己的文本。一个特别的菜单列表允许编辑文件框中的文本。例如,浏览器的地址输入框有一个下拉列表去选择以前输入过的地址,但你也可以输入你自己的地址。

-

创建一个可编辑的菜单列表,像下面这样添加editable 属性:

-

例6 : Source View

-
<menulist editable="true">
-  <menupopup>
-    <menuitem label="www.mozilla.org"/>
-    <menuitem label="www.xulplanet.com"/>
-    <menuitem label="www.dmoz.org"/>
-  </menupopup>
-</menulist>
-
-

这里创建的地址输入框由三个预设的选择,用户可以从中选择或者他们可以在文本框内输入一个他们自己的地址。用户输入的文本不会添加到新的选择中。因为label属性没有用在这个例子中,默认是空的。

-

在下一节我们将会学习creating progress meters

-

-

« 上一页下一页 »

-

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/localization/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/localization/index.html deleted file mode 100644 index ffa7dd99de..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/localization/index.html +++ /dev/null @@ -1,296 +0,0 @@ ---- -title: 本地化 -slug: Mozilla/Tech/XUL/Tutorial/Localization -translation_of: Archive/Mozilla/XUL/Tutorial/Localization ---- -

 

-
-

« Previous Next »

-
-

  

-

 

-

XUL 和 XML 提供的实体(entities)是一个本地化的好方法。

-
-

实体

-
- Edit section
-

    不少软件都希望将界面上的语言尽可能简单的翻译为另外的语言。通常他们会为每一种语言创建一份字符串列表,来代替在代码中进行硬编码。代码中的每一段文本都代表字符串列表中的一项, XML 提供的实体正好实现这一目的。

-

    如果你写过 HTML 代码,你应该对实体很熟悉 , 像这样的代码 &lt;&gt; 是作为“小于”和“大于”在文本中的替代出现的。XML 的语法允许你定义用户实体。你可以使用这些实体代替它实际的值,当然这个值可以是一段文本。实体可以用在任何文本应该出现的地方,包括属性。下面的例子在一个按钮中使用了实体。

-
<button label="&findLabel;"/>
-
-

    出现在按钮上的文本将是 &findLabel; 所代表的值。对每一种所要支持的语言需要创建一个文件包含对实体的定义。在英语中,&findLabel; 实体可能代表文本 "Find"。

-
-
-

DTD 文件

-
- Edit section
-

    实体在 Document Type Definition (DTD) 文件中定义。这类文件往往用于特定 XML 文件的语法和语义的定义,当然也可以用来定义实体。在  Mozilla 的 chrome 体系中,你会在 locales 子目录中找到 DTD 文件。对应一个XUL 文件,一般会有一个 DTD 文件 (extension .dtd)。

-

    如果你查看 chrome 目录,你会看到一个针对你所用语言的压缩包 (en-US.jar 默认是英语的语言包) 。你也可能会找到多种语言的语言包:美式英语 (en-US) 、法语 (fr)等。在这些压缩包中,你会发现它保存着每个窗口的本地化文本。这种压缩包的结构与 skins 是很相似的。

-

    你可以把你定义实体的 DTD 文件放置到语言包里,一般的,你应该为每一个 XUL 文件建立一个 DTD 文件,通常使用相同的文件名但以 .dtd 作为后缀。因此对应我们的 findfile 对话框,我们需要一个 findfile.dtd 文件。

-

    对于非安装的 chrome 文件,你可以简单的把 DTD 文件放在与 XUL 相同的目录中。

-
- 注意: 你需要将含有非 ASCII 字符的 DTD 文件的字符编码设为 UTF-8。也就是说你应该按照 UTF-8 格式 (without BOM)保存。参见 Mozilla Language Packs.
-

    一旦为你的 XUL 文件创立 DTD 文件,你应该在 XUL 文件上添加一行以声明使用 DTD 文件。否则会发生找不到实体的错误,在 XUL 文件的头部加如下一行。

-
<!DOCTYPE window SYSTEM "chrome://findfile/locale/findfile.dtd">
-
-

    这一行表示这个 URL 被当作一个 DTD 使用。在这个例子中,我们引入了我们需要的 findfile.dtd 文件,这一行通常放在 window 元素之前。

-

    你同样需要在 chrome.manifest 文件中添加本地化信息,如下:

-
locale findfile en-US locale/
-
-
-
-

申明实体

-
- Edit section
-

    实体的申明使用如下语法:

-
<!ENTITY findLabel "Find">
-
-

    上例创建了一个名为 findLabel 值为 "Find" 的实体,这意味着在文本中的任意位置出现的 "&findLabel;" 都将会被 "Find" 替代。注意实体申明无需反斜杠结束。在不同语言的 DTD 文件中,文件使用的不同的语言替代即可。

-
日文:
-<!ENTITY findLabel "検索">
-
-

    例如,下面的文字:

-
<description value="&findLabel;"/>
-
-

被翻译为:

-
英文版:
-<description value="Find"/>
-
-日文版:
-<description value="検索"/>
-
-

    你应该为你在界面中出现的每一个标签或字符串申明一个实体,在XUL文件中不应出现任何的显示文本。

-

    补充来说你可以在任何因语言不同而不同的的地方使用实体。以 Access keys 及 keyboard shortcuts 为例。

-
 XUL
- <menuitem label="&undo.label;" accesskey="&undo.key;"/>
- DTD
- <!ENTITY undo.label "Undo">
- <!ENTITY undo.key "u">
-
-

    上面的例子使用了两个实体,一个由于 Undo 菜单项的标签,第二个用于快捷键。

-
-
-

改写 Find Files 的例子

-
- Edit section
-

    让我们看一看如何使用DTD文件修改我们的find files 对话框并将所有文本放在一起。整个文件列在下面。

-
<?xml version="1.0"?>
-
-<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
-<?xml-stylesheet href="findfile.css" type="text/css"?>
-
-<!DOCTYPE window SYSTEM "chrome://findfile/locale/findfile.dtd">
-
-<window
-  id="findfile-window"
-  title="&findWindow.title;"
-  persist="screenX screenY width height"
-  orient="horizontal"
-  onload="initSearchList()"
-  xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul">
-
-<script src="findfile.js"/>
-
-<popupset>
-   <menupopup id="editpopup">
-     <menuitem label="&cutCmd.label;" accesskey="&cutCmd.accesskey;"/>
-     <menuitem label="&copyCmd.label;" accesskey="&copyCmd.accesskey;"/>
-     <menuitem label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;" disabled="true"/>
-   </menupopup>
-</popupset>
-
-<keyset>
-   <key id="cut_cmd" modifiers="accel" key="&cutCmd.commandkey;"/>
-   <key id="copy_cmd" modifiers="accel" key="&copyCmd.commandkey;"/>
-   <key id="paste_cmd" modifiers="accel" key="&pasteCmd.commandkey;"/>
-   <key id="close_cmd" keycode="VK_ESCAPE" oncommand="window.close();"/>
-</keyset>
-
-<vbox flex="1">
-
- <toolbox>
-
-  <menubar id="findfiles-menubar">
-    <menu id="file-menu" label="&fileMenu.label;"
-        accesskey="&fileMenu.accesskey;">
-      <menupopup id="file-popup">
-        <menuitem label="&openCmd.label;"
-                  accesskey="&openCmd.accesskey;"/>
-        <menuitem label="&saveCmd.label;"
-                  accesskey="&saveCmd.accesskey;"/>
-        <menuseparator/>
-        <menuitem label="&closeCmd.label;"
-                  accesskey="&closeCmd.accesskey;" key="close_cmd" oncommand="window.close();"/>
-      </menupopup>
-    </menu>
-    <menu id="edit-menu" label="&editMenu.label;"
-          accesskey="&editMenu.accesskey;">
-      <menupopup id="edit-popup">
-        <menuitem label="&cutCmd.label;"
-                  accesskey="&cutCmd.accesskey;" key="cut_cmd"/>
-        <menuitem label="&copyCmd.label;"
-                  accesskey="&copyCmd.accesskey;" key="copy_cmd"/>
-        <menuitem label="&pasteCmd.label;"
-                  accesskey="&pasteCmd.accesskey;" key="paste_cmd" disabled="true"/>
-      </menupopup>
-    </menu>
-  </menubar>
-
-  <toolbar id="findfiles-toolbar">
-    <toolbarbutton id="opensearch" label="&openCmdToolbar.label;"/>
-    <toolbarbutton id="savesearch" label="&saveCmdToolbar.label;"/>
-  </toolbar>
- </toolbox>
-
- <tabbox>
-  <tabs>
-    <tab label="&searchTab;" selected="true"/>
-    <tab label="&optionsTab;"/>
-  </tabs>
-
-  <tabpanels>
-
-   <tabpanel id="searchpanel" orient="vertical" context="editpopup">
-
-   <description>
-     &findDescription;
-   </description>
-
-   <spacer class="titlespace"/>
-
-   <groupbox orient="horizontal">
-     <caption label="&findCriteria;"/>
-
-     <menulist id="searchtype">
-       <menupopup>
-         <menuitem label="&type.name;"/>
-         <menuitem label="&type.size;"/>
-         <menuitem label="&type.date;"/>
-       </menupopup>
-     </menulist>
-   <spacer class="springspace"/>
-     <menulist id="searchmode">
-       <menupopup>
-         <menuitem label="&mode.is;"/>
-         <menuitem label="&mode.isnot;"/>
-       </menupopup>
-     </menulist>
-   <spacer class="springspace"/>
-
-   <menulist id="find-text" flex="1"
-             editable="true"
-             datasources="file:///mozilla/recents.rdf"
-             ref="http://www.xulplanet.com/rdf/recent/all">
-     <template>
-       <menupopup>
-         <menuitem label="rdf:http://www.xulplanet.com/rdf/recent#Label" uri="rdf:*"/>
-       </menupopup>
-     </template>
-   </menulist>
-
-   </groupbox>
-
-  </tabpanel>
-
-  <tabpanel id="optionspanel" orient="vertical">
-     <checkbox id="casecheck" label="&casesensitive;"/>
-     <checkbox id="wordscheck" label="&matchfilename;"/>
-    </tabpanel>
-
-  </tabpanels>
- </tabbox>
-
- <tree id="results" style="display: none;" flex="1">
-   <treecols>
-     <treecol id="name" label="&results.filename;" flex="1"/>
-     <treecol id="location" label="&results.location;" flex="2"/>
-     <treecol id="size" label="&results.size;" flex="1"/>
-   </treecols>
-
-   <treechildren>
-     <treeitem>
-       <treerow>
-         <treecell label="mozilla"/>
-         <treecell label="/usr/local"/>
-         <treecell label="&bytes.before;2520&bytes.after;"/>
-       </treerow>
-     </treeitem>
-   </treechildren>
- </tree>
-
- <splitter id="splitbar" resizeafter="grow" style="display: none;"/>
-
- <spacer class="titlespace"/>
-
- <hbox>
-   <progressmeter id="progmeter" value="50%" style="display: none;"/>
-   <spacer flex="1"/>
-   <button id="find-button" label="&button.find;"
-           oncommand="doFind()"/>
-   <button id="cancel-button" label="&button.cancel;"
-           oncommand="window.close();"/>
- </hbox>
-</vbox>
-
-</window>
-
-

    每一个字符串均被实体引用代替。一个 DTD 文件被包含在XUL文件的开头。每一个被引用的实体必须在DTD文件中申明,如果发现引用的实体没有申明,则窗口不会显示。

-

    注意实体的名字并不重要,在上面的例子里实体的名字被分成几段来写,请你不要这样,请按照其他代码的书写习惯来写实体引用。

-

    你可能已经注意到里字符串 '2520 bytes' 被两个实体代替。这是因为在别的语言中可能会有不同的语法要求。比如,可能要求数字写在后面而把 'bytes' 写在前面。当然对于 KB 、MB 会有更复杂的顺序要求。

-

    键盘访问键及快捷键也被翻译为实体因为对不同的语言这些也会不同。

-

    下面是 DTD 文件 - findfile.dtd:

-
<!ENTITY findWindow.title "Find Files">
-<!ENTITY fileMenu.label "File">
-<!ENTITY editMenu.label "Edit">
-<!ENTITY fileMenu.accesskey "f">
-<!ENTITY editMenu.accesskey "e">
-<!ENTITY openCmd.label "Open Search...">
-<!ENTITY saveCmd.label "Save Search...">
-<!ENTITY closeCmd.label "Close">
-<!ENTITY openCmd.accesskey "o">
-<!ENTITY saveCmd.accesskey "s">
-<!ENTITY closeCmd.accesskey "c">
-<!ENTITY cutCmd.label "Cut">
-<!ENTITY copyCmd.label "Copy">
-<!ENTITY pasteCmd.label "Paste">
-<!ENTITY cutCmd.accesskey "t">
-<!ENTITY copyCmd.accesskey "c">
-<!ENTITY pasteCmd.accesskey "p">
-<!ENTITY cutCmd.commandkey "X">
-<!ENTITY copyCmd.commandkey "C">
-<!ENTITY pasteCmd.commandkey "V">
-<!ENTITY openCmdToolbar.label "Open">
-<!ENTITY saveCmdToolbar.label "Save">
-<!ENTITY searchTab "Search">
-<!ENTITY optionsTab "Options">
-<!ENTITY findDescription "Enter your search criteria below and select the Find button to begin the search.">
-<!ENTITY findCriteria "Search Criteria">
-<!ENTITY type.name "Name">
-<!ENTITY type.size "Size">
-<!ENTITY type.date "Date Modified">
-<!ENTITY mode.is "Is">
-<!ENTITY mode.isnot "Is Not">
-<!ENTITY casesensitive "Case Sensitive Search">
-<!ENTITY matchfilename "Match Entire Filename">
-<!ENTITY results.filename "Filename">
-<!ENTITY results.location "Location">
-<!ENTITY results.size "Size">
-<!ENTITY bytes.before "">
-<!ENTITY bytes.after "bytes">
-<!ENTITY button.find "Find">
-<!ENTITY button.cancel "Cancel">
-
-

    现在,为一个新语言添加文本仅需创建一个新的DTD文件。使用 chrome 系统把 DTD 文件加到另一个 locales 中,这样同一个 XUL 文件就可以使用不同的语言。

-

Find files example so far: Source

-
-
-

 

-

    下一章,看看 property files.

-

 

-
-

« Previous Next »

-
-

  

-

 

-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/manifest_files/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/manifest_files/index.html deleted file mode 100644 index 10dcc5a2dd..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/manifest_files/index.html +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Manifest Files -slug: Mozilla/Tech/XUL/Tutorial/Manifest_Files -translation_of: Archive/Mozilla/XUL/Tutorial/Manifest_Files ---- -

Contents.rdf 文件

-

这部分内容,我们将了解如何将chrome和XUL文件打成包,以及为它们创建manifest文件。

-

<big></big>

-

一个包,就是一组XUL文件和定义了用户界面功能的脚本的集合,它可以直接存成一个目录,也可以打成JAR文件。包可以被安装到Mozilla里,并且可以被chrome URL 引用。一个包里面包含了多种类型的文件,这些文件也可以划分到包内的不同的子目录里。

-

<big>Manifest 文件</big>

-

manifest文件描述了包在硬盘上的物理存放位置与chrome URL的映射关系。当一个Mozilla应用启动时,它将检查chrome文件夹中的manifest文件,从而知道已经安装了哪些包。也就是说,当安装了一个新包时,你需要在应用程序的chrome目录下或者用户自己的chrome目录中加入一个新的manifest文件。一般情况下,当应用程序没有足够的权限向其目录中写入manifest文件时,才会将manifest文件放到用户自己的chrome目录中。

-

如果你想在Firefox浏览器中测试一下XUL代码的效果,只要在manifest文件中加入一行,就可以轻松实现了:

-
    -
  1. 创建一个目录. 例如, 在系统盘下创建一个目录, 就可以用 C:\testfiles
  2. -
  3. 在chrome目录下创建一个新的名为 test.manifest 的文件(实际上,文件叫什么名字并不重要,只要扩展名是.manifest就可以了),则用下面一句:
  4. -
-

content tests file:///C:/testfiles/

-
- 这里的文件路径是指向上面创建的目录的。如果你不知道应该怎么写这个文件路径,可以在浏览器中打开那个目录,然后将地址栏里面的URL拷贝下来,就可以了。
-

好了,现在,你只需要向上面新建的那个目录中加入一些XUL文件,然后,按照chrome://tests/content/<filename> 的格式键入chrome URL,就可以看到你的成果了。当然,为了你的修改能够起作用,需要重启浏览器。如果你创建的文件没有被加载,确认一下你键入的文件路径是否是正确的。

-

manifest 文件中每一行的基本语法是:

-

content <packagename> <filepath>

-

第一个字段指明了包类型。主题包是'skin',语言地区包是'locale'。上面例子中,包名为'tests',也就意味着chrome URL中第一个部分是'tests',例如:chrome://tests/content/sample.xul。如果包名为'browser',那么chrome URL就变成chrome://browser/content/。基本语法中最后一个字段为文件所在的路径。这既可以是用file URL(译者注:如file:///c:/dir/a)表示的本地文件路径,又可以是下面我们马上要说到的jar URL表示的JAR包。在manifest文件中添加多行,可以指定多个包。

-

Firefox用到的browser.manifest文件看起来是这样的:

-
content branding jar:browser.jar!/content/branding/ xpcnativewrappers=yes
-content browser jar:browser.jar!/content/browser/ xpcnativewrappers=yes
-overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul
-overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
-overlay chrome://browser/content/pageInfo.xul chrome://pippki/content/PageInfoOverlay.xul
-
-

这里有两个包,'branding'和'browser'。此外还有三个overlay,它们使得来自不同包的内容可以组合在一起。扩展(Extension)中会大量使用overlay,因为overlay的功能是将包的用户界面与浏览器的用户界面融合在一起。

-

由于内容被打包成jar,branding和browser包中文件的路径使用了jar URL。一个jar包可以通过ZIP工具来生成。在chrome目录中的JAR文件,语法相当简单:

-

jar:<filename.jar>!/<path_in_archive>

-

browser包对应的JAR包是browser.jar,与manifest文件放在同一个chrome目录中。'content/browser'指明了在JAR压缩包中XUL的路径。若压缩包里面不含任何目录,则无需指明任何路径。在我们的例子中,压缩包里面有目录,所以这里需要指明。

-

对于上面我们建立的'tests'包,文件没有压缩到一个jar包里,所以我们用直接的文件路径来代替jar路径。这样做有利于开发——我们就不用每次在改动文件后重新打包。不过,在发布一个扩展或者应用是,为了避免安装一堆的小文件,通产都会采用打包的方式。

-

在manifest文件的最后,xpcnativewrappers=yes是一个可选的标志。JavaScript可以将网页中内置的函数替换成自己的代码。如果有xpcnativewrappers标志,这就表明在特权环境(privileged context)下的脚本不运行覆盖的版本而是运行原始自带的版本。否则,如果一个扩展试图调用一个修改版的脚本,就有可能无法正常工作甚至更糟——产生安全漏洞。添加这个标志就是为了避免类似的问题,在新的扩展中应当坚持使用,而对于那些无法兼容改变的老扩展可以不用这个标志。

-

主题(Themes)和本地化(Locales)

-

主题(Themes)和本地化(Locales)的打包语法,与内容(content)打包的语法上是相似的。如果你要提供一个主题(Themes)和本地化(Locales)时,你需要了解更多细节。例如:

-

skin browser classic/1.0 jar:classic.jar!/skin/classic/browser/
- locale browser en-US jar:en-US.jar!/locale/browser/

-

如上面例子, 浏览器用来表示皮肤和本地化的特殊的项被加入。皮肤的名称是 'classic/1.0'。这里, 版本号被作为主体的一部分来使用, 但如果你制作自己的主题它是可选的。 Mozilla浏览器并不是用特殊方式来处理版本号;版本号仅仅作为主体名称的一部分。本地化语言是 'en-US'。映射的chrome URL应该是chrome://browser/skin和chrome://browser/locale。如果你正在创作你自己的主题或者本地化浏览器,你说要做的全部是建立一个包含着两行内容的manifest文件,再修改内容来适应你的主题(Themes)和本地化(Locales)。

-

如果必要,也能够合并全部的三种类型内容放到一个单独文件里面。这种情况通常发生在当创建一个扩展(extension/Add on)时,你也许会把所有部分放到一个文件里面。例如,我们想做一个查找文件对话框时可以这样做。在chrome目录建立一个名称为findfiles.manifest的文件。把下面的内容加到文件里面:

-
content findfiles file:///findfiles/content/
-skin findfiles classic/1.0 file:///findfiles/skin/
-locale findfiles en-US file:///findfiles/locale/
-
-

通常, 你希望目录路径内够适应你的系统(不同的文件系统,目录的结构不同)。 这种情况下, 我们仅仅建立测试路径。如果我们在发布这个包,我们应该把全部内容打包成一个JAR文件,并且修改路径。这里只是一个例子,今后可以参照这个例子来做。注意,例子里的skinhe和 locale行的第二项被指定为'findfiles'。这意味着,skin和locale可以访问和修改在第一行定义的findfiles包。

-

上述的三个路径每部分有自己的子路径,意味着你可以给每一部分建立和指定的特殊子路径。

-

安装包

-

为了安装一个应用,你将需要建立一个安装器,或者把它作为另一个应用的一部分。方式依赖于你所创建的是那种应用,一般来说不同的应用类型安装包是不同的。例如扩展,你需要建立一个名为install.rdf的安装描述文件,它描述了哪些东西被安装,以及扩展的作者和兼容性(那一个版本的浏览器,与那些程序兼容等等)。 还需要一个专用的目录结构,安装文件也许被安装到里面,并被限制在这个目录。一个扩展通常打包成一个 XPI 文件。 XPI 是XPInstall的缩写,被以Mozilla为基础的浏览器用来安装组件。类似于JAR文件,一个 XPI文件仅仅是一个带有不同的扩展的ZIP文件,所以你可以用ZIP格式兼容的工具来创建和察看 XPI 文件。

-

Firefox的扩展管理器能够自动的安装 XPI 文件内部的扩展包。他建议上传你的扩展到[Add-ons site],用户通常在这个地址寻找扩展包来安装特殊的应用。当然他们也可以从任何网址安装,不过不是Firefox默认的网址。

-

也可以用JavaScript写一个安装脚本来安装文件。这样你可以把文件复制到任何位置并执行文件管理任务。但是,用脚本安装的应用不能够被扩展管理器列出,意味着不能像其他应用那样自动地卸载。所以通常不使用脚本安装文件。

-

标准的应用,可以使用XULRunner来打包。由于与执行文件分离,可以被发布成与浏览器版本无依赖的应用。

-

创建扩展的更多信息请参照构建一个扩展XULRunner的更多信息请参照http://developer.mozilla.org/en/docs/XULRunner

-

旧版本应用程序

-

如果你为旧版本的Mozilla软件创建应用程序,比如Firefox 1.5或者Mozilla 1.8,那么这一章就很重要的。以下便是讲解怎样为先前版本建立包。如果你正在写新的扩展或者XUL应用程序的话,完全可以跳过此章。

-

1. 在你的磁盘上创建一个目录。许多人喜欢在Mozilla的chrome目录下面创建一个子目录,这样是没有必要的。这个目录可以在任何地方建立,随你喜欢。然后将你的XUL文件放置其中。

-

2. 创建一个名为contents.rdf,并放置在前面你所建立的目录中。将下面的文本框中的内容复制粘贴进新的contents.rdf文件中。这个文件是用来区别应用程序的id,它的名字,作者,版本等等的。

- - - - - - -
-
-     <?xml version="1.0"?>
-
-
-     <RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-              xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
-
-
-       <RDF:Seq about="urn:mozilla:package:root">
-         <RDF:li resource="urn:mozilla:package:myapplication"/>
-       </RDF:Seq>
-
-
-       <RDF:Description about="urn:mozilla:package:myapplication"
-               chrome:displayName="Application Title"
-               chrome:author="Author Name"
-               chrome:name="myapplication"
-               chrome:extension="true"/>
-
-
-     </RDF:RDF>
-
-
-

3. 将文本中的高亮显示部分改换成你自己的信息。比如红色部分“myapplication”应该是你应用程序的ID。你把它填写上,这个ID和你的应用程序名是相似的。用你的应用程序的题目和作者来替换文本中的蓝色高亮部分。

-

4. 如果'chrome:extension'字段为真,那么这个应用程序是Mozilla Firefox Extension(即Mozilla Firefox的扩展),而且还会在浏览器相应的附加软件窗口中见到。否则,它将不会显示。

-

5. 保存contents.rdf文件,同时确认它在你在步骤一中创建的那个文件内。

-

6. 打开<mozilla-directory>/chrome/installed-chrome.txt 这个文件,<mozilla-directory>就是Mozilla程序所安装的那个目录。记住在此之前先退出Mozilla程序。

-

7. 接下来,你必须在注册新的应用程序,这样Mozilla程序就可以找到它。在installed-chrome.txt中的最后添加新的一行,来指向你在步骤一中创建的那个目录。

-

 

-
     content,install,url,file:///main/app/
-
-
- 用你的目录的URL来替换掉上面高亮的文字。并且必须在最后的保留一个斜杠再加一个回车。如果你不能确定那个URL是什么,那么就用Mozilla浏览器来打开该目录,并复制地址栏中所显示的URL。注意这一项必须是个目录的显示,而不是具体到文件的显示。
-

8. 删除 <mozilla-directory>/chrome/chrome.rdf 文件.

-

9. 打开 Mozilla 程序.你将可以看到任何你放到那个目录下的XUL文件,以下面的URL:chrome://applicationid/content/file.xul其中file.xul是文件名。主XUL文件应该是:applicationid.xul,你可以用以下的方式打开它chrome://applicationid/content/

-

如果你要创建skin和locale这两项的话,重复以上步骤,除了contents.rdf的形式略有不同。可以参考contents.rdf为其它应用程序所设置的细节。

-

创建一个chrome包是一件艰难的事情,诊断问题也很困难。以下是一些小小的提示,如果你遇到困难时也许用得着。

- -
-
- << 前页 后页 >>
diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/modifying_a_xul_interface/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/modifying_a_xul_interface/index.html deleted file mode 100644 index 3ee3d691e0..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/modifying_a_xul_interface/index.html +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: XUL_教程/修改XUL界面 -slug: Mozilla/Tech/XUL/Tutorial/Modifying_a_XUL_Interface -tags: - - DOM - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/Modifying_a_XUL_Interface ---- -

 

-

-

« 上一页下一页 »

-

-

    

-

DOM 提供了一系列方法来修改文档。

-

创建新元素 

-

    你可以使用文档对象的 createElement() 方法创建新元素。它有一个参数,待创建元素的标签名。可以使用元素的 setAttribute() 方法设置属性,使用 appendChild() 方法将其加入到XUL文件之中。例如下面的例子将一个按钮加入的XUL窗口中。

-

Example 1 : Source View

-
<script>
-function addButton(){
-  var aBox = document.getElementById("aBox");
-  var button = document.createElement("button");
-  button.setAttribute("label","A new Button");
-  aBox.appendChild(button);
-}
-</script>
-
-<box id="aBox" width="200">
-  <button label="Add" oncommand="addButton();"/>
-</box>
-
- -

    createElement() 方法将为文档创建一个默认类型的元素。对于XUL 文档,通常会创建一个XUL元素。对于 HTML 文档会创建一个HTML元素,它会包含HTML元素的功能及方法。 createElementNS() 方法用于在不同的名空间创建元素。

-

     appendChild() 方法用于像一个元素添加另一个元素。有三个相关的方法: insertBefore()replaceChild()removeChild 语法如下。

-
parent.appendChild(child);
-parent.insertBefore(child, referenceChild);
-parent.replaceChild(newChild, oldChild);
-parent.removeChild(child);
-
-

    下面是这桑函数的简单说明。

- -

    注意,以上所有的方法中的 referenceChild 及 child 必须是一个已经存在的节点否则会出错。

-

    通常你会希望移除一个现有的节点,并把它放到其他的位置。那么你没有必要先删除它。因为一个节点在同一时间只能在一个位置,插入方法总是先将节点从当前位置删除再插入新位置。这是一个在文档中移动节点的好方法。

-

拷贝节点

-

    可以使用 cloneNode() 方法复制节点。这方法复制现有的节点,你可以将新的节点放置到任何位置(原始节点不动),此方法带一个 boolean 型参数确定是否复制此元素的全部子节点。如果‘否’只复制此节点,不包含任何子节点。如果‘是’,将复制全部子节点。此函数会递归调用,如需复制树结构请传递true给函数,如下例。

-

Example 2 : Source View

-
<hbox height="400">
-  <button label="Copy"
-          oncommand="this.parentNode.appendChild(this.nextSibling.cloneNode(true));"/>
-
-  <vbox>
-    <button label="First"/>
-    <button label="Second"/>
-  </vbox>
-</hbox>
-
-

当 Copy 按钮按下:

- -

    注意:有些元素,如listboxmenulist 提供了一些其他的修改方法,可以使用他们来代替,下一章( next section)会讨论。

-

处理基本元素

-

    像按钮,复选框,单选按钮这些XUL的注意元素可以通过脚本属性处理。这些属性列在 element reference 。一些公共的属性如 label, value, checkeddisabled 。可以根据需要来设定他们。

-

例:标签和值特性

-

    这里有一个改变按钮标签的例子。

-

Example 3 : Source View

-
<button label="Hello" oncommand="this.label = 'Goodbye';"/>
-
-

    当按钮按下时label会改变。对于有标签的元素这是通用的。比如文本框。同样的可以修改 value 属性。

-

Example 4 : Source View

-
<button label="Add" oncommand="this.nextSibling.value += '1';"/>
-<textbox/>
-
-

    当按钮按下时文本框中的内容每次加 '1' 。 nextSibling 重当前元素转移到下一个元素(textbox)。 += 用于像当前值加一个值,此处把 1 加到文本的末尾。注意此时你仍可以在文本框中输入,你也可以获取现在的标签和值属性的值,如下例。

-

Example 5 : Source View

-
<button label="Hello" oncommand="alert(this.label);"/>
-
-

标记checkbox

-

    Checkboxes 有 checked 属性可以是 check 或 uncheck 。很容易知道怎么样。下一个例子,当按钮按下时把checked属性取反 注意 labelvalue 属性是字符串,而 checked 属性是布尔值。

-

Example 6 : Source View

-
<button label="Change" oncommand="this.nextSibling.checked = !this.nextSibling.checked;"/>
-<checkbox label="Check for messages"/>
-
-

    单选按钮也可以用属性选中或取消,注意在一个组中一次只能选中一个,这无需手工操作。单选组的 selectedIndex属性用在这里 selectedIndex 属性用于获得被选中的单选按钮的序号,同样可改变它。

-

激活或无效一个元素

-

    在某些情况下一些操作将不被支持,有些内容将会无效。比如,在参数选择对话框中,能选择一系列参数但只有一项允许用户改变。下面的例子创建这样的一个界面。

-

Example 7 : Source View

-
<script>
-function updateState(){
-  var name = document.getElementById("name");
-  var sindex = document.getElementById("group").selectedIndex;
-  name.disabled = sindex == 0;
-}
-</script>
-
-<radiogroup id="group" onselect="updateState();">
-  <radio label="Random name" selected="true"/>
-  <hbox>
-    <radio label="Specify a name:"/>
-    <textbox id="name" value="Jim" disabled="true"/>
-  </hbox>
-</radiogroup>
-
-

    当单选组中的一个选择事件发生时会调用updateState() 方法。这个函数用selectedIndex 属性返回当前被选中的 radio 元素。。注意hbox中的元素也被包含在单选组中。如果第一个按钮 (序0)被选中,通过设置文本框的 disabled 属性,使文本框无效,第二个按钮被选中时,文本框又被激活了。

-

下一章将提供关于单选框和列表的更多信息。

-

-

« 上一页下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/modifying_the_default_skin/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/modifying_the_default_skin/index.html deleted file mode 100644 index 5bf9abae27..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/modifying_the_default_skin/index.html +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: 修改默认的皮肤 -slug: Mozilla/Tech/XUL/Tutorial/Modifying_the_Default_Skin -translation_of: Archive/Mozilla/XUL/Tutorial/Modifying_the_Default_Skin ---- -

  本章论述如何修改窗口的皮肤。

- -
-

关于皮肤Edit section  

- -

皮肤 是一组样式表,图片及应用于XUL的行为文件。 通过使用不同的皮肤,你可以再不改变窗口的功能的前提下改变其外观。火狐提供了一个默认的皮肤,并且你也可以下载到其他的一些。对于所有的皮肤来说XUL是一样的,只是,他们使用的样式表及图片不同罢了。

- -

  如果你想让你的火狐窗口看起来更有个性,你可以简单的改变与之关联的样式表文件。当然可以创建一个全新的皮肤来进行进一步的修改。火狐有一个主题管理器用以修改默认的皮肤(尽管在底层代码中,人们把皮肤和用户界面叫“主题”,但实际上他们就是指一个相同的东西)。

- -

  皮肤使用 CSS描述,允许你定义绘图元素使用的颜色、边框和图片。再文件classic.jar中包含有皮肤的定义。此包中的全局目录中有一个主样式定义,他用于定义一系列XUL元素是如何显示的。通过修改这些文件,你就能改变XUL程序的外观。。

-
- -
-

  使用userChrome.css定制Edit section 

- -

  在你的profile文件夹中,'chrome'文件夹下放置一个'userChrome.css' 文件你就可以通过覆盖而不是修改主题包来改变程序外观。当你创建一个profile 是就会创建这样一个文件夹,并且其中会包含一些内容。文件'userContent.css' 定制网页, 文件'userChrome.css' 定制chrome 文件。

- -

  下例,把下面这行加到文件的底部,你会发现所有的菜单栏都变成了红色背景。

- -
menubar {
-  background-color: red;
-}
-
- -

  当你进行了以上修改之后,你会发现所有的火狐窗口都已改变,所有的菜单栏都是红色的。因为他改变了用户样式表,并且作用于所有的窗口。也就是说,浏览器菜单栏、书签菜单栏甚至是查找菜单栏都是红色的。

-
- -

 

- -

皮肤包

- -
Edit section
- -

  仅改变一个窗口,你需要修改与XUL文件相关的样式表。比如,为书签管理器的菜单命令增加一个红色的边框,把下面的内容加到classic.jar或你要用的其他主题包的 bookmarksManager.css 文件最后。

- -
menuitem {
-  border: 1px solid red;
-}
-
- -

  如果你观察一个皮肤包,你就会注意到其中包含有一系列的样式表及图片。样式表引用图片。当你希望你的程序可以改变皮肤时,你应该避免在XUL文件中直接引用图片。这是因为一个别的什么皮肤设计者可能不希望使用图片,但是如果在XUL文件中直接使用了图片,就会使他的工作变得复杂。请使用CSS间接引用图片,这样就很容易被移除。

- -

  使用list-style-image属性,你可以为按钮、复选框或是其他什么元素设计图形,如下例:

- -
checkbox {
-  list-style-image: url("chrome://findfile/skin/images/check-off.jpg");
-}
-
-checkbox[checked="true"] {
-  list-style-image: url("chrome://findfile/skin/images/check-on.jpg");
-}
-
- -

  这些代码改变了与复选框相关的图形,首先复选框有一个一般的外观,然后为选中的复选框设置了一个新的图像。修饰'checked=true' makes the style only apply to elements which have their checked attributes set to true.

- -

See also  : creating a skin for Firefox and CSS getting started

- -

下一节,创建一个新皮肤

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/more_button_features/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/more_button_features/index.html deleted file mode 100644 index a5dc1c3a54..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/more_button_features/index.html +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: 沙盒 -slug: Mozilla/Tech/XUL/Tutorial/More_Button_Features -tags: - - test - - 沙盒 - - 练习 -translation_of: Sandbox ---- -
-
-

{{EmbedLiveSample('Sample')}}

- -

How To Edit The Sandbox For Publication

- -

There should be a video editing add-on.

- -

Another in this article section (maybe)

- -

Nesting?

- -

Hmmm, maybe this works? I don't know.

- -

I will get there!

- -

link testing

- -
let there = 999999999;
-
-let stepCount = 1;
-
-while(!there) {
-  stepCount++;
-}
-//you cannot got there
-alert('I GOT THERE!!!!!!');
- -

H4 heading

- -
h5 indicates that you've dug too deep!
- -

Code Sample

- -
#include <iostream>
-
-int main()
-
-{
-
-print("This is a sample code!");
-
-return 3;
-
-}
- -

Alert's in Javascript

- -

HTML

- -
<p id='test_code'>
-  Test Sample Code
-</p>
- -

CSS

- -
#test_code {
-  background-color: purple;
-}
- -

JavaScript

- -
console.log("Hi there !!");
- -

Result

- -

{{EmbedLiveSample('My_Alert')}}

- -

Hello World

- -

HTML

- -
<input type="date">
- -

Result

- -

{{EmbedLiveSample('Hello_World')}}

- -

结论

- -

本文档提供了JavaScript中alerts---警告的基本信息

- -

WebGL 基本原理

- -

WebglRenderingContext的shaderSource方法非常酷!

- -

子导航

- - -
-
- -
-
-

中文 (简体) 翻译:

-
- - - -
-
-
- -
草稿已自动保存:
-
- -
-
-
- -
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
- -

如何编辑沙盒页面的发布版本test

- -

这里应该有一个视频编辑插件。

- -

本文的另一个小节(大概

- -

嵌套?

- -

嗯, 这样能行吧? 我也不知道

- -

我会做到的!

- -

链接测试

- -
let there = 999999999;
-
-let stepCount = 1;
-
-while(!there) {
-  stepCount++;
-}
-
-alert('I GOT THERE!!!!!!');
- -

H4 标题

- -
h5 表明你钻研的太深奥了(有么?)
- -

代码示例

- -
#include <iostream>
-
-int main()
-
-{
-
-print("This is a sample code!");
-
-return 3;
-
-}
- -

我的警示

- -

HTML

- -
<p id='test_code'>
-  测试示例代码
-</p>
- -

CSS

- -
#test_code {
-  background-color: purple;
-}
- -

JavaScript

- -
console.log("嗨,我在这儿 !!");
- -

结果

- -

{{EmbedLiveSample('My_Alert')}}

- -

大家好

- -

本文档旨在健全科学。

- -

WebGL基本原理

- -

WebglRenderingContext中的shaderSource方法非常酷炫!

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/more_event_handlers/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/more_event_handlers/index.html deleted file mode 100644 index efb14f298f..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/more_event_handlers/index.html +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: 其他事件处理器 -slug: Mozilla/Tech/XUL/Tutorial/More_Event_Handlers -translation_of: Archive/Mozilla/XUL/Tutorial/More_Event_Handlers ---- -
-

更多关于事件处理

-
-
-
-

 

-

 

-
-

« Previous Next »

-
-

  

-

 

-

    在这一章,详细讨论事件对象,并引入一些新事件。

-
-

事件对象

-
- Edit section
-

    每一个事件处理函数都包含一个保存这事件( event )对象的参数。在以属性的发生添加的事件监听器里也有一个隐含的事件对象(event)被当作参数传递到事件监听器中。在 addEventListener 的形式中,事件监听器的第一个参数就是事件对象。实践大学有一系列的属性,完整列表参见  reference

-

    我们已经在上一章知道了target 属性,它保存这产生事件元素的一个引用。一个相似的 currentTarget 属性当前处理此事件的元素,下面的例子 currentTarget 总是 vbox,而 target 可能是不同的元素, button 或 checkbox。

-

Example 1  : Source View

-
<vbox oncommand="alert(event.currentTarget.tagName);">
-  <button label="OK"/>
-  <checkbox label="Show images"/>
-</vbox>
-
-
-

停止事件传播

-
- Edit section
-

    一旦你处理一个事件,无论事件传播到什么程度,你都希望停止事件继续向下传播。因为添加事件监听器的方式不同有以下两种方式停止事件传播。

-

    由于路由阶段先于返回阶段发生所以路由监听器会先于返回监听器触发。如果路由阶段停止事件传播,那么其后的路由监听器及所有返回监听器都不会触发。手动停止事件对象传播使用 stopPropagation 方法,如下例。

-

Example 2  : Source View

-
<hbox id="outerbox">
-  <button id="okbutton" label="OK"/>
-</hbox>
-
-<script>
-function buttonPressed(event){
-  alert('Button was pressed!');
-}
-
-function boxPressed(event){
-  alert('Box was pressed!');
-  event.stopPropagation();
-}
-
-var button = document.getElementById("okbutton");
-button.addEventListener('command',buttonPressed,true);
-
-var outerbox = document.getElementById("outerbox");
-outerbox.addEventListener('command',boxPressed,true);
-</script>
-
-

    这里分别在按钮和box上添加事件监听器,在调用box的监听器中使用了 stopPropagation 方法,因此按钮的监听器永远不会被调用。如果去掉此命令两个监听器的显示都会出现。

-
-
-

阻止默认响应

-
- Edit section
-

    如果没有注册事件处理,那么当完成路由及返回后,元素会以一种默认的方式对事件作出响应。这种默认响应依赖于元素的定义。比如, 'popupshowing' 事件在快捷菜单显示之前被发送。默认的响应就是显示快捷菜单。如果默认的响应被阻止,那么快捷菜单就不会显示。默认的响应可以使用事件对象的 preventDefault 方法阻止,如下例。

-

Example 3  : Source View

-
<button label="Types" type="menu">
-  <menupopup onpopupshowing="event.preventDefault();">
-    <menuitem label="Glass"/>
-    <menuitem label="Plastic"/>
-  </menupopup>
-</button>
-
-

     另一种方式, 对于以属性形式使用的可以在代码中直接返回 false 。 注意阻止默认响应不同于 stopPropagation 方法,即使默认响应被阻止,事件依然会传播下去。同样的,定义 stopPropagation 方法也不会阻止默认响应。如果需要,必须同时调用。

-

    注意一旦传播或默认调用被阻止,都不可恢复。

-

    下面的几章列出可能用到的一些事件,一个完整的列表在这里 XULPlanet event reference

-
-
-
-

鼠标事件

-
- Edit section
-

    这里的一些事件用来描述鼠标动作,简单的描述如下:

-
-
- click 
-
- 当鼠标键在一个元素上按下并释放后调用。
-
-
-
- dblclick 
-
- 当鼠标双击时调用。
-
-
-
- mousedown 
-
- 当鼠标键在一个元素上按下时调用,事件处理会被立即调用,甚至在鼠标键释放之前。
-
-
-
- mouseup 
-
- 当鼠标键在一个元素上释放时调用。
-
-
-
- mouseover 
-
- 当鼠标移动到一个元素之上时调用,你可以使用它来高亮显示该元素,然而CSS提供了一个方案自动实现它,所以你可能不会使用它,当然你也可以在状态栏显示一些提示信息。
-
-
-
- mousemove 
-
- 当鼠标在一个元素上移动时调用,在移动过程中可能会多次调用事件处理,请务必避免冗长,复杂操作。
-
-
-
- mouseout 
-
- 当指针移除元素时调用。你可以将该元素取消高亮或移除状态栏提示。
-
-

    也有一些与拖动相关的事件,当用户按下鼠标键并移动鼠标时产生,这一部分参见 Drag and Drop.

-
-

鼠标键事件属性

-
- Edit section
-

    当一个鼠标键事件产生,一系列附件属性也随之产生用以描述哪个鼠标键被按下及鼠标指针的位置。事件的 button 可以用于确定哪个按键被按下。0 代表左键,1 代表中键 ,2代表右键。如果鼠标设置不同,值也不同。

-

    detail 保存着鼠标键被短时间内快速点击的次数。这允许你检查这是一次单击,双击还是三击。当然如果你希望检查双击你可以使用 dblclick 事件代替。一旦第一次点击开始 click 事件就会触发,第二次点击会再触发一次,第三次又一次。但 dblclick 事件仅在双击发生时触发。

-

     buttondetail 仅支持与鼠标键相关的事件,对鼠标移动事件无效。对于鼠标移动事件这两个值均为0。

-
-
-

鼠标位置事件属性

-
- Edit section
-

    所以的鼠标事件都提供事件发生时鼠标的坐标位置。有两个坐标系统。其一是 screenXscreenY 属性他们是基于屏幕左上角的。另一个是 clientXclientY 他们是相对于文件左上角的。这里有一个显示当前鼠标位置的例子。

-

Example 4  : Source View

-
<script>
-
-function updateMouseCoordinates(e){
-  var text = "X:" + e.clientX + " Y:" + e.clientY;
-  document.getElementById("xy").value = text;
-}
-</script>
-
-<label id="xy"/>
-<hbox width="400" height="400" onmousemove="updateMouseCoordinates(event);"/>
-
-

    在这个例子里,box 的尺寸被准确设定,这样更容易看出结果。事件处理器得到 clientXclientY 属性并根据他们创建一个字符串。这个字符串又被设置成为 label.value 的值。注意事件对象必须作为参数传递给updateMouseCoordinates 函数。如果快速的在剥削的边缘上移动鼠标,你可能会发现坐标并不会准确的停到 400。这是因为 mousemove 事件触发的间隔取决于鼠标移动的速度。因为当鼠标移动过一段距离后新的事件才触发,因为发送鼠标每一像素的移动是十分没有效率的。

-
-
-

元素相关坐标

-
- Edit section
-

    你经常想知道事件发生时对元素的坐标而非对于这个窗口。这时你可以使用减法来计算,示例如下。

-
var element = event.target;
-var elementX = event.clientX - element.boxObject.x;
-var elementY = event.clientY - element.boxObject.y;
-
-

      XUL 元素有一个 box 对象可以通过 boxObject 属性获得。在后一章我们会学习更多相关内容,但记住它保存着如何显示元素包括元素的x,y 位置。在这个例子中,这些坐标被从事件坐标中减去,这样就得到了事件相对于元素的坐标。

-
-
-
-

加载事件

-
- Edit section
-

    一旦XUL文件加载完成 load 事件就会被发送到文件 ( window 标记),此时正是内容显示之前。这个事件通常被用于初始化操作及完成一些任务使得用户可以使用窗口。你可以通过调用一个顶层的脚本函数来使用这一事件处理以上这些事情。这是因为XUL文件为完全加载,一些事情可能会处理出错。使用 load 事件,在 window 标记处放置 onload 属性,调用处理加载事件的处理器来完成必要的界面初始化。

-

    也有unload 事件,它当窗口关闭时被调用,或者作为浏览器的内容时,页面换为另一URL 时调用。你可以使用这一事件保存任何改变的信息。

-


-      接下来我们看看如何添加键盘快捷方式( keyboard shortcuts).

-

 

-
-

« Previous Next »

-
-

  

-

 

-
-
-
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/more_menu_features/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/more_menu_features/index.html deleted file mode 100644 index 30cc1b3046..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/more_menu_features/index.html +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: XUL_教程/更多菜单特性 -slug: Mozilla/Tech/XUL/Tutorial/More_Menu_Features -tags: - - XUL_Tutorial -translation_of: Archive/Mozilla/XUL/Tutorial/More_Menu_Features ---- -

 

-

-

« 上一页下一页 »

-

-

在本节中,我们来学习如何创建子菜单和check菜单。

-

创建子菜单

-

使用已存在元素可以在其它菜单(递归菜单)中创建子菜单。记住可以在menupopup中放置任意元素。我们已经学过在menuseparators中放置menuitems。但是,还可以通过在menupopup元素中简单的放置menu元素来创建子菜单。这样也可以运行,因为菜单元素即使不直接放在菜单栏里面它也是有效的。下面的示例在 文件 菜单中创建了一个简单的子菜单:

-

Example 1 : Source View

-
- Image:menubar-ex3.png
-
<toolbox flex="1">
-  <menubar id="sample-menubar">
-    <menu id="file-menu" label="File">
-      <menupopup id="file-popup">
-        <menu id="new-menu" label="New">
-          <menupopup id="new-popup">
-            <menuitem label="Window"/>
-            <menuitem label="Message"/>
-          </menupopup>
-        </menu>
-        <menuitem label="Open"/>
-        <menuitem label="Save"/>
-        <menuseparator/>
-        <menuitem label="Exit"/>
-      </menupopup>
-    </menu>
-  </menubar>
-</toolbox>
-
-
-

在我们的 查找文件 示例中加入菜单

-

让我们在查找文件对话框中加入菜单。我们仅加入少量简单的命令至 文件 菜单和 编辑 菜单中。这与上面示例类似。

-
<toolbox>
-
- <menubar id="findfiles-menubar">
-  <menu id="file-menu" label="File" accesskey="f">
-    <menupopup id="file-popup">
-      <menuitem label="Open Search..." accesskey="o"/>
-      <menuitem label="Save Search..." accesskey="s"/>
-      <menuseparator/>
-      <menuitem label="Close" accesskey="c"/>
-    </menupopup>
-  </menu>
-  <menu id="edit-menu" label="Edit" accesskey="e">
-    <menupopup id="edit-popup">
-      <menuitem label="Cut" accesskey="t"/>
-      <menuitem label="Copy" accesskey="c"/>
-      <menuitem label="Paste" accesskey="p" disabled="true"/>
-    </menupopup>
-  </menu>
- </menubar>
-
-<toolbar id="findfiles-toolbar>
-
-
- Image:menubar1.png
-

在此我们已经加入了两个菜单以及一些不同的菜单命令。注意菜单栏是如何放置在toolbox内的。在 打开搜索 和 保存搜索 后面的三个点通常提示用户本命令操作会打开一个对话框。每个菜单和菜单项已经加入了访问快捷键。在图中可以看到菜单标签内的字母已经被打上了下划线。而 粘贴 命令在此被禁止。我们假定没有什么可以用来粘贴。

-

Our Find files example so far : Source View

-
-

给菜单加入勾选(check)标记

-

许多应用程序的菜单项都有check标记。例如,许可特性在命令里面会有一个check,而禁止特征则没有check在里面。当用户选择菜单后,check状态就进行了切换。你也可以在菜单项上创建radio按钮。

-

check创建类似于checkbox元素和radio元素。包括了两个属性的使用:type标识check的类型,而name标识同在一起的组命令。下面的示例创建一个带有check项的菜单。

-

Example 2 : Source View

-
<toolbox>
-  <menubar id="options-menubar">
-    <menu id="options_menu" label="Options">
-      <menupopup>
-        <menuitem id="backups" label="Make Backups" type="checkbox"/>
-        <menuitem id="backups" label="Email Administrator" type="checkbox" checked="true"/>
-      </menupopup>
-    </menu>
-  </menubar>
-</toolbox>
-
-

加入的type属性用来标识菜单项是可以check的。通过设置checkbox的值,通过选择菜单项,使它被勾选或取消勾选。

-

带有radio标记的菜单

-

除标准check菜单外,还可以通过设置type的值为radio来创建radio风格的check型菜单。radio风格的check菜单用于在一组目录项中仅选择一项的时候。例如在一个菜单中每次只能选取一个生效的情况。当选取另外一项时,前面的选择项就会自动取消选择。

-

为了将一组菜单项放置在一起,需要将每一项的name属性设置为一样,就会形成一个菜单组。示例如下:

-

Example 3 : Source View

-
<toolbox>
-  <menubar id="planets-menubar">
-    <menu id="planet-menu" label="Planet">
-      <menupopup>
-        <menuitem id="jupiter" label="Jupiter" type="radio" name="ringed"/>
-        <menuitem id="saturn" label="Saturn" type="radio" name="ringed" checked="true"/>
-        <menuitem id="uranus" label="Uranus" type="radio" name="ringed"/>
-        <menuseparator/>
-        <menuitem id="earth" label="Earth" type="radio" name="inhabited" checked="true"/>
-        <menuitem id="moon" label="Moon" type="radio" name="inhabited"/>
-      </menupopup>
-    </menu>
-  </menubar>
-</toolbox>
-
-

试一下这个示例,可以发现前三个菜单项只有一个可以被勾选。它们被聚为一组,因为他们的name属性值相同。最后一个菜单项--Earth,一个radio按钮,由于拥有不同的name属性值,因此不是这个菜单组的一部分。

-

当然,聚集在一组中的项只能放置在相同的菜单中。虽然将它们相邻的放在一起比分开放要直观得多,但在菜单中并没有必要将它们放在一起。

-

下一回,我们将学习如何创建弹出菜单

-

-

« 上一页下一页 »

-

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/more_wizards/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/more_wizards/index.html deleted file mode 100644 index 48648bb971..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/more_wizards/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: More Wizards -slug: Mozilla/Tech/XUL/Tutorial/More_Wizards -translation_of: Archive/Mozilla/XUL/Tutorial/More_Wizards ---- -
-
-

This section describes some additional features of wizards.

-

More Complex Wizard Navigation

-

Normally, a wizard displays each wizardpage in the order that you place them in the XUL file. In some cases however, you may want to have different pages of the wizard appear depending on what the user selects in earlier pages.

-

In this case, place a pageid attribute on each of the pages. This should be set to an identifier for each page. Then, to navigate to a page, use one of two methods:

-
    -
  1. Set the next attribute on each page to the page ID of the next page to go to. You can change these attributes as needed to navigate to different pages.
  2. -
  3. Call the wizard's goTo() method. It takes one argument, the page ID of a page to go to. You might call this method in the onpageadvanced or onwizardnext handlers. Remember to return false in this case, because you have already changed the page yourself. Note that the goTo() method, because it causes a page change, will fire the events again, so you'll have to make sure you handle that case.
  4. -
-

For example, here are a set of wizard pages (the inner content has been omitted):

-
<wizardpage pageid="type" next="font">
-<wizardpage pageid="font" next="done">
-<wizardpage pageid="color" next="done">
-<wizardpage pageid="done">
- -

A script will adjust the next attributes as necessary to go to the page with the page ID color when needed.

-

Wizard Functions

-

The wizard works much like a tabbed panel, except that the tabs are not displayed and the user navigates between pages by using the buttons along the bottom. Because all of the pages are part of the same file, all of the values of the fields on all pages will be remembered. Thus, you do not have to load and save information between pages.

-

However, you may want to do some validation of each field on each page. For this, use the handlers described in the previous section. If a field is invalid, you might display an alert. In some cases, it would be more convenient to disable the Next button until valid input has been entered.

-

The wizard has a property canAdvance, which can be set to true to indicate that the Next button should be enabled. If set to false, the Next button is disabled. You can change the property when invalid or valid data has been entered.

-

In the following example, the user must enter a secret code into a textbox on the first page of the wizard. The function checkCode() is called whenever the first page is shown as indicated by the onpageshow attribute. It is also called whenever a key is pressed in the textbox, to determine whether the Next button should be enabled again.

-

Wizard example

-

Source

-
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<wizard id="theWizard" title="Secret Code Wizard"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<script>
-function checkCode(){
-  document.getElementById('theWizard').canAdvance = (document.getElementById('secretCode').value == "cabbage");
-}
-</script>
-
-  <wizardpage onpageshow="checkCode(); return true;">
-       <label value="Enter the secret code:"/>
-       <textbox id="secretCode" onkeyup="checkCode();"/>
-  </wizardpage>
-
-  <wizardpage>
-       <label value="That is the correct secret code."/>
-  </wizardpage>
-
-</wizard>
-

There is also a corresponding canRewind property that you can use to enable or disable the Back button. Both properties are adjusted automatically as you switch pages. Thus, the Back button will be disabled on the first page so you don't have to set it yourself.

-

Another useful property of the wizard is currentPage, which holds a reference to the currently displayed wizardpage. You can also modify the current page by changing this property. If you do change it, the various page change events will still be fired.

-

Next, we'll see how to use overlays to handle common content.

-
-
diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/numeric_controls/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/numeric_controls/index.html deleted file mode 100644 index 310abf97a4..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/numeric_controls/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: 数值控件 -slug: Mozilla/Tech/XUL/Tutorial/Numeric_Controls -translation_of: Archive/Mozilla/XUL/Tutorial/Numeric_Controls ---- -

-

« 上一页下一页 »

-

-

-

XUL有两种输入数值或者范围的元素,两种输入日期和时间的元素。这些元素仅适用于Firefox 3以及后续版本。

-

XUL has two elements used for the entry of numeric values or ranges, and well as two elements for entering dates and times. These elements are only available in Firefox 3 and later.

-

数值域Number Fields

-

textbox元素也可以用于输入数值,只要设置type属性的值为number即可。这种类型的textbox可以仅用于输入数字而会忽略输入的其他类型字符。另外,textbox一侧添加了上下箭头,允许用户增减输入的值。

-

A textbox may be used for entering numbers by setting the value of the type attribute to the value number. This type of textbox may only be used to enter numbers. Other characters are not allowed and are just ignored if typed. In addition, arrow buttons appear beside the textbox to allow the user to cycle through the values.

-
- Image:Controlguide-textbox-number.gif
-

和其他类型的textbox一样,可以通过value属性指定默认值。自然,这个值应该是一个数值。另外,可以通过min属性和max属性指定元素的最小和最大值。如果指定了最小和最大值,你就设定了textbox可以输入的值域。如果用户输入了一个超出上下界的值,它会自动取最大值或最小值代替。例如,下面的数值类型textbox的值域是1到20。

-

As with other textboxes, the default value can be specified with the value attribute. Naturally, this value should be a number. However, the minimum and maximum values can also be specified using the min and max attributes. If these are set, you can control the range of values that the textbox may be set to. If the user enters a value less or greater than this value, it will be reset to the minimum or maximum value as necessary. For instance, the following numeric textbox has a range between 1 and 20.

-
<textbox type="number" min="1" max="20"/>
-
-

由于没有指定默认值,元素默认取值1,即最小值。设置min属性为1表明元素的最小可能值是1,同时设置max属性为20表明最大可能值是20。如果没有设置最小值,那么默认是0。max属性默认是Infinity,即最大值没有限制。

-

As the default value isn't specified, it will default to 1, the minimum value. The min attribute is set to 1 to indicate a minimum possible value of 1 and the max attribute is set to 20 to indiciate a maximum possible value of 20. If the minimum value is not specified, it has a default value of 0. The maximum value defaults to the special value Infinity which means that there is no limit.

-

其他数值型textbox属性Other numeric textbox attributes

-

increment属性指定当点击箭头时数值的改变量。默认值是1,当然可以设置一个更大的值来加大改变量。例如,下面的例子设置为以10的倍数改变值。

-

The increment attribute may be used to specify by how much the value changes when the arrows are pressed. The default value is 1, but specifying a different value allows the number to change by a larger amount. For instance, the following example steps in multiples of 10.

-
<textbox type="number" increment="10" max="100"/>
-
-

这个textbox从0到100,依次取10的倍数。由于没有指定min属性,默认是0。注意,用户仍然可以直接输入其他值。increment属性只会影响到上下箭头。当textbox有焦点时,用户可以通过上箭头增加值,用下箭头减小值。

-

This textbox steps in multiples of 10 from 0 to 100. Since the min attribute was not specified, it defaults to 0. Note that the user can still enter other values if they are typed in. The increment attribute only affects the arrow buttons. The user may also increment or decrement the value using this increment by using the up and down cursor keys while the textbox is focused.

-

decimalplaces属性表明需要显示的小数位数。默认值是0,表明只显示整数部分。指定其他值则可用于显示小数。

-

The decimalplaces attribute indicates how many decimal places to show. The default value is 0, which means show integers only. However a different value may be used to show decimal values.

-
<textbox type="number" decimalplaces="2"/>
-
-

在这个例子中,textbox将显示小数点后两位数字。小数位数多于两位的数值会被舍入到两位小数。

-

In this example, two digits right of the decimal point are shown. Values with additional fractional digits are rounded to two digits.

-

滑块Scales

-

scale元素也可以用来从一个区间中选择值。和textbox不同的是滑轨代替了文本框。用户可以拖动滑轨上的滑块来调整值。

-

A scale element may also be used to select from a range of values. Instead of a textbox however, a sliding scale is used. The user may drag the thumb of the scale to adjust the value.

-
- Image:Controlguide-scale.gif
-

Scale与textbox有很多相同的属性:value, min, max and increment,使用方法也类似。Scale并不实际显示数值,但这个值可能在脚本中用到。当值改变时,Scale将触发change事件。

-

Many of the same attributes as a numeric textbox may be used with a scale: value, min, max and increment may all be used in a similar fashion. The scale does not actually show the value as a number, but it may be used in a script. A scale will fire a change event whenever the scales's value is modified.

-
<scale value="40" min="1" max="50"/>
-
-

这个例子设置了一个默认值是40,值域是1到50的Scale元素。

-

This scale defaults to a value of 40 and has a range between 1 and 50.

-

数值型textbox一般应用于数值对用户而言很重要的情况,例如需要用户输入天数或者文件的最大大小。而Scale则应该用于实际值对用户不那么重要,只要用户能改变它就可以的情况。例如调整音量或者缩放。

-

A numeric textbox would normally be used when the value was important to the user, for instance, a field to enter a number of days, or the maximum size of a file. A scale would be used when the actual value isn't important, just that sliding the scale decreases or increases a state. For instance, a volume slider or a zoom level.

-

Scale元素的默认布局是小值在左,大值在右,水平放置。可以通过改变orient属性和dir属性修改。

-

The default arrangement of a scale is horizontal with lower values to the left and higher values to the right. However, you can change this orientation with the orient and dir attributes.

-
<scale orient="vertical" dir="reverse"/>
-
-

这个例子设置Scale垂直显示,且小值在下,大值在上。

-

This scale will be shown vertical with lower values at the bottom and higher values at the top.

-

日期时间输入域Date and Time Entry Fields

-

datepicker元素和timepicker元素用于用户输入日期和时间。他们会显示一组数值textbox用于输入日期和时间的各部分。

-

The datepicker and timepicker elements may be used to allow the user to enter dates and times. When used, they display a set of numeric textboxes to enter each of the components of the date or time.

-
<datepicker value="2004-03-24"/>
-<timepicker value="15:30:00"/>
-
-
- Image:Controlguide-timepicker.gif
-

value属性用于设置默认值;如果没有显示指定,则初始化为当前日期或时间。属性值的格式严格按照例子所示,日期为YYYY-MM-DD,时间是HH:MM:SS(也可以省去秒以及前面的冒号)。

-

The value attribute is used to set the default value; if this attribute is omitted, the field will be initially set to the current date or time. The format of the attribute is exactly as above, that is dates are of the form YYYY/MM/DD and times are of the form HH:MM:SS (although the seconds and the accompanying colon may be omitted).

-

这两个元素保证用户输入一个有效的日期或者时间,因此你就不用再自己校验用户输入的日是不是大于当月的总天数以及闰年等等。

-

These two elements ensure that the user enters a value date or time. This way, you do not have to check for valid dates, ensure that the day isn't greater than the number of days in the month, handle leap years, and so forth.

-

timepicker元素只有一种样式,而datepicker元素有三种不同的样式。默认样式是显示三个输入域分别对应年月日。type属性用于选择另外两种样式。grid样式效果如下。

-

While the timepicker only comes is one style, the datepicker has three different variations. The default style shows three fields for entering the year, month and date. The type attribute may be used to select the other two. Using a value of grid uses a calendar grid, as shown in the image below.

-

Image:Controlsguide-datepicker-grid.png

-

你也可以使用popup样式,该样式结合了另两种,也有三个输入域用于输入年月日,同时提供一个下拉按钮,用于显示日历供用户选择一天。

-

You can also use the value popup which creates a combination of the two types. This type has three fields for entering the year, month and date, as well as a dropdown button for displaying a popup calendar grid for selecting a day.

-
<datepicker type="popup"/>
-
-

-

« 上一页下一页 »

-

-

 

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/popup_menus/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/popup_menus/index.html deleted file mode 100644 index 026ec62f83..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/popup_menus/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: 弹出菜单 -slug: Mozilla/Tech/XUL/Tutorial/Popup_Menus -translation_of: Archive/Mozilla/XUL/Tutorial/Popup_Menus ---- -

[fd]

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/progress_meters/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/progress_meters/index.html deleted file mode 100644 index bacf39b352..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/progress_meters/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: XUL_教程/进度条 -slug: Mozilla/Tech/XUL/Tutorial/Progress_Meters -tags: - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/Progress_Meters ---- -

-

« 上一页下一页 »

-

-

 

-

添加一个进度条

-

进度条是条状的,它用来指示一个任务完成了多少。你通常可以在当下载文件或当执行一个很长的操作时看到它。XUL有一个progressmeter元素可以用来创建这些。有两种类型的进度条: 确定的和不确定的。

-

确定的进度条可以用在当你已经知道完成某个操作的时间长度时。进度条将会被往上填充,并且在充 满时,操作刚好完成。这会用在文件的长度已经知道的下载文件对话框。

-

不确定进度条会用于当你不知道一个操作的时间长度的情况。进度条是动态的就像一个不停循环移动的杆或一个可调整的框,发生在平台和外观被使用。

-

确定的进度条: Image:prog-det.png

-

不确定的进度条: Image:prog-udet.png

-

进度条的语法如下:

-
<progressmeter
-    id="identifier"
-    mode="determined"
-    value="50%"/>
-
-

属性如下:

-
-
- id 
-
- 进度条的唯一标识符。
-
- mode
-
- 进度条的类型。如果这里设置为determined,进度条就是确定型进行度,在任务完成时在填满。如果这里设置为undetermined,这个进度条就是不确定型进度条,用于当你不知道花费时间的长度时。如果不指定这个属性默认值为确定型。
-
- value 
-
- 当前进度条的尺度值。你只能在确定型进度条中使用这个属性。这个值可以设成从0%到100%的百分值。这个值可以在任务结束时由脚本来改变。
-
-
-
文件查找的例子
-

让我们添加一个进度条到我们文件查找的对话框吧。我们应该使用不确定的进度条因为我们不知道能搜索到多少文件或者要多久才能搜索完成。然而,现在我们将要增加一个普通的因为动态的可以避免在开发期间的困恼。 进度条仅显示在搜索过程中。我们将在后面的脚本中对它进行开合控制。

-
<hbox>
-
-  <progressmeter value="50%" style="margin: 4px;"/>
-
-  <spacer flex="1"/>
-</hbox>
-
-

值被设成50%因此我们能在窗口上看到尺度。边缘被设成4像素因此它会与窗口的边缘分开。最开始,我们只希望进度条被显示在搜索开始时。脚本会在需要时显示和隐藏它。

-

例子太长了。 Source View

-

Image:progress1.png

-

 

-
-

在下一节,我们将学习如何在窗口增加HTML的附加元素

-

-

« 上一页下一页 »

-

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/property_files/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/property_files/index.html deleted file mode 100644 index a5800e69f9..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/property_files/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: 属性文件 -slug: Mozilla/Tech/XUL/Tutorial/Property_Files -translation_of: Archive/Mozilla/XUL/Tutorial/Property_Files ---- -
-
-

 

-

    在脚本中,不能使用实体,用属性文件代替。

-

 

-
-

属性

-
- Edit section
-

    当你在XUL文件中使用DTD文件是恰当的。然而,脚本不解析实体。也就是说,如果你希望在脚本中显示信息而且你不知道到底要显示什么,请使用属性文件

-

    一个属性文件包含一系列字符串。你可以在DTD文件旁边找到属性文件(.properties后缀)。属性按照以下语法定义 name=value。实例如下。

-
notFoundAlert=No files were found matching the criteria.
-deleteAlert=Click OK to have all your files deleted.
-resultMessage=%2$S files found in the %1$S directory.
-
-

    上例中,属性文件包含桑属性,可以由脚本读取显示给用户。

-
-
-

Stringbundles

-
- Edit section
-

   你可以写一段代码手动来读取属性,而在XUL中有一个 stringbundle 元素来帮你做。这个元素有一系列函数有属性文件中获取属性并得到本地化信息。这个元素有属性文件读取内容并为你建立一个属性列表。你可以通过名字来查找属性。

-
<stringbundleset id="strbundles">
-<stringbundle id="strings" src="strings.properties"/>
-</stringbundleset>
-
-

    这个元素会从与该XUL文件系统的目录中读取名为 'strings.properties'的文件。像其他非显示元素一样你可以使用一个 stringbundleset 来包含所以的stringbundle

-
-

stringbundle获取字符串

-
- Edit section
-

     stringbundle 元素有一系列方法。首先是 getString 用于脚本读取字符串。

-
var strbundle = document.getElementById("strings");
-var nofilesfound=strbundle.getString("notFoundAlert");
-
-alert(nofilesfound);
-
-
    -
  • 本例首先使用 id 获得字符串束的一个引用
  • -
  • 然后在属性文件中查找 'notFoundAlert' 字符串 getString() 函数返回字符串的值或 null (字符串不存在)。
  • -
  • 最后把职工文本显示在提示框里。
  • -
-
-
-

文本格式

-
- Edit section
-

    getFormattedString()方法也根据名字从文本束中查找字符串,此外会按照格式控制代码 (如 %S) 将其后给出的数组内容替换入字符串。

-
var dir = "/usr/local/document";
-var count = 10;
-
-var strbundle = document.getElementById("strings");
-var result = strbundle.getFormattedString("resultMessage", [ dir, count ]);
-
-alert(result);
-
-

    本例显示如下。

-
10 files found in the /usr/local/document directory.
-

    你会注意到格式化代码 %1$S%2$S被使用,替换顺序也和在数组中的不同。格式化代码 %n$S 直接描述替换参数的位置。尽管在不同语言中词序可能不同通过 getFormattedString()描述的顺序可以被写入属性文件。

-
-
-
-

非ASCII码的换码符

-
- Edit section
-

    (这可能不再正确:在 Localizing extension descriptions中说 “使用 UTF-8 编码(而非 BOM) 保证外文正确显示。” UTF-8 编码文本有效, 换码符同样有用。一些新想法的引入会更有用。)

-

    尽管大多数语言使用非ASCII字符集。属性文件只能使用ASCII字符集编制。然而,属性文件支持其他字符的换码形式: \uXXXX 这里的 XXXX 是字符码,因此,你的属性文件可以包含非ASCII字符,不过你需要把他们转换为换码形式。你可以使用 Sun's Java Development Kit (JDK)的 native2ascii 命令来完成它。

-

Gecko 1.8.x (or later) 支持属性文件以 UTF-8编码。你可以直接写入非ASCII字符。

-


- 下一章,我们将讨论 XBL,它用于定义元素的行为( behavior of an element.)

-

 

-
-

« Previous Next »

-
-

  

-

 

-
-
-
-
-
-

Retrieved from "https://developer.mozilla.org/En/XUL_Tutorial/Property_Files"

-
- -

 

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/rdf_datasources/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/rdf_datasources/index.html deleted file mode 100644 index b4d4c51238..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/rdf_datasources/index.html +++ /dev/null @@ -1,267 +0,0 @@ ---- -title: RDF Datasources -slug: Mozilla/Tech/XUL/Tutorial/RDF_Datasources -translation_of: Archive/Mozilla/XUL/Tutorial/RDF_Datasources ---- -

 

-

-

« 上一页下一页 »

-

-

Here, we'll look at additional datasources and how to use your own RDF files as datasources.

-

Other Mozilla Datasources

-

Mozilla provides a number of other built-in datasources. Some of them are listed here with a few examples. They work very similarly to the bookmarks, although the fields will be different in each case.

-

The History List

-

The history datasource provides access to the user's history list which is the list of URLs the user has visited recently. The resource can be referred to using rdf:history as the datasource. The table below shows the resources (or fields) that you can retrieve from the history datasource. Put the URL values below where you want the value of the resource to be used.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Datehttp://home.netscape.com/NC-rdf#DateDate of last visit
Namehttp://home.netscape.com/NC-rdf#NameTitle of the page
Pagehttp://home.netscape.com/NC-rdf#PagePage name
Referrerhttp://home.netscape.com/NC-rdf#ReferrerReferrer of the page
URLhttp://home.netscape.com/NC-rdf#URLURL of the page
Visit Counthttp://home.netscape.com/NC-rdf#VisitCountNumber of page visits
-

A typical history list will display a tree with a selection of these fields. To use them, just put the URL values above in the label attributes of the buttons or treecells. You can use NC:HistoryRoot as the value of the ref attribute. You can also use the value NC:HistoryByDate to get the history sorted into days.

-

Using The History List Example

-

Let's see an example of displaying the history list. We'll display the history in a tree with three columns, the Name, the URL and the Date.

-

Example 1 : Source

-
<tree flex="1" datasources="rdf:history" ref="NC:HistoryRoot">
-
-  <treecols>
-    <treecol id="name" label="Name" flex="1"/>
-    <treecol id="url" label="URL" flex="1"/>
-    <treecol id="date" label="Date" flex="1"/>
-  </treecols>
-
-  <template>
-
-    <rule>
-      <treechildren>
-       <treeitem uri="rdf:*">
-         <treerow>
-           <treecell label="rdf:http://home.netscape.com/NC-rdf#Name"/>
-           <treecell label="rdf:http://home.netscape.com/NC-rdf#URL"/>
-           <treecell label="rdf:http://home.netscape.com/NC-rdf#Date"/>
-         </treerow>
-       </treeitem>
-      </treechildren>
-    </rule>
-
-  </template>
-</tree>
-
-

Other Datasources

-

The tables below list some of the other datasources available with Mozilla. You can use any of the resources that you want.

-
-
- Bookmarks (rdf:bookmarks)
-
- The bookmarks are generated from the user's bookmark list.
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Resources
Added Datehttp://home.netscape.com/NC-rdf#BookmarkAddDateDate the bookmark was added
Descriptionhttp://home.netscape.com/NC-rdf#DescriptionBookmark description
Last Modifiedhttp://home.netscape.com/WEB-rdf#LastModifiedDateDate of last modification
Last Visitedhttp://home.netscape.com/WEB-rdf#LastVisitDateDate of last visit
Namehttp://home.netscape.com/NC-rdf#NameBookmark name
Shortcut URLhttp://home.netscape.com/NC-rdf#ShortcutURLCustom keywords field
URLhttp://home.netscape.com/NC-rdf#URLThe URL to link to
- - - - - - - - - - - - - - - - - - -
Possible Bookmarks Roots
NC:BookmarksRootThe top level of the bookmarks hierarchy
NC:IEFavoritesRootThe bookmark folder that corresponds to the user's IE favorites.
NC:PersonalToolbarFolderThe bookmark folder that corresponds to the personal toolbar folder.
-
-
- Files (rdf:files)
-
- A view of the user's files.
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Resources
Namehttp://home.netscape.com/NC-rdf#NameName of the file
URLhttp://home.netscape.com/NC-rdf#URLURL of the file
Content-Lengthhttp://home.netscape.com/NC-rdf#Content-LengthThe length of the file.
LastModifiedDatehttp://home.netscape.com/NC-rdf#LastModifiedDateThe date that URL was last modified.
extensionhttp://home.netscape.com/NC-rdf#extensionThe extension of the file, including the period. This property is only available on platforms that use file extensions.
- - - - - - - - - - - - - - -
Possible Files Roots
NC:FilesRootTop level of the filesystem (usually the list of drives)
A file URLBy using a file URL for the ref attribute, you can select a specific directory to be returned. For example, you might use file:///windows or files:///usr/local.
-

The files datasource is an example of a datasource that determines its resources only when necessary. We don't want every file in the filesystem to be determined before the data is displayed. Instead, only the files and directories that the tree element (or other elements) will need to display at a given time will be determined.

-

Composite Datasources

-

You can specify multiple datasources in the datasources attribute by separating them with whitespace as in the example below. This has the effect of reading the data from all the datasources mentioned.

-
<tree datasources="rdf:bookmarks rdf:history animals.rdf" ref="NC:BookmarksRoot">
-
-

This example reads the resources from the bookmarks, history and the animals.rdf file. They are combined into a single composite datasource and can be used as if they were one.

-

The special datasource rdf:null corresponds to nothing. You can use this datasource if you want to dynamically set the datasource using a script, but don't want one initially or don't know its exact URL.

-

Custom RDF Datasources

-

You can use any of the above internal datasources if you wish. There are several others for mail, address books and searching and so on. However, you might want to use your own RDF datasource stored in an RDF file. The file can be either a local file or a remote file. Just put the URL of the RDF file in the datasources attribute.

-

Using RDF files provides just as much functionality as any of the internal datasources. You can use rules to match specific types of content. The attributes on the rule element will match if they match the attributes on an RDF Description element. You can also create RDF files that are hierarchical.

-

Using RDF file Example

-

The following is an example of how an RDF file can be used as a datasource. The RDF file is fairly large and can be viewed separately: Source RDF

-

Example 2 : Source View

-
<tree flex="1" width="200" height="200"
-      datasources="animals.rdf" ref="http://www.some-fictitious-zoo.com/all-animals">
-
-  <treecols>
-    <treecol id="name" label="Name" primary="true" flex="1"/>
-    <treecol id="species" label="Species" flex="1"/>
-  </treecols>
-
-  <template>
-    <rule>
-      <treechildren>
-       <treeitem uri="rdf:*">
-         <treerow>
-           <treecell label="rdf:http://www.some-fictitious-zoo.com/rdf#name"/>
-           <treecell label="rdf:http://www.some-fictitious-zoo.com/rdf#species"/>
-         </treerow>
-       </treeitem>
-      </treechildren>
-    </rule>
-
-  </template>
-</tree>
-
-

Image:datasrc1.jpg

-

Here, the data has been generated from the file. The ref attribute has been set to the root element in the RDF file, which is the top-level Seq. This will give us a complete list of animals. If we wanted to, we could set the ref attribute to any of the other about attribute values to limit the set of data that is returned. For example, to display only the reptiles, use a value of http://www.some-fictitious-zoo.com/reptiles.

-

Setting the ref Attribute Example

-

The example below shows how to display a particular piece of an RDF datasource by setting the ref attribute.

-

Example 3 : Source View

-
<window
-  id="example-window"
-  title="History List"
-  xmlns:ANIMALS="http://www.some-fictitious-zoo.com/rdf#"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<button label="Click here to see the mammals the zoo has" type="menu"
-        datasources="animals.rdf" ref="http://www.some-fictitious-zoo.com/mammals">
-  <template>
-    <rule ANIMALS:specimens="0"></rule>
-    <rule>
-      <menupopup>
-        <menuitem uri="rdf:*" label="rdf:http://www.some-fictitious-zoo.com/rdf#name"/>
-      </menupopup>
-    </rule>
-  </template>
-</button>
-
-</window>
-
-

In this case only the mammals are desired, so we select the URI of the mammals list. You will notice that the value of the ref attribute in the example is http://www.some-fictitious-zoo.com/mammals which corresponds to one of the Seq elements in the RDF file. This causes only the descendants of this list to be returned.

-

Two rules have been used here. The first rule catches all the resources that have their ANIMALS:specimens attribute set to 0. You can see this attribute in the RDF file on each of the Description elements. Some of them have a value of 0. So in these cases, rule one will match. Because rule one has no content, nothing will be displayed for these ones. This is an effective way to hide data that we don't want to display.

-

The second rule applies to all other resources and creates a row in a popup menu. The end effect is that we get a popup menu containing all the mammals which have a specimen that is not 0.

-

Next, we'll look at the full rule syntax.

-

-

« 上一页下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/scroll_bars/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/scroll_bars/index.html deleted file mode 100644 index ea21fc9535..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/scroll_bars/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: 滚动栏 -slug: Mozilla/Tech/XUL/Tutorial/Scroll_Bars -translation_of: Archive/Mozilla/XUL/Tutorial/Scroll_Bars ---- -

This page has no content. Enrich M

DC by contributing.cxz - -
   
   
   
-

 

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/scrolling_menus/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/scrolling_menus/index.html deleted file mode 100644 index e484aba178..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/scrolling_menus/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: XUL_教程/滚动菜单 -slug: Mozilla/Tech/XUL/Tutorial/Scrolling_Menus -tags: - - XUL_Tutorial -translation_of: Archive/Mozilla/XUL/Tutorial/Scrolling_Menus ---- -

 

-

-

« 上一页下一页 »

-

-

本节讲述滚动菜单并且将本机制运用到其它元素中。

-

创建一个大菜单

-

如果创建一个菜单,里面有很多的命令在里面,会发生什么呢?这样所有的项不会一次性在屏幕上显示完。Mozilla提供一种滚动机制允许滚动这些项。

-
- Image:menuscroll1.png
-

如果可用空间太小,在每个菜单的末端会出现箭头。如果将鼠标移动到箭头上,菜单可以上翻或下翻。如果可用的空间足够大,箭头则不会显示。注意是否出现滚动行为完全依赖于当前的实际情况(theme)。

-

该行为是完全自动的。你不必特意的去为得到滚动菜单而做些工作。它会应用于菜单栏上的菜单,滚动菜单或菜单列表中。执行它使用arrowscrollbox元素。该元素用来创建带箭头的滚动框。

-

arrowscrollbox可以被用在任何使用规范框的地方。但不能用于菜单中。通常是用于垂直的框中,并且可能包括有很多元素在里面。可以将它用于下拉列表中,当你不想要它是一个下拉框的时候。

-

示例 - 按钮的滚动列表

-

下面的示例说明了如何创建多个按钮的一个滚动列表(需要改变窗口大小以查看箭头按钮):

-

Example 1 : Source View

-
<arrowscrollbox orient="vertical" flex="1">
-  <button label="Red"/>
-  <button label="Blue"/>
-  <button label="Green"/>
-  <button label="Yellow"/>
-  <button label="Orange"/>
-  <button label="Silver"/>
-  <button label="Lavender"/>
-  <button label="Gold"/>
-  <button label="Turquoise"/>
-  <button label="Peach"/>
-  <button label="Maroon"/>
-  <button label="Black"/>
-</arrowscrollbox>
-
-

试一下这个示例,首先它会以完全大小打开。但是,如果缩小窗口的高度,滚动箭头就会出现。将窗口拉大则箭头会消失。

-

可以设置CSS中arrowscrollboxmax-height属性来限制滚动框的大小,这样使箭头能够一直显示。

-

因此,arrowscrollbox在菜单和弹出菜单中相当有用。

-

下回,我们将学习如何添加一些XUL元素的事件句柄.

-

-

« 上一页下一页 »

-

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/simple_menu_bars/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/simple_menu_bars/index.html deleted file mode 100644 index a9179852f7..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/simple_menu_bars/index.html +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: XUL_教程/简单菜单栏 -slug: Mozilla/Tech/XUL/Tutorial/Simple_Menu_Bars -tags: - - XUL_Tutorial -translation_of: Archive/Mozilla/XUL/Tutorial/Simple_Menu_Bars ---- -

 

- -

-

« 上一页下一页 »

-

- -

在本节中,我们来看看如何创建菜单栏及菜单项。

- -

创建菜单

- -

XUL有几种不同的方式来创建菜单。最基本的方式当然是类似大多数程序拥有一个菜单栏并附有一排菜单项在上面。也可以创建弹出式菜单。XUL的菜单特性由几种不同的元素组成,它可以让你创建菜单栏和弹出式菜单。菜单上的项可以轻松的进行自定义。我们在part of how to make menus一文中已经学习过使用menulist了。本节我们就以此为基础。

- -

菜单栏通常像toolbar一样创建。菜单栏也可以放置于toolbox中,则菜单就像在其它类型工具栏一样。XUL拥有一些特殊元素,可以提供一些特定功能的菜单。

- -

有五种相关的元素用来创建菜单栏及其菜单,在此我们简单解释一下,在后面我们再详述:

- -
-
menubar
-
一排菜单的窗口。
-
- -
-
menu
-
尽管名字是菜单,但它实际上在菜单栏上仅仅体现其主题而已。该元素可以放置在菜单栏中或者独立放置。
-
- -
-
menupopup
-
当点击菜单主题时,弹出框会显现。该框包括了菜单命令的列表。
-
- -
-
menuitem
-
菜单上的独立命令。应放置于menupopup中。
-
- -
-
menuseparator
-
菜单上的分割条。应放置于menupopup中。
-
- -
-

你可以在除Macintosh之外的任何平台在菜单栏中自定义任何你想要的菜单。这是因为Macintosh自己特殊的菜单置于屏幕最顶端,由系统控制着。虽然你可以创建自定义菜单,但放置于菜单上的任何特殊样式的规则或非菜单元素均不能生效。在创建菜单时头脑中留意这一点。

-
- -
简单菜单栏示例
- -

Example 1 : Source View

- -
Image:menubar-ex1.png
- -
<toolbox flex="1">
-  <menubar id="sample-menubar">
-    <menu id="file-menu" label="File">
-      <menupopup id="file-popup">
-        <menuitem label="New"/>
-        <menuitem label="Open"/>
-        <menuitem label="Save"/>
-        <menuseparator/>
-        <menuitem label="Exit"/>
-      </menupopup>
-    </menu>
-    <menu id="edit-menu" label="Edit">
-      <menupopup id="edit-popup">
-        <menuitem label="Undo"/>
-        <menuitem label="Redo"/>
-      </menupopup>
-    </menu>
-  </menubar>
-</toolbox>
-
- -

喏,使用menubar元素创建了一个简单的菜单栏。上面还会创建一排菜单。menu元素在菜单顶端创建菜单主题显示于菜单栏上。使用menupopup元素创建弹出菜单。用户点击父菜单主题时,会弹出显示。弹出菜单框的大小会足够的大,可以容纳里面所有的菜单命令显示。菜单命令本身使用menuitem元素进行创建。每一个都代表菜单弹出框上的一个单独命令。

- -

你还可以使用menuseparator元素创建菜单上面的分割线。用于分割不同的菜单项组。

- - - -

menubar是一个包括菜单的框。注意它已经被放置于一个固定的toolbox中。菜单栏没有特殊的属性一,仅仅是一种类型的框。这意味着可以创建一个垂直的工具栏,通过设置orient属性为vertical。

- - - -

menu元素运行起来就像是button元素。可以接受与它相同的部分属性及额外的一些属性:

- -
-
id
-
菜单主题按钮的唯一标识符。
-
- -
-
label
-
显示在菜单上的文字,例如 文件 或 编辑。
-
- -
-
disabled
-
该布尔属性决定菜单是否被禁用。虽然可以,但很少情况需要禁止整个菜单。该属性值可以被设置为true或者false。当然,后者是默认值。
-
- -
-
accesskey
-
该属性值是用户可以按键盘激活菜单项的键值。该字母通常在菜单主题后面以下划线方式显示。Mozilla会视标签属性根据在此指定的字符给它加上下划线。因此,需要指定一个在文本中存在的字符(尽管指定的键不在文本中也能正常工作)。
-
- -
Image:menubar-ex2.jpg
- -

menu元素通常放置在菜单栏上,尽管这不是必需的。但是,这将出现不一样的显示结果。此处的图片展示了早期没有菜单栏的示例看起来的效果。

- - - -

menupopup元素创建包括菜单命令的弹出窗口。它是一种类型的框,默认为垂直布局。如果你想要并且将menuitems放置在一排中,你可以将它改为水平布局。通常仅有menuitems元素和menuseparators放置在menupopup中。你可以放置任何元素在menupopup中,但是在Macintosh中它们都会被忽略。

- - - -

menuitem元素与menu元素非常相似并且拥有部分相同属性。

- -
-
id
-
菜单项的唯一标识符。
-
- -
-
label
-
显示在菜单项上的文本,例如打开 或 保存。
-
- -
-
disabled
-
该布尔属性值决定菜单项是否被禁止。该属性可以被设置为true或者false,但默认值是后者。
-
- -
-
accesskey
-
该值是用户可以使用键盘激活菜单项的键值。该字母通常以下划线方式显示于菜单主题后面。Mozilla将视label属性值给指定的字母加上下划线。因此,你需要指定在文本中存在的字符。
-
- -
-
acceltext
-
该值指定显示在菜单命令末尾的快捷键文本提示。但是它还没有与menuitem进行键的关联。我们在后面再研究如何do this later.
-
- - - -

menuseparator没有特别的属性。它只是在两个相信的菜单元素之间创建一条水平的分割线。

- -

下一节,我们会学习一些更多菜单特性.

- -

-

« 上一页下一页 »

-

- -

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/splitters/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/splitters/index.html deleted file mode 100644 index 172190858c..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/splitters/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: 分割线 -slug: Mozilla/Tech/XUL/Tutorial/Splitters -translation_of: Archive/Mozilla/XUL/Tutorial/Splitters ---- -

我们来看看如何向一个窗口添加分隔线。

-

 分隔box

-

有时候你可能会想将一个窗口分成两节,而使用户可以改变这两节的尺寸。一个例子是mozilla的浏览器窗口,你可以通过拖动两个结构之间的小条来改变侧边栏的尺寸。你也可以点击旁边的标记隐藏这个侧边栏

-

元素splitter

-

这个特性是由一个叫做splitter的元素来实现的。它可以在两个节之间创建一个较小的条,可以让用户来改变两边的大小。你可以将splitter放在任何想要放置的地方,这样就可以改变在同一个格子里前后元素的大小了当在水平box中放置一个splitter的时候,将会水平的改变大小。当放在竖直的box中的时候,就可以改变竖直方向的大小了。

-

元素splitter的用法如下:

- - - - - - -
-

<splitter

-

    id="identifier"

-

    state="open"

-

    collapse="before"

-

    resizebefore="closest"

-

    resizeafter="closest">

-
-

属性如下:

-

属性id  全局唯一标识

-

属性state 指出splitter的状态。默认设为open,将分割面板分开,否则设置为collapse,将其中一个隐藏,另一个占据整个空间

-

属性collapse 这表明当点击隐藏标记的时候隐藏哪一边。设置为before则隐藏前面的元素,如果设置为after则隐藏分割线后面的元素。如果设置为none,也是默认的值,当点击隐藏标记的时候都不会隐藏。

-

属性resizebefore 当分割线被拖动的时候。其左边或者上面的元素会改变大小。这一属性说明哪一个元素改变大小。设置为closest会使左边离分割线最近的立即改变大小,设置为farther则左边离分割线最远的元素将会最先改变大小。默认值为closest。

-

属性resizeafter当分割线被拖动的时候。其右边或者下面的元素会改变大小。这一属性说明哪一个元素改变大小。设置为closest会使右边离分割线最近的立即改变大小,设置为farther则右边离分割线最远的元素会改变大小。这个属性还可以设置为grow,这种情况下分割线右边的部分不会改变大小,相反的,整个格子会改变大小。默认值为closest。

-

如果设置了collapse属性,还可以添加一个grippy元素在splitter里面,这个元素可以用来销毁元素。

-

分割线旁边的元素的width和height属性会在splitter拖动的时候进行调整。准确的说是根据resizebefore和resizeafter属性来调整。

-

Splitter的例子

-

例子1:

- - - - - - -
-

<hbox flex="1">

-

  <iframe id="content-1" width="60" height="20" src="w1.html"/>

-

  <splitter collapse="before" resizeafter="farthest">

-

    <grippy/>

-

  </splitter>

-

  <iframe id="content-2" width="60" height="20" src="w2.html"/>

-

  <iframe id="content-3" width="60" height="20" src="w3.html"/>

-

  <iframe id="content-4" width="60" height="20" src="w4.html"/>

-

</hbox>

-
-

-

这里创建了4个iframe以及一个分割线,分割线在第一个和第二个iframe之间。属性collapse设置为before,也就是当隐藏标记点击的时候,第一个frame会消失。

-

这个splitter的resizeafter属性设置为farther。也就是说当拖动splitter的时候,其后最远的元素会改变大小。也就是frame4会改变大小。

-

没有对resizebefore设置值,因此其默认值是closest。这里,分割线之前只有一个splitter,因此frame1会改变大小。

-

Frame2和frame3只有在frame4达到最小值时才会改变大小。

-

-

也可以在一个窗口上放置多个splitter。同样的也可以隐藏其他元素,而不仅仅是frame。

-

 查找文件对话框例子

-

让我们看看给查找文件对话框添加一个splitter之后是个什么样子。一个可能是在对话框中添加查找结果,在搜索选项和按钮之间。分割线可以让你隐藏或者查看搜索结果。

- - - - - - -
-

</tabbox>

-

 

-

  <iframe src="results.html"/>

-

  <splitter collapse="before" resizeafter="grow">

-

   <grippy/>

-

  </splitter>

-

 

-

 <hbox>

-
-

这里添加了一个iframe和一个splitter。这里在tabbox之后不需要spacer了,可以将其移除。Frame的内容包含在一个'results.html'文件里面,现在创建这个文件并将其放在任何地方。以后我们会用一个结果列表来代替它。

-

这个splitter的collapse属性设置为before,就是说分割线之前的元素将会被隐藏。这里就是这个iframe。下面又一个隐藏标志点击之后的图。

-

属性resizeafter设置为grow,这样分割线之后的元素将会在分割线向下拖动的时候向下移动。Frame中的内容的大小可以变到任何尺寸。注意,窗口自己不会改变大小,你也会发现这是一个水平分割线,因为是放在竖直box里面的。

-

正常状态

-

-

隐藏后状态

-

-

接下来将会介绍如何创建工具条

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/stack_positioning/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/stack_positioning/index.html deleted file mode 100644 index 40712df82e..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/stack_positioning/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: 定位层(stack堆) -slug: Mozilla/Tech/XUL/Tutorial/Stack_Positioning -translation_of: Archive/Mozilla/XUL/Tutorial/Stack_Positioning ---- -

这一节描述如何为堆中的元素进行定位

-

堆子元素的位置

-

通常,stack的子元素为与堆的大小匹配会自动扩展。然而,你也可以将其子元素放在指定的位置。例如,如果一个堆有两个按钮子元素,一个房子左边缘20像素,距顶部50像素。第二个可以房子距离左边缘100像素而距离顶部5像素。

-

可以通过设置两个属性来指定子元素的位置,水平方向上使用left属性,竖直方向上使用top属性。如果你在stack的子元素中不指定这些属性,就会扩展以匹配堆的尺寸。

-

例子1:

-

- - - - - - -
-

<stack>

-

  <button label="Goblins" left="5" top="5"/>

-

  <button label="Trolls" left="60" top="20"/>

-

  <button label="Vampires" left="10" top="60"/>

-

</stack>

-
-

这个堆有三个子元素,每个元素都使用了left和top属性来定位。这里所有的子元素都是按钮,但是并不是所有的子元素必须是同一类型。可以是任意元素,包括格子或者其他堆。

-

堆的大小由所有紫云山的位置来决定,总会将大小调整到所有子元素都可见的大小。如果你将left属性设置为400,堆将会有一个400加上元素宽度的宽度。你也可以通过各种样式的不同属性如width。Max-width等来重写这个尺寸。

-

也可以通过脚本来调整left和top的值,这样就会使元素移动。堆的优点是当一个指定位置元素位置发生变化时,其他元素不会受到影响。如果在格子中移动子元素,其他元素可能会动态的改它们的位置。

-

你也可以将元素重叠起来。当绘制子元素的时候,元素会按照它们出现在堆中的顺序出现。就是说,第一个子元素在最后面。最后一个元素出现在顶部。你可以使用DOM函数来改变子元素的顺序。

-

在响应鼠标事件的时候,顶部的元素会最先获取这个事件。也就是说如果有两个按钮重叠起来了,最上面的那个按钮会捕获到鼠标点击的事件。

-

下一节描述标签格子(tabboxes),与面板相似但有自己的外观

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/stacks_and_decks/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/stacks_and_decks/index.html deleted file mode 100644 index 39aa1762a1..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/stacks_and_decks/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: 层和卡片 -slug: Mozilla/Tech/XUL/Tutorial/Stacks_and_Decks -translation_of: Archive/Mozilla/XUL/Tutorial/Stacks_and_Decks ---- -

有时候需要将元素按照一系列重叠的卡片一样进行显示。堆和面板元素可以达到这一目的。

-

 容器

-

每一个XUL格子元素都是一个可以容纳其他元素的容器。有很多具有特殊样式的格子,例如工具条和标签面板。标签box可以创建不带有任何特殊属性的最简单格子。然而,具有特殊样式的格子与常规的格子一样对其内部的元素进行排列,只是他们有附加特性而已。

-

事实上,很多组件可以容纳其他元素。我们已经看到了按钮可以容纳除了默认元素之外的其他元素。滚动条也是也是一种特殊的格子类型,如果你不提供元素的话,他们会自己创建自己的元素。它也会自己处理滑块的运动。

-

接下来的几节,我们会介绍一些用来容纳其他元素的元素。他们都是有特殊样式的格子,可以将格子的所有属性都用在这些元素上。

-

  堆

-

元素stack是一个简单的格子,与其他格子的工作模式一样,只是它的子元素将会处于所有其他元素的最上面。第一个子元素会在最下面。第二个紧接着第一个,接着是第三个,等等。在一个堆中可以堆上任意多的元素。

-

属性orient没有什么意义,因为堆中的子元素都是一个在一个的上面,而不是一个紧挨一个的。堆的大小由最大的子元素的大小决定。但你可以使用CSS属性的width,height,min-width和其他相关属性来控制堆和他的子元素。

-

元素stack可以在需要为已经存在的元素添加状态指示器时使用。例如,进度条可能会用一个直条和上面一个label来创建。

-

带有阴影的堆

-

为了方便的使用stack元素,可能需要为它仿制很多CSS属性。比如像下面这样为它创建一个文字阴影的效果:

-

例子1:

- - - - - - -
-

<stack>

-

  <description value="Shadowed" style="padding-left: 1px; padding-top: 1px; font-size: 15pt"/>

-

  <description value="Shadowed" style="color: red; font-size: 15pt;"/>

-

</stack>

-
-

-

两个description元素都创建了一个大小为15点的文字。首先是通过在左边和顶部添加一个1像素的偏移。这样的结果是重复绘制文字'Shadowed'但会与另一个有一点点的偏移。

-

这种方法的比使用text-shadow有一些优势,因为你可以完全将主体文字与阴

-

影分开进行控制。它可以有自己的字体,下划线或者大小。(你甚至可以制作阴影闪烁的效果)。这在mozilla不支持CSS的文字阴影时也很有用。缺点是阴影的存在使得堆的尺寸变大了。。阴影效果对于创建禁用的按钮的外观很有用:

-

例子2:

- - - - - - -
-

<stack style="background-color: #C0C0C0">

-

  <description value="Disabled" style="color: white; padding-left: 1px; padding-top: 1px;"/>

-

  <description value="Disabled" style="color: grey;"/>

-

</stack>

-
-

这样安排文字和阴影颜色在某些平台上会产生禁用的外观

-

注意,鼠标点击或者按键按下的事件是在堆上顶部元素,即堆中的最后一个元素。就意味着按钮只有是堆中最后一个元素的时候才能工作。

-

  面板

-

元素deck也是和stack一样只在顶部显示一个子元素,但是面板一次只显示一个子元素。这对向导接口非常有用,其中一系列相似的面板顺序显示。你可以通过使面板中的内容发生变化而只创建一个窗口,而不是创建多个独立的窗口和导航按钮。

-

与堆相似,deck元素的直接子元素组成ianb的页面。面板的显示页面可以通过改变设置selectedIndex属性来控制显示出来的子元素。索引是一个数字,可以指定哪一个页面将会显示。页面索引起始值为0.因此第一个子元素的page0,第二个是page1,等等。

-

例子3:

- - - - - - -
-

<deck selectedIndex="2">

-

  <description value="This is the first page"/>

-

  <button label="This is the second page"/>

-

  <box>

-

    <description value="This is the third page"/>

-

    <button label="This is also the third page"/>

-

  </box>

-

</deck>

-
-

这里有三个页面,默认为显示第三个。第三个页面是一个格子,里面有两个元素。格子里面的元素和格子本身组成了一个页面。面板的大小是子元素中最大的大小这里就是第三个页面。

-

你可以在脚本中改变selectedIndex属性来对页面进行切换。更多关于这个方面的介绍在事件和DOM的章节

-

下一节将会描述如何定位堆中的元素

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/styling_a_tree/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/styling_a_tree/index.html deleted file mode 100644 index 7574e792b7..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/styling_a_tree/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: 样式化树 -slug: Mozilla/Tech/XUL/Tutorial/Styling_a_Tree -translation_of: Archive/Mozilla/XUL/Tutorial/Styling_a_Tree ---- -

XUL:<treerow properties="makeItBlue">

-

css:
- treechildren::-moz-tree-row(makeItBlue)
- {
-   background-color: blue;
- }

-

可以参考这里 点击这里

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/tabboxes/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/tabboxes/index.html deleted file mode 100644 index c8c3e527c7..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/tabboxes/index.html +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: 分页组 -slug: Mozilla/Tech/XUL/Tutorial/Tabboxes -tags: - - tabbox -translation_of: Archive/Mozilla/XUL/Tutorial/Tabboxes ---- -

选择对话框中经常出现标签页,这里我们将会了解如何创建它们。

-

分页组

-

在应用程序的选择窗口中经常出现典型的标签页。在窗口的顶部会出现一系列的标签。用户可以通过点击相应的标签来查看不同的选项集合。当你有很多选项而无法在一个屏幕中完全显示的时候非常有用。

-

XUL也提供了一种方法来创建这样的对话框。包含五种新的元素,下面详细的介绍这几个元素。

-

tabbox 最外层的格子,含有顶部的标签和标签页。

-

tabs 含有独立标签页的内部格。即这是一排标签

-

tabpanels 页面的容器

-

tabpanel 一个单独的页面的主体。你可以将一个页面的内容放在里面。第一个tabpanel对应于第一个标签页,第二个对应第二个,等等。

-

元素tabbox含有两个子元素,一个tabs元素和一个tabpanels元素。用法如下:

- - - - - - -
-

<tabbox id="tablist">

-

  <tabs>

-

    <!-- tab elements go here -->

-

  </tabs>

-

  <tabpanels>

-

    <!-- tabpanel elements go here -->

-

  </tabpanels>

-

</tabbox>

-
-

元素tab放在tabs里面,这与常规的box很像。元素tab与box其实没有什么不同的。Tab可以容纳任何类型的元素。不同的是,tab的面板一次只显示一个页面,与deck很相像。

-

每个标签页的内容应该放到每个tabpanel元素内部。他们不是在tab元素内部的。Tab元素的内容出现在顶部。

-

每个tabpanel元素成为显示时的一个页面。最大的页面的尺寸用作整个tabbox的尺寸。

-

分页组实例

-

例子1:

-

- - - - - - -
-

<tabbox>

-

  <tabs>

-

    <tab label="Mail"/>

-

    <tab label="News"/>

-

  </tabs>

-

  <tabpanels>

-

    <tabpanel id="mailtab">

-

      <checkbox label="Automatically check for mail"/>

-

    </tabpanel>

-

    <tabpanel id="newstab">

-

      <button label="Clear News Buffer"/>

-

    </tabpanel>

-

  </tabpanels>

-

</tabbox>

-
-

这里有两个标签页,一个mail一个news。当点击news标签的时候,带有'Clear News Buffer'按钮的页面会出现。

-

当前选择的标签元素有一个selected属性值为true。这可以改变当前选择的标签页。一次只能有一个标签的selected属性为true。

-

标签页的位置

-

最后,你可以改变标签页的位置以使他们出现这个页面的任意位置。没有特殊的语法。你可以简单的使用orient和dir属性来实现。注意在布局的时候记住tab元素就像一般的格子,而tabbox元素更像是常规的竖直容器,tabs元素更像是默认为水平的容器格子。

-

例如,要将标签放到左边,可以将tabs元素的朝向改为竖直的。然后调整tabbox使其具有水平朝向。这会使得标签出现在左边而不是顶部。注意改变tabpanels元素的朝向没有影响,因为标签页是相互覆盖的。

-

也可以通过将tabs元素放在tabpanels元素后面来实现将标签放在右边或者下面。或者,也可以将tabbox的dir属性设置为reverse来实现。但是你最好将标签放在上面,否则在某些流行的主题下可能看起来不是很好。

-

为查找文件对话框添加标签页。

-

让我们为查找文件的对话框添加第二个panel。我们将会创建一个选项标签(并默认选择)来包含一些搜索选项。这可能不是最好的接口。但我们使用它来说明标签的使用。顶部的文字和搜索选择各种需要放在第一个标签中,我们将会添加一些选项在第二个标签中。进度条和按钮可以放在主窗口中,在标签外部。

- - - - - - -
-

<vbox flex="1">

-

 

-

<tabbox selectedIndex="1">

-

  <tabs>

-

    <tab label="Search"/>

-

    <tab label="Options"/>

-

  </tabs>

-

  <tabpanels>

-

   <tabpanel id="searchpanel" orient="vertical">

-

 

-

    <description>

-

     Enter your search criteria below and select the Find button to begin

-

     the search.

-

    </description>

-

 

-

    <spacer style="height: 10px"/>

-

 

-

    <groupbox orient="horizontal">

-

      <caption label="Search Criteria"/>

-

 

-

      <menulist id="searchtype">

-

        <menupopup>

-

          <menuitem label="Name"/>

-

          <menuitem label="Size"/>

-

          <menuitem label="Date Modified"/>

-

        </menupopup>

-

      </menulist>

-

      <spacer style="width: 10px;"/>

-

      <menulist id="searchmode">

-

        <menupopup>

-

          <menuitem label="Is"/>

-

          <menuitem label="Is Not"/>

-

        </menupopup>

-

      </menulist>

-

 

-

      <spacer style="height: 10px"/>

-

      <textbox id="find-text" flex="1" style="min-width: 15em;"/>

-

 

-

    </groupbox>

-

   </tabpanel>

-

   <tabpanel id="optionspanel" orient="vertical">

-

    <checkbox id="casecheck" label="Case Sensitive Search"/>

-

    <checkbox id="wordscheck" label="Match Entire Filename"/>

-

   </tabpanel>

-

 </tabpanels>

-

</tabbox>

-
-

-

元素tab硬件放在了窗口的主要内容外面。你可以看到两标签,search和options。点击每一个都会将相应的标签页显示出来。如图中显示,两个选项出现在第二个标签上。第一个标签看起来与之前的更像,除了有顶部的标签之外。

-

下一节,我们来看看如何创建内容的网格(grid)

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/templates/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/templates/index.html deleted file mode 100644 index 01b1eb0cf4..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/templates/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: XUL_教程/模板(Templates) -slug: Mozilla/Tech/XUL/Tutorial/Templates -translation_of: Archive/Mozilla/XUL/Tutorial/Templates ---- -

 

-

在这一小节,我们将学习如果使用数据填充元素。

-

填充元素(Populating Elements)

-

XUL提供了通过RDF数据建立元素的方法,来源可以是一个RDF文件,也可以是一个内部数据源。Mozilla本身提供了很多数据源,比如书签、历史记录、邮件列表等。我们在下一小节会针对这部分进行更多的讨论。

-

我们通常会向treeitems和menuitems这类的元素填充数据。但你完全可以根据实际情况向其他元素填充数据。在这里,我们还是从这些其他元素入手开始讲解,因为实现树型和菜单需要的代码比较多。

-

为了使用RDF数据建立元素,首先要为这些元素提供一个复制用的模板。实际上,我们只是提供了第一个元素而已,剩下的元素都是在第一个元素的基础上构造出来的。

-

模板是通过template元素建立的。template元素里用于放置那些新构建元素的内容。template元素要置于包含新构建元素的容器中,比如说你要创建一个tree元素,那么就要把template元素置于tree元素中。

-

上面这些通过一个简单的例子来说明会很直观明了,在这个例子中,我们会为每个书签都建立 一个按钮。Mozilla提供了一个书签的数据源,我们可以直接拿来使用,为了简便,我们只取最顶层的书签(也可能是文件夹)来建立按钮。对于那些子标 签,我们可能会通过树型结构或者菜单等来显示这种层叠的结构。

-

这个例子和其他直接引用内部数据源的程序一样,只能通过chrome开头的地址来调用,处于安全考虑,Mozilla禁止从其他数据源间接调用内部数据源。

-

为了运行这个例子,你需要建立一个chrome包并把文件都置于包中,这时就可以通过在浏览器的地址栏输入chrome地址运行了。

-

示例 9.2.1: 下载

-
-
<vbox datasources="rdf:bookmarks" ref="NC:BookmarksRoot" flex="1">
-  <template>
-    <button uri="rdf:*" label="rdf:http://home.netscape.com/NC-rdf#Name"/>
-  </template>
-</vbox>
-
-

在这个例子中,建立了一个vbox,vbox里面包含一列的按钮,每个按钮都对应一个顶级的书签。你可以注意到template元素内只有一个button元素。这个唯一的按钮元素是所有按钮元素建立的基础。旁边的图片就是最后的运行结果,每个按钮对应于一个书签。

-

你可以试着在保持这个例子打开的情况下,向浏览器添加一个书签,你会发现这个例子中会立刻添加一个按钮,对应于你刚刚添加的那个书签。(你可能需要重新激活这个窗口,这样才能看到结果)

-

模板本身被置于vbox中,而box容器有两个特性专门是为模板服务的,可以标识数据的来源。第一个是datasource特性,用来声明用来建立元素的RDF数据源。在这个例子中,对应的是rdf:bookmarks。你一定可以猜到这个RDF对应的就是书签数据源。这个数据源是由Mozilla提供的。如果要使用自己的数据源,只需要在datasources特性中指定自定义的RDF地址就可以,就像下面例子中的一样:

-
-
<box datasources="chrome://zoo/content/animals.rdf"
-     ref="http://www.some-fictitious-zoo.com/all-animals">
-
-

也还可以同时设置多个数据源,只要在不同的数据源地址间加上空格就可以。这通常用于显示多个来源的数据。

-

ref特性用于说明你想从数据源获取哪些数据。在这个书签的例子中,使用的是NC:BookmarksRoot,对应的是最顶级的书签。ref具体取什么值依赖于要使用的数据源。如果你使用自己的RDF文件作为数据源,ref的value值通常被设置为Bag、Seq或者Alt元素的about特性的值。

-

当向box容器添加了这两个特性以后,就可以使用模板来生成元素了。模板里的元素要使用不同的方式来声明。你应该注意到上面例子中,button元素设置了uri特性,同时为label特性设置了一个特殊含义的值。

-

模板里的特性值如果是以“rdf:”开头的,就表明这个值是要从数据源中读取的。在上面的例子中,label特性就是这种情况。value中除了“rdf:”的剩余部分由命名空间和属性名称组成,表明要使用数据源中的name属性。如果你对这部分感到迷糊,请重新阅读《XUL教程 - 9.1 - RDF概述》的最后一段。那个例子描述了RDF中的资源是怎样被指向的。在这里我们只使用name属性,当然其他属性在这里也是可以使用的。

-

我们为这些按钮的label特性设置了特定的URI,是因为我们需要用RDF数据源中的name属性来填充label。我们可以把URI放到按钮的 任何一个特性中,放到其他元素中也是可以的。不管放到哪个特性中,都会被数据源中相应的值替换。最后的结果,就是我们用按钮label显示出了每个书签的 名字。

-

下面的例子展示了我们如何为按钮的其他特性设置数据源。当然我们已经假设数据源中包含相应的资源。如果需要的资源在数据源中没有被找到,那么特性的value就会被设置为空字符串。

-
-
<button class="rdf:http://www.example.com/rdf#class"
-        uri="rdf:*"
-        label="rdf:http://www.example.com/rdf#name"/>
-        crop="rdf:http://www.example.com/rdf#crop"/>
-
-

如上面例子所示,你可以通过不同的数据源动态设置元素的每个特性。

-

uri特性用定义开始生成内容的元素。之前的内容只会生成一次,而之后的内容会每次都生成。在后面通过模板建立树型元素的例子中,我们将对这点进行更加详细的阐述。

-

当我们将这些特性添加进模板所在的容器后(在这个例子中是box),就可以使用外部数据来建立各种有趣的列表了。我们当然可以在模板中多放几个元素,也可以在任何元素的特性上添加RDF引用,下面就是一个例子:

-

实例 9.2.2: 下载

-
-
<vbox datasources="rdf:bookmarks" ref="NC:BookmarksRoot" flex="1">
-  <template>
-    <vbox uri="rdf:*">
-      <button label="rdf:http://home.netscape.com/NC-rdf#Name"/>
-      <label value="rdf:http://home.netscape.com/NC-rdf#URL"/>
-    </vbox>
-  </template>
-</vbox>
-
-

这个模板建立了一个vbox,容器中每个书签都对应于一个按钮和一个标签。按钮上显示的是书签的名字,标签上显示的是书签的地址。

-

新建立的元素从功能上来说,和直接向XUL中添加数据是没有差别的。每一个通过模板建立的元素都会被自动添加id特性,用来标识这个资源,你也可以使用这个特性对每个资源进行引用。

-

你还可以在同一个特性的值中,定义多个不同的资源,中间用空格分隔,下面就是一个例子。可以在这里查看更多关于资源定义的语法。

-

示例 9.2.3: 源代码

-
-
<vbox datasources="rdf:bookmarks" ref="NC:BookmarksRoot"
-     flex="1">
-  <template>
-    <label uri="rdf:*" value="rdf:http://home.netscape.com/NC-rdf#Name
-rdf:http://home.netscape.com/NC-rdf#URL"/>
-  </template>
-</vbox>
-
-

建立模板(How Templates are Built)

-

一旦为元素设置了datasources特性,就表明这个元素将会通过模板来生成。要明确这点,是否生成内容不是由template标 记决定的,而是由atasources特性来决定的。只要设置了这个特性,元素就会自动被添加一个叫做构造器的对象。这个对象的责任就是通过模板来构建内 容。在JavaSciprt中,你可以使用builder属性来访问这个构造器对象,但通常你只有在需要手动重新生成内容的时候才需要调用这个对象。

-

构造器有两种类型,最常用的是内容构造器(content builder),另外一种是树型构造器(tree builder),当然只有在构造树型元素的时候才用的到。

-

内容构造器从template元素中读取内容,并在每行都进行复制。比如在上面的例子中如果有十个书签,就会构建10个label元素,并都会添加到vbox元素下面。如果你使用DOM函数对树型结构进行遍历,你可以找到这些元素,并可以调用它们的属性。这些元素最终会在界面显示出来,但是template元素本身是不会显示的,虽然在DOM中是可以找到template元素的。另外,每个label的id特性将被设置为RDF资源中对应的值。

-

内容构造器总是从uri="rdf:*"定义的地方开始操作。如果uri特性所在的元素不是在第一行,那么之前的元素都值将被建立一次。下面的例子中会建立一个hbox,hbox内会用一组label来填充。

-

--------------------------------------------------------------------------------

-

本文完整内容请参见:

-

http://cuimingda.com/2008/10/xul-tutorial-templates.html

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/the_box_model/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/the_box_model/index.html deleted file mode 100644 index be0bf1832c..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/the_box_model/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: XUL_教程/分组方式 -slug: Mozilla/Tech/XUL/Tutorial/The_Box_Model -tags: - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/The_Box_Model ---- -

-

« 上一页下一页 »

-

-

 

-

盒模型入门

-

在XUL里主要的布局叫做“盒模型”。这个模型允许你把窗口分割成连续的盒子。在盒子里面元素可以按水平或垂直方向排列。通过将一系列的盒子结合在一起,使用定位格和元素的flex属性,你可以控制窗口的布局。

-

虽然盒模型是XUL元素布局的基础部份,但原理并不复杂,只有几条简单的规则。一个盒子可以将它的子盒布置在两个方向之一,水平或垂直。水平盒子将它的元素进行水平排列,而垂直盒子将它的元素进行垂直排列。你可以把一个盒子想像HTML表格中的一行或一列。除了可以在子元素中放置不同的属性还可以使用一些样式表属性来控制子盒的精确定位和尺寸。

-

盒的例子

-

下面是定义盒子的基本语法:

-
<hbox>
-  <!-- horizontal elements -->
-</hbox>
-
-<vbox>
-  <!-- vertical elements -->
-</vbox>
-
-

hbox元素用来创建一个水平方向的盒子。每个放在hbox中的元素将被水平地排成一行。vbox 元素用来创建一个垂直方向的盒子。添加进来的元素将会被垂直地放在前一个的下面。

-

同样有一个普通的box元素默认是水平方向的,和hbox的意思相同。然而,你可以使用orient 属生去操作盒子的方向。你可以设置这个属性的值为horizontal 去创建一个水平的盒子和vertical去创建一个垂直的盒子。

-

因此,下面两行的效果是一样的:

-
<vbox></vbox>
-
-<box orient="vertical"></box>
-
-

下面例子展示怎么垂直放置三个按钮。

-

例1 : Source View

-
- Image:boxes-ex1.png
-
<vbox>
-  <button id="yes" label="Yes"/>
-  <button id="no" label="No"/>
-  <
diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/the_chrome_url/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/the_chrome_url/index.html deleted file mode 100644 index 817869f2d2..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/the_chrome_url/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: 关于Chrome URL -slug: Mozilla/Tech/XUL/Tutorial/The_Chrome_URL -translation_of: Archive/Mozilla/XUL/Tutorial/The_Chrome_URL ---- -
- << 前页 后页 >>
-

Chrome统一资源定位器(URL)

-

下面的部分将描述如何关联(引用)XUL文档和其他的chrome文件。

-

<big>Chrome统一资源定位器(URL)</big>

-

XUL文件可以像HTML文件一样被一个普通的HTTP URL(或者其他任何类型的URL)关联。尽管如此,用于Mozilla的chrome系统的软件包可以用特殊的chrome URL关联。Mozilla自带的软件包伴随Mozilla已经安装好,但你可以注册自己的包。

-

软件包安装过之后具有不受安全限制的优点——安全限制对于很多程序来说都是必须的。相对于其他类型的URL来说,另外一个好处是它们可以自动处理多个主题和语言选项。举例来说,一条chrome URL允许你关联(引用)某个主题当中的一个文件,比如说是图片,与此同时你不需要知道用户当前使用的是哪个主题。只要不同主题里面的对应文件名相同,你总是可以通过chrome URL来引用这个文件。Mozilla会找到文件的路径并返回正确的数据。这也就意味着,软件包安装的位置与是否能访问它没有关系。chrome URL与文件物理存放位置无关,这使得写含有很多文件的程序变得简单了,因为你无需关心文件位置的细节。

-

Chrome统一资源定位器(URL)的基本语法规则如下:

- - - - - - -
-
-chrome://<package name>/<part>/<file.xul>
-
-

上面的<package name>是软件包的名字,比如是编辑器或聊天工具。<part>可以是'content','skin'或'locale',这取决于你的需要。'file.xul'是文件名。

-

示例chrome://messenger/content/messenger.xul

-

这个例子关联到的是'content'中的messenger窗口。将'content'替换为'skin'并改掉文件名,就可以指向皮肤中的某个文件。同样的,用'locale'替换'content'后,我们就能指向语言中的文件。

-

当你打开一个chrome URL,Mozilla在其已安装包列表中查找,尝试定位到与URL中包名相同的JAR文件和目录.chrome URL和JAR文件之间的对应关系由chrome目录中的'清单'(manifest)文件来指定。如果你把messenger.jar移动到别的地方,并相应地更新'清单'文件中的信息,Thunderbird(译者注:此处Thunderbird是上文中提到的messenger)仍然能够正确工作,因为它不依赖特定的安装位置。利用chrome URL我们可以脱离Mozilla中例如包的位置等细节信息。类似地,如果用户改变了主题,'skin'部分的chrome URL实际所指向的就是另外的一套文件,但XUL和脚本无需改变。

-

下面是更多的示例。注意例子中URL是如何避免指定使用某个特定的主题或者语言,以及如何避免指定特定目录的。

- - - - - - -
-
-chrome://messenger/content/messenger.xul
-chrome://messenger/content/attach.js
-chrome://messenger/skin/icons/folder-inbox.png
-chrome://messenger/locale/messenger.dtd
-
-
-

要关联到子目录,你只要在chrome URL的最后加上目录名就可以。下面的这些URL关联到bookmarks窗口,这里列出来了适合Mozilla和Firefox的版本——因为两者软件包的名字有差异:

- - - - - - -
-
-chrome://communicator/content/bookmarks/bookmarksManager.xul (Mozilla)
-chrome://browser/content/bookmarks/bookmarksManager.xul (Firefox)
-
-
-

chrome URL在任何普通URL可以使用地方一样能用,甚至你可以在Mozilla的浏览器窗口(译者注:地址栏)中直接输入。当在浏览器地址栏中输入上面提到的URL之一,你会发现窗口会像网页一样显示出来,而且大多数功能和在单独的窗口一样可以正常使用。但是,有些对话框可能工作不正常,那可能是因为需要由父窗口在打开他们的时候传递一些参数。

-

你还将会遇到不带文件名的chrome URL,比如:

- - - - - - -
-
-chrome://browser/content/
-
-

这种情况只有给出了包名和模块名。这类的引用(关联)会自动从目录中选择一个合适的文件。对于content来说,与包同名并带有.xul后缀的文件会被选中。在上面的例子中,显示的会是'browser.xul'。对于messenger包,messenger.xul会被显示。当你创建自己的包时,你需要为你的主窗口创建一个和软件包同名的文件,这样它就能被上面这种短形式的URL关联。这样带来的便利是只要用户知道包的名字,他就能打这个应用程序。当然了,对于修改浏览器界面的扩展(extensions)来说,用户不需要知道URL,因为扩展通过用户界面来显示自身。

-

对于皮肤而言,包名.css被选中;对于语言,选中的是包名.dtd。

-

需要记住的是,chrome URL与它在磁盘上的位置无关。URL的第一部分两个元素是包名和模块(content,skin或locale)。将内容文件放在叫'content'的目录是很普遍的事情,这和惯例不符,这些文件会被放在一个完全不同的结构中。

-
-

(下一部分) 在接下来的部分,我们将看看如何创建'清单'(manifest)文件和包。

-
- << 前页 后页 >>
diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/toolbars/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/toolbars/index.html deleted file mode 100644 index 4ba0a4e2e3..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/toolbars/index.html +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: XUL_教程/工具栏 -slug: Mozilla/Tech/XUL/Tutorial/Toolbars -tags: - - XUL_Tutorial -translation_of: Archive/Mozilla/XUL/Tutorial/Toolbars ---- -

 

-

-

« 上一页下一页 »

-

-

工具栏通常沿着窗口顶部放置,并包含许多完成普通功能的按钮。XUL有一个创建工具栏的方法。

-

A toolbar is usually placed along the top of a window and contains a number of buttons that perform common functions. XUL has a method to create toolbars.

-


- 工具栏

-

Like a number of elements, XUL toolbars are a type of box.像许多的界面要素, XUL工具栏也是一种界面框。 Usually, a row of buttons would appear in the toolbar, but any element can be placed in a toolbar.通常,工具栏里会出现一排按钮,但任何界面要素都可以放到工具栏里。 For example, the Mozilla browser window contains a textbox that displays the page URL.举例来说, mozilla浏览器窗口包含一个文本框 ,显示了该网页的url 。

-

Toolbars may be placed on any side of the window, either horizontally or vertically.工具栏可被水平或垂直地放置在窗口的任一边。 Of course you wouldn't normally put a textbox in a vertical toolbar.当然,通常你不会把文本框放在一个垂直工具栏里。 Actually, because toolbars are just boxes they can actually go anywhere you want, even in the middle of a window.事实上,因为工具栏只是个界面框,它们能去你想要它们去的任何地方,即使是窗口的中间。 Typically however, a set of toolbars would appear along the top of a window.通常,一组工具栏会出现在窗口的顶部。 When more than one toolbar is placed next to each other, they are typically grouped together in something called a 'toolbox'.当多个工具栏一个接一个放置时,他们通常被一个叫做'工具箱'的东西集合在一起。 [ edit ] A simple toolbar inside a toolbox [编辑] 一个简单的工具栏里面一个工具箱

-

Source View 来源 查看 形象: toolbar1.jpg

-
<toolbox>   <toolbar id="nav-toolbar">     <toolbarbutton label="Back"/>     <toolbarbutton label="Forward"/>   </toolbar> </toolbox> <工具箱> <toolbar id="nav-toolbar"> <toolbarbutton label="back"/> <toolbarbutton label="forward"/> < /工具栏> < /工具箱>
-
-

This has created a toolbar containing two buttons, a Back button and a Forward button.这就造成了一种工具列载有两个按钮,有一个备份(后退)按钮和前进按钮。 The one toolbar has been placed inside the toolbox.在一个工具栏已被置于内工具箱。 This has involved four new tags, which are described here.这涉及到4个新的标签,这是形容这里。

-

toolbox 工具箱

-
   A box that contains toolbars.一个方框,其中包含工具栏。
-
-

toolbar 工具栏

-
   A single toolbar that contains toolbar items such as buttons.一个单一的工具栏包含了工具栏的项目,如按钮。
-
-

toolbarbutton toolbarbutton

-
   A button on a toolbar, which has all the same features of a regular button but is usually drawn differently.一个按钮,一个工具条,其中已全部一样的特点,定期按钮,但通常是取用不同。
-
-

The toolbar is the main element that creates the actual toolbar. 该工具是主要因素,造成了实际的工具栏。 Inside it are placed the individual toolbar items, usually buttons, but they can be other elements.它里面放置了个人工具栏的项目,通常是按钮,但是它们可以被其他元素。

-

In the example above, only one toolbar was created.在上面的例子中,只有一个工具栏被创建。 Multiple toolbars can be created just as easily by adding more toolbar elements after the first one.更多工具栏的创建就想在第一个工具栏中添加元素一样容易。

-

The toolbox is a container for toolbars. 工具箱是一个容器工具栏。 In some applications, you will have several toolbars along the top of the window.在某些应用中,你将有几个工具栏沿顶部的窗口。 You can put them all inside a toolbox .你可以把它们都内一个工具箱。

-

You do not have to put toolbar elements inside a toolbox .你不须要把工具栏的内容里面一个工具箱。 [ edit ] Our find files example [编辑] 我们找到档案为例

-

Let's add a toolbar to the find files dialog.让我们添加一个工具栏,向找到的文件对话框。 We don't really need one but we'll add one anyway to demonstrate its use.我们并不真的需要一个,但我们将增加一个无论如何,以证明其使用。 Two buttons will be added, an Open button and a Save button.两个按钮将被增加,一个打开按钮和一个储存按钮。 Presumably, they would allow the user to save search results and re-open them later.据推测,它们将使用户能够保存搜寻结果,或重新打开。

-
<vbox flex="1"> <toolbox>     <toolbar id="findfiles-toolbar">       <toolbarbutton id="opensearch" label="Open"/>       <toolbarbutton id="savesearch" label="Save"/>     </toolbar>   </toolbox> <tabbox> < vbox挠性= " 1 " > <toolbox> <toolbar id="findfiles-toolbar"> <toolbarbutton id="opensearch" label="open"/> <toolbarbutton id="savesearch" label="save"/> < /工具栏> < /工具箱> <tabbox>
-
-

形象: toolbar5.png

-

A toolbar with two buttons has been added here.工具栏上有两个按钮已被添加在这里。 In the image, you can see them appear horizontally along the top.在图像,你可以看到他们出现横向沿顶部。 Notice that the toolbar has been placed inside the vertical box just above the tabbox.公告说,该工具已被置于内垂直票房略高于tabbox 。 This is because we need the vertical orientation so that the toolbar will appear above everything else.这是因为,我们需要的垂直方向,使该工具栏将出现高于一切。

-

The find files example so far: Source View这一发现的档案为例,目前为止:源观

-

Next, we'll find out how to add a menu bar to a window .明年,我们将看看如何添加一个菜单栏,以一个窗口 。

-

 

-

Adding a Toolbar

-

Like a number of elements, XUL toolbars are a type of box. Usually, a row of buttons would appear in the toolbar, but any element can be placed in a toolbar. For example, the Mozilla browser window contains a textbox that displays the page URL.

-

Toolbars may be placed on any side of the window, either horizontally or vertically. Of course you wouldn't normally put a textbox in a vertical toolbar. Actually, because toolbars are just boxes they can actually go anywhere you want, even in the middle of a window. Typically however, a set of toolbars would appear along the top of a window. When more than one toolbar is placed next to each other, they are typically grouped together in something called a 'toolbox'.

-
A simple toolbar inside a toolbox
-

Source View

-
- Image:toolbar1.jpg
-
<toolbox>
-  <toolbar id="nav-toolbar">
-    <toolbarbutton label="Back"/>
-    <toolbarbutton label="Forward"/>
-  </toolbar>
-</toolbox>
-
-

This has created a toolbar containing two buttons, a Back button and a Forward button. The one toolbar has been placed inside the toolbox. This has involved four new tags, which are described here.

-
-
- toolbox
-
- A box that contains toolbars.
-
-
-
- toolbar
-
- A single toolbar that contains toolbar items such as buttons.
-
-
-
- toolbarbutton
-
- A button on a toolbar, which has all the same features of a regular button but is usually drawn differently.
-
-

The toolbar is the main element that creates the actual toolbar. Inside it are placed the individual toolbar items, usually buttons, but they can be other elements.

-

In the example above, only one toolbar was created. Multiple toolbars can be created just as easily by adding more toolbar elements after the first one.

-

The toolbox is a container for toolbars. In some applications, you will have several toolbars along the top of the window. You can put them all inside a toolbox.

-

You do not have to put toolbar elements inside a toolbox.

-
-

Our find files example

-

Let's add a toolbar to the find files dialog. We don't really need one but we'll add one anyway to demonstrate its use. Two buttons will be added, an Open button and a Save button. Presumably, they would allow the user to save search results and re-open them later.

-
<vbox flex="1">
-  <toolbox>
-    <toolbar id="findfiles-toolbar">
-      <toolbarbutton id="opensearch" label="Open"/>
-      <toolbarbutton id="savesearch" label="Save"/>
-    </toolbar>
-  </toolbox>
-  <tabbox>
-
-

 

-
- Image:toolbar5.png
-

A toolbar with two buttons has been added here. In the image, you can see them appear horizontally along the top. Notice that the toolbar has been placed inside the vertical box just above the tabbox. This is because we need the vertical orientation so that the toolbar will appear above everything else.

-

The find files example so far: Source View

-
-

Next, we'll find out how to add a menu bar to a window.

-

-

« 上一页下一页 »

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/trees/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/trees/index.html deleted file mode 100644 index 6162b31e6a..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/trees/index.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: 树结构 -slug: Mozilla/Tech/XUL/Tutorial/Trees -translation_of: Archive/Mozilla/XUL/Tutorial/Trees ---- -

XUL提一种供用树的形式而创建表格或是分层结构的列表。

-

-

在XUL中树是个很复杂的元素。它用于有层次需求的结构来显示行列中的文本。树允许用户对某行进行排序、调整、隐藏等操作。比如火狐中的书签项和雷鸟邮箱结构都是用树做成的。

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/using_spacers/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/using_spacers/index.html deleted file mode 100644 index 7501f87216..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/using_spacers/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: XUL_教程/使用定位格 -slug: Mozilla/Tech/XUL/Tutorial/Using_Spacers -tags: - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/Using_Spacers ---- -

-

« 上一页下一页 »

-

-

 

-

添加定位格

-

开发用户界面的问题之一是每个用户都有不同的显示器。一些用户使用较高分辨率的较大显示器而另外一些用户使用的是较低分辨率的。另外,不同的平台对用户界面的也不同。如果加上多语言支持,每种语言之间用到的文字的需要的显示空间也不一样。

-

应用程序的窗口通常需要考虑支持多平台和多语言。某些平台和用户接口工具提供组件让用户可以轻易地去调整适合他们自己的大小和位置。(例如Java平台使用布局管理器。)

-

XUL为元素提供能力自动调整位置和大小。 就像我们看到的文件查找窗口的尺寸是刚好能将元素放在它里面。每次我们增中一些东西,窗口就会变得更大。

-

XUL使用一个叫做“箱状模型”(Box Model)的布局系统。我们将在下一节中讲到。它允许你将一个窗口划分成连续的盒子存放元素。盒子可以基于你定义的规格调整位置和大小。到现在,可以知道 window 元素是属于盒子的类型。

-

在了解什么是盒子之前,我们将引入其他用于布局的XUL元素,spacer。定位格很简单,它只需要一个属性,稍后将会说明。一个简单的定位格看起来就像下面:

-
<spacer flex="1"/>
-
-

spacer用于在窗口中放置一片空白。它多数用于用户调整窗口大小时它可以拉伸或者收缩。 这将决定是将按钮放置在一个窗口的左边或底边还是放在右边或底边 。将要看到,你可以使用一连串的空格去创建许多布局效果。

-

上面这个语法中,定位格有一个属性,叫做flex。这用于定义定位格的弹性。在上面的例子中,定位格为1的弹性。这会创建一个有弹力的定位格。如果你直接将它放在窗口里,这个定位格会在窗口的大小被改变时自动伸缩。

-

马上我们将会把一个定位格添加到我们的文件查找例子中。首先,让我们看一下当调整当前对话框时会发生什么。

-

Image:springs1.jpg

-

如果你改变文件查找窗口的尺寸,你会看到所有的元素都保持着它们原来的位置。它们中没有一个移动或调整了大小虽然窗口里有更多的空间。让我们再看一下当增加了一个定位格后在文本输入框和查找按钮之间发生了什么。

-

Image:springs2.jpg

-

在添加了定位格后再调整窗口的大小时,你可以看到定位格填充了空白。按钮被推到了最后面。

-
-
我们文件查找的例子
-

下面的代码增加一个定位格。把它插入到查找按钮的前面。

-
<spacer flex="1"/>
-
-<button id="find-button" label="Find"/>
-
-
-

关于弹性的更多信息

-

XUL在窗口中放置有弹性元素是通过计算元素合适的宽度和高度然后再添加空间。除非你指定元素的宽度和高度信息,元素的内容就决定了它的默认大小。你需要注意在对话框中的取消按钮总是设置了宽度因此它能在它里面放文字。如果你创建一个具有非常长的标签的按钮,按钮的默认大小将会很大使得有足够的空间可以放下标签。其它的元素,像是文本输入框会选择一个合适的默认大小。

-

flex属性用于指定元素可以改变自身的尺寸去填充它所在的盒子 (在这个例子中的窗口)。我们已经看到了应用于定位格的弹性属性,但它是可以应用于所有的元素的。例如,你可以改成能自动调整大小的查找按钮。

-

Image:springs3.jpg

-

如图所示,在查找按钮上增中了弹性属性,在窗口进行大小调整时它也会跟着调整。定位格实际上是没有指定任何东西。它实际上就是一个隐藏的按钮。它除了不会在屏幕上显示外大部分的使用方法就是和按钮一样的。

-

你可以从上面的图片得到更多的提示。不仅是在查找按钮的尺寸增大了,而且在主标签和按钮之间显示了更多的空间。当然,这是我们之前放进去的定位格。它也调整了自己的尺寸。如果你更深入地观察,你会注意到在定位格和按钮之间分到的尺寸改变值是相等的。定位格拿到了一半的空余空间,按钮拿到了另外一半。

-

我们看到这个效果是因为定位格和查找按钮都使用了 flex 属性。因为都是可伸缩的,按钮和定位格的尺寸调整是相等的。

-

如果你想设置一个元素是另一个的两倍大小要怎么做呢?你可以给flex属性设一个更高的值。弹性元素的值是一个概率。如果一个元素的弹性值为1而另一个的弹性值是2,第二个比第一个大多少倍。在效果上,一个弹性为2说的是这个元素有一个弹性是二次的元素弹性增长。

-

flex属性不能用来指定一个真实的尺寸。作为替换,它说明在一个盒容器的子容器中填入多少的空白空间。我们将在下节看到盒子。一旦子盒的默认尺寸被指定,弹性值就被用于在对盒子中剩余的空白空间进行分割。例如,如果一个盒子有200像素宽并且包括2个可伸缩的按钮,第一个是50像素和另外一个是90像素,在它们的外面将还会有60像素的空白空间。如果两个按钮都有弹性的值为1,空白空间将会被分配给每个按钮伸缩长度为30像素。如果第二个按钮的弹性增加到2,第一个按钮将得到20像素的扩展空间,而第二个按钮将得到40像素的扩展空间。

-

flex属性可以被放在任何元素,但是当它直接放在XUL元素里面时就只有一个意思。意思是说即使你可以把flex放在HTML元素中,如果元素不是一个非盒元素它就得不到效果。

-
弹性例子
-
例1:
-  <button label="Find" flex="1"/>
-  <button label="Cancel" flex="1"/>
-
-例2:
-  <button label="Find" flex="1"/>
-  <button label="Cancel" flex="10"/>
-
-例3:
-  <button label="Find" flex="2"/>
-  <button label="Replace"/>
-  <button label="Cancel" flex="4"/>
-
-例4:
-  <button label="Find" flex="2"/>
-  <button label="Replace" flex="2"/>
-  <button label="Cancel" flex="3"/>
-
-例5:
-  <html:div>
-    <button label="Find" flex="2"/>
-    <button label="Replace" flex="2"/>
-  </html:div>
-
-例6:
-  <button label="Find" flex="145"/>
-  <button label="Replace" flex="145"/>
-
-
-
- 例1 
-
- 在这个例子中两个按钮平均分配弹性值。两个按钮的将会被平均地改变大小。
-
- 例2 
-
- 这,两个按钮都是可伸缩的,但查找按钮的伸展率是取消按钮的十分之一,因为取消按钮的弹性值为10,可用的空间被分割成查找按钮的一份和取消按钮的十分。
-
- 例3 
-
- 这里只有其中的两个按钮设置为可弹性。替换按钮将不会改变它的尺寸而另外两个会。 取消按钮将会比查找按钮大一倍因为它的弹性值是查找按钮的弹性值的二倍。
-
- 例4 
-
- 在这个例子,三个按钮都具有可弹性。查找和替换按钮的尺寸将是相同的,但取消按钮会更大一些(多50%的扩展)。
-
- 例5 
-
- 这里,两个按钮都放在div元素里面。按钮不是放在盒子里所以可申缩性在这里是无意义的。效果和没有使用flex属性是相同的。
-
- 例6 
-
- 因为两个按钮的弹性值是一样的,他们将得到相同的弹性。这样还不如用1来代替145。在这个例子中没有什么不同。建议你使用可读性更好的低数值。
-
-

注意像按钮的标签和按钮的最小尺寸等其他的因素会影响到按钮的尺寸。事实上,按钮不会收缩到比它的标签还小。

-

将弹性值设为0与没有设置flex属性的效果是一样的。它的意思是元素不使用弹性。你有时可以看到弹性值会指定为一个百分率。这没有特殊的意义,这已经是处理过的就算没有百分号在那里。

-

你也许注意到在你垂直改变查找对话框的尺寸时,按钮也会调整它自己的尺寸去适应窗口的高度。这是因为所有在窗口中的按钮都有隐含的垂直弹性。在下一节我们将会学习如何去改变这个值。

-
-
到目前为止的文件查找例子
-

Source View

-
-

接下来,我们将要学习 按钮的更多特性

-

-

« 上一页下一页 »

-

-

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/using_xbl_from_stylesheets/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/using_xbl_from_stylesheets/index.html deleted file mode 100644 index 04c8ab7123..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/using_xbl_from_stylesheets/index.html +++ /dev/null @@ -1,223 +0,0 @@ ---- -title: 通过CSS和XBL创建可复用的内容 -slug: Mozilla/Tech/XUL/Tutorial/Using_XBL_from_stylesheets -translation_of: Archive/Beginner_tutorials/Using_XBL_from_stylesheets ---- -

- -

本页面介绍了如何在Mozilla中使用CSS来提升在复杂应用结构中的代码与资源的复用。

- -
-

提示:XBL不能通过HTTP来加载,所以XBL只能使用file:///scheme或者通过附加代码的方式进行本地访问。

-
- -

你可以应用这项技术于一个简单的示例。

- -

Information: XBL bindings

- -

由标记语言和CSS提供的这个结构并不适用于组件需要自包含和复用的复杂应用。你可以将样式表(stylesheet)和脚本(script)放置在独立的文件中。但是你必须将这些文件加载到文档(html)中,最后形成一个整体。

- -

另一个结构上的限制则与内容有关。你可以使用CSS为选中的元素提供内容,但是内容限定在文本和图片,并且内容的位置只能是选中的元素前或者后。

- -

Mozilla provides a mechanism that overcomes these limitations: XBL (XML Bindings Language). You can use XBL to link selected elements to their own:

- -

Mozilla提供了一个机制来克服上述限制:XBL(XML Bindings Language)。

- - - -

因此你可以避免在文档中链接每一个组件,你可以使用自包含的组件来方便维护和复用。

- - - - - - - - -
More details
For more information about XBL bindings, see the XBL page in this wiki.
- -

Action: An XBL demonstration

- -

创建一个新的html文档,doc6.html。将下面的内容拷贝到文件中:

- -
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<HTML>
-
-<HEAD>
-<TITLE>Mozilla CSS Getting Started - XBL demonstration</TITLE>
-<LINK rel="stylesheet" type="text/css" href="style6.css">
-</HEAD>
-
-<BODY>
-<H1>XBL demonstration</H1>
-<DIV id="square">Click Me</DIV>
-</BODY>
-
-</HTML>
-
-
- -

创建一个新的CSS文件,style6.css。这个样式表包含了文档的样式。将下面的内容拷贝到CSS文件中:

- -
-
/*** XBL demonstration ***/
-#square {
-  -moz-binding: url("square.xbl#square");
-  }
-
-
- -

Make a new text file, square.xbl. This file contains the XBL binding. Copy and paste the content from here:

- -

创建一个新的文本文件,square.xbl。这个文件包含了XBL的绑定关系。将下面的内容拷贝到文件中。

- -
-
<?xml version="1.0"?>
-<!DOCTYPE bindings>
-<bindings xmlns="http://www.mozilla.org/xbl"
-          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-          xmlns:html="http://www.w3.org/1999/xhtml">
-
-<binding id="square">
-
-  <resources>
-    <stylesheet src="bind6.css"/>
-    </resources>
-
-  <content>
-    <html:div anonid="square"/>
-    <xul:button anonid="button" type="button">
-      <children/>
-      </xul:button>
-    </content>
-
-  <implementation>
-
-    <field name="square"><![CDATA[
-      document.getAnonymousElementByAttribute(this, "anonid", "square")
-      ]]></field>
-
-    <field name="button"><![CDATA[
-      document.getAnonymousElementByAttribute(this, "anonid", "button")
-      ]]></field>
-
-    <method name="doDemo">
-      <body><![CDATA[
-        this.square.style.backgroundColor = "#cf4"
-        this.square.style.marginLeft = "20em"
-        this.button.setAttribute("disabled", "true")
-        setTimeout(this.clearDemo, 2000, this)
-        ]]></body>
-      </method>
-
-    <method name="clearDemo">
-      <parameter name="me"/>
-      <body><![CDATA[
-        me.square.style.backgroundColor = "transparent"
-        me.square.style.marginLeft = "0"
-        me.button.removeAttribute("disabled")
-        ]]></body>
-      </method>
-
-    </implementation>
-
-  <handlers>
-    <handler event="click" button="0"><![CDATA[
-     if (event.originalTarget == this.button) this.doDemo()
-     ]]></handler>
-    </handlers>
-
-  </binding>
-
-</bindings>
-
-
- -

Make a new CSS file, bind6.css. This separate stylesheet contains style for the binding. Copy and paste the content from here:

- -

创建一个新的CSS文件,bind6.css。这个独立的样式表包含了

- -
-
/*** XBL demonstration ***/
-[anonid="square"] {
-  width: 20em;
-  height: 20em;
-  border: 2px inset gray;
-  }
-
-[anonid="button"] {
-  margin-top: 1em;
-  padding: .5em 2em;
-  }
-
-
- -

在你的浏览器中打开文档然后按下按钮。

- -

这个维基页面并不支持JavaScript,所以无法再这里展示示例。示例看上去就如下面所示,分别是按下按钮之前和之后的效果。

- - - - - - - - -
xbldemo0.pngxbldemo1.png
- -

关于这个示例的提示:

- - - -

挑战

- - - - - - - - -
 
Change the XBL file so that the square doubles in width when it changes color, instead of jumping to the right. -

Use the DOM Inspector tool to inspect the document, revealing the added content.

- -

 

-
- -

What next?

- -

If you had difficulty understanding this page, or if you have other comments about it, please contribute to its Discussion page.

- -

In this demonstration, the square and the button make a self-contained widget that functions within an HTML document. Mozilla has a specialized markup language for creating user interfaces. The next page demonstrates it: XUL user interfaces.

diff --git "a/files/zh-cn/mozilla/tech/xul/tutorial/xbl\344\273\213\347\273\215/index.html" "b/files/zh-cn/mozilla/tech/xul/tutorial/xbl\344\273\213\347\273\215/index.html" deleted file mode 100644 index 6b6ef8288e..0000000000 --- "a/files/zh-cn/mozilla/tech/xul/tutorial/xbl\344\273\213\347\273\215/index.html" +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: XUL 教程 -slug: Mozilla/Tech/XUL/Tutorial/XBL介绍 -tags: - - XBL -translation_of: Archive/Mozilla/XUL/Tutorial/Introduction_to_XBL ---- -

 

- -

-

« 上一页下一页 »

-

- -

 

- -

XUL有一个姐妹语言,XBL(可扩展绑定语言)。这种语言被用于声明 XUL 窗口控件的行为。

- -

Bindings

- -

你可以用 XUL 来为应用程序定义用户界面的外观。你可以通过 应用样式自定义元素的外观。你也可以通过改变样式以 创建新皮肤。所有元素的基础外观,比如 滚动条复选框,都可以通过调整样式或设置元素参数来进行修改。然而,XUL 没有提供改变元素的工作方式(或添加一个可重用的新元素)的方法。例如,您可能想改变滚动条的运行方式,就需要用到 XBL

- -

一个 XBL 文件包含一组绑定(binding)。每个绑定描述一个 XUL 控件的行为。例如,一个绑定可以和一个滚动条相关联。这个行为除却描述滚动条的属性于方法之外,还描述了组成滚动条的 XUL 元素。

- -

类似 XUL,XBL 是一种 XML 语言,所以它有与之相似的语法规范。下述例子展示了 XBL 文件的基础结构:

- -
<?xml version="1.0"?>
-<bindings xmlns="http://www.mozilla.org/xbl">
-  <binding id="binding1">
-    <!-- content, property, method and event descriptions go here -->
-  </binding>
-  <binding id="binding2">
-    <!-- content, property, method and event descriptions go here -->
-  </binding>
-</bindings>
-
- -

bindings 元素是 XBL 文件的根元素,包含了一个或多个 bindings 元素。每个 bindings 元素都声明一个单独的 binding,id 属性可以用来确定 binding,就像上述的例子一样。模板有两个 binding,分别叫做 binding1binding2。一个可与滚动条关联,另一个则与菜单关联。一个 binding 可以和任意 XUL 元素相关联。如果你使用 CSS 类,就能按需使用各种不同的 binding。注意上面模板中的 bindings 元素的命名空间。它声明了我们所使用的 XBL 语法。

- -

将绑定文件的链接正确设为 CSS 中 -moz-binding 的值,就可以把一个 binding 绑定到元素上。例如:

- -
scrollbar {
-    -moz-binding: url('chrome://findfile/content/findfile.xml#binding1');
-}
-
- -

URL 指向了 “chrome://findfile/content/findfile.xml” 文件中的 ID“binding1”。“#binding1”语法用于指向特定的 binding,很像指向 HTML 文件中的 anchor 标签的语法。通常你会(借助此语法)把所有的 binding 放进一个单独的文件里。例中结果是“binding1”将会描述所有的滚动条元素。如果您没用-moz-binding URL中的标签,就会用到XBL文件中的第一个binding。

- -

binding 声明了五种类型:

- -
    -
  1. 内容:添加到 binding 绑定到的元素的子元素
  2. -
  3. 属性:添加到 binding 绑定到的元素的属性。它们能通过脚本存取。
  4. -
  5. 方法:添加到 binding 绑定到的元素的方法。它们能从脚本调用。
  6. -
  7. 事件:元素将响应的例如鼠标单击和按键这类事件。 binding能添加脚本,来提供默认操作。另外,能够定义新事件。
  8. -
  9. 样式:被 XBL 定义的 binding 绑定到的元素所拥有的自定义样式的属性
  10. -
- -

Binding 示例

- -

box 很通用,您能用它来创建自定义的窗口控件(虽然您能用任何元素,甚至自己构造的)。给一个 box 标签分配一个 class 属性,您就可以将 binding 连接到只属于该类的 box。比如下面的例子:

- -

XUL (example.xul):

- -
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://example/skin/example.css" type="text/css"?>
-
-<window
-     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <box class="okcancelbuttons"/>
-</window>
- -

CSS (example.css):

- -
box.okcancelbuttons {
-    -moz-binding: url('chrome://example/skin/example.xml#okcancel');
-}
- -

XBL (example.xml):

- -
<?xml version="1.0"?>
-<bindings xmlns="http://www.mozilla.org/xbl"
-         xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <binding id="okcancel">
-    <content>
-      <xul:button label="OK"/>
-      <xul:button label="Cancel"/>
-    </content>
-  </binding>
-</bindings>
- -

这个例子创建了一个有单个 box 的窗口,这个 box 已经声明过含有一个 okcancelbuttons 类。与文件相关的样式表阐述了含类 okcancelbuttons 的box有在XBL文件中定义的特定的binding。除 box 之外,可用其它元素,甚至自定义的标签。

- -

部分 XBL 的细节将在下一章描述。不过呢,总结来说,它使得在box里自动增加了两个按钮。一个 OK 按钮,一个 Cancel 按钮。

- -

在下一节中,我们将看看该如何 使用 XBL 创建内容

- -

-

« 上一页下一页 »

-

- -

/*以下疑似是历史残余链接…*/

- -

 

diff --git "a/files/zh-cn/mozilla/tech/xul/tutorial/xpcom_\346\216\245\345\217\243/index.html" "b/files/zh-cn/mozilla/tech/xul/tutorial/xpcom_\346\216\245\345\217\243/index.html" deleted file mode 100644 index fb2dbb3699..0000000000 --- "a/files/zh-cn/mozilla/tech/xul/tutorial/xpcom_\346\216\245\345\217\243/index.html" +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: XPCOM 接口 -slug: Mozilla/Tech/XUL/Tutorial/XPCOM_接口 -translation_of: Archive/Mozilla/XUL/Tutorial/XPCOM_Interfaces ---- -

 

- -

-

« 上一页下一页 »

-

- -

    本章简单的看看 XPCOM (跨平台组件对象模型)——Mozilla 使用的对象系统。

- -

调用本地对象

- -

    通过XUL我们可以建立一个复杂的用户界面,我们可以通过脚本来修改界面及处理任务。然而有很多事件是不能有JavaScript直接完成的,比如,我们像创建一个邮件程序,我们需要写一个脚本来连接到服务器发送好接收邮件,而JavaScript没有这个能力。

- -

    处理这种事情的唯一手段就是用本地代码写一个获得邮件的模块,同时也需要一个用脚本调用本地对象的简单方法。 Mozilla 通过了这样的模型—— XPCOM (Cross-platform Component Object Model)。

- -
Mozilla 提供了不少XPCOM 组件及接口,并且大多数情况下,你不需要自己完成他们。通过学习本章,你可以在 XULPlanet XPCOM Reference 寻找合适的。
- -

关于XPCOM

- -

    Mozilla 是有一系列组件构成的。每一个组件都处理特定的任务。比如,有一个处理菜单,按钮及元素的组件。组件又建立在一系列定义(接口)上。

- -

    Mozilla 中的接口定义了在一个组件中需要实现的功能,组件是它的代码实现,每一个组件都要实现接口描述的功能。一个组件可以时多个接口,多个组件也可以实现同一个接口。

- -

    让我们来以‘文件’组件为例,需要创建一个描述‘文件’属性及功能的接口文件。文件需要有文件名、数据、大小等属性;删除、移动、复制等方法。

- -

    文件接口用字符文件描述而无需实现。实现的工作留给组件来完成,组件需要返回文件名、数据、大小的代码,以及复制、删除等代码。

- -

    我们不关心组件如何实现,只要它实现了接口。当然我们有不同的实现方法,并且对于不同的平台也会不同。然而,他们必须实现同样的接口,这样我们就可以利用从接口中得到的信息使用组件。

- -

    Mozilla中接口通常以'nsI'或 'mozI'开头,这样就很容易找出接口。比如 nsIAddressBook 用于地址表, nsISound 用于声音文件 , nsILocalFile 用于本地文件,Mozilla中的接口参见 Interfaces.

- -

    XPCOM 组件是一种本地实现,也就是说他们可以做 JavaScript 不能做的事情。我们可以调用接口定义的由组件属性的任意方法,比如,如果我们有一个组件,它实现了 nsISound 接口我们就可以用它来放声音。

- -

创建XPCOM 对象

- -

调用 XPCOM 组件分三步

- -
    -
  1. 获取组件
  2. -
  3. 获取组件实现的接口
  4. -
  5. 调用所需函数
  6. -
- -

    如果我们做了前两步,最后一步可以无限制的使用,例如,我们想要重命名文件,这个方法定义在nsILocalFile 接口中。第一步得到文件组件。第二步,我们获取它实现了的nsILocalFile 接口,最后,调用接口通过的方法。这个接口用于代表单个文件。

- -

    我们知道接口长椅 'nsI' 或 'mozI'开头。组件通常像使用URI一样来引用,Mozilla 储存了当前注册的组件列表。像插件一样,用户可以添加新的组件。

- -

    Mozilla 通过了一个文件组件,它实现了 nsILocalFile。可以通过'@mozilla.org/file/local;1'引用,这个字符串称作协议ID,语法如下:

- -
@<internetdomain>/module[/submodule[...]];<version>[?<name>=<value>[&<name>=<value>[...]]]
-
- -

    其他组件也按相似的方法引用。

- -

    组件的协议 ID 用于获取组件,可以用下面的脚本得到组件。

- -
var aFile = Components.classes["@mozilla.org/file/local;1"].createInstance();
-
- -

    一个文件组件返回并储存在变量 aFile 中,上例中的 Components 引用一个提供相关功能的全局对象。 这里,使用 classes 方法获得组件组,classes 方法返回可用组件的数组。得到不同的组件只需把双引号中的需要ID换成你需要的,最后用createInstance()方法创建实例。

- -

    你需要检查 createInstance() 的返回值以确保非空,如果为空则表示所需组件不存在。

- -

    当然,到此为止,我们只引用了文件组件本身,为了使用它的函数,我们需要得到它的接口,本例为 nsILocalFile。我们再加一行。

- -
var aFile = Components.classes["@mozilla.org/file/local;1"].createInstance();
-if (aFile) aFile.QueryInterface(Components.interfaces.nsILocalFile);
-
- -

     QueryInterface() 是一个所以组件都通过的函数来返回特定的接口。函数有一个参数,你想得到的接口Componentsinterfaces 方法包含一个可用接口的数组,这里把 nsILocalFile 作为参数传给 QueryInterface()。结果是aFile会引用它所实现了 nsILocalFile 接口的那部分。

- -

    上面的两行脚本可以用于获取任何组件及接口,只需更换组件名及接口名。下例,获得一个 sound 接口。

- -
var sound = Components.classes["@mozilla.org/sound;1"].createInstance();
-if (sound) sound.QueryInterface(Components.interfaces.nsISound);
-
- -

    XPCOM 接口可以继承其它的接口。这种接口拥有它自己的功能及它所继承的接口的功能所有的接口都继承自顶级接口nsISupports,它有一个函数由于支持JavaScript—— QueryInterface()。因为所以的组件都实现 nsISupports 接口所以QueryInterface()对每个组件都有效。

- -

    一些组件可能会实现相同的接口。他们可能是原件的子类但不是必须的。组件可能都会实现 nsILocalFile接口,另外一个组件可能会实现多个接口。因为这个原因我们在调用函数之前需要得到定义函数的接口。

- -

    这里有一个简写形式,不过一般的我们把它分成多行。

- -
var aLocalFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
-
- -

    这一行代码完成了上面两行所做的事。

- -

    如果你使用 QueryInterface() 引用一个本组件没有实现的接口,会抛出一个异常。如果不确定组件支持哪个接口请使用 instanceof 操作符检查。

- -
var aFile = Components.classes["@mozilla.org/file/local;1"].createInstance();
-if (aFile instanceof Components.interfaces.nsILocalFile){
-  // do something
-}
-
- -

    如果aFile实现nsILocalFile 接口 instanceof返回真,在块中就可以调用 QueryInterface()

- -

调用接口函数

- -

    现在你有了一个关联到 nsILocalFile 接口组件的一个引用,你就可以调用nsILocalFile通过的函数。下面列出了 nsILocalFile提供的属性及方法。

- -
-
initWithPath 
-
此方法用于初始化文件名及路径,第一个参数是文件路径如 '/usr/local/mozilla'.
-
leafName 
-
除去文件路径的文件名。
-
fileSize 
-
文件尺寸。
-
isDirectory() 
-
 nsILocalFile 代表目录返回真。
-
remove(recursive) 
-
删除一个文件。如果recursive 参数为true,一个目录及其中的所以文件包括子目录均被删除。
-
copyTo(directory,newname) 
-
把文件复制到新目录,并随意更改文件名。目录应保存在 nsILocalFile对象中。
-
moveTo(directory,newname) 
-
把文件移到新目录或重命名。 目录应保存在 nsILocalFile对象中。
-
- -

    为了删除文件,需要将其赋值给 nsILocalFile。我们可以使用initWithPath() 方法指明所需文件,然后调用 remove() 函数,它带一个参数;是否递归删除,如下例。

- -
var aFile = Components.classes["@mozilla.org/file/local;1"].createInstance();
-if (aFile instanceof Components.interfaces.nsILocalFile){
-  aFile.initWithPath("/mozilla/testfile.txt");
-  aFile.remove(false);
-}
-
- -

    以上代码会定位 /mozilla/testfile.txt 并删除它。试着把它与事件处理相连。你可以把文件名改为一个需要删除的文件并把它删除。

- -

    上面的函数中 copyTo() 及moveTo()可以用于复制及移动文件。注意他们移动的目标目录不是保存在字符串中而是nsILocalFile,也就是说你需要两个文件字节,下面是一个复制文件的例子。

- -
function copyFile(sourcefile,destdir)
-{
-  // get a component for the file to copy
-  var aFile = Components.classes["@mozilla.org/file/local;1"]
-    .createInstance(Components.interfaces.nsILocalFile);
-  if (!aFile) return false;
-
-  // get a component for the directory to copy to
-  var aDir = Components.classes["@mozilla.org/file/local;1"]
-    .createInstance(Components.interfaces.nsILocalFile);
-  if (!aDir) return false;
-
-  // next, assign URLs to the file components
-  aFile.initWithPath(sourcefile);
-  aDir.initWithPath(destdir);
-
-  // finally, copy the file, without renaming it
-  aFile.copyTo(aDir,null);
-}
-
-copyFile("/mozilla/testfile.txt","/etc");
-
- -

XPCOM 服务器

- -

    一些 XPCOM 组件是被称为服务器的特殊组件,你无需创建他们因为他们只能存在一个副本。服务器提供了类似于读取,设置全局数据或操作其他对象的方法。我们使用getService()代替 createInstance()方法来获取服务器组件,除此以外,服务器并没有与其他组件相异之处。

- -

    如Mozilla通过了一个书签服务器,它允许你向当前用户的书签列表中添加书签。如下例。

- -
var bmarks = Components.classes["@mozilla.org/browser/bookmarks-service;1"].getService();
-bmarks.QueryInterface(Components.interfaces.nsIBookmarksService);
-bmarks.addBookmarkImmediately("http://www.mozilla.org","Mozilla",0,null);
-
- -

    首先组件 "@mozilla.org/browser/bookmarks-service;1"被返回,并保存在变量 bmarks中,我们使用 QueryInterface() 得到 nsIBookmarksService 接口。这个接口通过的addBookmarkImmediately() 函数用于添加书签。函数的前两个参数是书签的 URL 和标题。第三个参数是书签类型通常是 0 ,最后一个参数是书签页的字符集,可为空。

- -

    下一章看看Mozilla为我们通过的接口。 interfaces provided with Mozilla that we can use.

- -

-

« 上一页下一页 »

-

- -

diff --git a/files/zh-cn/mozilla/tech/xul/tutorial/xul_structure/index.html b/files/zh-cn/mozilla/tech/xul/tutorial/xul_structure/index.html deleted file mode 100644 index 5983802be3..0000000000 --- a/files/zh-cn/mozilla/tech/xul/tutorial/xul_structure/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: XUL_教程/XUL的结构 -slug: Mozilla/Tech/XUL/Tutorial/XUL_Structure -tags: - - XUL_Tutorial -translation_of: Archive/Mozilla/XUL/Tutorial/XUL_Structure ---- -

-

下一页 »

-

-

 

-

XUL是怎么被处理的?

-

XUL与HTML的处理方式一样,先读出内容,然后解析为一棵对象树,再对每个对象作处理,使其显示出来。因为XUL是用来定义用户界面的,因此它与HTML用来做显示的功能一样。实际上,在Mozilla中,HTML和XUL,甚至SVG都是使用同样的底层代码来处理的。这样意味着一些CSS属性(注意是属性,不是CSS的全部)可以用在HTML和XUL。XUL同HTML一样可以从本地文件系统或web页面读取(不过这样多少有些功能上的限制)。另外就是打成一个包,可以让别人下载和安装。安装后的包就可以有一些更强的权限,象读文本文件,读用户参数和bookmark,以及访问其它系统特性。

-

包注册就是Firefox扩展的安装方式。包是由XUL、Javascript、CSS、HTML和图片等构成。文件名后缀为.xpi,它其实是一个zip格式的压缩包。象Firefox的扩展一般是通过overlay的方式,对Firefox进行扩展的,如增加菜单、工具条等。但这些功能的代码其实是与浏览器分离的,而且卸载也很容易(就象NewEdit中的插件一样)。

-

注册的包不一定要使用overlay的扩展方式(overlay是对已经存在的应用的扩展)。但这样,你就不能直接通过浏览器来使用这些功能。但你仍然可以使用称为chrome(增色) URL的方式来调用注册包。这种chrome URL的形式为"chrome://"。它用来指示安装的包和扩展。

-

通过chrome方式来访问可以获得比http方式更多的权限,而通过这种方式,你就可以做访问本地文件等操作。这一点非常重要,权限的区分是通过URL的类型来实现的。通过http方式访问HTML和XUL,没有这些特别的权限,而通过chrome方式访问,HTML和XUL都具有这样的权力。

-

Mozilla浏览器本身就是由许多的包构成的。而这些文件就是通过chrome URL来访问的,以获得特别的权限。

-

Mozilla中有三种主要的文档类型:HTML, XUL和XML。它们之间有些是可能共享的特性,有些是不能共享的,使用时要注意。

-

小结:

-

Mozilla使用同样的引擎来渲染HTML和XUL,使用CSS来指明它们的外观。 XUL可以从web站点、本地文件系统,或作为包被安装并通过chrome URL来访问(这就是浏览器扩展所做的方式)。 Chrome URL可以用来访问安装的包,并且使用特别的权限来打开它们。 HTML、XUL、XML有不同的文档类型。一些特性是互通的,然而另一些特性是各自的。

-

包的组织

-

由Mozilla提供的包可以在Mozilla的安装目录下的chrome子目录中找到。但仅仅把文件拷贝到chrome目录下是不会赋给它任何的权限,也不可以通过chrome URL来访问的,还需要配置才可以。需要按照chrome包格式的要求来组织才可以。

-

一个包的文件通常被组织为一个JAR文件。注意,很象Java中的Jar包,都是Zip格式的。但里面可不是Java程序。这也造成了某些人认为开发扩展需要懂Java,其实不是的。只是后缀与Java一样。(不清楚为什么用这个后缀)同时,也可以不打成一个JAR包,就是展开的目录也可以(如果你看到另一个教程XUL App Tutorial,你会看到就没有打成一个JAR包)。

-

通常一个chrome包有三个目录,但它们都是可选的,分别为:content、skin和locale。

- -

用户界面的定义都放在XUL文件中,这些文件都以.xul为后缀。一个content目录下可以有多个XUL文件,但主窗体文件名必须与包名相同。例如editor包必须有一个叫做editor.xul的文件。其它的脚本文件(一般是.js文件,Javascript)也放在这个目录下。

- -

样式表用来描述窗口显示的外观。它们与XUL分离,可以灵活地修改程序的外观。

- -

所有界面中用到的文本都放在这里。如果支持多国语言,它们将按语言种类进行组织。只要在这里进行翻译即可实现多语言。 同时在每个目录下还应该有一个名为:contents.rdf的文件,它用来描述相关目录的信息清单。Mozilla将读取它,并使用它的内容来注册包,并给这个包分配一个chrome URL,这样这些文件就可以通过这个chrome URL来访问了。如果没有contents.rdf文件,这个包就不能被分配一个chrome URL,因此也就不能通过chrome来访问了。同时要注意,只有你需要通过chrome URL来访问的目录才需要contents.rdf文件,不需要访问的目录可能不要。再有,如果一个目录下还有子目录,但子目录通过与父目录相同的chrome URL来访问,子目录也可以不要contents.rdf文件。

-

在locale目录中,语言化文件有两种形式:DTD和属性(properties)文件。DTD(Document Type Definition,文档类型定义)是XML中常用的文件,它一般是用来定义XML中的元素规则,还可以用来定义XML中出现的实体(entity)元素。XUL要使用DTD中的实体声明,用来显示文本信息。因此如果想实现多语言,就要按语种创建子目录,生成多个DTD文件。属性文件是给脚本使用的。

-

Mozilla中的包通常是放在chrome目录下,但是你也可以不放在这个目录下,而是放在磁盘任意的地方。在chrome目录下的chrome.rdf文件保存了安装了的包、skin、locale的列表及它们的位置。放在chrome下是最常见的。对于存在多种skin和locale的情况,chrome.rdf中保存了激活的配置。

-

 

-

-

下一页 »

-

-

diff --git "a/files/zh-cn/mozilla/tech/xul/tutorial/\346\233\264\345\244\232\347\232\204\346\214\211\351\222\256\347\211\271\346\200\247/index.html" "b/files/zh-cn/mozilla/tech/xul/tutorial/\346\233\264\345\244\232\347\232\204\346\214\211\351\222\256\347\211\271\346\200\247/index.html" deleted file mode 100644 index 4a72667660..0000000000 --- "a/files/zh-cn/mozilla/tech/xul/tutorial/\346\233\264\345\244\232\347\232\204\346\214\211\351\222\256\347\211\271\346\200\247/index.html" +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: XUL_教程/更多的按钮特性 -slug: Mozilla/Tech/XUL/Tutorial/更多的按钮特性 -tags: - - XUL_教程 -translation_of: Archive/Mozilla/XUL/Tutorial/More_Button_Features ---- -

-

« 上一页下一页 »

-

-

 

-

添加图像

-

你可以使用image属性通过指定URL为按钮添加一个图像。图像从URL进行加载,可以是一个相对或绝对的URL路径,然后在按钮上显示图像。 下面的按钮有labelimage 'happy.png'。图像显示在标签的左边。你可以使用其它两个属性去改变这个位置。这将会在后面进行解释。

-

例1 : Source View

-
<button label="help" image="happy.png"/>
-
-

使用CSS图像的按钮

-

在按钮上指定图像的另一个方法是使用样式表(CSS list-style-image )属性。这将计划允许不改变XUL文件去改变"外观"(在这个例子,外观指按钮的图片)。

-

例2 : Source View

-
<button id="find-button"
-  label="Find" style="list-style-image: url('happy.png')"/>
-
-

在这个例子,在按钮上显示图像 'happy.png'。 style属性的功能类似于在HTML中一样。通常,它可以使用在所有的XUL元素。注意你确实应该在一个分离的样式表里定义样式。

-

图像定位

-

默认情况下,按钮上的图像会放置在文本标签的左边。有两个属性可以用来控制定位。

-

dir属性控制图像和文本的方向。设置这个属性的值为reverse,图像将会放在文本的右边。使用normal值,或者删除这个属性,图像将会放在文本的左边。

-

orient属性用于在将图片放在文本的上面或下面。默认值是horizontal用于将用于将图像放在文本的左或右。你也可以使用值vertical将图像放在上方或下方。在这个例子,dir属性控制放置在上方或下方。相同的值被使用时,如果用在normal的意思是将图像放在文本的上方,而用在reverse的意思是将图像放在文本的下方。

-

例3 : Source View

-
- Image:advbtns1.png
-
<button label="Left" image="happy.png"/>
-<button label="Right" image="happy.png" dir="reverse"/>
-<button label="Above" image="happy.png" orient="vertical"/>
-<button label="Below" image="happy.png" orient="vertical" dir="reverse"/>
-
-


- 这个例子展示了四个连续的不同类型的按钮。注意两个属性都没有指定说明使用的是默认值。

-

特殊内容按钮

-

按钮可以在内部包含任意的标记元素,这些元素将会被渲染在按钮内部。你或许不会经常使用这个,但你可以在创建自定义元素时使用它。

-

例如,下面将创建一个有两个红字的按钮:

-

例4 : Source View

-
<button>
-  <description value="This is a"/>
-  <description value="rather strange" style="color: red;"/>
-  <description value="button"/>
-</button>
-
-

任何XUL元素都可以放在button里面。HTML元素将被忽略,因此你需要使用description元素来包装它来达到换行的目的。如果你在按钮上指定label属性,它将会覆盖按钮内的所有内容。

-

弹出菜单按钮

-

你可以在按钮里面放置一个menupopup去促使在按钮被按下时向下弹出一个菜单,就像使用 menulist。然而,在这个例子你必须设置type 属性的值为menu

-

例5 : Source View

-
- Image:advbtns2.png
-
<button type="menu" label="Device">
-  <menupopup>
-    <menuitem label="Printer"/>
-    <menuitem label="Mouse"/>
-    <menuitem label="Keyboard"/>
-  </menupopup>
-</button>
-
-

在这个例子中,用户可以点击按钮去弹出一个包括三个项目的菜单。注意在选择这些菜单项之中的一个时不会改变按钮的标签,不像menulist那样。这种按钮类型是有意做成类似于菜单的,在每个项目上附上脚本去执行任务。我们将会在后面看到更多的菜单。

-

你也可以设置 type 属性的值为menu-button。这也可以创建一个像菜单的按钮,但显示会有所不同,右边的图像显示它们的区别。左边是一个'menu'而第二个是'menu-button'。 它有一个箭头标记菜单的存在。 在'menu'上,用户可以点击按钮的任何地方去显示菜单。在 'menu-button'上,用户点击箭头去显示菜单。

-

接下来,我们将要学习更多关于 在窗口中放置元素.

-

-

« 上一页下一页 »

-

-

diff --git a/files/zh-cn/mozilla/tech/xul/vbox/index.html b/files/zh-cn/mozilla/tech/xul/vbox/index.html deleted file mode 100644 index eb23c89d10..0000000000 --- a/files/zh-cn/mozilla/tech/xul/vbox/index.html +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: vbox -slug: Mozilla/Tech/XUL/vbox -tags: - - XUL Elements - - XUL Reference -translation_of: Archive/Mozilla/XUL/vbox ---- -
- « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
- -

A container element which can contain any number of child elements. This is equivalent to the box element, except it defaults to vertical orientation.
- 一个可以包含任何子元素的容器元素。这相当于默认为垂直方向的box 元素。

- -

More information is available in the XUL tutorial.
- 更多信息参考XUL tutorial

- -

Example

- -

示例

- -

vbox example

- -
<!-- Two labels at bottom -->
-<vbox>
-  <spacer flex="1"/>
-  <label value="One"/>
-  <label value="Two"/>
-</vbox>
-
- -

Attributes

- -

属性

- -

- - - - - -

Inherited from XUL element
-align, -allowevents, -allownegativeassertions, -class, -coalesceduplicatearcs, -collapsed, -container, -containment, -context, -contextmenu, -datasources, -dir, -empty, -equalsize, -flags, -flex, -height, -hidden, -id, -insertafter, -insertbefore, -left, -maxheight, -maxwidth, -menu, -minheight, -minwidth, -mousethrough, -observes, -ordinal, -orient, -pack, -persist, -popup, -position, -preference-editable, -querytype, -ref, -removeelement, -sortDirection, -sortResource, -sortResource2, -statustext, -style, -template, -tooltip, -tooltiptext, -top, -uri, -wait-cursor, -width

-

- -

Properties

- -

特性

- -

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

- -

Methods

- -

方法

- -

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- - - -

相关

- -
-
Elements
- 元素
-
box, hbox
-
- -

 

- -
 
- -

diff --git a/files/zh-cn/mozilla/tech/xul/window/index.html b/files/zh-cn/mozilla/tech/xul/window/index.html deleted file mode 100644 index f748259648..0000000000 --- a/files/zh-cn/mozilla/tech/xul/window/index.html +++ /dev/null @@ -1,281 +0,0 @@ ---- -title: window -slug: Mozilla/Tech/XUL/window -translation_of: Archive/Mozilla/XUL/window ---- -
- « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
- -

window标签用来描述一个窗口的顶级结构,在 XUL文档中,他是一个根节点。默认情况下,它里面的控件是水平排列的。作为一个box容器, box的属性都可以被使用. 默认的, 窗口将有一个特定于平台的框架围绕着他。

- -

如果需要给窗口添加一个图标,你需要首先创建一个 icon 文件,也就是例如 <windowid>.ico<windowid>.xpm ,然后将他们放置到 项目文件夹的/chrome/icons/default/ 目录下. 这里所说的的 <windowid> 是此窗口内window标签的id. 这样,您就能为每个窗口设置不同的图标了。

- -

如果没有将 "chrome://global/skin/"下的指定css文件引用进来, 此窗口将不能正常加载 ,有可能看不见 或者被打开的时候出现漏洞.

- -
-

注意: 通过Gecko 1.9.2标记, 当一个窗口通过查看动作引起的“激活”或“失活”事件被“激活”或“失活”时,你可以侦测到。这方面的信息,请查看  窗口激活事件.

-
- -

更多的信息请查看 XUL tutorial.

- -
-
标记属性
-
accelerated, chromemargin, disablechrome, disablefastfind, drawintitlebar, fullscreenbutton, height, hidechrome, id, lightweightthemes, lightweightthemesfooter, screenX, screenY, sizemode, title, width, windowtype
-
- -

实例

- -
<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<!-- Extremely recommended to keep this css include!! -->
-<window id="rootWnd" title="Register Online!"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <vbox>
-    <hbox>
-      <image src="application_form.png"/>
-      <description>Register Online!</description>
-    </hbox>
-    <groupbox align="start">
-      <caption label="Your Information"/>
-      <radiogroup>
-        <vbox>
-          <hbox>
-            <label control="your-fname" value="Enter first name:"/>
-            <textbox id="your-fname" value="Johan"/>
-          </hbox>
-          <hbox>
-            <label control="your-lname" value="Enter last name:"/>
-            <textbox id="your-lname" value="Hernandez"/>
-          </hbox>
-          <hbox>
-            <button oncommand="alert('save!')">
-              <description>Save</description>
-            </button>
-          </hbox>
-        </vbox>
-      </radiogroup>
-    </groupbox>
-  </vbox>
-</window>
-
- -

标记属性

- -

-
accelerated
Type: boolean
Set this attribute to true to allow hardware layer managers to accelerate the window.
-
- -
-
- activetitlebarcolor
-
- Type: color string
-
- Specify background color of the window's titlebar when it is active (foreground). Moreover this hides separator between titlebar and window contents. This only affects Mac OS X.
-
- -

 

-
- -
chromemargin
Type: margin string
Controls the amount of chrome that should be visible on each side of the window. The specified string should contain four numbers, separated by commas, indicating the margin in pixels for the top, right, bottom, and left edges of the window, respectively. This value may be -1 to use the default margin for that side on the current platform, 0 to have no system border (that is, to extend the client area to the edge of the window), or a value greater than zero to indicate how much less than the default default width you wish the margin on that side to be. If this value turns out to be less than 0, 0 is used.
-
-
- -
disablechrome
Type: boolean
Set this attribute to true to disable chrome in the window. This is used to hide chrome when showing in-browser UI such as the about:addons page, and causes the toolbars to be hidden, with only the tab strip (and, if currently displayed, the add-on bar) left showing.
Note: This has no effect if the tabs on top preference is turned off.
-
-
-
disablefastfind
Type: boolean
Put disablefastfind="true" on the root element of a XUL document, which is intended to be loaded in a tab, to disable the find bar for the tab with this document. This is used to prevent the find bar from being displayed when it's not supported by the content (such as in the Add-ons manager tab).
-
- -
drawintitlebar
Type: boolean
If this attribute is true, the top of the window's content area will begin at the top edge of the title bar, instead of below the title bar. This allows the window to draw in the title bar. This is supported only from window elements, and is ignored on platforms that don't support drawing into the title bar.
-
-
- -
fullscreenbutton
Type: boolean
Set this attribute to true to display a button in the window chrome to allow the user to switch the window into full screen mode. Supported on Mac OS X 10.7 Lion and later and on Windows. The window receives a "fullscreen" event once the change has been made.
-
-
- - -
-
height
-
Type: string (representing an integer)
-
The preferred height of the element in pixels. The actual displayed height may be different if the element or its contents have a minimum or maximum height. The CSS height property may also be used.
-
-
- - -
-
hidechrome
-
Type: boolean
-
Set this attribute to true to have the chrome including the titlebar hidden.
-
-
- -
-
- id
-
- 类型: 元素的ID,在主窗口中必须唯一
-
- 一个唯一的标识一边开发者能够定义. 你可以使用方法 getElementById() 或者其他 DOM 的函数并在样式表中添加对元素的引用。
-
- -

-
- - -
-
inactivetitlebarcolor
-
Type: color string
-
Specify background color of the window's titlebar when it is inactive (background). Moreover this hides separator between titlebar and window contents. This affects only on Mac OS X.
-
-
- -
lightweightthemes
Type: boolean
true if the window supports lightweight themes, otherwise false.
-
-
- -
lightweightthemesfooter
Type: id
Specifies the ID of an element to which a lightweight theme's footer image will be applied.
-
-
- - -
-
screenX
-
Type: integer
-
The horizontal position at which the window appears on the screen.
-
-
- - -
-
screenY
-
Type: integer
-
The vertical position at which the window appears on the screen.
-
-
- - -
-
sizemode
-
Type: one of the values below
-
The state of the window. It can have one of the following values:
-
-
-
maximized
-
The window is maximized, and occupies the full size of the screen.
-
normal
-
The window appears in a normal state at the desired size.
-
-
-
- -

This attribute is used to save and restore the state of a window (together with the persist attribute) and for CSS styles (e.g. to hide the resizer grippy on maximized windows).

- -
Note: When a window is minimized, the sizemode attribute is not updated. This is done so that if a window is closed while minimized, its persisted sizemode attribute wouldn't be minimized.
- -

Setting this attribute does not change the window state. Use window.maximize(), window.restore(), or window.minimize() to change the window state.

- -

To get the window state from JavaScript code, use window.windowState. Listen to the sizemodechange event dispatched to the DOM window to get notified when the window state changes.

- - -
- - -
-
title
-
Type: string
-
The text to appear in the title bar of the window.
-
-
- - -
-
width
-
Type: string (representing an integer)
-
The preferred width of the element. The value should not include a unit as all values are in pixels. The actual displayed width may be different if the element or its contents have a minimum or maximum width, or the size is adjusted by the flexibility or alignment of its parent. The CSS width property may also be used.
-
- - -
- -
-
- windowtype
-
- Type: string
-
- Set to a string which can be used to identify the type of window. This might be used, for example, to distinguish between a browser window and an editor window. Some of Mozilla's window handling functions use this attribute to group windows of the same type together.
-
-
-

Values for window type as found on MXR: http://mxr.mozilla.org/mozilla-release/search?string=windowtype

-

navigator:browser - Looks like if window has gBrowser it has this window type

-

devtools:scratchpad - Scratchpad windows

-

navigator:view-source - The view source windows

-
- -

 

-

- -

属性

- -

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

- -

方法

- -

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -

另请参阅: DOM window object methods 

- -

请注意

- -

DTD文件如果丢失或者不可访问,而XUL文件中却引用了其中的内容,将会引起 "XML Parsing Error: undefined entity...<window" 的错误。DOCTYPE声明中系统关键字后如果含有文件名,将会引起没有提示的加载失败, 而唯一的错误提示将会是在下一个XUL元素加载时出现未定义实体的错误。

- - - -
-
prefwindow, dialog, dialogheader
-
- -

相关的话题

- -
-
- -

用户注意事项

- -

如果要更改窗口标题栏中的图标, 请参考这里: Window icons.

- -

如果要将小图标添加到地址栏和浏览器选项卡(即对话框不是弹出),请使用下面的代码片段来使用html名称空间和链接。

- -
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-	xmlns:html="http://www.w3.org/1999/xhtml">
-
-<!-- Icon from chrome -->
-<html:link rel="icon" href="chrome://myExtension/content/path/to/favicon.png"/>
-
-<!-- From a remote site -->
-<html:link rel="icon" href="http://www.mozilla.org/favicon.ico"/>
-
- -

由于Firefox3.6之前的代码不能正常工作 ——会出现以下提示: "Warning: XUL box for box element contained an inline link child, forcing all its children to be wrapped in a block". 如果这段代码放在window标签之间, 它将会使窗口内的所有其他控件都变得乱七八糟.而如果放在 box 标签之间, 窗口控件呈现反而很不错, 但是依然会引起错误。 这一问题可以如下解决:

- -
<html:link rel="icon" href="chrome://myExtension/content/path/to/favicon.png" style="display:none"/>
-
- -

or

- -
<html:head>
-  <html:link rel="icon" href="chrome://myExtension/content/path/to/favicon.png"/>
-</html:head>
-
- -

diff --git a/files/zh-cn/mozilla/tech/xul/xul_reference/index.html b/files/zh-cn/mozilla/tech/xul/xul_reference/index.html deleted file mode 100644 index 829a2a260e..0000000000 --- a/files/zh-cn/mozilla/tech/xul/xul_reference/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: XUL Reference -slug: Mozilla/Tech/XUL/XUL_Reference -tags: - - XUL - - XUL Reference -translation_of: Archive/Mozilla/XUL/XUL_Reference ---- -

« XUL Reference «

- -
全部 XUL 元素 (按英文字母顺序排列)

action
arrowscrollbox
assign
bbox
binding
bindings
box
broadcaster
broadcasterset
button
browser
checkbox
caption
colorpicker
column
columns
commandset
command
conditions
content
datepicker
deck
description
dialog
dialogheader
dropmarker
editor
grid
grippy
groupbox
hbox
iframe
image
key
keyset
label
listbox
listcell
listcol
listcols
listhead
listheader
listitem

member
menu
menubar
menuitem
menulist
menupopup
menuseparator
notification
notificationbox
observes
overlay
page
panel
param
popupset
preference
preferences
prefpane
prefwindow
progressmeter
query
queryset
radio
radiogroup
resizer
richlistbox
richlistitem
row
rows
rule
scale
script
scrollbar
scrollbox
scrollcorner
separator
spacer
spinbuttons
splitter
stack
statusbar

statusbarpanel
stringbundle
stringbundleset
tab
tabbrowser (Firefox 3/Gecko 1.9 开始只用于Firefox本身)
tabbox
tabpanel
tabpanels
tabs
template
textnode
textbox
textbox (Firefox autocomplete)
textbox (Mozilla autocomplete)
timepicker
titlebar
toolbar
toolbarbutton
toolbargrippy
toolbaritem
toolbarpalette
toolbarseparator
toolbarset
toolbarspacer
toolbarspring
toolbox
tooltip
tree
treecell
treechildren
treecol
treecols
treeitem
treerow
treeseparator
triple
vbox
where
window
wizard
wizardpage

-

XUL 参考

-

« XUL Reference «

- -
XUL 要素 (按类别排序)

WINDOWS

dialog
overlay
page
window
wizard
wizardpage
preference
preferences
prefpane
prefwindow

WINDOW STRUCTURE

browser
tabbrowser
editor
iframe
titlebar
resizer
statusbar
statusbarpanel
dialogheader
notification
notificationbox

MENUS AND POPUPS

menubar
menu
menuitem
menuseparator
menupopup
panel
tooltip
popupset

TOOLBARS

toolbar
toolbarbutton
toolbargrippy
toolbaritem
toolbarpalette
toolbarseparator
toolbarset
toolbarspacer
toolbarspring
toolbox

TABS AND GROUPING

tabbox
tabs
tab
tabpanels
tabpanel
groupbox
caption
separator
spacer

CONTROLS

button
checkbox
colorpicker
datepicker
menulist
progressmeter
radio
radiogroup
scale
splitter
textbox
textbox (Firefox autocomplete)
textbox (Mozilla autocomplete)
timepicker

TEXT AND IMAGES

description
label
image

LISTS

listbox
listitem
listcell
listcol
listcols
listhead
listheader
richlistbox
richlistitem

TREES

tree
treecell
treechildren
treecol
treecols
treeitem
treerow
treeseparator

 

LAYOUT

box
hbox
vbox
bbox
deck
stack
grid
columns
column
rows
row
scrollbox

TEMPLATES

action
assign
binding
bindings
conditions
content
member
param
query
queryset
rule
template
textnode
triple
where

SCRIPTING

script
commandset
command
broadcaster
broadcasterset
observes
key
keyset
stringbundle
stringbundleset

HELPER ELEMENTS

arrowscrollbox
dropmarker
grippy
scrollbar
scrollcorner
spinbuttons

-

更多XUL相关列表

- -

-
diff --git a/files/zh-cn/mozilla/thunderbird/index.html b/files/zh-cn/mozilla/thunderbird/index.html deleted file mode 100644 index 58129cc9e5..0000000000 --- a/files/zh-cn/mozilla/thunderbird/index.html +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Thunderbird -slug: Mozilla/Thunderbird -translation_of: Mozilla/Thunderbird ---- -

Thunderbird 是Mozilla的电子邮件/消息应用程序。These pages document Thunderbird and also provide links to documentation about the MailNews backend which is also used in other projects such as Eudora/Penelope, Seamonkey, Correo, etc.

-

Thunderbird is Firefox's kid sibling, and is built on the same technical platform as the web browser. In development for many years, and currently one of the most popular open source email clients, it is used by millions of people around the world to bring together all their email accounts, newsgroup and feed reading in a familiar high-productivity environment.  (From early 2007 to early 2011 Thunderbird was developed by Mozilla Messaging, a subsidiary that was owned by Mozilla.)

- - - - - - - -
-

文档

-
-
- Building Thunderbird
-
- Information about building Thunderbird with the comm-central repository. There's also information about how comm-central works, how the review process works and how to use the Mozilla symbol server to help with debugging.
-
- MailNews Protocols
-
- Rough documentation about mail protocols..
-
- Database views
-
- Backend information about {{ Interface("nsIMsgDBView") }} and related interfaces..
-
- Thunderbird API documentation
-
- Thunderbird API documentation
-
- Extension documentation
-
- Tutorials and tips for building Thunderbird extensions
-
- Automated Testing
-
- Details of Thunderbird's automated testing facilities
-
- Thunderbird in the Enterprise
-
- Help with deploying Thunderbird in large organizations
-
-

View All...

-
-

社区

- -

工具

- - - -
-

 

diff --git a/files/zh-cn/mozilla/thunderbird/mail_client_architecture_overview/index.html b/files/zh-cn/mozilla/thunderbird/mail_client_architecture_overview/index.html deleted file mode 100644 index b289702d64..0000000000 --- a/files/zh-cn/mozilla/thunderbird/mail_client_architecture_overview/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: Mail client architecture overview -slug: Mozilla/Thunderbird/Mail_client_architecture_overview -translation_of: Mozilla/Thunderbird/Mail_client_architecture_overview ---- -

{{ outdated("It was imported from mozilla.org and last updated in 2002. All of the links seem to be broken.") }}

- -

The mail reader

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
Gecko (XUL and HTML rendering)
-
-
RDF(dynamic widgets)
-
-
JS(menus, events)
-
-
libmime
-
-
Mail Datasources
-
-
Mail JavaScript
-
-
Folder/Message management
-
msgdb -
 
-
-
IMAP/NNTP/POP3
-
-
Necko(networking)
-
- -

 灰色 带黑框的表示mail/news之外的模块。

- -

 

- -

The base Module

- -

 

- -

基础模块提供了一个协议无关的消息服务接口。包括帐户、文件夹和消息管理。

- -

The base module consists of the following basic building blocks

- - - -

There are also a number of protocol independant subsystems that have a symbiotic relationship with base:

- - - -

Finally, there are larger modules outside of the mail client that are mail-oriented. Most of these modules have little dependancy on the mail reader itself:

- - diff --git a/files/zh-cn/mozilla/thunderbird/mailnews_protocols/index.html b/files/zh-cn/mozilla/thunderbird/mailnews_protocols/index.html deleted file mode 100644 index b6b0c4873f..0000000000 --- a/files/zh-cn/mozilla/thunderbird/mailnews_protocols/index.html +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: MailNews Protocols -slug: Mozilla/Thunderbird/MailNews_protocols -translation_of: Mozilla/Thunderbird/MailNews_protocols ---- - - -

除了RSS,这些协议以C++实现。 RSS以JS 实现,而且实现模式和其他以C++实现的协议不同。

- -

IMAP、POP3和NNTP 是 "incoming" 协议,即从服务器获取消息, 并以文件夹的形式展现给用户。这些协议在mailnews相应的协议子目录中定义(即 mailnews/imap, mailnews/local (for pop3), mailnews/news),均有如下的类组成:

- -

An incoming server class, which implements nsIMsgIncomingServer and inherits from mailnews/base/util/nsMsgIncomingServer, i.e.., nsPop3IncomingServer, nsImapIncomingServer, nsNNTPIncomingServer.

- -

A folder class, which implements nsIMsgFolder, and inherits from nsMsgDBFolder. Most commands/operations go through the folder object. nsImapMailFolder, nsNewsFolder, nsLocalMailFolder (for POP3)

- -

A service class, which generally sits between the folder object or the server object, and the protocol object. The service class creates and initializes the url object for the operation, and hands that off to a protocol object to run. The service classes usually have their own interface, but they also implement nsIMsgMessageService.

- -

A url object. These implement nsIMsgMailNewsUrl, inherit from base/util/nsMsgMailNewsUrl, and implement their own protocol-specific interface (nsIImapUrl, nsINntpUrl, nsIPop3Url).

- -

A protocol object that takes a url and handles the network communications with the actual server required to run that url. These implement nsIMsgProtocol, inherit from nsMsgProtocol, and implement their own protocol-specific interface (nsIImapProtocol, nsIPop3Protocol, nsINntpProtocol)

- -

In addition, in mailnews/db/msgdb/public, we have protocol-specific msg db classes (and in the case of news, a nsINewsDatabase interface), so that we can use polymorphism when msg db operations need to be specialized for different kinds of folders.

- -

The message search code also has protocol-specific code to handle searching on the server, or local mailbox. The search code also knows what the different search capabilities of the various protocols are.

diff --git a/files/zh-cn/mozilla/toolkit_version_format/index.html b/files/zh-cn/mozilla/toolkit_version_format/index.html deleted file mode 100644 index ce6e5b2399..0000000000 --- a/files/zh-cn/mozilla/toolkit_version_format/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: 版本格式说明 -slug: Mozilla/Toolkit_version_format -tags: - - Toolkit API -translation_of: Mozilla/Toolkit_version_format ---- -

本文档是 Firefox 1.5(XULRunner 1.8)及更高版本中使用的版本格式的参考。此格式由扩展管理器,软件更新和平台其他部分的使用。至少以下位置的版本必须符合以下格式:

- - - -

您可以使用 {{ interface("nsIVersionComparator") }} 来比较应用程序的版本。

- -

有关 Firefox / Thunderbird 1.0 中使用的旧版本格式的说明,请参阅 {{ Anch("Older version formats") }}.

- -

版本格式

- -

版本字符串由一个或多个版本部分组成,用点分隔。

- -

每个版本的一部分本身解析为四个部分组成一个序列:<number-a><string-b><number-c><string-d>. 每个部分都是可选的。数字是 10 进制的整数(可以是负数),字符串是非数字的ASCII字符。

- -

有效版本部分的几个例子:

- - - -

应用一些特殊的解析规则来实现向后兼容性和可读性:

- - - -

当比较版本时,将版本分解为字符串部分和数字部分对应起来一一比较, 例如 '1.0pre1' < '1.0pre10'。有关如何比较版本的详细信息,请参阅下一节。

- -

比较版本

- -

当比较两个版本字符串时,它们的版本部分将从左到右进行比较。空的或缺少的版本部分等于 0 。

- -

当一个版本字符串的版本部分大于另一个版本字符串的相应版本部分时,第一个版本字符串大于另一个版本字符串。

- -

否则,版本字符串相等。请注意,由于缺少的版本部分被视为 0,所以以下版本字符串相等: 1, 1.0, 1.0., 1.0.0, 还有 1.0...

- -

比较版本部分

- -

版本部分也从左到右进行比较,将 <number-a> 和 <number-c> 作为数字进行比较,而 <string-b> 和 <string-b> 按字节比较。 存在的字符串部分始终小于不存在的字符串部分(如 1.6a 小于1.6)。

- -

一些例子

- -
1.-1
-< 1 == 1. == 1.0 == 1.0.0
-< 1.1a < 1.1aa < 1.1ab < 1.1b < 1.1c
-< 1.1whatever
-< 1.1pre == 1.1pre0 == 1.0+
-< 1.1pre1a < 1.1pre1aa < 1.1pre1b < 1.1pre1
-< 1.1pre2
-< 1.1pre10
-< 1.1.-1
-< 1.1 == 1.1.0 == 1.1.00
-< 1.10
-< 1.* < 1.*.1
-< 2.0
-
- -

技术参考

- -

如果你有兴趣看 toolkit 版本比较的实现, 请参考 nsVersionComparator.cpp.

- -

旧版本的格式

- -

Firefox 和 Thunderbird 1.0 使用简单的版本格式,即

- -
major[.minor[.release[.build]]][+]
-
- -

其中 {{ mediawiki.external('..') }} 表示可选部分, majorminorrelease 和 build 都是非负整数。

diff --git a/files/zh-cn/mozilla/webidl_bindings/index.html b/files/zh-cn/mozilla/webidl_bindings/index.html deleted file mode 100644 index 27b670ceea..0000000000 --- a/files/zh-cn/mozilla/webidl_bindings/index.html +++ /dev/null @@ -1,920 +0,0 @@ ---- -title: WebIDL绑定 -slug: Mozilla/WebIDL_bindings -translation_of: Mozilla/WebIDL_bindings ---- -
-

注意:需要记录索引和命名的setter / creator / deleter的设置。

-
- -

在构建时生成 WebIDL binding 需要两个东西:一个实实在在的WebIDL文件,以及另一个描述了 WebIDL 如何映射为 Gecko 内部代码的元数据配置文件。

- -

所有的 WebIDL文件应该放置在 dom/webidl 中并将文件名添加到该目录下的 moz.build 文件的列表中。

- -

注意如果你添加了新的接口,关于 dom/tests/mochitest/general/test_interfaces.html 很可能会失效。这就表示你需要让你的 DOM peer review 一下。不要急于在没有 review 的情况下将你的接口添加到moz.build 列表中;这样只会惹恼你的 DOM peers,最后无论如何你的改动都得被重新review。

- -

dom/bindings/Bindings.conf配置文件是一个简单的Python dict(字典)类型数据。它会将接口名称与接口信息相映射,这被称为descriptor(python描述符)。会有各种可能的方式来处理每种边缘情况,然而大多数描述符通常都非常简单。

- -

所有生成的代码都放置在 mozilla::dom namespace 中。对于每个接口,将创建一个名称以Binding为后缀的namespace ,与该接口的 binding 相关的所有内容都放在该namespace中。

- -

有许多放在 dom/bindings 目录中的助手对象和工具方法同样也在 mozilla::dom 命名空间中,其头文件也被导出到了 mozilla/dom 中(在编译时会放到 $OBJDIR/dist/include 目录).。

- -

向一个类添加 WebIDL 绑定

- -

要将MyInterface 接口的WebIDL binding 添加到应该实现该接口的类 mozilla::dom::MyInterface中,你需要执行以下操作:

- -
    -
  1. 如果你的接口没有继承自其他任何接口,你应当继承 nsWrapperCache,并把该类Hook到生命周期收集器(cycle collector),以便它可以正确地跟踪 wrapper 缓存。请注意,如果您的对象只能创建,而不能从其他对象获取,则可能不需要执行此操作。如果你也继承了 nsISupports接口,请确保 nsISupports 在父类列表中位于 nsWrapperCache 之前。如果您的接口 确实 继承了别的接口,则只需继承另一个接口对应的C++类型即可。
  2. -
- -

如果确实需要Hook 生命周期收集器(cycle collector),在同样也继承了nsISupports的常见情况下,它将如下所示:

- -
// Add strong pointers your class holds here. If you do, change to using
-// NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE.
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MyClass)
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MyClass)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MyClass)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MyClass)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
- -

       2. 如果你的类不是继承自实现了 GetParentObject接口的类,则添加一个同名函数。对于您的类的给定实例,该函数每次都返回相同的对象(除非您编写显式代码,通过重新设置JS wrapper来处理父对象的更改,就像节点所做的那样)。其思想是遍历 GetParentObject 链最终会将您得到 Window。这样,每个WebIDL对象都与一个特定的窗口相关联。

- -

例如,nsINode::GetParentObject  返回节点的所有者文档。GetParentObject的返回类型并不重要,只是它必须单独从nsISupports继承,或者具有可以从中生成nsISupports的相应ToSupports方法。(这允许编译器通过该类的一个非显式构造函数将返回值隐式转换为 ParentObject实例.)

- -

如果希望快速创建许多 MyInterface 实例,则 GetParentObject 的返回值本身应从nsWrapperCache 继承以获得最佳性能。在出于安全目的将结果对象与随机全局对象相关联的情况下,允许从GetParentObject返回null ;对于将其暴露于Web content,这通常是不合适的。同样,如果您不需要wrapper 缓存,则不需要执行此操作。从GetParentObject返回的实际类型必须在你实现的头文件中的头部 include 中导入,以便此类型的定义对绑定代码可见。

- -

      3. 在 dom/webidl目录下添加 MyInterface 的WebIDL 定义, 并将该文件添加到 dom/webidl/moz.build 的列表中.

- -

      4. 在dom/bindings/Bindings.conf中添加一个条目,用于设置有关接口实现的一些基本信息。如果C++类型不是 mozilla::dom::MyInterface,则需要将 'nativeType'设置为正确的类型。如果通过将“::”替换为“/”并附加“.h”路径 的该类型头文件中不存在,则将其相应的位置添加至相应的“headerFile”注释中 (或向.webidl文件添加 HeaderFile annotation 注释)。如果您不需要设置任何注释,那么您也不需要添加条目,代码生成器将简单地采用此处的默认值。请注意,通常不建议使用“headerFile”注释。如果您确实使用了它,您将需要确保您的头文件 include 了 Func 注释所需的所有头文件。

- -

    5. 将外部接口条目添加到Bindings.conf中,用于新接口的任何 作为 非webidl接口的参数或返回值。

- -

    6.  在mozilla::dom::MyInterface上实现WrapObject 重载,它只调用 mozilla::dom::MyInterface_Binding::Wrap。请注意,如果您的C++类型正在实现多个不同的Web IDL接口,则需要选择在此处调用哪个mozilla::dom::MyInterface_Binding::Wrap。例如,参见AudioContext::WrapObject

- -

    7.  在mozilla::dom::MyInterface上公开接口需要的任何方法。它们可以是inline、virtual、具有任何调用约定的,等等,只要它们具有正确的参数类型和返回类型。通过运行mach webidl-example MyInterface,您可以看到函数声明应该是什么样子的示例。这将在objdir中的 dom/bindings 中生成两个文件:MyInterface-example.hMyInterface-example.cpp,这两个文件显示了使用从nsISupports继承并具有包装器缓存的类的接口的基本实现。

- -

参见  sample patch that migrates window.performance.* to WebIDL bindings(这是一个往window添加接口的提交。译者注).

- -
注意: 如果您的对象只能通过创建来被JS调用,而不是通过从某个地方获取它,那么您可以跳过上面的步骤1和2,而且向您的descriptor中添加 'wrapperCache': False。您需要在WebIDL中将返回对象的函数标记为[NewObject] 。如果您的对象没有使用引用计数,则返回它的函数的返回值应返回 nsAutoPtr
- -

创建WebIDL 之  C++反射

- -

WebIDL操作之C++反射(方法)

- -

WebIDL操作被转换为对底层C++对象的方法调用。如何确定返回类型和参数类型的方法 如下所述。除此之外,所有 允许抛出的方法 都将获得一个附加到其参数列表中的 ErrorResult& 参数。使用特定WebIDL类型( 如 any 或者object )的非静态方法将获得参数列表之前的JSContext*参数。静态方法将被传递一个 const GlobalObject& 用作相关的全局变量,并且可以通过对其调用 Context()来获取JSContext* 。

- -

C++方法的名称只是WebIDL操作的名称,第一个字母转换为大写。

- -

WebIDL重载被转换为C++重载:它们只是调用具有相同名称和不同签名的C++方法。

- -

例如如下所示的 webidl:

- -
interface MyInterface
-{
-  void doSomething(long number);
-  double doSomething(MyInterface? otherInstance);
-
-  [Throws]
-  MyInterface doSomethingElse(optional long maybeNumber);
-  [Throws]
-  void doSomethingElse(MyInterface otherInstance);
-
-  void doTheOther(any something);
-
-  void doYetAnotherThing(optional boolean actuallyDoIt = false);
-
-  static void staticOperation(any arg);
-};
- -

会需要这些方法声明:

- -
class MyClass
-{
-  void DoSomething(int32_t aNumber);
-  double DoSomething(MyClass* aOtherInstance);
-
-  already_AddRefed<MyInterface> DoSomethingElse(Optional<int32_t> aMaybeNumber,
-                                                ErrorResult& rv);
-  void DoSomethingElse(MyClass& aOtherInstance, ErrorResult& rv);
-
-  void DoTheOther(JSContext* cx, JS::Value aSomething);
-
-  void DoYetAnotherThing(bool aActuallyDoIt);
-
-  static void StaticOperation(const GlobalObject& aGlobal, JS::Value aSomething);
-}
- -

WebIDL属性的C++反射

- -

WebIDL属性被转换为底层C++对象上getter和setter的一对方法调用。只读属性只有getter而没有setter。

- -

getter的名称是将第一个字母转换为大写的属性的名称。如果满足以下任一条件,则将Get 前置:

- -
    -
  1. 属性的类型可以为空。
  2. -
  3. getter 可以 throw。
  4. -
  5. 属性的返回值通过C++ 中的 out parameter 返回。
  6. -
- -

getter的方法签名看起来就像没有参数的操作,并且属性的类型作为返回类型。

- -

 setter 的名称是Set ,后跟属性的名称,第一个字母转换为大写。方法签名看起来就像一个具有void返回值和单个参数的操作,该参数的类型是属性的类型。

- -

WebIDL构造函数的 C++反射

- -

WebIDL构造函数被转换为名为Constructor的静态类方法。此方法的参数将是WebIDL构造函数的参数,带有 const GlobalObject& 用于相关的全局前缀。对于非Worker情况,全局通常是构造函数附加到的 DOM Window 的 内部 Window 。如果由于某些参数类型也需要JSContext*,则它将位于全局变量之后。MyInterface的构造函数的返回值与返回MyInterface实例的方法的返回值完全相同。始终允许构造函数 throw。

- -

如下 IDL所示:

- -
[Constructor,
- Constructor(unsigned long someNumber)]
-interface MyInterface
-{
-};
- -

需要在 MyClass中进行如下声明:

- -
class MyClass {
-  // Various nsISupports stuff or whatnot
-  static
-  already_AddRefed<MyClass> Constructor(const GlobalObject& aGlobal,
-                                        ErrorResult& rv);
-  static
-  already_AddRefed<MyClass> Constructor(const GlobalObject& aGlobal,
-                                        uint32_t aSomeNumber,
-                                        ErrorResult& rv);
-};
- -

C++ reflections of WebIDL types

- -

The exact C++ representation for WebIDL types can depend on the precise way that they're being used: e.g. return values, arguments, and sequence or dictionary members might all have different representations.

- -

Unless stated otherwise, a type only has one representation.  Also, unless stated otherwise, nullable types are represented by wrapping Nullable<> around the base type.

- -

In all cases, optional arguments which do not have a default value are represented by wrappingconst Optional<>& around the representation of the argument type.  If the argument type is a C++ reference, it will also become a NonNull<> around the actual type of the object in the process.  Optional arguments which do have a default value are just represented by the argument type itself, set to the default value if the argument was not in fact passed in.

- -

Variadic WebIDL arguments are treated as a const Sequence<>& around the actual argument type.

- -

any

- -

any is represented in three different ways, depending on use:

- - - -

Methods using any always get a JSContext* argument.

- -

For example, this WebIDL:

- -
interface Test { attribute any myAttr; any myMethod(any arg1, sequence<any> arg2, optional any arg3); };
- -

will correspond to these C++ function declarations:

- -
void MyAttr(JSContext* cx, JS::MutableHandle<JS::Value> retval);
-void SetMyAttr(JSContext* cx, JS::Handle<JS::Value> value);
-void MyMethod(JSContext* cx, JS::Handle<JS::Value> arg1,
-              const Sequence<JS::Value>& arg2,
-              const Optional<JS::Handle<JS::Value> >& arg3,
-              JS::MutableHandle<JS::Value> retval);
- -

boolean

- -

The boolean WebIDL type is represented as a C++ bool.

- -

For example, this WebIDL:

- -
interface Test { attribute boolean myAttr; boolean myMethod(optional boolean arg); };
- -

will correspond to these C++ function declarations:

- -
bool MyAttr();
-void SetMyAttr(bool value);
-JS::Value MyMethod(const Optional<bool>& arg);
- -

Integer types

- -

Integer WebIDL types are mapped to the corresponding C99 stdint types.

- -

For example, this WebIDL:

- -
interface Test { attribute short myAttr; long long myMethod(unsigned long? arg); };
- -

will correspond to these C++ function declarations:

- -
int16_t MyAttr();
-void SetMyAttr(int16_t value);
-int64_t MyMethod(const Nullable<uint32_t>& arg);
- -

Floating point types

- -

Floating point WebIDL types are mapped to the C++ type of the same name.  So float andunrestricted float become a C++ float, while double and unrestricted doublebecome a C++ double.

- -

For example, this WebIDL:

- -
interface Test { float myAttr; double myMethod(unrestricted double? arg); };
- -

will correspond to these C++ function declarations:

- -
float MyAttr();
-void SetMyAttr(float value);
-double MyMethod(const Nullable<double>& arg);
- -

DOMString

- -

Strings are reflected in three different ways, depending on use:

- - - -

Nullable strings are represented by the same types as non-nullable ones, but the string will return true for DOMStringIsNull().  Returning null as a string value can be done usingSetDOMStringToNull on the out param if it's an nsAString or calling SetNull() on aDOMString.

- -

For example, this WebIDL:

- -
interface Test { DOMString myAttr; [Throws] DOMString myMethod(sequence<DOMString> arg1, DOMString? arg2, optional DOMString arg3); };
- -

will correspond to these C++ function declarations:

- -
void GetMyAttr(nsString& retval);
-void SetMyAttr(const nsAString& value);
-void MyMethod(const Sequence<nsString>& arg1, const nsAString& arg2,
-              const Optional<nsAString>& arg3, nsString& retval, ErrorResult& rv);
- -

ByteString

- -

ByteString is reflected in three different ways, depending on use:

- - - -

Nullable ByteString are represented by the same types as non-nullable ones, but the string will return true for IsVoid().  Returning null as a string value can be done using SetIsVoid()on the out param.

- -

object

- -

object is represented in three different ways, depending on use:

- - - -

Methods using object always get a JSContext* argument.

- -

For example, this WebIDL:

- -
interface Test { object myAttr; object myMethod(object arg1, object? arg2, sequence<object> arg3, optional object arg4, optional object? arg5); };
- -

will correspond to these C++ function declarations:

- -
void GetMyAttr(JSContext* cx, JS::MutableHandle<JSObject*> retval);
-void SetMyAttr(JSContext* cx, JS::Handle<JSObject*> value);
-void MyMethod(JSContext* cx, JS::Handle<JSObject*> arg1, JS::Handle<JSObject*> arg2,
-              const Sequence<JSObject*>& arg3,
-              const Optional<JS::Handle<JSObject*> >& arg4,
-              const Optional<JS::Handle<JSObject*> >& arg5,
-              JS::MutableHandle<JSObject*> retval);
- -

Interface types

- -

There are four kinds of interface types in the WebIDL bindings.  Callback interfaces are used to represent script objects that browser code can call into.  External interfaces are used to represent objects that have not been converted to the WebIDL bindings yet.  WebIDL interfaces are used to represent WebIDL binding objects.  "SpiderMonkey" interfaces are used to represent objects that are implemented natively by the JavaScript engine (e.g. typed arrays).

- -
Callback interfaces
- -

Callback interfaces are represented in C++ as objects inheriting frommozilla::dom::CallbackInterface, whose name, in the mozilla::dom namespace, matches the name of the callback interface in the WebIDL.  The exact representation depends on how the type is being used.

- - - -

If the interface is a single-opertion interface, the object exposes two methods that both invoke the same underlying JS callable.  The first of these methods allows the caller to pass in a thisobject, while the second defaults to undefined as the this value.  In either case, the thisvalue is only used if the callback interface is implemented by a JS callable.  If it's implemented by an object with a property whose name matches the operation, the object itself is always used as this.

- -

If the interface is not a single-operation interface, it just exposes a single method for every IDL method/getter/setter.

- -

The signatures of the methods correspond to the signatures for throwing IDL methods/getters/setters with an additional trailing "mozilla::dom::CallbackObject::ExceptionHandling aExceptionHandling" argument, defaulting to eReportExceptions.  If aReportExceptions is set toeReportExceptions, the methods will report JS exceptions before returning.  IfaReportExceptions is set to eRethrowExceptions, JS exceptions will be stashed in theErrorResult and will be reported when the stack unwinds to wherever the ErrorResult was set up.

- -

For example, this WebIDL:

- -
callback interface MyCallback { attribute long someNumber; short someMethod(DOMString someString); }; callback interface MyOtherCallback { // single-operation interface short doSomething(Node someNode); }; interface MyInterface { attribute MyCallback foo; attribute MyCallback? bar; };
- -

will lead to these C++ class declarations, in the mozilla::dom namespace:

- -
class MyCallback : public CallbackInterface
-{
-  int32_t GetSomeNumber(ErrorResult& rv, ExceptionHandling aExceptionHandling = eReportExceptions);
-  void SetSomeNumber(int32_t arg, ErrorResult& rv,
-                     ExceptionHandling aExceptionHandling = eReportExceptions);
-  int16_t SomeMethod(const nsAString& someString, ErrorResult& rv,
-                     ExceptionHandling aExceptionHandling = eReportExceptions);
-};
-
-class MyOtherCallback : public CallbackInterface
-{
-public:
-  int16_t
-  DoSomething(nsINode& someNode, ErrorResult& rv,
-              ExceptionHandling aExceptionHandling = eReportExceptions);
-
-  template<typename T>
-  int16_t
-  DoSomething(const T& thisObj, nsINode& someNode, ErrorResult& rv,
-              ExceptionHandling aExceptionHandling = eReportExceptions);
-};
- -

and these C++ function declarations on the implementation of MyInterface:

- -
already_AddRefed<MyCallback> GetFoo(); void SetFoo(MyCallback&); already_AddRefed<MyCallback> GetBar(); void SetBar(MyCallback*);
- -
External interfaces
- -

External interfaces are represented in C++ as objects that XPConnect knows how to unwrap to.  This can mean XPCOM interfaces (whether declared in XPIDL or not) or it can mean some type that there's a castable native unwrapping function for.  The C++ type to be used should be thenativeType listed for the external interface in the Bindings.conf file.  The exact representation depends on how the type is being used.

- - - -
WebIDL interfaces
- -

WebIDL interfaces are represented in C++ as C++ classes.  The class involved must either be refcounted or must be explicitly annotated in Bindings.conf as being directly owned by the JS object.  If the class inherits from nsISupports, then the canonical nsISupports must be on the primary inheritance chain of the object.  If the interface has a parent interface, the C++ class corresponding to the parent must be on the primary inheritance chain of the object.  This guarantees that a void* can be stored in the JSObject which can then be reinterpret_castto any of the classes that correspond to interfaces the object implements.  The C++ type to be used should be the nativeType listed for the interface in the Bindings.conf file, ormozilla::dom::InterfaceName if none is listed.  The exact representation depends on how the type is being used.

- - - -

For example, this WebIDL:

- -
interface MyInterface { attribute MyInterface myAttr; void passNullable(MyInterface? arg); MyInterface? doSomething(sequence<MyInterface> arg); MyInterface doTheOther(sequence<MyInterface?> arg); readonly attribute MyInterface? nullableAttr; readonly attribute MyInterface someOtherAttr; // Marked as resultNotAddRefed readonly attribute MyInterface someYetOtherAttr; };
- -

Would correspond to these C++ function declarations:

- -
already_AddRefed<MyClass> MyAttr();
-void SetMyAttr(MyClass& value);
-void PassNullable(MyClass* arg);
-already_AddRefed<MyClass> doSomething(const Sequence<OwningNonNull<MyClass> >& arg);
-already_AddRefed<MyClass> doTheOther(const Sequence<nsRefPtr<MyClass> >& arg);
-already_Addrefed<MyClass> GetMyAttr();
-MyClass* SomeOtherAttr();
-MyClass* SomeYetOtherAttr(); // Don't have to return already_AddRefed!
- -
"SpiderMonkey" interfaces
- -

Typed array, array buffer, and array buffer view arguments are represented by the objects inTypedArray.h.  For example, this WebIDL:

- -
interface Test { void passTypedArrayBuffer(ArrayBuffer arg); void passTypedArray(ArrayBufferView arg); void passInt16Array(Int16Array? arg); }
- -

will correspond to these C++ function declarations:

- -
void PassTypedArrayBuffer(const ArrayBuffer& arg);
-void PassTypedArray(const ArrayBufferView& arg);
-void PassInt16Array(const Nullable<Int16Array>& arg);
- -

Typed array return values are represented by JSObject*.

- -

Typed arrays store a JSObject* and hence need to be rooted properly.  On-stack typed arrays can be declared as RootedTypedArray<TypedArrayType> (e.g.RootedTypedArray<Int16Array>).  Typed arrays on the heap need to be traced.

- -

Dictionary types

- -

A dictionary argument is represented by a const reference to a struct whose name is the dictionary name in the mozilla::dom namespace.  The struct has one member for each of the dictionary's members with the same name except the first letter uppercased and prefixed with "m". The members that have default values have types as described under the corresponding WebIDL type in this document.  The members that don't have default values have those types wrapped in Optional<>.

- -

Dictionary return values are represented by an out parameter whose type is a non-const reference to the struct described above, with all the members that have default values preinitialized to those default values.

- -

Note that optional dictionary arguments are always considered to have a default value of nullso dictionary arguments are never wrapped in Optional<>.

- -

If necessary, dictionaries can be directly initialized from a JS::Value in C++ code by invoking their Init() method.  Consumers doing this should declare their dictionary asRootedDictionary<DictionaryName>.  When this is done, passing in a null scope object and even a null JSContext* is allowed if the passed-in JS::Value is JS::NullValue().  Likewise, a dictionary struct can be converted to a JS::Value in C++ by calling ToJSValuewith the dictionary as the second argument.  If Init() or ToJSValue() return false, they will generally set a pending exception on the JSContext; reporting those is the responsibility of the caller.

- -

For example, this WebIDL:

- -
dictionary Dict { long foo = 5; DOMString bar; }; interface Test { void initSomething(optional Dict arg); };
- -

will correspond to this C++ function declaration:

- -
void InitSomething(const Dict& arg);
- -

and the Dict struct will look like this:

- -
struct Dict {
-  bool Init(JSContext* aCx, JS::Handle<JS::Value> aVal, const char* aSourceDescription = "value");
-
-  Optional<nsString> mBar;
-  int32_t mFoo;
-}
- -

Note that the dictionary members are sorted in the struct in alphabetical order.

- -

Enumeration types

- -

WebIDL enumeration types are represented as C++ enums.  The values of the C++ enum are named by taking the strings in the WebIDL enumeration, replacing all non-alphanumerics with underscores, and uppercasing the first letter, with a special case for the empty string, which becomes the value _empty.

- -

For a WebIDL enum named MyEnum, the C++ enum is named MyEnum and placed in themozilla::dom namespace, while the values are placed in the mozilla::dom::MyEnumnamespace.  There is also a mozilla::dom::MyEnumValues::strings which is an array ofmozilla::dom::EnumEntry structs that gives access to the string representations of the values.

- -

For example, this WebIDL:

- -
enum MyEnum { "something", "something-else", "", "another" };
- -

would lead to this C++ enum declaration:

- -
MOZ_BEGIN_ENUM_CLASS(MyEnum, uint32_t)
-  Something,
-  Something_else,
-  _empty,
-  Another
-MOZ_END_ENUM_CLASS(MyEnum)
-
-namespace MyEnumValues {
-extern const EnumEntry strings[10];
-} // namespace MyEnumValues
- -

Callback function types

- -

Callback functions are represented as an object, inheriting frommozilla::dom::CallbackFunction, whose name, in the mozilla::dom namespace, matches the name of the callback function in the WebIDL.  If the type is nullable, a pointer is passed in; otherwise a reference is passed in.

- -

The object exposes two Call methods, which both invoke the underlying JS callable.  The firstCall method has the same signature as a throwing method declared just like the callback function, with an additional trailing "mozilla::dom::CallbackObject::ExceptionHandling aExceptionHandling" argument, defaulting to eReportExceptions, and calling it will invoke the callable withundefined as the this value.  The second Call method allows passing in an explicit thisvalue as the first argument.  This second call method is a template on the type of the first argument, so the this value can be passed in in whatever form is most convenient, as long as it's either a type that can be wrapped by XPConnect or a WebIDL interface type.

- -

If aReportExceptions is set to eReportExceptions, the Call methods will report JS exceptions before returning.  If aReportExceptions is set to eRethrowExceptions, JS exceptions will be stashed in the ErrorResult and will be reported when the stack unwinds to wherever the ErrorResult was set up.

- -

For example, this WebIDL:

- -
callback MyCallback = long (MyInterface arg1, boolean arg2); interface MyInterface { attribute MyCallback foo; attribute MyCallback? bar; };
- -

will lead to this C++ class declaration, in the mozilla::dom namespace:

- -
class MyCallback : public CallbackFunction
-{
-public:
-  int32_t
-  Call(MyInterface& arg1, bool arg2, ErrorResult& rv,
-       ExceptionHandling aExceptionHandling = eReportExceptions);
-
-  template<typename T>
-  int32_t
-  Call(const T& thisObj, MyInterface& arg1, bool arg2, ErrorResult& rv,
-       ExceptionHandling aExceptionHandling = eReportExceptions);
-};
- -

and these C++ function declarations in the MyInterface class:

- -
already_AddRefed<MyCallback> GetFoo(); void SetFoo(MyCallback&); already_AddRefed<MyCallback> GetBar(); void SetBar(MyCallback*);
- -

Sequences

- -

Sequence arguments are represented by const Sequence<T>&, where T depends on the type of elements in the WebIDL sequence.

- -

Sequence return values are represented by an nsTArray<T> out param appended to the argument list, where T is the return type for the elements of the WebIDL sequence.  This comes after all IDL arguments, but before the ErrorResult&, if any, for the method.

- -

Arrays

- -

IDL array objects are not supported yet.  The spec on these is likely to change drastically anyway.

- -

Union types

- -

Union types are reflected as a struct in the mozilla::dom namespace.  There are two kinds of union structs: one kind does not keep its members alive (is "non-owning"), and the other does (is "owning").  Const references to non-owning unions are used for plain arguments.  Owning unions are used in dictionaries, sequences, and for variadic arguments.  Union return values become a non-const owning union out param.  The name of the struct is the concatenation of the names of the types in the union, with "Or" inserted between them, and for an owning struct "Owning" prepended.  So for example, this IDL:

- -
void passUnion((object or long) arg); (object or long) receiveUnion(); void passSequenceOfUnions(sequence<(object or long)> arg); void passOtherUnion((HTMLDivElement or ArrayBuffer or EventInit) arg);
- -

would correspond to these C++ function declarations:

- -
void PassUnion(const ObjectOrLong& aArg);
-void ReceiveUnion(OwningObjectObjectOrLong& aArg);
-void PassSequenceOfUnions(const Sequence<OwningObjectOrLong>& aArg);
-void PassOtherUnion(const HTMLDivElementOrArrayBufferOrEventInit& aArg);
- -

Union structs expose accessors to test whether they're of a given type and to get hold of the data of that type.  They also expose setters that set the union as being of a particular type and return a reference to the union's internal storage where that type could be stored.  The one exception is the object type, which uses a somewhat different form of setter where theJSObject* is passed in directly. For example, ObjectOrLong would have the following methods:

- -
bool IsObject() const;
-JSObject* GetAsObject() const;
-void SetToObject(JSContext*, JSObject*);
-bool IsLong() const;
-int32_t GetAsLong() const;
-int32_t& SetAsLong()
- -

Owning unions used on the stack should be declared as a RootedUnion<UnionType>.  For example, RootedUnion<OwningObjectOrLong>.

- -

Date

- -

WebIDL Date types are represented by a mozilla::dom::Date struct.

- -

Stringifiers

- -

Named stringifiers operations in WebIDL will just invoke the corresponding C++ method.

- -

Anonymous stringifiers in WebIDL will invoke the C++ method called Stringify.  So for example given this IDL:

- -
interface FirstInterface { stringifier; }; interface SecondInterface { stringifier DOMString getStringRepresentation(); };
- -

the corresponding C++ would be:

- -
class FirstInterface { public: void Stringify(nsAString& aResult); }; class SecondInterface { public: void GetStringRepresentation(nsAString& aResult); };
- -

Legacy Callers

- -

Only anonymous legacy callers are supported, and will invoke the C++ method calledLegacyCall.  This will be passed the JS "this" value as the first argument, then the arguments to the actual operation.  A JSContext will be passed if any of the operation arguments need it.  So for example given this IDL:

- -
interface InterfaceWithCall { legacycaller long (float arg); };
- -

the corresponding C++ would be:

- -
class InterfaceWithCall {
-public:
-  int32_t LegacyCall(JS::Handle<JS::Value> aThisVal, float aArgument);
-};
- -

Named getters

- -

If the interface has a named getter, the binding will expect several methods on the C++ implementation:

- - - -

The NameIsEnumerable and GetSupportedNames methods need to agree on which names are and are not enumerable.  The NamedGetter and GetSupportedNames methods need to agree on which names are supported.

- -

So for example, given this IDL:

- -
interface InterfaceWithNamedGetter { getter long(DOMString arg); };
- -

the corresponding C++ would be:

- -
class InterfaceWithNamedGetter
-{
-public:
-  int32_t NamedGetter(const nsAString& aName, bool& aFound);
-  bool NameIsEnumerable(const nsAString& aName);
-  void GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames);
-};
- -

Throwing exceptions from WebIDL methods, getters, and setters

- -

WebIDL methods, getters, and setters that are explicitly marked as allowed to throw have anErrorResult& argument as their last argument.  To throw an exception, simply call Throw()on the ErrorResult& and return from your C++ back into the binding code.

- -

In cases when the specification calls for throwing a TypeError, you should useErrorResult::ThrowTypeError() instead of calling Throw().

- -

Custom extended attributes

- -

Our WebIDL parser and code generator recognize several extended attributes that are not present in the WebIDL spec.

- -

[ChromeOnly]

- -

This extended attribute can be specified on any method, attribute, or constant on an interface or on an interface as a whole.

- -

Interface members flagged as [ChromeOnly] are only exposed in chrome Windows (and in particular, are not exposed to webpages).  From the point of view of web content, it's as if the interface member were not there at all.  These members are exposed to chrome script working with a content object via Xrays.

- -

If specified on an interface as a whole, this functions like [Func] except that the binding code will automatically check whether the caller script has the system principal (is chrome or a worker started from a chrome page) instead of calling into the C++ implementation to determine whether to expose the interface object on the global.   This means that accessing a  content global via Xrays will show [ChromeOnly] interface objects on it.

- -

This extended attibute can be specified together with [AvailableIn][CheckPermissions],[Func],  and [Pref].  If more than one of these is specified, all conditions will need to test true for the interface or interface member to be exposed.

- -

[Pref=prefname]

- -

This extended attribute can be specified on any method, attribute, or constant on an interface or on an interface as a whole. It takes a value, which must be the name of a boolean preference.

- -

If specified on an interface member, the interface member involved is only exposed if the preference is set to true. An example of how this can be used:

- -
interface MyInterface { attribute long alwaysHere; [Pref="my.pref.name"] attribute long onlyHereIfEnabled; };
- -

If specifed on an interface as a whole, this functions like [Func] except that the binding will check the value of the preference directly without calling into the C++ implementation of the interface at all. This is useful when the enable check is simple and it's desirable to keep the prefname with the WebIDL declaration. The implementation can callMyInterfaceBinding::PrefEnabled() to check whether it is enabled or not.  An example of how this can be used:

- -
[Pref="my.pref.name"] interface MyConditionalInterface { };
- -

This extended attibute can be specified together with [AvailableIn][CheckPermissions],[ChromeOnly], and[Func].  If more than one of these is specified, all conditions will need to test true for the interface or interface member to be exposed.

- -

[Func="funcname"]

- -

This extended attribute can be specified on any method, attribute, or constant on an interface or on an interface as a whole.  It takes a value, which must be the name of a static function. 

- -

If specified on an interface member, the interface member involved is only exposed if the specified function returns true.   An example of how this can be used:

- -
interface MyInterface { attribute long alwaysHere; [Func="MyClass::StuffEnabled"] attribute long onlyHereIfEnabled; };
- -

The function is invoked with two arguments: the JSContext that the operation is happening on and the JSObject for the global of the object that the property will be defined on if the function returns true.  In particular, in the Xray case the JSContext is in the caller compartment (typically chrome) but the JSObject is in the target compartment (typically content).  This allows the method implementation to select which compartment it cares about in its checks.

- -

The above IDL would also require the following C++:

- -
class MyClass {
-  static bool StuffEnabled(JSContext* cx, JSObject* obj);
-};
- -

If specified on an interface as a whole, then lookups for the interface object for this interface on a DOM Window will only find it if the specified function returns true.  For objects that can only be created via a constructor, this allows disabling the functionality altogether and making it look like the feature is not implemented at all.

- -

An example of how [Func] can be used:

- -
[Func="MyClass::MyConditionalInterfaceEnabled"] interface MyConditionalInterface { };
- -

In this case, the C++ function is passed a JS::Handle<JSObject*>.  So the C++ in this case would look like this:

- -
class MyClass {
-  static bool MyConditionalInterfaceEnabled(JSContext* cx, JS::Handle<JSObject*> obj);
-};
- -

Just like in the interface member case, the JSContext is in the caller compartment but theJSObject is the actual object the property would be defined on.  In the Xray case that mean obj is in the target compartment (typically content) and cx is typically chrome.

- -

This extended attibute can be specified together with [AvailableIn][CheckPermissions],[ChromeOnly], and [Pref].  If more than one of these is specified, all conditions will need to test true for the interface or interface member to be exposed.

- -

[AvailableIn=Where]

- -

This extended attribute can be specified on any method, attribute, or constant on an interface or on an interface as a whole. It takes a value, which must be either PrivilegedApps orCertifiedApps.  This will make the interface or interface member only visible in privileged and certified apps respectively on Firefox OS.

- -

This extended attibute can be specified together with [ChromeOnly][CheckPermissions],[Func], and  [Pref].  If more than one of these is specified, all conditions will need to test true for the interface or interface member to be exposed.

- -

[CheckPermissions="list of permissions"]

- -

This extended attribute can be specified on any method, attribute, or constant on an interface or on an interface as a whole. It takes a whitespace-separated list of permissions to be checked before making the interface or interface member visible to a page or app. When multiple permission names are specified, at least one of them will need to be set to nsIPermissionManager::ALLOW_ACTION for the interface or interface member to be exposed.

- -

This extended attribute can be specified together with [AvailableIn][ChromeOnly],[Func] and [Pref]. If more than one of these is specified, all conditions will need to test true for the interface or interface member to be exposed.

- -

[Throws][GetterThrows][SetterThrows]

- -

Used to flag methods or attributes as allowing the C++ callee to throw.  This causes the binding generator, and in many cases the JIT, to generate extra code to handle possible exceptions.  Possibly-throwing methods and attributes get an ErrorResult& argument.

- -

[Throws] applies to both methods and attributes; for attributes it means both the getter and the setter can throw.  [GetterThrows] applies only to attributes.  [SetterThrows] applies only to non-readonly attributes.

- -

For bindings that involve workers, the above can all be specified with MainThread or Workersas a value.  When doing this, if [Throws] is specified on an attribute, no matter what its value, then [GetterThrows] and [SetterThrows] will be ignored.  So to have an attribute which can throw both when getting and setting on main thread but can only throw from the setter in workers, use [SetterThrows, GetterThrows=MainThread].

- -

For interfaces flagged with [JSImplementation], all methods and properties are assumed to be able to throw and do not need to be flagged as throwing.

- -

[Pure]

- -

Used to flag attributes whose getter has no side-effects or methods that have no side-effects in the DOM.  Attributes/methods flagged in this way promise that they will keep returning the same value as long as no DOM setters or non-[Pure] DOM methods executed.  This allows the JIT to perform loop-hoisting and common subexpression elimination on the return values of these attributes/methods in some cases.  [Pure] things are allowed to throw exceptions as long as they do so deterministically.  This extended attribute can be used on writable attributes as long as the getter obeys the above rules.

- -

[Constant]

- -

Used to flag readonly attributes that could have been annotated with [Pure] and also always return the same value.  This allows the JIT to do even more aggressive optimization of getters for such attributes.  This should only be used when it's absolutely guaranteed that the return value of the attribute getter will always be the same from the JS engine's point of view.  This extended attribute implies [Pure] as far as the JIT is concerned.

- -

[NeedNewResolve]

- -

Used to flag interfaces which have a custom resolve hook.  This annotation will cause theDoNewResolve method to be called on the underlying C++ class when a property lookup happens on the object.  The signature of this method is: bool DoNewResolve(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>).  Here the passed-in object is the object the property lookup is happening on (which may be an Xray for the actual DOM object) and the jsid is the property name.  The value that the property should have is returned in the MutableHandle<Value>, with UndefinedValue() indicating that the property does not exist.

- -

If this extended attribute is used, then the underlying C++ class must also implement a method called GetOwnPropertyNames with the signature void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames, ErrorResult& aRv).  This method wil be called by the JS engine's enumerate hook and must provide a superset of all the property names that DoNewResolve might resolve.  Providing names that DoNewResolve won't actually resolve is OK.

- -

[HeaderFile="path/to/headerfile.h"]

- -

Indicates where the implementation can be found. Similar to the headerFile annotation in Bindings.conf.

- -

[JSImplementation="@mozilla.org/some-contractid;1"]

- -

Used on an interface to provide the contractid of the JavaScript component implementing the interface.

- - - -

Setting this extended attribute to propName on an interface causeswindow.navigator.propName to be an instance of the interface.

- -

[StoreInSlot]

- -

Used to flag attributes that can be gotten very quickly from the JS object by the JIT.  Such attributes will have their getter called immediately when the JS wrapper for the DOM object is created, and the returned value will be stored directly on the JS object.  Later gets of the attribute will not call the C++ getter and instead use the cached value.  If the value returned by the attribute needs to change, the C++ code should call the ClearCachedFooValue method in the namespace of the relevant binding, where foo is the name of the attribute.  This will immediately call the C++ getter and cache the value it returns, so it needs a JSContext to work on.  This extended attribute can only be used in on attributes whose getters are [Pure] or[Constant] and which are not [Throws] or [GetterThrows].

- -

So for example, given this IDL:

- -
interface MyInterface { [Pure, StoreInSlot] attribute long myAttribute; };
- -

the C++ implementation of MyInterface would clear the cached value by callingmozilla::dom::MyInterfaceBinding::ClearCachedMyAttributeValue(cx, this).

- -

If the attribute is not readonly, setting it will automatically clear the cached value and reget it again before the setter returns.

- -

[Cached]

- -

Used to flag attributes that, when their getter is called, will cache the returned value on the JS object.  This can be used to implement attributes whose value is a sequence or dictionary (which would otherwise end up returning a new object each time and hence not be allowed in WebIDL).

- -

Unlike [StoreInSlot] this does not cause the getter to be eagerly called at JS wrapper creation time; the caching is lazy.  [Cached] attributes must be [Pure] or [Constant], because otherwise not calling the C++ getter would be observable, but are allowed to have throwing getters.  Their cached value can be cleared by calling the ClearCachedFooValue method in the namespace of the relevant binding, where foo is the name of the attribute.  Unlike [StoreInSlot] attributes, doing so will not immediately invoke the getter, so does not need a JSContext.

- -

So for example, given this IDL:

- -
interface MyInterface { [Pure, StoreInSlot] attribute long myAttribute; };
- -

the C++ implementation of MyInterface would clear the cached value by callingmozilla::dom::MyInterfaceBinding::ClearCachedMyAttributeValue(this).

- -

If the attribute is not readonly, setting it will automatically clear the cached value.

- -

[Frozen]

- -

Used to flag attributes that, when their getter is called, will call Object.freeze on the return value before returning it.  This extended attribute is only allowed on attributes that return sequences, and corresponds to returning a frozen Array.

- -

[ChromeConstructor]

- -

[ChromeConstructor] has the same behaviour as [Constructor], but the constructor will throw if it's not called from chrome code. The usage rules and restrictions as those for[Constructor] apply. Note that [Constructor] and [ChromeConstructor] are mutually exclusive, while there can be multiple of either, there can never be both on the same interface.

- -

Helper objects

- -

The C++ side of the bindings uses a number of helper objects.

- -

Nullable<T>

- -

Nullable<> is a struct declared in Nullable.h and exported tomozilla/dom/Nullable.h that is used to represent nullable values of types that don't have a natural way to represent null.

- -

Nullable<T> has an IsNull() getter that returns whether null is represented and a Value()getter that returns a const T& and can be used to get the value when it's not null.

- -

Nullable<T> has a SetNull() setter that sets it as representing null and two setters that can be used to set it to a value: "void SetValue(T)" (for setting it to a given value) and "T& SetValue()" for directly modifying the underlying T&.

- -

Optional<T>

- -

Optional<> is a struct declared in BindingDeclarations.h and exported tomozilla/dom/BindingDeclarations.h that is used to represent optional arguments and dictionary members, but only those that have no default value.

- -

Optional<T> has a WasPassed() getter that returns true if a value is available.  In that case, the Value() getter can be used to get a const T& for the value.

- -

NonNull<T>

- -

NonNull<T> is a struct declared in BindingUtils.h and exported tomozilla/dom/BindingUtils.h that is used to represent non-null C++ objects.  It has a conversion operator that produces T&.

- -

OwningNonNull<T>

- -

OwningNonNull<T> is a struct declared in BindingUtils.h and exported tomozilla/dom/BindingUtils.h that is used to represent non-null C++ objects and holds a strong reference to them.  It has a conversion operator that produces T&.

- -

Typed arrays, arraybuffers, array buffer views

- -

TypedArray.h is exported to mozilla/dom/TypedArray.h and exposes structs that correspond to the various typed array types, as well as ArrayBuffer and ArrayBufferView, all in the mozilla::dom namespace.  Each struct has an Data() method that returns a pointer to the relevant type (uint8_t for ArrayBuffer and ArrayBufferView) and a Length()method that returns the length in units of *Data().  So for example, Int32Array has aData() returning int32_t* and a Length() that returns the number of 32-bit ints in the array..

- -

Sequence<T>

- -

Sequence<> is a type declared in BindingDeclarations.h and exported tomozilla/dom/BindingDeclarations.h that is used to represent sequence arguments.  It's some kind of typed array, but which exact kind is opaque to consumers.  This allows the binding code to change the exact definition (e.g. to use auto arrays of different sizes and so forth) without having to update all the callees.

- -

CallbackFunction

- -

CallbackFunction is a type declared in CallbackFunction.h and exported tomozilla/dom/CallbackFunction.h that is used as a common base class for all the generated callback function representations.  This class inherits from nsISupports, and consumers must make sure to cycle-collect it, since it keeps JS objects alive.

- -

CallbackInterface

- -

CallbackInterface is a type declared in CallbackInterface.h and exported tomozilla/dom/CallbackInterface.h that is used as a common base class for all the generated callback interface representations.  This class inherits from nsISupports, and consumers must make sure to cycle-collect it, since it keeps JS objects alive.

- -

DOMString

- -

DOMString is a class declared in BindingDeclarations.h and exported tomozilla/dom/BindingDeclarations.h that is used for WebIDL DOMString return values.  It has a conversion operator to nsString& so that it can be passed to methods that take that type or nsAString&, but callees that care about performance, have an nsStringBufferavailable, and promise to hold on to the nsStringBuffer at least until the binding code comes off the stack can also take a DOMString directly for their string return value and call itsSetStringBuffer method with the nsStringBuffer and its length.  This allows the binding code to avoid extra reference-counting of the string buffer in many cases, and allows it to take a faster codepath even if it does end up having to addref the nsStringBuffer.

- -

GlobalObject

- -

GlobalObject is a class declared in BindingDeclarations.h and exported tomozilla/dom/BindingDeclarations.h that is used to represent the global object for static attributes and operations (including constructors).  It has a Get() method that returns theJSObject*  for the global and a GetAsSupports() method that returns an nsISupports*for the global on the main thread, if such is available. It also has a GetContext() method that returns the JSContext* the call is happening on.  A caveat: the compartment of theJSContext may not match the compartment of the global!

- -

Date

- -

Date is a class declared in BindingDeclarations.h and exported tomozilla/dom/BindingDeclarations.h that is used to represent WebIDL Dates.  It has aTimeStamp() method returning a double which represents a number of milliseconds since the epoch, as well as SetTimeStamp() methods that can be used to initialize it with a double timestamp or a JS Date object.  It also has a ToDateObject() method that can be used to create a new JS Date.

- -

ErrorResult

- -

ErrorResult is a class declared in ErrorResult.h and exported to mozilla/ErrorResult.hthat is used to represent exceptions in WebIDL bindings.  This has the following methods:

- - - -

Bindings.conf details

- -

XXXbz write me.  In particular, need to describe at least use of concreteprefable, andaddExternalInterface

- -

How to get a JSContext passed to a given method

- -

In some rare cases you may need a JSContext* argument to be passed to a C++ method that wouldn't otherwise get such an argument. To see how to achieve this, search forimplicitJSContext in dom/bindings/Bindings.conf.

- -

Implementing WebIDL using Javascript

- -

There is support for implementing WebIDL interfaces in JavaScript.  When this is done, there are actually two objects created: the implementation object (running as a chrome-privileged script) and the content-exposed object (which is what the web page sees).  This allows the implementation object to have various APIs that the content-exposed object does not.  It also means that consumers have to be careful about which object they are creating.

- -

Creating JS-implemented WebIDL objects

- -

To create a JS-implemented WebIDL object, one must create both the chrome-side implementation object and the content-side page-exposed object. There are three ways to do this.

- -

Using the WebIDL constructor

- -

If the interface has a constructor, a content-side object can be created by getting that constructor from the relevant content window and invoking it. For example:

- -
var contentObject = new contentWin.RTCPeerConnection();
- -

The returned object will be an Xray wrapper for the content-side object. Creating the object this way will automatically create the chrome-side object using its contractID.

- -

This method is limited to the constructor signatures exposed to webpages. Any additional configuration of the object needs to be done via [ChromeOnly] methods on the interface. 

- -

Creating many objects this way can be slow due to the createInstance overhead involved. 

- -

Using a _create method  

- -

 A content-side object can be created for a given chrome-side object by invoking the static_create method on the interface. This method takes two arguments: the content window in which to create the object and the chrome-side object to use. For example:

- -
var contentObject = RTCPeerConnection._create(contentWin,
-                                              new MyPeerConnectionImpl());
- -

However, if you are in a JS component, you may only be able to get to the correct interface object via some window object. In this case, the code would look more like:

- -
var contentObject = contentWin.RTCPeerConnection._create(contentWin,
-                                                         new MyPeerConnectionImpl());
- -

Creating the object this way will not invoke its __init method or init method.

- -

By returning a chrome-side object from a JS-implemented WebIDL method

- -

If a JS-implemented WebIDL method is declared as returning a JS-implemented interface, then a non-WebIDL object returned from that method will be treated as the chrome-side part of a JS-implemented WebIdL object and the content-side part will be automatically created.

- -

Creating the object this way will not invoke its __init method or init method.

- -

Implementing a WebIDL object in JavaScript

- -

To implement a WebIDL interface in JavaScript, first add a WebIDL file, in the same way as you would for a C++-implemented interface.  To support implementation in JS, you must add an extended attribute JSImplementation="CONTRACT_ID_STRING" on your interface, where CONTRACT_ID_STRING is the XPCOM component contract ID of the JS implementation.  Here's an example:

- -
[Constructor(optional long firstNumber), JSImplementation="@mozilla.org/my-number;1"] interface MyNumber { attribute long value; readonly attribute long otherValue; void doNothing(); };
- -

Next, create an XPCOM component that implements this interface.  Basic directions for how to do this can be found elsewhere on MDN.  Use the same contract ID as you specified in the WebIDL file.  The class ID doesn't matter, except that it should be a newly generated one.  ForQueryInterface, you only need to implement nsISupports, not anything corresponding to the WebIDL interface.  The name you use for the XPCOM component should be distinct from the name of the interface, to avoid confusing error messages.

- -

WebIDL attributes are implemented as properties on the JS object or its prototype chain, whereas WebIDL methods are implemented as methods on the object or prototype.  Note that any other instances of the interface that you are passed in as arguments are the full web-facing version of the object, and not the JS implementation, so you currently cannot access any private data.

- -

The WebIDL constructor invocation will first create your object.  If the XPCOM component implements nsIDOMGlobalPropertyInitializer, then the object's init method will be invoked with a single argument: the content window the constructor came from.  This allows the JS implementation to know which content window it's associated with.  The init method should not return anything.  After this, the content-side object will be created. Then, if there are any constructor arguments, the object's __init method will be invoked, with the constructor arguments as its arguments.

- -

If you want an instance of the class to be added to window.navigator, add an extended attribute NavigatorProperty="PropertyName" which will make the instance available aswindow.navigator.PropertyName.

- -

Checking for Permissions or Preferences

- -

When implementing an XPIDL interface using Javascript, the init method may check if the caller has the proper permissions, or if the appropriate preference is set. If this check fails, then it will return null to indicate that the object should not be created.  JS-implemented WebIDL does NOT work like that.  In JS-implemented WebIDL, the init method should only return undefined.  If any other value, such as null, is returned, the bindings code will assert or crash.  In other words, it acts like it has a "void" return type.

- -

Instead, preference or permission checking should be implemented by adding an extended attribute to the WebIDL interface. This has the advantage that if the check fails, the constructor or object will not show up at all.

- -

For preference checking, add an extended attribute Pref="myPref.enabled" wheremyPref.enabled is the preference that should be checked.  SettingsLock is an example of this.

- -

For permissions or other kinds of checking, add an extended attributeFunc="MyPermissionChecker" where MyPermissionChecker is a function implemented in C++ that returns true if the interface should be enabled.  This function can do whatever checking is needed.  One example of this is PushManager.

- -

Example

- -

Here's an example JS implementation of the above interface. The invisibleValue field will not be accessible to web content, but is usable by the doNothing() method.

- -
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); function MyNumberInner() { this.value = 111; this.invisibleValue = 12345; } MyNumberInner.prototype = { classDescription: "Get my number XPCOM Component", classID: Components.ID("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"), // dummy UUID contractID: "@mozilla.org/my-number;1", QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports]), doNothing: function() {}, get otherValue() { return this.invisibleValue - 4; }, __init: function(firstNumber) { if (arguments.length > 0) { this.value = firstNumber; } } } var components = [MyNumberInner]; var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
- -

Finally, add a component and a contract and whatever other manifest stuff you need to implement an XPCOM component.

- -

Guarantees provided by bindings

- -

When implementing a WebIDL interface in JavaScript, certain guarantees will be provided by the binding implementation.  For example, string or numeric arguments will actually be primitive strings or numbers.  Dictionaries will contain only the properties that they are declared to have, and they will have the right types.  Interface arguments will actually be objects implementing that interface.

- -

What the bindings will NOT guarantee is much of anything about object and any arguments.  They will get cross-compartment wrappers that make touching them from chrome code not be an immediate security bug, but otherwise they can have quite surprising behavior if the page is trying to be malicious.  Try to avoid using these types if possible.

- -

Accessing the content object from the implementation

- -

If the JS implementation of the WebIDL interface needs to access the content object, it is available as a property called __DOM_IMPL__ on the chrome implementation object.  This property only appears after the content-side object has been created. So it is available in__init but not in init.

- -

Determining the principal of the caller that invoked the WebIDL API

- -

This can be done by calling Component.utils.getWebIDLCallerPrincipal().

- -

Throwing exceptions from JS-implemented APIs

- -

There are two reasons a JS implemented API might throw.  The first reason is that some unforeseen condition occurred and the second is that a specification requires an exception to be thrown.

- -

When throwing for an unforeseen condition, the exception will be reported to the console, and a sanitized NS_ERROR_UNEXPECTED exception will be thrown to the calling content script, with the file/line of the content code that invoked your API.  This will avoid exposing chrome URIs and other implementation details to the content code.

- -

When throwing because a specification requires an exception, you need to communicate to the binding code that this is what you're doing.  Right now this is done by throwing a DOMErrorfrom the window your WebIDL object is associated with (the one that was passed to your initmethod).  The binding code will then rethrow just the message string of that DOMError to the web page, as a plain JS Error.  This does not allow implementing exceptions per spec (e.g. there is no way to explicitly throw a TypeError or other Error subclass), unfortunately; we're still working on that.  Since you know for this case the exception is being thrown because a spec requires it, you know you need to create the DOMError.  An example of how this could work:

- -
if (!isValid(passedInObject)) {
-  throw new this.contentWindow.DOMError("Error", "Object is invalid");
-}
- -

In some cases you may need to perform operations whose exception message you just want to propagate to the content caller.  This can be done like so:

- -
try {
-  someOperationThatCanThrow();
-} catch (e) {
-  throw new this.contentWindow.DOMError(e.name, e.message);
-}
- -

Inheriting from interfaces implemented in C++

- -

It's possible to have an interface implemented in JavaScript inherit from an interface implemented in C++.  To do so, simply have one interface inherit from the other and the bindings code will auto-generate a C++ object inheriting from the implementation of the parent interface.  The class implementing the parent interface will need a constructor that takes annsPIDOMWindow* (though it doesn't have to do anything with that argument).

- -

If the class implementing the parent interface is abstract and you want to use a specific concrete class as the implementation to inherit from, you will need to add a defaultImpl annotation to the descriptor for the parent interface in Bindings.conf.  The value of the annotation is the C++ class to use as the parent for JS-implemented descendants; if defaultImpl is not specified, the nativeType will be used.

- -

For example, consider this interface that we wish to implement in JavaScript:

- -
[JSImplementation
- -

="some-contract"] interface MyEventTarget : EventTarget { attribute EventHandler onmyevent; void dispatchTheEvent(); // Sends a "myevent" event to this EventTarget }

- -

The implementation would look something like this, ignoring the XPCOM boilerplate:

- -
function MyEventTargetImpl() { } MyEventTargetImpl.prototype = { init: function(contentWindow) { // XXXbz need to document how to get this called on you! this.contentWindow = contentWindow; } get onmyevent() { return this.__DOM_IMPL__.getEventHandler("onmyevent"); } set onmyevent(handler) { this.__DOM_IMPL__.setEventHandler("onmyevent", handler); } dispatchTheEvent: function() { var event = new this.contentWindow.Event("myevent"); this.__DOM_IMPL__.dispatchEvent(event); } };
- -

The implementation would automatically support the API exposed on EventTarget (so for example addEventListener).  Calling the dispatchTheEvent method would cause dispatch of an event that content script can see via listeners it has added.

- -

Note that in this case the chrome implementation is relying on some [ChromeOnly] methods on EventTarget that were added specifically to make it possible to easily implement event handlers.  Other cases can do similar things as needed

- -

- -

- -

- -

diff --git a/files/zh-cn/mozilla/xmlhttprequest_changes_for_gecko_1.8/index.html b/files/zh-cn/mozilla/xmlhttprequest_changes_for_gecko_1.8/index.html deleted file mode 100644 index cd7607f36c..0000000000 --- a/files/zh-cn/mozilla/xmlhttprequest_changes_for_gecko_1.8/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: XMLHttpRequest 在 Gecko1.8 发生的变化 -slug: Mozilla/XMLHttpRequest_changes_for_Gecko_1.8 -tags: - - AJAX - - Add-ons - - Extensions - - XMLHttpRequest -translation_of: Mozilla/XMLHttpRequest_changes_for_Gecko_1.8 ---- -

此文档描述了 Gecko's XMLHttpRequest 的实现自1.7版本 (i.e., Firefox 1.0附带的Gecko版本)。发生的一些改变,这些变化仅仅作用于XUL扩展以及XUL程序,将不会作用于web程序。

- -

 XMLHttpRequest.send的改变

- -

如果你将一个 nsIInputStream 实例传递给 send 方法, 那么流的起始部分将不再包含 Content-Length 和 Content-Type 头部信息. 并且 Content-Length 将由流的长度推断得出,  Content-Type 将必须通过调用 setRequestHeader 方法来手动指定. 更多关于这些要求的详细信息请查阅 nsIXMLHttpRequest.idl.

- -

XMLHttpRequest.onreadystatechange 的改变

- -

此属性现在的类型为 nsIOnReadystatechangeHandler 而不是 nsIOnReadyStateChangeHandler  。 (类型的名称中的 "S" 和 "C" 已变更为小写.)

diff --git "a/files/zh-cn/mozilla/\345\220\214\346\227\266\344\275\277\347\224\250\345\244\232\344\270\252\347\233\270\344\272\222\347\213\254\347\253\213\347\232\204\347\201\253\347\213\220\346\265\217\350\247\210\345\231\250/index.html" "b/files/zh-cn/mozilla/\345\220\214\346\227\266\344\275\277\347\224\250\345\244\232\344\270\252\347\233\270\344\272\222\347\213\254\347\253\213\347\232\204\347\201\253\347\213\220\346\265\217\350\247\210\345\231\250/index.html" deleted file mode 100644 index ab77b18752..0000000000 --- "a/files/zh-cn/mozilla/\345\220\214\346\227\266\344\275\277\347\224\250\345\244\232\344\270\252\347\233\270\344\272\222\347\213\254\347\253\213\347\232\204\347\201\253\347\213\220\346\265\217\350\247\210\345\231\250/index.html" +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: 同时使用多个相互独立的火狐浏览器 -slug: Mozilla/同时使用多个相互独立的火狐浏览器 -translation_of: Mozilla/Firefox/Multiple_profiles ---- -

{{ draft() }}

-

火狐浏览器的配置文件是用户在浏览器中的设置、自定义、个性化内容的集合。你可以在这个连接中看到它的详细内容: Profiles on Mozilla's end-user support site.

-

为什么要拥有多个配置文件

-

不同的家庭成员可能希望使用不同的配置文件。这样他们的书签设置和插件就可以区分开来。

-

Web developers might want a secondary profile for testing websites, apps, or other projects on different Firefox channels. For example, you might want to have the Firebug add-on installed for Web development, but not for general-purpose Web browsing. While using the Nightly channel, you may encounter some add-ons that have become temporarily incompatible with new API changes, until the add-on developer has a chance to update them. You can remove such add-ons from your profile for Nightly use, while keeping them for use with other profiles.

-

For QA, testing, and bug triaging contributors, you may want to have multiple development versions of Firefox installed, each with its own profile. Creating new profiles for testing can keep you from losing your preferences, bookmarks, and history. It takes some time to set up a new profile, but once it is complete, all of your Firefox versions will update separately and can be run simultanesouly.

-

可用的浏览器开发通道

-

There are four available browser channels, each at a different level of stability and development. The four channels are Release, Beta, Aurora, and Nightly. The Release channel is recommended for most users, as it is the "official release" channel. However, for those more adventurous, you can try one of the other three channels to see what is coming in Firefox and play around with emerging features. The Beta channel contains the features that are expected to be in the next release of Firefox and are in final stages of testing. Aurora contains experimental features, which are not yet at beta quality. Nightly contains the latest code from Firefox developers and is the least stable channel.

-

第三方工具

-

In addition to the built-in Profile Manager and the external Profile Manager, there are a few third-party tools that make working with multiple profiles easy:

-

Mac OSX

- -

配置文件管理器

-

{{ Note("On all operating systems, before you can start the Profile Manager, Firefox must be completely closed.") }}

-

These instructions are tentatively going away in favor of a new profile manager. You can find more details at Profile Manager

-

在Windows中启动配置文件管理器

-

Windows XP

-
    -
  1. Click the Start button
  2. -
  3. Click "Run"
  4. -
  5. Type "firefox -ProfileManager"
  6. -
-

Windows Vista/7

-
    -
  1. Click the Start button
  2. -
  3. Click the search bar at the bottom.
  4. -
  5. Type "firefox -ProfileManager"
  6. -
-

Windows 8/8.1

-
    -
  1. Press "Windows + R" on your keyboard.
  2. -
  3. Type "firefox -ProfileManager".
  4. -
-

If the Profile Manager window does not open, Firefox may have been running in the background, even though it was not visible. Close all instances of Firefox or restart the computer and then try again.

-

在Linux中启动配置文件管理器

-

If Firefox is already included in your Linux distribution or if you have installed Firefox with the package manager of your Linux distribution:

-
    -
  1. At the top of the Firefox window, click on the File menu and select Quit.
  2. -
  3. In Terminal run:
    - firefox --ProfileManager
  4. -
-

If the Profile Manager window does not open, Firefox may have been running in the background, even though it was not visible. Close all instances of Firefox or restart the computer and then try again.

-

在Mac OSX中启动配置文件管理器

-

Use the following tutorial until someone can test and step-by-step on a mac directly. Easily Run Multiple Firefox Instances on a Mac.

-

创建配置文件

-

These instructions should be the same for all operating systems.

-
    -
  1. To start the Create Profile Wizard, click "Create Profile..." in the Profile Manager.
  2. -
  3. Click Next and enter the name of the profile. Use a profile name that is descriptive, such as your personal name. This name is not exposed on the Internet.
  4. -
  5. You can also choose where to store the profile on your computer. To select storage location, click Choose Folder....
  6. -
  7. {{ Note("If you choose your own folder location for the profile, select a new or empty folder. If you choose a folder that isn't empty and you later remove the profile and choose the \"Delete Files\" option, everything inside that folder will be deleted.") }}
  8. -
  9. To create the new profile, click Finish.
  10. -
-

删除配置文件

-
    -
  1. In the Profile Manager, select the profile to remove, and click Delete Profile....
  2. -
  3. Confirm that you wish to delete the profile: -
      -
    • Don't Delete Files removes the profile from the Profile Manager yet retains the profile data files on your computer in the storage folder, so that your information is not lost. "Don't Delete Files" is the preferred option because it saves the old profile's folder and allows you to recover the files to a new profile.
    • -
    • Delete Files removes the profile and its files, including the profile bookmarks, settings, passwords, etc. {{ warning("If you use the \"Delete Files\" option, the profile folder and files will be deleted. This action cannot be undone.") }}
    • -
    • Cancel interrupts the profile deletion.
    • -
    -
  4. -
-

重命名配置文件

-
    -
  1. In the Profile Manager, select the profile you want to rename, and then click "Rename Profile".
  2. -
  3. Enter a new name for the profile and click on OK.
  4. -
  5. {{ Note("The folder containing the files for the profile is not renamed. ") }}
  6. -
-

可用选项

-

Work Offline

-

Choosing this option loads the selected profile and starts Firefox offline. You can view previously viewed web pages and experiment with your profile.

-

Don't ask at startup

-

If you have multiple profiles, Firefox prompts you for the profile to use each time you start Firefox. Select this option to allow Firefox to load the selected profile without prompting at startup.

-

{{ Note("To access other profiles after selecting this option, you must start the Profile Manager first.") }}

-

Using the profiles

-

Windows

-

If you want to have the profile manager to pop up each time you start Firefox, so you can choose a profile, you will need to edit the "Target" of the launch icon. To do this:

-
    -
  1. Right click the icon and choose "Properties".
  2. -
  3. When the properties dialog box pops up, you should see a "Target" text field that you can edit, and it should show the current file path.
  4. -
  5. After the closing quote, add "-ProfileManager"
  6. -
  7. Click Ok.
  8. -
-

Now whenever you double click that icon, the profile manager should appear, allowing you to choose which profile you'd like to use.

-

If you want individual icons to launch specific profiles, you will need to edit the "Target" of each icon. To do this:

-
    -
  1. Right click the icon and choose "Properties".
  2. -
  3. When the properties dialog box pops up, you should see a "Target" text field that you can edit, and it should show the current file path.
  4. -
  5. To permanently set a specific profile, add "-p PROFILE_NAME" to the target path, but outside of the quotes, replacing "PROFILE_NAME" with the actual profile name you chose.
  6. -
  7. If you would like to also allow multiple instances of Firefox to run at the same time, add "-no-remote" after the profile name.
  8. -
-

Once you are all done, click Ok. Do this for each icon you'd like to have a specific profile for. Once done, each one should automatically start with the specified profile.

-

Linux

-

There is no extremely straightforward way to create custom application launchers in Gnome 3 like there was in Gnome 2. The following tutorial will help get you going overall: Gnome 3 Custom application launcher. Once you get to the point of adding a new item, you can have the profile dialog show up every time or set the launcher to launch a specific profile.

-

If you want to have the profile manager to pop up each time you start Firefox, so you can choose a profile, you will need to set the command line for your new launcher.

-
    -
  1. Set the "command" text field to target the executable file, likely "/usr/bin/firefox", and add the "-p" parameter.
  2. -
-

If you want individual icons to launch specific profiles, you will need to set the command line for your new launcher. To do this:

-
    -
  1. Set the "command" text field to target the executable file, likely "/usr/bin/firefox", and add the "-p PROFILE_NAME" parameter, replacing "PROFILE_NAME" with the specific profile.
  2. -
  3. Repeat as necessary for each profile you want to set.
  4. -
  5. If you would like to also allow multiple instances of Firefox to run at the same time, add "-no-remote" after the profile name.
  6. -
-

Mac OSX

-

You can find a useful tutorial to set up custom launchers here: Managing Multiple Firefox Profiles in OSX. Do note it's best to follow all steps in the "Creating the scripts" section, including the "edit Info.plist" step. Leave off the profile name if you want the profile selector to show up every time you launch.

-

Setting up multiple profiles for different Firefox Channels

-

This section will be especially helpful if you are a developer wanting to work with multiple channels and each having their own separate launcher.

-

Windows

-

In Windows, the Aurora and Nightly builds get their own directory in the "Programs" folder, so you don't have to worry about where to store the downloaded files. However, all three will attempt to use the same profile by default, and you'll want to not keep this because the different channels have different levels of features. To set each launcher, follow the Windows instructions at Windows Launcher

-

Linux

-

In Linux, things aren't as automatically set up, and you will likely get a prompt to download a tar.bz2 file to extract from. Extract the files to a new directory and use the new launcher instructions from here. The only change you will need to make is the command path. You will want to set it to the directory you extracted the Firefox channel's tar.bz2 file into, and the executable "firefox" file located within. The remaining profile assignment methods will remain the same. You will want to, for sure, add the "-no-remote" part to the end of the command field, so that you could run multiple instances at the same time.

-

Mac OSX

-

You can find a useful tutorial to set up custom launchers here: Managing Multiple Firefox Profiles in OSX. Do note it's best to follow all steps in the "Creating the scripts" section, including the "edit Info.plist" step. Also you'll want to change the path in the do shell script to point to the correct .app file for the Firefox channel you want to target.

diff --git "a/files/zh-cn/mozilla/\346\227\245\345\216\206/index.html" "b/files/zh-cn/mozilla/\346\227\245\345\216\206/index.html" deleted file mode 100644 index 876073f871..0000000000 --- "a/files/zh-cn/mozilla/\346\227\245\345\216\206/index.html" +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Mozilla 日历 -slug: Mozilla/日历 -translation_of: Mozilla/Calendar ---- - - - - - - - -
Sunbird-Logo-148x155.png -

Mozillar日历项目是一个基于Mozilla应用程序架构的社区驱动的项目,其核心是基于libical的日历后端。Lightning附加组件是在该平台上构建的,它为Mozilla的邮件客户端Thunderbird提供集成化的日历功能。

-

Mozilla Calendar emphasizes free and open source technology and supports standardized technology like the ical/ics (rfc2445) format and the CalDAV (rfc4791) protocol, which is implemented by many freely available servers and also some commercial providers.

-
- - - - - - - -
-

开发相关的主题

-
-
- Building Calendar
-
- Information about building Calendar with the new comm-central repository. There is also a simple build page for Thunderbird including Lightning and information about how comm-central works.
-
-
-
- Creating a Calendar extension
-
- Tutorial on creating a Calendar extension for Sunbird and Lightning.
-
-
-
- Localization
-
- How to get started with translating Calendar into your language and how to build Lightning in your Language. 
-
- Testing Calendar
-
- CalendarUtils reference for writing Mozmill tests, which can automatically test the UI so that regressions can be easily found.
-
- Calendar Versions
-
- This page will tell you which Calendar version fits with which Mozilla Platform and where current development is being done.
-
-
-

工具

-
-
- Bugzilla
-
- The Bugzilla database used to track issues for Mozilla projects.
-
-  
-
- MXR
-
- Browse and search the Calendar source code repository on the Web.
-
-  
-
- Calendar Servers
-
- Setup your own calendar server, or check to see how well commercial products are supported.
-
-  
-
-
-

 

diff --git a/files/zh-cn/mozilla_dom_hacking_guide/index.html b/files/zh-cn/mozilla_dom_hacking_guide/index.html deleted file mode 100644 index 8c819d864f..0000000000 --- a/files/zh-cn/mozilla_dom_hacking_guide/index.html +++ /dev/null @@ -1,795 +0,0 @@ ---- -title: Mozilla DOM Hacking Guide -slug: Mozilla_DOM_Hacking_Guide -translation_of: Mozilla/Mozilla_DOM_Hacking ---- -
-

Warning: this document has not yet been reviewed by the DOM gurus, it might contain some errors. It is also perhaps outdated in parts, because of recent changes in the DOMClassInfo code. If anyone wants to help, please let me know.

-
- -
-

警告1: 这篇文档尚未经DOM大牛们审阅,它可能会包含某些错误。 由于DOMClassInfo代码最近的变化,本文某些部分可能已经过时。如果有人需要帮助,请告知我。

- -

警告2: 这篇文档的翻译也未经大牛审阅,它可能会包含某些错误。。

-
- -

Mozilla gives you the opportunity not only to use a very powerful and complete DOM support, but also to work on a world-class implementation of one of the greatest Internet technology ever created.

- -

Mozilla提供了有力且完整的DOM支持,它的DOM实现是曾有的最伟大的网络技术之一,并且除了使用DOM支持以外,你也有机会在这个世界级的实现之上工作。

- -

Mozilla's DOM is coded almost entirely in C++. Seriously hacking on it requires excellent knownledge of C++ and XPCOM, Mozilla's own component model. In this document I will try to outline the main aspects of the implementation, begining with the Class Info mechanism, which lies at the heart of the DOM, then with the description of various interfaces and classes. Since I am myself still learning how it works, don't expect this to be a complete reference quite yet. If you can contribute any time or knowledge to this document, it is greatly appreciated!

- -

Mozilla 的DOM几乎全是用C++写的,真要修改它,你需要对C++,XPCOM,还有Mozilla自己的组件模型有出色的了解。本文试图对 DOM实现的主要方面进行勾勒,从DOM的核心部分,Class info开始,然后描述各种接口和类。因为我自己也还在学习它的工作原理,就别指望本文会是个完整的指导书了。如果你也愿意为这篇文档贡献时间精力,那就 太感谢了。

- -

Target audience: People interested in learning how the DOM is implemented. Prior knowledge of C++ and XPCOM is assumed. If you don't know XPCOM yet, and would like to be able to read this document quickly, you can read the Introduction to XPCOM for the DOM. Otherwise, for more detailed XPCOM documentation, please see the XPCOM project page.

- -

目标受众:对DOM如何实现感兴趣的人。本文假设你对C++和XPCOM有了解。如果你还不了解XPCOM,并且希望快速阅读本文,你可用先看看 introduction to XPCOM for the DOM.。不然,要得到更详细的XPCOM文档,请参考XPCOM project page

- -

Class Info and Helper Classes

- -

Introduction to Class Info

- -

Class Info is what gives the DOM classes their correct behavior when used through XPConnect. It lies at the heart of the famous "XPCDOM landing" that happened in May. We will talk alot about XPConnect in this document, since it is so important for the DOM. By "correct behavior", I mean "the intended behavior with respect to the specification or de facto standard". We will see that Class Info is mainly used to implement the DOM Level 0. The W3C DOM is mainly implemented in IDL. The goals of Class Info are twofolds: Interface flattening, and implementing behaviors that are not possible with IDL alone.

- -

Class Info让DOM类在被通过XPConnect使用时,能够作出正确的行为。它是发生在五月的著名的"XPCDOM landing"的核心。在本文中,我们会大量地提到XPConnect,因为它对DOM很重要。提到“正确的行为”,我指的是规范或者标准所预期的行 为。我们会看到Class Info主要用来实现DOM Level 0。W3C DOM主要用IDL实现。Class Info的目标主要是两个:接口平坦化,还有实现不可能只用IDL实现的行为。

- -

A brief introduction to JavaScript and XPConnect.

- -

对JavaScript和XPConnect的简介

- -

Before we begin the explanation of Class Info, I'd like to introduce quickly the JavaScript engine and XPConnect. In JavaScript, there is no knowledge of types, like there is in C++. A function for example can be represented by a JSFunction, a JSObject, a jsval, ... This means that when we use the DOM from JavaScript, we pass arguments that have no type. However, since the DOM is coded in C++, we expect to receive an argument of the correct type for our function. This is one of the jobs of XPConnect. XPConnect will "wrap" the argument in a wrapper that will be of the type expected by our C++ function. Similarly, then return type of the C++ function will be wrapped by XPConnect so that JavaScript can use it safely.

- -

在我们开始解释Class Info之前,我想先快速地介绍一下JavaScript引擎和XPConnect。在JavaScript中,没有象C++那样类型的概念。比如说,一 个函数可以被表示成一个JSFunction,一个JSObject,一个jsval...这就意味着当我们从JavaScript中使用DOM是,我们 会传递没有类型的参数。然而,因为DOM是用C++编写的,我们会希望收到具有正确类型的参数。这就是XPConnect的一部分工作。 XPConnect会在参数外面"裹(wrap)"一层包装(wrapper),把它包装成C++函数所期望的类型。类似地,C++函数的返回值也会被 XPConnect包装成JavaScript可以安全使用的类型。

- -

When, in JavaScript, a client tries to access a DOM object or a DOM method on a DOM object, the JS engine asks XPConnect to search for the relevant C++ method to call. For example, when we ask for |document.getElementById("myID");|, XPConnect will find that |document| is a property of the window object, so it will look on the interface nsIDOMWindow, and it will find the GetDocument() method. The return value of GetDocument() is a nsIDOMDocument. So XPConnect will then try to find a method named GetElementById() on the nsIDOMDocument interface. And indeed it will find it, and thus call it.

- -

在JavaScript中,当客户端试图访问一个DOM对象或者一个DOM对象的一个DOM方法时,JS引 擎会向XPConnect要求寻找一个相关的C++函数来调用。比如,当我们要求|document.getElementById("myID");| 时,XPConnect会发现[document]
- 是window对象的一个属性,所以它会去找nsIDOMWindow接口,然后它会寻找GetDocument()方法。GetDocument()方 法的返回值是nsIDOMDocument。所以XPConnect会试图在nsIDOMDocument 接口中寻找叫GetElementById()的方法,它也确实找到了这个方法。所以它就调用了这个方法。

- -

This is the schema used most of the time when using W3C DOM objects and methods. It is however different for some DOM Level 0 objects and methods. I'll take two very different examples. The first one is the window.location object (the same holds true for document.location, actually). We can change the URL of the current window by assigning window.location. In IDL, location is declared to be a readonly attribute. This is because, if we had a SetLocation() method, it would take an nsIDOMLocation parameter, and not a URL string. Instead, in the helper class for the window object (nsWindowSH, see the next Section), we define the GetProperty() member function. GetProperty() is a function used by XPConnect when we are setting an unknown property on the object (window, in our case). In GetProperty(), we check if the property being set is "location". If that is the case, we call nsIDOMLocation::SetHref(). In fact, when setting window.location, we really set window.location.href. This is all possible thanks to the magic of the interaction between XPConnect and the DOM.

- -

这是使用W3C DOM对象和方法时最常用的场景。但是,对于有些DOM level 0的对象和方法来说有点不一样。我会举两个不同的例子。第一个是window.location对象(实际上document.location也是一 样)。我们可以通过给window.location赋值来改变当前窗口的URL。在IDL里,location被声明为一个只读属性。这是因为,如果我 们有个SetLocation()方法,它会接收一个nsIDOMLocation属性的参数,而不是一个URL字符串。与之相对地,在window对象 的helper类中,(nsWindowSH,见下章),我们定义了GetProperty()成员函数。GetProperty()是 XPConnect使用的函数,用来设置对象(在我们的例子中,是window)的一个未知变量。在GetProperty()里,我们检查要被设置的属 性是不是location。如果是的话,我们就调用nsIDOMLocation::SetHref()。实际上,当设置window.location 的时候,我们设置的是window.location.href。这些都归功于XPConnect和DOM之间的交互魔法。

- -

The second example is the history object. Other browsers allow the history object to be used like an array, e.g. history{{ mediawiki.external(1) }}. The behavior "act as an array" cannot be reflected in the IDL itself. Fortunately, XPConnect provides us with a way to make our class available as an array in JavaScript. I'm talking about the "scriptable flags". The nsIXPCScriptable interface, implemented by the nsDOMClassInfo class (see Section) defines several flags, one of which is the WANT_GETPROPERTY flag. When set, it allows us to define a GetProperty() function on nsHistorySH (the helper class for the history object), which will handle the array behavior. Indeed, it will forward the call history{{ mediawiki.external(1) }} to history.item(1), which is defined in the IDL and easily coded. The relevant code is at {{ Source("dom/src/base/nsDOMClassInfo.cpp#4520", "nsDOMClassInfo.cpp") }}, around line 4520.
- 第二个例子是history对象。其他浏览器允许history对象被当作数组使用。比 如,history[1]。这种"象数组一样干活"的行为不可能在IDL本身中表现出来。幸运的是,XPConnect为我们提供了一种方式,让我们的类 在JavaScript中能被当作数组使用。我要说的是"scriptable标志"。由nsDOMClassInfo类实现的 nsIXPCScriptable接口定义了一些标志,其中一个是WANT_GETPROPERTY。当这个标志被设置,我们就能在 nsHistorySH(history对象的helper类)中定义一个GetProperty()方法。这个方法会处理数组行为。实际上,它将把 history[1]这样的调用翻译成history.item(1)。后者定义在IDL里,并且被容易地编码实现。对应的代码在 nsDOMClassInfo.cpp 里,大概在4520行左右。

- -

These two examples demonstrate the power of the DOM combined with XPConnect and the JavaScript engine. The possibilities are endless. "What do you want to code today?" ;-)

- -

这两个例子展示了DOM跟XPConnect以及JavaScript引擎结合的威力。可能性是无限的,“您今天想写些啥?”:)

- -

All the DOM classes are listed in an enum defined in {{ Source("dom/public/nsIDOMClassInfo.h", "nsIDOMClassInfo.h") }}, nsDOMClassInfoID. There are classes for the DOM0, Core DOM, HTML, XML, XUL, XBL, range, css, events, etc...

- -

所有的DOM类都在nsIDOMClassInfo.h中的一个枚举变量,nsDOMClassInfoID中被列出。这儿有DOM0的类,还有核心DOM,HTML, XML, XUL, XBL, range, css, events, 等等。

- -

The array sClassInfoData, defined in {{ Source("dom/src/base/nsDOMClassInfo.cpp", "nsDOMClassInfo.cpp") }}, maps each DOM class to its helper class and to the interfaces that are exposed to JavaScript. It is an array of type nsDOMClassInfoData, which is a structure defined in {{ Source("dom/public/nsIDOMClassInfo.h", "nsIDOMClassInfo.h") }}. The array uses two macros to define its items: NS_DEFINE_CLASSINFO_DATA and NS_DEFINE_CLASSINFO_DATA_WITH_NAME. The first one calls the second one. The first argument passed to NS_DEFINE_CLASSINFO_DATA_WITH_NAME, _class, is used for debug purposes. The second argument, _name, is the name that should appear in JavaScript. The third argument, _helper, is the name of the helper class for this DOM class. Helper classes are detailed in Section 1.3. The fourth and last argument, _flags, is a bitvector of nsIXPCScriptable flags. The macros for those flags are defined {{ Source("dom/src/base/nsDOMClassInfo.cpp", "nsDOMClassInfo.cpp") }}. The flags give special behavior through XPConnect. See also Section 1.9.

- -

The nsDOMClassInfoData objects are created in the sClassInfoData array by explicitly initializing it. Here is the description of the structure:

- - - -

nsDOMClassInfo.cpp中的sClassInfoData数组,将各个DOM类跟它的 helper类,还有将要暴露给JavaScript的接口对应起来。这是一个nsDOMClassInfoData类型的数 组,nsDOMClassInfoData是个结构体,定义在nsIDOMClassInfo.h里。这个数组使用
- 两个宏来定义它的子项:NS_DEFINE_CLASSINFO_DATA跟NS_DEFINE_CLASSINFO_DATA_WITH_NAME。前 者调用后者。传递给NS_DEFINE_CLASSINFO_DATA_WITH_NAME的第一个参数,_class,是用来调试的。第二个参 数,_name,是应该在JavaScript中使用的名字。第三个参数,_helper,是这个DOM类的helper类的名字。Helper类在 1.3节中详述。第四个也是最后一个参数,_flag,是一存放nsIXPCScriptable标志的比特向量。这些标志的宏定义在 nsDOMClassInfo.cpp里。这些标志通过XPConnect赋予特殊的行为。同见1.9节。
-
- sClassInfoData数组里的nsDOMClassInfoData对象通过明确的初始化动作来创建。这是这个结构的描述:

- - - - - -

mName and mConstructorFptr, mScriptableFlags and mHasInterface are initialized by NS_DEFINE_CLASSINFO_DATA_WITH_NAME. mCachedClassInfo, mProtoChainInterface and mInterfaces, however, are initialized in nsDOMClassInfo::Init(), described in Section 1.5.

- -

mName和mConstructorFptr,mScriptableFlags,还有 mHasInterfaces通过NS_DEFINE_CLASSINFO_DATA_WITH_NAME初始化,mCachedClassInfo, mProtoChainInterface 还有 mInterfaces通过nsDOMClassInfo::Init()来初始化。我们在1.5节中有描述。

- -

Interface flattening

- -

接口平坦化

- -

One of the nicest -- and most important -- features of the XPConnect'ed DOM is the interface flattening. "Interface flattening is the ability to call methods on an object regardless of the interface it was defined on." For example, when we have the document object in JavaScript, we can call indistinctly document.getElementById(), or document.addEventListener(), although they are defined on two different interfaces ({{ Source("dom/public/idl/core/nsIDOMDocument.idl", "DOMDocument") }} and {{ Source("dom/public/idl/events/nsIDOMEventTarget.idl", "DOMEventTarget") }}. Needless to say this is critical for the use of the DOM in real-world content.

- -

使用了XPConnect的DOM的功能中,最美妙也是最重要的一个是接口平坦化。“接口平坦化”是指调用 一个对象的方法而不必知道这个方法定义在哪个接口中。比如,如果我们在JavaScript中有个document对象,我们可以模糊地调用 document.getElementById(),或者document.addEventListener(),尽管它们定义在两个不同地接口里 (DOMDocument和DOMEventTarget。)不用说,这是在真实世界中使用DOM的最重要的东西。

- -

In Mozilla interface flattening is obtained through the use of the nsIClassInfo interface. nsIClassInfo stores the interfaces available for an object and later on XPConnect uses those interfaces to lookup the right method to call.

- -

在Mozilla中,接口平坦化是通过使用nsIClassInfo接口实现的。nsIClassInfo保存了一个对象可用的所有接口,随后XPConnect使用这些接口来寻找该调用的正确的方法。

- -

The great thing is that one can easily see the interfaces available from JS through interface flattening by looking at the code. The interesting part is in {{ Source("dom/src/base/nsDOMClassInfo.cpp", "nsDOMClassInfo::Init()") }}. There we have a long list of macros. There is one set of macros per DOM class. There you can see, for each object, what interfaces are part of the "flattened" set. As an example, on the window object, we can call all the methods defined on the following interfaces: nsIDOMWindow, nsIDOMWindowInternal, nsIDOMJSWindow, nsIDOMEventReciever, nsIDOMEventTarget, nsIDOMViewCSS, and nsIDOMAbstractView. Again, without caring on what interface the method is defined. See Section 1.5 for more information about the Init() method.

- -

好消息是人们可以通过看代码轻易地找到所有可以由JS调用的接口(拜接口平坦化所赐)。有趣的故事发生在拥 有一长列宏的nsDOMClassInfo::Init()中。每个DOM类都有一组宏。在这儿你可以看到,对于每个对象,它会列出一组接口,这就是“平 坦化”过的接口组合。比如,在window对象上,我们可以调用如下接口中的方法:nsIDOMWindow, nsIDOMWindowInternal, nsIDOMJSWindow, nsIDOMEventReciever, nsIDOMEventTarget, nsIDOMViewCSS, 还有nsIDOMAbstractView。同样,这种调用不用说明方法在哪个接口中定义。在1.5节中可以找到关于Init()方法的更多信息。

- -

For the W3C DOM (Level 1, 2, 3) objects, for each object there is one "standards-compliant" interface, which is exactly the same as the W3C one, named nsIDOM<ObjectName>.idl, and a mozilla-specific extension interface, named nsIDOMNS<ObjectName>.idl, for compatibility with DOM Level 0. For example, the HTML "area" element has the following interfaces in its flattened set: nsIDOMHTMLAreaElement and nsIDOMNSHTMLAreaElement.

- -

对于(1,2,3级)的W3C DOM对象,每个对象都有一个跟W3C完全一致的“符合标准”的接口,叫做nsIDOM<对象名>.idl,另外,为了跟DOM 0级别兼容,还有一个mozilla特有的扩展接口,叫做nsIDOMNS<对象名>.idl。举例来说,HTML"area"元素有下列的 平坦化接口:nsIDOMHTMLAreaElement和nsIDOMNSHTMLAreaElement。

- -

Helper ClassesHelper类

- -

nsDOMClassInfo.h defines several new classes. They all end in "SH", for "Scriptable Helper" e.g. nsWindowSH, nsElementSH, ... . We call these classes the "Helper Classes". All the helper classes inherit from the nsDOMClassInfo class. To demonstrate this, look in {{ Source("dom/src/base/nsDOMClassInfo.h", "nsDOMClassInfo.h") }}. We can see that the nsEventRecieverSH helper class inherits from nsDOMGenericSH:

- -

nsDOMClassInfo.h定义了几个新类。它们都用"SH"结尾,意思是“Scriptable Helper(脚本化帮助类)”,比如,nsWindowSH,nsElementSH,...我们把这些类叫做帮助类。所有这些帮助类都继承自 nsDOMClassInfo类。为了展示这个,看看nsDOMClassInfo.h。我们会看到nsEventRecieverSH帮助类继承自 nsDOMGenericSH:

- -
class nsEventRecieverSH : public nsDOMGenericSH
-
- -

And nsDOMGenericSH is typedef'ed to nsDOMClassInfo:

- -

nsDOMGenericSH是nsDOMClassInfo的别名:

- -
typedef nsDOMClassInfo nsDOMGenericSH;
-
- -

Another example is nsWindowSH, which inherits from nsEventReceiverSH, thus inheriting from nsDOMClassInfo.

- -

另一个例子是nsWindowSH,它继承自nsEventReceiverSH,从而继承自nsDOMClassInfo。

- -

Each DOM class is mapped to its helper class during the initialization of the sClassInfoData array.

- -

每个DOM类通过sClassInfoData数组的初始化映射到它的帮助类。

- -

Each helper class has a public doCreate member function that is called by GetClassInfoInstance (see also Section 1.6) to create a new instance of the class if needed. Remember that the doCreate member function is called through a pointer to a function named mConstructorFptr, a member of the nsDOMClassInfoData struct. An instance of a helper class is created the first time XPConnect needs access to the flattened set of interfaces of an object. The instance is then cached for further use.

- -

每个帮助类都有一个公开的doCreate成员方法,它被GetClassInfoInstance调用 (见1.6节)来在需要的时候创建类实例。记住doCreate方法是通过一个叫做mConstructorFptr的函数指针来调用的。 mConstructorFptr是nsDOMClassInfoData结构的一个成员。一个帮助类的实例会在XPCOM第一次需要访问某对象的平坦化 的接口组时被创建。然后这个接口被缓存起来,以备后用。

- -

Most of the helper classes implement one or more nsIXPCScriptable methods. Those methods are used by XPConnect when we require something from JavaScript that was not defined in IDL. For example, GetProperty() is used when retrieving an attribute that was not defined in IDL, and NewResolve() is used when resolving for the first time an attribute or method that was not previously resolved. Please see the {{ Source("js/src/xpconnect/idl/nsIXPCScriptable.idl", "nsIXPCScriptable interface") }} for more information.

- -

这些帮助类的绝大部分实现了一个或多个nsIXPCScriptable接口中的方法。这些方法在我们需要 从JavaScript获取某些没有在IDL中定义的东西时会被XPConnect用到。比如,GetProperty()用来获取某个没有在IDL中定 义的属性。NewResolve()在第一次解析某个之前没有被解析过的属性或者方法时被调用。细节参见nsIXPCScriptable接口。

- -

The nsDOMClassInfo class  nsDOMClassInfo类

- -

The heart of Class Info is the nsDOMClassInfo class, defined in {{ Source("dom/src/base/nsDOMClassInfo.h", "nsDOMClassInfo.h") }}. It implements two interfaces besides nsISupports: {{ Source("js/src/xpconnect/idl/nsIXPCScriptable.idl", "nsIXPCScriptable") }} and {{ Source("xpcom/components/nsIClassInfo.idl", "nsIClassInfo") }}.

- -

Class Info的关键处在于nsDOMClassInfo类,它定义在nsDOMClassInfo.h中。除了nsISupports外,它还实现了两个接口:nsIXPCScriptable和nsIClassInfo。

- -

We already know what nsIXPCScriptable is used for (see the previous Section).

- -

我们已经知道nsIXPCScriptable是干嘛的了(见前节)

- -

nsIClassInfo is an XPCOM interface, very well described by Mike Shaver in this overview of nsIClassInfo. Basically it contains convenient methods to find out about the interfaces an object promises to support. In our case, this list of interfaces will be populated by "Class Info". See also Section 1.5 on the Init() function and Section 1.2 on interface flattening.

- -

nsIClassInfo是个XPCOM接口,在Mike Shaver 对nsIClassInfo的概述中已经描述得很清楚了。基本上来说,它包含了一些便利的方法,用来寻找一个对象承诺要支持的接口。在我们的情况下,这些 接口会通过“Class Info”导出。见1.5节对Init()方法的描述,还有1.2节对接口平坦化的描述。

- -

We saw in Section 1.3 that nsDOMClassInfo is the base class for all the helper classes. Let's see what it's made of. Let's begin with the public interface.

- -

在1.3节中,我们已经说过了nsDOMClassInfo是所有帮助类的基类。我们来看看它的组成,从公开接口开始。

- - - - - -

Protected section:保护函数 :

- - - - - - - -

nsDOMClassInfo::Init()

- -

This method is to be called only once. Its purpose is, well, to initialize... It does a lot of different things: Fill the blanks in the sClassInfoData array, initialize the sXPConnect and sSecMan data members, create a new JavaScript Context, define the JSString data members, and register class names and class prototypes. Finally it sets sIsInitialized to true. The actions that concern the DOM are described below.

- -

这个方法只调一次。它的目的是:好吧。。初始化。。。它干了很多不同的事,填写 sClassInfoData数组中的空白,初始化sXPConnect和sSecMan数据变量,创建一个新的JavaScript context,定义JSString数据成员,注册类名和类原型。最后,它把sIsInitialized设成true。跟DOM有关系的行为描述如 下:

- -

First, the call to CallGetService() initializes sXPConnect. Then the Script Security Manager (sSecMan) is initialized. GetSafeJSContext() grabs us a cool JS context to run our JavaScript code in. The part about ComponentRegistrar is designed to allow external modules (in this case XPath) to be included in DOMClassInfo and as such benefit from the JavaScript benefits it provides. After that, we fill the blanks in the sClassInfoData array.

- -

首先,它调用CallGetService()来初始化sXPConnect。然后脚本安全管理器 (sSecMan)被初始化。GetSafeJSContext()为我们获取一个挺不错的JS Context来跑我们的JavaScript代码。跟ComponentRegistrar有关的部分被设计成允许外部模块(在本例中是XPath)被 DOMClassInfo引用,以便从JavaScript提供的好处中得益。然后,我们填充sClassInfoData数组。

- -

If you remember the discussion in the introduction to Class Info, there is the main array, sClassInfoData, filled with objects of type nsDOMClassInfoData. However when the array is created, three data members of the structure are left as null pointers: mCachedClassInfo, mProtoChainInterface, and mInterfaces. Init() uses a set of macros to fill the blanks: the DOM_CLASSINFO_MAP family. Each DOM class needs to use these macros, otherwise bad things will happen. I will use the example of the Window class to illustrate the use of the macros. Here is the relevant piece of code.
- 如果你记得在介绍Class Info时的讨论的话,这个主数组,sClassInfoData,填充了一些nsDOMClassInfoData类型的对象。然而当数组被创建的时 候,这个数据结构的三个数据成员被保留为空指针:mCachedClassInfo, mProtoChainInterface, 还有mInterfaces。Init()使用一组宏来填补空白:DOM_CLASSINFO_MAP家族。每个DOM类都要使用这些宏,否则就会遭遇不 测。我会使用Window类来演示这些宏的使用。以下是相关的代码片断。

- -
DOM_CLASSINFO_MAP_BEGIN(Window, nsIDOMWindow)
-DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow)
-...
-DOM_CLASSINFO_MAP_ENTRY(nsIDOMAbstractView)
-DOM_CLASSINFO_MAP_END
-
- -

DOM_CLASSINFO_MAP_BEGIN(_class, _interface) maps to _DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), PR_TRUE). NS_GET_IID is a macro that expands to the IID of the interface passed in. We pass the address of this nsIID object to the second macro.

- -

DOM_CLASSINFO_MAP_BEGIN(_class, _interface) 被映射到_DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), PR_TRUE). NS_GET_IID是个宏,展开后,它表示被传入的接口的IID。我们把这个nsIID对象的地址传给第二个宏。

- -
#define _DOM_CLASSINFO_MAP_BEGIN(_class, _ifptr, _has_class_if)
-{
-nsDOMClassInfoData &d = sClassInfoData[eDOMClassInfo_##_class##_id];
-d.mProtoChainInterface = _ifptr;
-d.mHasClassInterface = _has_class_if;
-static const nsIID *interface_list[] = {
-
- -

In this macro, |d| is a reference to the entry of the sClassInfoData array that corresponds to the class passed as an argument to the macro. The mProtoChainInterface member pointer is initialized to the address of the IID of the interface passed as an argument to DOM_CLASSINFO_MAP_BEGIN. A static array of pointers to objects of type nsIID is then declared. It is initialized explicitly with the DOM_CLASSINFO_MAP_ENTRY macro (see below).

- -

在这个宏里面,[d]是个到sClassInfoData数组中某一项的引用。这个项是通过作为参数传给宏 的类来确定的。mProtoChainInterface成员指针被初始化成接口的IID的地址,这个接口被作为参数传递给 DOM_CLASSINFO_MAP_BEGIN宏。然后,声明了一个静态指针数组,指针指向nsIID类型的对象。它显式地用 DOM_CLASSINFO_MAP_ENTRY宏初始化。(见下)

- -

There are two other similar macros:

- -

下面是其他两个类似的宏:

- -
#define DOM_CLASSINFO_MAP_BEGIN_NO_PRIMARY_INTERFACE(_class)
-_DOM_CLASSINFO_MAP_BEGIN(_class, nsnull, PR_TRUE)
-
- -

This macro is used if the DOM class (for example XMLHTTPRequest) does not have any interface, yet you want the XMLHTTPRequest object to be available from JavaScript.

- -

这个宏在DOM类(比如XMLHTTPRequest),没有任何接口时使用。如果你希望XMLHTTPRequest对象在JavaScript中可用的话。

- -
#define DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(_class, _interface)
-_DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), PR_FALSE)
-
- -

This macro should be used for DOM classes that have no "leaf" interface. For example, there is no HTMLSpanElement in the W3C DOM specification. Therefore, the first interface in the prototype chain for the span element is HTMLElement. However we do want to be able to access HTMLSpanElement to modify it. This macro allows you to do that. See {{ Bug(92071) }} for more information. Let's now see how to specify the interfaces available from JavaScript for a particular DOM class.

- -

这个宏在DOM类没有"叶子"接口的时候使用。比如,在W3C DOM 中没有HTMLSpanElement的定义。因此在原型链中的第一个接口会是HTMLElement。但是,我们确实希望能够拿到 HTMLSpanElement并修改它。这个宏让你可以干这些。参见bug 92071。现在我们来看看如何为一个特定的DOM类声明它能够在JavaScript中使用的接口。

- -
#define DOM_CLASSINFO_MAP_ENTRY(_if)
-&NS_GET_IID(_if),
-
- -

The array of pointers interface_list is filled with the addresses of the IID's of all the interfaces passed as arguments to the macro. In our Window example, the interfaces are nsIDOMWindow, nsIDOMJSWindow, nsIDOMWindowInternal, nsIDOMEventReciever, nsIDOMEventTarget, nsIDOMViewCSS, and nsIDOMAbstractView. Please see Section 1.2 on interface flattening for an explanation of the use of these interfaces. The initialization for a class is finished by the DOM_CLASSINFO_MAP_END macro.

- -

这个指针数组interface_list里面保存了所有作为参数传递给宏的接口的IID的地址。在我们的 Window范例中,这些接口是nsIDOMWindow, nsIDOMJSWindow, nsIDOMWindowInternal, nsIDOMEventReciever, nsIDOMEventTarget, nsIDOMViewCSS, 还有 nsIDOMAbstractView。参见1.2节(接口平坦化)中对这些接口使用的解释。对一个类的初始化工作以 DOM_CLASSINFO_MAP_END宏结束。

- -
#define DOM_CLASSINFO_MAP_END
-nsnull
-};
-d.mInterfaces = interface_list;
-}
-
- -

The interface_list array is terminated by a null pointer. The line d.mInterfaces = interface_list assigns to mInterfaces the address of the first element of the interface_list array, which is itself a pointer. mInterfaces is thus correctly a pointer to a pointer to an object of type nsIID.

- -

interface_list数组以空指针结尾。d.mInterfaces = interface_list这一行把interface_list数组的第一个元素的地址赋给mInterfaces。mInterfaces本身也是 一个指针。mInterfaces现在被正确地初始化成了一个指向一个nsIID类型的对象的指针的指针。

- -

To define the jsvals, Init() simply calls DefineStaticJSVals(). To register the class names and class protos, Init() simply calls RegisterClassProtos and RegisterClassNames. This process might be described in a later document. Finally, sIsInitialized is set to true. Init() returns NS_OK if everything went fine.
- 为了定义jsvals,Init()简单地调用DefineStaticJSVals()。为了注册类名和 类原型。Init()简单地调用RegisterClassProtos和RegisterClassNames。这个流程会在稍后的文档中被描述。最 后,sIsInitialized被置真。Init()返回 NS_OK表示一切顺利。

- -

nsDOMClassInfo::GetClassInfoInstance()

- -

There are two versions of this function. The first one takes an ID as argument, the second takes a Data struct as argument. This function is very important so let's take a closer look at it. Here is the function definition.

- -

这个函数有两个版本。第一个接收一个ID作为参数,第二个接收一个数据结构作为参数。这个函数很重要,所以我们仔细看看它。这是函数定义:

- -
nsIClassInfo* nsDOMClassInfo::GetClassInfoInstance(nsDOMClassInfoID aID)
-{
-if(!sIsInitialized) {
-nsresult rv = Init();
-}
-
-if(!sClassInfoData[aID].mCachedClassInfo) {
-nsDOMClassInfoData &data = sClassInfoData[aID];
-data.mCachedClassInfo = data.u.mConstructorFptr(&data);
-NS_ADDREF(data.mCachedClassInfo);
-}
-
-return sClassInfoData[aID].mCachedClassInfo;
-}
-
- -

Here is the short explanation:

- -

这是简短版解释:
- This method returns the mCachedClassInfo member of the nsDOMClassInfoData structure that corresponds to aID in the sClassInfoData array, if it exists, i.e. if this method has been called before. If it is called for the first time however, mCachedClassInfo is still a null pointer, and the function will create a new instance of the relevant helper class, and cache it in the mCachedClassInfo pointer, then return it.

- -

这个函数按照对应的aID,从sClassInfoData数组中取出一个 nsDOMClassInfoData结构的对象,然后返回这个结构的一个成员mCachedClassInfo。如果这是第一次调 用,mCachedClassInfo还是空指针,这个函数会创建一个对应的帮助类,然后将mCachedClassInfo指向这个缓存,然后返回它。

- -

And for those interested, here the longer explanation.

- -

对于那些感兴趣的人,这是加长版的解释:

- -

The first time GetClassInfoInstance() is called, passing in an aID, mCachedClassInfo for that class will still be null. The body of the "if" clause is thus executed. We initialize "data" to be a reference to the nsDOMClassInfoData object that corresponds to the DOM class we want to "help". On the next line, there is a call to data.mConstructorFptr(aID), which, if you remember the introduction to Class Info, maps to the doCreate static member function of the relevant helper class. doCreate creates a new instance of the helper class, and returns a pointer to the nsIClassInfo interface, which is then assigned into mCachedClassInfo. mCachedClassInfo is AddRef'ed to keep it from being destroyed without our permission. Finally it is returned.

- -

GetClassInfoInstance()第一次被调用的时候,一个aID被传进来,这个类的 mCachedClassInfo还是空的,if语句的本体被执行。我们把data初始化成一个nsDOMClassInfoData对象的引用。这个对 象对应于我们想要“帮助”的DOM类。下一行,我们调用了data.mConstructorFptr(aID),这一行,如果你记得Class Info的介绍的话,被映射成对应的帮助类的doCreate静态成员变量。doCreate创建帮助类的一个实例,然后返回一个到 nsIClassInfo接口的指针。这个指针被赋值给mCachedClassInfo。mCachedClassInfo被增加一个引用,以避免不经 我们的允许被删除。最后这个指针被返回。

- -

On subsequent calls to this function with the same aID passed in, mCachedClassInfo will still be there, and thus the creation of a new helper class will not be necessary.

- -

下次这个函数被调用(用同一个aID参数),mCachedClassInfo还在那儿,所以就不用再创建新的帮助类了。

- -

"Where is GetClassInfoInstance used and why should I use it", would be an excellent question for now. The short answer is, "to implement the QueryInterface for nsIClassInfo". Indeed, a QueryInterface to nsIClassInfo cannot be implemented the same way as other interfaces. If you don't like macros, you can see the full QueryInterface implementation in {{ Source("content/xml/content/src/nsXMLElement.cpp", "nsXMLElement.cpp") }}. Two other GetClassInfoInstance member functions are defined in Mozilla, as member of class nsContentUtils and class nsDOMSOFactory. Both of these methods end up calling nsDOMClassInfo::GetClassInfoInstance so there is no real point in documenting them further. GetClassInfoInstance is used in the NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO macro, which is used to implement QueryInterface for the nsIClassInfo interface in {{ LXRSearch("ident", "i", "NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO", "most of the DOM classes") }}, and in the NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO macro, which is used to implement QueryInterface for the nsIClassInfo interface in most {{ LXRSearch("ident", "i", "NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO", "global object properties") }}.

- -

"GetClassInfoInstance在哪儿用到,为什么我需要用它"现在可能是个好问题。简短的回 答是:“为nsIClassInfo实现QueryInterface”。实际上,nsIClassInfo的QueryInterface方法不能象其 他接口那样实现。如果你不喜欢宏,你可以看看nsXMLElement.cpp中QueryInterface的完整实现。Mozilla中定义了另外两 个GetClassInfoInstance成员函数,作为nsContentUtils和nsDOMSOFactory的成员。所有这些方法都不调 nsDOMClassInfo::GetClassInfoInstance了,所以现在讲这些也没啥意义了。GetClassInfoInstance 用在NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO宏里,在大部分DOM类中,这个宏用来为 nsIClassInfo接口实现QueryInterface方法。这个函数还用在 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO 宏里,这个宏用来为大部分全局对象属性实现QueryInterface方法。

- -

I think that's all there is to say about this function. If you think of something else don't hesitate to contact me, as usual.

- -

我觉得这就是关于这个函数所有要讲的事了。如果你觉得还有什么要讲的话,请象平时一样,不要犹豫,过来找我。

- -

nsWindowSH::GlobalResolve()

- -

This Section will describe in detail the absolutely horrific GlobalResolve() member function of the nsWindowSH helper, as an example of those functions. This is not for the faint of heart, and is not absolutely necessary, so you might want to skip this Section if you don't have too much time (and I suppose you don't).

- -

作为这些功能的一个范例,这一节将讲到nsWindowSH帮助类的GlobalResolve()成员函数的极其可怕的细节。这不是为了惊吓你可怜的小心脏,也不是非常必要,所以如果你时间不够的话,也许你会希望跳过本节(当然我希望你不会)。

- -

User's guide to Class Info

- -
-

Warning: this document has not yet been reviewed by the DOM gurus, it might contain some errors. Specifically, due to some changes that happened around, April 2002, some things that were not possible before are now possible. I will try to update this guide as soon as possible. Please send any comment to Fabian Guisset.

-
- -

When should DOMClassInfo be used

- -

什么时候DOMClassInfo会被用到

- - - - - -

Example of functionality implemented using DOMClassInfo:

- -

使用DOMClassInfo完成的功能:

- - - - - -

How to add a new interface to an existing DOM object

- -

如何为已有的DOM对象添加一个新的接口

- -
-

For this Section, we will use the simple example of the DOMImplementation DOM object. This is a real-world case that was used to solve bug 33871 (the patch is not checked in yet, as of writing this document). The problem is the following: We have to add a new HTMLDOMImplementation interface to the DOMImplementation DOM object. The DOMImplementation object is used when one does, in JS, document.implementation. This object already implements the DOMImplementation interface, but DOM2 HTML says it should also implement the HTMLDOMImplementation interface, so here we go. The C++ implementation is in nsDocument.cpp. The first step is of course to do the C++ implementation of the interface, which is described in the intro to XPCOM document.

- -

本节中,我们会使用DOM对象DOMImplementation的一个简单的例子。这是一个真实的案例, 用来解决bug 33871(截止到写这篇文档的时候,patch还没有上传)。这个问题是这样的:我们必须为DOM对象DOMImplementation添加一个新的 HTMLDOMImplementation接口。DOMImplementation在人在JS中调用document.implementation 时被用到。这个对象已经实现了DOMImplementation接口,但是DOM2 HTML标准说它还应该实现HTMLDOMImplementation接口,这就是我们要干的活。它的C++实现是nsDocument.cpp,第一 步当然是象在XPCOM文档中的介绍那样,用C++实现这个接口。

- -

Let's assume nsDOMImplementation now implements the nsIDOMHTMLDOMImplementation interface (look in bug 33871 if you want to know how to do that). We want to expose this interface to JavaScript (otherwise only XPCOM callers will be able to access this interface). To do that, we have to add it to the DOMClassInfo of the DOMImplementation DOM object.

- -

不妨假设nsDOMImplementation现在实现了 nsIDOMHTMLDOMImplementation接口(如果你要知道怎么做到这一点的话,参见bug 33871),我们希望把这个接口暴露给JavaScript(否则只有XPCOM调用者才能访问到这个接口)。为了做到这一点,我们必须把它加到DOM 对象nsIDOMHTMLDOMImplementation的DOMClassInfo里面去。

-
- -
Benefits
- - - -

 好处
-  

- - - -
What there is to do
- -
    -
  1. Include the new interface definition in nsDOMClassInfo.cpp:
    - #include "nsIDOMHTMLDOMImplementation.h".
    - Put it where you think it fits the most.
  2. -
  3. Find the code where all the interfaces implemented by the relevant DOM object are implemented. This is in the nsDOMClassInfo::Init() method.
  4. -
  5. For DOMImplementation, this is around line 1220 (at the time of writing this document):
    - 1224 DOM_CLASSINFO_MAP_BEGIN(DOMImplementation, nsIDOMDOMImplementation)
    - The next line specifies that the DOMImplementation object implements the nsIDOMDOMImplementation interface.
  6. -
  7. Add the new interface to the DOMClassInfo definition. For us, it is:
    - 1225 DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDOMImplementation)
  8. -
  9. Add the new interface to the makefiles, manifests, etc.
  10. -
  11. Recompile.
  12. -
  13. Nuke components.reg if you build optimized.
  14. -
  15. Wonder at the beauty of DOMClassInfo.
  16. -
- -

要做些什么:
-
-    1. 在nsDOMClassInfo.cpp加入新接口的定义:
-       #include "nsIDOMHTMLDOMImplementation.h".
-       把它放在你觉得最合适的地方
-    2. 找到所有被相关的DOM对象实现的接口被实现的地方。在 nsDOMClassInfo::Init()方法里。
-    3. 对于DOMImplementation来说, 它大概在1220行 (本文档写作时):
-       1224 DOM_CLASSINFO_MAP_BEGIN(DOMImplementation, nsIDOMDOMImplementation)
-      下面几行声明了DOMImplementation对实现了nsIDOMDOMImplementation接口。
-    4. 向DOMClassInfo定义添加新接口,对于我们来说,应该是:
-       1225 DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDOMImplementation)
-    5. 把新接口添加到makefiles, manifests,等等。
-    6. 重新编译。
-    7. 手动修改components.reg,如果你打开了编译优化选项。
-    8. 惊叹DOMClassInfo的美妙之处。

- -

How to expose a new DOM object to JavaScript

- -

如何向JavaScript暴露一个新的DOM对象

- -

Let's now go a step further. Not only do we want to add a new interface to an object, but we also want to expose a completely new object to JavaScript. DOMClassInfo does almost everything for you, from prototypes to implementing a default ToString() method on your object.

- -

现在让我们更进一步。现在我们不但想要向一个对象添加一个新的接口,我们还想向JavaScript暴露一个新对象。DOMClassInfo几乎为你完成了所有的事,从要实现的原型到为你的对象实现一个默认的ToString()方法。

- -
-

We will again take the example of the DOMImplementation object. It is accessible using document.implementation. It is defined in the W3C DOM Level 1 Core spec. The requirements include that the global constructor DOMImplementation be accessible, that the ToString() method called on an instance of a DOMImplementation return "DOMImplementation", and that it implements the following methods: hasFeature() (DOM1), createDocumentType() and createDocument() (DOM2).

- -

这次我们还用DOMImplementation对象为例。它可以调用 document.implementation获取。它定义在W3C DOM级别1核心规范中。对它的要求包括它的全局构造函数DOMImplementation必须是可访问的,对一个DOMImplementation 实例调用ToString()必须返回"DOMImplementation",它还必须实现如下方法:hasFeature() (DOM1), createDocumentType() 还有 createDocument() (DOM2).

-
- -
What there is to do
- -

我们要做什么:

- -
    -
  1. Implement your object in C++. This is not in the scope of this document. The best thing you can do is probably to copy existing code. A DOM object is a simple XPCOM object with DOMClassInfo. In our example, the implementation class is nsDOMImplementation (in nsDocument.cpp). It implements the nsIDOMDOMImplementation interface (which contains the three methods mentionned above).
  2. -
  3. Modify the QueryInterface implementation of your XPCOM object to include DOMClassInfo data. Add the following line at the end of the QueryInterface implementation:
    - NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(dom_object_name)
    - For the DOMImplementation object, the line would be:
    - NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DOMImplementation)
    - What does it do? It's the QueryInterface implementation for the nsIClassInfo interface, which is requested internally by XPConnect. Basically it will create an instance of the scriptable helper class for this DOM object. More on this subject in the rest of this document.
  4. -
  5. Add the DOM object DOMClassInfo in the sClassInfoData array (nsDOMClassInfo.cpp): -
    NS_DEFINE_CLASSINFO_DATA(dom_object_name, scriptable_helper_class,
    -scriptable_flags)
    -
    - -

    For the DOMImplementation object, the lines would be:

    - -
    NS_DEFINE_CLASSINFO_DATA(DOMImplementation, nsDOMGenericSH,
    -DOM_DEFAULT_SCRIPTABLE_FLAGS)
    -
    - The place where you have to add the DOMClassInfo in that array should be obvious. If it is not, ask Johnny Stenback.
  6. -
  7. Add the DOM object DOMClassInfo in the nsDOMClassInfo::Init() method (nsDOMClassInfo.cpp): -
    DOM_CLASSINFO_MAP_BEGIN(dom_object_name, dom_object_main_interface)
    -DOM_CLASSINFO_MAP_ENTRY(interface1)
    -DOM_CLASSINFO_MAP_ENTRY(interface2)
    -...
    -DOM_CLASSINFO_MAP_END
    -
    - -

    For the DOMImplementation object, the lines would be:

    - -
    DOM_CLASSINFO_MAP_BEGIN(DOMImplementation, nsIDOMDOMImplementation)
    -DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMImplementation)
    -DOM_CLASSINFO_MAP_END
    -
    - The interface1, interface2, ... arguments are the name of the interfaces implemented by the DOM object AND exposed to JavaScript. The internal interfaces should NOT be a part of this list.
  8. -
  9. #include the relevant files to make it build, tweak the makefiles, etc. Make sure it builds on all platforms! :-P
  10. -
  11. If you used an already existing scriptable helper class, then all you need to do is build, nuke components.reg (if you build optimized) and run. Everything should work well.
  12. -
  13. If you want to use a new scriptable helper class, you will have to implement it as well.
  14. -
- -

1.用C++实现你的对象。这不在本文档的范围,你最好拷贝已经存在的代码。一个DOM对象是一个具有DOMClassInfo的简单的XPCOM对象。 在我们的例子中,实现类是nsDOMImplementation(在nsDocument.cpp)中。它实现了 nsIDOMDOMImplementation接口(它包含我们上面提到过的三个方法)。

- -

2.2.修改你的XPCOM对象的QueryInterface实现,以便包含DOMClassInfo数据。在QueryInterface实现的末尾加入下面几行:
- NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(dom_object_name)
- 对于DOMImplementation对象,这行会是:
- NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DOMImplementation)
- What does it do? It's the QueryInterface implementation for the nsIClassInfo interface, which is requested internally by XPConnect. Basically it will create an instance of the scriptable helper class for this DOM object. More on this subject in the rest of this document.
- 这行是干嘛的?它是nsIClassInfo接口的QueryInterface实现,这个也是XPConnect内部要求的。基本上,它会为DOM对象创建一个Scriptable的帮助类。这个主题的更多内容见本文档的余下部分。

- -

 3. 把DOM对象DOMClassInfo加到sClassInfoData数组 (nsDOMClassInfo.cpp):
-
-       NS_DEFINE_CLASSINFO_DATA(dom_object_name, scriptable_helper_class,
-       scriptable_flags)

-
-       对于DOMImplementation对象, 这几行应该是:
-
-       NS_DEFINE_CLASSINFO_DATA(DOMImplementation, nsDOMGenericSH,
-       DOM_DEFAULT_SCRIPTABLE_FLAGS)

-
-      你应该很清楚应该把DOMClassInfo加到数组的哪个位置,如果搞不清的话,问Johnny Stenback。

- -

4. 把DOM对象的DOMClassInfo加到nsDOMClassInfo::Init()方法里(nsDOMClassInfo.cpp):
-
-       DOM_CLASSINFO_MAP_BEGIN(dom_object_name, dom_object_main_interface)
-       DOM_CLASSINFO_MAP_ENTRY(interface1)
-       DOM_CLASSINFO_MAP_ENTRY(interface2)
-       ...
-       DOM_CLASSINFO_MAP_END

-
-      
对于DOMImplementation对象, 这几行应该是:
-
-       DOM_CLASSINFO_MAP_BEGIN(DOMImplementation, nsIDOMDOMImplementation)
-       DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMImplementation)
-       DOM_CLASSINFO_MAP_END

-
-       interface1, interface2, ... 参数是DOM对象实现的接口以及向JavaScript暴露的接口的并集。内部接口不应该包含在这个接口中。

- -

5. 用#include包含相关文件让它能构建成功,修改makefiles,等等。 确保它能在所有平台下通过编译:-P
- 6. 如果你用的是个已有的scriptable帮助类的话,你要做的所有事就是构建,修改components.reg(如果你打开了编译优化选项),然后运行。一切都会运作良好。
- 7. 如果你需要一个新的scriptable帮助类,你就得实现它。

- -

How to override the default behavior of XPConnect on DOM objects

- -

如何覆盖XPConnect对DOM对象的默认处理

- -

XPConnect implements default behaviors for XPCOM objects in general, and for DOM objects in particular. DOMClassInfo allows the implementor to override this default behavior using the nsIXPCScriptable interface. Before we begin, please take a look at the nsIXPCScriptable.idl file. It defines a set of constants, called the "scriptable flags", and a set of functions, like NewResolve(), SetProperty(), ... Each flag corresponds to one function. For example, nsIXPCScriptable::WANT_NEWRESOLVE means that we want to implement the NewResolve() function. The important thing to grasp is that each function corresponds to an event in the life of the DOM object. For example, the SetProperty() function is called automatically by XPConnect when, in JS, the client tries to set a property on this DOM object. This is how we can override the default "set this property on this object" XPConnect behavior. For more information about each nsIXPCScriptable function, please see the nsIXPCScriptable documentation.

- -


- XPConnect为XPCOM对象实现默认行为,这种实现是一般化的。但对于DOM对象,这实现是特定的。DOMClassInfo允许用 nsIXPCScriptable接口的实现来覆盖默认行为。在我们开始前,请看看nsIXPCScriptable.idl文件。它定义了一组常量,叫 做“scriptable标志位”,还有一组函数,比如NewResolve(),SetProperty()...每个标志位对应一个函数。比 如,nsIXPCScriptable::WANT_NEWRESOLVE表示我们希望实现NewResolve()函数。重要的是,要清楚每个函数对应 着DOM对象声明周期中的一个事件。比如,当在js里,客户端试图给DOM对象赋值时,XPConnect会自动调用SetProperty()方法。所 以我们能覆盖默认的“给对象属性赋值”这个XPConnect行为。要获取每个nsIXPCScriptable函数的信息,请参考 nsIXPCScriptable文档。

- -
-

To illustrate the use of nsIXPCScriptable and scriptable helper functions, we will take the example of the "location" property of the window object. window.location is a DOM object of type "Location". However a common technique is to do window.location = "http://mozilla.org" instead of the correct window.location.href = "http://mozilla.org". So, we have to override the default behavior of "setting the location property on the window object". The default behavior would be that XPConnect expects a nsIDOMLocation object. However it would be passed a JS string. A bad conversion exception would be thrown.

- -

为了演示nsIXPCScriptable的用法和scriptable帮助类的功能,我们会举 window对象的location属性为例。window.location是个“Location”类型的DOM对象。但是,一个常用的技法是,使用 window.location = "http://mozilla.org",而不是正确的用法:window.location.href = "http://mozilla.org"。所以,我们必须覆盖默认的“设置window对象的location属性”行为。默认的行为 是,XPConnect期望得到一个nsIDOMLocation对象,但是,它会拿到一个JS字符串,一个错误转型的异常将被抛出。

-
- -

Before we start looking at the implementation of the nsIXPCScriptable interface, the implementor needs the following information:

- - - -

在我们开始看nsIXPCScriptable接口的实现前,实现者必须知道下列信息:
-
-
-     * 它关联到什么DOM object
-     * 什么行为希望被覆盖
-     * 应该发生什么

- -

For our example, it is the window object. The action is setting a property. What should happen is that setting .location should set .location.href. With that information in hand, we can start coding.

- -

对于我们的范例,关联的对象是window对象。行为是设置属性。希望发生的事情是对.location的设置应该被设置到.location.href上。这一信息在手,我们可以开始编码了。

- -
What there is to do
- -
    -
  1. Locate the DOM object ClassInfo data in the sClassInfoData array. In our example, it is the Window object. The three parameters passed to the macro, as described in the previous Section, are the DOM object name, the scriptable helper class, and the scriptable flags.
  2. -
  3. The scriptable flags tell you which nsIXPCScriptable interfaces are implemented by this DOM object. If the flag you need is already there, then go on to the next step. Else, add it to the flag list.
  4. -
  5. Remember the name of the scriptable helper class for this object. For most objects, it is the nsDOMGenericSH class, which is just a typedef for the nsDOMClassInfo class. If your DOM object does not require any special-casing, then the scriptable helper for your object should be nsDOMGenericSH. If you need special-casing, scroll to the implementation of the helper class.
    - In our example, it's the nsWindowSH class.
  6. -
  7. If the helper class already implements the nsIXPCScriptable function you need, go on to the next step. Else, implement this new method, using the arguments described in the nsIXPCScriptable interface.
  8. -
  9. Now comes the interesting part. It is unfortunately impossible to describe all the uses of the scriptable helpers, you will have to use your coding skills and/or copy existing code. We will however describe the implementation of our example, the window.location property.
  10. -
- -

我们需要做什么

- -

  1.在sClassInfoData数组中找到DOM对象的ClassInfo数据。在我们的例子中,是Window对象。如前所述,三个传递给宏的参数是DOM对象名称,scriptable帮助类,还有scriptable标志。
-
-    2.scriptable标志告诉你应该为DOM对象实现那些nsIXPCScriptable接口方法。如果你需要的标志位已经在那儿了,就跳到下一步,否则,把它加到标志列表中。
-
-    3。记住这个对象的scriptable帮助类的名字。对于大多数对象,会是nsDOMGenericSH类,那是nsDOMClassInfo类的一个 别名。如果你的DOM对象不需要特殊处理,那你的scriptable帮助类就会是nsDOMGenericSH,如果你需要特殊处理,翻到你的帮助类的 实现部分。在我们的例子中,是nsWindowSH类。
-
-    4.如果帮助类已经实现了你需要的nsIXPCScriptable函数,跳到下一步,否则,使用nsIXPCScriptable接口中描述的参数实现该函数。
-
-   5。现在到了有趣的部分了。不幸的是,不大可能描述scriptable帮助类的所有用法。你可能需要使用你的编程技巧或者/还有拷贝已有的代码。不管怎么说,我们会描述我们例子的实现,window.location属性。

- -
The window.location implementation
- -

window.location实现

- -

Overriding the setter of a property requires two scriptable flags: WANT_NEWRESOLVE and WANT_SETPROPERTY. NewResolve() will define the property on the object using the JS API, the second one will map .location to .location.href. As of writing this document, the code in nsWindowSH::NewResolve() looks like this: (nsDOMClassInfo.cpp)

- -

覆盖属性的获取方法需要两个scriptable标志:WANT_NEWRESOLVE 和 WANT_SETPROPERTY,NewResolve()会用JS API定义这个对象的属性。第二个会把.locaiton映射到.locaiton.href。截止到写这篇文档的时 候,nsWindowSH::NewResolve() 中的代码看起来是这样:(nsDOMClassInfo.cpp)

- -
3553     if (flags & JSRESOLVE_ASSIGNING) {
-// Only define the property if we are setting it.
-3554       if (str == sLocation_id) {
-// Setting the location property.
-3555         nsCOMPtr<nsIDOMWindowInternal>
-window(do_QueryInterface(native));
-3556         NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
-3557
-3558         nsCOMPtr<nsIDOMLocation> location;
-3559         rv = window->GetLocation(getter_AddRefs(location));
-3560         NS_ENSURE_SUCCESS(rv, rv);
-// Use the DOM to get the Location object of the window object.
-3561
-3562         jsval v;
-3563
-3564         rv = WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation),
-&v);
-// This XPConnect method creates a wrapper for the Location object on the //
-Window object.
-3565         NS_ENSURE_SUCCESS(rv, rv);
-3566
-3567         if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
-3568                                    ::JS_GetStringLength(str), v, nsnull,
-3569                                    nsnull, 0)) {
-3570           return NS_ERROR_FAILURE;
-3571         }
-// This JS API call defines the "location" property on the window object, its
-// value being the XPConnect wrapper for the Location object.
-3572
-3573         *objp = obj;
-3574
-3575         return NS_OK;
-3576       }
-
- -

This is the first step. It is required to have the getter for .location work as well, but that's another story. The second step is to map .location to .location.href in nsWindowSH::SetProperty()

- -

这个是第一步,另外还需要让.location的getter函数干活,但是那是另一回事了。第二步是在nsWindowSH::SetProperty() 里把.location映射到.location.href。

- -
2894     if (str == sLocation_id) {
-// Setting the location property
-2895       JSString *val = ::JS_ValueToString(cx, *vp);
-2896       NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED);
-// Convert the value assigned to location (i.e. the url) to a JSString.
-2897
-2898       nsCOMPtr<nsISupports> native;
-2899       wrapper->GetNative(getter_AddRefs(native));
-// Get the pointer to the content object that was wrapped.
-2900
-2901       nsCOMPtr<nsIDOMWindowInternal>
-window(do_QueryInterface(native));
-2902       NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
-// QueryInterface to have a nsIDOMWindowInternal pointer to call
-// GetLocation() on it.
-2903
-2904       nsCOMPtr<nsIDOMLocation> location;
-2905       nsresult rv = window->GetLocation(getter_AddRefs(location));
-2906       NS_ENSURE_SUCCESS(rv, rv);
-// Get the Location object for this window.
-2907
-2908       nsDependentString href(NS_REINTERPRET_CAST(PRUnichar *,
-2909                                                  ::JS_GetStringChars(val)),
-2910                              ::JS_GetStringLength(val));
-// Convert the JSString to a string that can be passed to SetHref()
-2911
-2912       rv = location->SetHref(href);
-2913       NS_ENSURE_SUCCESS(rv, rv);
-// After this, we effectively mapped .location to .location.href
-2914
-2915       return WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation), vp);
-// Create a wrapper for the location object with vp (the url) as value.
-2916     }
-
- -

It's that simple. And the possibilities are endless.

- -

就这么简单,但可能性是无限的。

- -

Resources of interest

- - - -

Scriptable Helper flags

- -

This chapter has not been written yet. If you want to help please contact me!

- -

Security features implementation

- -

This chapter has not been written yet. If you want to help please contact me!

- -
-

Original Document Information

- - -
- -

{{ languages( { "ja": "ja/Mozilla_DOM_Hacking_Guide" } ) }}

diff --git a/files/zh-cn/mozilla_mathml_project/fonts/index.html b/files/zh-cn/mozilla_mathml_project/fonts/index.html deleted file mode 100644 index 578c22b092..0000000000 --- a/files/zh-cn/mozilla_mathml_project/fonts/index.html +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Fonts for Mozilla's MathML engine -slug: Mozilla_MathML_Project/Fonts -translation_of: Mozilla/MathML_Project/Fonts ---- -
These instructions are for Gecko 31.0 {{GeckoRelease("31.0")}} and higher. For former versions see Fonts for Mozilla 1.8, Fonts for Mozilla 1.9 or Fonts for Mozilla 2.0.
- -

安装说明

- -

重置旧的安装程序

- -

如果你已经安装过MathML之前的版本Gecko的字体,最好重新设定你的安装程序:

- - - -

Windows

- -

On Windows 7 and higher, Cambria Math is installed by default and will be used for the MathML rendering so you do not have anything to do. If you are using Windows XP, you can obtain the Cambria Math font by installing Microsoft Office 2007+, Microsoft’s PowerPoint Viewer, or Microsoft’s Office Compatibility Pack. Otherwise you can install any fonts with a MATH table (follow Microsoft's instruction for Windows XP) and they may also be included in TeX distributions such as TeX Live or MikTeX.

- -

Warning: Some fonts and some version of Windows are affected by rendering bug causing too much space above and below the lines of text in some MATH fonts.

- -

Mac

- -

On Mac, you must install any of the fonts with a MATH table. For example, you can install MacPorts and its texlive-fonts-recommended package (Latin Modern Math and TeX Gyre). An enhancement request has been submitted to Apple to make a MATH font installed by default (problem 16841023 for STIX and17021145 for Latin Modern).

- -

Linux

- -

On Linux, you must install any of the fonts with a MATH table. They are generally available from the package manager of many distributions, for example:

- - - -

If you installed "vanilla" TeX Live you will need to inform your system of fonts provided by it:

- -
$ mkdir ~/.fonts
-$ mdir ~/.fonts/OTF
-$ for f in $(find /path/to/your/texlive/texmf-dist/fonts/opentype/public/ -maxdepth 1 -mindepth 1); do ln -s $f ~/.fonts/OTF/; done
-# fc-cache ~/.fonts
-# mkfontscale ~/.fonts/OT
-# mkfontdir ~/.fonts/OTF
-
- -

Android

- -

You must use the MathML-fonts add-on. An enhancement request has been submitted to Google to make a MATH font installed by default. See this GitHub repository.

- -

Firefox OS

- -

You must use the MathML-fonts add-on. We plan to bundle a MATH font in the default installation. There are known bugs due to font-inflation.

- -

Other systems

- -

On other systems, consider installing a MATH font using your package manager Note that these fonts are generally delivered with TeX distributions such as TeX Live, but you might need to follow specific instructions so that your system is aware of the fonts. As a last resort, install the MathML fonts add-on.

- -

Arabic Mathematical Alphabetic Symbols

- -

Currently, very few fonts have appropriate glyphs for the Arabic Mathematical Alphabetic Symbols. If you are likely to need these characters, we recommend to install the XITS or Amiri fonts. A bug has been reported to the STIX consortium to add coverage for these characters.

- -

Fonts with a MATH table

- -

Gecko's MathML layout algorithm has long been based on some TeX rules and private per-font tables. Unfortunately, this did not always work well with the modern OpenType/TrueType Unicode fonts used by browsers and installed by default on various systems. If one of the few mathematical fonts supported by Gecko were not installed on the user system, then the MathML rendering could be very poor.

- -

Starting with Gecko 31, it is recommended to use OpenType fonts that have a MATH table. This table is based on the TeX rules and was designed by Microsoft for Microsoft Word, it has been implemented in many modern TeX typesetting systems and is currently being standardized in the ISO/IEC CD 14496-22 "Open Font Format" (see section 6.3.6). This is still a work-in-progress: there are known bugs in browsers & fonts and the fonts are not installed by default on many operating systems, but you can already start using these mathematical fonts instead of the old ones. See the implementation status on the Mozila wiki.

- -

Here is a list of known fonts with a MATH table. Firefox users can install the MathML-fontsettings add-on to configure which font to use to render mathematical formulas.

- - - -

Using mathematical fonts on Web pages

- -

Starting with Gecko 31.0 {{GeckoRelease("31.0")}}, it is now easy to set up the CSS style (and optional WOFF fonts) to use on your Web site. See the Authoring MathML page for details and try the MathML Torture Test. You can use FontForge to edit the MATH table and create your own mathematical fonts.

diff --git a/files/zh-cn/mozilla_mathml_project/index.html b/files/zh-cn/mozilla_mathml_project/index.html deleted file mode 100644 index 2b45c419b6..0000000000 --- a/files/zh-cn/mozilla_mathml_project/index.html +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Mozilla MathML Project -slug: Mozilla_MathML_Project -tags: - - MathML - - MathML Project - - NeedsTranslation - - TopicStub -translation_of: Mozilla/MathML_Project ---- -

Updates

-

mathboard.png

- -

November 16, 2012

-

MathML and Thunderbird

-

November 14, 2012

-

Writing mathematics in emails

-

October 12, 2012

-

MathML has been enabled in Chrome Canary!

-

September 25, 2012

-

Story of a MathML summer project by Quentin Headen: Summer of Mozilla.

-

September 1, 2012

-

Mozilla MathML Project: Roadmap

-

Thank you to all the contributors who have worked on the MathML project this summer!

-

May 3, 2012

-

New MathJax option available in Wikipedia. If you have a Wikipedia account, mathematical formulas can now be rendered with MathML!

-

Community

- - - -

Sample MathML Documents

- -

Create MathML Documents

- -
-

Original Document Information

- -
-

 

-
-  
diff --git a/files/zh-cn/mozilla_mathml_project/start/index.html b/files/zh-cn/mozilla_mathml_project/start/index.html deleted file mode 100644 index c0e6fb8dc1..0000000000 --- a/files/zh-cn/mozilla_mathml_project/start/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: MathML 演示 -slug: Mozilla_MathML_Project/Start -translation_of: Mozilla/MathML_Project/Start ---- -

MathML 演示

-

你能看到页面中整齐的数学公式吗?没有?那太糟了。这是你应该看到的样子。要修复这个情形,请下载一个支持 MathML 的Mozilla 版本。

-

你已经拥有一个支持 MathML 的版本但是你看到的和截屏不同?那可能是因为你缺少需要的 MathML 字体.

-

现在你已经万事俱备了,你应该可以看到这个带有变音符号的行内方程式: x ^ + xy ^ + xyz ^ . 接下来是一个小公式, det | a c b d | = a d - b c , 它也可以排版成独立行公式风格,如 det | a b c d | = a d - b c .

-

数学排版要求很多。 MathML in Mozilla 项目 旨在实现 MathML 规范以达到“所见即所标记”,换句话说“所见即所创造”, 或者英文缩写成 “WYSIWYM”。这两者之间的不同在于标记! ( ... ( ( a 0 + a 1 ) n 1 + a 2 ) n 2 + ... + a p ) n p ( ... ( ( a 0 + a 1 ) n 1 + a 2 ) n 2 + ... + a p ) n p

-

这个粗体方程式的根 y 3 + p y + q = 0 也是粗体 y = - q 2 + q 2 4 + p 3 27 2 3 + - q 2 - q 2 4 + p 3 27 2 3 .

-

至于方程式 a x 2 + b x + c = 0 的根,你可以点击黄色区域的任意位置进行放大或者缩小:

-
-

Zoomable Math

-

HTML Content

-
    <p>
-      <math display="block">
-        <mstyle id="zoomableMath" mathbackground="yellow">
-          <mrow>
-            <mi>x</mi>
-            <mo>=</mo>
-            <mfrac>
-              <mrow>
-                <mrow>
-                  <mo>-</mo>
-                  <mi>b</mi>
-                </mrow>
-                <mo>&#xB1;</mo>
-                <msqrt>
-                  <mrow>
-                    <msup>
-                      <mi>b</mi>
-                      <mn>2</mn>
-                    </msup>
-                    <mo>-</mo>
-                    <mrow>
-                      <mn>4</mn>
-                      <mi>a</mi>
-                      <mi>c</mi>
-                    </mrow>
-                  </mrow>
-                </msqrt>
-              </mrow>
-              <mrow>
-                <mn>2</mn>
-                <mi>a</mi>
-              </mrow>
-            </mfrac>
-          </mrow>
-        </mstyle>
-      </math>
-    </p>
-
-
-

JavaScript Content

-
      function zoomToggle()
-      {
-      if (this.hasAttribute("mathsize")) {
-      this.removeAttribute("mathsize");
-      } else {
-      this.setAttribute("mathsize", "200%");
-      }
-      }
-
-      function load()
-      {
-      document.getElementById("zoomableMath").
-      addEventListener("click", zoomToggle, false);
-      }
-
-      window.addEventListener("load", load, false);
-
-

{{ EmbedLiveSample('Zoomable_Math') }}

-

考虑这样一个有趣的标记 { u t + f ( u ) x = 0 u ( 0 , x ) = { u - 若  x < 0 u + 若  x > 0 或者其他复杂的标记 Ell ^ Y ( Z ; z , τ ) := Y ( l ( y l 2 π i ) θ ( y l 2 π i - z ) θ ( 0 ) θ ( - z ) θ ( y l 2 π i ) ) × ( k θ ( e k 2 π i - ( α k + 1 ) z ) θ ( - z ) θ ( e k 2 π i - z ) θ ( - ( α k + 1 ) z ) ) π ( n ) = m = 2 n ( k = 1 m - 1 ( m / k ) / m / k ) - 1 ϕ W s k ( Ω g ) ( | α | k α ϕ ξ α L s ( Ω g ) s ) 1 / s

-

请参考MathML 项目页面的链接以浏览更多样例。如果你正在创建你自己的 Mozilla 的二进制版本,请参考目录 mozilla/layout/mathml/tests

-

当你在 Mozilla 中尝试 MathML,面对那些没有按照 MathML 规范实现的少数情况,你有没有想做什么呢?或者那些看上去有些碍眼的部分,你是否希望能够做得更好一点吗?或者那些以前没有问题的东西现在出问题了?在这些情况下,欢迎前往Bugzilla报告错误。 Bugzilla 是一个记录这些东西的大仓库,要知道,如果那些错误没有被报告,你的问题怎么会解决?!

-

参与是你贡献的一部分,一起来让Gecko 成为一个优雅、符合标准的 MathML 渲染工具。你可以通过以下方法反馈:在互联网上书写 MathML 内容体现,在Bugzilla里报告错误,在待办事项列表中选择一个条目,甚至检查或改进当前的代码

diff --git a/files/zh-cn/mozilla_quirks_mode_behavior/index.html b/files/zh-cn/mozilla_quirks_mode_behavior/index.html deleted file mode 100644 index 5957c659fa..0000000000 --- a/files/zh-cn/mozilla_quirks_mode_behavior/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Mozilla 怪异模式表现 -slug: Mozilla_Quirks_Mode_Behavior -translation_of: Mozilla/Mozilla_quirks_mode_behavior ---- -

下面粗略地列出了标准模式和怪异模式在表现上的不同。

- -

其他以及样式

- - - -

Block and Inline layout

- - - -

Tables

- - - -

Frames

- - - -

HTML Parser

- - - -
-

Original Document Information

- - -
- -

See also

- -

Mozilla's Quirks Mode

- -

{{ languages( { "fr": "fr/Comportement_du_mode_quirks_de_Mozilla", "ja": "ja/Mozilla_Quirks_Mode_Behavior" } ) }}

diff --git a/files/zh-cn/mozilla_svg_project/index.html b/files/zh-cn/mozilla_svg_project/index.html deleted file mode 100644 index 0ab66db3da..0000000000 --- a/files/zh-cn/mozilla_svg_project/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Mozilla的SVG项目 -slug: Mozilla_SVG_Project -tags: - - SVG - - 矢量图 -translation_of: Mozilla/Mozilla_SVG_Project ---- -

引言

- -

如果你已经了解了一些基础知识,你可能知道SVG代表Scalable Vector Graphics(可缩放的矢量图形),是用XML语言表示二维图像的一种格式。与之相关的SVG面向图形、XHTML面向文本、MathML面向数学方程式、CML面向化学分子式。

- -

SVG与Adobe拥有专利的Flash技术有相似的范围:除此之外它还提供反锯齿的渲染、图案和渐变填充、复杂的滤镜效果、剪切到任意路径、文本和动画。如何区分SVG和Flash呢?SVG是W3C推荐标准(亦即,它是一个用于所有目的的标准),而且它是基于XML的语言,与封闭的二进制格式截然相反。它明确设计用来与别的W3C标准比如说CSS、DOM和SMIL一起作用。

- -

Firefox自从Firefox 1.5版本以来,原生支持SVG文件。

- -

一个简单的示例

- -

此时你好奇SVG看起来是如何,这里有一个示例:

- -
<svg xmlns="http://www.w3.org/2000/svg"
-     xmlns:xlink="http://www.w3.org/1999/xlink"
-     version="1.1"
-     baseProfile="full">
-  <g fill-opacity="0.7" stroke="black" stroke-width="0.1cm">
-    <circle cx="6cm" cy="2cm" r="100" fill="red"
-                    transform="translate(0,50)" />
-    <circle cx="6cm" cy="2cm" r="100" fill="blue"
-                    transform="translate(70,150)" />
-    <circle cx="6cm" cy="2cm" r="100" fill="green"
-                    transform="translate(-70,150)" />
-  </g>
-</svg>
-
- -

查看这个示例

- -

这个示例应该看起来如下所示(这是在Mozilla Forefox 1.5中呈现的):

- -

Mozilla Firefox 1.5 rendering of SVG example

- -

原生SVG 对比 插件SVG

- -

Mozilla SVG编译器是一个原生的SVG编译器。它与插件SVG浏览器比如说Adobe viewer截然相反。

- -

这两者有这些影响:

- - - -

状态

- -

Gecko 1.8 添加了SVG支持,从此它包含在Mozilla Firefox V1.5以及后的版本中。

- -

The goal we're working towards with Mozilla's SVG implementation is SVG 1.1 Full. What exists now in the tree should be treated as a technology preview. As we implement more of the specification, content written against Mozilla's SVG implementation might break if it unintentionally relies on bugs that are fixed. We realize this is not ideal, but ask you be patient as we continue implementing an extremely large specification that lacks a comprehensive test suite.

- -

Our goal is specification conformance. Where the specification and other implementations of SVG differ, we will conform to the specification. Where the specification is ambiguous, we will make an informed decision, consulting the SVG working group and other experts as appropriate.

- -

While we are still a long way away from full SVG support, the subset currently implemented is already pretty usable. We have support for all basic shapes including beziers, stroking and filling with opacity, gradients, scripting, events, and much of the DOM.

- -

Big areas of the SVG specification where we're still lacking include filters, svg defined fonts, and declarative animations. A page listing the current implementation status of svg elements and the rendering backends can be found at Mozilla SVG Status.

- -

Getting Involved

- -

SVG 1.1 is a big specification and we still have a lot of work to do to fully implement it. If you think you can help us by e.g. tracking down bugs, writing some test-cases or implementing some outstanding features, please get in touch.

- -

We have an IRC chat channel, #svg, on irc.mozilla.org.

- -

There is also newsgroup/mailing list dedicated to SVG in Mozilla. It's called mozilla.dev.tech.svg.

- -

If reporting bugs, the best place for them is in bugzilla so that we can track them and you can monitor the progress. File them in the "Core" product with the "SVG" component. If you have a testcase (which we love to have), please use the attachment feature of bugzilla to include it rather than pasting it in the bug.

- -

常见问题

- -

Before asking us questions directly, please take a look at the Frequently Asked Questions page to see if your question has already been answered. If your question hasn't been answered there, try asking in our newsgroup or IRC channel.

- - - -

Mozilla专有的SVG网站

- - - -

General resources

- - - -
-

Original Document Information

- - -
- -

{{ languages( { "ja": "ja/Mozilla_SVG_Project" } ) }}

diff --git a/files/zh-cn/mozilla_web_developer_faq/index.html b/files/zh-cn/mozilla_web_developer_faq/index.html deleted file mode 100644 index c009cbc1e6..0000000000 --- a/files/zh-cn/mozilla_web_developer_faq/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: Mozilla Web开发人员 FAQ -slug: Mozilla_Web_Developer_FAQ -tags: - - Web开发 -translation_of: Mozilla/Mozilla_Web_Developer_FAQ ---- -

This document answers questions that Web authors ask frequently specifically in connection with Mozilla and other Gecko-based browsers such as Firefox. There are links to more general Web authoring FAQs at the end of this document. -

-

什么是“怪异模式”,什么是“标准模式”?

-

Mozilla has two and a half layout modes: Quirks, Almost Standards and Standards. In the Standards mode Mozilla aims to treat documents authored in compliance with the Recommendations of the World Wide Web Consortium according to the W3C Recommendations. In the Quirks mode—for the purpose of backwards compatibility—Mozilla mimics some behaviors of legacy browsers in ways that could cause W3C Recommendation-compliant documents to be handled against the W3C specifications. The Almost Standards mode is like the Standards mode except it addresses the issue of the next question by rendering table cells with images in the traditional way. The mode is picked based on the doctype declaration (or the lack thereof) at the beginning of an HTML document. -

- -

The former declaration is for documents that don’t include any deprecated markup. The latter is for documents that may include deprecated markup. In either case the document should validate and be compatible with the CSS2 layout model. -

The easiest way to activate the Quirks mode for HTML is to omit the doctype declaration. However, authoring new documents that rely on quirks is discouraged. -

The Almost Standards mode was introduced in Mozilla 1.1 beta and Mozilla 1.0.1. In earlier versions the doctype declarations that now activate the Almost Standards mode activated the Standards mode. -

Doctype sniffing only applies to documents served as text/html. Documents sent as XML always activate the Standards layout mode. This includes documents sent as application/xhtml+xml. The consequence is that XHTML 1.0 Transitional documents are rendered in the Almost Standards mode when served as text/html under pretext of the Appendix C but in the Standards Mode when served as application/xhtml+xml. -

Since also other contemporary browsers have a standards mode, activating the Standards mode or the Almost Standards mode in other browsers as well (using the above-mentioned exact doctypes) is the best way to get consistent CSS layout results across different browsers. On the other hand, the quirks implemented in the quirks modes of different browsers vary from browser to browser. -

-

Why are there gaps between image rows in tables when the layout engine is in the Standards mode?

-

In the CSS2 box layout model the default vertical sizing of layout boxes and the default vertical alignment of images is different from the behavior of old browsers. These aspects of the layout can be changed by explicitly setting the display CSS property of the images (and possible surrounding <a> elements) to block. -

If the table cells that contain only an image are marked with <td class="imgcell">, the required CSS rule is: .imgcell img, .imgcell a { display: block; } -

Longer explanation… -

-

Why are there still gaps even between text rows in tables when the layout engine is in the Standards mode or in the Almost Standards mode?

-

In the Standards mode and in the Almost Standards mode Mozilla does not suppress the default margins of the first and last child element in table cells. Therefore, the default margins for paragraphs apply even with markup such as <td><p>foo</p></td>. -

Often the content of a cell in a table of tabular data does not constitute a paragraph. In that case, the easy solution is not to mark the contents of the cell as a paragraph. -

When the paragraph markup is called for but the default margins are unwanted, zero margins can be suggested using CSS. -

-

为什么我的样式表不能正常工作?

-

Here’s the check list: -

- -

It is also possible, although not very likely, that you are seeing a bug. -

-

为什么JavaScript不能工作?

-

Some proprietary document objects such as document.all and document.layers are not part of the W3C DOM and are not supported in Mozilla. (There is partial undetectable support for document.all, though, in newer versions of Mozilla. However, that functionality only exists for compatibility with sites authored specifically for IE. You should not rely on Mozilla’s document.all support on new pages.) The method document.getElementById() can be used instead. -

In the Standards mode Mozilla does not generate implicit top-level JavaScript variable bindings for elements with the id or name attribute. The correct way to access an element by id is to call the document.getElementById() method with the id as a string as the argument. -

Also, old client sniffers can shut out new browsers. The point of having a common API (the W3C DOM) is interoperability, and checking for a particular browser defeats that purpose. When working with the DOM, it is better to check for the existence of the methods and objects you are planning on using. For example, the existence of document.getElementById() can be checked as follows: -

-
if(document.getElementById) {
-   /* code that uses document.getElementById() */
-}
-
-

为什么Mozilla不能正常显示我的alt工具提示?

-

Contrary to a popular belief stemming from the behavior of a couple browsers running on the Windows platform, alt isn’t an abbreviation for ‘tooltip’ but for ‘alternative’. The value of the alt attribute is a textual replacement for the image and is displayed when the image isn’t. -

Mozilla doesn’t display the alt attribute as a tooltip, because it has been observed that doing so encourages authors to misuse the attribute. -

- -

There is another attribute that Mozilla shows as a tooltip: title. In fact, the HTML 4.01 specification suggests that the title attribute may be displayed as a tooltip. However, this particular display method is not required and some other browsers show the title attribute in the browser status bar, for example. -

At this point some people feel compelled to post a “But IE…” rant in the newsgroups or in Bugzilla. Please note that Mac IE 5 behaves in the same way as Mozilla when it comes to the alt and title attributes. Windows IE also shows the title attribute in a tooltip. -

-

Does Mozilla support downloadable fonts?

-

Downloadable fonts are not supported. -

Downloadable fonts are usually used on sites using writing systems for which proper support has been missing in browsers in the past. These sites (for example some Indian sites) code the text in Latin gibberish and then use a font that to the browser and operating system seems to be a Latin font but has eg. Devanagari glyphs, so that when the Latin gibberish is rendered with the font it seems to a human reader to be intelligible text in some language.

Obviously, that kind of ad hockery falls apart when Unicode-savvy browsers come along and render Latin gibberish as Latin gibberish (since that’s what is coded in the file from the Unicode point of view). Instead of providing support for downloadable fonts, Mozilla is addressing the real issue: support for various Unicode ranges. -

However, there are still bugs related to support for Indic scripts on some platforms. For example, on Mac OS X Mozilla does not use the Devanagari font that comes with the system but can use a third-party font like TITUS Cyberbit. -

A lot of work has been put into Mozilla’s Unicode support. Supporting downloadable fonts in a cross-platform way would also be a lot of work and would potentially require navigating past a bunch of patents but the rewards would be small. For the purpose of rendering non-ISO-8859-1 characters Mozilla already provides Unicode support that, in the long run, is a lot better approach than using pseudo-Latin downloadable fonts separately on each site. -

-

为什么symbol/dingbat字体不能工作?

-

They are working. Characters in HTML 4 and XML documents are Unicode characters (even if the document has been encoded using a legacy encoding for transfer)—not font glyph indexes.

<font face="Symbol">a</font> means the character LATIN SMALL LETTER A (U+0061) preferably displayed using the Symbol font. Since the Symbol font does not have glyph for that character, another font is used. If you mean α, you should use GREEK SMALL LETTER ALPHA (U+03B1). If you are using a legacy encoding that cannot represent that character, you can use a numeric character reference: &#945;. -

Likewise, to use a dingbat, you should use the appropriate Unicode character instead of trying to apply a dingbat font to an ASCII character. For example, to represent ☺, you should use WHITE SMILING FACE (U+263A).

-

Why isn’t Mozilla rendering my page as I intended? So my page isn’t standards-compliant, but good browsers should render pages as the author intended anyway!

-

Authors are supposed to communicate their intentions using the Web standards. Otherwise, finding out the intentions of each particular author would require psychic abilities which can’t be implemented in software. Even in cases where a human could deduce the intention, doing so in software would be very slow, bug-inducing, difficult and complicated. -

The usual counter argument is that there is no need to guess—Mozilla should do whatever browser x does (where x is the favorite non-Mozilla browser of whoever is presenting the counter argument). However, doing whatever browser x does in every conceivable case isn’t simple at all, even though it might appear to be simple when presented as a passing remark. -

Different people have different ideas about what x should be. The second problem is that Web authors are very creative in coming up with different ways of deviating from the standards. In fact, since the input to the browser can be of arbitrary length, there is no upper bound for the number of distinct ways of deviating from the standards. Therefore, it is impossible to test whether Mozilla reacts exactly like browser x to every possible input. (Likewise, there is no upper bound for the number of ways different features of the standards themselves can be combined, which makes software quality assurance challenging.) -

Also, the ways in which browser x reacts to some standards-incompliant input are not all intentional. Some of the reactions are due to unknown and unintentional interactions within a complex program. Even if you had the source code for browser x, you couldn’t change anything without risking changing one or more of the unknown and unintentional interactions within the program. -

The usual counter argument is that Mozilla doesn’t need to match the behavior of browser x in every possible case but only in the alleged common cases. However, it turns out Mozilla is doing that already. Mozilla’s Standards mode is, obviously, already compatible with other browsers that implement the same standards reasonably correctly. On the other hand, Mozilla’s quirks mode already accommodates common non-standardisms that are due to the behaviors of common legacy browsers. -

Instead of putting time and effort into reverse-engineering and cloning legacy browsers, it makes more sense to focus on implementing standards. Standards (when implemented by others as well) promote interoperability better than cloning legacy software bug by bug. -

Also, HTML was designed to adapt to different presentation media, so different presentations of the same document are to be expected.

-

According to the Accept header, Mozilla prefers application/xhtml+xml over text/html. Should I serve application/xhtml+xml to Mozilla?

-

The preference for application/xhtml+xml was added to the Accept header in order to enable the serving of MathML to both Mozilla and IE with Apache without scripting back when the MathPlayer plug-in for IE did not handle application/xhtml+xml. -

If your document mixes MathML with XHTML, you should use application/xhtml+xml. If you’re developing XHTML Basic content for mobile devices and are serving it as application/xhtml+xml, you can serve it as application/xhtml+xml to Mozilla as well without taking special steps (except perhaps providing a different style sheet for the handheld and screen media). -

However, if you are using the usual HTML features (no MathML) and are serving your content as text/html to other browsers, there is no need to serve application/xhtml+xml to Mozilla. In fact, in versions prior to Gecko 1.9/Firefox 3, doing so would deprive the Mozilla users of incremental display, because incremental loading of XML documents has not been implemented in those versions. Serving valid HTML 4.01 as text/html ensures the widest browser and search engine support. -

There is a fad of serving text/html to IE but serving the same markup with no added value as application/xhtml+xml to Mozilla. This is usually done without a mechanism that would ensure the well-formedness of the served documents. Mechanisms that ensure well-formed output include serializing from a document tree object model (eg. DOM) and XSLT transformations that do not disable output escaping. When XHTML output has been retrofitted to a content management system that was not designed for XML from the ground up, the system usually ends up discriminating Mozilla users by serving tag soup labeled as XML to Mozilla (leading to a parse error) and serving the same soup labeled as tag soup to IE (not leading to a parse error). -

-

MIME类型为application/xhtml+xml的文档和类型为text/html的文档,有什么不同?

- -

我没有找到问题的答案,我还可以到哪里寻找帮助?

-

Try asking in the newsgroup relevant to your question in the comp.infosystems.www.authoring.* hierarchy or, if your question is about JavaScript/ECMAScript or the DOM, in comp.lang.javascript (after reading the group FAQs first, of course). Please do not ask Web authoring questions in the newsgroups intended for discussion about the development of Mozilla. -

- -
-

原始文档信息

- -
-{{ languages( { "ja": "ja/Mozilla_Web_Developer_FAQ", "en": "en/Mozilla_Web_Developer_FAQ" } ) }} diff --git "a/files/zh-cn/mozilla\344\270\255\347\232\204xml/index.html" "b/files/zh-cn/mozilla\344\270\255\347\232\204xml/index.html" deleted file mode 100644 index fb24cd8e17..0000000000 --- "a/files/zh-cn/mozilla\344\270\255\347\232\204xml/index.html" +++ /dev/null @@ -1,227 +0,0 @@ ---- -title: Mozilla中的XML -slug: Mozilla中的XML -tags: - - XML -translation_of: Archive/Mozilla/XML_in_Mozilla ---- -

-

Mozilla has good support for XML. Several World Wide Web Consortium (W3C) Recommendations and drafts from the XML family of specifications are supported, as well as other related technologies. -

-

Supported Core XML W3C Recommendations

-

The core XML support includes parsing XML without validation (we use the Expat parser), displaying XML with CSS, manipulating XML documents with scripts via DOM, associating stylesheets with XML documents, and namespaces in XML. The core support is very good with few bugs. -

-

DTDs and Other External Entities

-

Mozilla does not load external entities from the web. -

Mozilla can load external entities whose system identifier uses the chrome protocol. This feature is used mainly to localize Mozilla to different languages (the UI strings are stored in external DTD files). Another exception is an entity whose system identifier is a relative path, and the XML declaration states that the document is not standalone (default), in which case Mozilla will try to look for the entity under <tt><bin>/res/dtd</tt> directory. -

Mozilla may also make an exception with XHTML documents, see below. -

Mozilla will read internal (DTD) subsets, and in special circumstances external DTDs as explained above and will use this information to recognize ID type attributes, default attribute values, and general entities. -

-

Other Notes

-

A lot of the Document Object Model (DOM, W3C Recommendations and drafts) applies to XML. Likewise, the Cascading Style Sheets (CSS, W3C Recommendations and drafts) style language can be used to style XML documents. -

The code for most the core XML can be found in the following directories on the Mozilla CVS server: content/xml/, parser/expat/ and parser/htmlparser/. -

The newsgroup to discuss XML in Mozilla depends a bit on the nature of the question. For example, DOM related questions should probably be discussed in the netscape.public.mozilla.dom newsgroup, while style issues should be discussed on netscape.public.mozilla.style and so on. The catch-all newsgroup for XML discussion is netscape.public.mozilla.xml. -

- - - - - - - - - - - - -
Specification or technology -Status and/or further documentation -
XML -W3C Recommendation -
Namespaces in XML -W3C Recommendation -
Associating Stylesheets with XML Documents -W3C Recommendation -
Styling XML Documents with CSS - -
Manipulating XML documents with scripts through DOM - -
-

Other Supported XML W3C Recommendations

- - - - - - - - - - - - - - - - - - - - - - -
Specification or Technology -Documentation -
XHTML -W3C Recommendation -
XML Base (for links only, not used for :visited etc. CSS properties) -W3C Recommendation -
XLink (simple XLinks only) -W3C Recommendation -
FIXptr -W3C "proposal" -
XPointer Framework -W3C Recommendation -
XPointer element() scheme -W3C Recommendation -
XPointer xmlns() scheme -W3C Recommendation -
XPointer fixptr() scheme -This scheme is simply a wrapper for FIXptr -
XPointer xpath1() scheme -Internet-Draft -
document.load(), document.async -Part of DOM Level 3 Load & Save module, a W3C Working Draft -
-

XHTML

-

We have reasonable XHTML support, most things should work. We treat XHTML documents differently depending on the mime type (or file suffix if files are loaded from local discs). Files that go through the HTML code path are not checked for well-formedness. You will also notice not all XHTML features are supported when you exercise HTML code path. -

- - - - - - -
MIME Type -File Suffix -Code Path -
text/xml
application/xml
application/xhtml+xml -
xml
xht
xhtml -
XML -
text/html -html
htm -
HTML -
-

The entire document need not be XHTML. You can use XHTML elements inside an arbitrary XML document by using the XHTML namespace. See the Testing and QA section for samples. The correct XHTML namespace is http://www.w3.org/1999/xhtml -

Please note that the XHTML entities, like &auml;, work only in conforming XHTML documents that have a valid XHTML Formal Public Identifier (or in other words, a DOCTYPE section with a PUBLIC identifier). XHTML entities will not work in arbitrary XML documents, not even if the XHTML namespace is used. The public identifiers that are recognized are: -

-
-//W3C//DTD XHTML 1.0 Transitional//EN
--//W3C//DTD XHTML 1.1//EN
--//W3C//DTD XHTML 1.0 Strict//EN
--//W3C//DTD XHTML 1.0 Frameset//EN
--//W3C//DTD XHTML Basic 1.0//EN
--//W3C//DTD XHTML 1.1 plus MathML 2.0//EN
--//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN
--//W3C//DTD SVG 20001102//EN
--//WAPFORUM//DTD XHTML Mobile 1.0//EN
-
-

XML Linking and Pointing

-

XML Linking support includes XML Base (used only when you mouse over a link or click a link) and simple XLinks. You can make any XML element into an XLink by using the XLink namespace http://www.w3.org/1999/xlink. You can also use the linking elements from the XHTML namespace. See the Testing and QA section for samples. -

For pointing into resources in XML documents Mozilla also supports FIXptr, a simplified, non-compatible version of XPointer. In addition to using FIXptr in links, it is possible to use it from scripts. See the proprietary dom/public/idl/core/nsIDOMXMLDocument.idl interface. There is test case for FIXptr links and a scripting example. -

Since 1.4alpha, Mozilla also supports XPointer Framework, XPointer element() scheme, XPointer xmlns() scheme, XPointer fixptr() scheme and XPointer xpath1() scheme. The XPointer processor is extensible and it is easy to implement support for other schemes - have a look at the API. The xpath1() scheme was implemented using this extensible mechanism. There is also a proprietary API from scripts to the XPointer processor. There is a testcase for XPointers that you can also study. -

Lastly, there is a pref you might want to try (especially useful with FIXptr) that will select the link target when you traverse it. There is no UI for setting this pref yet, so you will need to manually edit the preferences file. Add this line: -

-
pref("layout.selectanchor", true);
-
-

DOM Load and Save Methods

-

document.load() is a part of the W3C DOM Level 3 Load & Save module. Mozilla currently implements only the load() method and the async property. Since 1.4alpha it has been possible to load documents synchronously, before that it was only asynchronous. See the load sample in the XML tests directory. (Loading the load.html file from the LXR generated page will not work because LXR will munge the test.xml file into HTML and serve it as HTML. To test this functionality, create the files on your local disk or on a webserver.) -

-

Outside Supported XML W3C Recommendations

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Specification or Technology -Documentation -Mozilla Project -
XSLT -W3C Recommendation -XSLT -
XPath -W3C Recommendation -XSLT -
XMLHttpRequest -Microsoft -XML Extras -
DOMParser and XMLSerializer -Mozilla -XML Extras -
SOAP -W3C Note -Web Services -
XML-RPC -UserLand Software -XML-RPC -
RDF -W3C Recommendations -RDF -
SVG -W3C Proposed Recommendation -SVG -
MathML -W3C Recommendation -MathML -
P3P -W3C Recommendation -P3P -
WSDL -W3C Note -Web Services -
XBL -W3C Note (by Mozilla) -XBL -
XUL -Mozilla -XPToolkit -
-

Roadmap

-

Next big tasks would include support for XPointer xpointer() scheme (bug 32832), full XLink support (bug 61664), XInclude, XML Catalogs (bug 98413), XForms (bug 97806), validating parser (bug 196355), XML Schemas and incremental layout of XML document (bug 18333), and a SAX API (bug 315825). -

To fully implement XLink, we need something called a link manager. See some initial design documents. -

-

Testing and QA

-

We have a lot of testcases linked to from the browser standards compliance QA page. -

Most of the core XML test documents on the CVS server are located in content/xml/tests. We also have a couple online: the books demo and the IRS table of contents demo. Both of them demonstrate XML, Associating stylesheets with XML, displaying XML with CSS, Namespaces in XML, XHTML, simple XLinks, and manipulation of XML with scripts via DOM. -

There is an XML component in Bugzilla. -

We also have the "xhtml" keyword for XHTML bugs (these tend to be scattered across components). -

We have bugs open to make NIST DOM (bug 51247) and NIST XML test suites to work in Mozilla - they currently do not work. -

-

How can I help?

-

If you can code, look for helpwanted keyword in XML bugs. We don't use that always, so if you want to avoid doing duplicate work you could start working on bugs that have Future milestone, or otherwise have a milestone that is set way into the future. -

You can always test our XML support. We'd really like to get tests that can be run automatically (this would require knowledge of web development; document.load() and/or XML Extras might be needed), but probably most of the bugs we get have just been found by normal people trying to do something that works in some other browser and does not work in Mozilla. -

-
-
diff --git a/files/zh-cn/new_compatibility_tables_beta/index.html b/files/zh-cn/new_compatibility_tables_beta/index.html deleted file mode 100644 index 24a3b2a5ca..0000000000 --- a/files/zh-cn/new_compatibility_tables_beta/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 全新的测试版兼容性表格 -slug: New_Compatibility_Tables_Beta -translation_of: Archive/MDN/New_Compatibility_Tables_Beta ---- -

您来到此页面,应该是因为您在我们的新版兼容性表格上点击了测试通知链接。 (不是么? 想要看看最新的表格么? 申请成为测试员)

- -

感谢您帮助我们测试这些内容。 它们是更大项目的一部分。 我们正在迁移我们的 浏览器兼容性数据至结构化JSON.

- -

当数据转换为新的格式时,新的表格将出现在页面上。

- -

编辑

- -

我们的兼容性数据已经转移到了Github 上 browser-compat-data 的JSON文件。

- -

若您想贡献兼容性数据,您可以在存储库上提交拉取请求(Pull request)或发起issue。

- -

如何帮助

- -

如果您在数据之中发现问题,请在 GitHub 上提交 Issue.

- -

若表格外观或功能出现问题,请点击表格上方的下拉菜单中的“报告错误”按钮。

- -

如果您有时间参与我们的调查,我们将不胜感激。

diff --git a/files/zh-cn/npclass/index.html b/files/zh-cn/npclass/index.html deleted file mode 100644 index b207ae7b46..0000000000 --- a/files/zh-cn/npclass/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: NPClass -slug: NPClass -translation_of: Archive/Plugins/Reference/NPClass ---- -

« Gecko Plugin API Reference « Scripting plugins

- -

Summary

- -

NPClass 是一个包含着一组函数指针的结构体。这些函数指针所指向的函数是组成NPClass某个实例(例如一个NPObject)的所有行为 。

- -

Syntax

- -
struct NPClass
-{
-  uint32_t structVersion;
-  NPAllocateFunctionPtr allocate;
-  NPDeallocateFunctionPtr deallocate;
-  NPInvalidateFunctionPtr invalidate;
-  NPHasMethodFunctionPtr hasMethod;
-  NPInvokeFunctionPtr invoke;
-  NPInvokeDefaultFunctionPtr invokeDefault;
-  NPHasPropertyFunctionPtr hasProperty;
-  NPGetPropertyFunctionPtr getProperty;
-  NPSetPropertyFunctionPtr setProperty;
-  NPRemovePropertyFunctionPtr removeProperty;
-  NPEnumerationFunctionPtr enumerate;
-  NPConstructFunctionPtr construct;
-};
-
- -
警告:不要直接调用这些函数,你应该使用这些 API functions.
- -

Fields

- -
-
structVersion
-
结构体的版本号。它的值是NP_STRUCT_VERSION。在Mozilla 1.8.*中,NP_STRUCT_VERSION的值是1, 从Mozilla 1.9a1开始变成2, 从Firefox 3.0b1开始是3。
-
allocate
-
返回一个新分配的 NPObject对象的指针。 如果该指针不为空,则将会被NPN_CreateObject()函数调用, 否则浏览器会调用 malloc()。 这个函数应该分配并且返回能保存创建出来的NPObject对象的存储区域。
-
deallocate
-
当一个对象的引用计数为零的时候被NPN_ReleaseObject()调用。如果这个指针为空,那浏览器就直接调free()函数。
-
invalidate
-
当属于一个插件实例的活跃对象(live objects)被销毁时被调用。这个函数通常在 deallocate 函数或者free()之前被调用。 任何对失效对象(invalidated object)的操作都会导致未定义的行为。
-
hasMethod
-
NPN_HasMethod()调用,用来判断在给定的NPObject中是否存在某个特定的方法。返回true 如果该方法存在,否则返回false.
-
invoke
-
NPN_Invoke()调用,来调用给定NPObject对象中的指定方法。如果调用成功,返回true,如果任何错误产生则返回false。
-
invokeDefault
-
NPN_InvokeDefault()调用,来调用给定NPObject对象中的默认方法(该对象有默认方法的话)。如果调用成功,返回true,如果任何错误产生则返回false。
-
hasProperty
-
NPN_HasProperty()调用,来检查给定NPObject对象中是否存在某个属性。返回true如果存在该属性,否则返回false。
-
getProperty
-
NPN_GetProperty()调用,来获取给定NPObject对象中的某个属性。返回true如果属性获取成功,否则返回false。
-
setProperty
-
NPN_SetProperty()调用,来设置给定NPObject对象中的某个属性。返回true如果属性设置成功,否则返回false。
-
removeProperty
-
NPN_RemoveProperty()调用,来删除给定NPObject对象中的某个属性。返回true如果属性删除成功,否则返回false。
-
enumerate
-
NPN_Enumerate调用。只有当structVersion的值大于等于NP_CLASS_STRUCT_VERSION_ENUM (2)时,该指针才有效。
-
construct
-
NPN_Construct调用。只有当structVersion的值大于等于NP_CLASS_STRUCT_VERSION_CTOR (3),该指针才有效。
-
- -

Function pointer syntax

- -
typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);
-typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);
-typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);
-typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
-typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,
-                                    const NPVariant *args, uint32_t argCount,
-                                    NPVariant *result);
-typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,
-                                           const NPVariant *args,
-                                           uint32_t argCount,
-                                           NPVariant *result);
-typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
-typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
-                                         NPVariant *result);
-typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
-                                         const NPVariant *value);
-typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,
-                                            NPIdentifier name);
-typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value,
-                                         uint32_t *count);
-typedef bool (*NPConstructFunctionPtr)(NPObject *npobj,
-                                       const NPVariant *args,
-                                       uint32_t argCount,
-                                       NPVariant *result);
-
- -

See also

- - diff --git a/files/zh-cn/npobject/index.html b/files/zh-cn/npobject/index.html deleted file mode 100644 index 9bf5bc580f..0000000000 --- a/files/zh-cn/npobject/index.html +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: NPObject -slug: NPObject -translation_of: Archive/Plugins/Reference/NPObject ---- -
-
« Gecko Plugin API Reference « Scripting plugins
-
- -

Summary

- -

NPObject 是个包含着一个指向 NPClass 的指针,和一个整型的引用计数,还有可能的特定成员的实现(特定插件,或者特定的浏览器)的结构体。

- -

NPObject 是用来展示被插件或者浏览器通过这些API暴露出来的对象的类型。浏览器通过这些API来暴露他们的窗口对象和其他可以通过它来获取的东西。

- -

NPObjects 是有引用计数的对象, 所以调用者必须谨慎地释放他们的引用. Mozilla 提供了 NPN_CreateObject(), NPN_RetainObject(), NPN_ReleaseObject(), 和 NPN_ReleaseVariantValue()这些函数来增加引用技术和进行常规的所有权的管理。

- -

NPObject 的行为是通过调用 NPClass 中定义的一组回调函数来实现的.

- -

Syntax

- -
struct NPObject {
-  NPClass *_class;
-  uint32_t referenceCount;
-  /*
-   * Additional space may be allocated here by types of NPObjects
-   */
-};
-
- -

Fields

- -
-
_class
-
指向标明当前对象是哪个 NPClass 的成员的指针.
-
referenceCount
-
对象的引用计数.
-
- -
警告:不要直接操纵_class 和 referenceCount 成员,用下面的函数来完成对它们的控制。
- -

Functions

- - - -

See also

- - diff --git a/files/zh-cn/nsidomparser/index.html b/files/zh-cn/nsidomparser/index.html deleted file mode 100644 index 6b27366e91..0000000000 --- a/files/zh-cn/nsidomparser/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: nsIDOMParser -slug: nsIDOMParser -tags: - - DOMParser - - nsIDOMParser -translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMParser ---- -
- 注意: 如果你是一名 Web 开发者, 请参考 DOMParser 文档。
-

创建 DOMParser

-

To create a DOMParser object from a web page or a chrome script running in a window, simply use new DOMParser(). When you create a DOMParser from a privileged script, you can pass parameters to the constructor, more on that below.

-

To create a DOMParser when the constructor is not available (e.g., from a JS XPCOM component, a JS module, or an xpcshell test), use:

-
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
-             .createInstance(Components.interfaces.nsIDOMParser);
-// optionally, call parser.init(principal, documentURI, baseURI);
-
-

Principals, document and base URI

-

Note: This section covers changes introduced to DOMParser in Gecko 1.9.

-

(This section is only relevant to Firefox extensions--not to Web content.)

-

To create a document, the parser needs to specify a principal (see Security check basics), a base URI (see document.baseURIObject), and a documentURI.

-

These values are automatically determined as defined below, but if you work with DOMParser from privileged code, you can override the defaults by providing arguments to the DOMParser constructor or calling parser.init(). Usually you don't need to do that. If you come across a situation when these matter, feel free to ask questions in mozilla.dev.tech.dom and update this documentation to mention these cases.

- -

Cases where these values matter:

- -

解析字符串

-

Web platform documentation 中所述的,一旦你已创建了一个 DOMParser 对象,你可以使用它的 parseFromString 方法来解析 XML 或 HTML。

-

示例

-

Within the context of a window:

-
var parser = new DOMParser();
-var doc = parser.parseFromString(aStr, "application/xml");
-
-

Outside of a window (e.g., a JS XPCOM component, a JS module, or an xpcshell test):

-
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
-             .createInstance(Components.interfaces.nsIDOMParser);
-var doc = parser.parseFromString(aStr, "application/xml");
-
-

Using Components.Constructor():

-
const DOMParser = new Components.Constructor("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
-var parser = new DOMParser();
-parser.init(principal, documentURI, baseURI);
-var doc = parser.parseFromString(aStr, "application/xml");
-
diff --git a/files/zh-cn/nss/building/index.html b/files/zh-cn/nss/building/index.html deleted file mode 100644 index 2d7adf09b2..0000000000 --- a/files/zh-cn/nss/building/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Building NSS -slug: NSS/Building -translation_of: Mozilla/Projects/NSS/Building ---- -

介绍

- - - -

此页包含有关如何构建NSS的详细信息。因为NSS是一个跨平台的库,它构建在许多不同的平台上,并且有许多选项,所以构建起来可能很复杂。在尝试构建之前,请仔细阅读这些说明。

- -

Build 环境

- -

NSS需要一个C和C++编译器。它有最小的依赖关系,包括标准的C和C++库,再加上ZLIB。

- -

For building, you also need make.  Ideally, also install gyp and ninja and put them on your path.  This is recommended, as the build is faster and more reliable.

- -

Windows

- -

Windows上的NSS编译使用与Mozilla Firefox相同的共享生成系统。 你必须先安装 Windows Prerequisites, 包括 MozillaBuild.

- -

您还可以在Windows子系统上为Linux构建NSS,但是生成的二进制文件不能被其他Windows应用程序使用。

- -

获取源码

- - - -

NSS和NSPR像其他Mozilla项目一样使用Mercurial进行源代码管理。 要查看NSS和NSPR的最新源(可能不是稳定版本的一部分),请使用以下命令:

- -
hg clone https://hg.mozilla.org/projects/nspr
-hg clone https://hg.mozilla.org/projects/nss
-
- -

To get the source of a specific release, see NSS Releases.

- -
-
-
-
-
-
- -

Build

- -

Build NSS using our build script:

- -
nss/build.sh
-
- -

This builds both NSPR and NSS.

- -

Build with make

- -

Alternatively, there is a make target called "nss_build_all", which produces a similar result.  This supports some alternative options, but can be a lot slower.

- -
make -C nss nss_build_all USE_64=1
-
- -

The make-based build system for NSS uses a variety of variables to control the build. Below are some of the variables, along with possible values they may be set to.

- -
-
BUILD_OPT
-
-
-
0
-
Build a debug (non-optimized) version of NSS. This is the default.
-
1
-
Build an optimized (non-debug) version of NSS.
-
-
-
USE_64
-
-
-
0
-
Build for a 32-bit environment/ABI. This is the default.
-
1
-
Build for a 64-bit environment/ABI. This is recommended.
-
-
-
USE_ASAN
-
-
-
0
-
Do not create an AddressSanitizer build. This is the default.
-
1
-
Create an AddressSanitizer build.
-
-
-
- -

单元测试

- -

NSS包含大量的单元测试。运行这些测试的脚本可以在测试目录中找到。 通过以下方式运行标准套件:

- -
HOST=localhost DOMSUF=localdomain USE_64=1 nss/tests/all.sh
- -

单元测试配置

- -

NSS测试是使用环境变量配置的。
- 脚本将尝试推断主机和DOMSUF的值,但可能会失败。 用主机名和域后缀替换localhost和localdomain。 您需要能够连接到$HOST.$DOMSUF。

- -

如果没有域后缀,则可以将条目添加到/etc/hosts (on Windows, c:\Windows\System32\drivers\etc\hosts) as follows:

- -
127.0.0.1 localhost.localdomain
- -

验证是否打开命令shell并键入: ping localhost.localdomain.

- -

Remove the USE_64=1 override if using a 32-bit build.

- -

测试结果

- -

运行所有测试可能需要相当长的时间。

- -

测试输出存储在tests_results/security/$HOST.$NUMBER/中。 文件results.html概要结果,output.log捕获所有测试输出。

- -

nss/tests的其他子目录包含运行完整套件子集的脚本。 它们可以直接运行,而不是all.sh,这可能会节省一些时间,但会降低覆盖率。

diff --git a/files/zh-cn/nss/index.html b/files/zh-cn/nss/index.html deleted file mode 100644 index d12ceec9a1..0000000000 --- a/files/zh-cn/nss/index.html +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: Network Security Services -slug: NSS -tags: - - JSS - - NSS - - NeedsMigration - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Projects/NSS ---- -

网络安全服务 (NSS) 是一组旨在支持支持安全的客户端和服务器应用程序跨平台开发的库。使用NSS构建的应用程序可以支持 SSL v2 和 v3 、TLS 、 PKCS #5 、 PKCS #7 、 PKCS #11 、 PKCS #12 、 S/MIME 、 X.509 v3 证书以及其他安全标准。

- -

有关支持的标准的详细信息,请参阅NSS概述。有关常见问题的列表,请参阅FAQ

- -

NSS可在Mozilla公共许可证下使用。有关将NSS发布版本下载为tar文件的信息,请参阅下载PKI源文件

- -

如果您是一名开发人员,并希望为NSS做出贡献,您可能需要阅读NSS内部详细信息的文档高级概述,并开始使用NSS

- - - - - - - - -
-

文档

- -

背景信息

- -
-
NSS概况
-
NSS简介及功能说明
-
NSS答疑
-
常见基础问题解答
-
公钥加密技术简介
-
解释NSS背后公钥加密技术的基础概念
-
SSL简介
-
介绍SSL协议,包括其支持的加密密码相关的信息以及SSL握手过程中的相关步骤
-
- -

开始使用

- -
-
NSS发布版本页面
-
页面中包含最新以及历史版本的NSS发布版的内容。
-
获取并运行源代码
-
说明如何在不同支持的平台上构建NSS
-
使用Mercurial获取Mozilla的源代码
-
说明如何使用Mercurial进行工作
-
使用CVS获取Mozilla的源代码(已弃用)
-
已废弃的旧版本CVS文档
-
- -

NSS API文档

- -
-
网络安全服务介绍
-
提供NSS库的概览与使用他们所需的前置知识
-
NSS SSL公用函数
-
总结NSS共享库暴露的SSL API
-
NSS Reference
-
API used to invoke SSL operations.
-
NSS API Guidelines
-
Explains how the libraries and code are organized, and guidelines for developing code (naming conventions, error handling, thread safety, etc.)
-
NSS Technical Notes
-
Links to NSS technical notes, which provide latest information about new NSS features and supplementary documentation for advanced topics in programming with NSS.
-
- -

工具、测试和其他技术细节

- -
-
Build Instructions for NSS
-
Describe how to check out and build NSS releases.
-
NSS Tools
-
Tools for developing, debugging, and managing applications that use NSS.
-
Sample Code
-
Demonstrates how NSS can be used for cryptographic operations, certificate handling, SSL, etc.
-
NSS 3.2 Test Suite
-
Archived version. Describes how to run the standard NSS tests.
-
NSS Performance Reports
-
Archived version. Links to performance reports for NSS 3.2 and later releases.
-
Encryption Technologies Available in NSS 3.11
-
Archived version. Lists the cryptographic algorithms used by NSS 3.11.
-
NSS 3.1 Loadable Root Certificates
-
Archived version. Describes the scheme for loading root CA certificates.
-
cert7.db
-
Archived version. General format of the cert7.db database.
-
- -

PKCS #11 information

- - - -
-
- -

CA certificates pre-loaded into NSS

- - - -
-
- -

NSS is built on top of Netscape Portable Runtime (NSPR)

- -
-
Netscape Portable Runtime
-
NSPR project page.
-
NSPR Reference
-
NSPR API documentation.
-
- -

附加信息

- - - -

测试

- - - -

计划

- -

Information on NSS planning can be found at wiki.mozilla.org, including:

- - -
-

社区

- -
    -
  • 查看Mozilla安全论坛...
  • -
- -

{{ DiscussionList("dev-security", "mozilla.dev.security") }}

- -
    -
  • 查看Mozilla加密论坛...
  • -
- -

{{ DiscussionList("dev-tech-crypto", "mozilla.dev.tech.crypto") }}

- - - - -
diff --git a/files/zh-cn/nss/introduction_to_network_security_services/index.html b/files/zh-cn/nss/introduction_to_network_security_services/index.html deleted file mode 100644 index a65951eb1f..0000000000 --- a/files/zh-cn/nss/introduction_to_network_security_services/index.html +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: Introduction to Network Security Services -slug: NSS/Introduction_to_Network_Security_Services -translation_of: Mozilla/Projects/NSS/Introduction_to_Network_Security_Services ---- -

Network Security Services (NSS) 是被设计为支持跨平台开发支持SSL,S/MIME和他气网络安全标准一组库。有关NSS及其支持的标准的概述,请参见Overview of NSS.

- -

共享库

- -

网络安全服务提供静态库和共享库。 使用共享库的应用程序必须只使用它们导出的api。 三个共享库导出公共功能:

- - - -

We guarantee that applications using the exported APIs will remain compatible with future versions of those libraries. For a complete list of public functions exported by these shared libraries in NSS 3.2, see NSS functions.

- -

For information on which static libraries in NSS 3.1.1 are replaced by each of the above shared libraries in NSS 3.2 , see Migration from NSS 3.1.1.

- -

Figure 1, below, shows a simplified view of the relationships among the three shared libraries listed above and NSPR, which provides low-level cross platform support for operations such as threading and I/O. (Note that NSPR is a separate Mozilla project; see Netscape Portable Runtime for details.)

- -
-
Figure 1 Relationships among core NSS libraries and NSPR
-
- -

Diagram showing the relationships among core NSS libraries and NSPR.

- -

Naming conventions and special libraries

- -

Windows and Unix use different naming conventions for static and dynamic libraries:

- - - - - - - - - - - - - - - - - - - -
WindowsUnix
static.lib.a
dynamic.dll.so or .sl
- -

In addition, Windows has "import" libraries that bind to dynamic libraries. So the NSS library has the following forms:

- - - -

NSS, SSL, and S/MIME have all of the above forms.

- -

The following static libaries aren't included in any shared libraries

- - - -

The following static libaries are included only in external loadable PKCS #11 modules:

- - - -

The following shared libraries are standalone loadable modules, not meant to be linked with directly:

- - - -

Support for ILP32

- -

In NSS 3.2 and later versions, there are two new shared libraries for the platforms HP-UX for PARisc CPUs and Solaris for (Ultra)Sparc (not x86) CPUs. These HP and Solaris platforms allow programs that use the ILP32 program model to run on both 32-bit CPUs and 64-bit CPUs. The two libraries exist to provide optimal performance on each of the two types of CPUs.

- -

These two extra shared libraries are not supplied on any other platforms. The names of these libraries are platform-dependent, as shown in the following table.

- - - - - - - - - - - - - - - - - - - - - - - - -
Platformfor 32-bit CPUsfor 64-bit CPUs
Solaris/Sparclibfreebl_pure32_3.solibfreebl_hybrid_3.so
HPUX/PARisclibfreebl_pure32_3.sllibfreebl_hybrid_3.sl
AIX (planned for a future release)libfreebl_pure32_3_shr.alibfreebl_hybrid_3_shr.a
- -

An application should not link against these libraries, because they are dynamically loaded by NSS at run time. Linking the application against one or the other of these libraries may produce an application program that can only run on one type of CPU (e.g. only on 64-bit CPUs, not on 32-bit CPUs) or that doesn't use the more efficient 64-bit code on 64-bit CPUs, which defeats the purpose of having these shared libraries.

- -

On platforms for which these shared libraries exist, NSS 3.2 will fail if these shared libs are not present. So, an application must include these files in its distribution of NSS shared libraries. These shared libraries should be installed in the same directory where the other NSS shared libraries (such as libnss3.so) are installed. Both shared libs should always be installed whether the target system has a 32-bit CPU or a 64-bit CPU. NSS will pick the right one for the local system at run time.

- -

Note that NSS 3.x is also available in the LP64 model for these platforms, but the LP64 model of NSS 3.x does not have these two extra shared libraries.

- -

What you should already know

- -

在使用NSS之前,您应该熟悉以下主题:

- - - -

Where to find more information

- -

For information about PKI and SSL that you should understand before using NSS, see the following:

- - - -

For links to API documentation, build instructions, and other useful information, see the NSS Project Page.

- -

As mentioned above, NSS is built on top of NSPR. The API documentation for NSPR is available at NSPR API Reference.

diff --git a/files/zh-cn/nss/key_log_format/index.html b/files/zh-cn/nss/key_log_format/index.html deleted file mode 100644 index a997036b31..0000000000 --- a/files/zh-cn/nss/key_log_format/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: NSS Key Log Format -slug: NSS/Key_Log_Format -tags: - - NSS Key Log Format -translation_of: Mozilla/Projects/NSS/Key_Log_Format ---- -
-

Starting with NSS 3.24 (around Firefox 48), the SSLKEYLOGFILE approach is disabled by default. Distributors can re-enable it at compile time though which is done for the official Firefox binaries. (See bug 1188657.)  it should work again on Firefox >= 50

-
- -

Key logs can be written by NSS so that external programs can decrypt TLS connections. Wireshark 1.6.0 and above can use these log files to decrypt packets. You can tell Wireshark where to find the key file via Edit→Preferences→Protocols→SSL→(Pre)-Master-Secret log filename.

- -

Key logging is enabled by setting the environment variable SSLKEYLOGFILE <FILE> to point to a file. This file is a series of lines. Comment lines begin with a sharp character ('#'). Otherwise the line takes one of these formats.

- -

RSA <space> <16 bytes of hex encoded encrypted pre master secret> <space> <96 bytes of hex encoded pre master secret>

- -

CLIENT_RANDOM <space> <64 bytes of hex encoded client_random> <space> <96 bytes of hex encoded master secret>

- -

The RSA form allows ciphersuites using RSA key-agreement to be logged and is supported in shipping versions of Wireshark. The CLIENT_RANDOM format allows other key-agreement algorithms to be logged but is only supported starting with Wireshark 1.8.0. For Wireshark usage, see SSL - Wireshark Wiki.

diff --git a/files/zh-cn/nss/overview/index.html b/files/zh-cn/nss/overview/index.html deleted file mode 100644 index d452abed79..0000000000 --- a/files/zh-cn/nss/overview/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: Overview of NSS -slug: NSS/Overview -translation_of: Mozilla/Projects/NSS/Overview ---- -

Open Source Crypto Libraries

- -

Proven Application Security Architecture

- -

If you want to add support for SSL, S/MIME, or other Internet security standards to your application, you can use Network Security Services (NSS) to implement all your security features. NSS provides a complete open-source implementation of the crypto libraries used by AOL, Red Hat, Google, and other companies in a variety of products, including the following:

- - - -

NSS includes a framework to which developers and OEMs can contribute patches, such as assembler code, to optimize performance on their platforms. NSS 3.x has been certified on 18 platforms.

- -

For more detailed information about NSS, see wiki.mozilla.org and NSS FAQ.

- -

Source code for a Java interface to NSS is available in the Mozilla CVS tree. For details, see Network Security Services for Java.

- -

NSS makes use of Netscape Portable Runtime (NSPR), a platform-neutral open-source API for system functions designed to facilitate cross-platform development. Like NSS, NSPR has been battle-tested in multiple products. For more information, see the NSPR Project Page.

- -

互操作性和开放标准

- -

你可以使用NSS去支持一系列安全标准在你的应用中,包括如下:

- - - -

For complete details, see Encryption Technologies.

- -

FIPS 140 Validation and NISCC Testing

- -

The NSS software crypto module has been validated three times for conformance to FIPS 140 at Security Levels 1 and 2. For more information, see the NSS FIPS page (Or this one).

- -

The NSS libraries passed the NISCC TLS/SSL and S/MIME test suites (1.6 million test cases of invalid input data).

- -

Complete Software Development Kit

- -

除了开发库和APIs,NSS还提供了security tools工具以提供调试,诊断,证书和密钥管理,密码学模块管理和其他开发任务.

- -

NSS comes with an extensive and growing set of documentation, including introductory material, API references, man pages for command-line tools, and sample code.

- -

NSS is available as source and shared (dynamic) libraries. Every NSS release is backward compatible with previous releases, allowing NSS users to upgrade to the new NSS shared libraries without recompiling or relinking their applications.

- -

Open-Source Licensing and Distribution

- -

NSS is available under the Mozilla Public License, version 2. The latest source code is available for free worldwide from https://www.mozilla.org and its mirror sites.

diff --git a/files/zh-cn/nss/tools/index.html b/files/zh-cn/nss/tools/index.html deleted file mode 100644 index b0971d9bae..0000000000 --- a/files/zh-cn/nss/tools/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: NSS Tools -slug: NSS/tools -tags: - - NSS - - NeedsTranslation - - TopicStub -translation_of: Mozilla/Projects/NSS/tools ---- -

NSS Security Tools

-

Newsgroup: mozilla.dev.tech.crypto

-

Overview

-

The NSS Security Tools allow developers to test, debug, and manage applications that use NSS. The Tools Information table below describes both the tools that are currently working and those that are still under development. The links for each tool take you to the source code, documentation, plans, and related links for each tool. The links will become active when information is available.

-

Currently, you must download the NSS 3.1 source and build it to create binary files for the NSS tools. For information about downloading the NSS source, see https://developer.mozilla.org/NSS/Building.

-

If you have feedback or questions, please feel free to post to mozilla.dev.tech.crypto. This newsgroup is the preferred forum for all questions about NSS and NSS tools.

-

Overall Objectives

-
    -
  1. Provide a tool for analyzing and repairing certificate databases (dbck).
  2. -
  3. Migrate tools from secutil.h interface to PKCS #11 interface.
  4. -
  5. Eliminate redundant functionality in tools. Many tools implement private versions of PKCS11Init(), OpenCertDB(), etc.
  6. -
  7. Eliminate use of getopt() and replace with NSPR calls to get command options (to eliminate platform dependencies with getopt()).
  8. -
-

Tools Information

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ToolDescriptionLinks
certutil 2.0Manage certificate and key databases (cert7.db and key3.db).Source, Documentation, Tasks/Plans
cmsutil 1.0Performs basic CMS operations such as encrypting, decrypting, and signing messages.Source, Documentation
crlutilManage certificate revocation lists (CRLs).Source, Documentation,
dbck 1.0Analyze and repair certificate databases (not working in NSS 3.2)Source, Tasks/Plans
modutil 1.1Manage the database of PKCS11 modules (secmod.db). Add modules and modify the properties of existing modules (such as whether a module is the default provider of some crypto service).Source, Documentation, Tasks/Plans
pk12util 1.0Import and export keys and certificates between the cert/key databases and files in PKCS12 format.Source, Documentation, Tasks/Plans
signtool 1.3Create digitally-signed jar archives containing files and/or code.Source, Documentation,
signver 1.1Verify signatures on digitally-signed objects.Source, Documentation, Tasks/Plans
sslstrengthSSL StrengthDocumentation
ssltap 3.2Proxy requests for an SSL server and display the contents of the messages exchanged between the client and server. The ssltap tool does not decrypt data, but it shows things like the type of SSL message (clientHello, serverHello, etc) and connection data (protocol version, cipher suite, etc). This tool is very useful for debugging.Source, Documentation
-

 

-
    -
  1. Currently points to the Netscape Certificate Management System Administration Guide on docs.sun.com. For additional information about this tool, see Object Signing.
  2. -
  3. Currently points to the signver documentation on developer.netscape.com. For additional information about this tool, see Form Signing
  4. -
diff --git "a/files/zh-cn/nss/tools/nss_\345\267\245\345\205\267_certutil/index.html" "b/files/zh-cn/nss/tools/nss_\345\267\245\345\205\267_certutil/index.html" deleted file mode 100644 index 7707907d64..0000000000 --- "a/files/zh-cn/nss/tools/nss_\345\267\245\345\205\267_certutil/index.html" +++ /dev/null @@ -1,924 +0,0 @@ ---- -title: NSS 工具 certutil -slug: NSS/tools/NSS_工具_certutil -translation_of: Mozilla/Projects/NSS/tools/NSS_Tools_certutil ---- -

证书数据库工具使用说明

-

Newsgroup: mozilla.dev.tech.crypto

-

证书数据库工具是基于命令行的工具,能创建和修改Netscape Communicator cerct8.db 和 key3.db 数据库文件。该工具也能列出,生成,修改或者删除cert8.db里的证书,并且可以创建或修改密码,生成新的公钥和私钥对,显示秘钥数据库的内容,或者删除key3.db的秘钥对。

-

秘钥和证书管理流程一般由两部分组成:1) 在秘钥数据库里创建秘钥 2) 在证书数据库中生成并管理证书

-

该文档主要描述了证书和秘钥数据库的管理。对于信息安全模块数据库管理,请看安全模块数据库工具使用

-

可用性

-

请查看 release notes 以了解该工具在哪些平台可用

-

语法

-

使用如下命令运行数据库工具

-

certutil - - option - [ - - arguments - ]

-

本例例举的Option 和 arguments是下述列表的option和arguments的结合 . 每个命令可以指定一个option.每个option可以携带0或多个arguments. 查看命令用法可以通过两种方式: 输入没有option的命令或者输入命令制定 option -H.

-

Options 和 Arguments

-

Options 是大写的字符,主要指定命令要完成的操作. Option arguments 是小写的字符,主要修改操作的细节. 证书数据库工具命令 options 和其的arguments定义如下:

-

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Options -

-
-

-N

-
-

创建新的证书和秘钥数据库.

-
-

-S

-
-

创建单独的证书,并且将证书加入证书数据库.

-
-

-R

-
-

创建 一个 certificate-request 文件, 该证书可以提交到Certificate Authority(CA) 以生成完整证书. 如果不指定option -O output-file argument,输出默认到标准输出

-

-

使用-a argument 以指定ASCII编码输出

-
-

-C

-
-

Create a new binary certificate file from a binary certificate-request file. Use the -i argument to specify the certificate-request file. If this argument is not used Certificate Database Tool prompts for a filename.

-
-

-G

-
-

Generate a new public and private key pair within a key database. The key database should already exist; if one is not present, this option will initialize one by default.

-

-

Some smart cards (for example, the Litronic card) can store only one key pair. If you create a new key pair for such a card, the previous pair is overwritten.

-
-

-F

-
-

Delete a private key from a key database. Specify the key to delete with the -n argument. Specify the database from which to delete the key with the -d argument.

-

-

Use the -k argument to specify explicitly whether to delete a DSA or an RSA key. If you don't use the -k argument, the option looks for an RSA key matching the specified nickname.

-

-

When you delete keys, be sure to also remove any certificates associated with those keys from the certificate database, by using -D.

-

-

Some smart cards (for example, the Litronic card) do not let you remove a public key you have generated. In such a case, only the private key is deleted from the key pair. You can display the public key with the command certutil -K -h - - tokenname - .

-
-

-K

-
-

List the keyID of keys in the key database. A keyID is the modulus of the RSA key or the publicValue of the DSA key. IDs are displayed in hexadecimal ("0x" is not shown).

-
-

-A

-
-

Add an existing certificate to a certificate database. The certificate database should already exist; if one is not present, this option will initialize one by default.

-
-

-D

-
-

Delete a certificate from the certificate database.

-
-

-L

-
-

List all the certificates, or display information about a named certificate, in a certificate database.

-

-

Use the -h - - tokenname - argument to specify the certificate database on a particular hardware or software token.

-
-

-V

-
-

Check the validity of a certificate and its attributes.

-
-

-M

-
-

Modify a certificate's trust attributes using the values of the -t argument.

-
-

-H

-
-

Display a list of the options and arguments used by the Certificate Database Tool.

-
-

-W

-
-

Change the password to a key database.

-
-

-U

-
-

List all available modules or print a single named module.

-
-

Arguments

-
-

-
-

-a

-
-

Use ASCII format or allow the use of ASCII format for input or output. This formatting follows RFC #1113. For certificate requests, ASCII output defaults to standard output unless redirected.

-
-

-b - - validity-time -

-
-

Specify a time at which a certificate is required to be valid. Use when checking certificate validity with the -V option. The format of the - - validity-time - argument is "YYMMDDHHMMSS[+HHMM|-HHMM|Z]". Specifying seconds (SS) is optional. When specifying an explicit time, use "YYMMDDHHMMSSZ". When specifying an offset time, use "YYMMDDHHMMSS+HHMM" or "YYMMDDHHMMSS-HHMM". If this option is not used, the validity check defaults to the current system time.

-
-

-c - - issuer -

-
-

Identify the certificate of the CA from which a new certificate will derive its authenticity. Use the exact nickname or alias of the CA certificate, or use the CA's email address. Bracket the - - issuer - string with quotation marks if it contains spaces.

-
-

-d - - directory -

-
-

Specify the database directory containing the certificate and key database files. On Unix the Certificate Database Tool defaults to $HOME/.netscape (that is, ~/.netscape). On Windows NT the default is the current directory.

-

-

The cert8.db and key3.db database files must reside in the same directory.

-
-

-P - - dbprefix -

-
-

Specify the prefix used on the cert8.db and key3.db files (for example, my_cert8.db and my_key3.db). This option is provided as a special case. Changing the names of the certificate and key databases is not recommended.

-
-

-e

-
-

Check a certificate's signature during the process of validating a certificate.

-
-

-f - - password-file -

-
-

Specify a file that will automatically supply the password to include in a certificate or to access a certificate database. This is a plain-text file containing one password. Be sure to prevent unauthorized access to this file.

-
-

-g - - keysize -

-
-

Set a key size to use when generating new public and private key pairs. The minimum is 512 bits and the maximum is 8192 bits. The default is 1024 bits. Any size that is a multiple of 8 between the minimum and maximum is allowed.

-
-

-h - - tokenname -

-
-

Specify the name of a token to use or act on. Unless specified otherwise the default token is an internal slot (specifically, internal slot 2). This slot can also be explicitly named with the string "internal". An internal slots is a virtual slot maintained in software, rather than a hardware device. Internal slot 2 is used by key and certificate services. Internal slot 1 is used by cryptographic services.

-
-

-i - - cert|cert-request-file -

-
-

Specify a specific certificate, or a certificate-request file.

-
-

-k rsa|dsa|all

-
-

Specify the type of a key: RSA, DSA or both. The default value is rsa. By specifying the type of key you can avoid mistakes caused by duplicate nicknames.

-
-

-l

-
-

Display detailed information when validating a certificate with the -V option.

-
-

-m - - serial-number -

-
-

Assign a unique serial number to a certificate being created. This operation should be performed by a CA. The default serial number is 0 (zero). Serial numbers are limited to integers.

-
-

-n - - nickname -

-
-

Specify the nickname of a certificate or key to list, create, add to a database, modify, or validate. Bracket the - - nickname - string with quotation marks if it contains spaces.

-
-

-o - - output-file -

-
-

Specify the output file name for new certificates or binary certificate requests. Bracket the - - output-file - string with quotation marks if it contains spaces. If this argument is not used the output destination defaults to standard output.

-
-

-p - - phone -

-
-

Specify a contact telephone number to include in new certificates or certificate requests. Bracket this string with quotation marks if it contains spaces.

-
-

-q - - pqgfile -

-
-

Read an alternate PQG value from the specified file when generating DSA key pairs. If this argument is not used, the Key Database Tool generates its own PQG value. PQG files are created with a separate DSA utility.

-
-

-r

-
-

Display a certificate's binary DER encoding when listing information about that certificate with the -L option.

-
-

-s - - subject -

-
-

Identify a particular certificate owner for new certificates or certificate requests. Bracket this string with quotation marks if it contains spaces. The subject identification format follows RFC #1485.

-
-

-t - - trustargs -

-
-

Specify the trust attributes to modify in an existing certificate or to apply to a certificate when creating it or adding it to a database.

-

-

There are three available trust categories for each certificate, expressed in this order: " - - SSL - , - - email - , - - object signing - ". In each category position use zero or more of the following attribute codes:

-

-

p    Valid peer
- P    Trusted peer (implies p)
- c    Valid CA
- T    Trusted CA to issue client certificates (implies c)
- C    Trusted CA to issue server certificates (SSL only)
-       (implies c)
- u    Certificate can be used for authentication or signing
- w    Send warning (use with other attributes to include a warning when the certificate is used in that context)

-

-

The attribute codes for the categories are separated by commas, and the entire set of attributes enclosed by quotation marks. For example:

-

-t "TCu,Cu,Tuw"

-

-

Use the -L option to see a list of the current certificates and trust attributes in a certificate database.

-
-

-u - - certusage -

-
-

Specify a usage context to apply when validating a certificate with the -V option. The contexts are the following:

-

-

C (as an SSL client)
- V (as an SSL server)
- S (as an email signer)
- R (as an email recipient)

-
-

-v - - valid-months -

-
-

Set the number of months a new certificate will be valid. The validity period begins at the current system time unless an offset is added or subtracted with the -w option. If this argument is not used, the default validity period is three months. When this argument is used, the default three-month period is automatically added to any value given in the - - valid-month - argument. For example, using this option to set a value of 3 would cause 3 to be added to the three-month default, creating a validity period of six months. You can use negative values to reduce the default period. For example, setting a value of -2 would subtract 2 from the default and create a validity period of one month.

-
-

-w - - offset-months -

-
-

Set an offset from the current system time, in months, for the beginning of a certificate's validity period. Use when creating the certificate or adding it to a database. Express the offset in integers, using a minus sign (-) to indicate a negative offset. If this argument is not used, the validity period begins at the current system time. The length of the validity period is set with the -v argument.

-
-

-x

-
-

Use the Certificate Database Tool to generate the signature for a certificate being created or added to a database, rather than obtaining a signature from a separate CA.

-
-

-y - - exp -

-
-

Set an alternate exponent value to use in generating a new RSA public key for the database, instead of the default value of 65537. The available alternate values are 3 and 17.

-
-

-z - - noise-file -

-
-

Read a seed value from the specified binary file to use in generating a new RSA private and public key pair. This argument makes it possible to use hardware-generated seed values and unnecessary to manually create a value from the keyboard. The minimum file size is 20 bytes.

-
-

-1

-
-

Add a key usage extension to a certificate that is being created or added to a database. This extension allows a certificate's key to be dedicated to supporting specific operations such as SSL server or object signing. The Certificate Database Tool will prompt you to select a particular usage for the certificate's key. These usages are described under Standard X.509 v3 Certificate Extensions in Appendix A.3 of the - - Red Hat Certificate System Administration Guide. -

-
-

-2

-
-

Add a basic constraint extension to a certificate that is being created or added to a database. This extension supports the certificate chain verification process. The Certificate Database Tool will prompt you to select the certificate constraint extension. Constraint extensions are described in Standard X.509 v3 Certificate Extensions in Appendix A.3 of the - - Red Hat Certificate System Administration Guide. -

-
-

-3

-
-

Add an authority keyID extension to a certificate that is being created or added to a database. This extension supports the identification of a particular certificate, from among multiple certificates associated with one subject name, as the correct issuer of a certificate. The Certificate Database Tool will prompt you to select the authority keyID extension. Authority key ID extensions are described under Standard X.509 v3 Certificate Extensions in Appendix A.3 of the - - Red Hat Certificate System Administration Guide. -

-
-

-4

-
-

Add a CRL distribution point extension to a certificate that is being created or added to a database. This extension identifies the URL of a certificate's associated certificate revocation list (CRL). The Certificate Database Tool prompts you to enter the URL. CRL distribution point extensions are described in Standard X.509 v3 Certificate Extensions in Appendix A.3 of the - - Red Hat Certificate System Administration Guide. -

-
-

-5

-
-

Add a Netscape certificate type extension to a certificate that is being created or added to the database. Netscape certificate type extensions are described in Standard X.509 v3 Certificate Extensions in Appendix A.3 of the - - Red Hat Certificate System Administration Guide. -

-
-

-6

-
-

Add an extended key usage extension to a certificate that is being created or added to the database. Extended key usage extensions are described in Standard X.509 v3 Certificate Extensions in Appendix A.3 of the - - Red Hat Certificate System Administration Guide. -

-
-

-7 - - emailAddrs -

-
-

Add a comma-separated list of email addresses to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.

-
-

-8 - - dns-names -

-
-

Add a comma-separated list of DNS names to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.

-
- - - - - - -
 
-

 

-

Usage

-

The Certificate Database Tool's capabilities are grouped as follows, using these combinations of options and arguments. Options and arguments in square brackets are optional, those without square brackets are required.

-

 

-

 

-
- -N [-d - - certdir - ]
-

 

-
- -S -k rsa|dsa -n - - certname - -s - - subject -
- [-c - - issuer - |-x] -t - - trustargs - [-h - - tokenname - ]
- [-m
- - serial-number - ] [-v - - valid-months - ] [-w - - offset-months - ]
- [-d
- - certdir - ] [-p - - phone - ] [-f - - password-file - ] [-1] [-2] [-3] [-4]
-

 

-
- -R -k rsa|dsa -s - - subject - [-h - - tokenname - ]
- [-d
- - certdir - ] [-p - - phone - ] [-o - - output-file - ] [-f - - password-file - ]
-

 

-
- -C -c - - issuer - [-f - - password-file - ]
- [-h
- - tokenname - ] -i - - cert-request-file - -o - - output-file - [-m - - serial-number - ]
- [-v
- - valid-months - ] [-w - - offset-months - ] [-d - - certdir - ] [-1] [-2] [-3]
- [-4]
-

 

-
- -A -n - - certname - -t - - trustargs - [-h - - tokenname - ] [-d - - certdir - ] [-a]
- [-i
- - cert-request-file - ]
-

 

-
- -L [-n - - certname - ] [-d - - certdir - ] [-r] [-a]
-

 

-
- -V -n - - certname - -b - - validity-time - -u - - certusage - [-e] [-l] [-d - - certdir - ]
-

 

-
- -M -n - - certname - -t - - trustargs - [-d - - certdir - ]
-

 

-
- -H
- -

Examples

-

Creating a New Certificate Database
- Listing Certificates in a Database
- Creating a Certificate Request
- Creating a Certificate
- Adding a Certificate to the Database
- Validating a Certificate

-

 

-

Creating a New Certificate Database

-

This example creates a new certificate database (cert8.db file) in the specified directory:

-

 

-

certutil -N -d - - certdir -

-

 

-

You must generate the associated key3.db and secmod.db files by using the Key Database Tool or other tools.

-

 

-

Listing Certificates in a Database

-

This example lists all the certificates in the cert8.db file in the specified directory:

-

 

-

certutil -L -d - - certdir -

-

 

-

The Certificate Database Tool displays output similar to the following:

-

 

-

Certificate Name              Trust Attributes
- Uptime Group Plc. Class 1 CA        C,C,
- VeriSign Class 1 Primary CA         ,C,
- VeriSign Class 2 Primary CA         C,C,C
- AT&T Certificate Services           C,C,
- GTE CyberTrust Secure Server CA     C,,
- Verisign/RSA Commercial CA          C,C,
- AT&T Directory Services             C,C,
- BelSign Secure Server CA            C,,
- Verisign/RSA Secure Server CA       C,C,
- GTE CyberTrust Root CA              C,C,
- Uptime Group Plc. Class 4 CA        ,C,
- VeriSign Class 3 Primary CA         C,C,C
- Canada Post Corporation CA          C,C,
- Integrion CA                        C,C,C
- IBM World Registry CA               C,C,C
- GTIS/PWGSC, Canada Gov. Web CA      C,C,
- GTIS/PWGSC, Canada Gov. Secure CA   C,C,C
- MCI Mall CA                         C,C,
- VeriSign Class 4 Primary CA         C,C,C
- KEYWITNESS, Canada CA               C,C,
- BelSign Object Publishing CA        ,,C
- BBN Certificate Services CA Root 1  C,C,
- p    Valid peer
- P    Trusted peer (implies p)
- c    Valid CA
- T    Trusted CA to issue client certs (implies c)
- C    Trusted CA to issue server certs(for ssl only) (implies c)
- u    User cert
- w    Send warning

-

 

-

Creating a Certificate Request

-

This example generates a binary certificate request file named e95c.req in the specified directory:
- certutil -R -s "CN=John Smith, O=Netscape, L=Mountain View, ST=California, C=US" -p "650-555-8888" -o mycert.req -d - - certdir -
- Before it creates the request file, the Certificate Database Tool prompts you for a password:
- Enter Password or Pin for "Communicator Certificate DB":

-

 

-

Creating a Certificate

-

A valid certificate must be issued by a trusted CA. If a CA key pair is not available, you can create a self-signed certificate (for purposes of illustration) with the -x argument. This example creates a new binary, self-signed CA certificate named myissuer, in the specified directory.
- certutil -S -s "CN=My Issuer" -n myissuer -x -t "C,C,C" -1 -2 -5 -m 1234 -f - - password-file - -d - - certdir -
- The following example creates a new binary certificate named mycert.crt, from a binary certificate request named mycert.req, in the specified directory. It is issued by the self-signed certificate created above, myissuer.
- certutil -C -m 2345 -i mycert.req -o mycert.crt -c myissuer -d - - certdir -

-

 

-

 

-

Adding a Certificate to the Database

-

This example adds a certificate to the certificate database:
- certutil -A -n jsmith@netscape.com -t "p,p,p" -i mycert.crt -d - - certdir -
- You can see this certificate in the database with this command:
- certutil -L -n jsmith@netscape.com -d - - certdir -
- The Certificate Database Tool displays output similar to the following:
- Certificate:
-   Data:
-     Version: 3 (0x2)
-     Serial Number: 0 (0x0)
-     Signature Algorithm: PKCS #1 MD5 With RSA Encryption
-     Issuer: CN=John Smith, O=Netscape, L=Mountain View, ST=California, C=US
-     Validity:
-         Not Before: Thu Mar 12 00:10:40 1998
-         Not After: Sat Sep 12 00:10:40 1998
- Subject: CN=John Smith, O=Netscape, L=Mountain View, ST=California, C=US

- Subject Public Key Info:
-   Public Key Algorithm: PKCS #1 RSA Encryption
-   RSA Public Key:
-     Modulus:
-         00:da:53:23:58:00:91:6a:d1:a2:39:26:2f:06:3a:
-         38:eb:d4:c1:54:a3:62:00:b9:f0:7f:d6:00:76:aa:
-         18:da:6b:79:71:5b:d9:8a:82:24:07:ed:49:5b:33:
-         bf:c5:79:7c:f6:22:a7:18:66:9f:ab:2d:33:03:ec:
-         63:eb:9d:0d:02:1b:da:32:ae:6c:d4:40:95:9f:b3:
-         44:8b:8e:8e:a3:ae:ad:08:38:4f:2e:53:e9:e1:3f:
-         8e:43:7f:51:61:b9:0f:f3:a6:25:1e:0b:93:74:8f:
-         c6:13:a3:cd:51:40:84:0e:79:ea:b7:6b:d1:cc:6b:
-         78:d0:5d:da:be:2b:57:c2:6f
-     Exponent: 65537 (0x10001)
- Signature Algorithm: PKCS #1 MD5 With RSA Encryption
- Signature:
-   44:15:e5:ae:c4:30:2c:cd:60:89:f1:1d:22:ed:5e:5b:10:c8:
-   7e:5f:56:8c:b4:00:12:ed:5f:a4:6a:12:c3:0d:01:03:09:f2:
-   2f:e7:fd:95:25:47:80:ea:c1:25:5a:33:98:16:52:78:24:80:
-   c9:53:11:40:99:f5:bd:b8:e9:35:0e:5d:3e:38:6a:5c:10:d1:
-   c6:f9:54:af:28:56:62:f4:2f:b3:9b:50:e1:c3:a2:ba:27:ee:
-   07:9f:89:2e:78:5c:6d:46:b6:5e:99:de:e6:9d:eb:d9:ff:b2:
-   5f:c6:f6:c6:52:4a:d4:67:be:8d:fc:dd:52:51:8e:a2:d7:15:
-   71:3e

- Certificate Trust Flags:
-   SSL Flags:
-     Valid CA
-     Trusted CA
-   Email Flags:
-     Valid CA
-     Trusted CA
-   Object Signing Flags:
-     Valid CA
-     Trusted CA

-

 

-

 

-

Validating a Certificate

-

This example validates a certificate:
- certutil -V -n jsmith@netscape.com -b 9803201212Z -u SR -e -l -d - - certdir -
- The Certificate Database Tool shows results similar to
- Certificate:'jsmith@netscape.com' is valid.
- or
- UID=jsmith, E=jsmith@netscape.com, CN=John Smith, O=Netscape Communications Corp., C=US : Expired certificate
- or
- UID=jsmith, E=jsmith@netscape.com, CN=John Smith, O=Netscape Communications Corp., C=US : Certificate not approved for this operation

-

 

-

 

-
-

 

-
-

 

diff --git a/files/zh-cn/places/index.html b/files/zh-cn/places/index.html deleted file mode 100644 index 039387911a..0000000000 --- a/files/zh-cn/places/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Places -slug: Places -tags: - - Add-ons - - Developing Mozilla - - Extensions - - Places -translation_of: Mozilla/Tech/Places ---- -

- -

Places 是一个重新编写的 Firefox 的书签和历史系统。它致力于拥有更灵活的实现处理复杂检索请求的能力。 它还包含一些新特性诸如:图标保存、用任意信息注释页面,并且拥有许多没有写在此开发者文档上的新 UI(见 Mozilla wiki 上的 Places 条目)。

- -

Places 的数据保存在一个使用 mozStorage 交互界面的 sqlite 数据库中。

- -

条目

- -
-
检索系统
-
怎样使用详细的参数来检索书签和历史系统。
-
- -
-
存取书签
-
怎样存取书签。
-
- -
-
定制容器
-
怎样创建一个特定的容器以 Places 查看方式显示来自第三方的链接。
-
- -
-
查看
-
怎样在你自己的应用程序或者扩展中实现和配置 places 查看。
-
- -
-
实例化查看
-
怎样实例化一个控件来实现在你自己的应用程序或者扩展中使用内建 places 查看。
-
- -

Services API documentation

- -
-
History Service
-
Bookmarks Service
-
Annotation Service
-
Livemark Service
-
Favicon Service
-
Tagging Service
-
- -

Design documents

- -
-
Places Database Design
-
High-level overview of the places database design.
-
History Service Design
-
Design of the history service.
-
Bookmark Service Design
-
Design of the bookmarks service.
-
Annotation Service Design
-
Design of the annotation service.
-
Location Bar Design
-
Design and algorithm of the Places-driven Location Bar (aka the "awesomebar").
-
diff --git a/files/zh-cn/properly_using_css_and_javascript_in_xhtml_documents/examples/index.html b/files/zh-cn/properly_using_css_and_javascript_in_xhtml_documents/examples/index.html deleted file mode 100644 index 78257132f1..0000000000 --- a/files/zh-cn/properly_using_css_and_javascript_in_xhtml_documents/examples/index.html +++ /dev/null @@ -1,404 +0,0 @@ ---- -title: Examples -slug: Properly_Using_CSS_and_JavaScript_in_XHTML_Documents/Examples -tags: - - CSS - - JavaScript - - Web Development - - XHTML - - 所有分类 -translation_of: Archive/Web/Properly_Using_CSS_and_JavaScript_in_XHTML_Documents_/Examples ---- -

 

-

This page contains the source code of the examples related to the "Properly Using CSS and JavaScript in XHTML Documents" article.

-

Please refer to the article to learn more about these examples.

-

If you wish to test these examples by yourself, please read the Important Notes.

-

Important Notes

-

If you plan to test these examples by yourself, you must use the right extension (it is written a the beginning of the code). Ideally, upload the file to a web server and you're done.

-

Please note that the examples 4, 5 and 6 require a file named style.css to exist in the same directory as the example. You can get the contents of style.css at the bottom of this page.

-

Examples for "Problems with Inline <tt>style</tt> and <tt>script</tt>"

-

Problem 1

-
<!-- This file should have a .xhtml extension
-     and will generate an error when parsed. -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Problem 1 - &lt; in XHTML</title>
-  <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
-  <script type="text/javascript">
-   var i = 0;
-
-   while (++i > 10)
-   {
-     // ...
-   }
-  </script>
-</head>
-<body>
-  <h1>Problem 1 - &lt; in XHTML</h1>
-  <p>
-   This document is not well formed due to the use of a raw &lt;.
-  </p>
-</body>
-</html>
-
-

Back to the article

-

Problem 2

-
<!-- This file should have a .xhtml extension -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Problem 2 - Comments in XHTML</title>
-  <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
-  <style type="text/css">
-   <!--
-    body {background-color: blue; color: yellow; }
-   -->
-  </style>
-  <script type="text/javascript">
-   <!--
-   var i = 0;
-   var sum = 0;
-
-   for (i = 0; i < 10; ++i)
-   {
-     sum += i;
-   }
-   alert('sum = ' + sum);
-   // -->
-  </script>
-</head>
-<body>
-  <h1>Problem 2 - Comments in XHTML</h1>
-
-  <p>
-  This document is valid XHTML 1.0 Strict served as
-  <code>application/xhtml+xml</code>.
-  </p>
-
-  <p>
-  This document contains inline CSS rules contained in a
-  <code>style</code> element and surrounded by a Comment
-  and JavaScript contained in a <code>script</code> element
-  and surrounded by a Comment.
-  </p>
-
-  <dl>
-  <dt>Mozilla 1.1+/Opera 7</dt>
-  <dd>Do not apply CSS or execute the JavaScript.</dd>
-  <dt>Netscape 7.0x/Mozilla 1.0.x</dt>
-  <dd>Do not apply CSS but does execute the JavaScript.</dd>
-  <dt>Internet Explorer 5.5+</dt>
-  <dd>Can not display the document.</dd>
-  </dl>
-
-  <p>
-  <a href="http://validator.w3.org/check/referer"><img
-    src="http://www.w3.org/Icons/valid-xhtml10"
-    alt="Valid XHTML 1.0!" height="31" width="88" /></a>
-  </p>
-</body>
-</html>
-
-

Back to the article

-

Problem 3

-
<!-- This file should have a .xhtml extension
-     and will generate an error when parsed. -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Problem 3 - Comments in XML</title>
-  <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
-  <script type="text/javascript">
-   var i;
-   var sum = 0;
-
-   for (i = 10; i > 0; --i)
-   {
-     sum += i;
-   }
-  </script>
-</head>
-<body>
-  <h1>Problem 3 - Comments in XHTML</h1>
-  <p>
-   This document is not well formed XHTML due to the double dash
-   contained in the Comment.
-  </p>
-</body>
-</html>
-
-

Back to the article

-

Examples for "Using CSS rules in inline <tt>style</tt> within comments"

-

Example 1

-
<!-- This file should have a .html extension -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Example 1 - XHTML 1.0 Strict as text/html</title>
-  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
-  <style type="text/css">
-   <!--
-    body { padding-top: 8em; }
-    html { color: #fff; background: #000 no-repeat fixed;}
-    p {width: 30em; font-weight: bold;}
-   -->
-  </style>
-</head>
-<body>
-  <h1>Example 1 - XHTML 1.0 Strict as text/html</h1>
-  <p>
-   This document is valid XHTML 1.0 Strict served as
-   <code>text/html</code>.
-  </p>
-
-  <p>
-  This document contains inline CSS rules contained in a <code>style</code>
-  element and surrounded by a SGML Comment.
-  </p>
-
-  <p>
-  Note how the CSS rules for the background are applied in Netscape 7.x,
-  Mozilla, Opera 7 and Internet Explorer 5.5+.
-  </p>
-
-  <p>
-    <a href="http://validator.w3.org/check/referer"><img
-        src="http://www.w3.org/Icons/valid-xhtml10"
-        alt="Valid XHTML 1.0!" height="31" width="88" /></a>
-  </p>
-
-</body>
-</html>
-
-

Back to the article

-

Example 2

-
<!-- This file should have a .xml extension -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Example 2 - XHTML 1.0 Strict as text/xml</title>
-  <meta http-equiv="Content-Type" content="text/xml; charset=utf-8" />
-  <style type="text/css">
-   <!--
-    body { padding-top: 8em; }
-    html { color: #fff; background: #000 no-repeat fixed;}
-    p {width: 30em; font-weight: bold;}
-   -->
-  </style>
-</head>
-<body>
-  <h1>Example 2 - XHTML 1.0 Strict as text/xml</h1>
-  <p>
-   This document is valid XHTML 1.0 Strict served as
-   <code>text/xml</code>.
-  </p>
-
-  <p>
-  This document contains inline CSS rules contained in a <code>style</code>
-  element and surrounded by a SGML Comment.
-  </p>
-
-  <p>
-  Note how the CSS rules for the background are <strong>not</strong>
-  applied in Netscape 7.x, Mozilla and Opera 7 and that
-  Internet Explorer 5.5+ can not display the page correctly at all.
-  </p>
-
-  <p>
-    <a href="http://validator.w3.org/check/referer"><img
-        src="http://www.w3.org/Icons/valid-xhtml10"
-        alt="Valid XHTML 1.0!" height="31" width="88" /></a>
-  </p>
-
-</body>
-</html>
-
-

Back to the article

-

Example 3

-
<!-- This file should have a .xhtml extension -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Example 3 - XHTML 1.0 Strict as application/xhtml+xml</title>
-  <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
-  <style type="text/css">
-   <!--
-    body { padding-top: 8em; }
-    html { color: #fff; background: #000 no-repeat fixed;}
-    p {width: 30em; font-weight: bold;}
-   -->
-  </style>
-</head>
-<body>
-  <h1>Example 3 - XHTML 1.0 Strict as application/xhtml+xml</h1>
-  <p>
-   This document is valid XHTML 1.0 Strict served as
-   <code>application/xhtml+xml</code>.
-  </p>
-
-  <p>
-  This document contains inline CSS rules contained in a <code>style</code>
-  element and surrounded by a SGML Comment.
-  </p>
-
-  <p>
-  Note how the CSS rules for the background are <strong>not</strong>
-  applied in Netscape 7.x, Mozilla and Opera 7 and that
-  Internet Explorer 5.5+ can not display the page correctly at all.
-  </p>
-
-  <p>
-    <a href="http://validator.w3.org/check/referer"><img
-        src="http://www.w3.org/Icons/valid-xhtml10"
-        alt="Valid XHTML 1.0!" height="31" width="88" /></a>
-  </p>
-
-</body>
-</html>
-
-

Back to the article

-

Examples for "Using CSS rules in external file"

-

Example 4

-
<!-- This file should have a .html extension -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Example 4 - XHTML 1.0 Strict as text/html</title>
-  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
-  <link rel="stylesheet" type="text/css" href="style.css" />
-</head>
-<body>
-  <h1>Example 4 - XHTML 1.0 Strict as text/html</h1>
-  <p>
-   This document is valid XHTML 1.0 Strict served as
-   <code>text/html</code>.
-  </p>
-
-  <p>
-  This document references CSS rules contained in an external
-  stylesheet via <code>link</code>.
-  </p>
-
-  <p>
-  Note how the CSS rules for the background are applied in Netscape 7.x,
-  Mozilla, Opera 7 and Internet Explorer 5.5+.
-  </p>
-
-  <p>
-    <a href="http://validator.w3.org/check/referer"><img
-        src="http://www.w3.org/Icons/valid-xhtml10"
-        alt="Valid XHTML 1.0!" height="31" width="88" /></a>
-  </p>
-
-</body>
-</html>
-
-

Before testing this example by yourself, please read this.

-

Back to the article

-

Example 5

-
<!-- This file should have a .xml extension -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Example 5 - XHTML 1.0 Strict as text/xml</title>
-  <meta http-equiv="Content-Type" content="text/xml; charset=utf-8" />
-  <link rel="stylesheet" type="text/css" href="style.css" />
-  </style>
-</head>
-<body>
-  <h1>Example 5 - XHTML 1.0 Strict as text/xml</h1>
-  <p>
-   This document is valid XHTML 1.0 Strict served as
-   <code>text/xml</code>.
-  </p>
-
-  <p>
-  This document references CSS rules contained in an external
-  stylesheet via <code>link</code>.
-  </p>
-
-  <p>
-  Note how the CSS rules for the background are applied in Netscape 7.x,
-  Mozilla, Opera 7 but that Internet Explorer can not display the page at all.
-  </p>
-
-  <p>
-    <a href="http://validator.w3.org/check/referer"><img
-        src="http://www.w3.org/Icons/valid-xhtml10"
-        alt="Valid XHTML 1.0!" height="31" width="88" /></a>
-  </p>
-
-</body>
-</html>
-
-

Before testing this example by yourself, please read this.

-

Back to the article

-

Example 6

-
<!-- This file should have a .xhtml extension -->
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-  <title>Example 6 - XHTML 1.0 Strict as application/xhtml+xml</title>
-  <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
-  <link rel="stylesheet" type="text/css" href="style.css" />
-  </style>
-</head>
-<body>
-  <h1>Example 6 - XHTML 1.0 Strict as application/xhtml+xml</h1>
-  <p>
-   This document is valid XHTML 1.0 Strict served as
-   <code>application/xhtml+xml</code>.
-  </p>
-
-  <p>
-  This document references CSS rules contained in an external
-  stylesheet via <code>link</code>.
-  </p>
-
-  <p>
-  Note how the CSS rules for the background are applied in Netscape 7.x,
-  Mozilla, Opera 7 but that Internet Explorer can not display the page at all.
-  </p>
-
-  <p>
-    <a href="http://validator.w3.org/check/referer"><img
-        src="http://www.w3.org/Icons/valid-xhtml10"
-        alt="Valid XHTML 1.0!" height="31" width="88" /></a>
-  </p>
-
-</body>
-</html>
-
-

Before testing this example by yourself, please read this.

-

Back to the article

-

Stylesheet

-
/*
- * If you try to view the results of these examples,
- * you will need to put a file named style.css with
- * the following content in the same directory as
- * the examples.
- */
-
-body { padding-top: 8em; }
-html { color: #fff; background: #000 no-repeat fixed;}
-p {width: 30em; font-weight: bold;}
-
diff --git a/files/zh-cn/properly_using_css_and_javascript_in_xhtml_documents/index.html b/files/zh-cn/properly_using_css_and_javascript_in_xhtml_documents/index.html deleted file mode 100644 index 4ed9681ad1..0000000000 --- a/files/zh-cn/properly_using_css_and_javascript_in_xhtml_documents/index.html +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: 在XHTML文档中合适的使用CSS和JavaScript -slug: Properly_Using_CSS_and_JavaScript_in_XHTML_Documents -tags: - - CSS - - JavaScript - - Web Development - - XHTML - - 所有分类 -translation_of: Archive/Web/Properly_Using_CSS_and_JavaScript_in_XHTML_Documents_ ---- -

 

-

XHTML™ 1.0 The Extensible HyperText Markup Language (Second Edition) 定义XHTML是为了把HTML 4扩展成像XML 1.0一样的应用程序。

-

在许多站点中XHTML正在迅速的替代HTML 4;然而,主流浏览器对完全支持XHTML方面表现得不足,和网页设计师对HTML 4与XHTML的基本差异缺乏理解,产生了当今网络上的一个不断扩大的问题。

-

XHTML是XML,不是HTML

-

其中关于XHTML的主要的误解是,它仅仅是另外一个版本的HTML。这个误解产生于这样的事实:Microsoft® Internet Explorer只在文件以Mime类型为 text/html提交时,才支持XHTML,而标准中建议的类型其实是<tt>application/xhtml+xml</tt>。

-

当一个XHTML页面的MIME类型被提交为<tt>text/html</tt>时,它被所有的浏览器当作HTML处理,就好像XHTML比起HTML来没有任何不同。但是当一个XHTML页面的MIME类型被提交为<tt>text/xml</tt>或<tt>application/xhtml+xml</tt>时,它将被当作XML文档处理,而设计和显示XML都是必须要遵守严格规则的。

-

真正的XHTML就是一个XML的应用,所以创建XHTML时也要遵守严格的规则。特别是:

-
    -
  1. 未经过处理的<tt><</tt>和<tt>&</tt>不允许出现在CDATA区域(<tt><!CDATA...></tt>)之外。
  2. -
  3. 注释(<tt><!—— ... ——></tt>)中不能包含双横线。
  4. -
  5. 包含在注释(<tt><!—— ... ——></tt>)中的内容将被忽略。
  6. -
-

在内嵌的<tt>style</tt>和<tt>script</tt>中出现的问题

-

在被当作XML而不是HTML处理时,内嵌的style和script标记会产生几个不同的问题。

-

JavaScript中包含了一些在XHTML中不允许存在的字符

-

典型的JavaScript中包含了一些特殊字符,这些字符在XHTML中是不允许放在CDATA区域之外的。

-
<script type="text/javascript">
-  var i = 0;
-
-  while (++i < 10)
-  {
-    // ...
-  }
-</script>
-
-

注意这个例子不是以正确格式书写的XHTML,因为使用了未经处理的“<”,它只能在被当作XHTML或XML标记的一部分时出现。

-

在内嵌的<tt>style</tt>和<tt>script</tt>中使用注释

-

熟悉HTML的设计师通常把内嵌的<tt>style</tt>和<tt>script</tt>内容放到注释中,这样可以在不支持样式和脚本的浏览器中隐藏它们。

-
<style type="text/css">
- <!--
-  body {background-color: blue; color: yellow;}
- -->
-</style>
-<script type="text/javascript">
- <!--
-  var i = 0;
-  var sum = 0;
-
-  for (i = 0; i < 10; ++i)
-  {
-    sum += i;
-  }
-  alert('sum = ' + sum);
- // -->
-</script>
-
-

这个例子举例说明了特定的浏览器可以忽略注释里的内容。另外,这个例子还显示了不同的浏览器在处理<tt>text/xml</tt>或者 <tt>application/xhtml+xml</tt>内容时产生的不同问题。

-
-
- Mozilla 1.1+/Opera 7
-
- 不能使用CSS,也不能执行JavaScript。
-
- Netscape 7.0x/Mozilla 1.0.x
-
- 不能使用CSS,但可以执行JavaScript。
-
- Internet Explorer 5.5+
-
- 无法正常显示文档。
-
-

包含双横线的内嵌<tt>style</tt>和<tt>script</tt>

-

另一个把JavaScript包含在XHTML文件的注释中产生的问题,与在XHTML的注释中使用双横线会产生的问题一样。

-
<script type="text/javascript">
-<!--
-  var i;
-  var sum = 0;
-
-  for (i = 10; i > 0; --i)
-  {
-    sum += i;
-  }
-// -->
-</script>
-
-

使用CDATA替代注释

-

直接把JavaScript放入CDATA区域会在低版本不支持XML的浏览器中产生问题,不过,把JavaScript的注释(//……)与CDATA一起使用,就能解决向下兼容的问题了。

-
<script type="text/javascript">
- //<![CDATA[
-  var i = 0;
-
-  while  (++i < 10)
-  {
-    // ...
-  }
- //]]>
-</script>
-
-

例子

-

在注释中使用内嵌<tt>style</tt>的CSS规则

-
-
- 例子1 - XHTML 1.0 Strict在<tt>text/html</tt>
-
- 这个例子举例说明当CSS规则包含内联和包含在注释中时的XHTML在<tt>text/html</tt>的行为。这个例子支持Netscape 7.x,Mozilla,Opera 7和Internet Explorer 5.5+那一个都能像期望一样应用CSS规则。
-
-
-
- 例子2 - XHTML 1.0 Strict在<tt>text/xml</tt>
-
- 这个例子举例说明当CSS规则包含内联和包含在注释中时的XHTML在<tt>text/xml</tt>的行为。这个例子支持Netscape 7.x,Mozilla,Opera 7但不支持Internet Explorer 5.5+。注意etscape 7.x,Mozilla和Opera同意包含在注释的内联CSS规则将被忽略。
-
-
-
- 例子3 - XHTML 1.0 Strict在<tt>application/xhtml+xml</tt>
-
- 这个例子举例说明当CSS规则包含内联和包含在注释中时的XHTML在<tt>application/xhtml+xml</tt>的行为。这个例子支持Netscape 7.x,Mozilla,Opera 7但不支持Internet Explorer 5.5+。注意etscape 7.x,Mozilla和Opera同意包含在注释的内联CSS规则将被忽略。
-
-

使用外部文件的CSS规则

-
-
- 例子4 - XHTML 1.0 Strict在<tt>text/html</tt>
-
- 这个例子举例说明当在使用外部文件的CSS规则的时候XHTML在<tt>text/html</tt>的行为。这个例子支持Netscape 7.x,Mozilla,Opera 7和Internet Explorer 5.5+。
-
-
-
- 例子5 - XHTML 1.0 Strict在<tt>text/xml</tt>
-
- 这个例子举例说明当在使用外部文件的CSS规则的时候XHTML在<tt>text/xml</tt>的行为。这个例子支持Netscape 7.x,Mozilla和Opera 7但不支持不支持Internet Explorer 5.5+
-
-
-
- 例子6 - XHTML 1.0 Strict在<tt>application/xhtml+xml</tt>
-
- 这个例子举例说明当在使用外部文件的CSS规则的时候XHTML在<tt>application/xhtml+xml</tt>的行为。这个例子支持Netscape 7.x,Mozilla和Opera 7但不支持不支持Internet Explorer 5.5+
-
-

建议

-

不要在XHTML中内联<tt>style</tt>或<tt>script</tt>

-

用外部文件包含CSS规则和JavaScript来替换内联样式和脚本是创建XHTML最佳方式,在向后兼容方式时,如果内容的MIME类型从<tt>text/html</tt>向<tt>application/xhtml+xml</tt>改变时将不会被打断。

-

这个建议可能看起来更强烈,可是,它是未来XHTML要打算的问题,当XHTML在<tt>text/html</tt>向<tt>application/xhtml+xml</tt>转移在几年后发生。

-

如果你仅仅测试你的XHTML在<tt>text/html</tt>的时候,那么你可能产生问题,例如像:不能准确的描述出主题。移动CSS和JavaScript到单独的文件是可靠的方法,关于改变你XHTML的服务方式。

-

理解XHTML 1.0的HTML兼容指导

-

这个XHTML 1.0 HTML Compatibility Guidelines帮助创建XHTML文档向后兼容性在那些不能理解XML的老浏览器。

-

请注意那是纯粹的XHTML文档,你不需要使用xml-stylesheet处理指导,但应该使用<tt>link</tt>涉及的外部文件包含CSS。

-
-

原始文档信息

- -
-

 

diff --git a/files/zh-cn/spidermonkey/hacking_tips/index.html b/files/zh-cn/spidermonkey/hacking_tips/index.html deleted file mode 100644 index ab5a5d0e59..0000000000 --- a/files/zh-cn/spidermonkey/hacking_tips/index.html +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: Hacking Tips -slug: SpiderMonkey/Hacking_Tips -translation_of: Mozilla/Projects/SpiderMonkey/Hacking_Tips ---- -

当你需要深入SpiderMonkey去分析或调试bug时,这里汇总的一些小技巧对你或许会有帮助。本文中所有技巧使用的SpiderMonkey都是按照 SpiderMonkey构建文档(build documentation of SpiderMonkey) 里面的过程编译的。本文分成两个部分,第一部分介绍调试技巧,第二部分介绍如何构造一个优化。

-

调试技巧

-

打印帮助信息(JS shell中)

-

通过执行help函数可以打印出所有内置工具函数名以及各自的简单介绍.

-

获取函数的字节码(JS shell中)

-

shell中有一个名为dis的函数,可以导出一个函数的字节码.如果不指定参数,它会打印出当前调用函数的字节码.

-
js> function f () {
-  return 1;
-}
-js> dis(f);
-flags:
-loc     op
------   --
-main:
-00000:  one
-00001:  return
-00002:  stop
-
-Source notes:
- ofs  line    pc  delta desc     args
----- ---- ----- ------ -------- ------
-  0:    1     0 [   0] newline
-  1:    2     0 [   0] colspan 2
-  3:    2     2 [   2] colspan 9
-
-
-

获取函数的字节码(gdb)

-

In jsopcode.cpp, a function named js_DisassembleAtPC can print the bytecode of a script.  Some variants of this function such as js_DumpPc, js_DumpScript and js_DumpScriptDepth are convenient for debugging.

-

利用GDB输出JS调用栈

-

Printing the JS stack. (from gdb)

-

In jsobj.cpp, a function named js_DumpBacktrace print a backtrace à la gdb for the JS stack.  The backtrace contains in the following order, the stack depth, the interpreter frame pointer (see js/src/vm/Stack.h, StackFrame class) or (nil) if compiled with IonMonkey, the file and line number of the call location and under parentheses, the JSScript pointer and the jsbytecode pointer (pc) executed.

-
$ gdb --args js
-[…]
-(gdb) b js_ReportOverRecursed
-(gdb) r
-js> function f(i) {
-  if (i % 2) f(i + 1);
-  else f(i + 3);
-}
-js> f(0)
-
-Breakpoint 1, js_ReportOverRecursed (maybecx=0xfdca70) at /home/nicolas/mozilla/ionmonkey/js/src/jscntxt.cpp:495
-495         if (maybecx)
-(gdb) call js_DumpBacktrace(maybecx)
-#0          (nil)   typein:2 (0x7fffef1231c0 @ 0)
-#1          (nil)   typein:2 (0x7fffef1231c0 @ 24)
-#2          (nil)   typein:3 (0x7fffef1231c0 @ 47)
-#3          (nil)   typein:2 (0x7fffef1231c0 @ 24)
-#4          (nil)   typein:3 (0x7fffef1231c0 @ 47)
-[…]
-#25157 0x7fffefbbc250   typein:2 (0x7fffef1231c0 @ 24)
-#25158 0x7fffefbbc1c8   typein:3 (0x7fffef1231c0 @ 47)
-#25159 0x7fffefbbc140   typein:2 (0x7fffef1231c0 @ 24)
-#25160 0x7fffefbbc0b8   typein:3 (0x7fffef1231c0 @ 47)
-#25161 0x7fffefbbc030   typein:5 (0x7fffef123280 @ 9)
-
-
-

利用GDB为执行代码生成断点(x86/x86_64平台)

-

Setting a breakpoint in the generated code. (from gdb, x86 / x86-64)

-

To set a breakpoint the generated code of a specific JSScript compiled with IonMonkey (this will also work with JäegerMonkey, except that functions would be different). Set a breakpoint on the instruction you are interested in. If you have no precise idea which function you are looking at, you can set a breakpoint on the js::ion::CodeGenerator::visitStart function.  Optionally, a condition on the ins->id() of the LIR instruction can be added to select precisely the instruction you are looking for. Once the breakpoint is on CodeGenerator function of the LIR instruction, add a command to generate a static breakpoint in the generated code.

-
$ gdb --args js
-[…]
-(gdb) b js::ion::CodeGenerator::visitStart
-(gdb) command
->call masm.breakpoint()
->continue
->end
-(gdb) r
-js> function f(a, b) { return a + b; }
-js> for (var  i = 0; i < 100000; i++) f(i, i + 1);
-
-Breakpoint 1, js::ion::CodeGenerator::visitStart (this=0x101ed20, lir=0x10234e0)
-    at /home/nicolas/mozilla/ionmonkey/js/src/ion/CodeGenerator.cpp:609
-609     }
-
-Program received signal SIGTRAP, Trace/breakpoint trap.
-0x00007ffff7fb165a in ?? ()
-(gdb)
-
-
-

Once you hit the generated breakpoint, you can replace it by a gdb breakpoint to make it conditional, the procedure is to first replace the generated breakpoint by a nop instruction, and to set a breakpoint at the address of the nop.

-
(gdb) x /5i $pc - 1
-   0x7ffff7fb1659:      int3
-=> 0x7ffff7fb165a:      mov    0x28(%rsp),%rax
-   0x7ffff7fb165f:      mov    %eax,%ecx
-   0x7ffff7fb1661:      mov    0x30(%rsp),%rdx
-   0x7ffff7fb1666:      mov    %edx,%ebx
-
-(gdb) # replace the int3 by a nop
-(gdb) set *(unsigned char *) ($pc - 1) = 0x90
-(gdb) x /1i $pc - 1
-   0x7ffff7fb1659:      nop
-
-(gdb) # set a breakpoint at the previous location
-(gdb) b *0x7ffff7fb1659
-Breakpoint 2 at 0x7ffff7fb1659
-
-
-

Finding the script of Ion generated assembly (from gdb)

-

When facing a bug in which you are in the middle of IonMonkey generated code, first thing to note, is that gdb's backtrace is not reliable, because the generated code does not keep a frame pointer. To figure it out you have to read the stack to infer the IonMonkey frame.

-
(gdb) x /64a $sp
-[…]
-0x7fffffff9838: 0x7ffff7fad2da  0x141
-0x7fffffff9848: 0x7fffef134d40  0x2
-[…]
-(gdb) p (*(JSFunction**) 0x7fffffff9848)->u.i.script_->lineno
-$1 = 1
-(gdb) p (*(JSFunction**) 0x7fffffff9848)->u.i.script_->filename
-$2 = 0xff92d1 "typein"
-
-

The stack is order as defined in js/src/ion/IonFrames-x86-shared.h, it is composed of the return address, a descriptor (a small value), the JSFunction (if it is even) or a JSScript (if the it is odd, remove it to dereference the pointer) and the frame ends with the number of actual arguments (a small value too). If you want to know at which LIR the code is failing at, the js::ion::CodeGenerator::generateBody function can be intrumented to dump the LIR id before each instruction.

-
for (; iter != current->end(); iter++) {
-    IonSpew(IonSpew_Codegen, "instruction %s", iter->opName());
-    […]
-
-    masm.store16(Imm32(iter->id(), Address(StackPointer, -8))); // added
-    if (!iter->accept(this))
-        return false;
-
-    […]
-}
-

This modification will add an instruction which abuse the stack pointer to store an immediate value (the LIR id) to a location which would never be generated by any sane compiler. Thus when dumping the assembly under gdb, this kind of instructions would be easily noticeable.

-

Break on valgrind errors

-

Sometimes, a bug can be reproduced under valgrind but hardly under gdb.  One way to investigate is to let valgrind start gdb for you, the other way documented here is to let valgrind act as a gdb server which can be manipulated from the gdb remote.

-
$ valgrind --smc-check=all-non-file --vgdb-error=0 ./js …
-

This command will tell you how to start gdb as a remote. Be aware that functions which are usually dumping some output will do it in the shell where valgrind is started and not in the shell where gdb is started. Thus functions such as js_DumpBacktrace, when called from gdb, will print their output in the shell containing valgrind.

-

Hacking tips

-

Using the Gecko Profiler (browser / xpcshell)

-

see the section dedicated to profiling with the gecko profiler. This method of profiling has the advantage of mixing the JavaScript stack with the C++ stack, which is useful to analyze library function issues.  One tip is to start looking at a script with an inverted JS stack to locate the most expensive JS function, then to focus on the frame of this JS function, and to remove the inverted stack and look at C++ part of this function to determine from where the cost is coming from.

-

Using the JIT Inspector (browser)

-

Install the JIT Inspector addon in your browser. This addon provides estimated cost of IonMonkey , JaëgerMonkey and the interpreter. In addition to provides a clean way to analyze if instructions are infered as being monomorphic or polymorphic in addition to the number of time each category of type has been observed.

-

Using callgrind (JS shell)

-

As SpiderMonkey just-in-time compiler are rewriting the executed program, valgrind should be informed from the command line by adding --smc-check=all-non-file.

-
$ valgrind --tool=callgrind --callgrind-out-file=bench.clg --smc-check=all-non-file ./js ./run.js
-
-

The output file can then be use with kcachegrind which provides a graphical view of the call graph.

-

Using IonMonkey spew (JS shell)

-

IonMonkey spew is extremely verbose (not as much as the INFER spew), but you can filter it to focus on the list of compiled scripts or channels, IonMonkey spew channels can be selected with the IONFLAGS environment variable, and compilation spew can be filtered with IONFILTER.

-

IONFLAGS contains the names of each channel separated by commas. The logs channel produces 2 files in /tmp/, one (/tmp/ion.json) made to be used with iongraph (made by Sean Stangl) and another one (/tmp/ion.cfg) made to be used with c1visualizer. These tools will show the MIR & LIR steps done by IonMonkey during the compilation.

-

Compilation logs and spew can be filtered with the IONFILTER environment variable which contains locations as output in other spew channels. Multiple locations can be separated with comma as a separator of locations.

-
$ IONFILTER=pdfjs.js:16934 IONFLAGS=logs,scripts,osi,bailouts ./js ./run.js 2>&1 | less
-
-

The bailouts channel is likely to be the first thing you should focus on, because this means that something does not stay in IonMonkey and fallback to the interpreter. This channel output locations (as returned by the id() function of both instructions) of the lastest MIR and the lastest LIR phases. These locations should correspond to phases of the logs and a filter can be used to remove uninteresting functions.

-

[Hack] Replacing one instruction.

-

To replace one specific instruction, you can use in visit function of each instruction the JSScript filename in lineno fields as well as the id() of the LIR / MIR instructions.  The JSScript can be obtained from info().script().

-
bool
-CodeGeneratorX86Shared::visitGuardShape(LGuardShape *guard)
-{
-    if (info().script()->lineno == 16934 && guard->id() == 522) {
-        [… another impl only for this one …]
-        return true;
-    }
-    [… old impl …]
-
diff --git a/files/zh-cn/spidermonkey_garbage_collection_tips/index.html b/files/zh-cn/spidermonkey_garbage_collection_tips/index.html deleted file mode 100644 index 66156068bf..0000000000 --- a/files/zh-cn/spidermonkey_garbage_collection_tips/index.html +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: SpiderMonkey Garbage Collection Tips -slug: SpiderMonkey_Garbage_Collection_Tips -tags: - - SpiderMonkey -translation_of: Mozilla/Projects/SpiderMonkey/Internals/Garbage_collection ---- -

 

-

关于消除垃圾回收机制缺陷的心得

-
    -
  1. -

    使用预定义的本地 roots:

    -

    argv{{ mediawiki.external('i') }} for i in {{ mediawiki.external('0, argc-1') }}. *rval. Even argv{{ mediawiki.external(-1) }} to root a conversion of the obj (a.k.a. this) parameter to a different object, or a new object created to replace obj.

    -
  2. -
  3. -

    当你需要的时候定义更多的本地 roots :

    -

    初始化额外的JSFunctionSpec成员到你需要的本地 roots ("extra args") 当中, 之后使用 argv{{ mediawiki.external('argc') }}, argv{{ mediawiki.external('argc+1') }}, 等. (或者只使用 argv{{ mediawiki.external(3) }} 如果你能够确定这个函数只接收三个参数).

    -

    N.B.: The nargs member of JSFunctionSpec tells the engine to provide at least that many args, so you can generally hardwire the local root indices (argv{{ mediawiki.external(3) }} rather than argv{{ mediawiki.external('argc') }}). If more args are passed and you don't care (you aren't writing a varargs-style function), you can just overwrite the extra args with the locally rooted jsvals.

    -
  4. -
  5. -

    Root as you go to avoid newborn pigeon-hole problems:

    -
     JSString *str1, *str2;
    -
    - /* Bad! */
    - str1 = JS_ValueToString(cx, argv[0]);
    - if (!str1) return JS_FALSE;
    - str2 = JS_ValueToString(cx, argv[1]);
    - if (!str2) return JS_FALSE;
    - SomethingThatMightCallTheGC();
    -
    - /* Good! */
    - str1 = JS_ValueToString(cx, argv[0]);
    - if (!str1) return JS_FALSE;
    - argv[0] = STRING_TO_JSVAL(str1);
    -
    - str2 = JS_ValueToString(cx, argv[1]);
    - if (!str2) return JS_FALSE;
    - argv[1] = STRING_TO_JSVAL(str2);
    -
    - SomethingThatMightCallTheGC();
    -
    -
  6. -
  7. -

    Avoid malloc'ing temporary storage that contains unrooted jsvals:

    -
     /* Bad! */
    - jsint i, len;
    - jsval *vec;
    - JSString *str;
    - JSObject *myArrayObj;
    -
    - len = NumberOfNativeStrings();
    - vec = JS_malloc(cx, len * sizeof(jsval));
    - if (!vec) return JS_FALSE;
    - for (i = 0; i < len; i++) {
    -     str = JS_NewStringCopyZ(cx, GetNativeString(i));
    -     if (!str) {
    -	 JS_free(cx, vec);
    -	 return JS_FALSE;
    -     }
    -     vec[i] = STRING_TO_JSVAL(str);
    - }
    - myArrayObj = JS_NewArrayObject(cx, len, vec);
    - JS_free(cx, vec);
    - if (!myArrayObj) return JS_FALSE;
    - OtherStuffThatMightGC();
    - *rval = OBJECT_TO_JSVAL(myArrayObj);
    -
    - /* Good! */
    - JSObject *myArrayObj;
    - jsint i, len;
    - JSString *str;
    - jsval val;
    -
    - myArrayObj = JS_NewArrayObject(cx, 0, NULL);
    - if (!myArrayObj) return JS_FALSE;
    - *rval = OBJECT_TO_JSVAL(myArrayObj);
    - len = NumberOfNativeStrings();
    - for (i = 0; i < len; i++) {
    -     str = JS_NewStringCopyZ(cx, GetNativeString(i));
    -     if (!str) return JS_FALSE;
    -     val = STRING_TO_JSVAL(str);
    -     if (!JS_SetElement(cx, myArrayObj, i, &val))
    -	 return JS_FALSE;
    - }
    - OtherStuffThatMightGC();
    -
    -

    Note that this example also shows tip #4 (root as you go).

    -
  8. -
  9. -

    Important: don't run the GC at arbitrary times. You must run it only when threads that might have JS interpreter code active on their stacks are all stopped at "safe GC points". The easiest way to do this is to use JS_BeginRequest and JS_EndRequest around each thread's largest chunk of JS API usage (say, evaluating a script and converting its result into a string). You can run the GC after some number of scripts, or from a "GC thread" that wakes up periodically, e.g. Beware realtime effects! Just how sensitive are you to latency?

    -
  10. -
-

How to Dump the GC Heap

-

Using these steps you can find all the GC'able items and what they're linked to.

-

Steps

- -
extern "C" FILE* js_DumpGCHeap;
-
-js_DumpGCHeap = fopen("c:\\jsds-roots.txt", "w");
-
-JS_GC((*i)->jsc);
-
-fclose(js_DumpGCHeap);
-
-js_DumpGCHeap = NULL;
-
-

Interpreting the results

-

Results will come out like the following:

-
061f6810 object 06202ED8 Root via global object(Root @ 0x061f6810).
-

This points that the JSObject (0x061f6810) with private data (0x06202ED8) and class name "Root" is referenced by the global object (cx->globalObject).

-

提示

- -
if(flags & GCX_STRING)
-    return;
-
-


-  

-
-

原始文档信息

- -
-

 

diff --git a/files/zh-cn/storage/index.html b/files/zh-cn/storage/index.html deleted file mode 100644 index ac67689eae..0000000000 --- a/files/zh-cn/storage/index.html +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: Storage -slug: Storage -tags: - - Interfaces - - SQLite - - Storage - - Toolkit API -translation_of: Mozilla/Tech/XPCOM/Storage ---- -

Storage 存储是一个 SQLite 数据库API。它可用于受信任的调用者,仅限于扩展和Firefox组件。

- -

For a complete reference of all methods and properties of the database connection interface see mozIStorageConnection.

- -

The API is currently "unfrozen," which means it is subject to change at any time. It's likely that the API will change somewhat between Firefox 2 and Firefox 3.

- -
Note: Storage is not the same as the DOM:Storage feature which can be used by web pages to store persistent data or the Session store API (an XPCOM storage utility for use by extensions).
- -

入门

- -

This document covers the mozStorage API and some peculiarities of sqlite. It doesnot cover SQL or "regular" sqlite. You can find some very useful links in the See also section however. For mozStorage API help, you can post to mozilla.dev.apps.firefox on the news server news.mozilla.org. To report bugs, use Bugzilla (product "Toolkit", component "Storage").

- -

Here we go then. mozStorage is designed like many other database systems. The overall procedure for use is:

- - - -

打开一个连接

- -

C++ users: The storage service's first initialization must be from the main thread. You will get an error if you initialize it the first time from another thread. Therefore, if you want to use the service from a thread, be sure to call getService from the main thread to ensure the service has been created.

- -

C++ example of opening a connection to "asdf.sqlite" in the user's profile directory:

- -
nsCOMPtr<nsIFile> dbFile;
-rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                            getter_AddRefs(dbFile));
-NS_ENSURE_SUCCESS(rv, rv);
-rv = dbFile->Append(NS_LITERAL_STRING("asdf.sqlite"));
-NS_ENSURE_SUCCESS(rv, rv);
-
-mDBService = do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
-NS_ENSURE_SUCCESS(rv, rv);
-rv = mDBService->OpenDatabase(dbFile, getter_AddRefs(mDBConn));
-NS_ENSURE_SUCCESS(rv, rv);
-
- -

MOZ_STORAGE_SERVICE_CONTRACTID is defined in storage/build/mozStorageCID.h. It's value is "@mozilla.org/storage/service;1"

- -

JavaScript example:

- -
var file = Components.classes["@mozilla.org/file/directory_service;1"]
-                     .getService(Components.interfaces.nsIProperties)
-                     .get("ProfD", Components.interfaces.nsIFile);
-file.append("my_db_file_name.sqlite");
-
-var storageService = Components.classes["@mozilla.org/storage/service;1"]
-                        .getService(Components.interfaces.mozIStorageService);
-var mDBConn = storageService.openDatabase(file);
-
- -
-
-
Note: The OpenDatabase function is subject to change. It will likely be enhanced/simplified to make it more difficult to get into trouble.
-
-
- -

It may be tempting to give your database a name ending in ".sdb" for sqlite database, but this isnot recommended. This extension is treated specially by Windows as a known extension for an "Application Compatibility Database" and changes are backed up by the system automatically as part of system restore functionality. This can result in much higher overhead file operations.

- -

-

Warning: It may be tempting to give your database a name ending in '.sdb' for sqlite database, but this is not recommended. This extension is treated specially by Windows as a known extension for an 'Application Compatibility Database' and changes are backed up by the system automatically as part of system restore functionality. This can result in significantly higher overhead file operation.

-

- -

关闭一个连接

- -

To close a connection on which only synchronous transactions were performed, use the mozIStorageConnection.close() method. If you performed any asynchronous transactions, you should instead use the mozIStorageConnection.asyncClose() method. The latter will allow all ongoing transactions to complete before closing the connection, and will optionally notify you via callback when the connection is closed.

- -

Statements

- -

Follow these steps to create and execute SQL statements on your SQLite database. For a complete reference see mozIStorageStatement.

- -

Creating a statement

- -

There are two ways to create a statement. If you have no parameters and the statement doesn't return any data, use mozIStorageConnection.executeSimpleSQL.

- -
C++:
-rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE TABLE foo (a INTEGER)"));
-
-JS:
-mDBConn.executeSimpleSQL("CREATE TABLE foo (a INTEGER)");
-
- -

Otherwise, you should prepare a statement using mozIStorageConnection.createStatement:

- -
C++:
-nsCOMPtr<mozIStorageStatement> statement;
-rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM foo WHERE a = ?1"),
-                              getter_AddRefs(statement));
-NS_ENSURE_SUCCESS(rv, rv);
-
-JS:
-var statement = mDBConn.createStatement("SELECT * FROM foo WHERE a = ?1");
-
- -

This example uses the placeholder "?1" for a parameter to be bound later (see next section).

- -

Once you have a prepared statement, you can bind parameters to it, execute it, and reset it over and over. If you are doing a statement many times, using a precompiled statement will give you a noticable performance improvement because the SQL query doesn't need to be parsed each time.

- -

If you are familiar with sqlite, you may know that prepared statements are invalidated when the schema of the database changes. Fortunately, mozIStorageStatement detects the error and will recompile the statement as needed. Therefore, once you create a statement, you don't need to worry when changing the schema; all statements will continue to transparently work.

- -

Binding parameters

- -

It is generally best to bind all parameters separately rather than try to construct SQL strings on the fly containing the parameters. Among other things, this prevents SQL injection attacks, since a bound parameter can never be executed as SQL.

- -

You bind parameters to a statement that has placeholders. The placeholders are addressed by index, starting from "?1", then "?2"... You use the statement functions BindXXXParameter(0) BindXXXParameter(1)... to bind to these placeholders.

- -
-
-
Watch out: The indices in the placeholders count from 1. The integers passed to the binding functions count from 0. This means "?1" corresponds to parameter 0, "?2" corresponds to parameters 1, etc.
-
-
- -

You can also use named parameter, like this ":example" instead of "?xx".

- -

A placeholder can appear multiple times in the SQL string and all instances will be replaced with the bound value. Unbound parameters will be interpreted as NULL.

- -

The examples below only use bindUTF8StringParameter() and bindInt32Parameter(). For list of all binding functions see mozIStorageStatement.

- -

C++ example:

- -
nsCOMPtr<mozIStorageStatement> statement;
-rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM foo WHERE a = ?1 AND b > ?2"),
-                              getter_AddRefs(statement));
-NS_ENSURE_SUCCESS(rv, rv);
-rv = statement->BindUTF8StringParameter(0, "hello"); // "hello" will be substituted for "?1"
-NS_ENSURE_SUCCESS(rv, rv);
-rv = statement->BindInt32Parameter(1, 1234); // 1234 will be substituted for "?2"
-NS_ENSURE_SUCCESS(rv, rv);
-
- -

JavaScript example:

- -
var statement = mDBConn.createStatement("SELECT * FROM foo WHERE a = ?1 AND b > ?2");
-statement.bindUTF8StringParameter(0, "hello");
-statement.bindInt32Parameter(1, 1234);
-
- -

If you use named parameters, you should use the getParameterIndex method to get the index of the named parameter. Here is a JavaScript example:

- -
var statement = mDBConn.createStatement("SELECT * FROM foo WHERE a = :myfirstparam AND b > :mysecondparam");
-
-var firstidx = statement.getParameterIndex(":myfirstparam");
-statement.bindUTF8StringParameter(firstidx, "hello");
-
-var secondidx = statement.getParameterIndex(":mysecondparam");
-statement.bindInt32Parameter(secondidx, 1234);
-
- -

You can of course mix named parameters and indexed parameters in a same query:

- -
var statement = mDBConn.createStatement("SELECT * FROM foo WHERE a = ?1 AND b > :mysecondparam");
-
-statement.bindUTF8StringParameter(0, "hello");
-// you can also use
-// var firstidx = statement.getParameterIndex("?1");
-// statement.bindUTF8StringParameter(firstidx, "hello");
-
-var secondidx = statement.getParameterIndex(":mysecondparam");
-statement.bindInt32Parameter(secondidx, 1234);
-
- -

If you want to use a WHERE clause with an IN ( value-list ) expression, Bindings won't work. Construct a string instead. If you're not handling user input it's no safety concern:

- -
var ids = "3,21,72,89";
-var sql = "DELETE FROM table WHERE id IN ( "+ ids +" )";
-
- -

Executing a statement

- -

The main way to execute a statement is with mozIStorageStatement.executeStep. This function allows you to enumerate all the result rows your statement produces, and will notify you when there are no more results.

- -

After a call to executeStep, you use the appropriate getter function in mozIStorageValueArray to get the values in a result row (mozIStorageStatement implements mozIStorageValueArray). The example below only uses getInt32().

- -

You can get the type of a value from mozIStorageValueArray.getTypeOfIndex, which returns the type of the specified column. Be careful: sqlite is not a typed database. Any type can be put into any cell, regardless of the type declared for the column. If you request a different type, sqlite will do its best to convert them, and will do some default value if it is impossible. Therefore, it is impossible to get type errors, but you may get weird data out.

- -

C++ code can also use AsInt32, AsDouble, etc. functions which return the value as a more convenient C++ return value. Watch out, though, because you won't get any errors if your index is invalid. Other errors are impossible, because sqlite will always convert types, even if they don't make sense.

- -

C++ example:

- -
PRBool hasMoreData;
-while (NS_SUCCEEDED(statement->ExecuteStep(&hasMoreData)) && hasMoreData) {
-  PRInt32 value = statement->AsInt32(0);
-  // use the value...
-}
-
- -

Javascript example:

- -
while (statement.executeStep()) {
-  var value = statement.getInt32(0); // use the correct function!
-  // use the value...
-}
-
- -

mozIStorageStatement.execute() is a convenience function for when you are getting no data out of the statement. It steps the statement once and resets it. This can be useful for insert statements because it really cleans up the code:

- -
var statement = mDBConn.createStatement("INSERT INTO my_table VALUES (?1)");
-statement.bindInt32Parameter(52);
-statement.execute();
-
- -

This Image:TTRW2.zip is a simple, but complete, JavaScript and XUL example of how you run an SQL SELECT against a database.

- -

Resetting a statement

- -

It is important to reset statements that are no longer being used. Un-reset write statements will keep a lock on the tables and will prevent other statements from accessing it. Un-reset read statements will prevent writes.

- -

When the statement object is freed, its corresponding database statement is closed. If you are using C++ and you know that all references will be destroyed, you don't have to explicitly reset the statement. Also, if you use mozIStorageStatement.execute(), you don't need to explicitly reset the statement; this function will reset it for you. Otherwise, call mozIStorageStatement.reset().

- -

JavaScript callers should ensure that statements are reset. Be particularly careful about exceptions. You will want to make sure to reset your statements even if an exception is fired, or subsequent access to the database may not be possible. Resetting a statement is relatively lightweight, and nothing bad happens if it's already reset, so don't worry about unnecessary resets.

- -
var statement = connection.createStatement(...);
-try {
-  // use the statement...
-} finally {
-  statement.reset();
-}
-
- -

C++ callers must do the same. There is a scoped object in storage/public/mozStorageHelper.h called mozStorageStatementScoper which will ensure that a given statement is reset when the enclosing scope is exited. It is hightly recommended that you use this object if possible.

- -
void someClass::someFunction()
-{
-  mozStorageStatementScoper scoper(mStatement)
-  // use the statement
-}
-
- -

Last insert id

- -

Use the lastInsertRowID property on the connection to get the id (rowid) from the last INSERT operation on the db.
- This is useful if you have a column in your table set to INTEGER PRIMARY KEY or INTEGER PRIMARY KEY AUTOINCREMENT in which case SQLite automatically assigns a value for each row inserted if you don't provide one. The returned value is of type number in JS and long long in C++.

- -

lastInsertRowID JS example:

- -
var sql = "INSERT INTO contacts_table (number_col, name_col) VALUES (?1, ?2)"
-var statement = mDBConn.createStatement(sql);
-    statement.bindUTF8StringParameter(0, number);
-    statement.bindUTF8StringParameter(1, name);
-    statement.execute();
-    statement.reset();
-
-var rowid = mDBConn.lastInsertRowID;
-
- -

Transactions

- -

mozIStorageConnection has functions for beginning and ending transactions. If you do not explicitly use transactions, an implicit transaction will be created for you for each statement. This has major performance implications. There is overhead for each transaction, especially for commits. You will therefore see a large performance win when you are doing multiple statements in a row if you put them in a transaction. See Storage:Performance for more performance information.

- -

The major difference between other database systems is that sqlite does not support nested transactions. This means that once a transaction is open, you can not open another transaction. You can check mozIStorageConnection.transactionInProgress to see if a transaction is currently in progress.

- -

You can also just execute "BEGIN TRANSACTION" and "END TRANSACTION" directly as SQL statements (this is what the connection does when you call the functions). However, use of mozIStorageConnection.beginTransaction and related functions arestrongly recommended because it stores transaction state in the connection. Otherwise, the attribute transactionInProgress will have the wrong value.

- -

sqlite has several types of transactions:

- - - - - - - -

You can pass this type of transaction to mozIStorageConnection.beginTransactionAs to determine what kind of transaction you need. Keep in mind that if another transaction has already started, this operation will not succeed. Generally, the default TRANSACTION_DEFERRED type is sufficient and you shouldn't use the other types unless you really know why you need them. For more information, see the sqlite documentation about BEGIN TRANSACTION and locking.

- -
var ourTransaction = false;
-if (!mDBConn.transactionInProgress) {
-  ourTransaction = true;
-  mDBConn.beginTransactionAs(mDBConn.TRANSACTION_DEFERRED);
-}
-
-// ... use the connection ...
-
-if (ourTransaction)
-  mDBConn.commitTransaction();
-
- -

From C++ code, you can use the mozStorageTransaction helper class defined in storage/public/mozStorageHelper.h. This class will begin a transaction of the specified type on the specified connection when it comes into scope, and will either commit or rollback the transaction when it goes out of scope. If a transaction is already in progress, the transaction helper class will not do anything.

- -

It also has functions for explicitly committing. The typical use is that you create the class defaulting to rollback, and then explicitly commit the transaction when processing has succeeded:

- -
nsresult someFunction()
-{
-  // deferred transaction (the default) with rollback on failure
-  mozStorageTransaction transaction(mDBConn, PR_FALSE);
-
-  // ... use the connection ...
-
-  // everything succeeded, now explicitly commit
-  return transaction.Commit();
-}
-
- -

How to corrupt your database

- - - - - - - - - - - - - -

SQLite Locking

- -

SQLite locks the entire database; that is, any active readers will cause an attempt to write to return SQLITE_BUSY, and an active writer will cause any attempt to read to return SQLITE_BUSY. A statement is considered active from the first step() until reset() is called. execute() calls step() and reset() in one go. A common problem is forgetting to reset() a statement after you've finished step()'ing through.

- -

While a given SQLite connection is capable of having multiple statements open, its locking model limits what these statements can do concurrently (reading or writing). It is in fact possible for multiple statements to be actively reading at one time. It is not possible, however, for multiple statements to be reading and writing at one timeon the same table -- even if they are derived from the same connection.

- -

SQLite has a two-tiered locking model: connection level and table level. Most people are familiar with the connection (database) level locking: multiple readers but only one writer. The table-level (B-Tree) locks are what can sometimes be confusing. (Internally, each table in the database has its own B-Tree, so "table" and "B-Tree" are technically synonymous).

- -

Table-level locks

- -

You would think that if you have only one connection, and it locks the database for writing, you could use multiple statements to do whatever you want. Not entirely. You must be aware of table-level (B-Tree) locks, which are maintained by statement handles traversing the database (i.e. open SELECT statements).

- -

The general rule is this: a statement handle may not modify a table (B-Tree) which other statement handles are reading (have open cursors on) -- even if that statement handle shares the same connection (transaction context, database lock, etc.) with the other statement handles.Attempts to do so will still block (or return SQLITE_BUSY) .

- -

This problem often crops up when you attempt to iterate over a table with one statement and modify records within it using another statement. This will not work (or carries a high probability of not working, depending on the optimizer's involvement (see below)). The modifying statement will block because the reading statement has an open cursor on the table.

- -

Working around locking problems

- -

The solution is to follow (1) as described above. Theoretically, (2) actually shouldn't work with SQLite 3.x. In this scenario, database locks come into play (with multiple connections) in addition to table locks. Connection 2 (modifying connection) will not be able to modify (write to) the database while the Connection 1 (reading connection) is reading it. Connection 2 will require an exclusive lock to execute a modifying SQL command, which it cannot get as long as Connection 1 has active statements reading the database (Connection 1 has a shared read lock during this time which prohibits any other connections from getting an exclusive lock).

- -

Another option is to use a temporary table. Create a temporary table containing the results of the table of interest, iterate over it (putting the reading statement's table lock on the temp table) and then the modifing statement can make changes to the real table without any problem. This can be done with statements derived from a single connection (transaction context). This scenario sometimes happens behind the scenes anyway as ORDER BY can produce temporary tables internally. However, it is not safe to assume that the optimizer will do this in all cases. Explicitly creating a temporary table is only safe way to do perform this latter option.

- -

Thread safety

- -

The mozStorage service and sqlite are threadsafe. However, no other mozStorage or sqlite objects or operations are threadsafe.

- - - - - - - -

It's worth noting, however, that authors of JavaScript browser extensions are less impacted by these restrictions than it might first appear. If a database is created and used exclusively from within JavaScript, thread safety usually will not be an issue. SpiderMonkey (the JavaScript engine run within Firefox) executes JavaScript from a single persistent thread, except when the JavaScript runs in a different thread or is executed from a callback made on a different thread (e.g. via some networking or stream interfaces). Barring incorrect use of multi-threaded JavaScript, problems should occur only if a database already in use by a non-JavaScript, system-level thread is accessed through mozStorage.

- -

See also

- - - - - -
 
- -

diff --git a/files/zh-cn/structure_of_an_installable_bundle/index.html b/files/zh-cn/structure_of_an_installable_bundle/index.html deleted file mode 100644 index b9975166f5..0000000000 --- a/files/zh-cn/structure_of_an_installable_bundle/index.html +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: 可安装bundle的目录结构 -slug: Structure_of_an_installable_bundle -translation_of: Archive/Mozilla/Bundles ---- -

XULRunner应用扩展主题都共享相同的目录结构,并且这样的目录结构某些时候还可以用于像可安装应用扩展那样的独立XULRunner应用。

-

一个bundle的基本目录结构

-

一个bundle可能包含以下任何种类的文件:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bundle内容相对于root的路径说明 -

版本信息

-
/install.rdf扩展或主题的安装清单文件 
/application.ini应用启动清单文件 
/bootstrap.jsThe bootstrap script for extensions not requiring a restart (those with <em:bootstrap>true</em:bootstrap> in their install.rdf). Note that other files and directories (e.g. chrome.manifest, components, defaults) in bootstrapped extensions are not processed by a supporting application.(>=2.0)
/chrome.manifestChrome注册清单文件(>=1.8)
/components/*XPCOM 组件 (*.js, *.dll)和 *.xpt 接口文件(>=1.7)
/defaults/preferences/*.js默认配置文件(>=1.7)
/plugins/*NPAPI 插件(>=1.8)
/chrome/icons/default/*窗口图标(>=1.8)
/options.xul用于显示在Add-ons管理器中的扩展配置选项画面(>=7.0)
...附加资源 (如 chrome:// 或 resource:// 提供可在chrome.manifest文件中被注册的附加资源) 
Application-specific
/searchplugins/*.srcSherlock search pluginsFirefox 1.5 and greater.
/searchplugins/*.xmlMozSearch and OpenSearch pluginsFirefox 2 and greater
/dictionaries/*.{aff|dic}Myspell dictionariesFirefox 2 and greater
-

当然一个扩展并不需要(通常是不需要)所有的这些目录。主题由于安全原因被限制了功能,并且通常仅能提供一个chrome.manifest文件用于注册主题和JAR文件。

-

平台特定文件

-

Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) 移除了对平台特定文件子目录的支持,接下来讨论。取而代之的是你需要使用清单标识(如OSABI标识)在你的chrome.manifest文件中以指定组件应该被加载到哪种平台上。

-

例如:

-
binary-component components/windows/mycomponent.dll ABI=WINNT_x86-msvc
-binary-component components/mac/mycomponent.dylib ABI=Darwin_x86-gcc3
-binary-component components/mac/mycomponent64.dylib ABI=Darwin_x86_64-gcc3
-binary-component components/linux/mycomponent.so ABI=Linux_x86-gcc3
-
-

这也意味着你可以不再将平台特定配置文件包含进你的bundle。

-

平台特定子目录:Gecko 1.9.2x及其更早版本

-
-
-Gecko 2.0 note -
(Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)
-
-

对于平台特定子目录的支持已经在Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)中被移除. 参见 Platform-specific files 以学习如何使用平台特定文件。

-
-

在某些情况下一个扩展或应用可能希望包含针对不同平台的组件或插件,或者主题的作者可能想要包含多平台特定的JAR文件。为了实现第一种情况,扩展或应用需要为平台特定文件(starting with Toolkit/Gecko 1.8, Firefox/Thunderbird 1.5)指定特定的子目录。平台字符串标识被定义于工具构建处理、操作系统唯一结果结合、处理器架构和编译期间。具体字符串格式如下:

-
{OS_TARGET}_{TARGET_XPCOM_ABI}
-
-

所有加载于主扩展目录中的文件此时都会从子目录中被加载

-
/platform/{platform string}
-
-

如何它存在的话。比如如果一个插件的供应商想让他的插件可以用于装有Linux(of the form: /platform/Linux*/)、Macintosh(of the form: /platform/Darwin*/)或Windows(of the form: /platform/WIN*/)的电脑上,那么他需要提供以下文件:

-
/platform/Linux_x86-gcc3/plugins/libMyPlugin.so
-/platform/WINNT_x86-msvc/plugins/MyPlugin.dll
-/platform/Darwin_ppc-gcc3/plugins/libMyPlugin.dylib
-
-

因为XPT文件不是平台特定的,因此任何相关的XPT文件都可以放到通用的组件目录中:

-
/components/MyPlugin.xpt
-
-

如果一个扩展含有非二进制的平台特定代码(例如那种从脚本中使用windows注册表的代码),那么它也可以使用系统标识符作为平台子目录名:

-
/platform/WINNT/components/registerDoctype.js
-
-

当平台特定JAR文件被使用时,每个平台目录都应该拥有它自己的chrome.manifest清单文件:

-
chrome.manifest
-chrome/mytheme-base.jar
-platform/Darwin/chrome.manifest
-platform/Darwin/chrome/mytheme-mac.jar
-platform/WINNT/chrome.manifest
-platform/WINNT/chrome/mytheme-win.jar
-
-

应用或扩展加载器先处理基础目录,然后再是可应用平台目录(先是 /{OS_TARGET}/, 然后是 /{OS_TARGET}_{TARGET_XPCOM_ABI}/)。当默认配置被定义于几个目录中,那么最后一个被加载的配置将覆盖之前的配置。

-

Official references for toolkit API

-

-

diff --git a/files/zh-cn/the_mozilla_platform/index.html b/files/zh-cn/the_mozilla_platform/index.html deleted file mode 100644 index 0c994f5c84..0000000000 --- a/files/zh-cn/the_mozilla_platform/index.html +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: The Mozilla platform -slug: The_Mozilla_platform -translation_of: Mozilla/The_Mozilla_platform ---- -

The Mozilla project encompasses several technologies that, together, comprise the Mozilla platform.  These links will direct you to documentation about each of these, as well as how to use the Mozilla platform to build your own projects.

- - - - - - - -
-

Documentation topics

-
-
- Participating in the Mozilla project
-
- Articles about the Mozilla project, including how to contribute to the Mozilla project.
-
- The Mozilla Developer Guide
-
- Tools, tips, and documentation for working with Mozilla's source code.
-
- Using Mozilla code in other projects
-
- How to use Mozilla technologies in your own projects.
-
- JavaScript
-
- Much of the Mozilla project is written in JavaScript.
-
- XPCOM
-
- Information about the Cross-Platform Component Object Model, used to allow components written in different languages communicate with one another.
-
- Interfaces
-
- Documentation for the various interfaces that add functionality to the platform.
-
- XUL
-
- Mozilla projects' user interfaces are described using the XML User Interface Language.
-
- XBL
-
- The Extensible Binding Language is used to bind user interface elements created in XUL to events that are handled by code.
-
- Security
-
- Information related to security in the Mozilla project.
-
- Mobile
-
- Information about the Fennec project, a version of Firefox for mobile devices.
-
- Accessibility
-
- Information about accessibility, the notion that software should be usable by people with disabilities.
-
- Quality Assurance
-
- Documentation about all forms of testing.
-
-
-

Tools

-
-
- Bugzilla
-
- The Bugzilla database used to track issues for Mozilla projects.
-
- MXR
-
- Browse and search the Mozilla source code repository on the Web.
-
- Bonsai
-
- The Bonsai tool lets you find out who changed what file in the repository, and when they did it.
-
- Tinderbox
-
- Tinderbox shows the status of the tree (whether or not it currently builds successfully).  Check this before checking in and out, to be sure you're working with a working tree.
-
- Crash tracking
-
- Information about the Socorro and Talkback crash reporting systems.
-
- Performance tracking
-
- See performance information for Mozilla projects.
-
- Developer forums
-
- A topic-specific list of discussion forums where you can talk about Mozilla development issues.
-
-
-

{{ languages( { "es": "es/La_plataforma_Mozilla", "ja": "ja/The_Mozilla_platform" } ) }}

diff --git a/files/zh-cn/theme_packaging/index.html b/files/zh-cn/theme_packaging/index.html deleted file mode 100644 index 643abe0119..0000000000 --- a/files/zh-cn/theme_packaging/index.html +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: Theme Packaging -slug: Theme_Packaging -tags: - - Themes - - Toolkit API -translation_of: Mozilla/Thunderbird/Thunderbird_extensions/Theme_Packaging ---- -

 

-

This document describes how to package themes for Firefox and Thunderbird.

-
-

Note: This article is out of date, in that it still talks about the contents.rdf file, which has been deprecated since Gecko 1.8, and is no longer supported starting with Gecko 1.9.2. You must use the chrome.manifest method for registering chrome to be forward compatible. It would be greatly appreciated if someone with theming experience could work on an update to this article.

-
-

Pre-requisites

-

Making a theme for Firefox or Thunderbird requires knowledge of Cascading Stylesheets (CSS), probably XBL, and some graphic design and aesthetic skill (...or maybe not). This document describes only how Themes are packaged in order to be shown in Firefox's Themes window.

-

Theme File Layout

-

Firefox/Thunderbird themes are packaged in a JAR file with the following structure:

-
theme.jar:
-  install.rdf
-  contents.rdf
-  preview.png
-  icon.png
-  browser/files
-  global/files
-  mozapps/files
-  communicator/files
-  ...
-
-
- -

install.rdf

-

Your install.rdf manifest will look something like this:

-
<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:type>4</em:type>more properties
-  </Description>
-</RDF>
-
-

Required install.rdf Properties

-

Your install.rdf file must have the following properties. See the install.rdf Reference for more information:

- -

Optional install.rdf Properties

- -

Note that if your theme will be made available on the http://addons.mozilla.org website, it should not include an updateURL.

-

Sample install.rdf File

-
<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>{18b64b56-d42f-428d-a88c-baa413bc413f}</em:id>
-    <em:version>1.0</em:version>
-    <em:type>4</em:type>
-
-    <!-- Target Application this extension can install into,
-         with minimum and maximum supported versions. -->
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>0.8</em:minVersion>
-        <em:maxVersion>0.9</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Front End MetaData -->
-    <em:name>New Theme 1</em:name>
-    <em:description>A test theme for Firefox</em:description>
-    <em:creator>Ben Goodger</em:creator>
-    <em:contributor>John Doe</em:contributor>
-    <em:homepageURL>http://www.bengoodger.com/</em:homepageURL>
-
-    <!-- Front End Integration Hooks (used by Theme Manager)-->
-    <em:internalName>newtheme1</em:internalName>
-  </Description>
-</RDF>
-
-

The following are some common target application GUIDs that you can use in your targetApplication properties:

-
Firefox      {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
-Thunderbird  {3550f703-e582-4d05-9a08-453d09bdfdc6}
-Sunbird      {718e30fb-e89b-41dd-9da7-e25a45638b28}
-
-

Official References for Toolkit API

-
- {{page("/en-US/docs/Toolkit_API/Official_References")}}
-
-  
diff --git a/files/zh-cn/tools/scratchpad/index.html b/files/zh-cn/tools/scratchpad/index.html deleted file mode 100644 index ecfae26051..0000000000 --- a/files/zh-cn/tools/scratchpad/index.html +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Scratchpad -slug: Tools/Scratchpad -tags: - - Scratchpad - - 工具 - - 网页开发 - - 网页开发:工具 -translation_of: Archive/Tools/Scratchpad ---- -
{{ToolsSidebar}}
- -

Scratchpad 使用JavaScript去提供一种实验环境。你能编写,执行代码,并且查看代码和Web页面交互的结果

- -

和被设计为一次只能执行单行命更多工具令的 Web Console 不同的是, Scratchpad 让你可以编辑大段的Javascript代码, 然后就取决于你希望如何输出,有多种方式执行这些代码。

- -

{{EmbedYouTube("Pt7DZACyClM")}}

- -

使用

- -

在单独窗口中打开Scratchpad

- -

有几种不同的方式可以在独立窗口中打开Scratchpad

- - - -

这都能在单独窗口中打开Scratchpad。

- -

从工具箱中打开Scratchpad

- -
New in Firefox 47.
- -

从Firefox 47起,你能从Toolbox中打开Scratchpad。首先你需要在设置的"Default Firefox Developer Tools"部分里选中"Scratchpad"。

- -

现在你应该可以在Toolbox中使用Scratchpad了,还有其他工具,如页面检查器和Web控制台。这在拆分控制台模式下特别有用:您可以使用Scratchpad作为持久性,多行编辑器,或者控制台来与页面进行交互。

- -

编辑

- -

Scratchpad 窗口看起来如下图 (在OS X中菜单条在屏幕顶部)

- -

A screenshot of the Scratchpad

- -

如果想了解编辑器本身或者有用的键盘快捷键,请查看 Using the Source Editor

- -

File菜单提供 Javascript 代码的保存和加载,以便以后你能反复使用这些代码。

- -

代码补完

- -

Scratchpad 使用tern code analysis engine 提供自动补完建议并使用弹出窗口显示当前符号的关于信息。使用 Control + Space 便可以呼出自动补完。如果是为了显示弹出信息, 在Firefox 32中使用Shift + Space

- -

例如,键入d, 然后按下Control + Space。 你可以看到自动补完的弹框,类似如下

- -

每个显示在建议之前的图标表明了类型,当前高亮显示的会弹出更多的信息,使用箭头切换选项并使用EnterTab来选择高亮的选项。

- -

內连文档

- -

当鼠标位于某个标识符上时,通过按下 Ctrl + Shift + Space 进行显示内连文档的弹框. 举个例子, 当你输入 document.addEventListener, 人后按下 Ctrl + Shift + Space, 你将会看到该方法的语法摘要以及一段简介:

- -

这个"[docs]"链接指向该标志的MDN文档

- -

Executing

- -

当你写好了你的代码后,选中你想要的代码来运行。如果你没有选中任何代码,整个窗口的代码都会被执行。选择你想要的运行方式,可以通过顶部的按钮、运行菜单,或者上下文菜单。代码会在当前选中的Tab范围内被执行。你在函数外声明的变量会被加到这个标签栏的全局对象中

- -

这里有4个可用的选项:

- -

Run

- -

当你选择Run选项,选中的代码会被执行。这是用来执行那些只是操纵页面内容而不需要返回结果的函数或者其他代码的。

- -

Inspect

- -

Inspect选项会像Run选项一样执行代码,但是当代码返回时会打开一个对象检查器让你验证返回值

- -

例如,当你敲入这段代码

- -
window
-
- -

然后选择Inspect,对象检查器就会显示如下:

- -

Inspecting an object in the Scratchpad

- -

Display

- -

Display选项执行选中的代码,然后直接将结果作为一个注解插入到你的Sratchpad编辑窗口,所以你可以把它当作一个REPL

- -

Reload And Run

- -

Reload And Run选项只在执行菜单可用,它首先重新加载页面,然后当页面加载完毕执行代码。这在比较古老的运行环境中比较有用。

- -

在浏览器上下文中运行Scratchpad

- -

你可以在整个浏览器的上下文环境运行Sratchpad,而不只是在指定的网页中。这在你使用Firefox工作或开发插件时很有用。要使用这个请在Developer Tool Settings中确认允许chrome跟插件调试。设置完后环境菜单会有个浏览器选项。选中它的时候,你的作用域就是整个浏览器而不只是页面范围了,从下面的测试中可以看出一些全局变量。

- -
window
-/*
-[object ChromeWindow]
-*/
-
-gBrowser
-/*
-[object XULElement]
-*/
- -

Scratchpad的执行环境在该状态下将被设置为browser:当代码段的第一行为
- // -sp-context: browser

- -

Keyboard shortcuts

- -

{{ Page ("zh-CN/docs/tools/Keyboard_shortcuts", "scratchpad") }}

- -

Source editor shortcuts

- -

{{ Page ("zh-CN/docs/tools/Keyboard_shortcuts", "source-editor") }}

diff --git a/files/zh-cn/tools/webide/index.html b/files/zh-cn/tools/webide/index.html deleted file mode 100644 index 3dc19db451..0000000000 --- a/files/zh-cn/tools/webide/index.html +++ /dev/null @@ -1,271 +0,0 @@ ---- -title: WebIDE -slug: Tools/WebIDE -tags: - - NeedsTranslation - - TopicStub -translation_of: Archive/WebIDE ---- -
{{ToolsSidebar}}
-

WebIDE是 App Manager 的替代开发工具。 像App Manager一样,WebIDE能够使你在Firefox OS模拟器 或者真实的Firefox OS设备中运行 Firefox OS 应用程序。

- -

无论如何,WebIDE也为你创建和开发Firefox OS程序提供一个编辑环境, 包括具备编辑和存储你的应用程序所有文件的树形视图,并且提供两个应用程序模板来帮助你开始。

-
- -

要使用WebIDE,你首先需要安装一个或者多个运行环境 。运行环境是你运行和调试应用程序的地方,运行环境可以是通过USB接口链接到电脑的Firefox OS设备,也可能是安装到电脑中的Firefox OS模拟器。

- -

接下来你可以 创建一个app,或者打开已有的app。 如果你正要创建一个新的app,你可以从一个包含目录结构以及你需要的最小样板文件的模板开始。或者从一个更完整的能够展现如何使用特权API的模板开始。WebIDE使用树形结构来显示你的app文件,并且可以使用WebIDE内建的代码编辑器来编辑和存储你的代码文件。当然你不必非要使用内建的编辑器,你完全能够不使用WebIDE来开发你的app,仅仅使用他来调试你的app。

- -

最后,你能够在运行环境中安装和运行你的app,并且打开常用的开发工具套件 -- Inspector, Console, JavaScript Debugger 等来检测和修改正在运行的app。

- -

使用WebIDE来开发和调试程序,你需要的所用东西就是Firefox 33或者更新的版本。为了在一个实际设备上测试,你需要Firefox OS 1.2 或者更新版本,还需要一条USB线。

- -

如果你针对的Firefox OS是1.2 或者更新版本的话, 你只能使用WebIDE调试程序。

- -

打开WebIDE

- -

在Web开发者菜单上点击WebIDE就能打开WebIDE界面, 你也能够使用快捷键 Shift + F8来启动WebIDE:你可以在左边下拉菜单"Open App"中打开已有的apps,或者创建一个新的app, 在右边的下拉菜单 "Select Runtime" 中选择一个运行环境或者安装新的运行环境。

- -

中间的按钮分别是 运行,停止,和调试功能:他们仅仅在你打开了一个应用并选择了一个运行环境时才是可用的。

- -

安装运行环境

- -

在 "Select Runtime" 下拉菜单里,运行环境分为三个类型:

- - - -

在第一次使用时,你可能不会看到任何运行环境:

- -

这部分余下的内容将描述如何安装运行环境。

- -

链接一个Firefox OS设备

- -

在这之前,有一些设置你需要完成:

- - - -
-

Linux系统:

- - -
- -
-

Windows 系统:

- - -
- -

如果有其他的Android设备连接到你的计算机,断开他们。现在你可以使用USB线连接你的设备到计算机, 你应该可以在“USB DEVICE” 下看到你的设备了:

- -

- -

如果你仍然没有看到你的设备,请看 故障排除 页面。

- -

添加模拟器

- -

Firefox OS 模拟器是Firefox OS更高层次的版本,他模拟一个Firefox OS设备, 但是运行在计算机桌面上。模拟器运行在一个与类似Firefox OS设备同样大小的窗体中,他包括Firefox OS用户界面,内建apps,并且模拟了很多Firefox OS设备APIs。

- -

这意味着在许多情况下,你没有必要使用真实的设备来测试和调试你的应用。

- -

模拟器是比较大的,所以没有集成到Firefox浏览器中,而是作为Firefox的一个附加组件 附加组件。如果你在“Select Runtime”中点击 "Install Simulator" ,你会去到一个能够安装各种版本Firefox OS模拟器的页面,如下图:你能够安装你想要的所有模拟器,耐心点,既然模拟器是比较大的,这可能需要花上好几分钟来下载。一旦你已经安装了一些模拟器,你可以关闭“Extra Componets” 窗口, 你安装的模拟器将会显示在“Select Runtime”下拉菜单上面:

- -

要进一步了解模拟器, 请看他的 文档页面

- -

自定义运行环境

- -

使用自定义运行环境,你能够使用任意的主机名和端口来链接远程设备。

- -

在表面之下, Firefox OS设备和Android设备使用一个叫 Android Debug Bridge, or ADB 的程序来连接到电脑桌面。默认情况下,WebIDE使用附件组件 ADB Help: 这简化了让你安装 ADB 和设置转发端口以便Firefox桌面工具能够与设备交换信息的过程。

- -

在大多数情况下这是方便的,但有时候你可能想要单独运行ADB,例如: 你或许需要在命令行上直接运行ADB。在这种情形下,你需要通过命令 adb forward 来指定一个主机和端口来连接到你的设备。
-
- 如果你想用WebIDE来像上面一样手动连接的话, 你应该禁止ADB Helper附件组件,并且使用定制的运行环境,输入主机名和端口号,那也是你要传给adb forward命令的参数。

- -

ADB Helper 目前仍然不支持连接到Android的Firefox, 所以如果你想要连接WebIDE到你的Android Firefox, 你需要设置你自己的转发端口,并使用定制的运行环境。查看更多有关使用ADB连接到Android Firefox

- -

选择运行环境

- -

一旦你设置好了运行环境, 你就就可以使用 “Select Runtime” 来选择你要使用他们。

- - - -

这是在WebIDE工具栏中间的 “ play ” 按钮就可以使用了, 点击它会在当前的运行环境中安装并运行app。

- -

运行环境动态

- -

当一个运行环境被选中后,下拉菜单下面有三个额外的菜单项:

- - - -

- -

- -

创建和打开app

- -

在左边下拉菜单 "Open App" 中有三个菜单项:“New App..." , "Open Packaged App... " "Open Hosted App", 分别对应 创建一个新的app, 打开一个打包的app, 打开一个主机上的app 。

- -

- -

创建一个新的app

- -

选择 "New App..." 来创建一个新的app, 你会看到如下图的对话框提供两个app模板供你选择: "Privileged Empty App" 和 "Privileged App".

- -

- -

两个模板都来自Mozilla的  app模板收集 ,为你提供了程序初始的基本结构。"Privileged App" 模板为你演示了app如何使用权限来装载跨域的远程内容。

- -

一旦你选择了一个模板,你需要命名这个app并选择一个目录来存储这些模板文件,然后你的新app就在项目编辑器中打开了。

- -

开启一个包装的app

- -

选择 "Open Packaged App..." 来打开一个 包装好的app。WebIDE会要求你选择包含 app的manifest 目录, 并且WebIDE会在 project editor 中打开app。

- -

开启一个主机上的app

- -

你可以选择 "Open Hosted App..." 来开启一个 hosted app 。你需要输入一个URL,他链接到app的manifest ,同样app会在 project editor中打开。

- -

编辑app

- -

project editor 为app提供了一个编辑环境,它的左边是app中所有文件的一个树形视图,你能够使用右键中菜单来够添加和删除文件,右边是文件的编辑窗口。

- -

app概要页面

- -

当第一次开启或创建app时, 编辑器的编辑窗口会显示app的概要信息页面,如下图所示:

- -

- -

当你需要回到这个页面时, 你可以通过点击左边视图中的根目录。

- -

Manifest验证

- -

WebIDE会自动地检查manifest一些特定的通用问题,如果发现了问题的话,WebIDE会在app的概要页面上显示app是无效的并描述发现的问题:

- -

- -

当然,你也能够在项目编辑器中将 manifest.webapp 编辑修改正确。

- -

源代码编辑器The source editor

- -

WebIDE使用 CodeMirror 源代码编辑器

- -

Source editor shortcuts

- -

{{ Page ("en-US/docs/tools/Keyboard_shortcuts", "source-editor") }}

- -

代码补全功能

- -

当使用WebIDE编辑 CSS 和 JavaScript的代码时, 编辑器提供自动补全建议, 并且CSS自动补全的功能总是开启的。

- -

要开启JavaScript的自动补全功能,需要按 Ctrl + 空格键:

- -

内联文档

- -

编辑器也可以为JavaScript代码显示内联文档。将光标停留在相应的符号上面,按Shift+Space键可以看到包含文档内容的弹窗。

- -

- -

如上图,点击在弹窗中的[docs],将会链接到符号的MDN页面。

- -

存储文件

- -

你需要存储你的文件才能使修改生效,对于有变化而没有存储的文件,WebIDE会在文件名前面标记星号,你可以通过菜单上的保存功能或使用 Control + S键来存储文件(在Mac OS X系统上的快捷键是 Command + S)。

- -

移除项目

- -

要从WebIDE移除一个app,到app概要页面并点击 "Remove Project" 。

- -

运行与调试app

- -

当你准备好运行app时, 你需到从"Select Runtime" 下拉菜单中选择一个运行环境 。如果你没有任何可用的运行环境,可以在 安装运行环境 章节中找到如何添加一个。

- -

现在,WebIDE 工具栏中的 "play" 按钮已经可以使用了, 点击它可以在选定的运行环境中安装并运行app。

- -

要调试app的话,点击 "Pause" 按钮, 会显示开发者工具箱Toolbox,并连接了你的app:

- -

哪些工具可以使用依赖于你选择的运行环境, 但是至少有这些基本工具:Inspector, Console, JavaScript Debugger, Style Editor, ProfilerScratchpad。恰恰像在一个Web页面中一样,你在工具中所作的任何改变在app中都是可以立即可见的,但是能保存下来。 相反地,你在编辑窗口所作的改变可以保存到磁盘中,但是如果你不重启app的话是不会看到改变的。

- -

调试认证的应用程序 (包括主进程)

- -

你能够针对模拟器、b2g桌面、或者一个真实设备运行调试器。

- -

当选择了一个运行环境的同时,如果你点击app下拉菜单,你不仅可看到你的app,还可以看到运行环境中的所有app。你可以使用模拟器来调试他们,包括认证的应用程序:

- -

- -


- 无论如何,要在一个真实的设备上调试认证的应用程序:

- - - -

要启用认证应用程序调试需要连接到运行环境,然后在WebIDE主菜单 “Runtime” 中选择“Runtime Info” , 如果你看到 "DevTools restricted privileges: yes",意味着认证应用程序不能被调试。启用路径可能随着你针对的调试设备不同而不同:

- - - -

现在,你可以在WebIDE里面看到设备上所有的认证应用程序(B2G 桌面客户端或许需要重启一遍)。

- -

监视执行性能

- -

如果你对你的应用程序的执行性能有兴趣的话,有几个办法可以测量他们对WebIDE的运行环境的影响:

- - - -

故障排除

- -

如果你在使用WebIDE时有任何问题, 请查阅 故障排除 页面.

- -

 

- -

 

diff --git a/files/zh-cn/tools/webide/monitor/index.html b/files/zh-cn/tools/webide/monitor/index.html deleted file mode 100644 index 5a650a572d..0000000000 --- a/files/zh-cn/tools/webide/monitor/index.html +++ /dev/null @@ -1,158 +0,0 @@ ---- -title: Monitor -slug: Tools/WebIDE/Monitor -translation_of: Archive/WebIDE/Monitor ---- -
{{ToolsSidebar}}
-

The WebIDE Monitor is a general-purpose data tool designed to help you track the performance of Firefox OS apps and devices.

-
- -

The WebIDE Monitor

- -

The Monitor is able to display live, interactive graphs to visualize time series.

- -

Available graphs

- -

The Monitor comes with several different graphs. They usually show up once WebIDE is connected to a Firefox OS runtime.

- -

Unique Set Size

- -

Unique Set Size

- -

This graph shows the memory footprint of all Firefox OS processes over time. If you are interested in the memory consumption of a Firefox OS app, launch it, and the private memory used by its process will be displayed here.

- -

Displaying your own data

- -

It's relatively easy to display any kind of data in the Monitor, because it accepts loosely-formatted updates from many different sources.

- -

From a Firefox OS device

- -

You can send data from a connected device by sending observer notifications.

- -

Note: If you would like to do this in a certified app, please follow these instructions.

- -

JavaScript

- -

Services.obs.notifyObservers(null, 'devtools-monitor-update', data);

- -

You can send data from any JS code with chrome privileges. Here is a complete example measuring the run time of some JS code:

- -

const Services = require('Services');
-
- var start = Date.now();
- // code to benchmark
- var stop = Date.now();
-
- var data = { graph: 'Performance', myFeature: stop-start, time: stop }
;
- Services.obs.notifyObservers(null, 'devtools-monitor-update', JSON.stringify(data));

- -

C++

- -

observerService->NotifyObservers(nullptr, "devtools-monitor-update", data);

- -

You can send data from anywhere in Gecko. Here is a complete example measuring the run time of some code:

- -

#include <time.h>
- #include "nsPrintfCString.h"
- #include "nsIObserverService.h"
-
- clock_t start = clock();
- // code to benchmark
- clock_t stop = clock();
- double time = (double)(stop - start) / (CLOCKS_PER_SEC / 1000);
-
- nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
- if (observerService) {
-   nsPrintfCString str("{\"graph\":\"Performance\",\"myFeature\":%f}", time);
-   nsAutoString data = NS_ConvertUTF8toUTF16(str);
-   observerService->NotifyObservers(nullptr, "devtools-monitor-update", data.get());
- }

- -

From your computer

- -

You can easily send data to the Monitor over a WebSockets server. This can be useful if you're writing a Firefox extension, a command-line tool or a web service.

- -

By default, the Monitor looks for a server running on the port 9000 of you computer. You can change this by updating the devtools.webide.monitorWebSocketURL preference.

- -

You can even make it accept data from your local network, or from anywhere on the Internet.

- -

Node.js

- -

TODO

- -

Python

- -

TODO

- -

Supported formats

- -

The Monitor accepts data in the form of JSON objects that generally look like this:

- -

{
-   "graph": "myGraph",
-   "curve": "myCurve",
-   "value": 42,
-   "time": 1234567890
- }

- -

That format is meant to be very flexible. If a specified graph or curve doesn't exist, it will be created automatically.

- -

Arbitrary names

- -

Unrecognized entries will be considered as curve name and value.

- -

The smallest data packet you can send is something like:

- -

{ "myCurve": 42 }

- -

This will add a data point to "myCurve" in a graph with no name. The missing time will default to when the Monitor received the packet.

- -

For better precision, it's probably better to always specify a timestamp for your data:

- -

{
-   "current": 60,

-   "voltage": 500,
-   "time": 1234567890
- }

- -

Multiple values

- -

In a single update, you can send data for multiple curves:

- -

{
-   "graph": "myGraph",
-   "myCurve1": 50,
-   "myCurve2": 300,
-   "myCurve3": 9000,
-   "time": 1234567890
- }

- -

Or several data points for a single curve:

- -

{
-   "graph": "myGraph",
-   "curve": "myCurve",
-   "values": [
-     { "time": 1234567890, "value": 42 },
-     { "time": 1234567981, "value": 51 }
-   ]
- }

- -

Multiple updates

- -

And you can also send multiple data updates as an Array:

- -

[
-   { "graph": "Memory", "time": 1234567890, "System": 2600, "My App": 1000 },
-   { "graph": "Power", "time": 1234567890, "current": 60, "voltage": 500 }
- ]

- -

Punctual events

- -

To mark special events in a graph with a vertical bar, add an event key to your update:

- -

{
-   "graph": "myGraph",
-   "event": "myEvent",
-   "time": 1234567980
- }

diff --git a/files/zh-cn/tools/webide/opening_webide/index.html b/files/zh-cn/tools/webide/opening_webide/index.html deleted file mode 100644 index 5ca53cf1ac..0000000000 --- a/files/zh-cn/tools/webide/opening_webide/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Opening WebIDE -slug: Tools/WebIDE/Opening_WebIDE -translation_of: Archive/WebIDE/Opening_WebIDE ---- -
{{ToolsSidebar}}

有三种方式打开WebIDE:

- - - -

- -

下面是WebIDE的样子:在左边的侧边栏你可以打开已经存在的项目,或者创建新的项目.而在右边的侧边栏你可以选择一个运行环境或者新安装一个运行环境.

- -

中间的按钮分别是:运行,停止和调试app:他们只有在你打开一个项目并且选择了运行环境是才可以使用.

- -

在WebIDE中你可以使用通用的快捷键(在OS X中用Command代替Control)改变字体的大小:

- - diff --git "a/files/zh-cn/tools/webide/\351\227\256\351\242\230\346\216\222\351\231\244/index.html" "b/files/zh-cn/tools/webide/\351\227\256\351\242\230\346\216\222\351\231\244/index.html" deleted file mode 100644 index 4bb1d714d8..0000000000 --- "a/files/zh-cn/tools/webide/\351\227\256\351\242\230\346\216\222\351\231\244/index.html" +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: WebIDE 问题排除 -slug: Tools/WebIDE/问题排除 -translation_of: Archive/WebIDE/Troubleshooting ---- -
{{ToolsSidebar}}

使用USB连接Firefox for Android

- -

如果你试着连接一个Android设备上的Firefox实例,但并没有成功。你可以尝试下面的解决方法:

- - - -

调试认证的应用

- -

如果你想要调试认证的app,包括内建的app,请参考:调试认证的app

- -

启用日志功能

- -

你也可以启用详细日志功能来收集诊断信息:

- -
    -
  1. 访问 about:config, 增加一个新的配置: .console.logLevel, 将其值设置为all,并设置extensions.adbhelper@mozilla.org.debug为True。
  2. -
  3. 插件管理器中禁用 ADB Helper add-on,然后在启用。
  4. -
  5. 打开浏览器控制台 现在你可以看到带adb前缀的控制台信息,如果这个信息对你来说没有任何用处,请寻求帮助
  6. -
- -

获取帮助

- -

你也可以去 IRC的devtools房间 , 我们会尝试提供帮助。

diff --git a/files/zh-cn/updating_an_extension_to_support_multiple_mozilla_applications/index.html b/files/zh-cn/updating_an_extension_to_support_multiple_mozilla_applications/index.html deleted file mode 100644 index 9fc563eb39..0000000000 --- a/files/zh-cn/updating_an_extension_to_support_multiple_mozilla_applications/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: 升级扩展支持多种Mozilla应用程序 -slug: Updating_an_extension_to_support_multiple_Mozilla_applications -tags: - - 扩展 -translation_of: Archive/Updating_an_extension_to_support_multiple_Mozilla_applications ---- -

{{ Previous("Localizing an extension") }}

-

这篇文章展示了如何将一个扩展升级使其能够用于更多的Mozilla应用程序。我们将使用本系列中早先的文章提到的股票监视扩展,将其升级使其能够用于Thunderbird和Sunbird。(原有的版本只能用于Firefox)。

-

如果你还没有建立扩展,或者希望回忆相关内容,可以参考本系列以前的文章:

- -

下载例子

-

你可以下载这篇文章中的示例代码以便和文章对照着看,或者以之作为你自己的扩展的基础。

- -

更新安装清单

-

第一步是修改扩展的install manifest指示它可以安装在Thunderbird和Sunbird上。这通过在<tt>install.rdf</tt>文件中增加新的<targetApplication>标记完成,类似这样:

-
    <!-- Describe the Thunderbird versions we support -->
-
-    <em:targetApplication>
-      <Description>
-        <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
-        <em:minVersion>1.5</em:minVersion>
-        <em:maxVersion>2.0.0.*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Describe the Sunbird versions we support -->
-
-    <em:targetApplication>
-      <Description>
-        <em:id>	{718e30fb-e89b-41dd-9da7-e25a45638b28}</em:id>
-        <em:minVersion>0.2</em:minVersion>
-        <em:maxVersion>0.4.*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-

这两段指明扩展支持Thunderbird 1.5版本到2.0.0.x版本,Sunbird0.2版本到0.4.x版本。

-

插入这段代码以后,你可以将这个扩展安装到Firefox,Thunderbird和Sunbird中任何一个(或全部)上,但是你在Thunderbird和Sunbird上看不到任何效果。

-

这是因为这两个应用程序并不知道由这个扩展提供的chrome能够做些什么。这时候就该chrome manifest登场了。

-

更新chrome清单

-

建立我们自己的chrome清单的时候,可以回忆一下本系列第一篇文章,那时我们还有什么没有接触到?现在该涉及到它了。正像你能够(或者不能)回忆起来的那样,那个文件通知应用程序,你的扩展界面需要覆盖哪些XUL代码。

-

对于Firefox,我们要覆盖<tt>browser.xul</tt>,它描绘了Firefox浏览器窗口。我们需要在Thunderbird和Sunbird清单中加入几行,类似这样的:

-
# Thunderbird
-overlay chrome://messenger/content/messenger.xul chrome://stockwatcher2/content/stockwatcher2.xul
-
-# Sunbird
-
-overlay chrome://calendar/content/calendar.xul chrome://stockwatcher2/content/stockwatcher2.xul
-
-

这些行使得我们通过<tt>stockwatcher2.xul</tt>文件能够覆盖Thunderbird主消息窗口和Sunbird的主窗口。

-

通过这些简单的技巧,这个扩展将能够在所有这三个应用程序中工作,且同样能够以同样的方式运转。

diff --git a/files/zh-cn/using_breakpoints_in_venkman/index.html b/files/zh-cn/using_breakpoints_in_venkman/index.html deleted file mode 100644 index ddf030f18b..0000000000 --- a/files/zh-cn/using_breakpoints_in_venkman/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: 在Venkman中使用断点 -slug: Using_Breakpoints_in_Venkman -tags: - - Tools - - Venkman -translation_of: Archive/Mozilla/Venkman/Using_breakpoints ---- -

这篇文章包含在以Venkman入门开篇的一系列关于Venkman的文档中。

-

调试任何一种编程语言的一个基本任务是设置“断点”。断点表示了代码的执行在什么位置暂停。当你在像Venkman这类调试程序中设置断点时,你可以暂停程序的执行,来检查变量,对象和其它的运行参数。

-

这篇文章描述了在JavaScript中的断点,和如何在Venkman中设置和使用断点。

-

基本的断点

-

“Stop”按钮和debugger命令是JavaScript调试器中很关键的要素,但是当你深入调试极其复杂的代码时,你会发现使用基本的工具已经无能为力,这时你需要断点来帮忙了。

-

断点的类型

-

Venkman有两种类型的断点。第一种,也是最常见的,叫做“硬断点”。A hard breakpoint represents an actual trap instruction included in the pseudocode of a compiled function. Hard breakpoints can only exist in the context of a function currently "live" in the browser. Hard breakpoints are the ones that actually stop program execution.

-

第二种类型的断点,“将来断点”,represents a promise from Venkman to set a hard breakpoint as soon as it is possible. Future breakpoints are used when you want to stop in a script that has not yet been compiled. The most common use of future breakpoints is to stop in a "top level" script (script that executes outside of any function), or script that executes during the onLoad event of a page. When a script is loaded that matches the URL of a future breakpoint, and has executable code at the specified line, Venkman will automatically set a future breakpoint.

-

除了下面提到的这个差别以外,断点工作在Venkman和工作在其它调试器中的情况是很相似的。你在源代码视图左边框看到的点显示了哪一行包含了可执行的代码,同时也表明了那一行可以设置硬断点。

-

“Figure 1” Venkman“源代码”视图中标明的可执行代码

-

设置断点

-

在源代码视图中点击一个圆点,就会在这一行设置一个断点。Venkman会在这行代码执行前停止代码的运行。当一个断点被设置后,这一行左侧的边沿就会变成字母"B",如Figure 2。如果你在设置完断点后再次执行代码,Venkman会在第81行停止运行。

-

“Figure 2” 设置断点

-

Venkman会在“已加载脚本”视图中显示一个或更多已经设置好的断点,一个红色的圆点会出现在已设置有断点的文件旁,后面还会显示断点所在的函数的行号。

-

“Figure 3” 在“已加载脚本”视图中的带有断点的文件

-

使用断点进行调试

-

当你设置一个断点后,你就给了Venkman(或是任何你使用的调试器)显示执行环境信息的机会。 调试脚本或程序,最重要的表现是,它可以检查函数返回值,错误,计数器,变量作用范围,这些改变了脚本执行的路线。

-

在Figure 1中的onFlipX函数,例如,使用变量newSign来指明用什么图片表示fish。当你在第81行设置一个断点,你可以激活浏览器窗口的页面,Venkman停止代码的执行,当他加入了onFlipX函数。停在那里,Venkman在本地变量视图中显示了变量newSign的值"1"。

-

“Figure 4” 在断点处的本地变量

-

使用断点和交互视图,你可以改变Venkman显示的变量值(仅仅是在调试环境的上下文中),还可以观察这些改变怎样影响代码的执行。

-

“Figure 5” 在断点处与脚本结合

-

如果你想获得更多关于“调试动作”的信息,请浏览Venkman入门的调试基础章节。

-

清除断点

-

点击两次边框来清除断点。第一次单击会清除硬断点,只保留一个用字母“F”表示的将来断点。第二次单击将会清除将来断点。

-

“Figure 6” 将来断点

-

高级断点

-

Venkman允许你将一个断点和一段脚本关联在一起:当遇到断点时,这个脚本就会被执行。这个针对关联脚本的高级特性和其他一些选项,你可以在将来断点属性对话框中找到他们,你只需要右键单击一个断点,选择“属性”。

-

“Figure 7” 将来断点属性对话框

-

一旦你创建了一个与断点相关联的脚本,你就可以从将来断点属性对话框中选择一些不同的选项,这些选项决定了Venkman如何处理关联脚本的输出。下面是经常用到的选项:

- -

关键性注释

-

You can also embed scripted breakpoints directly into the souce code you are debugging by using a Venkman facility called - - meta comments - . Meta comments are specially formatted comments that pull in the script named after the comment and specify how to treat the output of that script. The following meta comment types are available:

- -

To enable meta comments in a script, select "Scan for Meta Comments" from the context menu of the file in the Loaded Scripts view.

-

When you add a meta comment, a normal breakpoint is created. You can change or delete this breakpoint just as you would a breakpoint created by hand.

-

Resources

- -
-

Original Document Information

- -
-
-

--AndyYard 01:46 2007年11月15日 (PST)

diff --git a/files/zh-cn/using_mozilla_code_in_other_projects/index.html b/files/zh-cn/using_mozilla_code_in_other_projects/index.html deleted file mode 100644 index 29ca57d7b1..0000000000 --- a/files/zh-cn/using_mozilla_code_in_other_projects/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: 在其他项目中使用Mozilla代码 -slug: Using_Mozilla_code_in_other_projects -translation_of: Mozilla/Using_Mozilla_code_in_other_projects ---- -

在你自己的项目中,可以通过以下方式使用Mozilla代码。

- - -

创建XUL应用程序

The Joy of XUL
XUL入门;开发新手必读。
XUL参考
完整的XUL参考。
XULRunner
一个Mozilla运行时包,通过它可以用来方便的引导XUL和XPCOM应用程序。
Mozilla Toolkit
Mozilla工具包API信息。

使用Mozilla组件

SpiderMonkey
SpiderMonkey是用在Mozilla项目中的JavaScript运行时引擎。
NSPR
Netscape Portable Runtime为系统级的和库类型的函数提供了一个平台中立的API。
Necko
提供跨平台网络功能的Mozilla网络库。
-

嵌入Mozilla

-

在您自己的应用程序中嵌入一个Web浏览器的更多内容见Embedding Mozilla.

-

{{ languages( {"zh-cn": "cn/Using_Mozilla_code_in_other_projects", "en":"en/Using_Mozilla_code_in_other_projects"} ) }}

diff --git a/files/zh-cn/using_the_clipboard/index.html b/files/zh-cn/using_the_clipboard/index.html deleted file mode 100644 index 2f0e6659d5..0000000000 --- a/files/zh-cn/using_the_clipboard/index.html +++ /dev/null @@ -1,158 +0,0 @@ ---- -title: 使用剪贴板 -slug: Using_the_Clipboard -translation_of: Mozilla/Tech/XPCOM/Using_the_clipboard ---- -

This section provides information about cutting, copying and pasting to and from the clipboard.

-

The Clipboard

-

Mozilla provides a number of interfaces for accessing the clipboard. The component @mozilla.org/widget/clipboardhelper;1 can be used to copy text to the clipboard. This component implements the interface nsIClipboardHelper, which has a function copyString which can be used to copy a string.

-

Mozilla 提供很多剪贴板的接口。可使用 nsIClipboardHelper 接口的方法 copyString ,实现对字符串的拷贝。

-
const gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].
-getService(Components.interfaces.nsIClipboardHelper);
-gClipboardHelper.copyString("Put me on the clipboard, please.");
-
-

This example will first create a clipboard helper and then copy a short string to the clipboard. This method only works to put strings on the clipboard. For other types of data, such as URLs or images, you will need to use a more complex method.

-

以上方法只提供了拷贝一个字符串的功能,如实现拷贝其他类型数据,如 URLS 或者图片,需使用其他较复杂的方法。

-

A component @mozilla.org/widget/clipboard;1 and an interface nsIClipboard provide general access to the system clipboard. You can use it to copy and paste any type of data from your application to the clipboard. Three XPCOM objects are needed to handle clipboard operations. The first is an object that holds the data to put on the clipboard. The second is the clipboard object. The third is an object which is used to transfer the data from the first object to the clipboard. The clipboard model in Mozilla requires you to perform the following steps to copy data:

-

nsIClipboard 接口提供了系统剪贴板的入口。可使用该接口拷贝粘贴任何类型的数据到剪贴板中。不过,需要三种XPCOM对象来实现该功能。第一,拷贝的源数据对象;第二,剪贴板对象;第三,粘贴目标对象。

-

可使用一下步骤来拷贝数据:

-
    -
  1. Create an XPCOM wrapper for the data which you want to put on the clipboard. This is needed because you can put anything on the clipboard from text to images.  将要拷贝的数据封装到xpcom对象中。这样就可以把各种类型的数据填充到剪贴板了。
  2. -
  3. Create a transferring object. This object can be the component @mozilla.org/widget/transferable;1 which implements the interface nsITransferable.创建一个传输对象,需实现 nsITransferable 对象。
  4. -
  5. Tell the transferring object about the type of data being copied. 告知传输对象将要拷贝的数据类型。
  6. -
  7. Tell the transferring object about the data to copy. 告知传输对象将要拷贝的数据。
  8. -
  9. Create a clipboard object which refers to the system clipboard. 创建一个剪贴板对象,该对象将指向系统剪贴板。
  10. -
  11. Tell the clipboard object to copy the data using the transferring object.  剪贴板对象使用传输对象完成剪贴板对象对数据的拷贝。
  12. -
-

You might wonder why a transferring object is needed instead of just putting the object directly on the clipboard. One reason is that some systems do not copy the data right away. Instead, they wait until the data is pasted. Another reason is that the transferable can hold multiple representations of the same data. For example, a piece of HTML can be represented in both its original HTML form and in plain text. If an application wants to get the data from the clipboard and doesn't understand HTML, it can use the plain text version. If it does understand HTML, it can grab that version. The transferring object will hold the clipboard contents until the application has decided what it needs. This allows the clipboard to be used by another application right away.

-

为什么要借用传输对象,而不是直接将对象放置于剪贴板中呢?原因之一,一些系统并不是立即拷贝数据,相反,它们在数据被粘贴时才进行拷贝;原因之二,传输对象可持有同一数据的多种表示形式。如:一份HTML数据可表示为原始HTML格式或者是纯文本格式。当应用程序需要拷贝该数据却不能识别HTML时,它可使用纯文本格式;如果识别,则抓取HTML格式。传输对象将持有该剪贴板数据,直到程序决定如何使用它们时。这样,剪贴板可方便其他应用程序使用。

-

Let's break down the steps needed to copy data to the clipboard. First, we need to create an XPCOM object to wrap what we want to copy. We'll assume that we want to copy some text. We will use the interface nsISupportsString which can be used to represent strings (specifically, Unicode strings).

-

以下将分步实现将数据拷贝到剪贴板中。

-

首先,创建封装拷贝数据的XPCOM对象。这里用 nsISupportsString 接口表征字符串(特别是 Unicode 字符串)。

-
var copytext = "Text to copy";
-var str      = Components.classes["@mozilla.org/supports-string;1"].
-                          createInstance(Components.interfaces.nsISupportsString);
-str.data     = copytext;
-
-

The first line holds the text that we want to copy. Next, the variable str is assigned to a component that can be used to hold a string. The third line assigns the string to the component using the data property. Here, the string "Text to copy" will be copied but you can replace this with the text string that you want to copy. Now that we have the object to copy, a transferring object needs to be created:

-

创建传输对象。  

-
var trans = Components.classes["@mozilla.org/widget/transferable;1"].
-                       createInstance(Components.interfaces.nsITransferable);
-trans.addDataFlavor("text/unicode");
-trans.setTransferData("text/unicode", str, copytext.length * 2);
-
-

  

-

The first line gets the transferring component which implements nsITransferable. Next, we need to tell the transferable what type of data we want to use. The type of data is referred to as a data flavor. The function addDataFlavor is used to tell the transferable that it needs to transfer data of a certain flavour. In this case, we are transferring the flavor "text/unicode" which is a Unicode string. Then, the function setTransferData is called which copies the data from the string into the transferable. This function takes three parameters. The first is the flavor we are setting, the second is the object holding the string and the third is the length of the data, in bytes. Here, the length is multiplied by two because we are using a Unicode string which requires two bytes per character.

-

创建传输对象组件;告知传输对象要传输的类型,用 addDataFlavor 指定;使用 setTransferData 方法来设置传输的数据:包括数据类型,数据内容,以及数据长度。

-

You can repeat the last two lines and call addDataFlavor and setTransferData for multiple flavors. That way, you could have a text version and an HTML version of the content. The Transferable object will hold its own copy of the data. When you've added all the flavors you want, you can put it all on the clipboard at once. The transferable object will hold all of the data that you want until you're ready to put it on the clipboard.

-

Next, we need to create a clipboard object that refers to the system clipboard.

-
var clipid = Components.interfaces.nsIClipboard;
-var clip   = Components.classes["@mozilla.org/widget/clipboard;1"].getService(clipid);
-clip.setData(trans, null, clipid.kGlobalClipboard);
-

We get the system clipboard object and store it in the clip variable. We can copy the data to the clipboard by calling the function setData. The first parameter of this function is the transferable. The second parameter can usually be set to null but you could set it to a nsIClipboardOwner so that you can tell when the data you've copied is overwritten by another copy operation. Call setData only when you're ready to copy to the system clipboard.

-

The third parameter to setData (and the parameter to emptyClipboard) indicates which clipboard buffer to use. The above code uses the constant kGlobalClipboard for this, which refers to the global clipboard. This would be the same one that cut and paste operations from the Edit menu typically use. If you use kSelectionClipboard instead, you will copy into the selection buffer, which is generally only available on Unix systems.

-

This multi-step process has resulted in text being copied on the clipboard. We can cut to the clipboard instead of copying by doing a copy and then deleting the original data. Normally, the text would be in a document or textbox. The code is put together below, with additional error checking:

-
var copytext = "Text to copy";
-
-var str = Components.classes["@mozilla.org/supports-string;1"].
-createInstance(Components.interfaces.nsISupportsString);
-if (!str) return false;
-
-str.data = copytext;
-
-var trans = Components.classes["@mozilla.org/widget/transferable;1"].
-createInstance(Components.interfaces.nsITransferable);
-if (!trans) return false;
-
-trans.addDataFlavor("text/unicode");
-trans.setTransferData("text/unicode", str, copytext.length * 2);
-
-var clipid = Components.interfaces.nsIClipboard;
-var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(clipid);
-if (!clip) return false;
-
-clip.setData(trans, null, clipid.kGlobalClipboard);
-
-

The complete function shown below copies some text to the clipboard as HTML, as well as making it a clickable Hyperlink. So we've added a text flavor and an HTML flavor of the content. The Transferable object will hold both flavors.

-
copyLinkToClipboard : function(copyURL,copyLabel) {
-
-// generate the Unicode and HTML versions of the Link
-
-var textUnicode = copyURL;
-var textHtml = ("<a href=\"" + copyURL + "\">" + copyLabel + "</a>");
-
-
-// make a copy of the Unicode
-
-var str = Components.classes["@mozilla.org/supports-string;1"].
-                       createInstance(Components.interfaces.nsISupportsString);
-if (!str) return false; // couldn't get string obj
-str.data = textUnicode; // unicode string?
-
-
-// make a copy of the HTML
-
-var htmlstring = Components.classes["@mozilla.org/supports-string;1"].
-                       createInstance(Components.interfaces.nsISupportsString);
-if (!htmlstring) return false; // couldn't get string obj
-htmlstring.data = textHtml;
-
-
-// add Unicode & HTML flavors to the transferable widget
-
-var trans = Components.classes["@mozilla.org/widget/transferable;1"].
-                       createInstance(Components.interfaces.nsITransferable);
-if (!trans) return false; //no transferable widget found
-
-trans.addDataFlavor("text/unicode");
-trans.setTransferData("text/unicode", str, textUnicode.length * 2); // *2 because it's unicode
-
-trans.addDataFlavor("text/html");
-trans.setTransferData("text/html", htmlstring, textHtml.length * 2); // *2 because it's unicode
-
-
-// copy the transferable widget!
-
-var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"].
-                       getService(Components.interfaces.nsIClipboard);
-if (!clipboard) return false; // couldn't get the clipboard
-
-clipboard.setData(trans, null, Components.interfaces.nsIClipboard.kGlobalClipboard);
-return true;
-
-},
-
-

Pasting Clipboard Contents

-

To paste data from the clipboard we can use a similar process, except we use getData instead of setData and getTransferData instead of setTransferData. Here are the steps to pasting:

-
    -
  1. Create a clipboard object which refers to the system clipboard.
  2. -
  3. Create a transferring object which implements the nsITransferable interface.
  4. -
  5. Tell the transferring object about the flavor of data you want to get.
  6. -
  7. Retrieve the data from the clipboard and put it in the transferable.
  8. -
  9. Get the data from the transferring object.
  10. -
-

The first steps are similar to that used for copying:

-
var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard);
-if (!clip) return false;
-
-var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
-if (!trans) return false;
-trans.addDataFlavor("text/unicode");
-
-

This code gets the system clipboard object and a transferable object. The flavor is added to the transferable. Next, we need to get the data from the clipboard:

-
clip.getData(trans, clip.kGlobalClipboard);
-
-var str       = new Object();
-var strLength = new Object();
-
-trans.getTransferData("text/unicode", str, strLength);
-
-

The first line performs the opposite of getData. The data currently on the system clipboard is placed into the transferable. Next we create two JavaScript objects which will hold the data and the length of the data. Note that we have no idea what type of data is currently on the clipboard. It may have been placed there by another application. This is why we use generic Objects for str and strLength.

-

Then we use getTransferData to retrieve the data from the transferable. We specify the flavor we would like to get. The data will be converted if it is not of the desired flavor and a conversion between the actual and desired flavor is possible. If you originally copied data of multiple flavors onto the clipboard, you can retrieve the data in the best format necessary. For example, a textbox would accept "text/unicode" (or "text/plain") while a Composer window might accept HTML and image data.

-

The variable str now holds the data from the clipboard. We need to convert the data back into a JavaScript string from an XPCOM object. The code below can be used for this purpose:

-

 

-
if (str) str       = str.value.QueryInterface(Components.interfaces.nsISupportsString);
-if (str) pastetext = str.data.substring(0, strLength.value / 2);
-
 
-

Because the data from the transferable is a nsISupportsString, we need to convert it into a JavaScript string. The property value of the object filled in by getTransferData, which is str in this case, provides the actual value of the object.

-

We assign the string to the variable pastetext. We can then put that into a textbox or other location as necessary.

diff --git a/files/zh-cn/using_workers_in_extensions/index.html b/files/zh-cn/using_workers_in_extensions/index.html deleted file mode 100644 index 73bed93d1b..0000000000 --- a/files/zh-cn/using_workers_in_extensions/index.html +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: 在 extensions 中使用 workers -slug: Using_workers_in_extensions -tags: - - Extensions - - Workers -translation_of: Archive/Using_workers_in_extensions ---- -

{{ Previous("Updating an extension to support multiple Mozilla applications") }}

- -

{{ fx_minversion_header(3.5) }}

- -

这篇文章为你演示了如何在不阻塞UI的情况下,利用worker进程在扩展中执行后台任务。

- -

如果你还没创建一个扩展,或者想缕下自己的记忆,那么就看下这个系列中之前的文章。

- - - -

下载样例

- -

你可以从下面的链接下载完整的样例:

- - - -

该版本和之前版本的区别

- -

这个版本的stock ticker extension 将 获取最新股票信息的XMLHttpRequest调用移到了一个 worker thread,然后将那些信息传递到这个扩展代码的主体中,从而更新状态栏的展示。 这不仅展示了如何在扩展中使用workers,也展示了如何在worker中执行 XMLHttpRequest ,并且展示了workers和主线程之间如何来回传递数据。 

- -

The worker

- -

这个示例中worker thread的作用就是为了发出XMLHttpRequest的调用,从而获取最新的股票信息。 它所做的就是下面的内容: 每隔十分钟,它调用XMLHttpRequest,当接收到结果时,将含有接收到的数据的事件传递到主线程。

- -

因此我们需要将 refreshInformation() 方法从 stockwatcher2.js文件中移动到ticker_worker.js中,这个文件将host the worker thread。 ticker_worker.js代码如下所示:

- -
var symbol = "";
-
-function refreshInformation() {
-  if (!symbol) {
-    throw "No symbol set!";
-  }
-
-  var fullUrl =
-    "http://quote.yahoo.com/d/quotes.csv?f=sl1d1t1c1ohgv&e=.csv&s=" + symbol;
-
-  function infoReceived()
-  {
-    var output = httpRequest.responseText;
-    if (output) {
-      postMessage(output.trim());
-    }
-    httpRequest = null;
-  }
-
-  var httpRequest = new XMLHttpRequest();
-  httpRequest.open("GET", fullUrl, true);
-  httpRequest.onload = infoReceived;
-  httpRequest.send(null);
-}
-
-setInterval(function() {
-  refreshInformation();
-}, 10*60*1000);
-
-onmessage = function(event) {
-  if (event.data) {
-    symbol = event.data.toUpperCase();
-  }
-  refreshInformation();
-}
- -

当 worker thread被启动后, 代码主体 (在26-35行)被执行。通过设置一个间断的handler来开始它,这个handler每10分钟调用下refreshInformation() 。

- -

然后它将这个worker的onmessage event handler 设置给接收event参数的一个函数, 并且做下面两件事中的一个:

- - - -

refreshInformation() 方法和之前的版本相当相似,也有两个需要注意的例外:

- - - -

主线程

- -

这里的改动也相对较少,但是很重要。

- -

startup() 方法

- -

当扩展被加载的时候,这个方法就被调用了,并且需要更新下从而启动和配置worker。让我门看下代码:

- -
  startup: function()
-  {
-    // Register to receive notifications of preference changes
-
-    this.prefs = Components.classes["@mozilla.org/preferences-service;1"]
-        .getService(Components.interfaces.nsIPrefService)
-        .getBranch("stockwatcher2.");
-    this.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
-    this.prefs.addObserver("", this, false);
-
-    this.tickerSymbol = this.prefs.getCharPref("symbol").toUpperCase();
-
-    this.worker = new Worker("chrome://stockwatcher2/content/ticker_worker.js");
-
-    // Small little dance to get 'this' to refer to StockWatcher, not the
-    // worker, when a message is received.
-    var self = this;
-    this.worker.onmessage = function(event) {
-      self.onworkermessage.call(self, event);
-    };
-
-    this.worker.postMessage(this.tickerSymbol);
-  },
-
- -

worker 在第13-22行被设置和配置:

- - - -

observe() 方法

- -

这个方法主要用来当用户更改首选项的时候,更新哪个股票正在被监视。它需要向worker发送一个消息,从而告诉它需要监视哪个股票代号。

- -
  observe: function(subject, topic, data)
-  {
-    if (topic != "nsPref:changed") {
-      return;
-    }
-
-    switch(data) {
-      case "symbol":
-        this.tickerSymbol = this.prefs.getCharPref("symbol").toUpperCase();
-        this.worker.postMessage(this.tickerSymbol);
-        break;
-    }
-  },
-
- -

第10行是关键, 通过调用ticker线程的postMessage()方法向监视器发送一个新的股票代码。

- -

watchStock() and refreshInformation() 方法

- -

这两个方法非常简单. watchStock()用来向ticker 线程传递代号; refreshInformation()的主要函数体现在在worker里面 ,被用来向worker简单传递一个空消息,从而告诉worker立刻刷新股票信息。

- -
  watchStock: function(newSymbol)
-  {
-    this.tickerSymbol = newSymbol.toUpperCase();
-    this.prefs.setCharPref("symbol", newSymbol);
-    this.worker.postMessage(this.tickerSymbol);
-  },
-
-  refreshInformation: function()
-  {
-    // Empty message just means 'refresh'.
-    this.worker.postMessage("");
-  },
-
- -

onworkermessage() 方法

- -

当worker向主线程回传一个消息的时候,这个方法被调用。它主要用来向当前展示的状态栏中更新股票信息,在鼠标放到ticker上时,它也被用来更新显示的提示信息。这些代码基本和上个版本的做法一致,除了它是在事件中的response中完成的,而不是在refreshInformation() 方法中。

- -

{{ h2_gecko_minversion("A note about ChromeWorkers", "2.0") }}

- -

{{ gecko("2.0") }} 添加了新的 {{ domxref("ChromeWorker") }} 对象, 提供了一个只能在chrome的应用和扩展中使用的worker。这个worker对象可以访问  js-ctypes, 而标准的worker是不能的。

- -

See also

- - diff --git a/files/zh-cn/venkman/index.html b/files/zh-cn/venkman/index.html deleted file mode 100644 index b685a131c4..0000000000 --- a/files/zh-cn/venkman/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: venkman -slug: venkman -translation_of: Archive/Mozilla/Venkman ---- -

Venkman is the code name for Mozilla's JavaScript Debugger. It aims to provide a powerful JavaScript debugging environment for Mozilla based browsers namely Firefox, Netscape 7.x/9.x and SeaMonkey. Note that it is not included in the Gecko-based browsers such as K-Meleon, Galeon and Netscape 8.x. Venkman has been provided as part of the Mozilla install distribution since October 2001, as well as an extension package in XPI format.

- - - - - - - -
-

Documentation

-
-
- Venkman Introduction
-
- An overview and some practical examples of using the JavaScript Debugger in Web development.
-
- Using Breakpoints in Venkman
-
- This article describes breakpoints in JavaScript and how to use Venkman to set and examine breakpoints.
-
- Learning the JavaScript debugger Venkman
-
- Written by Svend Tofte to the JavaScript programmers who are not familiar with other debugging tools.
-
- Venkman FAQ
-
- Answers to common questions on Venkman.
-
- Venkman Internals
-
- Notes on Venkman source code.
-
- Venkman Development Page
-
- Older news and releases.
-
-

View All...

-

Brief History

-

In 1998, John Bandhauer was in charge of creating the Netscape 4.x JavaScript debugger. In order to keep things modular, he began by creating a mid-level JavaScript debugging API known as js/jsd. This API augments the existing JavaScript API, providing clients with a useful set of debugger functionality implemented in C.  Bandhauer then went on to reflect that API into Java, and create his cross platform front end, eventually producing Netscape JavaScript Debugger 1.0 and 1.1.

-

In April of 2001, Robert Ginda began work on a JavaScript debugger for Mozilla, called Venkman. Venkman builds on the js/jsd portion of John's 1998 work, {{ Source("js/jsd/idl/jsdIDebuggerService.idl", "exposing it") }} as an XPCOM component. This allows the {{ Source("extensions/venkman/resources/content/", "user interface") }} be written in JavaScript and XUL, which allows Venkman to be fully cross-platform.

-

Venkman is named after the character Dr. Peter Venkman, played by Bill Murray in the movies Ghostbusters and Ghostbusters II.

-
-

Getting Venkman

-
-
- Firefox and Thunderbird
-
- The latest version of JavaScript Debugger is available from Firefox Add-ons.
-
- Mozilla Suite and SeaMonkey
-
- These releases come with Venkman pre-installed. On Windows, it is an install option; choose Advanced install. Also available from Firefox Add-ons as an extension.
-
- Nvu and KompoZer
-
- JavaScript Debugger extension version 0.9.84 is available from Nvu's downloads page. We encourage you to use the latest available version 0.9.87.1 (or higher) with Firefox instead.
-
- Source Code
-
- The source code for Venkman may be found in Mercurial at the following URL: http://hg.mozilla.org/venkman/summary
-
-

Community

-
    -
  • View Mozilla forums...
  • -
-

{{ DiscussionList("dev-apps-js-debugger", "mozilla.dev.apps.js-debugger") }}

- -

Report a bug in Venkman

-

If you find a problem with Venkman, please follow directives mentioned at Venkman FAQ section 5.4 and then you may report a bug on JavaScript Debugger component.

- -

JavaScript, Web Development, Developing Mozilla

-
-
-

Original Document Information

- -
-

 

diff --git a/files/zh-cn/venkman_internals/index.html b/files/zh-cn/venkman_internals/index.html deleted file mode 100644 index 72eb0127b3..0000000000 --- a/files/zh-cn/venkman_internals/index.html +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: Venkman精髓 -slug: Venkman_Internals -tags: - - Developing Mozilla - - Tools - - Venkman -translation_of: Archive/Mozilla/Venkman/Internals ---- -

Start with Venkman Information.

-

Notes on Venkman source code. As with any complex application, aspects of the design may not be clear for new readers of the source. These notes are written by such readers: as you learn please correct any errors.

-

Questions

-

- - Why can't breakpoints be set on some source lines some of the time? -

-

Sometimes the source has small ticks in the margin for every executable line in my JavaScript. Sometimes these ticks are missing on some or all lines of a file. Only lines with tick marks seem to break point properly.

-
-
- Venkman asks the JS engine which lines are executable. It will mark these with a "tick" as you call it. If the file is not currently loaded, the JS engine doesn't know anything about the file. You can still set breakpoints, but they will be future breakpoints, which will be "real" breakpoints when/if the file is loaded (note that this may never happen!). Note also that this is just my knowledge of Venkman, which is quite limited. You would be better off asking Silver (James Ross). GijsKruitbosch 05:41, 7 March 2007 (PST)
-
-

{{ Source("extensions/venkman/resources/content/venkman-debugger.js", "venkman-debugger.js") }}

-

Sets hooks in to the jsdIDebuggerService. initDebugger().

-

ScriptManager

-

In initDebugger() the previous loaded scripts are passed to an onScriptCreated() method which binds them to a ScriptManager. There is one ScriptManager per url (web page). This method is set into jsdIScriptHook.onScriptCreated

-

{{ Source("extensions/venkman/resources/content/venkman-views.js", "venkman-views.js") }}

-

Views are the panels shown within the venkman window. For example, the "Open Windows" view shows the browser's windows.

-

{{ Source("extensions/venkman/resources/content/venkman-records.js", "venkman-records.js") }}

-

A "record" seems to be data underlying a view. For example, FrameRecord represents a JavaScript stack frame.

-

venkman-msg.js

-

Localization code, reads venkman.properties from a subdirectory of "locale" and injects variables. Things like msg.alert define variables MSG_ALERT.

-

venkman-utils.js

-

Defines the dd debug dump and friends

-

WindowRecord

-

Representation of the open windows.

- -

ScriptWrapper

-

newsgroup, 2002, rgrinda

-

Here is a bit more information about how Venkman tracks files and functions...

-

A scriptWrapper is a pure JS object defined only inside Venkman. As you pointed out, there is a 1:1 relationship between scriptWrappers and functions. scriptWrapper has-a jsdScript property, which is an object which supports the jsdIScript interface. jsdIScript is a lower level access to the function than the scriptWrapper. In order to set a breakpoint in a particular function, you'll want to call scriptWrapper.setBreakpoint(pc{{ mediawiki.external(', parentBP') }}); where |pc| is the program counter location to set the breakpoint, and |parentBP| is an optional "future breakpoint" object to use as the parent for this breakpoint. If you set the breakpoint right from the jsdScript instead, you wouldn't see it in the Venkman UI, and you might confuse Venkman when the actual breakpoint was hit and it couldn't find a matching breakpoint object.

-

You can see the prototype for this object at http://lxr.mozilla.org/mozilla/sourc...ebugger.js#914

-

scriptWrapper.jsdScript is the reference to the jsdIScript object for the function.

-

sourceContext is the 5 lines of source text before the last instance of the word "function" on the line where this function starts. (not in 2006, seems to be computed on the fly in getSourceContext()).

-

The full text of the file can be found in an array located at scriptWrapper.scriptInstance.sourceText.lines. This array is 0 based, of course.

-

The starting line of the function is scriptWrapper.jsdScript.baseLineNumber (one based).

-

The total length of the function is scriptWrapper.jsdScript.lineExtent.

-

If you want to get at the pretty printed source text, instead of the actual source text, use scriptWrapper.jsdScript.functionSource.

-

ScriptInstance

-

All scriptWrappers are parented by a single scriptInstance, which holds all of the scriptWrappers for a particular URL. From here, you can set and clear breakpoints by line number (instead of by program counter), locate a scriptWrapper for a given line number, and do a few other useful things. scriptInstance.functions is a hash of all of the functions in the script instance, keyed by the tag property of the jsdScript. scriptInstance.topLevel is the top-level script for the instance.

-

ScriptManager

-

Sometimes the same URL is loaded more than once in the browser. To deal with this, all scriptInstances are parented by a single scriptManager. A scriptManager keeps all of the loaded instances of a particular URL in the scriptManager.instances array, in the order that they were loaded. From here, you can set and clear breakpoints in all instances. scriptManager.transients is a hash of all of the "transient" scripts from this URL, where a transient script is something compiled as a the result of an eval, setTimeout, or setInterval.

-

Try starting up Venkman and type "/watch-expr client.scriptManagers", make sure to turn on "Include Functions". This tree should give you a pretty good idea of how it all fits together.

diff --git a/files/zh-cn/venkman_introduction/index.html b/files/zh-cn/venkman_introduction/index.html deleted file mode 100644 index 81e85ea831..0000000000 --- a/files/zh-cn/venkman_introduction/index.html +++ /dev/null @@ -1,351 +0,0 @@ ---- -title: Venkman入门 -slug: Venkman_Introduction -tags: - - Tools - - Venkman -translation_of: Archive/Mozilla/Venkman/Introduction ---- -

一个强大的新工具现在提供给使用基于Mozilla的系列浏览器(包括Firefox,Mozilla套件和Netscape 7.x)的Web开发人员。JavaScript调试器,又名“Venkman”,已经成为Mozilla浏览器、Web社区和脚本开发人员的一部分很长时间了。这篇文档提供一个JavaScript调试器的概览和一些在Web页面脚本开发中使用它的实际例子。这篇“入门”是一系列关于Venkman文档的第一篇。假设你已经开始使用Venkman,这里所提到的特性、程序和要点会让你作为一个Web开发人员或脚本调试者更加自信。

- -

Venkman是一个同时拥有控制台界面和图形界面的调试器。你可以根据自己的喜好或特长,从控制台界面或图形界面使用“断点控制”,“调用栈”和“变量/对象监视器”。交互式的命令行界面允许你执行任何可用的JavaScript代码。Venkman的键盘快捷键可用于可视化的调试环境,gdb用户对于Venkman的/break/step/next/finish/frame/where命令一定非常熟悉。

- -

在Windows平台上上,JavaScript调试器的界面外观和Visual Interdev以及其它大型的web开发工具是很相似的。在其它操作系统平台上,如Mac OS和Unix,它提供了一个在易用性、性能居于同等水平上的独特的开发调试环境。

- -

开始使用调试器

- -

JavaScript调试器会被自动的预装在Mozilla 1.x里,但是在Firefox和其它基于Gecko的产品中(如Thunderbird和Netscape 7.x)中必须被单独安装。幸运的是,XPInstall技术使你只需要点击一个超级链接就可以在Firefox安装一个新的应用模块。

- -

如果你还没有拥有Venkman,并且希望升级使用它,你可以通过访问Firefox Add-ons来获得最新版本。安装过程只需要两个步骤:首先,从你希望安装Venkman的浏览器中,访问Firefox Add-ons 页面,点击“install”链接获得最新版本。下载完成后,重新启动你的浏览器(一些Windows用户可能还需要重新启动计算机)。 You can then access the debugger via a new, dynamically created menuitem in the Tools menu of that browser, or else restart the browser with a special debugger option.

- -

如果你想查看你使用的Venkman的版本号,在交互视图区域中输入/version。 如果想了解更多关于版本和升级的信息,请访问Venkman Development Page.

- -

下面有两种启动调试器的方法:

- - - -

(当Venkman启动显示"Recorded local startup X, global YYY."时,请注意这些有用的信息。This data comes from a counter built in to the application. For more information about this counter and the data, see Item 2.2 in the Venkman FAQ.)

- -

Figure 1. The JavaScript Debugger.

- -

当你第一次启动Venkman,the basic views are arranged as in the screenshot above—though you can customize the layout and presence of the different views however you want, as we describe in the {{ Anch("View Customization") }} section below. The scripts that have been loaded by the JavaScript engine appear in the Loaded Scripts window (for more information about how scripts are loaded and accessed in Venkman, see "{{ Anch("Loading Scripts into the Debugger") }}").

- -

Figure 2. View Controls

- -

The menubar, toolbar, and all of the views can be collapsed or hidden, giving you a lot of control over the debugging environment. The {{ Anch("Source Code View") }} is empty until you select a script, and {{ Anch("The Interactive Session View") }} starts up with basic startup information.

- -

每一个视图面板都有一个“标签”,一个“浮动按钮”(使面板脱离调试器主窗口,拥有自己单独的窗口)和一个“关闭按钮”。请参看Figure 2。

- -

The following section describes these views and their use within the interface as a whole.

- -

Venkman的用户界面

- -

工具栏

- -

Figure 3. The Venkman Toolbar

- -

The Toolbar is located at the top of the debugger. The Toolbar contains icons for Stop, Continue, Step Over, Step Into, Step Out, Profile, and Pretty Print commands. These commands should be self explanatory, with the possible exception of Stop, which causes the debugger to stop - when the next line of JavaScript is executed - , and the Profile button, which can be used to measure execution times for your scripts. When you enable profiling by clicking this button, a green checkmark appears next to the button and profile data for every function is collected, and can be saved by choosing Save Profile Data As... from the Profile menu.

- -
-

Image:venkintro-stop-checked.png
- Figure 4.
- Stop Button
- Waiting for
- Execution

-
- -

Also note that when you are currently executing JavaScript and click the Stop button, the JavaScript stops immediately. If you are not running JavaScript and click the Stop button, it will display "...", as in the Figure 4, to indicate that the debugger will stop at the next instruction, but doesn't have anywhere to stop yet.

- -

This quick stop mode reflects a common scenario in JavaScript debugging, which is to inspect and debug scripts while they are running, as on a page where elements are moved around dynamically with DHTML. You can also use commands available in the Debug menu and from the console to stop at errors or at exceptions.

- -

The Continue button to the right of the Stop button dismisses the Stop mode and specifies that scripts should be executed normally, without pausing as each statement is executed.

- -

The Pretty Print button toggles Pretty Print mode. While in Pretty Print mode, the contents of the source view will contain the decompiled source text for the selected function. This is the same text you would get from the toSource method of the Function prototype. If the source text you are debugging is poorly formatted, Pretty Print can help make it easier to read by inserting line breaks and whitespace in appropriate places.

- -

When Pretty Print is enabled you will see a green check mark on the toolbar button, and the menu item will be checked as well.

- -

“已加载脚本”视图

- -

Figure 5. The Loaded Scripts View. Active files and functions

- -

The - Loaded Scripts View - is in the top left portion of the window. When a file is loaded by the browser it will appear in this view, and when unloaded it will be removed. Files are listed in alphabetical order, grouped by file type. File names are displayed after a color coded, single letter icon representing the file extension. Figure 6 shows the table of icon and file types. At the time if this writing, the order and grouping of file names cannot be changed.

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IconFile type
J.js
H.html, .htm
Z.xul
X.xml
?All other files
.JavaScript function
- -

Figure 6.
- Icons in the Script View

-
- -

The "special" function name __toplevel__ is displayed for scripts that are not part of an actual function. Clicking on a file name brings you to the top of that file, while clicking on a function name brings you to the start of that function.

- -

The Line column in this view displays the line number that this function starts on. The column picker for this view (the Tree column picker box on the top right) can be used to display a Length column. This column displays the size of functions, in lines. Both the Line and Length column are blank for file names.

- -

If a function has a breakpoint in it, a small red dot will show up in the function icon, as well as the parent's file icon.

- -

“局部变量”视图

- -

Figure 7. The Local Variables View

- -

The - Local Variables view - is on the left portion of the window, at the bottom. When the debugger is stopped, the Local Variables view displays values for the current function. The scope object holds all arguments and local variables, and the this object holds the value of the this keyword.

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
eEnumerable property
rRead Only property
pPermanent (cannot be deleted)
AAlias to another property
aArgument to a function
vDeclared with var
- -

Figure 8. Property flags

-
- -

Properties of both scope and this objects are listed alphabetically, grouped by data type. Figure 9 shows which icons represent which data types.

- -

Properties which are of the type Object are displayed with the name of their constructor function in curly braces as their value. You can locate the source code of the constructor by selecting "Find Constructor" from the property's context menu. You can find the place where the object was instantiated with the "Find Creator" command. By default, properties of type function are not displayed, in order to conserve space in the view. If you would like to have functions displayed, check the "Include Functions" menu item in the view's context menu. You may need to close and re-open any objects you had open to see the change.

- -

Properties that show up in a bold grey font are defined on an object from the prototype chain, and not on the actual object you are inspecting. If you would like to inspect the object's prototype and parent chains, check the "Include ECMA Properties" menu item in the view's context menu. If a property shows up in a bold red font, an exception occurred when Venkman tried to read the value. The exception object will appear as the value of the property.

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IconData TypeIconData Type
XVoid (undefined) valuenullNull value
t/fBoolean value`'String value
#Integer value##Double value
*Object valuefFunction value
- -

Figure 9. Type Icons

-
- -

The column picker for this view (the Tree column picker box on the top right) can be used to display Type and Flags columns. The Type column contains a textual description of the type of the object. Flags lists one or more applicable flags for this object. Flags are shown enumerated in Figure 8.

- -

If an item visible in the Local Variables View is modified via the Interactive Session View the modification will be immediately reflected in the Local Variable View.

- -

At the time of this writing, the Local Variables View's default sort order and grouping are not adjustable.

- -

“命名栈”视图

- -

Figure 10. The Call Stack View

- -

The - Call Stack View - is on the left portion of the window by default, at the bottom. When the debugger is stopped, the Call Stack View displays the list of active functions. The function at the top of the Call Stack View is the one in which the debugger stopped, the function below it is the caller, below that is the caller's caller, and so on. These items are referred to as stack frames.

- -

Double-clicking on a stack frame will change the "current" frame. This will cause the source of function to be displayed in the Source Code view, the Local Variables view will change to display variables local to the selected stack frame, and script evaluated in the Interactive Session view will be relative to the selected frame.

- -

If you would like to copy the current call stack to the clipboard, select "Dump Stack to Interactive Session" from the context menu, or type /where in the Interactive Session view. You may then copy the text from the Interactive Session view.

- -

If you would like to keep Venkman from stopping in a particular stack frame in the future, check "Don't Debug" from the stack frame's context menu.

- -

“源代码”视图

- -

Figure 11. The Source Code View. Source code, line numbers, and breakpoints.

- -

The Source Code View is a read-only file viewer. Files and specific functions within them can be displayed by selecting the appropriate file or function name in the Script View.

- -

When script execution is interrupted by the debugger, the line of the file where the interruption occurred is automatically displayed in the Source Code View. The line in question will be highlighted in yellow to make it easy to spot.

- -

Clicking in the left margin of this view will set a breakpoint at that line. If the breakpoint is successfully set, the margin will show the letter "B" on a red background, and both the Loaded Scripts View and Interactive Session View will provide feedback. The breakpoint can be cleared by clicking in the margin again (on the letter "B"). Breakpoints cannot be set on lines which do not contain executable code, such as blank and comment lines. For these lines, the Interactive Session View will display an error message explaining why the breakpoint could not be set.

- -

Breakpoints can also be set and cleared from the Interactive Session View, with the break and fbreak commands. The break command takes a file pattern and line number. Any loaded file which matches the file pattern, and contains an executable line at the requested line number will have a breakpoint set. If no loaded files match the file pattern or line number, an error message is printed to the console and the command fails. The fbreak command is identical, with the exception that if no files match the pattern or line, a "future breakpoint" is recorded. The next time a file is loaded that matches the pattern and line, a breakpoint will be set. In this way, fbreak allows one to set breakpoints in files that are not yet loaded, as well as set breakpoints that are triggered when a file is loaded.

- -

“交互区域”视图

- -

Figure 12. The Interactive Session View. Command line interface to the debugger

- -

Another basic view in Venkman is the actual Interactive Session View, which allows you to interact with the debugger from a command line.

- -

Commands are entered in the text box, and responses are appended to the end of the output. Type /commands in the input area (the text box) to list all of the commands available. The /help command can be used to get additional information about a specific command. You can type /help next, for example, to see how to use the next command.

- -

The input area supports command history and tab-completion for command names. Command history remembers the last 20 commands entered. The up and down arrows can be used to revisit these previous commands. Tab completion allows the user to type the first portion of a command, and press tab twice to see possible completions. If only one command matches, it will be auto-completed on the first tab.

- -

View Customization

- -

Venkman offers nearly complete control over the arrangement and display of views within the application. The debugger is built on top of an application framework that allows you to drag and drop, resize, and toggle all the available views, and even to create new views or modules for the debugger if you choose—though this latter is an advanced topic and a subject for a future article.

- -

To remove a view from Venkman, simply click the Close button at the top right of that view. When the view again becomes necessary—for example, when you open a source file from the Loaded Scripts view and want to view the source—the view reappears where it was last positioned. To make a view reappear explicitly, select it from the View->Show/Hide menu of the debugger. You can also make views float in their own separate windows. To make a view float, click the float button in the upper left of that view.

- -

You can access any of the basic views from the Show/Hide submenu of the View menu. The list displayed there includes all of the basic views in Venkman. As you change which views are displayed and where in the UI they appear, your preferences are stored and persisted across sessions.

- -

加载脚本

- -

Whether or not you start Venkman first or the browser component, when the Mozilla suite starts up, the JavaScript engine begins to keep track of and compile all the scripts that are loaded in web pages and in the various Mozilla user interfaces themselves. The engine tells Venkman about the scripts it knows about, and those scripts are loaded into the "Loaded Scripts" view in the debugger.

- -

If you want to load new scripts in—say from a web page you are trying to troubleshoot—you can do so by simply opening that web page - in the regular browser window - , at which point the compiler gets the JavaScript source and populates the Loaded Scripts window with the new entry.

- -

Using File->Open from Venkman will open a local file in the debugger, and using File->Open Web Location will open and display the entire HTML contents of the requested page. Probably, neither of these is what you really want. Since the JavaScript engine automatically populates the Loaded Scripts list in the debugger with JavaScript it executes as the browser opens web pages, it's usually enough simply to - - browse - the sites whose scripts you are interested in debugging.

- -

基础调试

- -

This section provides a brief example of a debugging session in order to familiarize you with some of the basic commands and operations of the debugger.

- -
    -
  1. -

    Start Venkman

    - -

    Note: At one point, the debugger needed to be started - before - the scripts it was going to debug. This limitation is fixed, and now the JavaScript compiler makes all the scripts you access via the browser available to the debugger. See - - {{ Anch("Loading Scripts into the Debugger") }} - for more information about finding and loading scripts in Venkman.

    -
  2. -
  3. -

    Launch a browser window and go to http://wp.netscape.com/fishcam/dhtmltank.html.

    - -

    Note that in Mozilla 1.x and Netscape 7.x, the debugger contains a Window menu like other major components in the application suite. From this menu, you can access the browser, mail, and other applications.

    -
  4. -
  5. -

    Type /break Animator-0.03 121 in the debugger.

    - -

    The console command /break is used to set and list breakpoints. The first parameter is the file name that contains the JavaScript you want to break at. The second parameter is the line number. You don't need to specify the entire file name. In this example, we are setting a breakpoint in the pause function called when the browser starts the DHTML fishcam window.

    - -

    Alternately, you can select Animator-0.03.js from the Loaded Scripts view, locate the pause function at line 119, and click in the left margin. Setting breakpoints in this manner is equivalent to using the /break command in the console. In either case, a red breakpoint icon appears in the Source Code view.

    -
  6. -
  7. -

    Type /break in the debugger.

    - -

    If you don't provide arguments to the /break command, all breakpoints are listed in the Interactive Session view.

    -
  8. -
  9. -

    On the fishcam page, press the "pause" link.

    - -

    You should hit the breakpoint you just set in Step 3.

    - -

    In the interactive session, context becomes Animator-0.03.js and the scope is the pause function. There will also be "stopped for breakpoint" in red in the interactive session, along with the file name, line number, and snippet source code from where it stopped.

    - -
    -

    450px
    - Figure 13. (from Step 5) Stopped at a breakpoint.

    -
    -
  10. -
  11. -

    In the interactive session's input field, enter this.fPaused

    - -

    Venkman evaluates the expression, giving you {{ mediawiki.external('boolean') }} false back. Press Step Into to follow the steps until you have finished debugging the function, and the fishes have paused.

    - -

    In addition to Step In, which will execute a single line of JavaScript and stop, Step Over can be used to step over a impending function call, and return control to the debugger when the call returns. Step Out executes until the current function call exits.

    -
  12. -
  13. -

    Click the "pause" link again on the fishcam page to resume the demo.

    - -

    This starts the DHTML down the other codepath in start() and makes the fishes start swimming again.

    -
  14. -
- -

As you can see, this is a very modest introduction to the functionality of the JavaScript debugger and the complexity that scripts can have. But the steps described here can give you a basic feel for the debugger if you haven't already had some experience using it, and they provide the basis for the more interesting and practical examples in the articles that follow this one.

- -

The best way to get to know Venkman, of course, is to play around with it — to set it up in the way that makes the most sense to you, to try loading scripts and setting breakpoints, evaluating expressions in the Interactive Session View, watching the values of variables as they change when scripts are executed, getting profile data.

- -

资源

- - - -
-

Original Document Information

- - -
- -
-

--AndyYard 00:50 2007年11月15日 (PST)

diff --git a/files/zh-cn/web/api/cameracontrol/getpreviewstream/index.html b/files/zh-cn/web/api/cameracontrol/getpreviewstream/index.html deleted file mode 100644 index be1756631d..0000000000 --- a/files/zh-cn/web/api/cameracontrol/getpreviewstream/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: CameraControl.getPreviewStream -slug: Web/API/CameraControl/getPreviewStream -translation_of: Archive/B2G_OS/API/CameraControl/getPreviewStream ---- -

{{APIRef("Camera API")}}{{ non-standard_header() }}

- -

概述

- -

该方法用来根据指定的配置,从摄像头获取到一个{{domxref("MediaStream")}}数据流,你可以从该数据流中捕获到静态的照片.

- -
-

注:使用该方法获取到的数据流仅能用来捕获静态的照片.如果你想录制视频,那么必须使用{{domxref("CameraControl.getPreviewStreamVideoMode()")}}方法来代替.

-
- -

语法

- -
CameraControl.getPreviewStream(options, onsuccess[, onerror]);
- -

参数

- -
-
options
-
一个包含有两个属性widthheight的对象.该对象可以通过{{domxref("CameraCapabilities")}}.previewSizes属性获取到.
-
onsuccess
-
一个回调函数,会被传入一个参数,这个参数是一个{{domxref("MediaStream")}}数据流对象,可以使用该数据流对象捕获静态的图像.
-
onerror {{optional_inline()}}
-
一个回调函数,会被传入一个参数,这个参数是一个表示错误原因的字符串.如果在尝试获取MediaStream数据流对象时发生了错误,则会调用该函数.
-
- -

示例

- -

这个例子演示了如何通过使用{{domxref("MediaStream")}}数据流对象来从摄像头捕获并播放静态的图片.

- -
var display = document.getElementsByTagName('video')[0];
-var options = {
-  camera: navigator.mozCameras.getListOfCameras()[0]
-};
-
-function onStreamReady( stream ) {
-  display.mozSrcObject = stream;
-  display.play();
-}
-
-function onAccessCamera( camera ) {
-  var size = camera.capabilities.previewSizes[0];
-
-  camera.getPreviewStream(size, onStreamReady);
-};
-
-navigator.mozCameras.getCamera(options, onAccessCamera)
-
- -

规范

- -

不属于任何规范.当WebRTC Capture and Stream API实现时,该方法应该会被删除.

- -

相关链接

- - diff --git a/files/zh-cn/web/api/cameracontrol/index.html b/files/zh-cn/web/api/cameracontrol/index.html deleted file mode 100644 index 3be97dac90..0000000000 --- a/files/zh-cn/web/api/cameracontrol/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: CameraControl -slug: Web/API/CameraControl -translation_of: Archive/B2G_OS/API/CameraControl ---- -

{{APIRef("Camera API")}}

- -

{{ non-standard_header() }}

- -

When you use the {{domxref("CameraManager.getCamera()")}} method to get a reference to a camera, you specify a callback function to be invoked on success. That function receives as a parameter a CameraControl object. You can use its methods and properties to manage and make use of the camera.

- -

Properties

- -
-
{{domxref("CameraControl.capabilities")}} {{readonlyinline}}
-
A {{domxref("CameraCapabilities")}} object indicating all the capabilities for the given camera.
-
{{domxref("CameraControl.effect")}}
-
A string defining the effect to be used by the camera (none by default). Its value must be one of the values available in {{domxref("CameraCapabilities.effects")}}.
-
{{domxref("CameraControl.exposureCompensation")}} {{readonlyinline}}
-
A value used to compensate the camera exposure. This attribute is read-only; to change the exposure, you need to call the {{domxref("CameraControl.setExposureCompensation()")}} method.
-
{{domxref("CameraControl.flashMode")}}
-
A string that defines how the flash, if any, is to be used; this is auto by default if the device has a flash, none otherwise. When set, its value must be chosen from the list of options specified by  {{domxref("CameraCapabilities.flashModes")}}.
-
{{domxref("CameraControl.focalLength")}} {{readonlyinline}}
-
A number that express the camera's focal length in millimeters.
-
{{domxref("CameraControl.focusAreas")}}
-
An Array of one or more objects that define where the camera will perform auto-focusing.
-
{{domxref("CameraControl.focusDistanceFar")}} {{readonlyinline}}
-
This value is a distance in meter used with {{domxref("CameraControl.focusDistanceNear")}} to defined the image's depth of field. The value for this property may be Infinity.
-
{{domxref("CameraControl.focusDistanceNear")}} {{readonlyinline}}
-
This value is a distance in meter used with {{domxref("CameraControl.focusDistanceFar")}} to defined the image's depth of field.
-
{{domxref("CameraControl.focusDistanceOptimum")}} {{readonlyinline}}
-
This value is a distance in meter where the subject will appear sharpest.
-
{{domxref("CameraControl.focusMode")}}
-
A string that defines which kind of focus mode the camera should use (auto or fixed by default). Its value must be chosen from {{domxref("CameraCapabilities.focusModes")}}.
-
{{domxref("CameraControl.meteringAreas")}}
-
An Array of one or more objects that define where the camera will perform auto-focusing.
-
{{domxref("CameraControl.onShutter")}}
-
A handler for the camera's "shutter" event, to trigger a shutter sound and/or a visual shutter indicator.
-
{{domxref("CameraControl.onClosed")}}
-
A handler called when a new CameraControl object in the same app takes over the camera.
-
{{domxref("CameraControl.onRecorderStateChange")}}
-
A function to call when the recorder changes state, either because the recording process encountered an error, or because one of the recording limits (see {{domxref("CameraControl.startRecording()")}}) was reached.
-
{{domxref("CameraControl.sceneMode")}}
-
A string that defines which scene mode the camera is to use (auto by default). Its value must be chosen from {{domxref("CameraCapabilities.sceneModes")}}.
-
{{domxref("CameraControl.whiteBalanceMode")}}
-
A string that defines which white balance mode the camera is to use (auto by default). Its value must be chosen from {{domxref("CameraCapabilities.whiteBalanceModes")}}.
-
{{domxref("CameraControl.zoom")}}
-
A number that defines which kind of zoom factor mode the camera is to use (1 by default). Its value must be chosen from {{domxref("CameraCapabilities.zoomRatios")}}.
-
- -

Methods

- -
-
{{ domxref("CameraControl.autoFocus()") }}
-
Tells the camera to attempt to focus the image.
-
{{ domxref("CameraControl.getPreviewStream()") }}
-
Gets a video stream from the camera; you can use this in an arbitrary context.
-
{{ domxref("CameraControl.getPreviewStreamVideoMode()") }}
-
Gets a video stream from the camera based on a specific video mode.
-
{{ domxref("CameraControl.release()") }}
-
Releases the camera so that other applications can use it.
-
{{ domxref("CameraControl.resumePreview()") }}
-
Resumes the preview video stream after it's been paused by a call to {{domxref("CameraControl.takePicture()")}}.
-
{{ domxref("CameraControl.setExposureCompensation()") }}
-
Lets you specify the exposure compensation factor.
-
{{ domxref("CameraControl.startRecording()") }}
-
Lets you start recording a video stream.
-
{{ domxref("CameraControl.stopRecording()") }}
-
Lets you stop recording a video stream.
-
{{ domxref("CameraControl.takePicture()") }}
-
Lets you capture a single image, receiving it as a {{domxref("Blob")}}.
-
- -

Specification

- -

{{page("/en-US/docs/Web/API/Navigator.MozCameras","Specification")}}

- -

Permissions

- -

{{page("/en-US/docs/Web/API/Navigator.MozCameras","Permissions")}}

- -

See also

- - diff --git a/files/zh-cn/web/api/identitymanager/index.html b/files/zh-cn/web/api/identitymanager/index.html deleted file mode 100644 index 35dab1a6c2..0000000000 --- a/files/zh-cn/web/api/identitymanager/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: IdentityManager -slug: Web/API/IdentityManager -translation_of: Archive/IdentityManager ---- -

{{APIRef("Persona")}}{{non-standard_header}}

- -

The IdentityManager of the  BrowserID protocol exposes the BrowserID API, via {{domxref("navigator.id")}}. This API has gone through several significant revisions. Each generation is listed separately below.

- -

The "Observer" API (Current)

- -

The Observer API introduces much-requested features, such as an improved post-verification experience for first-time users, automatic persistent logins, and easier integration with native applications.

- -
-
{{ domxref("IdentityManager.watch()")}}
-
Registers callbacks to be invoked when a user logs into or out of a website.
-
{{ domxref("IdentityManager.request()")}}
-
Requests a signed identity assertion from the user.
-
{{ domxref("IdentityManager.logout()")}}
-
Logs the user out of a website and prevents the onlogin action from automatically firing on their next visit.
-
- -
-

Users with third-party cookies disabled may experience problems logging in using the Observer API as detailed in issue 2999.

-
- -

The "Callback" API (Current)

- -

The Callback API was introduced in November 2011. It improved upon the initial API by allowing options to be passed to navigator.id.get() and offering experimental support for BrowserID-managed persistent sessions.

- -
-
{{ domxref("IdentityManager.get()")}}
-
Gets the user's BrowserID in a signed assertion.
-
- -

The "VerifiedEmail" API (Deprecated)

- -

The VerifiedEmail API was BrowserID's first API. It was deprecated at the end of 2011.

- -
-
{{ domxref("IdentityManager.getVerifiedEmail()")}} {{ deprecated_inline() }}
-
Gets the user's BrowserID in a signed assertion. This method is deprecated; {{ domxref("navigator.id.get()")}} is backwards compatible and can be used instead.
-
diff --git a/files/zh-cn/web/api/identitymanager/watch/index.html b/files/zh-cn/web/api/identitymanager/watch/index.html deleted file mode 100644 index 1660ccdacf..0000000000 --- a/files/zh-cn/web/api/identitymanager/watch/index.html +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: IdentityManager.watch() -slug: Web/API/IdentityManager/watch -translation_of: Archive/IdentityManager/watch ---- -

{{ ApiRef("Persona") }}

- -
注意: 不是所有的浏览器都支持这项功能. 使用 Persona 的网站必须在他们的页面中包含 polyfill library .
- -

概要

- -

This function registers callbacks that respond to a Persona user logging in or out.

- -

语法

- -
navigator.id.watch({
-  loggedInUser: 'bob@example.org',
-  onlogin: function(assertion) {
-    // A user has logged in! Here you need to:
-    // 1. Send the assertion to your backend for verification and to create a session.
-    // 2. Update your UI.
-  },
-  onlogout: function() {
-    // A user has logged out! Here you need to:
-    // Tear down the user's session by redirecting the user or making a call to your backend.
-  }
-});
-
- -

参数

- -
-
loggedInUser {{ optional_inline() }}
-
NOTE: This parameter was renamed from loggedInEmail in early September. Both names will continue to work for the time being, but code should be changed to use loggedInUser instead.
-
The email address of the currently logged in user. This should be a string containing the user's email address if the website believes that a user is currently logged in, or null otherwise. If the website is unsure, this should be set to undefined or omitted.
-
Persona compares its knowledge of the local user to the value of loggedInUser to determine which callback—onlogin, onlogout, or none at all—to automatically invoke when your page loads. If loggedInUser is undefined or omitted, Persona will invoke either onlogin or onlogout, depending on whether or not a local user should be logged in to your site. These callbacks are not invoked automatically if both BrowserID and loggedInUser agree on the local user's state.
-
Note that Persona may automatically call either onlogin or onlogout when your page loads, but not both. If loggedInUser is set to foo@example.com, but Persona believes bar@example.com should be logged in, only onlogin will be called. It will have an assertion for bar@example.com as its first parameter.
-
onlogin
-
A function which will be invoked and passed a single argument, an assertion, when the user logs in. This function should send the assertion to the site's backend for verification. If verification succeeds, the backend should establish a session for the user and the function should update the UI as appropriate.
-
onlogout
-
A function that will be invoked, without any arguments, when the user logs out. This should tear down the user's session by making a call to the site's backend, or by redirecting the user.
-
- -

示例

- -

需要示例.

- -

技术规范

- -

没有包含在任何技术规范中.

- -

查看其它内容

- - diff --git a/files/zh-cn/web/api/indexeddb_api/using_indexeddb_in_chrome/index.html b/files/zh-cn/web/api/indexeddb_api/using_indexeddb_in_chrome/index.html deleted file mode 100644 index d9d9aa2cbf..0000000000 --- a/files/zh-cn/web/api/indexeddb_api/using_indexeddb_in_chrome/index.html +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Using IndexedDB in chrome -slug: Web/API/IndexedDB_API/Using_IndexedDB_in_chrome -translation_of: Mozilla/Tech/XPCOM/Using_IndexedDB_in_chrome ---- -

indexedDB API 通常被用来在用户的浏览器端存储来自JavaScript的数据。(点击 Using IndexedDB 复习)。然而,使用system-privileged JavaScript的 Components.utils.importGlobalProperties() 函数也能获取这些API:

- -
Components.utils.importGlobalProperties(["indexedDB"]);
-
-// From here on, it's like using IndexedDB from content
-var req = indexedDB.open("my-database");
-// ...
- -

如果你要创建一个 sandbox ,并且打算在sandbox中使用indexedDB,那么在 Sandbox 的构造函数中使用 wantGlobalProperties配置项:

- -
var options = {
-  "wantGlobalProperties": ["indexedDB"]
-}
-var principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
-var sandbox = Components.utils.Sandbox(principal, options);
-
-// The sandbox will have access to indexedDB
-var sandboxScript = 'var req = indexedDB.open("my-database");';
-Components.utils.evalInSandbox(sandboxScript, sandbox);
-
- -

在Firefox 33之前,你可能要使用nsIIndexedDatabaseManager的initWindowless方法,从chrome的代码中方法获取indexedDB。这种方法在Firefox 33时,已经被移除。

diff --git a/files/zh-cn/web/api/navigator/id/index.html b/files/zh-cn/web/api/navigator/id/index.html deleted file mode 100644 index c2d8597274..0000000000 --- a/files/zh-cn/web/api/navigator/id/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Navigator.id -slug: Web/API/Navigator/id -translation_of: Archive/Navigator-id ---- -
{{ ApiRef("Persona") }}
- -

{{ non-standard_header() }}

- -
注意: 这个功能的支持还没有构建到任何浏览器中,使用 Persona 的网站必须包含托管在 https://login.persona.org/include.js 上的填充库。
- -

概述

- -

BrowserID 协议定义了 {{ domxref ("window.navigator")}} 对象上的一个新的 id 属性,通过这个属性暴露 BrowserID API。这个 API 已经经历了几个重要修订。下面独立列出了每代 API。

- -

观察者 API(当前)

- -

观察者 API 引入了非常请求化的特性,诸如一个为新手用户改进的提交-验证体验、自动持久化登入和更简单的本地应用集成。

- -
-
{{ domxref("navigator.id.watch()")}}
-
登记在用户登入或登出网站时调用的回调。
-
{{ domxref("navigator.id.request()")}}
-
从用户请求一个签名的身份断言。
-
{{ domxref("navigator.id.logout()")}}
-
把用户登出网站并阻止 onlogin 行为在他们下次访问时触发。
-
- -

回调 API(当前)

- -

回调 API 在 2011 年 11 月被引入。它通过允许传递给 navigator.id.get()和提供 BrowserID 管理的持久会话的实验性支持改进了初始的 API。

- -
-
{{ domxref("navigator.id.get()")}}
-
Gets the user's BrowserID in a signed assertion.
-
- -

VerifiedEmail API(弃用)

- -

VerifiedEmail API 是 BrowserID 的第一个 API。它在 2011 年末被弃用。

- -
-
{{ domxref("navigator.id.getVerifiedEmail()")}} {{ deprecated_inline() }}
-
在一个签名的断言里获取用户的 BrowserID。这个方法已经弃用了;{{ domxref("navigator.id.get()")}} 是向后兼容的替代方法。
-
diff --git a/files/zh-cn/web/api/navigator/mozsettings/index.html b/files/zh-cn/web/api/navigator/mozsettings/index.html deleted file mode 100644 index bd96466118..0000000000 --- a/files/zh-cn/web/api/navigator/mozsettings/index.html +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Navigator.mozSettings -slug: Web/API/Navigator/mozSettings -translation_of: Archive/B2G_OS/API/Navigator/mozSettings ---- -

{{APIRef("Firefox OS")}}{{ non-standard_header() }}

- -

{{ B2GOnlyHeader2('certified') }}

- -

概述

- -

返回一个{{ domxref("SettingsManager") }}对象,你可以使用返回的对象来修改设备的各项设置.

- -

语法

- -
var settings = window.navigator.mozSettings;
-
- -

- -

navigator.mozSettings是一个{{domxref("SettingsManager")}}对象,你可以使用该对象来修改设备的各项设置.

- -

规范

- -

目前还不属于任何的规范,不过这个API将作为System Applications Working Group规范的一部分在W3C上讨论.

- -

相关链接

- - diff --git a/files/zh-cn/web/api/navigator/mozsms/index.html b/files/zh-cn/web/api/navigator/mozsms/index.html deleted file mode 100644 index c6c9aff864..0000000000 --- a/files/zh-cn/web/api/navigator/mozsms/index.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: Navigator.mozSms -slug: Web/API/Navigator/mozSms -translation_of: Archive/B2G_OS/API/Navigator/mozSms ---- -

{{APIRef("Firefox OS")}}

- -

{{ non-standard_header() }}

- -

{{ obsolete_header(25) }}

- -

{{ B2GOnlyHeader2('certified') }}

- -

返回 {{ domxref("SmsManager") }} 对象,你可以通过该对象进行短消息的收发操作。

- -
-

注意: 废弃! 该对象已被废弃,请参考使用: {{ domxref("window.navigator.mozMobileMessage") }}。

-
- -

语法

- -
var sms = window.navigator.mozSms;
-
- -

参数说明

- -

这是一个非标准接口,不过该接口有在 W3C 部分提及: System Application Working Group.

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Messaging')}}{{Spec2('Messaging')}}Editor Draft (WIP).
- -

浏览器兼容

- -

For obvious reasons, support is primarily expected on mobile browsers.

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatGeckoMobile("12.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -

Preferences & availability

- - - -

参阅

- - diff --git a/files/zh-cn/web/api/using_the_browser_api/index.html b/files/zh-cn/web/api/using_the_browser_api/index.html deleted file mode 100644 index a829b11d58..0000000000 --- a/files/zh-cn/web/api/using_the_browser_api/index.html +++ /dev/null @@ -1,214 +0,0 @@ ---- -title: Using the browser API -slug: Web/API/Using_the_Browser_API -tags: - - API - - B2G - - Firefox OS - - WebAPI - - 指南 - - 浏览器 - - 非标准 -translation_of: Mozilla/Gecko/Chrome/API/Browser_API/Using ---- -

{{ non-standard_header() }}

- -

{{ B2GOnlyHeader2('privileged') }}

- -

概述

- -

HTML Browser API 是对 HTML {{HTMLElement("iframe")}} 元素的扩展,允许 web app 用来实现浏览器或浏览器类似的应用。主要涉及到两个方面:

- - - -

除此之外,也可以表示成嵌入的内容就是一个 Open Web App。在那种情况下,页面内容就会在适当的 app 上下文(如权限)中被装载。

- -

用法

- -

{{HTMLElement("iframe")}} 可以通过设置 {{htmlattrxref("mozbrowser","iframe")}} 属性而转化为浏览器框架

- -
<iframe src="http://hostname.tld" mozbrowser>
- -

要想嵌入一个 Open Web App,  必须要提供 {{htmlattrxref("mozapp","iframe")}} 以及 app manifest 路径。

- -
<iframe src="http://hostname.tld" mozapp='http://path/to/manifest.webapp' mozbrowser>
- -

最后, {{HTMLElement("iframe")}} 的内容可以在它单独的子进程中装载,通过使用{{htmlattrxref("remote","iframe")}}  属性可以单独嵌入到此页面的框架中。

- -
<iframe src="http://hostname.tld" mozbrowser remote>
- -
-

警告: That last attribute is necessary for security reasons if you plan to load content from an untrusted/unknown origin. If you don't use it, you take the risk of your application being compromised by a malicious web site.

-
- -

权限

- -

想要嵌入到 browser frame 中的任何应用必须要在其中的 app manifest 拥有 browser 权限。

- -
{
-  "permissions": {
-    "browser": {}
-  }
-}
- -

此外,要嵌入一个  Open Web App, app 必须具有 embed-apps 权限。

- -
{
-  "permissions": {
-    "browser": {},
-    "embed-apps": {}
-  }
-}
- -

额外方法

- -

Firefox OS 扩展了 {{domxref("HTMLIFrameElement")}} DOM 接口以支持 browser {{HTMLElement("iframe")}} 所产生的需求。这些新的方法赋予  {{HTMLElement("iframe")}} 了一些强大的功能:

- - - -

这些方法能够使 {{HTMLElement("iframe")}} 根据历史记录进行导航。此处也有必要来实现 back, forward, stop, and reload 按钮。

- - - -

性能方法

- -

Those methods are used to manage the resources used by a browser {{HTMLElement("iframe")}}. This is especially useful for implementing tabbed browser application.

- - - -

Event 方法

- -

In order to manage the browser {{HTMLElement("iframe")}}'s content, many new events were added (see below). The following methods are used to deal with those events:

- - - -

其他方法

- -

Those methods are utilities, useful for apps that host a browser {{HTMLElement("iframe")}}.

- - - -

Events

- -

In order to allow an application to manage the browser {{HTMLElement("iframe")}}, the application can listen for new events about what's happening within the browser {{HTMLElement("iframe")}}. The following new events can be listened for:

- - - -

示例

- -

In this example we'll see how to implement a very basic browser app.

- -

HTML

- -

In the HTML we just add a URL bar, a "Go" and "Stop" button, and a browser {{HTMLElement("iframe")}}.

- -
<header>
-  <input id="url">
-  <button id="go">Go</button>
-  <button id="stop">Stop</button>
-</header>
-
-<iframe src="about:blank" mozbrowser remote></iframe>
-
- -

CSS

- -

We switch between the go and stop button with a little css trick.

- -
button:disabled {
-  display: none;
-}
- -

JavaScript

- -

Now we can add the required functionalities:

- -
document.addEventListener("DOMContentLoaded", function () {
-  var url  = document.getElementById("url");
-  var go   = document.getElementById("go");
-  var stop = document.getElementById("stop");
-
-  var browser = document.getElementsByTagName("iframe")[0];
-
-  // This function is used to switch the Go and Stop button
-  // If the browser is loading content, "Go" is disabled and "Stop" is enabled
-  // Otherwise, "Go" is enabled and "Stop" is disabled
-  function uiLoading(isLoading) {
-      go.disabled =  isLoading;
-    stop.disabled = !isLoading;
-  }
-
-  go.addEventListener("touchend", function () {
-    browser.setAttribute("src", url.value);
-  });
-
-  stop.addEventListener("touchend", function () {
-    browser.stop();
-  });
-
-  // When the browser starts loading content, we switch the "Go" and "Stop" buttons
-  browser.addEventListener('mozbrowserloadstart', function () {
-    uiLoading(true);
-  });
-
-  // When the browser finishes loading content, we switch back the "Go" and "Stop" buttons
-  browser.addEventListener('mozbrowserloadend', function () {
-    uiLoading(false);
-  });
-
-  // In case of error, we also switch back the "Go" and "Stop" buttons
-  browser.addEventListener('mozbrowsererror', function (event) {
-    uiLoading(false);
-    alert("Loading error: " + event.detail);
-  });
-
-  // When a user follows a link, we make sure the new location is displayed in the address bar
-  browser.addEventListener('mozbrowserlocationchange', function (event) {
-    url.value = event.detail;
-  });
-});
- -

参考

- - diff --git a/files/zh-cn/web/api/webvr_api/webvr_environment_setup/index.html b/files/zh-cn/web/api/webvr_api/webvr_environment_setup/index.html deleted file mode 100644 index d3ede8add1..0000000000 --- a/files/zh-cn/web/api/webvr_api/webvr_environment_setup/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: WebVR环境配置 -slug: Web/API/WebVR_API/WebVR_environment_setup -translation_of: Archive/WebVR/WebVR_environment_setup ---- -

{{draft("WebVR API文档目前正在更新中以涵盖1.0版本规范, 因此这些信息中的一部分将会过时。如果你对此有任何疑问请联系 ~~chrisdavidmills。")}}

- -

在这篇文章中, 我们将带你了解配置你的WebVR测试环境所需要做的工作 — 包括硬件和软件配置以及一些常见的错误的解决方法.

- -

硬件

- -

首先来看WebVR的硬件需求。

- -

头戴式显示器与位置追踪器

- -

目前有几款产品可作为VR头戴式显示器,其中最好的是Oculus Rift,它具有坚固的头戴式显示器和安装在三脚架或监视器上的位置追踪相机。Oculus Rift DK2 目前的零售价是350美元(约2410人民币),但是随着技术的进步和越来越多的头戴设备的出现,预计Oculus Rigt的价格会下降。

- -

- -

对于那些没有能力购买整套VR设备的人,也有其他便宜的产品可以选择。一个VR头戴式显示器其实就是一个高分辨率的屏幕,这个屏幕前面有一组眼镜。显示屏显示的是两个并排的有些偏移和渐晕的屏幕影像的副本,人的两眼各看其中一个,这样就给用户带来立体感,这些对于创建VR景象都是至关重要的。

- -

- -

你可以使用支持的浏览器去感受几近相同的体验,比如使用 Android Nightly版的火狐浏览器—— 如同谷歌的Google Cardboard的想法那样,你可以用任何能固定在头部的装置将手机固定在双眼前面,然后通过手机运行VR软件。这里主要的缺点就是没有位置追踪器,手机处理器没有桌面PC的处理器强大,所以体验上相对就没有那么真实(你转动头部的时候你可能得不到和PC上相同的体验,它有可能比较卡),但是,作为一个便宜的入门的设备,它还是不错的。

- -

一台计算机:用于渲染VR场景

- -

VR硬件需要提供高精度,低延迟的数据,来提供令人满意的用户体验 — 显示刷新需要达到60fps,否则,用户会觉得卡顿、抖动。为了保证达到这点,单位时间有大量的数据需要处理。因此,运行VR应用的计算机的配置要求比较高。最理想的是,你有台带独显的高配的笔记本或台式电脑,如新版MacBook Pro 15“/ 17”或Mac Pro,或Windows游戏本。如果你的电脑运行比较慢,你的体验会比较糟糕。

- -

软件

- -

要运行WebVR软件,你需要如下描述的软件设置。

- -

Oculus Rift SDK

- -

如果你使用Oculus Rift,你需要在你的系统上下载并安装 Oculus Rift SDK 。它包含了VR软件所需的运行环境和OculusWorldDemo示例软件,它对排除故障很有用。

- -

Firefox Nightly与WebVR Enabler Add-on (或其他可替代的)

- -

要设置浏览器,请按照下列步骤操作:

- -
    -
  1. Firefox NightlyDeveloper Edition 都支持WebVR。如果你还没装选择其中之一安装,注意安装最新的版本。
  2. -
  3. 然后,安装 WebVR Enabler Add-on — 这将启用WebVR并禁用多处理浏览(E10S),这是一种新的Firefox浏览功能,目前与WebVR不兼容。
  4. -
  5. 最后,重启浏览器。
  6. -
- -
-

Note: 手动开启对WebVR的支持,你可以进入 about:config 然后打开dom.vr*选项。 WebVR Enabler Add-on更加的fang方便,它一次可以完成您所需要的一切。

-
- -
-

Note: 对于移动端用户,Android版Firefox在Nightly builds中也支持WebVR,但是现在还没优化,欢迎反馈意见。

-
- -
-

Note: 还有可用的WebVR支持的实验性Chrome产品。 要了解更多,请查看Brandon Jones的 Bringing VR to Chrome

-
- -

显示配置

- -

为了获得最佳性能,以下步骤的显示器配置非常重要。 不这样做会导致过度抖动和延迟。 我们正在努力改进这些方面,使WebVR真正的即插即用,但是现在最好的结果需要手动配置。

- -

Windows

- -

在控制面板中,先进入Display > Screen Resolution(显示 > 屏幕分辨率). 设置:

- - - -

- -

然后,进入 Advanced Settings > Monitor > Monitor Settings(高级显示设置 > 监视器 > 监视器设置), 设置屏幕刷新频率为 60Hz.

- -

- -

Mac

- -

首先,进入System Preferences > Displays > Display. 设置:

- - - -

- -

然后,进入 System Preferences > Displays > Arrangement 设置ArrangementMirrored.

- -

- -

故障排除

- -

在这个部分,我们提供一些故障排除方法。

- -
-
我的头戴式显示器或者位置追踪器相机不工作
-
尝试使用Oculus Rift SDK附带的OculusWorldDemo测试系统,如果您使用的是其他的VR硬件设备,则使用配套的测试系统。 如果您的硬件设备完全不工作,请确保已完全按照随附手册中的说明进行设置。 常见的错误包括将镜头盖留在追踪相机上和忘记插入USB电缆。
-
我的头戴式显示器或者位置追踪器相机还是不工作
-
一个常见的问题是追踪摄像机停止工作,所以你仍然可以看到图像,但它不会跟着你的头一起旋转。 提示:如果摄像机工作,相机的蓝色指示灯将亮起。 如果WebVR应用程序仍然不工作,并且OculusWorldDemo正常运行,请尝试重新启动浏览器 —— Nightly仍然处于实验性阶段,有时会出现异常。
-
即使我正确的配置了 {{anch("Display configuration")}},我看到显示的图像卡顿抖动
-
有可能是您的显卡太慢,您没有独显,或者当Oculus Rift打开时,您的计算机没有切换到显卡。 但我们不能确定适用于所有的电脑。无论哪种情况,你可以通过测试看看发生了什么,比如在Mac上使用gfxCardStatus软件来测试。 它会让你看到在什么时候集成或独显会切换,或强制使用某一个。 如果它返回消息“您正在使用gfxCardStatus不支持的系统,请确保您使用的是具有双GPU的MacBook Pro。 那么你可能没有GPU,你需要一个更快的处理器或选择容忍。 对于Windows,目前没有类似的应用程序,您必须手动进行更改。
-
我的VR设备旁的第二个监视器表现很奇怪。
-
如果你有第二个监视器(或者笔记本的外接显示器),当你使用 VR设备的时候最好将它断开,否则,有时候它会造成奇怪的问题。
-
Linux系统可以使用吗?
-
WebVR在Linux系统上目前不能使用。未完待续
-
diff --git a/files/zh-cn/web/css/-moz-binding/index.html b/files/zh-cn/web/css/-moz-binding/index.html deleted file mode 100644 index 5a26aec3c2..0000000000 --- a/files/zh-cn/web/css/-moz-binding/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: '-moz-binding' -slug: Web/CSS/-moz-binding -tags: - - CSS - - CSS参考 - - NeedsBrowserCompatibility - - NeedsUpdate - - XBL - - 不规范的 -translation_of: Archive/Web/CSS/-moz-binding ---- -
{{Non-standard_header}}{{CSSRef}}
- -

-moz-binding 属性被基于 Mozilla 的应用程序用于附加 XBL 绑定到 DOM 元素。

- -

{{cssinfo}}

- -

语法

- -
/* <uri> value */
--moz-binding: url(http://www.example.org/xbl/htmlBindings.xml#checkbox);
-
-/* Global values */
--moz-binding: inherited;
--moz-binding: initial;
--moz-binding: unset;
-
- -

取值

- -
-
<uri>
-
The URI for the XBL binding (including the fragment identifier).
-
none
-
No XBL binding is applied to the element.
-
- -

正式语法

- -
{{csssyntax}}
- -

示例

- -
.exampleone {
-  -moz-binding: url(http://www.example.org/xbl/htmlBindings.xml#radiobutton);
-}
- -

规范

- -

Not part of any specification.

- -

浏览器兼容性

- -
-

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

1. XBL is deprecated and being removed (See {{bug(1397874)}}).

- -

参见

- - -
diff --git a/files/zh-cn/web/css/-moz-border-bottom-colors/index.html b/files/zh-cn/web/css/-moz-border-bottom-colors/index.html deleted file mode 100644 index b5f5ca73d6..0000000000 --- a/files/zh-cn/web/css/-moz-border-bottom-colors/index.html +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: '-moz-border-bottom-colors' -slug: Web/CSS/-moz-border-bottom-colors -translation_of: Archive/Web/CSS/-moz-border-bottom-colors ---- -
{{Non-standard_header}}{{CSSRef}}
- -

在Mozilla Firefox中, the -moz-border-bottom-colors CSS 属性的作用是给元素添加下边框的颜色。

- -

When an element has a border that is larger than a single CSS pixel, each line of pixels uses the next color specified in this property, from the outside in. This eliminates the need for nested boxes. If the border is wider than the number of specified colors, the remaining part of the border is the innermost color specified.

- -

{{cssinfo}}

- -

It does not apply

- -
    -
  1. if {{Cssxref("border-style")}} is dashed or dotted.
  2. -
  3. to tables with border-collapse: collapse.
  4. -
- -

Syntax

- -
/* Single <color> value */
--moz-border-bottom-colors: #f0f0f0;
-
-/* Multiple <color> values */
--moz-border-bottom-colors: #f0f0f0 #a0a0a0 #505050 #000000;
-
-/* Global values */
--moz-border-bottom-colors: inherit;
--moz-border-bottom-colors: initial;
--moz-border-bottom-colors: unset;
-
- -

Values(属性值)

- -

Accepts a white-space separated list of color values.

- -
-
<颜色>
-
Specifies the color of a line of pixels of the bottom border. transparent is valid. See {{cssxref("<color>")}} values for possible units.
-
none
-
Default, no colors are drawn or {{cssxref("border-color")}} is used, if specified.
-
- -

Formal syntax

- -
{{csssyntax}}
- -

Example

- -
<div id="example">Example</div>
-
- -
#example {
-  padding: 20px;
-  background-color: gray;
-  border: 10px solid black;
-  -moz-border-top-colors: #e00 #c30 #c50 #c60 #c70 #c80 #c90 #ca0 #cb0 #cc0;
-  -moz-border-right-colors: red #f60 #f80 #f90 #fa0 #fb0 #fc0 #fd0 #fe0 #ff0;
-  -moz-border-bottom-colors: red #f60 #f80 #f90 #fa0 #fb0 #fc0 #fd0 #fe0 #ff0;
-  -moz-border-left-colors: #e00 #c30 #c50 #c60 #c70 #c80 #c90 #ca0 #cb0 #cc0;
-}
-
- -

{{EmbedLiveSample("Example", 120, 90)}}

- -

Specifications

- -

This property is not part of any specification.

- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatGeckoDesktop("1.7")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

See also

- - diff --git a/files/zh-cn/web/css/-ms-overflow-style/index.html b/files/zh-cn/web/css/-ms-overflow-style/index.html deleted file mode 100644 index 895b1cf043..0000000000 --- a/files/zh-cn/web/css/-ms-overflow-style/index.html +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: '-ms-overflow-style' -slug: Web/CSS/-ms-overflow-style -tags: - - CSS - - CSS属性 - - 参考 -translation_of: Archive/Web/CSS/-ms-overflow-style ---- -
{{CSSRef}}
- -
{{non-standard_header}}
- -
- -

-ms-overflow-style 的CSS 属性是一个 Microsoft extension 用于控制元素内容溢出时滚动条的行为。

- -

{{cssinfo}}

- -

语法

- -

Values

- -
-
auto
-
  初始值等同于inherit.
-
-
none
-
永远不会显示滚动条,但是如果元素的内容溢出,仍然可以滚动元素。
-
scrollbar
-
如果元素的内容溢出,则显示“传统”滚动条。“传统的”滚动条不会自动隐藏,也不会覆盖元素的内容。因此,内容的布局区域的大小将通过滚动条的宽度(垂直滚动条)或高度(水平滚动条)来减少。
-
-ms-autohiding-scrollbar
-
如果元素的内容溢出,则使用自动隐藏滚动条。自动隐藏滚动条在滚动期间或指针与页面交互后不久显示,在滚动和指针交互停止后不久隐藏。当它们可见时,自动隐藏的滚动条会覆盖元素的内容。
-
- -

语法形式

- -
  {{csssyntax}}
-
- -

说明书

- -

不是任何规范的一部分

- -

另请参阅

- - diff --git a/files/zh-cn/web/css/_doublecolon_-ms-check/index.html b/files/zh-cn/web/css/_doublecolon_-ms-check/index.html deleted file mode 100644 index 6ebbdb1ea4..0000000000 --- a/files/zh-cn/web/css/_doublecolon_-ms-check/index.html +++ /dev/null @@ -1,169 +0,0 @@ ---- -title: '::-ms-check' -slug: 'Web/CSS/::-ms-check' -translation_of: 'Archive/Web/CSS/::-ms-check' ---- -
{{CSSRef}}
- -
{{non-standard_header}}
- -
 
- -

::-ms-check这个css伪类是微软扩展的用以表达 checkboxes 和 radio 的勾选状态,其中 checkboxes 和 radio分别通过 <input type="checkbox"> 和 <input type="radio">创建

- -

只有IE浏览器和微软Edge浏览器支持该伪类。

- -

属性支持性

- -

只有以下css属性可以在选择器里使用 ::-ms-check 伪类. 其他属性会被自动忽略

- - - -

语法

- -
  {{csssyntax}}
-
- -

例子

- -

HTML

- -
<form>
-  <label for="redButton">Red</label>
-  <input type="radio" id="redButton"><br>
-  <label for="greenCheckbox">Green</label>
-  <input type="checkbox" id="greenCheckbox">
-</form>
- -

CSS

- -
input, label {
-  display: inline;
-}
-
-input[type=radio]::-ms-check {
-  border-color: red; /* This will make the border red when the button is checked. */
-  color: red; /* This will make the circle red when the button is checked. */
-}
-
-input[type=checkbox]::-ms-check {
-  border-color: green; /* This will make the box green when the button is checked. */
-  color: green; /* This will make the checkmark green when the button is checked. */
-}
-
- -

结果

- -

可以尝试下面的例子, 左边的截屏显示当用户不在ie浏览器或Edge浏览器上运行时勾选上按钮时的情况

- -

{{ EmbedLiveSample('Examples', '', '', 'https://mdn.mozillademos.org/files/15814/ie11-example.PNG', 'Web/CSS/::-ms-check') }}

- -

详述

- -

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}10.0{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileiOS WebKit
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatUnknown}}{{CompatNo}}{{CompatNo}}
-
diff --git a/files/zh-cn/web/css/_doublecolon_-ms-clear/index.html b/files/zh-cn/web/css/_doublecolon_-ms-clear/index.html deleted file mode 100644 index ef01ab3b21..0000000000 --- a/files/zh-cn/web/css/_doublecolon_-ms-clear/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: '::-ms-clear' -slug: 'Web/CSS/::-ms-clear' -translation_of: 'Archive/Web/CSS/::-ms-clear' ---- -
{{ CSSRef() }}
- -

{{ Non-standard_header() }}

- -

概述

- -

::-ms-clear CSS 伪元素 代表文本输入框 {{HTMLElement("input")}} 边缘的一个按钮(清除按钮),用于清除文本框 {{HTMLElement("input")}} 的当前值。这个按钮和伪元素是不标准的,目前只有Internet Explorer 10+可用,需要带上前缀。只有文本框 {{HTMLElement("input")}} 聚焦且非空的情况下该按钮才会出现。

- -

规范

- -

不属于任何规范。

- -

微软在MSDN上有 一篇描述 。

- -

Bugs

- -

在设置了 {{cssxref("text-align")}}: right 的文本框 {{HTMLElement("input")}} 中,如果清除按钮出现,则会裁剪文本框右侧边缘的内容。解决方案是使用 {{cssxref("display")}}: none 隐藏该按钮。详情见 IE bug 776537 。

diff --git a/files/zh-cn/web/css/overflow-clip-box/index.html b/files/zh-cn/web/css/overflow-clip-box/index.html deleted file mode 100644 index fdef49313b..0000000000 --- a/files/zh-cn/web/css/overflow-clip-box/index.html +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: overflow-clip-box -slug: Web/CSS/overflow-clip-box -translation_of: Mozilla/Gecko/Chrome/CSS/overflow-clip-box ---- -

Summary

-

 

-

Syntax

-
Formal syntax: {{csssyntax("overflow-clip-box")}}
-
overflow-clip-box: padding-box;
-overflow-clip-box: content-box;
-
-

Values

-

padding-box

-

content-box

-

Examples

-
 
-

Specifications

- - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS2.1', 'visufx.html#overflow-clipping', 'Overflow and clipping')}}{{Spec2('CSS2.1')}} 
-

Browser compatibility

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari (WebKit)
Basic support{{ CompatGeckoDesktop("30.0") }}Bug{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
-
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox Mobile (Gecko)AndroidIE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
-

 

diff --git a/files/zh-cn/web/events/domlinkadded/index.html b/files/zh-cn/web/events/domlinkadded/index.html deleted file mode 100644 index d066512013..0000000000 --- a/files/zh-cn/web/events/domlinkadded/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: DOMLinkAdded -slug: Web/Events/DOMLinkAdded -translation_of: Archive/Add-ons/Events/DOMLinkAdded ---- -

当把一个<link>元素插入到文档中的时候,会触发DOMLinkAdded事件.

- -

基本信息

- -
-
规范
-
附加组件私有
-
接口
-
Event
-
是否冒泡
-
-
能否取消默认行为
-
-
目标
-
window, browser
-
默认行为
-
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
diff --git a/files/zh-cn/web/events/mozafterpaint/index.html b/files/zh-cn/web/events/mozafterpaint/index.html deleted file mode 100644 index fc3b766b45..0000000000 --- a/files/zh-cn/web/events/mozafterpaint/index.html +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: MozAfterPaint -slug: Web/Events/MozAfterPaint -translation_of: Archive/Add-ons/Events/MozAfterPaint ---- -

MozAfterPaint事件在页面呈现给用户屏幕时触发,并提供页面重绘的信息,主要应用于页面优化审查。

- -

注意MozAfterPaint并非在页面重绘时立即触发,而是在重绘并合成后发生。这意味着有部分内容触发时已经呈现给客户。

- -
Note: - - -
- -

General info

- -
-
Specification
-
Add-ons specific
-
Interface
-
Event
-
Bubbles
-
Yes
-
Cancelable
-
Yes
-
Target
-
window
-
Default Action
-
None
-
- -

Properties

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}booleanDoes the event normally bubble?
cancelable {{readonlyInline}}booleanIs it possible to cancel the event?
boundingClientRectclientRectThe equivalent of {{domxref("Element.getBoundingClientRect", "getBoundingClientRect()")}} for the repainted zone. Read only.
clientRectsclientRectListThe equivalent of {{domxref("Element.getClientRects", "getClientRects()")}}  for the repainted zone. Read only.
transactionIduint64_tThe transaction id of the composition that just occurred to present something to the user. Read only.
- -

Example

- -

This example highlights elements that get repainted while hovering the document with a cursor.

- -
(function(){
-  var store = [];
-
-  // every repaint will be logged in store
-  window.addEventListener("MozAfterPaint", log, false);
-
-  if ( document.body )
-    bind();
-  else
-    window.addEventListener("load", bind, false);
-
-  function log(e){
-    store.push( [(new Date).getTime(), e.clientRects] );
-  }
-
-  function bind(){
-    // clicking anywhere on the document will prevent other repaint to be logged
-    // as well as display the visual "repaint heatmap"
-    document.body.addEventListener("click", function onClick(){
-      window.removeEventListener("MozAfterPaint", log, false);
-
-      for ( var pos = 0; pos < store.length; pos++ ) {
-        var rects = store[pos][1];
-
-        for ( var i = 0; i < rects.length; i++ ) {
-          // will simply "draw" semi-transparent red divs where
-          // repaints where recorded
-          var rect = rects[i];
-          var div = document.createElement("div");
-
-          with (div.style) {
-            background = "red";
-            opacity = "0.1";
-            position = "absolute";
-            top = rect.top + "px";
-            left = rect.left + "px";
-            width = (rect.right - rect.left) + "px";
-            height = (rect.bottom - rect.top) + "px";
-          }
-
-          document.body.appendChild( div );
-        }
-      }
-
-      document.body.removeEventListener("click", onClick, false);
-    }, false);
-  }
-})();
-
- -

This example is for measuring how long something took to paint to the user.

- -
// Suppose we want to measure how long it takes to paint the
-// next frame after a click event is fired on element "target".
-
-let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                     .getInterface(Ci.nsIDOMWindowUtils);
-
-// The last transaction id is the last id that was sent to the
-// compositor before our script started to execute.
-let lastTransactionId = winUtils.lastTransactionId;
-let start = window.performance.now();
-
-// Set up our MozAfterPaint listener, but we only care about
-// MozAfterPaint events where the transaction id is GREATER
-// than lastTransactionId. This is to account for the possibility
-// that a composite is underway at the time this script is running.
-addEventListener("MozAfterPaint", function onPaint(event) {
-  if (event.transactionId > lastTransactionId) {
-    // Since the transaction id is greater than the last transaction
-    // id, that means we're safe to assume that whatever effect that
-    // clicking on the "target" element was supposed to have, if the
-    // change should have been instantaneous, then it has been presented
-    // to the user.
-    let finish = window.performance.now();
-    alert(`Time to present: ${finish - start}ms`);
-    removeEventListener("MozAfterPaint", onPaint);
-  }
-});
-
-document.getElementById("target").click();
-
-
- -

See also

- - diff --git a/files/zh-cn/web/events/tabopen/index.html b/files/zh-cn/web/events/tabopen/index.html deleted file mode 100644 index 7d668792be..0000000000 --- a/files/zh-cn/web/events/tabopen/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: TabOpen -slug: Web/Events/TabOpen -translation_of: Archive/Add-ons/Events/TabOpen ---- -

TabOpen事件在一个新的标签页打开时触发.

- -

常规信息

- -
-
规范
-
附加组件特有
-
接口
-
Event
-
是否冒泡
-
-
能否取消默认行为
-
-
目标
-
tab
-
默认行为
-
None
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
diff --git a/files/zh-cn/web/guide/api/camera/index.html b/files/zh-cn/web/guide/api/camera/index.html deleted file mode 100644 index 64fe08d634..0000000000 --- a/files/zh-cn/web/guide/api/camera/index.html +++ /dev/null @@ -1,219 +0,0 @@ ---- -title: 使用Camera API -slug: Web/Guide/API/Camera -translation_of: Archive/B2G_OS/API/Camera_API/Introduction ---- -

通过Camera API,你可以使用手机的摄像头拍照,然后把拍到的照片发送给当前网页.这些操作主要是通过一个input元素来实现的,其中该元素的type属性必须为"file",accept属性要允许图片格式,这样才能知道这个文件选择框是用来选择图片的.,完整的HTML结构看起来是这样的:

-
<input type="file" id="take-picture" accept="image/*">
-
-

当用户激活这个HTML元素的时候,系统会呈现给用户一个选择界面,其中一个选项是选择本地的图片文件,另一个选项是要通过摄像头直接 拍摄照片作为所选文件.如果用户选择了摄像头,则会进入手机的拍照模式.拍照结束后,,用户可以选择确定还是放弃.如果接受了,则该照片会作为所选文件发 送给那个<input type="file">元素,同时触发该元素的onchange事件.

-

获取到所拍摄照片的引用

-

通过File API,你可以获取到用户所拍摄的照片或者所选择的图片文件的引用:

-
var takePicture = document.querySelector("#take-picture");
-takePicture.onchange = function (event) {
-    // 获得图片文件的引用
-    var files = event.target.files,
-        file;
-    if (files && files.length > 0) {
-        file = files[0];
-    }
-};
-
-

在网页中展示图片

-

如果你获取到了那张照片的引用(也就是File对象),你就可以使用{{ domxref("window.URL.createObjectURL()") }}方法创建一个指向那个照片的URL,然后把得到的URL赋给img元素的src属性:

-
// 获取到img元素
-var showPicture = document.querySelector("#show-picture");
-
-// 获取到window.URL对象
-var URL = window.URL || window.webkitURL;
-
-// 创建一个对象URL字符串
-var imgURL = URL.createObjectURL(file);
-
-// 设置img元素的src属性为那个URL
-showPicture.src = imgURL;
-
-// 释放那个对象URL,提高性能
-URL.revokeObjectURL(imgURL);
-
-

如果浏览器不支持createObjectURL()方法,还可以使用{{ domxref("FileReader") }}来实现:

-
// 如果createObjectURL方法不可用
-var fileReader = new FileReader();
-fileReader.onload = function (event) {
-    showPicture.src = event.target.result;
-};
-fileReader.readAsDataURL(file);
-
-

完整的示例代码

-

这里有一个完整的使用Camera API的demo,下面是这个demo的完整代码:

-

HTML页面:

-
<!DOCTYPE html>
-<html>
-    <head>
-        <meta charset="utf-8">
-        <title>Camera API</title>
-        <link rel="stylesheet" href="css/base.css" type="text/css" media="screen">
-    </head>
-
-    <body>
-
-        <div class="container">
-            <h1>Camera API</h1>
-
-            <section class="main-content">
-                <p>A demo of the Camera API, currently implemented in Firefox and Google Chrome on Android. Choose to take a picture with your device's camera and a preview will be shown through createObjectURL or a FileReader object (choosing local files supported too).</p>
-
-                <p>
-                    <input type="file" id="take-picture" accept="image/*">
-                </p>
-
-                <h2>Preview:</h2>
-                <p>
-                    <img src="about:blank" alt="" id="show-picture">
-                </p>
-
-                <p id="error"></p>
-
-            </section>
-
-            <p class="footer">All the code is available in the <a href="https://github.com/robnyman/robnyman.github.com/tree/master/camera-api">Camera API repository on GitHub</a>.</p>
-        </div>
-
-
-        <script src="js/base.js"></script>
-
-
-    </body>
-</html>
-
-

JavaScript文件:

-
(function () {
-    var takePicture = document.querySelector("#take-picture"),
-        showPicture = document.querySelector("#show-picture");
-
-    if (takePicture && showPicture) {
-        // Set events
-        takePicture.onchange = function (event) {
-            // Get a reference to the taken picture or chosen file
-            var files = event.target.files,
-                file;
-            if (files && files.length > 0) {
-                file = files[0];
-                try {
-                    // Get window.URL object
-                    var URL = window.URL || window.webkitURL;
-
-                    // Create ObjectURL
-                    var imgURL = URL.createObjectURL(file);
-
-                    // Set img src to ObjectURL
-                    showPicture.src = imgURL;
-
-                    // Revoke ObjectURL
-                    URL.revokeObjectURL(imgURL);
-                }
-                catch (e) {
-                    try {
-                        // Fallback if createObjectURL is not supported
-                        var fileReader = new FileReader();
-                        fileReader.onload = function (event) {
-                            showPicture.src = event.target.result;
-                        };
-                        fileReader.readAsDataURL(file);
-                    }
-                    catch (e) {
-                        //
-                        var error = document.querySelector("#error");
-                        if (error) {
-                            error.innerHTML = "Neither createObjectURL or FileReader are supported";
-                        }
-                    }
-                }
-            }
-        };
-    }
-})();
-
-

浏览器兼容性

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Camera API{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
createObjectURL()16{{CompatGeckoDesktop("8.0")}}10+{{CompatNo()}}{{CompatNo()}}
{{domxref("FileReader")}}16{{CompatGeckoDesktop("1.9.2")}}10+11.6+{{CompatNo()}}
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Camera API3.0{{ CompatVersionUnknown() }}{{ CompatGeckoMobile("10.0") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
createObjectURL()4{{CompatVersionUnknown()}}{{CompatGeckoMobile("10.0")}}{{CompatNo()}}{{CompatNo()}}{{CompatNo()}}
{{domxref("FileReader")}}3{{CompatVersionUnknown()}}{{CompatGeckoMobile("10.0")}}{{CompatNo()}}11.1{{CompatNo()}}
-
-

 

diff --git a/files/zh-cn/web/guide/css/getting_started/xml_data/index.html b/files/zh-cn/web/guide/css/getting_started/xml_data/index.html deleted file mode 100644 index bbdbd784f5..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/xml_data/index.html +++ /dev/null @@ -1,241 +0,0 @@ ---- -title: XML 数据 -slug: Web/Guide/CSS/Getting_started/XML_data -tags: - - CSS - - Web - - 中级 - - 实例 - - 开始学CSS - - 指南 - - 需要更新 -translation_of: Archive/Beginner_tutorials/XML_data ---- -

{{ CSSTutorialTOC() }}

- -

此页面包含一个如何使用CSS和XML数据的示例。

- -

你将创建一个XML文档范例,和使之在浏览器中展现的样式表。

- -

这是 CSS tutorial 第二部分的第三节。
- 前一章节: SVG
- 后一章节:  XBL binding

- -

信息: XML 数据

- -

XML (eXtensible Markup Language 可扩展标记语言) 是一种可用于任何类型的结构化数据的通用型语言。

- -

默认情况下,Mozilla 浏览器会将 XML 按照非常类似XML文件的原始数据的方式展现。你可以看到定义数据结构的具体的标签。

- -

通过将你的XML文档与CSS样式表链接,你可以定义展现XML的其他方式。为了实现这一点,样式表建立了映射规则,将XML文档中的标签映射为HTML中使用的展现类型。

- - - - - - - - -
示例
XML文档中的数据采用<INFO> 标签。你希望文档中的 INFO 元素像 HTML 的段落一样展现。. -

在该文档的样式表中,你指定了 INFO 元素的展现方式:

- -
-
-INFO {
-  display: block;
-  margin: 1em 0;
-  }
-
-
-
- -

在display属性中最常用的值是:

- - - - - - - - - - - - -
blockDisplayed like HTML's DIV (for headings, paragraphs)
inlineDisplayed like HTML's SPAN (for emphasis within text)
- -

如同对待HTML一样,通过设置字体、间距和其他细节来添加你自己的样式规则。

- - - - - - - - -
更多细节
其他display的值可以展现类似于列表项目的元素,或者类似表格组件的元素。 -

请查看CSS规范中的The display property ,来获取全部display类型。

- -

单独使用CSS,display的结构必须与文档结构一致。其它方式是修改display的结构—例如:使用XBL添加内容,使用JavaScript修改DOM。

- -

请查看 XML 页面,来获取更多关于XML in Mozilla的信息。

-
- -

实例: XML 演示

- -

新建一个 XML 文件: doc9.xml 。复制粘帖以下内容,注意滚动以获得全部:

- -
-
<?xml version="1.0"?>
-<!-- XML demonstration -->
-
-<?xml-stylesheet type="text/css" href="style9.css"?>
-
-<!DOCTYPE planet>
-<planet>
-
-<ocean>
-<name>Arctic</name>
-<area>13,000</area>
-<depth>1,200</depth>
-</ocean>
-
-<ocean>
-<name>Atlantic</name>
-<area>87,000</area>
-<depth>3,900</depth>
-</ocean>
-
-<ocean>
-<name>Pacific</name>
-<area>180,000</area>
-<depth>4,000</depth>
-</ocean>
-
-<ocean>
-<name>Indian</name>
-<area>75,000</area>
-<depth>3,900</depth>
-</ocean>
-
-<ocean>
-<name>Southern</name>
-<area>20,000</area>
-<depth>4,500</depth>
-</ocean>
-
-</planet>
-
-
- -

新建一个 CSS 文件: style9.css 。复制粘帖以下内容,注意滚动以获得全部:

- -
-
/*** XML demonstration ***/
-
-planet:before {
-  display: block;
-  width: 8em;
-  font-weight: bold;
-  font-size: 200%;
-  content: "Oceans";
-  margin: -.75em 0px .25em -.25em;
-  padding: .1em .25em;
-  background-color: #cdf;
-  }
-
-planet {
-  display: block;
-  margin: 2em 1em;
-  border: 4px solid #cdf;
-  padding: 0px 1em;
-  background-color: white;
-  }
-
-ocean {
-  display: block;
-  margin-bottom: 1em;
-  }
-
-name {
-  display: block;
-  font-weight: bold;
-  font-size: 150%;
-  }
-
-area {
-  display: block;
-  }
-
-area:before {
-  content: "Area: ";
-  }
-
-area:after {
-  content: " million km\B2";
-  }
-
-depth {
-  display: block;
-  }
-
-depth:before {
-  content: "Mean depth: ";
-  }
-
-depth:after {
-  content: " m";
-  }
-
-
- -

在你的浏览器中打开该文档:

- - - - - - - -
-
-

Oceans

- -

Arctic
- Area: 13,000 million km²
- Mean depth: 1,200 m

- -

Atlantic
- Area: 87,000 million km²
- Mean depth: 3,900 m

- -

. . .

-
-
- -


- 此演示的注解:

- - - -

 

- - - - - - - - -
挑战
修改样式表使文档可以作为表格展现。 -

(请参见 CSS 规范的 Tables 章节作为参考。)

-
- -

接下来?

- -

如果你难以理解此页面,或者你有其他意见,请提交到讨论页: Discussion 。

- -

这是本教程的最后一页。请查看此 wiki 的 CSS 主页,获取更多Mozilla CSS 信息。

diff --git a/files/zh-cn/web/javascript/ecmascript_7_support_in_mozilla/index.html b/files/zh-cn/web/javascript/ecmascript_7_support_in_mozilla/index.html deleted file mode 100644 index 55732f87ad..0000000000 --- a/files/zh-cn/web/javascript/ecmascript_7_support_in_mozilla/index.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: Mozilla对下一代ECMAScript 的支持 -slug: Web/JavaScript/ECMAScript_7_support_in_Mozilla -tags: - - ECMAScript 2015 - - ECMAScript 2016 - - ECMAScript 2017 - - ECMAScript 2018 - - new features -translation_of: Archive/Web/JavaScript/ECMAScript_Next_support_in_Mozilla ---- -
{{jsSidebar("New_in_JS")}}
- -

下一代 ECMAScript 是指在 ECMAScript 2015 被推出后的 ECMA-262 标准(通常被称为 JavaScript)的新特性。新版本的 ECMAScript 规范会每年发布。

- -

你可以在 tc39/ecma262 这个仓库中看见当前的规范草案。

- -

es-discuss 是一个关于 ECMAScript 标准有关反馈的渠道。

- -

ECMAScript 2016

- -

下面的 ECMAScript 2016 特性已实现:

- -

 

- - - -

ECMAScript 2017

- -

下面的 ECMAScript 2017 特性已实现:

- -

 

- - - -

实验性的新特性

- -

以下特性已经实现,但可能仅在 Firefox Nightly 中可用、或者需要浏览器 flags 开启;且此提案的标准可能尚未正式进入 ECMAScript 规范,请小心使用。

- -

ArrayBuffer 对象的新方法

- - - -

新的 TypedObject 对象

- - - -

新的 Shared Memory 对象

- - - -

相关链接

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.1/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.1/index.html deleted file mode 100644 index 968f518145..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.1/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: JavaScript 1.1的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.1 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.1 ---- -
{{jsSidebar("New_in_JS")}}
- -

下面介绍的是JavaScript从Netscape Navigator 2.0到3.0的更新日志。旧的Netscape文档请参考"第1版之后新增的特性"。Netscape Navigator 3.0在1996年8月19发布,是支持JavaScript的浏览器的第二个主要的版本。

- -

JavaScript 版本

- -

Netscape Navigator 3.0 也引进了JavaScript语言的版本号。

- -
<SCRIPT LANGUAGE="JavaScript">    <!-- JavaScript for Navigator 2.0. -->
-<SCRIPT LANGUAGE="JavaScript1.1"> <!-- JavaScript for Navigator 3.0. -->
- -

JavaScript 1.1 新特性

- -

新增的对象

- - - -

新增的属性

- - - -

新增的方法

- - - -

新增的操作符

- - - -

其他新特性

- - - -

JavaScript 1.1修改的功能

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.2/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.2/index.html deleted file mode 100644 index 17fde7ba38..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.2/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: JavaScript 1.2的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.2 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.2 ---- -
{{jsSidebar("New_in_JS")}}
- -

下面介绍的是JavaScript从Netscape Navigator 3.0到4.0的更新日志。旧的Netscape文档可以在archive.org上面找到。Netscape Navigator 4.0在1997年6月11日发布,它是是支持JavaScript的浏览器的第三个主要的版本。

- -

JavaScript 版本

- -

Netscape Navigator 4.0将JavaScript语言的版本升到1.2。需要注意的是,Netscape Navigator 3.0以及更早的版本忽略了设置为"JavaScript 1.2"和更高的版本的脚本语言属性。

- -
<SCRIPT LANGUAGE="JavaScript1.1"> <!-- JavaScript for Navigator 3.0. -->
-<SCRIPT LANGUAGE="JavaScript1.2"> <!-- JavaScript for Navigator 4.0. -->
- -

JavaScript 1.2新特性

- -

新增的对象

- - - -

新增的属性

- - - -

新增的方法

- - - -

新增的操作符

- - - -

新增的语句

- - - -

其他新特性

- - - -

JavaScript 1.2修改的功能

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.3/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.3/index.html deleted file mode 100644 index 193d5156d8..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.3/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: JavaScript 1.3的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.3 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.3 ---- -
{{jsSidebar("New_in_JS")}}
- -

下面介绍的是JavaScript从Netscape Navigator 4.0到4.5的更新日志。旧的Netscape文档可以在archive.org上面找到。Netscape Navigator 4.5是在1998年10月19日发布的。

- -

JavaScript 1.3 最显著的变化是通过消除JavaScript1.2和1997年6月发布的新ECMA标准的不一致性来遵守ECMA-262和Unicode。JavaScript 1.2附加的特性,在ECMA-262的规定外还保留在JavaScript语言(见下面的列表中的差异)。

- -

JavaScript 版本

- -

Netscape Navigator 4.06 到 4.5 将JavaScript语言的版本升到1.3。需要注意的是,Netscape Navigator 4.0 到 4.05以及更早的版本忽略了设置为"JavaScript 1.3"和更高的版本的脚本语言属性。

- -
<SCRIPT LANGUAGE="JavaScript1.2"> <!-- JavaScript for Navigator 4.0. -->
-<SCRIPT LANGUAGE="JavaScript1.3"> <!-- JavaScript for Navigator 4.5. -->
- -

JavaScript 1.3新特性

- -

新增的全局变量

- - - -

新增的方法

- - - -

其他新特性

- - - -

JavaScript 1.3 修改的功能

- - - -

非ECMA-262规范的JavaScript 1.3特性

- -

下面是关于1998年6月的ECMA-262版本和JavaScript 1.3之间的比较。下面的特性不是当时的标准的一部分,但是在JavaScript 1.3里面实施了。

- -

关键字和操作符

- - - -

语句

- - - -

内置对象

- - - -

内置对象的方向

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.4/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.4/index.html deleted file mode 100644 index a76c4f5424..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.4/index.html +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: JavaScript 1.4的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.4 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.4 ---- -
{{jsSidebar("New_in_JS")}}
- -

下面是 JavaScript 1.4 的更新记录,它只可用于 1999 年发布的 Netscape 服务端 JavaScript。 旧的 Netscape 文档可在 archive.org 找到。

- -

JavaScript 1.4的新特性

- - - -

JavaScript 1.4的功能改动

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.5/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.5/index.html deleted file mode 100644 index 0375ad3f7f..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.5/index.html +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: JavaScript 1.5 的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.5 -tags: - - JavaScript - - 版本 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.5 ---- -
{{jsSidebar("New_in_JS")}}
- -

以下为JavaScript 1.5 的更新日志。该版本包含在发行于2000年11月14日的Netscape Navigator 6.0中,也在后续的的Netscape Navigator版本和Firefox 1.0中使用。你可以拿JavaScript 1.5 和JScript version 5.5,Internet Explorer 5.5进行比较,后者发行于2000年7月。相应的ECMA 标准是 ECMA-262 Edition 3版 (自1999年12月)。

- -

JavaScript 1.5 新特性

- - - -

JavaScript 1.5 功能变化

- - - -

 

diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.6/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.6/index.html deleted file mode 100644 index 928fd75334..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.6/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: JavaScript 1.6 的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.6 -tags: - - JavaScript - - 版本 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.6 ---- -
-
{{jsSidebar("New_in_JS")}}
- -

以下是JavaScript 1.6的更新日志。JavaScript 1.6已经被包含在2005年11月发布的Firefox 1.5 (Gecko 1.8)中。JavaScript 1.6相对应的ECMA标准是ECMA-262第3版和ECMAScript for XML (E4X),这让它拥有了一些额外的特性 。引入了一些新特性:E4X,几个新的数组方法,还数组字符串的通用接口(generics)

- -

JavaScript 1.6新特性

- - - -

JavaScript 1.6功能变化

- - -
diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.7/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.7/index.html deleted file mode 100644 index e268345ca5..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.7/index.html +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: JavaScript 1.7 的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.7 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.7 ---- -
{{jsSidebar("New_in_JS")}}
- -
 
- -
以下是javaScript 1.7版本的更新日志,这个版本被包括在 Firefox 2 (2006年10月)。
- -

 

- -

JavaScript 1.7是一个引出了一些新特性的语言更新,尤其是generator,iterator,数组推导式, let 表达式和解构赋值。

- -

使用 JavaScript 1.7

- -

为了使用 JavaScript 1.7的一些新特性,你需要明确指出你希望使用 JavaScript 1.7。在HTML 或XUL code中,使用:

- -
<script type="application/javascript;version=1.7"></script>
-
- -

当使用 JavaScript shell的时候,你需要用 -version 170 开启命令行或者用version() 函数来设置你想使用的JavaScript版本。

- -
version(170);
-
- -

你需要指定1.7版本来使用新的“yield”和“let”关键字,因为现存的代码可能用它们当变量或者函数名用。没有涉及到新关键词的特性(比如解构赋值和数组推导式)可以直接使用,而不需要指明JavaScript版本。

- -

JavaScript 1.7的新特性

- -

以下JavaScript 1.7的新特性目前还不是ECMA-262标准的一部分。在最近的Firefox版本中会根据ECMAScipt6中的描述来实现这些功能。具体内容见这些参考页面。

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.8.1/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.8.1/index.html deleted file mode 100644 index 9ca99c06af..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.8.1/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: JavaScript 1.8.1 的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.8.1 -tags: - - Firefox 3.5 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.8.1 ---- -
{{jsSidebar("New_in_JS")}}
- -

下面是JavaScript 1.8.1 的更新内容. 该版本已包含在 Firefox 3.5 中.

- -

JavaScript 1.8.1 是在语义上有适度更新的版本; 其主要更新是添加能够提升性能的Tracemonkey即时编译器

- -

JavaScript 1.8.1 新特性

- - - -

JavaScript 1.8.1 功能更新

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.8.5/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.8.5/index.html deleted file mode 100644 index a61a892e70..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.8.5/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: JavaScript 1.8.5 的新特性 -slug: Web/JavaScript/New_in_JavaScript/1.8.5 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.8.5 ---- -
{{jsSidebar("New_in_JS")}}
- -

下面的内容是JavaScript 1.8.5的更新记录. 该版本已包含在Firefox 4中.

- -

JavaScript 1.8.5的新特性

- -

新函数

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FunctionDescription
Object.create()使用指定的原型对象和属性. {{bug("492840")}}
Object.defineProperty()为对象添加给定的描述信息的属性名.
Object.defineProperties()为对象添加多个给定的描述信息的属性名.
Object.getOwnPropertyDescriptor()返回对象的指定属性名的描述信息. {{bug("505587")}}
Object.keys()返回由对象的所有可枚举属性组成的数组. {{bug("307791")}}
Object.getOwnPropertyNames()返回由对象的所有可枚举和不可枚举属性组成的数组. {{bug("518663")}}
Object.preventExtensions()防止对象进行任意的扩展. {{bug("492849")}}
Object.isExtensible()判断对象是否可以扩展. {{bug("492849")}}
Object.seal()防止其他代码删除对象的属性. {{bug("492845")}}
Object.isSealed()判断对象是否是密封(即禁止删除属性)的. {{bug("492845")}}
Object.freeze()冻结一个对象: 其他代码不能删除或修改任何属性. {{bug("492844")}}
Object.isFrozen()判断对象是否是冻结的. {{bug("492844")}}
Array.isArray()判断变量是否是数组. {{bug("510537")}}
Date.prototype.toJSON()返回一个Date对象用JSON格式化的字符串.
Function.prototype.bind()创建一个新函数,当这个函数被调用时,函数会使用提供的上下文环境(给定的字符序列) {{bug("429507")}}
- -

ECMAScript5新特性

- - - -

其他标准化的工作

- -

删除一些定义getters和setters的非标准化语法; ECMAScript 5 定义的语法没有变化. 这些语法很难懂且很少被使用; 如果这个影响到你, 详细内容请看 这篇博客.

- -

新对象

- - - - - - - - - - - - - - -
ObjectDescription
Proxy提供创建对象和函数的代理,以在Javascript中支持元编程.
- -

JavaScript 1.8.5中功能变化

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/1.8/index.html b/files/zh-cn/web/javascript/new_in_javascript/1.8/index.html deleted file mode 100644 index d69d021c25..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/1.8/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: New in JavaScript 1.8 -slug: Web/JavaScript/New_in_JavaScript/1.8 -tags: - - JavaScript - - 版本 -translation_of: Archive/Web/JavaScript/New_in_JavaScript/1.8 ---- -
{{jsSidebar("New_in_JS")}}
- -

以下为JavaScript 1.8的更新日志。JavaScript 1.8 是 Gecko 1.9(已合并在 Firefox 3 中)的一部分。参见 {{ Bug("380236") }} 以跟踪 JavaScript 1.8。

- -

使用 JavaScript 1.8

- -

为了可以在 HTML 中使用 JavaScript 1.8 的新特性,需要这样写:

- -
 <script type="application/javascript;version=1.8"> ... 你的代码 ... </script>
-
- -

另一种方法(不推荐)是使用旧式的 <script> 属性 language,把它定义为 "JavaScript1.8"。

- -

在使用 JavaScript shell 、JavaScript XPCOM 组件,或者 XUL <script> 元素的时候,将自动启用最新的JS版本(Mozilla 1.9中的 JS1.8)({{ Bug("381031") }}, {{ Bug("385159") }})。

- -

如果需要使用新的关键字 "yield" 和 "let",你需要指定是1.7版本或者更高的版本,因为现有的代码可能会把这两个关键字用作变量名或者函数名。如果要使用的新特性没有引入任何新的关键字(例如生成器表达式),就可以不指定 JavaScript 的版本。

- -

JavaScript 1.8新特性

- - - -

JavaScript 1.8功能更新

- -

对for..in解构的修改

- -

JavaScript1.8中的一个修改是对JavaScript1.7中引入的数组键值结构相关的bug修复。之前可以用for ( var [key, value] in array )的方式来解构一个数组的键值。但是,这也让对数组的数组的键值解构变得不可能(比如一个迭代器返回一个当前键值对的数组)。现在这个问题可以用for ( var [key, value] in Iterator(array))来解决({{ Bug("366941") }})。

diff --git a/files/zh-cn/web/javascript/new_in_javascript/ecmascript_5_support_in_mozilla/index.html b/files/zh-cn/web/javascript/new_in_javascript/ecmascript_5_support_in_mozilla/index.html deleted file mode 100644 index 2dc69205cb..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/ecmascript_5_support_in_mozilla/index.html +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: ECMAScript 5 support in Mozilla -slug: Web/JavaScript/New_in_JavaScript/ECMAScript_5_support_in_Mozilla -translation_of: Archive/Web/JavaScript/New_in_JavaScript/ECMAScript_5_support_in_Mozilla ---- -
{{jsSidebar("New_in_JS")}}
- -

ECMAScript 5.1, an older version of the standard upon which JavaScript is based, was approved in June 2011.

- -

The JavaScript runtime used in the latest versions of Mozilla projects including both Firefox and Thunderbird has full support for ECMAScript 5.1 features. This article covers the features supported by different versions of Mozilla's JavaScript runtime.

- -

Supported features

- -

Added in JavaScript 1.8.5 (Gecko 2, Firefox 4 and later)

- -

Firefox 4 has full ECMAScript 5 support including the Object.* methods and strict mode. See New in JavaScript 1.8.5.

- -

Added in JavaScript 1.8.1 (Gecko 1.9.1, Firefox 3.5)

- - - -

Improvements laid out by ECMAScript 5 have been made in the parsing algorithm that prevents evaluating XHTML as JavaScript code in certain circumstances.

- -

Added in JavaScript 1.6 (Gecko 1.8, Firefox 1.5)

- -

New Array methods offering several improved methods for manipulating arrays -- have been part of JavaScript since JavaScript 1.6. Now they've been standardized as part of ECMAScript 5.

- -

See also

- - diff --git a/files/zh-cn/web/javascript/new_in_javascript/ecmascript_6_support_in_mozilla/index.html b/files/zh-cn/web/javascript/new_in_javascript/ecmascript_6_support_in_mozilla/index.html deleted file mode 100644 index 25210c32b2..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/ecmascript_6_support_in_mozilla/index.html +++ /dev/null @@ -1,282 +0,0 @@ ---- -title: Mozilla 对 ECMAScript 6 的支持 -slug: Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla -tags: - - ECMAScript2015 - - ECMAScript6 - - Firefox - - JavaScript -translation_of: Archive/Web/JavaScript/New_in_JavaScript/ECMAScript_2015_support_in_Mozilla ---- -
-
{{jsSidebar("New_in_JS")}}
- -

ECMAScript 2015 (6th Edition)是目前 ECMAScript 语言规范的标准。通常被称为"ES2015",在SpiderMonkey 中它规定了 JavaScript 的实现标准,SpiderMonkey 是一个 JavaScript 引擎,被广泛用于火狐浏览器等谋智的众多产品中。

- -

"ES.next" 的第一份工作草案 (基于 ECMAScript 5.1) 发布于 2011 年 7 月 12 日,代号为 "ES.next" 或 "Harmony"。2014 年 8 月,ECMAScript 2015 草案规范停止增加新的功能,开始进入稳定期与 bug 修复阶段。最终,ECMA-262 Edition 6 于 2015 年 6 月 17 日由 ECMA 联合大会 (ECMA General Assembly) 作为标准正式发布。它同时也是国际工业标准 ISO/IEC 16262:2016。

- -

你可以通过 ecma-international.org 免费下载规范的 PDFHTML 版本。

- -

es-discuss 是 ECMAScript 规范的讨论与反馈渠道。

- -

Firefox 已经支持的特性

- -

这里列出的功能已经在 Firefox 中支持;每个特性后面标注了具体实现的浏览器版本。

- -

标准库

- -

Array 对象的补充

- - - -

新的 Map 和 Set,以及 WeakMap 和 WeakSet 对象

- - - -

新的 Math 方法

- - - -

Number 对象的补充

- - - -

Object 对象的补充

- - - -

Date 对象的补充

- - - -

新的 Promise 对象

- - - -

新的 Reflect 对象

- - - -

RegExp 对象的补充

- - - -

String 对象的补充

- - - -

新的 Symbol 对象

- - - -

Typed Arrays

- -

Typed arrays 已经合并到 ECMAScript 2015 中,不再具有自己单独的规范

- - - -

表达式和操作符

- - - - - -

语句

- - - -

函数

- - - -

其他特性

- - - -

和 ES2015 规范不兼容的特性

- -

Firefox (部分)实现了以下特性,但是与规范不兼容。原因有如下几个:Firefox 是依据 ES 6 规范的早期草案来实现,或者 Firefox 是作为实验性特性来实现,而当时与之类似的特性还没有被添加到 ES2015 规范中。

- - - -

相关链接

- - -
diff --git a/files/zh-cn/web/javascript/new_in_javascript/index.html b/files/zh-cn/web/javascript/new_in_javascript/index.html deleted file mode 100644 index 95eee26559..0000000000 --- a/files/zh-cn/web/javascript/new_in_javascript/index.html +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: JavaScript更新 -slug: Web/JavaScript/New_in_JavaScript -tags: - - ECMAScript - - ECMAScript 2017 - - JavaScript - - 版本 -translation_of: Archive/Web/JavaScript/New_in_JavaScript ---- -
{{jsSidebar("New_in_JS")}}
- -
 
- -

本章包含有关JavaScript版本历史记录的信息,以及基于Mozilla/SpiderMonkey-的JavaScript应用程序的实现状态,例如Firefox。

- -

ECMAScript版本

- -
-
语言资源
-
在这里学习更多的JavaScript的标准ECMAScript。
-
ECMAScript 5的支持情况
-
Mozilla 的引擎和产品 对于标准ECMA-262 Edition 5.1的支持情况。
-
ECMAScript 2015的支持情况
-
Mozilla 的引擎和产品对于标准ECMA-262 Edition 6的支持情况。
-
ECMAScript 2016的支持情况
-
Mozilla 的引擎和产品对于即将到来的ECMA-262 Edition 7的支持情况.
-
- -

JavaScript发布说明

- -
-
Firefox中的JavaScript更新日志
-
Firefox 5以及以后版本的JavaScript日志更新情况。
-
Chrome中的JavaScript更新日志
-
Chrome中的JavaScript日志更新情况。
-
- -

JavaScript版本

- -

弃用项 ({{deprecated_inline()}})。这里面是一些已经确定的弃用的api以及一下Mozilla组织专用的API  正在被慢慢的弃用不建议使用。Firefox 4 所用的javascirpt引擎是 ECMAScript(1.8.5). 就像现在我们提到的新的引擎 ECMA-262 里面的标准都在 ECMAScript 2015 里面的实现了API。

- -

JavaScript于1996年3月在Netscape Navigator 2.0和Internet Explorer 2.0中发布为1.0版。

- -
-
JavaScript 1.1
-
该版本在Netscape Navigator 3.0中使用。发布于1996年8月19日。
-
JavaScript 1.2
-
该版本在Netscape Navigator 4.0-4.05中使用。发布于1997年6月11日。
-
JavaScript 1.3
-
该版本在Netscape Navigator 4.06-4.7x中使用。发布于1998年10月19日。符合ECMA-262第1版和第2版的标准
-
JavaScript 1.4
-
版本在Netscape的服务器端发送的JavaScript。于1999年发行。
-
JavaScript 1.5
-
该版本在Netscape Navigator 6.0和Firefox 1.0中使用。发布于2000年11月14日。符合ECMA-262第3版的标准
-
JavaScript 1.6
-
该版本在 Firefox 1.5中使用。发布于2005年11月。加入了ECMAScript标准的XML(E4X),Array方法,String以及泛型
-
JavaScript 1.7
-
Version shipped in Firefox 2. Released in October 2006.
- Includes generators, iterators, array comprehensions, let expressions, and destructuring assignment.
-
JavaScript 1.8
-
Version shipped in Firefox 3. Released in June 2008.
-
包括表达式闭包,生成器表达式和Array.reduce()
-
JavaScript 1.8.1
-
Version shipped in Firefox 3.5. Released on June 30, 2009.
-
包括TraceMonkey JIT并原生支持JSON。
-
JavaScript 1.8.2
-
Version shipped in Firefox 3.6. Released June 22, 2009.
- Includes only minor changes.
-
JavaScript 1.8.5
-
Version shipped in Firefox 4. Released July 27, 2010.包括符合ECMA-262 Edition 5的许多新功能。 这是最后一个JavaScript版本。
-
ES2015
-
- - - -

ES2016

- - - -

ES2017

- - - -

 

- -

 

diff --git a/files/zh-cn/web/javascript/reference/functions/arguments/caller/index.html b/files/zh-cn/web/javascript/reference/functions/arguments/caller/index.html deleted file mode 100644 index 13128ec962..0000000000 --- a/files/zh-cn/web/javascript/reference/functions/arguments/caller/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: caller -slug: Web/JavaScript/Reference/Functions/arguments/caller -translation_of: Archive/Web/JavaScript/arguments.caller ---- -

{{jsSidebar("Functions")}}

- -

废弃的 arguments.caller 属性原先用在函数执行的时候调用自身。本属性已被移除且不再有用。

- -

描述

- -

arguments.caller 已经不可使用了,但是你还可以使用 {{jsxref("Function.caller")}}。

- -
function whoCalled() {
-   if (whoCalled.caller == null)
-      console.log('I was called from the global scope.');
-   else
-      console.log(whoCalled.caller + ' called me!');
-}
-
- -

示例

- -

下例演示了arguments.caller属性的作用.

- -
function whoCalled() {
-   if (arguments.caller == null)
-      console.log('该函数在全局作用域内被调用.');
-   else
-      console.log(arguments.caller + '调用了我!');
-}
- -

规范

- -

无相关标准。JavaScript 1.1 实现,{{bug(7224)}} 移除 caller,因为潜在的不安全性。

- -

浏览器支持

- - - -

{{Compat("javascript.functions.arguments.caller")}}

- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/observe/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/observe/index.html deleted file mode 100644 index 7c2dcc8474..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/array/observe/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Array.observe() -slug: Web/JavaScript/Reference/Global_Objects/Array/observe -tags: - - JavaScript - - 实验性 - - 数组 - - 方法 - - 过时的 -translation_of: Archive/Web/JavaScript/Array.observe ---- -
{{JSRef}}{{obsolete_header}}
- -

Array.observe() 方法用于异步监视数组发生的变化,类似于针对对象的 {{jsxref("Object.observe()")}} 。当数组的值发生变化时,它按发生顺序提供了一个变化流。与 Object.observe() 类似,它由如下可接受的变化类型列表["add"、"update"、"delete"、"splice"]触发。

- -

语法

- -
Array.observe(arr, callback)
- -

参数

- -
-
arr
-
用于被监视的数组
-
callback
-
每当数组发生变化时,使用如下参数调用该函数: -
-
changes
-
用于表示变化的对象数组。每个变化对象的属性如下: -
    -
  • name: 变化的属性名。
  • -
  • object: 变化后的数组。
  • -
  • type: 用于表示变化类型的字符串。其取值为"add"、"update"、"delete""splice"之一。
  • -
  • oldValue: 仅用于"update""delete"类型。变化之前的取值。
  • -
  • index: 仅用于"splice"类型。变化发生所在索引。
  • -
  • removed: 仅用于"splice"类型。被删除元素组成的数组。
  • -
  • addedCount: 仅用于"splice"类型。被添加的元素数量。
  • -
-
-
-
-
- -

描述

- -

每次 arr 发生任何变化时,回调函数将被调用,调用参数为所有变化按发生顺序组成的数组。

- -
-

通过Array方法如 Array.prototype.pop( ) 触发的变化将被报告成"splice"变化,长度不变但索引赋值发生变化的将被报告成"update"变化。

-
- -

示例

- -

Example: Logging different change types

- -
var arr = ['a', 'b', 'c'];
-
-Array.observe(arr, function(changes) {
-  console.log(changes);
-});
-
-arr[1] = 'B';
-// [{type: 'update', object: <arr>, name: '1', oldValue: 'b'}]
-
-arr[3] = 'd';
-// [{type: 'splice', object: <arr>, index: 3, removed: [], addedCount: 1}]
-
-arr.splice(1, 2, 'beta', 'gamma', 'delta');
-// [{type: 'splice', object: <arr>, index: 1, removed: ['B', 'c'], addedCount: 3}]
-
- -

标准规范

- -

Strawman proposal specification.

- -

浏览器支持

- -
-
- - -

{{Compat("javascript.builtins.Array.observe")}}

-
-
- -

相关内容

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/unobserve/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/unobserve/index.html deleted file mode 100644 index 90678a1081..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/array/unobserve/index.html +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Array.unobserve() -slug: Web/JavaScript/Reference/Global_Objects/Array/unobserve -translation_of: Archive/Web/JavaScript/Array.unobserve ---- -
{{JSRef}} {{non-standard_header}}
- -

Array.unobserve()方法用来移除{{jsxref("Array.observe()")}}设置的所有观察者。

- -

语法

- -
Array.unobserve(arr, callback)
- -

参数

- -
-
arr
-
停止观察的数组。
-
 
-
callback回调
-
需要停止的array arr每次改变都会调用的函数引用。
-
- -

描述

- -

Array.unobserve() 方法因为要移除观察者,所以应该在{{jsxref("Array.observe()")}}调用后调用。

- -

回调函数应该是一个函数的引用并且不能是匿名函数, 因为这个函数需要用来移除前面的观察者, 如果用匿名函数是没有用的,将不能移除任何观察者。

- -

例子

- -

停止观察一个数组

- -
var arr = [1, 2, 3];
-
-var observer = function(changes) {
-  console.log(changes);
-}
-
-Array.observe(arr, observer);
-​
-arr.push(4);
-// [{type: "splice", object: <arr>, index: 3, removed:[], addedCount: 1}]
-
-Array.unobserve(arr, observer);
-
-arr.pop();
-// The callback wasn't called
- -

使用匿名函数

- -
var persons = ['Khalid', 'Ahmed', 'Mohammed'];
-
-Array.observe(persons, function (changes) {
-  console.log(changes);
-});
-
-persons.shift();
-// [{type: "splice", object: <arr>, index: 0, removed: [ "Khalid" ], addedCount: 0 }]
-
-Array.unobserve(persons, function (changes) {
-  console.log(changes);
-});
-
-persons.push('Abdullah');
-// [{type: "splice", object: <arr>, index: 2, removed: [], addedCount: 1 }]
-// The callback will always be called
-
- -

浏览器兼容性

- -
-
- - -

{{Compat("javascript.builtins.Array.unobserve")}}

-
-
- -

相关内容

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/transfer/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/transfer/index.html deleted file mode 100644 index cf3185f637..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/transfer/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: ArrayBuffer.transfer() -slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transfer -translation_of: Archive/Web/JavaScript/ArrayBuffer.transfer ---- -
{{JSRef}} {{SeeCompatTable}}
- -

 静态ArrayBuffer.transfer() 方法返回一个新的ArrayBuffer, 其内容取自oldBuffer的数据,并且根据 newByteLength 的大小来对数据进行截取或者以0扩展。 如果 newByteLength 未定义,则使用 oldBuffer 的byteLength。这个操作使得 oldBuffer 处于被移除的状态。

- -

语法

- -
ArrayBuffer.transfer(oldBuffer [, newByteLength]);
- -

参数

- -
-
oldBuffer
-
 要转移的{{jsxref("ArrayBuffer")}}对象。
-
newByteLength
-
ArrayBuffer 对象的字节长度。
-
- -

返回值

- -

一个新的ArrayBuffer对象。

- -

描述

- -

ArrayBuffer.transfer()方法允许你增长和移除 ArrayBuffer 对象。不需复制就能增长一个ArrayBuffer的功能,对于大的缓冲区来说,有速度优势 (类似realloc) 。当释放底层内存时,移除ArrayBuffer的功能给开发者提供了显式控制。这避免了必须丢弃所有引用和等待垃圾回收。

- -

示例

- -
var buf1 = new ArrayBuffer(40);
-new Int32Array(buf1)[0] = 42;
-
-var buf2 = ArrayBuffer.transfer(buf1, 80);
-buf1.byteLength; // 0 but if you use the polyfill then the value is still 40
-buf2.byteLength; // 80
-new Int32Array(buf2)[0]; // 42
-
-var buf3 = ArrayBuffer.transfer(buf2, 0);
-buf2.byteLength; // 0 but if you use the polyfill then the value is still 80
-buf3.byteLength; // 0
-
- -

Polyfill

- -

You can partially work around this by inserting the following code at the beginning of your scripts, allowing use of much of the functionality of transfer() in implementations that do not natively support it. This is not the exact equivalent of this API, but this function transfers data from one ArrayBuffer to another ArrayBuffer.

- -
if(!ArrayBuffer.transfer) {
-    ArrayBuffer.transfer = function (source, length) {
-        source = Object(source);
-        var dest = new ArrayBuffer(length);
-        if(!(source instanceof ArrayBuffer) || !(dest instanceof ArrayBuffer)) {
-            throw new TypeError("Source and destination must be ArrayBuffer instances");
-        }
-        if(dest.byteLength >= source.byteLength) {
-            var nextOffset = 0;
-            var leftBytes = source.byteLength;
-            var wordSizes = [8, 4, 2, 1];
-            wordSizes.forEach(function (_wordSize_) {
-                if (leftBytes >= _wordSize_) {
-                    var done = transferWith(_wordSize_, source, dest, nextOffset, leftBytes);
-                    nextOffset = done.nextOffset;
-                    leftBytes = done.leftBytes;
-                }
-            });
-        }
-        return dest;
-        function transferWith(wordSize, source, dest, nextOffset, leftBytes) {
-            var ViewClass = Uint8Array;
-            switch (wordSize)  {
-                case 8:
-                    ViewClass = Float64Array;
-                    break;
-                case 4:
-                    ViewClass = Float32Array;
-                    break;
-                case 2:
-                    ViewClass = Uint16Array;
-                    break;
-                case 1:
-                    ViewClass = Uint8Array;
-                    break;
-                default:
-                    ViewClass = Uint8Array;
-                    break;
-            }
-            var view_source = new ViewClass(source, nextOffset, Math.trunc(leftBytes / wordSize));
-            var view_dest = new ViewClass(dest, nextOffset, Math.trunc(leftBytes / wordSize));
-            for(var i=0; i<view_dest.length; i++) {
-                view_dest[i] = view_source[i];
-            }
-            return {
-                nextOffset : view_source.byteOffset + view_source.byteLength,
-                leftBytes : source.byteLength - (view_source.byteOffset + view_source.byteLength)
-            }
-        }
-    };
-}
- -

规范

- -

Not part of any current specification draft document, but has been proposed for a future ECMA-262 edition.

- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.ArrayBuffer.transfer")}}

- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/tolocaleformat/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/tolocaleformat/index.html deleted file mode 100644 index 40c72fc476..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/date/tolocaleformat/index.html +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Date.prototype.toLocaleFormat() -slug: Web/JavaScript/Reference/Global_Objects/Date/toLocaleFormat -tags: - - Date - - 非标准 -translation_of: Archive/Web/JavaScript/Date.toLocaleFormat ---- -
{{JSRef}} {{non-standard_header}}
- -

非标准方法 toLocaleFormat() 按特定的格式将一个日期转换成一个字符串。 {{jsxref("Global_Objects/DateTimeFormat", "Intl.DateTimeFormat")}} 是符合标准的格式化日期的替代方法。另见更新的(newer)版本的 {{jsxref("Date.prototype.toLocaleDateString()")}}方法.

- -

语法

- -
dateObj.toLocaleFormat(formatString)
- -

参数

- -
-
formatString
-
与C语言中的 strftime() 方法的参数形式要求相同的格式字符串。
-
- -

描述

- -

toLocaleFormat() 方法通过格式化生成的日期或时间提供了更好的软件层面的控制(provides greater software control over the formatting of the generated date and/or time)。用操作系统的地点来月份和星期几的名称本地化。然而,However, ordering of the day and month and other localization tasks are not handled automatically since you have control over the order in which they occur. You should take care that the format string is localized properly according to the user's system settings. Be aware that the locale used is not necessarily the same as the locale of the browser.

- -

Extension and XULRunner developers should know that just loading the format string from a .dtd or .properties file using a chrome://somedomain/locale/somefile.ext URI should be avoided, as the .dtd/.properties file and the toLocaleFormat() method does not not necessarily use the same locale, which could result in odd looking or even ambiguous or unreadable dates.

- -

Also note that the behavior of the used locale depends on the platform, and the user might customize the locale used, so using the system locale the choose the format string might in some cases not even be adequate. You might consider using some of the more general toLocale* methods of the {{jsxref("Global_Objects/Date", "Date")}} object or doing your own custom localization of the date to be displayed using some of the get* methods of the {{jsxref("Global_Objects/Date", "Date")}} object instead of using this method.

- -

示例

- -

Using toLocaleFormat()

- -
var today = new Date();
-var date = today.toLocaleFormat('%A, %B %e, %Y'); // Bad example
-
- -

In this example, toLocaleFormat() returns a string such as "Wednesday, October 3, 2007". Note that the format string in this example is not properly localized, which will result in the problems described above.

- -

腻子(Polyfill)

- -

When using the DateJS library you can polyfill {{jsxref("Date.prototype.toLocaleDateString()")}} like this:

- -
if (!Date.prototype.toLocaleFormat) {
-    (function() {
-        Date.prototype.toLocaleFormat = function(formatString) {
-            return this.format(formatString);
-        };
-    }());
-}
- -

标准

- -

不属于任何标准。在JavaScript 1.6中被实现。

- -

兼容性

- -
- - -

{{Compat("javascript.builtins.Date.toLocaleFormat")}}

-
- -

另见

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/arity/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/arity/index.html deleted file mode 100644 index d8e8668ca2..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/function/arity/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Function.arity -slug: Web/JavaScript/Reference/Global_Objects/Function/arity -translation_of: Archive/Web/JavaScript/Function.arity ---- -
-
{{JSRef("Global_Objects", "Function")}} {{obsolete_header}}
-
- -

概述

- -

返回一个函数的形参数量.

- -

描述

- -

arity是一个古老的已经没有浏览器支持的属性,你应该使用Function.prototype.length属性来代替.

diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/isgenerator/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/isgenerator/index.html deleted file mode 100644 index f377f0a210..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/function/isgenerator/index.html +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Function.prototype.isGenerator() -slug: Web/JavaScript/Reference/Global_Objects/Function/isGenerator -translation_of: Archive/Web/JavaScript/Function.isGenerator ---- -
{{JSRef("Global_Objects", "Function")}} {{non-standard_header}}
- -

概述

- -

判断一个函数是否是一个生成器.

- -

语法

- -
fun.isGenerator()
- -

描述

- -

该方法用来判断一个函数是否是一个生成器.

- -

例子

- -
function f() {}
-function* g() {
-  yield 42;
-}
-console.log("f.isGenerator() = " + f.isGenerator());
-console.log("g.isGenerator() = " + g.isGenerator());
-
- -

上面代码的输出结果为

- -
f.isGenerator() = false
-g.isGenerator() = true
-
- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/iterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/iterator/index.html deleted file mode 100644 index 775c8d60d6..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/iterator/index.html +++ /dev/null @@ -1,188 +0,0 @@ ---- -title: Iterator -slug: Web/JavaScript/Reference/Global_Objects/Iterator -tags: - - Deprecated -translation_of: Archive/Web/Iterator ---- -
{{jsSidebar("Objects")}}
- -
非标准。 Iterator 函数是一个 SpiderMonkey 专有特性,并且会在某一时刻被删除。为将来使用的话,请考虑使用 {{jsxref("Statements/for...of", "for...of")}} 循环和  迭代协议
- -

Iterator 函数返回一个对象,它实现了遗留的迭代协议,并且迭代了一个对象的可枚举属性。

- -

语法

- -
Iterator(object, [keyOnly])
- -

参数

- -
-
object
-
要迭代属性的对象。
-
keyOnly
-
 如果keyOnly是真值,Iterator.prototype.next 只返回property_name
-
- -

描述

- -

返回迭代了object的Iterator 实例。如果keyOnly为假值,则Iterator 实例返回每次迭代而生成的 [property_name, property_value] 数组,否则,如果keyOnly是真值,则它返回每次迭代的 property_name。如果objectIterator 实例或 {{jsxref("Generator")}} 实例 ,则它返回 object 自身。

- -

属性

- -
-
Iterator.prototype[@@iterator]
-
返回一个函数,它返回符合{{jsxref("Iteration_protocols", "迭代协议", "", 1)}}的迭代对象。
-
- -

方法

- -
-
Iterator.prototype.next
-
返回[property_name, property_value] 格式或property_name 的下一项。 如果没有更多项,抛出 StopIteration
-
- -

示例

- -

迭代一个对象的属性

- -
var a = {
-  x: 10,
-  y: 20,
-};
-var iter = Iterator(a);
-console.log(iter.next()); // ["x", 10]
-console.log(iter.next()); // ["y", 20]
-console.log(iter.next()); // throws StopIteration
-
- -

使用遗留的解构for-in迭代对象的属性

- -
var a = {
-  x: 10,
-  y: 20,
-};
-
-for (var [name, value] in Iterator(a)) {
-  console.log(name, value);   // x 10
-                              // y 20
-}
-
- -

使用for-of迭代

- -
var a = {
-  x: 10,
-  y: 20,
-};
-
-for (var [name, value] of Iterator(a)) {  // @@iterator is used
-  console.log(name, value);   // x 10
-                              // y 20
-}
-
- -

迭代属性名

- -
var a = {
-  x: 10,
-  y: 20,
-};
-
-for (var name in Iterator(a, true)) {
-  console.log(name);   // x
-                       // y
-}
-
- -

传入 Generator 实例

- -
function* f() {
-  yield 'a';
-  yield 'b';
-}
-var g = f();
-
-console.log(g == Iterator(g)); // true
-
-for (var v in Iterator(g)) {
-  console.log(v);   // a
-                    // b
-}
-
- -

传入 Iterator 实例

- -
var a = {
-  x: 10,
-  y: 20,
-};
-
-var i = Iterator(a);
-
-console.log(i == Iterator(i)); // true
-
- -

规范

- -

非标准。不是目前任何标准文档的一部分。

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/tointeger/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/tointeger/index.html deleted file mode 100644 index 24abe2125e..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/number/tointeger/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Number.toInteger() -slug: Web/JavaScript/Reference/Global_Objects/Number/toInteger -translation_of: Archive/Web/JavaScript/Number.toInteger ---- -
{{JSRef("Global_Objects", "Number")}} {{obsolete_header("33")}} {{non-standard_header}}
- -

概览

- -

Number.toInteger() 用来将参数转换成整数,但该方法的实现已被移除.

- -

如果参数是 {{jsxref("Global_Objects/NaN", "NaN")}}, {{jsxref("Global_Objects/null", "null")}} 或 {{jsxref("Global_Objects/undefined", "undefined")}}, 会返回0 . 如果参数值是true返回1,false的话返回0.

- -

语法

- -
Number.toInteger(number)
- -

参数

- -
-
number
-
将被转换成整数的参数.
-
- -

示例

- -

例子: 使用 toInteger()方法

- -
Number.toInteger(0.1);     // 0
-Number.toInteger(1);       // 1
-Number.toInteger(Math.PI); // 3
-Number.toInteger(null);    // 0
-
- -

Specifications

- - - -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}Firefox 16 to 32{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}Firefox 16 to 32{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

See also

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/count/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/count/index.html deleted file mode 100644 index c7dfb12f2b..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/count/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: Object.prototype.__count__ -slug: Web/JavaScript/Reference/Global_Objects/Object/count -tags: - - JavaScript - - Object - - Obsolete - - Property - - Prototype -translation_of: Archive/Web/JavaScript/Object.count ---- -
{{JSRef}} {{obsolete_header("2")}}
- -

 __count__ 属性曾经用来存放对象的可枚举的属性的个数,但是已经被废除。

- -

语法

- -
obj.__count__
- -

示例

- -
{ 1: 1 }.__count__              // 1
-[].__count__                    // 0
-[1].__count__                   // 1
-[1, /* hole */, 2, 3].__count__ // 3
-
- -

详细说明

- -

无需详细说明

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

更多请参看

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/eval/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/eval/index.html deleted file mode 100644 index e823c314a8..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/eval/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Object.prototype.eval() -slug: Web/JavaScript/Reference/Global_Objects/Object/eval -translation_of: Archive/Web/JavaScript/Object.eval ---- -
{{JSRef}} {{obsolete_header}}
- -

Object.eval() 方法用于在对象的上下文中对 JavaScript 代码字符串求值,但该方法已被移除。

- -

语法

- -
obj.eval(string)
- -

参数

- -
-
string
-
包含任意 JavaScript 表达式、语句或一组语句的字符串。表达式中可包含已有对象的变量与属性。
-
- -

描述

- -

eval 方法已从对象方法中移除。可使用全局 {{jsxref("Global_Objects/eval", "eval()")}} 函数替代该方法。

- -

规范

- -

暂无规范

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/getnotifier/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/getnotifier/index.html deleted file mode 100644 index fac0573de3..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/getnotifier/index.html +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Object.getNotifier() -slug: Web/JavaScript/Reference/Global_Objects/Object/getNotifier -translation_of: Archive/Web/JavaScript/Object.getNotifier ---- -
{{JSRef}} {{obsolete_header}}
- -

Object.getNotifer() 方法用于创建可人工触发 change 事件的对象,但该方法在浏览器中已被废弃。

- -

语法

- -
Object.getNotifier(obj)
- -

参数

- -
-
obj
-
获取通知的对象。
-
- -

返回值

- -

与传入对象相关联的通知对象。

- -

描述

- -

通知对象可触发 Object.observe() 所观察到的人工变动。

- -

规范

- -

Strawman proposal specification.

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("36")}} [1]{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("36")}} [1]{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
-
- -

[1] Deprecated in Chrome 49.

- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/nosuchmethod/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/nosuchmethod/index.html deleted file mode 100644 index 7b54198c19..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/nosuchmethod/index.html +++ /dev/null @@ -1,208 +0,0 @@ ---- -title: Object.prototype.__noSuchMethod__ -slug: Web/JavaScript/Reference/Global_Objects/Object/noSuchMethod -translation_of: Archive/Web/JavaScript/Object.noSuchMethod ---- -
{{JSRef}} {{obsolete_header}}
- -

__noSuchMethod__ 属性曾经是指当调用某个对象里不存在的方法时即将被执行的函数,但是现在这个函数已经不可用。

- -

__noSuchMethod__ 属性被移除之后,ECMAScript 2015 (ES6) 规范转而采用 {{jsxref("Proxy")}} 对象, 可以实现下面的效果(以及更多)。

- -

语法

- -
obj.__noSuchMethod__ = fun
- -

参数

- -
-
fun
-
函数形式如下:
-
-
function (id, args) { . . . }
- -
-
id
-
调用的不存在的方法名
-
args
-
传递给该方法的参数数组
-
-
-
- -

描述

- -

默认情况喜爱,试图调用对象上不存在的方法其结果是在{{jsxref("TypeError")}}上抛出异常,这种行为可以在

- -

By default, an attempt to call a method that doesn't exist on an object results in a {{jsxref("TypeError")}} being thrown. This behavior can be circumvented by defining a function at that object's __noSuchMethod__ member. The function takes two arguments, the first is the name of the method attempted and the second is an array of the arguments that were passed in the method call. The second argument is an actual array (that is, it inherits through the {{jsxref("Array.prototype")}} chain) and not the array-like arguments object.

- -

If this method cannot be called, either as if undefined by default, if deleted, or if manually set to a non-function, the JavaScript engine will revert to throwing TypeErrors.

- -

Examples

- -

Simple test of __noSuchMethod__

- -
var o = {
-  __noSuchMethod__: function(id, args) {
-                      console.log(id, '(' + args.join(', ') + ')');
-                    }
-};
-
-o.foo(1, 2, 3);
-o.bar(4, 5);
-o.baz();
-
-// Output
-// foo (1, 2, 3)
-// bar (4, 5)
-// baz ()
-
- -

Using __noSuchMethod__ to simulate multiple inheritance

- -

An example of code that implements a primitive form of multiple inheritance is shown below.

- -
// Doesn't work with multiple inheritance objects as parents
-function noMethod(name, args) {
-  var parents = this.__parents_;
-
-  // Go through all parents
-  for (var i = 0; i < parents.length; i++) {
-    // If we find a function on the parent, we call it
-    if (typeof parents[i][name] == "function") {
-      return parents[i][name].apply(this, args);
-    }
-  }
-
-  // If we get here, the method hasn't been found
-  throw new TypeError;
-}
-
-// Used to add a parent for multiple inheritance
-function addParent(obj, parent) {
-  // If the object isn't initialized, initialize it
-  if (!obj.__parents_) {
-    obj.__parents_ = [];
-    obj.__noSuchMethod__ = noMethod;
-  }
-
-  // Add the parent
-  obj.__parents_.push(parent);
-}
-
- -

An example of using this idea is shown below.

- -
// Example base class 1
-function NamedThing(name){
-  this.name=name;
-}
-
-NamedThing.prototype = {
-  getName: function() { return this.name; },
-  setName: function(newName) { this.name = newName; }
-}
-
-// Example base class 2
-function AgedThing(age) {
-  this.age = age;
-}
-
-AgedThing.prototype = {
-  getAge: function() { return this.age; },
-  setAge: function(age) { this.age = age; }
-}
-
-// Child class. inherits from NamedThing and AgedThing
-// as well as defining address
-function Person(name, age, address){
-  addParent(this, NamedThing.prototype);
-  NamedThing.call(this, name);
-  addParent(this, AgedThing.prototype);
-  AgedThing.call(this, age);
-  this.address = address;
-}
-
-Person.prototype = {
-  getAddr: function() { return this.address; },
-  setAddr: function(addr) { this.address = addr; }
-}
-
-var bob = new Person("bob", 25, "New York");
-
-console.log("getAge is " + (("getAge" in bob) ? "in" : "not in") + " bob");
-// getAge is not in bob
-
-console.log("bob's age is: " + bob.getAge());
-// bob's age is: 25
-
-console.log("getName is " + (("getName" in bob) ? "in" : "not in") + " bob");
-// getName is not in bob
-
-console.log("bob's name is: " + bob.getName());
-// bob's name is: bob
-
-console.log("getAddr is " + (("getAddr" in bob) ? "in" : "not in") + " bob");
-// getAddr is in bob
-
-console.log("bob's address is: " + bob.getAddr());
-// bob's address is: New York
-
- -

Specifications

- -

Not part of any specifications. This feature has been removed, see {{bug(683218)}}.

- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}} [1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

[1] This feature was implemented until version 43.

diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/observe/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/observe/index.html deleted file mode 100644 index e37cc6ab6f..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/observe/index.html +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: Object.observe() -slug: Web/JavaScript/Reference/Global_Objects/Object/observe -tags: - - ECMAScript7 - - Experimental - - JavaScript - - Method - - Object - - observe -translation_of: Archive/Web/JavaScript/Object.observe ---- -
{{JSRef}} {{obsolete_header}}
- -

概述

- -

Object.observe() 方法用于异步地监视一个对象的修改。当对象属性被修改时,方法的回调函数会提供一个有序的修改流。然而,这个接口已经被废弃并从各浏览器中移除。你可以使用更通用的 {{jsxref("Proxy")}} 对象替代。

- -

语法

- -
Object.observe(obj, callback[, acceptList])
- -

参数

- -
-
obj
-
被监控的对象.
-
callback
-
当对象被修改时触发的回调函数,其参数为: -
-
changes
-
一个数组,其中包含的每一个对象代表一个修改行为。每个修改行为的对象包含: -
    -
  • name: 被修改的属性名称
  • -
  • object: 修改后该对象的值
  • -
  • type: 表示对该对象做了何种类型的修改,可能的值为"add", "update", or "delete"
  • -
  • oldValue: 对象修改前的值。该值只在"update""delete"有效。
  • -
  •  
  • -
-
-
acceptList
-
在给定对象上给定回调中要监视的变化类型列表。如果省略, ["add", "update", "delete", "reconfigure", "setPrototype", "preventExtensions"] 将会被使用。
-
-
-
- -

描述

- -

callback 函数会在对象被改变时被调用,其参数为一个包含所有修改信息的有序的数组对象。

- -

例子

- -

例子: 打印出三种不同操作类型的日志

- -
var obj = {
-  foo: 0,
-  bar: 1
-};
-
-Object.observe(obj, function(changes) {
-  console.log(changes);
-});
-
-obj.baz = 2;
-// [{name: 'baz', object: <obj>, type: 'add'}]
-
-obj.foo = 'hello';
-// [{name: 'foo', object: <obj>, type: 'update', oldValue: 0}]
-
-delete obj.baz;
-// [{name: 'baz', object: <obj>, type: 'delete', oldValue: 2}]
-
- -

例子: 数据绑定

- -
// 一个数据模型
-var user = {
-  id: 0,
-  name: 'Brendan Eich',
-  title: 'Mr.'
-};
-
-// 创建用户的greeting
-function updateGreeting() {
-  user.greeting = 'Hello, ' + user.title + ' ' + user.name + '!';
-}
-updateGreeting();
-
-Object.observe(user, function(changes) {
-  changes.forEach(function(change) {
-    // 当name或title属性改变时, 更新greeting
-    if (change.name === 'name' || change.name === 'title') {
-      updateGreeting();
-    }
-  });
-});
-
- -

规范

- -

Strawman proposal for ECMAScript 7.

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("36")}}{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("36")}}{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
-
- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/parent/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/parent/index.html deleted file mode 100644 index 8597b6c4a3..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/parent/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Object.prototype.__parent__ -slug: Web/JavaScript/Reference/Global_Objects/Object/Parent -tags: - - JavaScript - - 原型 - - 对象 - - 属性 - - 已废弃 - - 非标准 -translation_of: Archive/Web/JavaScript/Object.parent ---- -
{{JSRef}}{{Non-standard_Header}}{{Obsolete_Header("gecko2")}}
- -

The __parent__ property used to point to an object's context, but it has been removed.

- -

指向一个对象的上下文.

- -

语法

- -
obj.__parent__
- -

描述

- -

对于最顶层对象来说,这个属性的值就是全局对象 window。

- -

规范

- -

不属于任何规范。

- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.Object.parent")}}

- -

参见

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/unobserve/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/unobserve/index.html deleted file mode 100644 index bcae6ae8e7..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/unobserve/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Object.unobserve() -slug: Web/JavaScript/Reference/Global_Objects/Object/unobserve -translation_of: Archive/Web/JavaScript/Object.unobserve ---- -
{{JSRef}} {{non-standard_header}}
- -

Object.unobserve() 是用来移除通过 {{jsxref("Object.observe()")}}设置的观察者的方法。

- -

语法

- -
Object.unobserve(obj, callback)
- -

参数

- -
-
obj
-
需要停止观察的对象。
-
callback
-
通过 observer 给 obj 对象设置的回调函数.
-
- -

描述

- -

Object.unobserve() 用来在 {{jsxref("Object.observe()")}} 被调用以后,从对象上移除一个观察者。

- -

这个回调函数必须是一个函数的引用,而不能是一个匿名函数。因为这个引用将被用来移除之前设置的观察者方法。 给 Object.unobserve() 传入匿名函数作为回调是不起作用的, 它不能移除任何观察者方法。

- -

例子

- -

观察一个对象

- -
var obj = {
-  foo: 0,
-  bar: 1
-};
-
-var observer = function(changes) {
-  console.log(changes);
-}
-
-Object.observe(obj, observer);
-​
-obj.newProperty = 2;
-// [{name: 'newProperty', object: <obj>, type: 'add'}]
-
-Object.unobserve(obj, observer);
-
-obj.foo = 1;
-// 回调函数不会被调用
- -

使用匿名函数

- -
var person = {
-  name : 'Ahmed',
-  age : 25
-};
-
-Object.observe(person, function (changes) {
-  console.log(changes);
-});
-
-person.age = 40;
-// [{name: 'age', object: <obj>, oldValue: 25, type: 'update'}]
-
-Object.unobserve(person, function (changes) {
-  console.log(changes);
-});
-
-person.age = 63;
-// [{name: 'age', object: <obj>, oldValue: 40, type: 'update'}]
-// 回调函数将会被调用
-
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("36")}}{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("36")}}{{CompatNo}}{{CompatNo}}{{CompatOpera("23")}}{{CompatNo}}
-
- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/unwatch/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/unwatch/index.html deleted file mode 100644 index 986154992d..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/unwatch/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Object.prototype.unwatch() -slug: Web/JavaScript/Reference/Global_Objects/Object/unwatch -translation_of: Archive/Web/JavaScript/Object.unwatch ---- -
{{JSRef}}
- -
-

警告 : 请尽量避免使用 unwatch() 和  {{jsxref("Object.prototype.watch", "watch()")}} . 这两个方法仅在 Gecko 中实现 , 并且他们过去主要作调试用. 另外, 使用 watchpoints 对性能有一系列的副面影响 ,特别是当使用全局对象,如 window. 你应该使用  setters and getters 或 proxies 来替代. 查阅 {{anch("Browser compatibility")}} 以获取更多信息.

-
- -

unwatch() 删除一个 {{jsxref("Object.prototype.watch", "watch()")}} 设置的 watchpoint.

- -

语法

- -
obj.unwatch(prop)
- -

参数

- -
-
prop
-
想要停止监视的对象的属性名
-
- -

描述

- -

JavaScript调试器具有类似的功能,以及其他调试选项。有关调试器的信息  Venkman.

- -

默认地, 这个方法 被每一个 {{jsxref("Object")}} 的子类继承 

- -
-

Note: The reason for unwatch() to take the property name prop as its only parameter is due to the "single handler allowing" behavior of the {{jsxref("Object.watch", "watch()")}} method.

-
- -

例子

- -

See {{jsxref("Object.watch", "watch()")}}.

- -

说明

- -

Not part of any specifications. Implemented in JavaScript 1.2.

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

Compatibility notes

- - - -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/object/watch/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/watch/index.html deleted file mode 100644 index 540967eee3..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/watch/index.html +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: Object.prototype.watch() -slug: Web/JavaScript/Reference/Global_Objects/Object/watch -tags: - - Debugging - - Deprecated - - JavaScript - - Method - - Object - - Obsolete - - Prototype -translation_of: Archive/Web/JavaScript/Object.watch ---- -

{{JSRef}}

- -
-

警告: 通常来讲,你应该尽量避免使用 watch()和  {{jsxref("Object.prototype.unwatch", "unwatch()")}} 这两个方法。因为只有 Gecko 实现了这两个方法,并且它们主要是为了在调试方便。另外,使用 watchpoint 对性能有严重的负面影响,在全局对象(如 window)上使用时尤其如此。你可以使用 setters and getters 或者 proxy 代替。参见 {{ anch("Compatibility") }} 了解详情。

-
- -

watch() 方法会监视属性是否被赋值并在赋值时运行相关函数。

- -

语法

- -
obj.watch(prop, handler)
- -

参数

- -
-
prop
-
想要监视值是否发生变化的指定对象的某个属性的属性名称
-
- -
-
handler
-
当指定的属性发生变化时执行的回调函数
-
- -

返回值

- -

{{jsxref("undefined")}}.

- -

描述

- -

监视对指定对象的名为 prop 属性的赋值操作,只要 prop 属性被赋值,便调用 handler(prop, oldval, newval) 回调函数,并将函数返回值保存到该属性。 通过返回修改的新值(或者返回旧值),一个监视点可以过滤(或使之为 null )赋值。

- -

如果你删除某个设置监视点的属性,该监视点并不会消失。如果你之后重新创建这个属性,监视点仍然有效。

- -

要移除某个监视点,使用 unwatch() 方法。默认所有 Object 的后代都将继承 watch 方法。

- -

JavaScript 调试器有与之相似的机制以及其它调试选项。需要更多有关调试器的信息,请查阅 Venkman

- -

对于 Firefox,handler 只会被脚本内的赋值操作激活,并不包括本地代码。举个例子,如果用户点击一个指向当前文档内的某个锚点, window.watch('location', myHandler) 不会回调 myHandler ,但 window.location += '#myAnchor' 将触发回调  myHandler

- -
注意: 对一个对象的指定属性调用 watch()  将覆盖先前关联的 handler。
- -

例子

- -

使用 watchunwatch

- -
var o = {p:1};
-o.watch("p",
-  function (id, oldval, newval) {
-    console.log("o." + id + "由" + oldval + " 变为 " + newval);
-    return newval;
-  });
-
-o.p = 2;
-o.p = 3;
-delete o.p;
-o.p = 4;
-
-o.unwatch('p');
-o.p = 5;
-
- -

上面的代码显示结果如下:

- -
o.p 由 1 变为 2
-o.p 由 2 变为 3
-o.p 由 undefined 变为 4
-
- -

使用 watch 来验证一个对象的属性

- -

你可以使用 watch 来检测一个对象的属性赋值是否是合法的.下例演示了如何确保每个人始终具有一个合法的名字和0 到 200之间的年龄.

- -
Person = function(name,age) {
-  this.watch("age", Person.prototype._isValidAssignment);
-  this.watch("name", Person.prototype._isValidAssignment);
-  this.name = name;
-  this.age = age;
-}
-
-Person.prototype.toString = function() {
-  return this.name + ", " + this.age;
-};
-
-Person.prototype._isValidAssignment = function(id, oldval, newval) {
-  if (id === "name" && (!newval || newval.length > 30)) {
-    throw new RangeError("不合法的名字 " + this);
-  }
-  if (id === "age"  && (newval < 0 || newval > 200)) {
-    throw new RangeError("不合法的年龄 " + this);
-  }
-  return newval;
-}
-
-will = new Person("Will", 29);
-print(will);   // Will, 29
-
-try {
-  will.name = "";
-} catch (e) {
-  //print(e);
-  console.log(e);
-}
-
-try {
-  will.age = -4;
-} catch (e) {
-  console.log(e);
-}
-
- -

上面的代码显示结果如下:

- -
Will, 29
-RangeError: 不合法的名字 Will, 29
-RangeError: 不合法的年龄 Will, 29
-
- -

Specifications

- -

不是任何规范的一部分。从 JavaScript 1.2 开始实现。

- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

兼容性提示

- - - -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/parallelarray/index.html b/files/zh-cn/web/javascript/reference/global_objects/parallelarray/index.html deleted file mode 100644 index 739d25c173..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/parallelarray/index.html +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: ParallelArray -slug: Web/JavaScript/Reference/Global_Objects/ParallelArray -tags: - - JavaScript - - ParallelArray - - 过时 -translation_of: Archive/Web/ParallelArray ---- -

The goal of ParallelArray was to enable data-parallelism in web applications. The higher-order functions available on ParallelArray attempted to execute in parallel, though they may fall back to sequential execution if necessary. To ensure that your code executes in parallel, it is suggested that the functions should be limited to the parallelizable subset of JS that Firefox supports.

- -

语法

- -
new ParallelArray()
-new ParallelArray([element0, element1, ...])
-new ParallelArray(arrayLength, elementalFunction)
- -

ParallelArray instances

- -

属性

- -
-
length
-
Reflects the number of elements in the ParallelArray.
-
- -

方法

- -
-
map
-
reduce
-
scan
-
scatter
-
filter
-
flatten
-
partition
-
get
-
- -

示例

- -

Using map in parallel

- -
var p = new ParallelArray([0, 1, 2, 3, 4]);
-var m = p.map(function (v) {
-  return v + 1;
-});
- -

参见

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/quote/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/quote/index.html deleted file mode 100644 index 3d8d197f46..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/string/quote/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: String.prototype.quote() -slug: Web/JavaScript/Reference/Global_Objects/String/quote -tags: - - JavaScript - - Method - - Non-standard - - Obsolete - - Prototype - - String -translation_of: Archive/Web/JavaScript/String.quote ---- -
{{obsolete_header("37")}}
- -
{{JSRef("Global_Objects", "String")}}{{Non-standard_header}}
- -

概述

- -

将字符串中包含的特殊字符进行转义(反斜杠),然后在字符串两边各加上一个双引号(")并返回,并不修改原字符串.

- -

语法

- -
str.quote()
- -

示例

- - - - - - - - - - - - - - - - - - - - - - - - - - -
strstr.quote()eval(str.quote())
Hello world!"Hello world!"Hello world!
Hello
-         world!
"Hello\n\tworld!"Hello
-         world!
" \ — '"\" \\ \u2014 '"" \ — '
- -

规范

- -

不在任何规范中。实现于 JavaScript 1.3.

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html b/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html deleted file mode 100644 index 8bdfa28db2..0000000000 --- a/files/zh-cn/web/javascript/reference/operators/array_comprehensions/index.html +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: 数组推导式 -slug: Web/JavaScript/Reference/Operators/Array_comprehensions -tags: - - JavaScript - - Non-standard - - 参考 - - 运算符 -translation_of: Archive/Web/JavaScript/Array_comprehensions ---- -
-

非标准。不要使用!
- 数组推导是非标准的。以后应该用 {{jsxref("Array.prototype.map")}},{{jsxref("Array.prototype.filter")}},{{jsxref("Functions/Arrow_functions", "箭头函数", "", 1)}}和{{jsxref("Operators/Spread_operator", "展开语法", "", 1)}}.。

-
- -

{{jsSidebar("Operators")}} 

- -

数组推导式是一种 JavaScript 表达式语法,使用它,你可以在一个原有数组的基础上快速的构造出一个新的数组。但是它已经从标准和火狐中移除。不要用它!

- -

语法

- -
[for (x of iterable) x]
-[for (x of iterable) if (condition) x]
-[for (x of iterable) for (y of iterable) x + y]
-
- -

描述

- -

在数组推导式内部,可以使用下面两种子语句:

- - - -

每个 for-of 语句都放在与其配对的 if 语句(可以有多个,也可以完全省略)的左边,每个数组推导式中可以包含多组这样的配对,但最终选取的表达式值只能有一个,且这个值(也可以是个数组推导式,也就是说可以嵌套)只能放在推导式的最右边,紧靠着右中括号。

- -

示例

- -

基本的数组推导式写法

- -
[for (i of [ 1, 2, 3 ]) i*i ];
-// [ 1, 4, 9 ]
-
-var abc = [ "A", "B", "C" ];
-[for (letters of abc) letters.toLowerCase()];
-// [ "a", "b", "c" ]
- -

带有 if 语句的数组推导式

- -
var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
-
-[for (year of years) if (year > 2000) year];
-// [ 2006, 2010, 2014 ]
-
-[for (year of years) if (year > 2000) if(year < 2010) year];
-// [ 2006], 和下面的写法等效:
-
-[for (year of years) if (year > 2000 && year < 2010) year];
-// [ 2006]
-
- -

用数组推导式比用数组的 mapfilter 方法更简洁

- -

对比数组的 {{jsxref("Array.map", "map")}} 和 {{jsxref("Array.filter", "filter")}} 方法:

- -
var numbers = [ 1, 2, 3 ];
-
-numbers.map(function (i) { return i * i });
-[for (i of numbers) i*i ];
-// 返回值都是 [ 1, 4, 9 ]
-
-numbers.filter(function (i) { return i < 3 });
-[for (i of numbers) if (i < 3) i];
-// 返回值都是 [ 1, 2 ]
-
- -

带有两个数组的数组推导式

- -

用两个 for-of 语句迭代两个不同的数组:

- -
var numbers = [ 1, 2, 3 ];
-var letters = [ "a", "b", "c" ];
-
-var cross = [for (i of numbers) for (j of letters) i+j];
-// [ "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c" ]
-
-var grid = [for (i of numbers) [for (j of letters) i+j]];
-// [
-//  ["1a", "1b", "1c"],
-//  ["2a", "2b", "2c"],
-//  ["3a", "3b", "3c"]
-// ]
-
-[for (i of numbers) if (i > 1) for (j of letters) if(j > "a") i+j]
-// ["2b", "2c", "3b", "3c"],和下面的写法等效:
-
-[for (i of numbers) for (j of letters) if (i > 1) if(j > "a") i+j]
-// ["2b", "2c", "3b", "3c"]
-
-[for (i of numbers) if (i > 1) [for (j of letters) if(j > "a") i+j]]
-// [["2b", "2c"], ["3b", "3c"]],和下面的写法不等效:
-
-[for (i of numbers) [for (j of letters) if (i > 1) if(j > "a") i+j]]
-// [[], ["2b", "2c"], ["3b", "3c"]]
-
- -

规范

- -

最初起草在ECMAScript 6草案中,但在第27版(2014年8月)中被移除。 请参阅ES 6的旧修订版的规范语义。

- -

浏览器兼容性

- - - -

{{Compat("javascript.operators.array_comprehensions")}}

- -

同旧版的JS1.7/JS1.8数组推导的不同之处

- -

 

- -
JS1.7/JS1.8数组推导 在Gecko的46版本中已经被移除了 ({{bug(1220564)}}).
- -

旧版数组推导语法 (请不要再使用了!):

- -
[X for (Y in Z)]
-[X for each (Y in Z)]
-[X for (Y of Z)]
-
- -

不同点:

- - - -

点击查看 Bug 1220564, comment 42 并提出建设性建议.

- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html b/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html deleted file mode 100644 index e5dee577bc..0000000000 --- a/files/zh-cn/web/javascript/reference/operators/expression_closures/index.html +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Expression closures -slug: Web/JavaScript/Reference/Operators/Expression_closures -tags: - - Functions - - JavaScript - - Reference -translation_of: Archive/Web/JavaScript/Expression_closures ---- -
非标准,不要使用!
-闭包表达式语法是废弃的 SpiderMonkey 的特性,并且将被移除。为了长远使用,考虑使用箭头函数
- -
{{jsSidebar("Operators")}}
- -

表达式闭包是定义简单函数的一种便捷方式。

- -

语法

- -
function [name]([param1[, param2[, ..., paramN]]])
-   expression
-
- -

参数

- -
-
name
-
函数名。函数名可以省略不写,称为匿名函数。函数名仅在函数体有效。
-
paramN
-
形参名。一个函数最多可以有255个参数。
-
expression
-
构成函数体的表达式。
-
- -

描述

- -

这一附加特性只是编写简单函数的快捷方式,让语言更类似通常的 Lambda 标记

- -

JavaScript 1.7 及之前版本:

- -
function(x) { return x * x; }
- -

JavaScript 1.8:

- -
function(x) x * x
- -

该语法支持省略花括号和'return'语句。使用这种编码的目的只是为了在句法上使得代码更加简化,但除此之外没有其他好处。

- -

示例

- -

一种绑定事件监听器的便捷方式:

- -
 document.addEventListener("click", function() false, true);
-
- -

在 JavaScript 1.6 中的一些数组函数中使用该标记:

- -
elems.some(function(elem) elem.type == "text");
-
- -

浏览器兼容

- - - -

{{Compat("javascript.operators.expression_closures")}}

- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html b/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html deleted file mode 100644 index 1442d50019..0000000000 --- a/files/zh-cn/web/javascript/reference/operators/generator_comprehensions/index.html +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: Generator推导式 -slug: Web/JavaScript/Reference/Operators/Generator_comprehensions -translation_of: Archive/Web/JavaScript/Generator_comprehensions ---- -
非标准的。不要使用!
-generator推导式是非标准的,而且它不太可能会被添加到ECMAScript。考虑到将来,请使用 {{jsxref("Statements/function*", "generator", "", 1)}}。 -

 

-
- -

{{jsSidebar("Operators")}}

- -

生成器推导语法是一种JavaScript表达式,它允许您基于现有的可迭代对象快速组合新的生成器函数。

- -

许多编程语言中都存在推导。

- -

看下面,原来Generator推导式语法在SpiderMonkey的不同之处,它是基于对ECMAScript4的提议。

- -

语法

- -
(for (x of iterable) x)
-(for (x of iterable) if (condition) x)
-(for (x of iterable) for (y of iterable) x + y)
-
- -

描述

- -

在Generator推导式中,这两种构成方式都是允许的:

- - - -

for-of迭代器是构成的第一个部分。当由多重部分构成时,后面for-of和if构成方式都是被允许的。

- -

示例

- -

单个构成部分的 generator推导式:

- -
(for (i of [ 1, 2, 3 ]) i*i );
-// generator function which yields 1, 4, and 9
-
-[...(for (i of [ 1, 2, 3 ]) i*i )];
-// [1, 4, 9]
-
-var abc = [ "A", "B", "C" ];
-(for (letters of abc) letters.toLowerCase());
-// generator function which yields "a", "b", and "c"
-
-
- -

有if伴随的多重构成的gennerator推导式:

- -
var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
-
-(for (year of years) if (year > 2000) year);
-// generator function which yields 2006, 2010, and 2014
-
-(for (year of years) if (year > 2000) if(year < 2010) year);
-// generator function which yields 2006, the same as below:
-
-(for (year of years) if (year > 2000 && year < 2010) year);
-// generator function which yields 2006
-
- -

Generator推导式与Generator函数对比

- -

用一种简单的方式来理解generator推导式的语法并与generator函数来做个比较。

- -

Example 1: 仅是 generator.

- -
var numbers = [ 1, 2, 3 ];
-
-// Generator 函数
-(function*() {
-  for (let i of numbers) {
-    yield i * i;
-  }
-})()
-
-// Generator 推导式
-(for (i of numbers) i*i );
-
-// 结果: 两者都得到 yields [ 1, 4, 9 ]
-
- -

Example 2: 在 generator 中用if.

- -
var numbers = [ 1, 2, 3 ];
-
-// Generator 函数
-(function*() {
-  for (let i of numbers) {
-    if (i < 3) {
-      yield i * 1;
-    }
-  }
-})()
-
-// Generator 推导式
-(for (i of numbers) if (i < 3) i);
-
-// 结果: 两者都得到 yields [ 1, 2 ]
- -

规范

- -

Generator推导式是最初在ECMAScript 2015中进行拟稿,但是在14年8月27号修订中被移除了。 请参阅较旧版本的ES2015规范语义.

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{ CompatGeckoDesktop("30") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile("30") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

SpiderMonkey的具体实现笔记

- - - -

与旧的JS1.7 / JS1.8理解的区别

- - - -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/statements/for_each...in/index.html b/files/zh-cn/web/javascript/reference/statements/for_each...in/index.html deleted file mode 100644 index 05c1043588..0000000000 --- a/files/zh-cn/web/javascript/reference/statements/for_each...in/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: for each...in -slug: Web/JavaScript/Reference/Statements/for_each...in -translation_of: Archive/Web/JavaScript/for_each...in ---- -
{{jsSidebar("Statements")}}
- -

使用一个变量迭代一个对象的所有属性值,对于每一个属性值,有一个指定的语句块被执行。

- -
-
-

作为ECMA-357(E4X)标准的一部分,for each...in语句已被废弃,E4X中的大部分特性已被删除,但考虑到向后兼容,for each...in只会被禁用而不会被删除,可以使用ES6中新的for...of语句来代替。({{ bug("791343")}}.)

-
- -
for each...inECMA-357 (E4X) 标准的一部分,大部分非Mozilla浏览器都没有实现该标准,E4X并不是 ECMAScript 标准的一部分。
-
- -

语法

- -
for each (variable in object) {
-  statement
-}
- -

参数

- -
-
variable
-
用来遍历属性值的变量,前面的var关键字是可选的。该变量是函数的局部变量而不是语句块的局部变量。
-
- -
-
object
-
属性值会被遍历的对象。
-
- -
-
statement
-
遍历属性时执行的语句。如果想要执行多条语句,请用块语句({ ... }) 将多条语句括住。
-
- -

描述

- -

一些对象的内置属性是无法被遍历到的,包括所有的内置方法,例如String对象的indexOf方法。不过,大部分的用户自定义属性都是可遍历的.

- -

示例

- -

例子: 使用for each...in

- -

警告:永远不要使用for each...in语句遍历数组,仅用来遍历常规对象。这里讲解了为什么这么说

- -

下面的代码片段演示如何遍历一个对象的属性值,并计算它们的和:

- -
var sum = 0;
-var obj = {prop1: 5, prop2: 13, prop3: 8};
-
-for each (var item in obj) {
-  sum += item;
-}
-
-print(sum); // 输出"26",也就是5+13+8的值
- -

参见

- - diff --git a/files/zh-cn/web/rdf/index.html b/files/zh-cn/web/rdf/index.html deleted file mode 100644 index df76c59ae3..0000000000 --- a/files/zh-cn/web/rdf/index.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: RDF -slug: Web/RDF -tags: - - RDF -translation_of: Archive/Web/RDF ---- -

 

-
-

资源说明框架(RDF) 是一个元数据模型规范,常用来实现XML应用。该规范由万维网联盟(W3C).

-

RDF元数据模型想把外观中的资源建立声明,该声明是一个主题-断言-对象的表达,在RDF术语中被称为triple。这个主题是一个被描述的资源。描述的是该资源的特征或外观,并常表现为这个主题和对象之间的一个关系。而这个对象是某个关系对象或是某个特征的值。 {{ Ref("one") }}

-
- - - - - - - -
-

文档

-
-
- Mozilla RDF 引擎指导
-
- This presentation shows new developments in the Mozilla RDF engine. These include plans to expose the RDF API to public web content, as well as performance and correctness improvements.
-
-
-
- RDF是什么
-
- Tim Bray's introduction to the Resource Description Framework, at XML.com.
-
-
-
- RDF 问题集
-
- Frequently asked questions about the Resource Description Framework in Mozilla.
-
-
-
- RDF 简介
-
- A quick introduction to the Resource Description Framework.
-
-
-
- RDF 数据源 How-To
-
- A cookbook-style document describing how to create a native, client-side datasource that works with Mozilla's RDF implementation.
-
-
-
- 收集 In-Memory 数据源
-
- Using the XPCOM aggregation with the in-memory datasource.
-
-

View All...

-
-

社区

-
    -
  • 到 Mozilla 论坛...
  • -
-

{{ DiscussionList("dev-tech-rdf", "mozilla.dev.tech.rdf") }}

- -

工具

- -

相关主题

-
-
- XML
-
-
-

Categories

-

Interwiki Language Links

-

 

-

{{ languages( { "en": "en/RDF", "de": "de/RDF", "es": "es/RDF", "fr": "fr/RDF", "it": "it/RDF", "ja": "ja/RDF", "ko": "ko/RDF", "pl": "pl/RDF", "pt": "pt/RDF", "ru": "ru/RDF" } ) }}

diff --git "a/files/zh-cn/web/security/information_security_basics/tcp_ip_\345\256\211\345\205\250/index.html" "b/files/zh-cn/web/security/information_security_basics/tcp_ip_\345\256\211\345\205\250/index.html" deleted file mode 100644 index 5a8c1a68b0..0000000000 --- "a/files/zh-cn/web/security/information_security_basics/tcp_ip_\345\256\211\345\205\250/index.html" +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: TCP/IP 安全 -slug: Web/Security/Information_Security_Basics/TCP_IP_安全 -translation_of: Archive/Security/TCP_IP ---- -

{{draft}}

- -

TCP/IP 在全世界被广泛应用于提供网络通信。  TCP/IP 通信由四个工作层组成。当用户想要通过网络传输数据时,数据就会从更高层通过中间层逐渐传递到最底层,每层都会添加对应的信息。在每一层, 逻辑单元通常由标头和有效载荷组成。有效载荷由上一层传递下来的信息组成,而头部包含特定于层的信息,例如地址。在应用程序层,有效负载是实际的应用程序数据。最底层通过物理网络发送累积数据;然后,数据通过层向上传递到目的地。基本上,由层生成的数据通过其下面的层封装在更大的容器中。从最高到最低的四个TCP / IP层如下所示。

- - - -

存在用于TCP / IP模型的每一层的网络通信的安全控制。如前所述,数据从最高层传递到最低层,每层添加更多信息。因此,较高层的安全控制不能为较低层提供保护,因为较低层执行较高层不知道的功能。每层可用的安全控制包括:

- - - -

由于它们可以同时为许多应用程序提供保护而无需对其进行修改,因此经常使用网络层安全控制来保护通信,尤其是在诸如因特网的共享网络上。网络层安全控制提供单一解决方案,用于保护所有应用程序的数据,以及保护IP信息。然而,在许多情况下,另一层的控制比网络层控制更适合提供保护。例如,如果只有一个或两个应用程序需要保护,则网络层控制可能过多。 SSL等传输层协议最常用于为与各个基于HTTP的应用程序进行通信提供安全性,但它们也用于为其他类型的应用程序(如SMTP,存在点(POP),Internet)的通信会话提供保护。消息访问协议(IMAP)和文件传输协议(FTP)。由于所有主要的Web浏览器都包含对TLS的支持,因此希望使用受TLS保护的基于Web的应用程序的用户通常不需要安装任何客户端软件或重新配置其系统。传输层安全协议的较新应用程序保护HTTP和非HTTP应用程序通信,包括客户端/服务器应用程序和其他网络流量。每一层的控件都提供了其他层控件的优点和功能。

- -

SSL是最常用的传输层安全控制。根据SSL的实现和配置方式,它可以提供以下类型的保护的任意组合:

- - - - - -
-

Original Document Information

- - -
- -

{{QuickLinksWithSubpages("/en-US/docs/Web/Security")}}

diff --git a/files/zh-cn/web/security/information_security_basics/vulnerabilities/index.html b/files/zh-cn/web/security/information_security_basics/vulnerabilities/index.html deleted file mode 100644 index e060234976..0000000000 --- a/files/zh-cn/web/security/information_security_basics/vulnerabilities/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Vulnerabilities -slug: Web/Security/Information_Security_Basics/Vulnerabilities -translation_of: Archive/Security/Vulnerabilities ---- -
-

本文讨论漏洞,解释它们是什么以及它们在所有系统中的存在方式。

-
- -

漏洞是系统中的一个弱点,可被利用来对机密性,完整性和可用性产生负面影响。 可以通过多种方式对漏洞进行分类。 本文使用三个高级漏洞类别:软件缺陷,安全配置问题和软件功能滥用。 这些类别如下所述。

- -

漏洞级别

- -

 

- -

软件缺陷是由软件设计或编码中的意外错误引起的。比如输入验证错误,假如用户提供的输入未正确评估恶意字符串和与已知攻击相关的过长值。另一个示例是竞争条件错误,允许攻击者使用提升的权限执行特定操作。

- -

安全配置设置是软件安全性的一个元素,可以通过软件本身进行更改。设置的示例是提供对控制列表的访问的操作系统,该控制列表设置用户对文件的特权,以及提供用于启用或禁用由应用程序存储的敏感数据的加密的设置的应用程序。安全配置问题漏洞涉及使用对软件安全性产生负面影响的安全配置设置。

- -

软件功能是由软件提供的功能功能。软件功能滥用漏洞是一种漏洞,其中该功能还提供了破坏系统安全性的途径。这些漏洞是由软件设计者做出的信任假设允许软件提供有益的功能,同时也引入某人违反信任假设以破坏安全性的可能性引起的。例如,电子邮件客户端软件可能包含在电子邮件消息中呈现HTML内容的功能。攻击者可以制作包含超链接的欺诈性电子邮件,这些超链接在以HTML格式呈现时对收件人来说是良性的,但实际上在收件人点击时会将收件人带到恶意网站。 HTML内容呈现功能设计中的一个信任假设是用户不会收到恶意超链接并点击它们。

- -

在软件设计或软件组件(例如,软件实现的协议)期间引入软件特征滥用漏洞。信任假设可能是明确的 - 例如,设计者意识到安全漏洞并确定单独的安全控制会对其进行补偿。但是,信任假设通常是隐含的,例如创建特征而不首先评估它将引入的风险。威胁也可能在软件的生命周期或软件中使用的协议中发生变化。例如,地址解析协议(ARP)信任ARP回复包含媒体访问控制(MAC)和Internet协议(IP)地址之间的正确映射。 ARP缓存使用该信息提供有用的服务 - 以便在本地网络内的设备之间发送数据。但是,攻击者可能会生成错误的ARP消息来中毒系统的ARP表,从而发起拒绝服务或中间人攻击。 ARP协议在25年前已经标准化,从那时起威胁发生了很大的变化,因此其设计中固有的信任假设今天不太可能合理。

- -

可能很难将软件功能滥用漏洞与其他两个类别区分开来。例如,软件设计过程中的缺陷可能导致软件缺陷和滥用漏洞。但是,软件缺陷纯粹是消极的 - 它们对安全性或功能没有任何积极的好处 - 而软件特性由于提供额外的功能而导致滥用漏洞。

- -

对于可以启用或禁用的功能的滥用漏洞,可能存在混淆 - 在某种程度上,配置与安全配置问题。关键的区别在于,对于滥用漏洞,配置设置启用或禁用整个功能,并不特别改变其安全性;对于安全配置问题漏洞,配置设置仅更改软件的安全性。例如,禁用电子邮件中所有HTML使用的设置会对安全性和功能产生重大影响,因此与此设置相关的漏洞将是滥用漏洞。禁用电子邮件客户端中使用反网络钓鱼功能的设置仅对安全性有重大影响,因此具有该设置的漏洞将被视为安全配置问题漏洞。

- -

 

- -

The Presence of Vulnerabilities

- -

No system is 100% secure: every system has vulnerabilities. At any given time, a system may not have any known software flaws, but security configuration issues and software feature misuse vulnerabilities are always present. Misuse vulnerabilities are inherent in software features because each feature must be based on trust assumptions—and those assumptions can be broken, albeit involving significant cost and effort in some cases. Security configuration issues are also unavoidable for two reasons. First, many configuration settings increase security at the expense of reducing functionality, so using the most secure settings could make the software useless or unusable. Second, many security settings have both positive and negative consequences for security. An example is the number of consecutive failed authentication attempts to permit before locking out a user account. Setting this to 1 would be the most secure setting against password guessing attacks, but it would also cause legitimate users to be locked out after mistyping a password once, and it would also permit attackers to perform denial-of-service attacks against users more easily by generating a single failed login attempt for each user account.

- -

Because of the number of vulnerabilities inherent in security configuration settings and software feature misuse possibilities, plus the number of software flaw vulnerabilities on a system at any given time, there may be dozens or hundreds of vulnerabilities on a single system. These vulnerabilities are likely to have a wide variety of characteristics. Some will be very easy to exploit, while others will only be exploitable under a combination of highly unlikely conditions. One vulnerability might provide root-level access to a system, while another vulnerability might only permit read access to an insignificant file. Ultimately, organizations need to know how difficult it is for someone to exploit each vulnerability and, if a vulnerability is exploited, what the possible impact would be.

- -
-

Original Document Information

- - -
- -

{{QuickLinksWithSubpages("/en-US/docs/Web/Security")}}

diff --git "a/files/zh-cn/web/security/information_security_basics/\346\234\272\345\257\206\346\200\247\343\200\201\345\256\214\346\225\264\346\200\247\345\222\214\345\217\257\347\224\250\346\200\247/index.html" "b/files/zh-cn/web/security/information_security_basics/\346\234\272\345\257\206\346\200\247\343\200\201\345\256\214\346\225\264\346\200\247\345\222\214\345\217\257\347\224\250\346\200\247/index.html" deleted file mode 100644 index 2c415ae3ea..0000000000 --- "a/files/zh-cn/web/security/information_security_basics/\346\234\272\345\257\206\346\200\247\343\200\201\345\256\214\346\225\264\346\200\247\345\222\214\345\217\257\347\224\250\346\200\247/index.html" +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: 机密性、完整性和可用性 -slug: Web/Security/Information_Security_Basics/机密性、完整性和可用性 -translation_of: 'Archive/Security/Confidentiality,_Integrity,_and_Availability' ---- -
-

这篇文章讨论Web安全的三个主要目标:机密性、完整性和可用性。

-
- -

传统的关于信息安全的模型定义了三个Web安全的目标:保持机密性、完整性和可用性。每一个目标都阐述了信息安全的不同方面。

- -

机密性

- -

机密性指信息指在未验证状态下信息不能被用户获取。也就是说,只有被验证过的用户才能获得敏感数据。联想下你的银行卡,你是授权可以访问的,但是,银行的雇员们也可以访问,其他人不行。机密性不高也就意味着原本不能访问这些信息的人却能够获取到这些信息,不管是有意为之还是由于突发事故。保密失败,也就是通常所说的泄密,通常是很难被根治的。一旦秘密被泄露了,就不能重新加密它。如果你的银行账号被贴到了一个公共的网站上,每一个人就都能知道你的银行账号,收入等,而且这些信息并不会从他们的心里,纸上,电脑或者其他地方清除。今天几乎凡是媒体上报道的安全事故,都涉及到重大的机密损失。

- -

总的来说,机密信息的泄露指的就是本不能访问它的人却获得了这些信息。

- -

完整性

- -

完整性表示,经过验证的用户访问数据时,数据没有发生过任何改动,是原生的数据。想象下你有一个网站,并在上面出售商品。这时一个黑客在浏览你的网站,并恶意的修改了你产品的价格,这样一来,他就能够以任意的价格购买任何东西。这就是一个保护完整性的反面案例。因为你的信息--这个场景下,就是商品的价格--被修改了,而且你没有授权这一次变更。另一个反面案例,当你在连接一个网站的时候,攻击者重定向了你的传输到另外一个网站。在这种情况下,你被指向的网站并不是真实可靠的。

- -

可用性

- -

可用性指被验证过的用户可以轻易获得信息。

- -
-

初始文档信息

- - -
diff --git a/files/zh-cn/web/security/site_identity_button/index.html b/files/zh-cn/web/security/site_identity_button/index.html deleted file mode 100644 index fff6661ffd..0000000000 --- a/files/zh-cn/web/security/site_identity_button/index.html +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Site Identity Button -slug: Web/Security/Site_Identity_Button -tags: - - 安全 - - 火狐 -translation_of: Mozilla/Firefox/Site_identity_button ---- -

 Site Identity Button 是火狐的一个特性,用于向用户提示更多他们已经访问过的网站的信息。

- -

这个特性的使用取决于你网站的配置,按钮会显示许多不同的图标。

- -

如果站点身份按钮没有按照您的配置显示出来的话(如你想要看到一个绿色的锁却显示一个橙色的三角图标),你可以打开火狐开发者工具的控制台,在控制台里能找到一些原因:

- -
    -
  1. 确定您的控制台在'security'目录下显示信息。
  2. -
  3. 强制刷新有问题的站点
  4. -
  5. 耐心等待可能会出现的一些安全信息
  6. -
- -

由于以下的原因之一,UI的安全等级将会降低:

- - diff --git a/files/zh-cn/web/svg/faq/index.html b/files/zh-cn/web/svg/faq/index.html deleted file mode 100644 index 59ca239079..0000000000 --- a/files/zh-cn/web/svg/faq/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: 与SVG、Mozilla有关的常见问题 -slug: Web/SVG/FAQ -tags: - - SVG - - SVG FAQ - - 需要更新 -translation_of: Archive/Mozilla/SVG_FAQ ---- -
注意:这个页面可能有点过时了。
- -

SVG的编译器正处于哪种状态?

- -

我们目前维护了两个文档用来帮助回答这个问题:status page for SVG in Firefox 1.5+ 和 a status page for SVG in the development trunk.

- -

为什么Mozilla会显示源代码或乱码,而不是显示SVG图像?

- -

这有两种可能的原因:SVG文件中有一个小错误,或者服务器配置不对。

- -

如果源码的顶部有灰色区域,灰色区域里有文字“This XML file does not appear to have any style information associated with it(该XML文件找不到任何与它关联的样式信息)”,则问题是与SVG关。作为一个合未能的根SVG文件中的<svg>标签,必须至少跟随两个“命名空间绑定”。

- -
<svg xmlns="http://www.w3.org/2000/svg"
-xmlns:xlink="http://www.w3.org/1999/xlink">
-
- -

实际上第二个绑定并非总是必要的,但是除非你了解命名空间,我们强烈建议你包含它。欲了解更多信息,请看这个链接

- -

If source code is displayed without a gray area at the top, or if you just see gibberish, then the problem is server misconfiguration. When servers send user agents an SVG file they must tell the user agent that the file has the MIME type "image/svg+xml", and if the SVG file is stored gzipped they must tell the browser that too. Mozilla is strict about this, and no, it's not a bug. Failing to respect the MIME types servers send is incorrect and has been a source of security holes in other browsers. Mozilla will not be changing this behaviour. For more information on server configuration for SVG see this link.

- -

为什么Mozilla显示一个“XML解析错误”消息,而不是显示SVG?

- -

This is an XML debugging message to help XML authors correct errors in their XML documents. Mozilla will show this message when there's an XML well formedness error in the file it tried to load. (It doesn't mean there's an error in Mozilla.) There are many different XML errors, but the most common one in SVG files is "XML Parsing Error: prefix not bound to a namespace". This is (almost certainly) because the 'xmlns:xlink' attribute has been used in the file without including the following two namespace bindings on the root <svg> tag.

- -
<svg xmlns="http://www.w3.org/2000/svg"
-xmlns:xlink="http://www.w3.org/1999/xlink">
-
- -

确保你的所有的SVG文件都绑定了它。欲了解更多信息请阅读这个链接

- -

为什么我们被要求选择一个程序以打开SVG文件?

- -

When you try to load SVG files from some websites you may get a dialogue asking you "What should Firefox do with this file?". This is either because your browser doesn't support SVG (you must have Mozilla Firefox 1.5 or newer), or because the webpage/server isn't correctly telling Mozilla that the file contains SVG. For example, webpages that embed SVG using the <object> or <embed> tags must have a 'type' attribute assigned with the correct SVG MIME type of "image/svg+xml". If the MIME type specified is wrong (for example image/svg-xml) Mozilla won't recognise it. If that isn't the problem, then it may be that the server hosting the website is misconfigured. For information on configuring servers for SVG see this link.

- -

为什么我被要求安装一个插件以查看SVG文件?

- -

This is probably because there is an <embed> or <object> tag in the HTML page and its 'type' attribute is set to the wrong MIME type. The SVG MIME type is image/svg+xml (not image/svg-xml or anything else for that matter). Correct this mistake or ask the document maintainer to correct it.

- -

我需要如何在Mozilla SVG中报告bug?

- -

If you discover any problems with our SVG implementation that you think we should know about then we'd like to hear from you. To help us make the best use of our time, please first search in the SVG component of our bug database to check that the issue hasn't already been reported. If you can't find a matching bug please file a new SVG bug report, preferably attaching a (very small!) SVG file that demonstrates the bug. If you have any problems with the bug database feel free to contact contact us.

- -

我可以使用一个SVG的插件代替Mozilla的原生支持吗?

- -

Individuals can choose to use a plugin to view SVG in Mozilla on their own computers, but there is no way for SVG content authors to make Mozilla use a plugin when people view the SVG files on their website. The native SVG support must be turned off before Mozilla will look to see if there's an SVG plugin installed. This is done by toggling a hidden user configuration preference (pref). To access the pref type about:config into the URL bar, then type svg.enabled into the Filter field. When you double click on the pref you will see its value change to and from true/false, turning the native support on/off.

- -

Mozilla的SVG编译器与Adobe的编译器相比如何?

- -

Mozilla's native implementation is less complete than Adobe SVG Viewer's in general. There are major features such as filters and SMIL based animation that have still to be implemented in Mozilla. However, Mozilla's implementation already supports some things that Adobe's lacks, particularly parts of the XML and SVG DOMs. For example we support SVG exceptions and SVGTransform objects.

- -

你该如何在Mozilla中安装Adobe的SVG浏览器?

- -

The SVG project is about Mozilla's native implementation of SVG, not Adobe/Corel/whoever's plug-in. However, we might as well answer this question to save you searching for this information elsewhere. See these install instructions on mozdev.org. It's also useful to know that you can check whether Mozilla has recognised your plug-ins by typing 'about:plugins' into your address bar (linking to that doesn't work for security reasons).

- -

Mozilla可以与Corel的SVG插件共事吗?

- -

There are reports that it does, but that it's slower than the Adobe plug-in. See this document for information on how to install it.

- -

原生SVG支持以及SVG插件安装可以共存的吗?

- -

Yes. If the plug-in works with the equivalent non-SVG version of Mozilla, then it should also work in the SVG enabled version. To be able to use it, you must make sure the svg.enabled pref is set to false. This will disable the native SVG support.

- -

<embed> 标签支持SVG文档吗?

- -

Yes. As of 2004-11-11, builds with native SVG support will use the native support to render SVG documents that are embeded by reference into an HTML document using the <embed> tag. Note that this capability was added to support legacy content. The <object> tag should be used in preference to the <embed> tag in new content whenever possible.

- -

The first milestone builds that will have this support will be SVG enabled builds of Firefox 1.5.

- -

我可以为SVG项目做什么?

- -

Okay so maybe this isn't such a frequently asked question, but if it was, just think how much further on with our SVG implementation we could be! We're always looking for help from anyone willing to lend a hand. If you're a C++ programmer interested in working on the SVG implementation, please contact us and we'll be happy to help you get involved. Alternatively, if you're an SVG user you can help by testing the SVG enabled nightlies and filing bugs with minimal testcases whenever you encounter a problem. If you can't do either of these things you should still feel free to ask us friendly questions and give us constructive feedback.

- -

当前在做什么工作?

- -

Other than reviewing patches and fixing the occassional bug, Alex is currently taking a break from active SVG development to concentrate on 'real work' and cool stuff like XTF and JSSh. Tim is working on implementing <filter> and working on items that need to be done before turning on SVG by default. After recently implementing gradients, Scooter is working on fixing some issues that remain outstanding and fixing <switch>. Jonathan is working on various bugs, especially those that need to be fixed before SVG can be enabled in the official builds. David continues to create SVG enabled nightlies and answer build related questions as he has done for some time. Finally, occasional fixes are provided by other Mozilla hackers.

- -

怎样和你联系?

- -

The best way to get in contact with us is to join the #svg channel on mozilla.org's IRC server. This is where most of us hang out to discuss issues relating to the SVG implementation. If you don't have an IRC client then install ChatZilla into Mozilla/Mozilla Firefox (note it may already be built in). Clicking on the link above should then take you straight there. If you'd prefer to contact us by email you can send an email to our newsgroup mozilla.dev.tech.svg which is archived here. Alternatively you can email any of us directly of course (see the preceeding question for our email addresses).

- -
-

Original Document Information

- - -
- -

{{ languages( { "ja": "ja/Mozilla_SVG_Project_FAQ" } ) }}

diff --git "a/files/zh-cn/web_development/\345\223\215\345\272\224\345\274\217_web_\350\256\276\350\256\241/index.html" "b/files/zh-cn/web_development/\345\223\215\345\272\224\345\274\217_web_\350\256\276\350\256\241/index.html" deleted file mode 100644 index af96643b53..0000000000 --- "a/files/zh-cn/web_development/\345\223\215\345\272\224\345\274\217_web_\350\256\276\350\256\241/index.html" +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: 响应式 Web 设计 -slug: Web_Development/响应式_Web_设计 -tags: - - Web开发 - - 响应式设计 -translation_of: Web/Progressive_web_apps ---- -

随着越来越多的用户使用移动设备来浏览网站和应用,Web设计人员和开发人员需要确保他们的作品在移动设备上同样能正常运作,并且看上去和在传统台式电脑上一样好。 著名设计师 Luke Wroblewski 主张 "移动优先" 设计而不是为桌面端设计完之后再考虑移动端。 无论您将移动设备作为主要目标来设计或作为额外目标,您都可以借助强大的CSS来保证同样的内容从手机到宽屏高分辨率显示器上,实现跨全部硬件平台访问和适应。

- -

这种方法被称为“响应式 Web 设计”。它的一些策略包括::

- - - -

Firefox Marketplace 的最低需求

- -

如果您提交一个应用到 Firefox OS 或 Firefox for Android 上的Firefox Marketplace,那么这个应用必须响应不同的手机屏幕尺寸和屏幕像素密度。请记住屏幕最小尺寸为 320 * 480 像素。另一个常见的错误是未识别屏幕像素密度,以至于没有相应地调整字体大小和触摸目标。欲了解更多信息, 请参阅 Marketplace 审查准则

- -

相关资源

- -

概述

- - - -

技术文档

- - - -

工具

- - - -

样例

- - - -

diff --git a/files/zh-cn/window_icons/index.html b/files/zh-cn/window_icons/index.html deleted file mode 100644 index 9ccb58bf19..0000000000 --- a/files/zh-cn/window_icons/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: chrome window icons -slug: Window_icons -tags: - - Extensions - - Toolkit API - - XPInstall - - XUL -translation_of: Archive/Mozilla/XUL/Window_icons ---- -

 

-

Starting with Firefox 1.5, Thunderbird 1.5, and XULRunner 1.8, you can specify an icon for a XUL window by putting files named <tt>mywindow.ico</tt> (for Windows) and <tt>mywindow.xpm</tt> (Linux), where mywindow is the id of the <window> you want to attach the icon to, in the <tt>chrome/icons/default</tt> subfolder of your bundle.

-

These icons will override the global icon files, which are located in <tt> - - app_dir - /chrome/icons/default</tt>.

-

Older versions

-

为了支持早期版本, 比如 Firefox 1.0, 你必须在第一次运行时手工拷贝图标到<tt> - - app_dir - /chrome/icons/default</tt> (example code).

-

diff --git a/files/zh-cn/working_with_bfcache/index.html b/files/zh-cn/working_with_bfcache/index.html deleted file mode 100644 index 1b03206e23..0000000000 --- a/files/zh-cn/working_with_bfcache/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Working with BFCache -slug: Working_with_BFCache -tags: - - bug-840092 -translation_of: Archive/Misc_top_level/Working_with_BFCache ---- -

Q: 什么是BFCache?

-

A: BFCache的意思是“后退前进缓存“(back-forward cache).查看如何使用Firefox的缓存了解更多详情.

-

Q: 当用户点击一个链接,当前标签中的页面跳转到一个新的页面之后,再点击浏览器的”后退“按钮,这时发生了什么?

-

A: The outer nsIDOMWindow (the |window| object in content JS, aka the <browser>'s contentWindow object in the parent document) stays right where it is.  It just has its inner window and document replaced.

-

The inner nsIDOMWindow (the global scope object in content JS) is either thrown away when GC happens, or frozen and placed in the bfcache.  When the user hits the 'back' button, either the window in bfcache is thawed or a new inner window is created, depending on whether there's a window in the bfcache.

-

Q: Is the page reloaded? loaded from cache? or is the DOM saved in some way as if the window was there but invisible? Are scripts recompiled? Where do they live while the page was invisible?

-

A: In the non-bfcache case, the page is reloaded in the sense of reparsing from the original HTML source.  That might come from the HTTP cache or not, depending on whether it's been evicted; typically it does come from the HTTP cache.  The DOM is recreated during the parsing process, scripts are recompiled (and also reloaded, probably from the HTTP cache).

-

In the bfcache case, freezing the window just marks it as frozen; the DOM is preserved, as are compiled script objects.  Thawing marks it as thawed.  Freezing suspends timeouts and interval timers on the frozen window, so they won't execute.  The script that's running when the window is frozen runs to completion, as it would if it were being closed, for example.  After that, only scripts running on other windows can touch this window; if they modify the DOM, the cached DOM and window is thrown away.

-

Q: 我们可以使用pagehide/pageshow事件来检测BFCache的使用情况,对吗?

-

A: 对.pagehide事件可以告诉你这个页面什么时候进入了bfcache,pageshow事件可以告诉你这个页面什么时候从bfcache中读取了出来.和其他缓存一下,这个页面存在有bfcache并不意味着这个bfcache一定会被用到.

-

Q: Hmm, so what event tells me “you'll never get a pageshow so you can drop the megabytes of info you've saved in Firebug side table for that page?”

-

A: An observer notification with the topic "inner-window-destroyed" whose subject is an nsISupportsPRUint64 containing the window id of the inner window being destroyed.

diff --git a/files/zh-cn/xml_extras/index.html b/files/zh-cn/xml_extras/index.html deleted file mode 100644 index 6cf0a9db32..0000000000 --- a/files/zh-cn/xml_extras/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: XML Extras -slug: XML_Extras -tags: - - XML -translation_of: Mozilla/Tech/XML_Extras ---- -

 

-

The XML Extras module contains several features that allow developers to treat XML as data i.e. not as just another document format. The module is structured as a drop-in component and exposes its XML-as-data features both to JavaScript and C++/XPCOM users. The XML Extras module is built by default on all platforms, and is included in the browser installers so it is available in the nightly builds.

-

Feature Status

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureStatus
XMLSerializerAvailable
XMLHttpRequestAvailable
DOMParser (string and stream input source)Available
Web Services with SOAP and WSDLAvailable since 1.4alpha. Moved to Web Services module during 1.4beta.
XML Persistence 
FIXptr and XPointerAvailable since 1.4alpha in the core Mozilla. Moved to XMLExtras during 1.4beta.
-

See also:

- -

QA and Testing

-

There are some online tests for mainly exercising the HTTP GET method via XMLHttpRequest.

-

Other test cases for each of the implemented components listed above exist in extensions/xmlextras/tests/. More exhaustive test suites need to be created, however. If you'd like to help out with QA, you can do one of the following:

- -

Documentation

-

Probably the best way to learn how to use these technologies is through examples. There are some in extensions/xmlextras/tests/. If you follow that link to look at the examples you will need to look at page source for the HTML documents.

-

For XMLHttpRequest object you can mostly rely on the Microsoft XMLHttpRequest documentation, with some caveats: all functions and property names begin with a lower case letter and the object creation is different. Some properties are not implemented.

-

Thad Hoffman has written a document that shows how you can mimic XML Data Islands in Mozilla. Edmond Woychowsky has also written articles on XML Data Islands in Mozilla: "Make XML data islands work in Mozilla", "Build cross-browser XML paging code" and "Implement a flexible shopping cart with XML and ASP". The Mozilla Developer Center has several pages for XMLHttpRequest.

-

Below are some key differencies in "XML Extras" between Mozilla and Microsoft software:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DifferenceMicrosoftMozilla
Member namesCase insensitive?Begins with lower case letter
XMLHttpRequest Creationnew ActiveXObject("Msxml2.XMLHTTP")new XMLHttpRequest()
XMLHttpRequest.send("some string")okok starting with milestone 0.9.7 (actually nightly 2001-11-28). With older builds, passing strings to send() works only in chrome, see post.html sample. The "workaround" is to use DOMParser object's parseFromString() method to create a document from string, and pass the temporary document into send().
XMLHttpRequest.open("aHost")ok<tt>file://</tt> documents can access <tt>http://</tt> documents but you need to enable UniversalBrowserRead privilege in your scripts - see the JavaScript Security: Signed Scripts document for more details. Normally your files should reside on a webserver so this shouldn't pose a problem (there you do not need that line either). Additionally, "foo.com:80" and "foo.com:313" are considered different hosts for security purposes. You cannot open a connection to a different host.
DOMParser Creationnot availablenew DOMParser()
XMLSerializer Creationnot availablenew XMLSerializer()
-

Minimal documentation for the components listed above can be found using Mozilla documentation generated by Doxygen. File new bugs for additional documentation contributions, either specifically aimed at JavaScript developers or to complete & clarify the JavaDoc-style comments in the IDL files.

- -

Please see the XML Linking and Pointing section in XML in Mozilla document for FIXptr and XPointer documentation.

-

How can I help?

- diff --git a/files/zh-cn/xml_web_services/index.html b/files/zh-cn/xml_web_services/index.html deleted file mode 100644 index f14736a4d2..0000000000 --- a/files/zh-cn/xml_web_services/index.html +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: XML Web Services -slug: XML_Web_Services -tags: - - XML Web Services -translation_of: Archive/Mozilla/Firefox/SOAP_in_Gecko-based_Browsers ---- -

-

-
The Basics of Web Services
-A short introduction to web services.
-
XML Web Service是一组用于程序或系统之间交换数据的协议与标准。用不同语言编写的,在不同平台下运行的软件应用可以使用Web Service在计算机网络中(如因特网),像在本机的进程之间一样交换数据。在XML Web Service中,所有需要交换的数据使用XML标记。 -. {{ Ref(1) }}
- - -
-

相关文档

-
SOAP 在基于Gecko的浏览器中的应用 -
本文介绍了如何在通过Gecko的浏览器对SOAP和JavaScript的兼容性来访问Web Service。 -
-
W3School的 SOAP 教程 -
SOAP is a simple XML-based protocol to let applications exchange information over HTTP. In this W3Schools SOAP tutorial, you will learn what SOAP is, and how it uses XML to exchange information between applications. -
-
XML-RPC新手上路 -
Informal but informative introduction to XML Remote Procedure Calls (XML-RPC). -
-
Web Services 基础 -
"Web services are a new breed of Web application. They are self-contained, self-describing, modular applications that can be published, located, and invoked across the Web." -
-

查看全部... -

-
-

Community

-
  • View Mozilla forums... -
-

{{ DiscussionList("dev-tech-xml", "mozilla.dev.tech.xml") }} -

- - -
XML -
-
-
-

{{ Note(1) }} From Wikipedia. -

Categories -

Interwiki Language Links ---Halfmature 20:42 2006年4月24日 (PDT) -


-

{{ languages( { "en": "en/XML_Web_Services", "es": "es/Servicios_Web_XML", "fr": "fr/Services_Web_XML", "it": "it/XML_Web_Services", "ja": "ja/XML_Web_Services", "ko": "ko/XML_Web_Services", "pl": "pl/XML_Web_Services" } ) }} diff --git a/files/zh-cn/xpi/index.html b/files/zh-cn/xpi/index.html deleted file mode 100644 index 438dc798b4..0000000000 --- a/files/zh-cn/xpi/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: XPI -slug: XPI -tags: - - Toolkit API - - XPInstall -translation_of: Mozilla/XPI ---- -

 

-

Cross-Platform Installer Module (XPI) (pronounced "zippy") is a ZIP file used to install packages, utilizing the XPInstall technology. XPI modules (so called "Bundles") are employed to install a wide variety of software, including Plugins, Extensions, Themes, and Thunderbird dictionaries.

-

跨平台安装模块(XPI) (发音为 "zippy") 是一个ZIP 文件,它利用 XPInstall技术来安装插件. XPI 模块 (也叫做 "Bundles") 可用来安装各种软件,包括插件Plugins, Extensions, 主题Themes, 和 Thunderbird dictionaries.

-

A XPI contains installation instructions (install.js or install.rdf) as well as the actual software to install, which is often itself packaged as a JAR file. When downloaded or dropped into an extension manager, XPInstall automatically interacts with the installation instructions contained in the XPI, and installs the contained software.

-

一个XPI含有安装指令(install.js 或 install.rdf)和真正需要安装的软件。这个软件一般是用JAR格式打包的。当XPI包被下载或者拖动到插件管理器之后,XPInstall自动读取XPI里的安装指令,并安装所包含的软件。

-

When XPI files are served via HTTP, the application/x-xpinstall MIME type should be matched with the xpi file extension.

-

当用HTTP来提供XPI文件时,application/x-xpinstall的 MIME类型必修要和xpi文件的插件匹配。

-

参见

- -
-  
-

{{ languages( { "fr": "fr/XPI", "ja": "ja/XPI", "pl": "pl/XPI" } ) }}

diff --git a/files/zh-cn/xquery/index.html b/files/zh-cn/xquery/index.html deleted file mode 100644 index c35b1f0c60..0000000000 --- a/files/zh-cn/xquery/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: XQuery -slug: XQuery -translation_of: Archive/XQuery ---- -

XQuery is a W3C standard language which is meant to be for XML what SQL is for relational data--i.e., the ability to search, sort, extract, and remold data. It offers powerful and yet intuitive searching based on XPath, has SQL-like syntax for the query portion, and has scripting features such as function and variable definitions, XML-inclusion, etc. -

While XQuery is currently not supported in Firefox (whether through JavaScript to developers or to browser users), at least one extension has been developed to give a preliminary support for XQuery for browser users (and serving as a simple model for how XQuery can be implemented within extensions). -

XqUSEme is a working proof-of-concept (so far tested on Windows; Mac does not work) extension which allows one to perform XQueries on external URLs, the currently loaded webpage (even if originally from poorly formed HTML), and/or XML (including well-formed XHTML) documents stored locally. -

The extension now includes and interfaces with the open-source version of Saxonica's Saxon B by default, while optionally allowing association with an installation of Berkeley DB XML, as a database system has the advantage of allowing local storage and indexing (though this extension currently only performs the XQueries). Other popular native XML databases might also be supported (e.g., eXist) in the future, especially now that the extension has added some basic support for the open-standard (XQJ) for Java and eXist is in the midst of getting such an API. Berkeley DB XML was the initial choice by the extension developer for its support across many languages (C++, Java, Python, Perl, PHP, etc.) (besides its also being open source). -

A simple usage example is available. -

-

Notes for developers wishing to access XQuery in their own extensions

-

At present, the extension works simply by using LiveConnect to work with Berkeley DB XML's Java API (and via a Java wrapper class which circumvents LiveConnect's current inability to handle some types of Java exceptions properly).

However, use of the approach of the Java Firefox extension might be used to turn the above extension concept into an XPCOM component (giving it access to all open windows), and for Berkeley DB XML, possibly implementing it in C++ instead, which is that database's original language of development.

However, the extension demonstrates a technique which does not depend on using XPCOM, while still giving full privileges. -

-

Tutorials

- -{{ languages( { "en": "en/XQuery" } ) }} diff --git a/files/zh-cn/xslt_2.0/index.html b/files/zh-cn/xslt_2.0/index.html deleted file mode 100644 index 3a2d4bdd87..0000000000 --- a/files/zh-cn/xslt_2.0/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: XSLT 2.0 -slug: XSLT_2.0 -translation_of: Mozilla/Tech/XSLT_2.0 ---- -

For users

-

Although XSLT 2.0 is not supported natively in Firefox, it is possible, via Saxon-B to perform XSLT 2.0, either as a regular user using the XSL Results extension, or within one's own extensions using the approach taken in its code (see below).

-

The extension author hopes to soon add support for having XSLT performed automatically when visiting a page containing a processing instruction for XSLT (and which was not already performed by Firefox's own 1.0 XSLT processor).

-

For developers

-

While it is possible to use the approach taken in the extension's code to add XSLT 2.0 support to one's own extension (or also Saxon-B's XQuery or XPath), at this time, it is fairly complicated, especially if one is not familiar with Java, due largely to the fact that there is a bug in LiveConnect with try-catch blocks, thus necessitating one to write one's own Java wrapper classes rather than to rely on JavaScript's own try-catch blocks (otherwise, the code might fail upon encountering a Java exception and be unusable again until restart).

-

If the bug is not fixed, in order to expose the full API, one would need to rewrite at least all of the public classes, handling exceptions on the Java side and returning an error string or object so that the JavaScript side could deal with any errors in XSLT (or XQuery) processing. However, a wrapper (or a direct rewrite of the Saxon code) would also need to take into account that if a method would return a given object, that object should also be a wrapped object so that it can also return error messages, in the event that the JavaScript tries to act on the Java object and an exception is returned.

-

Also, perhaps due to lagging Java support on the Mac, the code currently does not work on the Mac. However, if someone familiar with Java can try compiling Saxon-B completely in Java 5 (rather than its current mixture of JDK 1.4 and 5, the Saxon-B library author suggests this might solve the problem--any Java developers would be most welcome to help me (the XSL Results extension author) fix this). (You can leave a message on the discussion page.)

-

diff --git a/files/zh-cn/xtech_2005_presentations/directions_of_the_mozilla_rdf_engine/index.html b/files/zh-cn/xtech_2005_presentations/directions_of_the_mozilla_rdf_engine/index.html deleted file mode 100644 index 4adb5e1eb0..0000000000 --- a/files/zh-cn/xtech_2005_presentations/directions_of_the_mozilla_rdf_engine/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: XTech_2005_Presentations/Mozilla_RDF_引擎指导 -slug: XTech_2005_Presentations/Directions_of_the_Mozilla_RDF_engine -tags: - - Presentations - - RDF -translation_of: Archive/Mozilla/XTech_2005_Presentations/Directions_of_the_Mozilla_RDF_engine ---- -

 

-

Presentation

- -

Summary

-

This presentation showed new developments in the Mozilla RDF engine. These include plans to expose the RDF API to public web content, as well as performance and correctness improvements.

-

Questions and Discussion

-

Directions of the Mozilla RDF engine - Discussion

-

{{ languages( { "ja": "ja/XTech_2005_Presentations/Directions_of_the_Mozilla_RDF_engine" } ) }}

diff --git a/files/zh-cn/xtech_2005_presentations/index.html b/files/zh-cn/xtech_2005_presentations/index.html deleted file mode 100644 index daf0bf6c44..0000000000 --- a/files/zh-cn/xtech_2005_presentations/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: XTech 2005 Presentations -slug: XTech_2005_Presentations -translation_of: Archive/Mozilla/XTech_2005_Presentations ---- -

{{wiki.localize('System.API.page-generated-for-subpage')}}

diff --git a/files/zh-cn/xtech_2005_presentations/xul_-_mozilla's_xml_user_interface_language/index.html b/files/zh-cn/xtech_2005_presentations/xul_-_mozilla's_xml_user_interface_language/index.html deleted file mode 100644 index 16bc5bd27b..0000000000 --- a/files/zh-cn/xtech_2005_presentations/xul_-_mozilla's_xml_user_interface_language/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: XUL - Mozilla's XML User Interface Language -slug: XTech_2005_Presentations/XUL_-_Mozilla's_XML_User_Interface_Language -translation_of: >- - Archive/Mozilla/XTech_2005_Presentations/XUL_-_Mozilla's_XML_User_Interface_Language ---- -

短片

- -

概述

-

这是Ben Goodger在XTech 2005大会上展示的短片, Ben Goodger是Mozilla Firefox的首席工程师。 此胶片主要介绍了XUL,即Mozilla的XML用户界面语言。

-

问题与讨论

-

讨论:XTech_2005_Presentations:XUL_-_Mozilla's_XML_User_Interface_Language

diff --git "a/files/zh-cn/xul/\346\240\207\351\242\230\346\240\217/index.html" "b/files/zh-cn/xul/\346\240\207\351\242\230\346\240\217/index.html" deleted file mode 100644 index 3b7d814d8e..0000000000 --- "a/files/zh-cn/xul/\346\240\207\351\242\230\346\240\217/index.html" +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: 标题栏titlebar -slug: XUL/标题栏 -tags: - - XUL元素 - - XUL参考 -translation_of: Archive/Mozilla/XUL/titlebar ---- -
- - « XUL Reference home [ - 示例 | - 属性 | - 特性 | - 方法 | - 相关 ] -
-

由titlebar(标题栏)元素创建的盒子的行为就像是普通的窗口标题栏:当这个元素被点击并拖曳,窗体随着它移动。这个元素不能被用来改变普通窗体的平台原生标题栏,作为代替,它被用来给无chrome窗体创建自定义标题栏。如果标题栏在面板元素中,拖曳它会使那个面板移动。

-

标题栏中元素不会接受任何鼠标事件,例如,里面的按钮不能被点击,文本框不能通过鼠标获得焦点。如果你想要的不是这种行为,你可以通过在标题栏元素中设置allowevent="true"来重写它。

-

当移动完成时,标题栏会发送一个command事件。

-

示例

-

这个XUL文件创建了一个可以通过鼠标移动的HUD风格的窗体。它将会在鼠标释放时关闭。

-
<?xml version="1.0"?>
-<window title="Movable HUD Window"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        width="300" height="200"
-        style="background: transparent; -moz-appearance: none;">
-  <titlebar flex="1" oncommand="close()"
-            style="background: rgba(30, 30, 30, 0.9);
-                   -moz-border-radius: 10px;
-                   -moz-box-shadow: 0 1px 8px rgba(0, 0, 0, 0.8);
-                   margin: 8px 12px 16px;"/>
-</window>
-
-

可以在错误控制台输入这些打开它:open("file:///Users/markus/Sites/hudwindow.xul", "", "chrome=1, titlebar=0")

-

特征

-

- - - - - -

Inherited from XUL element
-align, -allowevents, -allownegativeassertions, -class, -coalesceduplicatearcs, -collapsed, -container, -containment, -context, -contextmenu, -datasources, -dir, -empty, -equalsize, -flags, -flex, -height, -hidden, -id, -insertafter, -insertbefore, -left, -maxheight, -maxwidth, -menu, -minheight, -minwidth, -mousethrough, -observes, -ordinal, -orient, -pack, -persist, -popup, -position, -preference-editable, -querytype, -ref, -removeelement, -sortDirection, -sortResource, -sortResource2, -statustext, -style, -template, -tooltip, -tooltiptext, -top, -uri, -wait-cursor, -width

-

-

Note: allowevents特征在Firefox 3之前的标题栏中不起作用。

-

属性

-

-

Inherited Properties
align, , allowEvents, , boxObject, builder, , , , className, , , , , collapsed, contextMenu, controllers, database, datasources, dir, , , flex, height, hidden, id, , , left, , maxHeight, maxWidth, menu, minHeight, minWidth, , , , , , , observes, ordinal, orient, , pack, , persist, , , , ref, resource, , , , , statusText, style, ,, tooltip, tooltipText, top, width

-

方法

-

-

Inherited from XUL element
blur, click, doCommand, focus, getElementsByAttribute

Inherited from DOM element
addEventListener(), appendChild(), dispatchEvent(), getAttribute(), getAttributeNode(), getAttributeNodeNS(), getAttributeNS(), getElementsByTagName(), getElementsByTagNameNS(), hasAttribute(), hasAttributeNS(), hasAttributes(), hasChildNodes(), insertBefore(), isSupported(), normalize(), removeAttribute(), removeAttributeNode(), removeAttributeNS(), removeChild(), removeEventListener(), replaceChild(), setAttribute(), setAttributeNode(), setAttributeNodeNS(), setAttributeNS()

- -

TBD

-

diff --git a/files/zh-cn/xul_element_attributes/index.html b/files/zh-cn/xul_element_attributes/index.html deleted file mode 100644 index 9a98275da0..0000000000 --- a/files/zh-cn/xul_element_attributes/index.html +++ /dev/null @@ -1,594 +0,0 @@ ---- -title: XUL element attributes -slug: XUL_element_attributes -tags: - - XUL Attributes -translation_of: Archive/Mozilla/XUL/XUL_Reference/XUL_element_attributes ---- -« XUL Reference home The following attributes are common to all XUL elements: -

- - -
-
align
-
Type: one of the values below
-
The align attribute specifies how child elements of the box are aligned, when the size of the box is larger than the total size of the children.
- 当box的尺寸大于全部子元素的尺寸时,align属性指定box元素的对齐方式。 -
    -
  • For boxes that have horizontal orientation, it specifies how its children will be aligned vertically.
  • -
  • 当box设置水平排列,它指定子元素如何垂直对齐。
  • -
  • For boxes that have vertical orientation, it specifies how its children will be aligned horizontally.
  • -
  • 当box设置垂直排列,它指定子元素如何水平对齐
  • -
-
-
-
-
start
-
Child elements are aligned starting from the left or top edge of the box. If the box is larger than the total size of the children, the extra space is placed on the right or bottom side.
- 子元素从box的左边或顶部开始排列。如果box大于全部子元素的总和,多出的空间在右边或底部。
-
center
-
Extra space is split equally along each side of the child elements, resulting in the children being placed in the center of the box.
- 多出的空间在子元素的周围,使子元素放置在box的中间。
-
end
-
Child elements are placed on the right or bottom edge of the box. If the box is larger than the total size of the children, the extra space is placed on the left or top side.
- 子元素从box的右边或底部开始排列。如果box大于全部子元素的总和,多出的空间在左边或顶部部。
-
baseline
-
This value applies to horizontally oriented boxes only. It causes the child elements to be aligned so that their text labels are lined up.
- 这个值只适用于水平方向的box元素。它让子元素的文本标签成一条直线。
-
stretch
-
This is the default value. The child elements are stretched to fit the size of the box. For a horizontal box, the children are stretched to be the height of the box. For a vertical box, the children are stretched to be the width of the box. If the size of the box changes, the children stretch to fit. Use the flex attribute to create elements that stretch in the opposite direction.
- 这是默认值。拉伸子元素来填充box。在水平的box元素中,子元素在高度上被拉伸。在垂直的box元素中,子元素在宽度上被拉伸。如果box元素尺寸改变,子元素也随之改变。使用flex属性创建的元素在相反方向被拉伸。
-
left
-
The elements are aligned on their left edges.
- 元素左边缘对齐。
-
center
-
The elements are centered horizontally.
- 元素水平居中。
-
right
-
The elements are aligned on their right edges.
- 元素右边缘对齐。
-
-
-
The pack attribute is related to the alignment but is used to specify the position in the opposite direction. You can also specify the value of align using the style property -moz-box-align.
- pack也是有关对齐的属性,但是指定相反方向的位置。你也可以在style中使用对齐的方式-moz-box-align
-
-
-
- - -
-
allowevents
-
Type: - boolean
-
- 类型:boolean
-
If true, events are passed to children of the element. Otherwise, events are passed to the element only.
- 如果为真,事件向子元素传递。否则,事件只传递到当前元素。
-
- - - -

-
- - -
-
allownegativeassertions
-
Type: boolean
- 类型:布尔类型
-
Valid on any element that has a datasources attribute. When multiple datasources are used, one may override an assertion from another. This attribute, if true, which is the default, allows a datasource to negate an earlier assertion.
- 适用于任何有 datasources 属性的元素。当使用多个数据源,一个数据源可以指定覆盖另一个。这个属性,如果为真,这是默认值,允许一个数据源覆盖之前的数据源。
-
- - -
- - -
-
class
-
Type: - string
-
- 类型:字符串(string)
-
The style class of the element. Multiple classes may be specified by separating them with spaces.
- 元素样式类型。多个类可以使用空格分开。
-
- - - -

-
- - -
-
coalesceduplicatearcs
-
Type: boolean
- 类型:布尔类型(boolean)
-
Valid on any element that has a datasources attribute. When multiple datasources are used, one may override an assertion from another. This attribute, if true, which is the default, allows a datasource to negate an earlier assertion.
- 任何有 datasources 属性的元素有效。当有多个数据源时使用,可以覆盖另一个声明。这个属性,如果是真,这是默认属性,允许一个数据源取消更早的声明。 
-
-
- - -
-
collapsed
-
Type: boolean
- 类型:布尔类型(boolean)
-
If true, then the element is collapsed and does not appear. It is equivalent to setting the CSS visibility property to collapse.
- 如果是真,那么这个元素可以折叠并且隐藏。相当于设置CSS的 visibility 属性为 collapse。
-
- - - -

 

-
- - -
-
container
-
Type: boolean
- 类型:布尔类型(boolean)
-
Set to true if the element is to act as a container which can have child elements. This would be used for folders. This will be set by the template builder as needed.
- 如果该元素是作为一个容器可以有子元素,设置为真。
-
- - -
- - -
-
containment
-
Type: URI
-
This attribute specifies RDF properties (an RDF predicate) that indicate that a resource is a container. When generating content from a template this is used to determine which resources from the datasource are containers and thus can have child nodes and which ones are not containers.
-
This attribute should be placed on the same element that the datasources and the ref attribute is on. It may be set to a space-separated list of RDF properties or resources.
-
-
- - -
-
context
-
Type: id
-
Should be set to the value of the id of the popup element that should appear when the user context-clicks on the element. A context-click varies on each platform. Usually it will be a right click. You can use the special value '_child' to indicate the first menupopup child of the element.
-
-
- - -
-
contextmenu
-
Type: id
-
Alternate name for the context attribute, but also has a corresponding script property contextMenu.
-
-
- - -
-
datasources
-
Type: space separated list of datasource URIs
-
A space-separated list of datasources that an element's template will use for content generation. These can be either internal datasources such as rdf:bookmarks or a URL. The datasources attribute may be placed on most elements, although it will usually be found on trees and menu related elements. The element should have a template element as a child.
-
For RDF templates, the specified datasources are combined into a single composite datasource which holds the data from all of the datasources. This composite datasource is accesssible via a script through the database property.
-
For XML datasources, only one source is used, either the URL of an XML file or an anchor reference to another element within the same document. For instance, the reference '#data' refers to an element with the id 'data'.
-
If you plan on adding a datasource to an element but don't want one to be added right away, set this attribute to 'rdf:null'. This will make the element so that its contents can be generated from a datasource. Otherwise, you cannot add one later.
-
When the XUL document is contained on a remote web site, the datasources may only be loaded from the same domain as the document.
-
-
- -
-
- dir
-
- Type: - - one of the values below -
-
- The direction in which the child elements of the element are placed.
-
-
-
- normal
-
- For scales, the scale's values are ordered from left to right (for horizontal scales) or from top to bottom (for vertical scales)  For other elements, the elements are placed left to right or top to bottom in the order they appear in the XUL code
-
- reverse
-
- For scales, the scale's values are ordered from right to left (for horizontal scales) or from bottom to top (for vertical scales). For other elements, they are placed right to left or bottom to top. This is reverse of the order in which they appear in the XUL code.
-
- - -

 

-
- - -
-
empty
-
Type: boolean
-
Set to true if the element is a container that contains no children. This will be set by the template builder as needed.
-
-
- - -
-
equalsize
-
Type: one of the values below
-
This attribute can be used to make the children of the element equal in size. -
-
always
-
For a horizontally oriented element, this will make all of its children have the width of the widest child. For a vertically oriented element, this will make its children all have the height of the tallest child.
-
never
-
All of the children are displayed at the size required by the content or as specified by the width and height attributes or the CSS width and height properties.
-
-
-
-
- - -
-
flags
-
Type: space-separated list of the values below
-
A set of flags used for miscellaneous purposes. Two flags are defined, which may be the value of this attribute. -
    -
  • dont-test-empty: For template generated content, the builder will not check that a container is empty.
  • -
  • dont-build-content: This flag may be used on a tree to indicate that content elements should not be generated. This results in a performance enhancement, but you will not be able to use the DOM functions to retrieve the tree rows.
  • -
-
-
-
- - -
-
flex
-
Type: string (representing an integer)
- 类型:字符串 (string) 表示一个整数
-
Indicates the flexibility of the element, which indicates how an element's container distributes remaining empty space among its children. Flexible elements grow and shrink to fit their given space. Elements with larger flex values will be made larger than elements with lower flex values, at the ratio determined by the two elements. The actual value is not relevant unless there are other flexible elements within the same container. Once the default sizes of elements in a box are calculated, the remaining space in the box is divided among the flexible elements, according to their flex ratios. Specifying a flex value of 0 has the same effect as leaving the flex attribute out entirely.
- 指示一个元素的伸缩性,
-
- - - -

 

-
- - -
-
height
-
Type: string (representing an integer)
-
The preferred height of the element in pixels. The actual displayed height may be different if the element or its contents have a minimum or maximum height. The CSS height property may also be used.
-
-
- - -
-
hidden
-
Type: boolean
-
If set to true, the element is not displayed. This is similar to setting the CSS display property to 'none'.
-
- - -
- -
-
- id
-
- 类型: 元素的ID,在主窗口中必须唯一
-
- 一个唯一的标识一边开发者能够定义. 你可以使用方法 getElementById() 或者其他 DOM 的函数并在样式表中添加对元素的引用。
-
- -

-
- - -
-
insertafter
-
Type: id
-
When an element is in an overlay, the insertafter attribute specifies the id of the element in the base window that the element should appear after. This attribute overrides the insertbefore attribute. This value may be a comma-separated list of ids, which are scanned and the first one found in the window is used.
-
-
- - -
-
insertbefore
-
Type: id
-
When an element is in an overlay, the insertbefore attribute specifies the id of the element in the base window that the element should appear before. This value may be a comma-separated list of ids, which are scanned and the first one found in the window is used.
-
-
- - -
-
left
-
Type: string (representing an integer)
-
For elements placed directly within a stack, specifies the pixel position of the left edge of the element relative to the left edge of the stack.
-
-
- - -
-
maxheight
-
Type: string (representing an integer)
-
The maximum height of the element. This corresponds to the max-height CSS property.
-
-
- - -
-
maxwidth
-
Type: string (representing an integer)
-
The maximum width of the element. This corresponds to the max-width CSS property.
-
-
- - -
-
menu
-
Type: id
-
Alternate name for the popup attribute, but also has a corresponding script property 'menu'.
-
-
- - -
-
minheight
-
Type: string (representing an integer)
-
The minimum height of the element. This corresponds to the min-height CSS property.
-
-
- - -
-
minwidth
-
Type: string (representing an integer)
-
The minimum width of the element. This corresponds to the min-width CSS property.
-
-
- - -
-
mousethrough
-
Type: one of the values below
-
Determines whether mouse events are passed to the element or not. If this attribute is not specified, the value is inherited from the parent of the element. If no ancestor has the mousethrough attribute set, the default value is never. -
-
always
-
Mouse events are transparent to the element. This means that the element will not receive any mouse events due to either clicking or movement. Child elements may override this if they specify mousethrough="never".
-
never
-
Mouse events are passed to the element as normal.
-
-
-
- - -
- - -
-
observes
-
Type: id
-
Set to an id of a broadcaster element that is being observed by the element. If an attribute changes in the broadcaster it is also changed in the observer.
-
-
- - -
-
ordinal
-
Type: string (representing an integer)
-
An integer which specifies the position of the element within its parent. By default, elements appear in the order they appear in the XUL code. The ordinal attribute can be used to change the order. Note the default ordinal for elements is 1. You can retrieve the displayed order by using the properties of the boxObject of the container.
-
-
-

布局(orient)

-
-
- 值类型:可以是下面值中的一种。
- 指定了子控件的布局(orient)为水平分布的(horizontally)或者是垂直分布的(vertically)。默认值依赖于控件本身。你也可以使用-moz-box-orient中的样式属性。 -
    -
  • horizontally: 子控件会被按照在xul源文件中出现的位置依次布置在一行中。
  • -
  • vertically: 子控件会被按照在xul源文件中出现的位置依次布置在一列中。
  • -
-
-
-
- - -
-
pack
-
Type: one of the values below
-
The pack attribute specifies where child elements of the box are placed when the box is larger that the size of the children. For boxes with horizontal orientation, it is used to indicate the position of children horizontally. For boxes with vertical orientation, it is used to indicate the position of children vertically. The align attribute is used to specify the position in the opposite direction. You can also specify the value of pack using the style property -moz-box-pack. -
-
start
-
Child elements are placed starting from the left or top edge of the box. If the box is larger than the total size of the children, the extra space is placed on the right or bottom side.
-
center
-
Extra space is split equally along each side of the child elements, resulting the children being placed in the center of the box.
-
end
-
Child elements are placed on the right or bottom edge of the box. If the box is larger than the total size of the children, the extra space is placed on the left or top side.
-
-
-
- - -
- -
-
- persist
-
- Type: - - space-separated list of attribute names -
-
- A space-separated list of attributes that are maintained when the window is closed. When the window is re-opened, the values of persistent attributes are restored. In Mozilla, persistent attributes are stored in the per-profile file localstore.rdf. Persistence can also be stored using the document.persist function. In order for persistence to work, the element must also have an id.
-
-

 

- -

-
- - -
-
popup
-
Type: id
-
Should be set to the value of the id of the popup element that should appear when the user clicks on the element.
-
- - -
- - -
-
position
-
Type: string (representing an integer)
-
When an element is in an overlay, the position is an index where the child is inserted. The position is one-based, so use a value of 1 to place the element at the beginning. This attribute is ignored if either an insertbefore or insertafter attribute matches an element.
-
-
- - -
-
preference-editable
-
Mozilla 1.8
-
Type: boolean
-
If true, the element may be used as one that modifies a preference in a prefwindow. The preference attribute may be used to connect to a preference element. This is useful for custom elements implemented in XBL. The element should fire change, command, or input event when the value is changed so that the preference will update accordingly.
-
- See the pref system documentation for more information.
-
-
- - -
-
querytype
-
Type: string
-
Indicates the type of datasource used in a template. Firefox 3 provides 3 built-in datasources: 'rdf', default, 'xml' and 'storage'. Extensions may provide support for additional datasources.
-
-
- - -
-
ref
-
Type: URI
-
For template-generated elements, this attribute is used to specify the root RDF node where content generation begins. This will correspond to the value of an about attribute on an RDF container. This attribute should be placed alongside the datasources attribute.
-
-
- - -
-
removeelement
-
Type: id
-
When placed on an element in an overlay, it indicates that the element in the base file should be removed from the window.
-
-
- - -
-
sortDirection
-
Type: one of the values below
-
Set this attribute to set the direction that template-generated content is sorted. Use the sortResource attribute to specify the sort key. -
-
ascending
-
The data is sorted in ascending order.
-
descending
-
The data is sorted in descending order.
-
natural
-
The data is sorted in natural order, which means the order that it is stored in.
-
-
-
-
- - -
-
sortResource
-
Type: URI
-
For template-generated content, this specifies the sort key, if you would like the content to be sorted. The key should be the full URI of the RDF resource to sort by, for example 'http://home.netscape.com/NC-rdf#Name'. Place this attribute on the same element as the datasources attribute. Use sortResource2 to specify a secondary sort key.
-
-
- - -
-
sortResource2
-
Type: URI
-
The value of this attribute is the URI of an RDF predicate that serves as a secondary key for sorted content.
-
-
- - -
-
statustext
-
Type: string
-
Used to set the text that appears on the status bar when the user moves the mouse over the element. Mozilla doesn't adjust the status bar automatically however. This attribute serves only as a place to keep the text. In Firefox, this text is automatically placed in the statusbar for menuitems on the menu bar.
-
- - -
- - -
-
style
-
Type: CSS inline style
-
CSS style rules to be applied to the element. Syntax is as in the HTML style attribute. It is preferred to put style rules in style sheets.
-
-
- - -
-
template
-
Type: id
-
For template generated elements, this attribute may optionally be placed on the root node (the element with the datasources attribute) to refer to a template that exists elsewhere in the XUL code. This template attribute should be set to the id of the template element. This might be used to share a single template between multiple trees or menus. If this attribute is not specified, there should be a template element directly inside the node.
-
-
- - -
-
tooltip
-
Type: id
-
Should be set to the value of the id of the tooltip or panel element that should be used as a tooltip window when the mouse hovers over the element for a moment. The tooltip will automatically disappear when the mouse is moved. If this attribute is set to '_child', the first tooltip child element inside the element is used.
-
-
- - -
-
tooltiptext
-
Type: string
-
Used to set the text which appears in the tooltip when the user moves the mouse over the element. This can be used instead of setting the tooltip to a popup for the common case where it contains only text. The tooltip is displayed in a default tooltip which displays only a label, however the default tooltip may be changed by setting the default attribute on a tooltip element.
-
-
- - -
-
top
-
Type: string (representing an integer)
-
For elements placed directly within a stack, specifies the pixel position of the top edge of the element relative to the top edge of the stack.
-
-
- - -
-
uri
-
Type: string
-
For template-generated content, the attribute should be placed on the element where content generation should begin. Thus, it should be placed on an element that is a descendant of a template. The value should be set to rdf:*.
-
- -
-
Elements that appear inside the element with the attribute will be repeated for each node in the RDF datasource. Elements outside will appear only once.
-
-
- - -
-
- wait-cursor
-
- Type: boolean
-
- Set this attribute to true to have the cursor switch to a waiting cursor while the mouse is hovering over the element. Usually, you would only use this on the window element or other top-level elements. In order to revert to the normal cursor state call the method removeAttribute("wait-cursor") when the process effectively has ended otherwise the wait cursor might never disappear.
-
- -
- - -
-
width
-
Type: string (representing an integer)
-
The preferred width of the element. The value should not include a unit as all values are in pixels. The actual displayed width may be different if the element or its contents have a minimum or maximum width, or the size is adjusted by the flexibility or alignment of its parent. The CSS width property may also be used.
-
- - -

diff --git a/files/zh-cn/xul_explorer/index.html b/files/zh-cn/xul_explorer/index.html deleted file mode 100644 index 7c97ce1101..0000000000 --- a/files/zh-cn/xul_explorer/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: XUL Explorer -slug: XUL_Explorer -translation_of: Archive/Mozilla/XUL_Explorer ---- -

XUL Explorer是一款提供一个很容易上手来进行XUL测试的 XULRunner 应用。这个编辑器很简单,他能在线预览或者在一个独立窗口预览XUL。它有一个列表的代码片段(小片段的XUL或JavaScript),可以快速插入到编辑器中。XUL可以加载和保存到文件。其中的XUL验证器和 错误控制台 可以帮助您找到问题所在。帮助菜单提供了访问 MDC上XUL信息的通道,更有 “keyword” 查找框帮助查找XUL元素。

- -

蓝图

- -

特性:

- - - -

特性:

- - - -

获取更多详细信息, 请关注 {{ interwiki('wikimo', 'XUL_Explorer:Planning#Feature_Planning_for_XUL_Explorer') }}.

- -

安装

- -

最后版本:

- - - -

贡献

- - - -

博客文章

- -

XUL Explorer - Updated (1.0a1pre)
- XUL Explorer 0.4
- XUL Explorer 0.3
- XUL Explorer 0.2
- Exploring XUL

- -

{{ languages( { "pl": "pl/XUL_Explorer" } ) }}

diff --git "a/files/zh-cn/xul_\347\250\213\345\272\217\346\211\223\345\214\205/index.html" "b/files/zh-cn/xul_\347\250\213\345\272\217\346\211\223\345\214\205/index.html" deleted file mode 100644 index e590b74be8..0000000000 --- "a/files/zh-cn/xul_\347\250\213\345\272\217\346\211\223\345\214\205/index.html" +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: XUL 程序打包 -slug: XUL_程序打包 -translation_of: Archive/Mozilla/XULRunner/XUL_Application_Packaging ---- -

XULRunner application packages are standard toolkit bundles (like a Firefox extension), with one additional manifest file (application.ini) which helps describe the application. XUL app packages are typically ZIPped into an archive with the extension .xulapp or .xpi. They can be installed with a XULRunner command-line flag "-install-app" (see the XULRunner 1.8.0.4 Release Notes).

-

application.ini

-

The application.ini manifest is located at the root of the extension and provides metadata that allows XULRunner to launch the application properly. It is parsed as a Windows-style INI file with {{mediawiki.external('Headings')}} and Key=Value pairs. Lines beginning with ; or # are treated as comments.

-

A sample application.ini file can be found in {{Source("xulrunner/examples/simple/application.ini", "the mozilla source tree")}}.

-

The [App] section

-

The App section specifies metadata about the application

-
-
- Name
-
- Specifies the application name.
- REQUIRED
- Example: Name=TestApplication
-
- Version
-
- Specifies the application version number.
- REQUIRED
- See Toolkit version format for version numbering details
- Example: Version=0.1
-
- BuildID
-
- Specifies a unique build identifier. This is typically a date identifier, and should be different for every released version of an application.
- REQUIRED
- Example: BuildID=20060201
-
- ID
-
- Specifies the unique application ID
- REQUIRED
- The application ID, like extension IDs, can be formatted either like an email ApplicationName@vendor.tld or a UUID {12345678-1234-1234-1234-123456789abc}. The email format is recommended for newly developed applications.
- Example: ID=TestApplication@example.tld
-
- Vendor
-
- Specifies the application vendor
- OPTIONAL
- Example: Vendor=Grinch Productions
-
- Profile
-
- Specifies the path to use for the application's profile, based within the user's application data directory
- OPTIONAL
- Example: Profile=MyAppData
-
-

The [Gecko] section

-

The Gecko section specifies what version of XULRunner is required by the application.

-
-
- MinVersion
-
- Specifies the minimum XULRunner version needed by this application. If there are binary components, MinVersion must equal the version of the libxul SDK which is used to build the application.
- REQUIRED
- Example: MinVersion=1.8
-
- MaxVersion
-
- Specify the maximum XULRunner version needed by this application.
- OPTIONAL - default value is any XULRunner less than XULRunner 2
- Example: MaxVersion=1.8.0.*
-
-

The [XRE] section

-

The XRE section specifies various features of XULRunner startup that can be enabled

-
-
- EnableExtensionManager
-
- Specifies whether to enable extensions and extension management. Legal values are 1 and 0.
- OPTIONAL - default is 0
- Note: This option does not add menu items that make the extension/theme manager available in the UI; that is the responsibility of the application author.
- Example: EnableExtensionManager=1
-
- EnableProfileMigrator
-
- Specifies whether, when the application is launched for the first time and there are no profiles, to enable profile migration code through the nsIProfileMigrator interface. Legal values are 1 and 0.
- OPTIONAL - default is 0
- Note: The application author is responsible for implementing the {{Source("toolkit/profile/public/nsIProfileMigrator.idl", "nsIProfileMigrator interface")}}; if an implementation is not found no migration will be performed.
- Example: EnableProfileMigrator=1
-
-

The [Crash Reporting] Section

- diff --git a/files/zh-cn/xulrunner/index.html b/files/zh-cn/xulrunner/index.html deleted file mode 100644 index 84389b591f..0000000000 --- a/files/zh-cn/xulrunner/index.html +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: XULRunner -slug: XULRunner -tags: - - XUL - - XULRunner -translation_of: Archive/Mozilla/XULRunner ---- -

 

-
- Getting Started with XULRunner
- A short introduction to XULRunner.
-
- XULRunner是谋智(Mozilla)运行包,它可以启动像火狐(Firefox)和雷鸟(Tunderbird)这样多功能的XUL+XPCOM程序。它为程序提供安装、升级、删除机制。 XULRunner还会提供libxul, 它允许其它项目或产品嵌入使用谋智(Mozilla)技术。
- - - - - - - -
-

Releases

-
-

最新版本的XULRunner可以到downloaded from ftp.mozilla.org下载。 安装、删除或其它信息请阅读版本说明

-

火狐3(Firefox 3)及以后的版本已内置一个私有的XULRunner包,你可以使用-app 运行其它兼容XULRunner程序。

-

旧版本依然可用。

-
-

概况

- -

文档

-
-
-  
-
-
-
- XULRunner 入门
-
- 一个简短的通过XULRunner构建桌面应用程序的教程.
-
-
-
- XUL 教程
-
- 一旦你有一个可运行的XULRunner程序,通过XUL教程可将它变为出色的XUL程序。
-
-
-
- XULRunner提醒
-
- XULRunner一些需要注意的内容.
-
-
-
- 发布XULRunner
-
- 怎样打包你的XULRunner程序。
-
-
-
- XULRunner Hall of Fame
-
- Tracks all available applications based on XULRunner.
-
-
-
- Build Documentation
-
- Learn how to get the source and build it.
-
- -
-
- Steps to configure Venkman to debug your App
-
-
-

Community

-
    -
  • View Mozilla forums...
  • -
-

{{ DiscussionList("dev-platform", "mozilla.dev.platform") }}

- - -
-
- XUL
-
-
-

Categories

-

Interwiki Language Links

-

 

-

{{ languages( { "ca": "ca/XULRunner", "es": "es/XULRunner", "fr": "fr/XULRunner", "it": "it/XULRunner", "zh-cn": "cn/XULRunner", "ja": "ja/XULRunner", "pl": "pl/XULRunner", "ko": "ko/XULRunner" } ) }}

diff --git a/files/zh-cn/xulrunner/what_xulrunner_provides/index.html b/files/zh-cn/xulrunner/what_xulrunner_provides/index.html deleted file mode 100644 index 8f431cbe70..0000000000 --- a/files/zh-cn/xulrunner/what_xulrunner_provides/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: What XULRunner Provides -slug: XULRunner/What_XULRunner_Provides -tags: - - References - - XULRunner - - 'XULRunner:References' -translation_of: Archive/Mozilla/XULRunner/What_XULRunner_Provides ---- -

XULRunner提供了一个开发xul程序的解决方案. XULRunner的目的就是提供一个部署XUL应用(目前主要是Firefox和Thunderbird)的解决方案,同时也提供一个嵌入式应用的机制。目前已经实现或计划的功能如下:

-

 

-

Gecko Features

- -

User Interface Features

-

The following user interface will be supplied by XULRunner, and may be overridden by embedders in certain circumstances:

- -

Embedding APIs

-

The following embedding APIs will be provided by XULRunner:

- -

The "Maybe" List

-

The following features have been discussed and may be included if developer time permits and codesize is controlled:

- -

What's out

-

XULRunner will not supply:

- diff --git a/files/zh-cn/xulrunner_old_releases/index.html b/files/zh-cn/xulrunner_old_releases/index.html deleted file mode 100644 index 402aa716fb..0000000000 --- a/files/zh-cn/xulrunner_old_releases/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: XULRunner/Old Releases -slug: XULRunner_Old_Releases -translation_of: Archive/Mozilla/XULRunner/Old_releases ---- -
-
- 1.9.2.x XULRunner releases
-
- These builds are built from the stable 1.9.2 branch.
-
- Nightly builds of XULRunner 1.9.0.x
-
- These builds are built from the stable 1.9 branch.
-
- Community contributed builds of XULRunner 1.8.1.3
-
- These builds are contributed by the Eclipse ATF community and are intended for embedding. The Windows and Linux builds will run normal XULRunner applications, but the Mac build uses Cocoa widgets and will not run XULRunner applications.
-
- XULRunner 1.8.0.4
-
- This is the last official stable developer preview release from the 1.8.0 branch. It has known security holes and should not be used in applications that deal with public web content.
-
diff --git a/files/zh-cn/xulrunner_tips/index.html b/files/zh-cn/xulrunner_tips/index.html deleted file mode 100644 index f0f1384344..0000000000 --- a/files/zh-cn/xulrunner_tips/index.html +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: XULRunner tips -slug: XULRunner_tips -translation_of: Archive/Mozilla/XULRunner/Tips ---- -

XULRunner常见问题,正在整理。

-

扩展管理器

-

要安装扩展,你首先要在application.ini中激活扩展管理器. XULRunner 1.8.0不会从程序目录载入扩展;只有XULRunner目录和用户配置目录会被检查。 然而,XULRunner 1.9在配置和程序目录检查后,XULRunner目录将被略过。要让XPInstall对话框、扩展管理器、皮肤管理器运行,下面的选项必须要进行设置:

-
pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
-pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul?type=themes");
-pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul?type=extensions");
-pref("xpinstall.dialog.progress.type.skin", "Extension:Manager-themes");
-pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager-extensions");
-pref("extensions.update.enabled", true);
-pref("extensions.update.interval", 86400);
-pref("extensions.dss.enabled", false);
-pref("extensions.dss.switchPending", false);
-pref("extensions.ignoreMTimeChanges", false);
-pref("extensions.logging.enabled", false);
-pref("general.skins.selectedSkin", "classic/1.0");
-// NB these point at AMO
-pref("extensions.update.url", "chrome://mozapps/locale/extensions/extensions.properties");
-pref("extensions.getMoreExtensionsURL", "chrome://mozapps/locale/extensions/extensions.properties");
-pref("extensions.getMoreThemesURL", "chrome://mozapps/locale/extensions/extensions.properties");
-
-

If your application is based on Gecko 2.0, you need to register a component through the new component registration because the extension manager uses FUEL, namely Application.restart(), to restart your xulrunner-based application after any change (installation, removal, enabling, disabling) in the extensions' list:

-
    -
  1. copy files fuelApplication.js and fuelApplication.manifest from browser/fuel/src for instance into your components/ directory
  2. -
  3. tweak the line #include ../../../toolkit/components/exthelper/extApplication.js in your copy of fuelApplication.js as needed
  4. -
  5. make sure to declare the FUEL module and the two files in your components/Makefile.in as in browser/fuel/src/Makefile.in
  6. -
  7. rebuild...
  8. -
-

Useful Chrome URLs

-

Most of these require branding.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WindowURLWindow Type
Extension Managerchrome://mozapps/content/extensions/extensions.xul?type=extensionsExtension:Manager-extensions
Theme Managerchrome://mozapps/content/extensions/extensions.xul?type=themesExtension:Manager-themes
JavaScript Consolechrome://global/content/console.xulglobal:console
about:configchrome://global/content/config.xul  
-

Developer Extensions

-

Venkman

- -

DOM Inspector

-

To add DOM Inspector 2.0.* to your XULRunner 1.9.0.* application follow these steps:

- -
content  inspector                       jar:inspector.jar!/content/inspector/ xpcnativewrappers=no
-locale   inspector           en-US       jar:inspector.jar!/locale/en-US/inspector/
-skin     inspector           modern/1.0  jar:inspector.jar!/skin/modern/inspector/
-skin     inspector           classic/1.0 jar:inspector.jar!/skin/classic/inspector/
-
-overlay  chrome://inspector/content/popupOverlay.xul   chrome://inspector/content/viewers/dom/popupOverlay.xul
-overlay  chrome://inspector/content/commandOverlay.xul chrome://inspector/content/viewers/styleRules/commandOverlay.xul
-overlay  chrome://inspector/content/keysetOverlay.xul  chrome://inspector/content/viewers/dom/keysetOverlay.xul
-overlay  chrome://inspector/content/popupOverlay.xul   chrome://inspector/content/viewers/styleRules/popupOverlay.xul
-overlay  chrome://inspector/content/commandOverlay.xul chrome://inspector/content/viewers/dom/commandOverlay.xul
-
-

To launch DOM Inspector in your application, you need to open its main window, with a command like this:

-
window.open("chrome://inspector/content/inspector.xul", "", "chrome");
-
-

Alternatively, the DOM Inspector may also be added as an extension:

-
    -
  1. (if you already have inspector installed for another application you can skip to the next step)
    - Follow the instructions above through "Unzip the package."
  2. -
  3. Create a file in the extensions directory of your application with the same name as the DOM Inspector ID (inspector@mozilla.org) containing one line of text -- the exact path to the root directory of DOM inspector (where the install.rdf is) like this one: -
    /home/username/.mozilla/firefox/numbersandletters/extensions/inspector@mozilla.org/
    -
  4. -
  5. Now create a javascript file with the following code and include it in the main window of your application: -
    function startDOMi()
    -{
    -  // Load the Window DataSource so that browser windows opened subsequent to DOM
    -  // Inspector show up in the DOM Inspector's window list.
    -  var windowDS = Components.classes["@mozilla.org/rdf/datasource;1?name=window-mediator"]
    -                                   .getService(Components.interfaces.nsIWindowDataSource);
    -  var tmpNameSpace = {};
    -  var sl = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
    -    .createInstance(Components.interfaces.mozIJSSubScriptLoader);
    -  sl.loadSubScript("chrome://inspector/content/hooks.js", tmpNameSpace);
    -  tmpNameSpace.inspectDOMDocument(document);
    -}
    -
    -
  6. -
  7. Now create a hook in your application window to start DOM Inspector, like this one: -
    <button label="Start Inpector" oncommand="startDOMi()"/>
    -
  8. -
  9. Start your application and DOM Inspector will be installed.
  10. -
-

Note: I use this method of installing extensions into all of my Mozilla applications. This way I have one directory where I keep all my Mozilla extensions, and each application (Firefox, Thunderbird) simply contains a few small, one line files pointing to the location of the extensions. (I keep them in source control to be sure I can maintain compatibility)

-

Component Viewer

-

Need custom build, first of all. What else?

-

Extension Developer's Extension

-

Extension Developer's Extension is a useful tool, featuring Live XUL Editor and JavaScript Shell. To install the extension into your application you'll need to hack its install.rdf (see above). You'll probably also want to create menuitems that let you open the JS Shell and other tools provided by the extension.

-

Branding

-

Branding is a chrome package containing product-specific information (e.g. the product name, vendor, and logo). Some XULRunner components (in particular, the Extension Manager) depend on branding, in the sense that they expect to find certain strings in chrome://branding/locale/brand.dtd and chrome://branding/locale/brand.properties. In order to satisfy these dependencies, you can save Firefox's brand.dtd/brand.properties to chrome/locale/branding folder, modify them appropriately, and register a locale provider for branding by adding the following line to your chrome manifest:

-
locale branding en-US chrome/locale/branding/
-
-

The location you put the branding files in doesn't matter, as long as you register it appropriately in the manifest. In addition, a branding content package must be registered to include the application logos:

-
content branding chrome/branding/
-
-

3 files should be provided in this folder: about.png, icon48.png and icon64.png. See Firefox for example.

-

Making Windows display correct application name and icon when buttons are grouped

-

By default, the task bar on Windows might group windows belonging to the same process into one button to save space. This button is usually called "xulrunner.exe" and has XULRunner's icon. There are two approaches to display the branding of your application instead:

- -

Reading command line arguments

-

See Chrome: Command Line. Command line arguments are handled via nsICommandLineHandler, as usual.

-

Preferences needed for file download dialogs

-

To use the unknown-content-type and file-downloads dialogs from a <browser> element, you need to add the following prefs:

-
pref("browser.download.useDownloadDir", true);
-pref("browser.download.folderList", 0);
-pref("browser.download.manager.showAlertOnComplete", true);
-pref("browser.download.manager.showAlertInterval", 2000);
-pref("browser.download.manager.retention", 2);
-pref("browser.download.manager.showWhenStarting", true);
-pref("browser.download.manager.useWindow", true);
-pref("browser.download.manager.closeWhenDone", true);
-pref("browser.download.manager.openDelay", 0);
-pref("browser.download.manager.focusWhenStarting", false);
-pref("browser.download.manager.flashCount", 2);
-//
-pref("alerts.slideIncrement", 1);
-pref("alerts.slideIncrementTime", 10);
-pref("alerts.totalOpenTime", 4000);
-pref("alerts.height", 50);
-
-

If you are missing preferences that a dialog requires, you will get the following errors:

-
Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIPrefBranch.getBoolPref]
-
-Error: dialog has no properties
-Source File: chrome://mozapps/content/downloads/u...ontentType.xul
-Line: 1
-
-

Enabling Password Manager

-

These preferences seem to be the default in Firefox, however, they are missing in XULRunner. Without these settings Password Manager will not store login details.

-
pref("signon.rememberSignons", true);
-pref("signon.expireMasterPassword", false);
-pref("signon.SignonFileName", "signons.txt");
-
-

You also need to get an instance of the login manager service, which internally initializes the system:

-
Components.classes["@mozilla.org/login-manager;1"].getService(Components.interfaces.nsILoginManager);
-
-

Using Firefox 3 to run XULRunner applications

-

Firefox 3 contains the XULRunner runtime. It has an -app command-line switch to run a specified XUL application instead of starting the browser.

-

On Windows:

-
  firefox.exe -app path\to\application.ini
-
-

On Linux:

-
  firefox -app path/to/application.ini
-

On the Mac:

-
  /Applications/Firefox.app/Contents/MacOS/firefox-bin -app /path/to/application.ini
-
-

Note that at least on the Mac, you need to use a full path. Partial paths don't seem to work.

-

Troubleshooting

-

Window title missing

-

If the title of your XUL <window> is blank, even though you specified a title attribute, make sure the extension on your XUL file is .xul rather than .xml

-

默认皮肤

-

To create a default theme you need to create a folder in the extensions folder with an install.rdf in it.  As of Oct. 2008, the folder needs to have the same name as the one in Firefox 3.0. 

-

\MyApp\Extensions\{972ce4c6-7e08-4474-a285-3208198ce6fd}\install.rdf

-

It should also have an <em:internalName>classic/1.0</em:internalName> as that is the default theme in Firefox.

-

{{ languages( { "ja": "ja/XULRunner_tips", "fr": "fr/Astuces_XULRunner" } ) }}

diff --git a/files/zh-cn/zones/index.html b/files/zh-cn/zones/index.html deleted file mode 100644 index 8054f631ff..0000000000 --- a/files/zh-cn/zones/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Zones -slug: Zones -translation_of: Zones ---- -

MDN 空间为你提供了一个能一站式获取一些指定主题或者产品的信息。以下为可用空间信息表。

- -
-
-

网页和app开发

- -
-
App 中心
-
- -

学习如何制作开源的web 应用—可以运行在不同的设备的丰富经验—使用你所知道的web标准和开放的技术。

- -
-
开发者工具
-
学习如何使用火狐的开发者工具去调试,测试和优化你的web 应用和站点 。
-
火狐应用商店
-
一个开放的,非盈利性的在线应用商店,里面有用HTML,CSS和JavaScript制作的web 应用。 提交你的apps到火狐应用商店吧,或者用你的代码制作属于你自己的应用商店。
-
游戏开发
-
学习如何用为网页开发游戏,如何把web技术和已经存在的游戏结合,并且如何把你的游戏变成web应用。
-
-
- -
-

产品和项目

- -
-
Emscripten
-
An LLVM to JavaScript compiler; this lets you compile, for example, C++ code into JavaScript code which can be run in any Web browser.
-
L20n
-
A JavaScript localization framework for unleashing your natural language's power with simple code.
-
The MDN project
-
The Mozilla Developer Network (this site) relies on its community of readers and contributors to grow and improve. You can learn here how to help use, contribute to, and build the code behind MDN!
-
Persona
-
A new simple, privacy-sensitive single-sign in system developed by Mozilla which lets users log into your Web site using their email address, freeing you from password management.
-
- -

Mozilla 技术

- -
-
附加组件
-
学会开发和安装基于Mozilla软件(包括流行的火狐浏览器)的拓展,主题和插件
-
火狐浏览器
-
学习关于Firefox的一切,从如何修改和构建到如何为它打造专属的插件。
-
火狐操作系统
-
Mozilla开发的手机操作系统,支持用户安装和运行使用HTML,CSS和JavaScript开发的开放Web应用程序。
-
-
-
- -

 

diff --git "a/files/zh-cn/\345\212\250\346\200\201\344\277\256\346\224\271\345\237\272\344\272\216xul\347\232\204\347\224\250\346\210\267\347\225\214\351\235\242/index.html" "b/files/zh-cn/\345\212\250\346\200\201\344\277\256\346\224\271\345\237\272\344\272\216xul\347\232\204\347\224\250\346\210\267\347\225\214\351\235\242/index.html" deleted file mode 100644 index c46deb30eb..0000000000 --- "a/files/zh-cn/\345\212\250\346\200\201\344\277\256\346\224\271\345\237\272\344\272\216xul\347\232\204\347\224\250\346\210\267\347\225\214\351\235\242/index.html" +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: 动态修改基于XUL的用户界面 -slug: 动态修改基于XUL的用户界面 -tags: - - DOM - - Extensions - - XUL -translation_of: Archive/Mozilla/XUL/Dynamically_modifying_XUL-based_user_interface ---- -

This article discusses manipulating XUL interfaces, using DOM and other APIs. It explains the concept of DOM - - documents - , demonstrates a few simple examples of using DOM calls to perform basic manipulations on a document, and then demonstrates working with - - anonymous XBL content - using Mozilla-specific methods.

-

It is written for beginner to intermediate XUL developers. We assume that the reader has basic knowledge of both XUL and JavaScript. You may also want to read some introductory documents about DOM, like the About the Document Object Model article or the Introduction page of the Gecko DOM Reference.

-

介绍

-

如你所知,XUL是一种在各种基于Mozilla应用程序,如Firefox和Thunderbird 中使用,用于描述用户界面的XML语言。在 XUL 应用程序中 JavaScript 定义行为,使用DOM API访问XUL文档。

-

那么什么是文档模型API?

-

They are the interfaces that are used in any interaction of a script and a document. If you have ever written a script that interacts with a XUL (or HTML) document, you have already used DOM calls. The most well known DOM method is probably document.getElementById(), which returns an element, given its id. You may also have used other calls, such as element.setAttribute(), or, if you wrote an extension, the addEventListener() method. All of these are defined in DOM.

-

There are also DOM methods that create, move, or delete elements from a document. They will be demonstrated in a later section. Right now, let's learn what a - - document - is.

-

What is a document?

-

A document is a data structure which is manipulated through DOM APIs. A logical structure of every document is a tree, with nodes being elements, attributes, processing instructions, comments, etc. Use the DOM Inspector tool to see the tree representation of any document. Todo: simple example of a XUL document and a tree

-

You can think of a document as an in-memory representation of valid HTML or well-formed XML such as XHTML or XUL.

-

It is important to remember that different web pages (and even different instances of the same web page) correspond to different documents. Each XUL window has its own distinct document, and there may even be a few different documents in a single window, when there is an <iframe>, <browser>, or a <tabbrowser> element. You must be sure to always manipulate the correct document. (Read more about this in Working with windows in chrome code.) When your script is included using a <script> tag, the document property references the DOM document that includes the script.

-

示例:使用DOM方法

-

本节演示 appendChild(), createElement(), insertBefore(), 和removeChild() DOM 方法的使用。

-

移除一个元素的所有子元素

-

This example removes all children of an element with id=someElement from the current document, by calling removeChild() method to remove the first child, until there are no children remaining.

-

Note, that hasChildNodes() and firstChild are also part of the DOM API.

-
var element = document.getElementById("someElement");
-  while(element.hasChildNodes()){
-    element.removeChild(element.firstChild);
-  }
-
-

插入菜单项到菜单中

-

This example adds two new menu items to a <menupopup>: to the start and to the end of it. It uses document.createElementNS() method to create the items, and insertBefore() with appendChild() to insert the created xml elements within the document.

-

注意力:

- -
function createMenuItem(aLabel) {
-  const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-  var item = document.createElementNS(XUL_NS, "menuitem"); // create a new XUL menuitem
-  item.setAttribute("label", aLabel);
-  return item;
-}
-var popup = document.getElementById("myPopup"); // a <menupopup> element
-var first = createMenuItem("First item");
-var last = createMenuItem("Last item");
-popup.insertBefore(first, popup.firstChild);
-popup.appendChild(last);
-
-

You can also use appendChild() and insertBefore() to move existing elements. For example you could move the item labeled "First item" to the end of popup by adding this statement as a last line to the snippet above:

-
popup.appendChild(first);
-
-

This statement would remove the node from its current position in the document and re-insert it at the end of the popup.

-

Anonymous content (XBL)

-

XBL is the language used in Mozilla to define new widgets. Widgets defined in XBL may choose to define some content which is inserted to the bound element, when the binding is attached. This content, called - - anonymous content - , is not accessible through normal DOM methods.

-

You need to use the methods of nsIDOMDocumentXBL interface instead. For example:

-
// gets the first anonymous child of the given node
-document.getAnonymousNodes(node)[0];
-
-// returns a NodeList of anonymous elements with anonid attribute equals el1
-document.getAnonymousElementByAttribute(node, "anonid", "el1");
-
-

See getAnonymousNodes and getAnonymousElementByAttribute in the XBL reference for more information.

-

Once you have an anonymous node, you can use regular DOM methods to navigate and manipulate the rest of the nodes of that binding.

-

See also

- diff --git "a/files/zh-cn/\346\211\251\345\261\225/using_the_dom_file_api_in_chrome_code/index.html" "b/files/zh-cn/\346\211\251\345\261\225/using_the_dom_file_api_in_chrome_code/index.html" deleted file mode 100644 index 9198b4b544..0000000000 --- "a/files/zh-cn/\346\211\251\345\261\225/using_the_dom_file_api_in_chrome_code/index.html" +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: 在chrome代码中使用DOM File API -slug: 扩展/Using_the_DOM_File_API_in_chrome_code -translation_of: Extensions/Using_the_DOM_File_API_in_chrome_code ---- -

{{ gecko_minversion_header("6.0") }}

-

如果你想在chrome代码中使用DOM File API,可以使用,且没有任何限制.事实上,你还获得了一个额外的特性:你可以通过传入文件的本地路径来创建一个 {{ domxref("File") }}对象.这个特性只在特权代码中可用,web页面中不可用.很明显,这是因为安全问题,否则网页可以读取到用户计算机中任意的本地文件.如果你在非特权代码(比如普通的web页面)中向{{ domxref("File") }}构造函数传入了一个路径字符串,则会抛出异常.

-

通过文件路径访问文件

-

想要通过文件路径引用到某个文件,你只需要传入一个路径字符串:

-
var file = File("path/to/some/file");
-
-

注: 由于windows和linux系统上使用的路径分隔符不同(这里使用了"/"),所以这样写会产生无法跨平台的问题.而且我们没有一个类似于Java中的File.pathSeparator来动态的获取到适合用户操作系统的路径分隔符.所以如果你的扩展程序需要跨平台,更好的做法是避免把路径写死(字符串形式),而是使用 nsIFile::append()方法来指定某个目录中所需要的文件,具体看下一节.

-

访问特殊目录中的文件

-

你也可以通过directory服务来获取到所需访问文件的路径.例如,你的附加组件需要访问用户的profile目录中的一个文件.你可以这样做:

-
var dsFile = Components.classes["@mozilla.org/file/directory_service;1"]
-                    .getService(Components.interfaces.nsIProperties)
-                    .get("ProfD", Components.interfaces.nsIFile);
-
-dsFile.append("myfilename.txt");
-
-var file = File(dsFile.path);
-
-

这个例子中使用到了directory服务获取到了用户的profile目录(使用键"ProfD"),然后通过调用{{ ifmethod("nsIFile", "append") }}方法获取到了所需访问的文件.最后,我们通过将{{ ifmethod("nsIFile", "path") }} 属性传入{{ domxref("File") }}构造函数来生成一个{{ domxref("File") }}对象.

-

还有更方便的方法,就是直接把一个{{ interface("nsIFile") }}对象传入File构造函数:

-
var dsFile = Components.classes["@mozilla.org/file/directory_service;1"]
-                    .getService(Components.interfaces.nsIProperties)
-                    .get("ProfD", Components.interfaces.nsIFile);
-
-dsFile.append("myfilename.txt");
-
-var file = File(dsFile);
-

还有其他很多类似"ProfD"的键,请查看directory服务.

-

译者注:{{ interface("nsIFile") }}对象比{{ domxref("File") }}对象强大多了,在扩展程序中,我们不可能需要将一个{{ interface("nsIFile") }}对象转换成一个{{ domxref("File") }}对象.

-

备注

-

从Gecko 8.0 {{ geckoRelease("8.0") }}开始, 你也可以在组件代码中使用上面这些代码.

-

相关链接

- diff --git "a/files/zh-cn/\346\211\251\345\261\225/\345\206\205\345\265\214\351\200\211\351\241\271/index.html" "b/files/zh-cn/\346\211\251\345\261\225/\345\206\205\345\265\214\351\200\211\351\241\271/index.html" deleted file mode 100644 index d6aeadcf43..0000000000 --- "a/files/zh-cn/\346\211\251\345\261\225/\345\206\205\345\265\214\351\200\211\351\241\271/index.html" +++ /dev/null @@ -1,169 +0,0 @@ ---- -title: 内嵌选项 -slug: 扩展/内嵌选项 -tags: - - inline options - - 内嵌选项 -translation_of: Archive/Add-ons/Inline_Options ---- -

{{ gecko_minversion_header("7.0") }}

-

Firefox 7 支持新的定义扩展首选项的语法,同时适用于无需启动(bootstrapped)扩展和传统扩展。该新语法定义的首选项用户界面会出现在附加组件管理器的扩展详细视图里。该功能最初出现在 Firefox 移动版,现在已经可以在 Firefox 桌面版使用了。

-

选项文件

-

The XUL allowed for the inline options is limited to a few new tags. Here is an example of an options.xul file:

-
<?xml version="1.0"?>
-
-<!DOCTYPE mydialog SYSTEM "chrome://myaddon/locale/mydialog.dtd">
-
-<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <setting type="bool" pref="extensions.myaddon.bool" title="Boolean" desc="Stored as a boolean preference" />
-</vbox>
-
-

Note that it's limited to <setting> tags. The root <vbox> just acts as a container, it isn't merged into the main window. If you need script support, see the display notifications section.

-

设置类型

-

There are several types of <setting>s, each with a different type attribute:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type attributedisplayed aspreference stored as
bool{{ XULElem("checkbox") }}boolean
boolint{{ XULElem("checkbox") }}integer (use the attributes on and off to specify what values to store)
integer{{ XULElem("textbox") }}integer
string{{ XULElem("textbox") }}string
color{{ XULElem("colorpicker") }}string (in the #123456 format)
filebrowse button and labelstring
directorybrowse button and labelstring
menulist {{ gecko_minversion_inline("8.0") }}{{ XULElem("menulist") }}dependent on the menu item values
radio {{ gecko_minversion_inline("8.0") }}{{ XULElem("radio") }} buttonsdependent on the radio values
control{{ XULElem("button") }}no pref stored
-

The pref attribute should have the full name of the preference to be stored. The title attribute is used as a label for the controls. To set a description, either use the desc attribute, or a text node as a child of the <setting> tag.

-

Settings are tied to actual preferences, except the button setting, which is designed more for actions.

-

Some examples:

-
<!-- Boolean examples -->
-<setting pref="extensions.myaddon.bool1" type="bool" title="Boolean 1"/>
-<setting pref="extensions.myaddon.bool2" type="bool" title="Boolean 2">
-  Description of Boolean 2
-</setting>
-
-<!-- Boolean stored as an integer -->
-<setting pref="extensions.myaddon.boolInt" type="boolint" title="Boolean 3" on="1" off="2"/>
-
-<!-- Integer example -->
-<setting pref="extensions.myaddon.int" type="integer" title="Integer"/>
-
-<!-- String examples -->
-<setting pref="extensions.myaddon.text" type="string" title="Text"/>
-<setting pref="extensions.myaddon.password" type="string" title="Password" inputtype="password"/>
-
-<!-- Color example -->
-<setting pref="extensions.myaddon.color" type="color" title="Color"/>
-
-<!-- File and directory examples -->
-<setting pref="extensions.myaddon.file" type="file" title="File"/>
-<setting pref="extensions.myaddon.directory" type="directory" title="Directory"/>
-
-<!-- List example (this example would be stored as an integer) -->
-<setting pref="extensions.myaddon.options1" type="menulist" title="Options 1">
-  <menulist>
-    <menupopup>
-      <menuitem value="500" label="small"/>
-      <menuitem value="800" label="medium"/>
-      <menuitem value="1200" label="large"/>
-    </menupopup>
-  </menulist>
-</setting>
-
-<!-- Radio Button example (this example would be stored as a boolean) -->
-<setting pref="extensions.myaddon.options2" type="radio" title="Options 2">
-  <radiogroup>
-    <radio value="false" label="disabled"/>
-    <radio value="true" label="enabled"/>
-  </radiogroup>
-</setting>
-
-<!-- Button example - not tied to a preference, but attached to a command -->
-<setting title="Do Something" type="control">
-  <button id="myaddon-button" label="Click Me" oncommand="alert('Thank you!');"/>
-</setting>
-
-

显示通知

-

If you want to use the settings UI for anything more than storing preferences, then you will probably need to initialize them when they first appear. You can't do this until your options XUL has been loaded into the Add-on Manager window, so you should listen for the addon-options-displayed notification to initialize your settings. For example:

-
var observer = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic == "addon-options-displayed" && aData == "MY_ADDON@MY_DOMAIN") {
-      var doc = aSubject;
-      var control = doc.getElementById("myaddon-pref-control");
-      control.value = "test";
-    }
-  }
-};
-
-Services.obs.addObserver(observer, "addon-options-displayed", false);
-// Don't forget to remove your observer when your add-on is shut down.
-
-

This code should be in bootstrap.js (within the startup() function) for restartless extensions or in an XPCOM component or a JavaScript code module (not an overlay!) for traditional extensions.

-
-

{{ gecko_callout_heading("13.0") }}

-

Starting in Gecko 13.0 {{ geckoRelease("13.0") }}, you can also listen for the addon-options-hidden notification, which has the same subject and data as above, to find out when the UI is about to be removed. Use this notification to remove event listeners, or any other references that might otherwise be leaked.

-
-

Locating the options file

-

There are two ways to let the Add-on Manager find your options file:

- -

See also

- diff --git "a/files/zh-cn/\346\211\251\345\261\225/\347\244\276\345\214\272/index.html" "b/files/zh-cn/\346\211\251\345\261\225/\347\244\276\345\214\272/index.html" deleted file mode 100644 index 6505d6f33d..0000000000 --- "a/files/zh-cn/\346\211\251\345\261\225/\347\244\276\345\214\272/index.html" +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: 扩展/社区 -slug: 扩展/社区 -translation_of: Extensions/Community ---- -

 

-

如果你知道与扩展开发相关的邮件列表、新闻组、论坛或者其他社区,请链接到这里。

- -

{{ languages( { "en": "en/Extensions/Community","fr": "fr/Extensions/Communaut\u00e9", "ja": "ja/Extensions/Community", "pl": "pl/Rozszerzenia/Spo\u0142eczno\u015b\u0107" } ) }}

diff --git "a/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/bug_writing_guidelines/index.html" "b/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/bug_writing_guidelines/index.html" deleted file mode 100644 index a170bb1bfc..0000000000 --- "a/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/bug_writing_guidelines/index.html" +++ /dev/null @@ -1,366 +0,0 @@ ---- -title: Bug 提交指南 -slug: 质量保证/Bug_writing_guidelines -tags: - - Bugzilla - - 可能过时 - - 问答 -translation_of: Mozilla/QA/Bug_writing_guidelines ---- -
-

This page needs a technical review from the Mozilla QA Team in Q4 2014. (Assigned to Ioana Chiorean.) The following articles have been merged into this page from QMO:

- - - -

If you need help with Mozilla software (for example with Firefox or Thunderbird), use one of the available support options. Do not edit this page! Please read this page to learn how to report a bug using Bugzilla, which is Mozilla's bug tracking system.

- -

If you're new to reporting bugs, you may want to try getting help from the more experienced contributors. See the Community section on the QA page for pointers. If you're going to report a Firefox bug, you can also get assistance in the #firefox channel on irc.mozilla.org.

-
- -

有效的问题报告会最可能得到处理。这份指南则阐释了如何来写出这样的报告。

- -

准备

- -
    -
  1. 请确保你的软件是更新到最新的 -
      -
    • 理想情况下,请测试一个正在开发中的版本来看你所提交的问题是否已经处理掉。 (例如 Firefox Beta, Aurora, 或者 bleeding-edge Nightly).
    • -
    -
  2. -
  3. Bugzilla 上搜索,看看你的问题是否已经被提交。(教程).
  4. -
  5. 点击 输入一个新bug  表单,它就会指引你来完成绝大部分问题报告过程。如果你有多个问题需要报告, 请对每个问题分别提交一个问题报告。
  6. -
- -

写出清楚而准确的步骤来复现问题

- -

开发者怎样可以在他的设备上复现这个问题?

- -

复现问题的步骤是问题报告中最重要的部分。如何开发者可以重现这个问题, 这个问题就可能得到处理。 如果复现问题的步骤不清晰, 我们就不会知道这个问题是否已经被处理。 

- -

除了与每个步骤交互的意图外,尽量精确的描述出与 Firefox 交互的方法。

- - - -

在下面的步骤后,准确描述观察的结果和预期结果。明确区分实时(观察现象)和推测。

- - - -

如果这个bug看起来非常严重,那么您的设置可能有一些不正常的地方,这是重现该bug的必要步骤之一。看看您是否可以在新的Firefox配置文件中重现此错误。如果错误只发生在您现有的概要文件中,请尝试找出重现错误需要哪些设置、扩展名或概要文件。

- - - -

写出一个简洁的标题

- -

怎样用尽量少的字来描述一个Bug? 这是开发人员将在你的反馈报告中看到的第一部分。

- -

好的标题将会在众多反馈中被迅速区分开。它应该是报告一个问题, 而不是建议的解决方案。

- -

下面有一些范例:

- - - - - -

查找出准确的 product 和 component分类

- -

你需要将你提交的问题分类到product和component, 来确保你提交的问题报告被相关的开发人员看到。

- -

如果你正在使用 Firefox,问题很可能出在 "Firefox", "Toolkit"或"Core"中。

- - - -

如果有疑问,请搜索类似的错误并查看它们所在的分类。

- -

如果看起来以上的分类都不合适,那么在最合适的分类中寻找一个“通用”组件。

- -

指定 bug 的类型

- -

如果您正在报告一个崩溃错误,请包含一个Breakpad ID或附加堆栈跟踪,并在错误摘要中包含崩溃签名。如果您正在报告内存使用或溢出bug,请附上about:memory (Firefox 6+)的输出。理想情况下,找到一些步骤来重现在about:memory中显示的增长(即使在单击底部的“最小化内存使用”按钮之后)。如果您难以找到复制步骤,请尝试Firefox支持页面“高内存使用量”。如果您是c++开发人员,可以使用更精确的工具。

- -
-

原始文档信息

- - -
- -
-
-

下面的文章源自QMO: 如何合适地报告bug

-
- -

检查bug是否有效

- -

验证您发现的问题是一个新bug

- -

要验证您所发现的是否确实是Mozilla产品中的一个新bug,请查看下面的检查方法,以确保值得为其创建一个新的bug报告。

- - - -

如果你不知道该做什么,看看irc频道的问答。如果没人回答,就看看或把问题发到bugzilla论坛。如果仍然没人回答再编写bug报告。

- -

Bug报告

- -

怎么创建一个bug报告?

- - - -

在哪个社区可以发布bug报告?

- -

在创建错误时,应该考虑几个原则。 比如:

- -

     保持描述和摘要清晰简洁

- -

     仅报告错误报告中的一个问题

- -

     仅报告您的错误中的事实并删除您可能拥有的任何假设

- -

bug报告的概要

- - - -

继续阅读 How to Write a Proper Bug Report Part 2

- -
-

Original document information

- - -
- -
-
-

The following article has been merged into this page from QMO: How to write a proper bug - Part 2

-
- -

Reporting and Writing Good Bugs

- -

By Tyler Downer

- -

Contents

- - - -
    -
  1. Thank You
  2. -
  3. Read for all bugs
  4. -
  5. Choose Your Issue
  6. -
  7. Using Bugzilla
  8. -
  9. Related Information
  10. -
- - - -

Thank You!

- -

So, you think have found a bug in Firefox and you want to report it to be fixed. Great and thank you. The Mozilla projects rely on users to find and report bugs. However, you need to make sure that you write a good bug report on Bugzilla (bugzilla.mozilla.org) in order for it to be useful. These guidelines will help you write a good bug.

- -

Note: These instructions are written for Firefox, but similar ones apply for most Thunderbird and Seamonkey bugs, only details differ. Hopefully, a Thunderbird version of this page will be released with Thunderbird 3.

- -

IMPORTANT

- -

Please read For All Bugs thoroughly before going to your specific issue. The information contained there is critical to making sure your issue is with Firefox, and not with an extension or corruption in your profile.

- -

For all Bugs

- -

No matter what type of bug you have found, make sure to follow these steps to confirm that it is a bug in a Firefox, and not an extension. To do that, follow these steps:

- -
    -
  1. Update Firefox, add-ons and plugins to the most recent versions (this includes programs like Flash and Acrobat Reader). All of your plugins must be on the latest supported version, as well as Firefox. NOTE:Firefox 2 is no longer supported, and support for Firefox 3 will end by the end of the year. Please update to Firefox 3.5.
  2. -
  3. Start Firefox in Safe Mode and try to find the bug. If the issue goes away: -
      -
    1. Disable your extensions/themes one by one, until you find the one causing the issue.
    2. -
    3. Contact the developer of that extension.
    4. -
    5. Read below for more information on Extensions.
    6. -
    -
  4. -
  5. If the issue is still there in Safe Mode, make a new profile with no extensions or changes (instructions here). Then try to find the problem. If the issue goes away, your Firefox install was most likely corrupted. Migrate your bookmarks and other information to this new profile, and you should be good to go.
  6. -
  7. You can read Basic Troubleshooting for more steps to try.
  8. -
  9. If the issue is still present after these steps, it is likely your problem is with Firefox. However, make sure to go to support.mozilla.com and search for your issue there. Many problems can be solved with simple end-user support steps, and do not need to be reported as bugs. If you can not find any information to help on Mozilla support, keep reading to make sure your issue is really a bug, and to write a good helpful bug report.
  10. -
  11. One thing to help developers is to use the latest nightly development build. These are the absolute latest in development on the Firefox program and help developers know if the issue has already been fixed. Also, if a patch is written, it will be put in the trunk first, making it easy to test. You can find trunk builds at the Mozilla FTP site.
  12. -
- -

Extensions, Themes and Other Applications

- -

If you are experiencing a problem with an add-on, plugin, or other programs, please follow these steps:

- -
    -
  1. Update to the latest version. You can use Firefox's handy Add-on update manager to update extensions and themes. Some plugins and outside applications will have to be updated internally or manually from their website. It is very important that you are always using the latest version of plugins like Adobe Acrobat Reader, Flash Player, Real Player, VideoLAN and the like.
  2. -
  3. Read troubleshooting extensions and themes for more information.
  4. -
  5. If the problem lies with the extension (this can be proved using the steps listed for all bugs), then you should contact the developer of the extension or other application. Mozilla can not fix someone else's program for them.
  6. -
  7. If the issue lies with how Firefox uses the extension, the go ahead and report it to both Mozilla and the extension developer.
  8. -
- -

Choose your Issue

- -

After reading the information for All bugs above, choose your issue below.

- - - -
    -
  1. Crash
  2. -
  3. Enhancement
  4. -
  5. Internet Connectivity Issue
  6. -
  7. Memory Leak
  8. -
  9. Performance Issue
  10. -
  11. Regression
  12. -
  13. Webpage
  14. -
  15. Window Shakes
  16. -
  17. For Bugs Not Listed
  18. -
- - - -

崩溃

- -

If Firefox crashes, and you have already followed the steps for all bugs above, fill out a bug report with the following information:

- -
    -
  1. Try to reproduce the bug (what you did to make the crash occur). If possible, try to reproduce it on different computers with the same version of Firefox, and with the current nightly development build of Firefox.
  2. -
  3. Make sure you turn on the crash reporter, and provide the crash ids with your bug report (those can be found by typing about:crashes in your URL bar and copying the appropriate number).
  4. -
  5. Make sure to read how to get a stacktrace and more information that is important for developers.
  6. -
  7. Now that you have all this information, create a bug with a severity of Critical. Give as much information as possible.
  8. -
- -

Enhancement

- -

When you would like a feature added to Firefox, it is called an Enhancement and the severity is marked as such. To file a good enhancement request, simply follow these two steps:

- -
    -
  1. Make sure you have explored all possible settings and other areas of Firefox to confirm that what you want does not already exist.
  2. -
  3. Give a clear description on what, where and how this should be changed. Give the dialog box to be improved, maybe even a screenshot if it is a little known feature or it would assist in understanding. Remember, there are many areas of Firefox, so don't be offended if the Triage team asks for more details or why this should be added.
  4. -
- -

Internet Connectivity Issue

- -

If you are having issues connecting to the Internet, it is most likely not an issue with Firefox, but an incorrectly set up Firewall. Make sure your Internet settings are set up correctly, and follow the steps listed for all bugs, then search the Firefox Support site. They will let you know if it is something you should report on Bugzilla or not.

- -

Memory Leak

- -

Memory Leaks are very difficult to diagnose, so make sure the issue is not with your machine. Then provide the following information:

- -
    -
  1. Detailed information on your machine, what is happening when the leak occurs, and what seems to cause it.
  2. -
  3. Read the following information found on David Barron's blog (Part 1, Part 2)and the Mozilla Developer Center on writing good memory leak bugs.
  4. -
- -

Performance Issue (High CPU use, hard drive use, etc)

- -

Performance issues are also difficult to confirm and diagnose. The only real way to confirm them is to have a website (create a testcase, read here for more info) that we can use to confirm on any similar machine. Please try to test on at least one other machine of the same or similar configuration before reporting. Also, issues such as startup times are almost impossible to confirm and can be influenced by other factors, so please make a strong case before submitting. Developers are always working on performance, so your problem may be fixed in the next release of Firefox.

- -

Regression

- -

If a bug has just recently occurred in Firefox that was not there before and is caused by an update, it is a regression. These usually only happen on the Trunk builds, though occasionally they creep onto the Releases. To properly report a regression:

- -
    -
  1. Follow the steps listed for all bugs. Also, make sure you did not make a change recently to the settings or something else that could have caused this.
  2. -
  3. Install an older version of Firefox (starting with the most recent) to find out where the bug crept in. When you find it, then file that information.
  4. -
- -

Webpage Displaying Incorrectly

- -

Make sure that the issue you are seeing is a Firefox problem, and easy way to do this is follow these steps:

- -
    -
  1. Test in another browser such as Internet Explorer, Opera or Safari. If the issue is still there, it is probably something wrong with the website and they should be contacted.
  2. -
  3. Follow the steps for all bugs. Extensions can mess with the rendering of a website, especially audio and video.
  4. -
  5. Try to reproduce the issue on another computer running Firefox. You can also adjust your screen resolution to see if that is causing the issue.
  6. -
  7. Try contacting the webmaster in charge of the website. Inform them of the problem, and ask if they know what could be causing it (some sites only work with certain browsers).
  8. -
  9. Finally, if the issue is still there, make a testcase that shows in the bare minimum what the problem it. Information on how to can be found here.
  10. -
- -

窗口抖动

- -

If you Firefox window begins to shake, vibrate, or move around without any action on your part, it is usually fixed easily by reading these webpages:

- -
    -
  1. Follow the steps for all bugs. Extensions can cause window shakes.
  2. -
  3. Read this support document, Window Shakes.
  4. -
- -

对于没有列出的问题

- -

If the issue you are experiencing does not fall into these specific categories, follow the steps for all bugs, then write a clear, concise bug report. Make sure you eliminate any unnecessary information that could distract from the bug itself, and give a detailed steps to reproduce with all the information you think is necessary. Remember, no bug is too little to report and it will never get fixed unless it it reported.

- -

使用Bugzilla

- -

Now that you have followed all these steps, found that your problem is with Firefox, and gathered the proper information, you can submit to bugzilla. When you submit a bug, make sure you read Bug Filing Guidelines. This provides basic information to make sure you fill the bug out completely Also, read the Etiquette and Privacy Policy. Before filing any bug, make sure to search thoroughly for any duplicates of the same issue. Keep your bug reports down to only one issue per bug report, it may be closed because of too many issues in one report.

- -

相关信息

- -

You can visit the following pages for more information on bug reports and good related resources:

- - - -
    -
  1. Bug Writing Guidelines
  2. -
  3. Mozilla Support
  4. -
  5. Mozilla Developer Center
  6. -
  7. Firefox Trunk builds
  8. -
  9. Bugzilla
  10. -
- - - -

返回顶部

- -
-

Original document information

- - -
diff --git "a/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/index.html" "b/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/index.html" deleted file mode 100644 index 4b9d08bd30..0000000000 --- "a/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/index.html" +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: 质量保证 -slug: 质量保证 -translation_of: Mozilla/QA ---- -

要帮助我们的质量保证部门,你有很多事可以做,其中几乎没有一件需要了解怎么编写程序。有些即使你是个HTML或者其他的网络技术的都不懂的“小白”都可以做到!如果你对帮助我们测试或者其他的质量保证工作有兴趣的话,你应该先读一下Mozilla 质量保证以及帮助质量保证这几页。

- - - - - - - -
-

精选文章

-
-
- How to write a good bug
-
- The more effectively a bug is reported, the more likely that an engineer will actually fix it. By following these guidelines, you can help ensure that your bugs stay at the top of the Mozilla engineers' heap, and get fixed.
-
-

察看全部...

-
-

相关页面

- -

Nightly Builds

- -

相关主题

-
-
- 开发 Mozilla
-
-
-

 

diff --git "a/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/webrender/index.html" "b/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/webrender/index.html" deleted file mode 100644 index 848fc91948..0000000000 --- "a/files/zh-cn/\350\264\250\351\207\217\344\277\235\350\257\201/webrender/index.html" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: WebRender -slug: 质量保证/WebRender -translation_of: Mozilla/QA/WebRender ---- -

The WebRender class of tests are used to test the WebRender module (lives in gfx/wr) in a standalone way, without being pulled into Gecko. WebRender is written entirely in Rust code, and has its own test suites.

- -

If you are having trouble with these test suites please contact :kats or somebody else on the Graphics team (#gfx on IRC or Slack) and they will be able to point you in the right direction. Bugs against these test suites should be filed in the Core :: Graphics: WebRender component.

- -

WebRender

- -

The WebRender suite has one linting job, WR(tidy), and a WR(wrench) test job per platform. Generally these test jobs are only run if code inside the gfx/wr subtree are touched, although they may also run if upstream files they depend on (e.g. docker images) are modified.

- -

WR(tidy)

- -

The tidy lint job basically runs the servo-tidy tool on the code in the gfx/wr subtree. This tool checks a number of code style and licensing things, and is good at emitting useful error messages if it encounters problems. To run this locally, you can do something like this:

- -
cd gfx/wr
-pip install servo-tidy
-servo-tidy
-
- -

To run on tryserver, use ./mach try fuzzy and select the webrender-lint-tidy job.

- -

WR(wrench)

- -

The exact commands run by this test job vary per-platform. Generally, the commands do some subset of these things:

- - - -

Running locally (Desktop platforms)

- -

The test scripts can be found in the gfx/wr/ci-scripts/ folder and can be run directly from the gfx/wr folder if you have the prerequisite tools (compilers, libraries, etc.) installed. If you build mozilla-central you should already have these tools. On MacOS you may need to do a brew install cmake pkg-config in order to get additional dependencies needed for building osmesa-src.

- -
cd gfx/wr
-ci-scripts/linux-debug-tests.sh # use the script for your platform as needed
-
- -

Note that when running these tests locally, you might get small antialiasing differences in the reftests, depending on your local freetype library. This may cause a few tests from the reftests/text folder to fail. Usually as long as they fail the same before/after your patch it shouldn't be a problem, but doing a try push will confirm that.

- -

Running locally (Android emulator/device)

- -

To run the wrench reftests locally on an Android platform, you have to first build the wrench tool for Android, and then run the mozharness script that will control the emulator/device, install the APK, and run the reftests. Steps for doing this are documented in more detail in the gfx/wr/wrench/android.txt file.

- -

Running on tryserver

- -

To run on tryserver, use ./mach try fuzzy and select the appropriate webrender-<platform>-(release|debug) job.

-- cgit v1.2.3-54-g00ecf